npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@aredridel/t6

v7.1.0

Published

tap-producing ESM test harness for node and browsers

Downloads

20

Readme

@aredridel/t6

tap-producing test harness for node and browsers

This is based on tape, but ported to pure ESM style, for running in modern runtimes only.

example

import test from "@aredridel/t6";

test('timing test', function (t) {
    t.plan(2);

    t.equal(typeof Date.now, 'function');
    var start = Date.now();

    setTimeout(function () {
        t.equal(Date.now() - start, 100);
    }, 100);
});
$ node example/timing.js
(node:12355) ExperimentalWarning: The ESM module loader is experimental.
TAP version 13
# timing test
ok 1 should be equal
not ok 2 should be equal
  ---
    operator: equal
    expected: 100
    actual:   107
  ...

1..2
# tests 2
# pass  1
# fail  1

usage

You always need to import test from "@aredridel/t6" in test files. You can run the tests by usual node means (import('test-file.js') or node test-file.js). You can also run tests using the t6 binary to utilize globbing, on Windows for example:

$ t6 tests/**/*.js

t6's arguments are passed to the glob module. If you want glob to perform the expansion on a system where the shell performs such expansion, quote the arguments as necessary:

$ t6 'tests/**/*.js'
$ t6 "tests/**/*.js"

Preloading modules

Additionally, it is possible to make t6 load one or more modules before running any tests, by using the -r or --require flag. Here's an example that loads babel-register before running any tests, to allow for JIT compilation:

$ t6 -r babel-register tests/**/*.js

Depending on the module you're loading, you may be able to parameterize it using environment variables or auxiliary files. Babel, for instance, will load options from .babelrc at runtime.

The -r flag behaves exactly like node's require, and uses the same module resolution algorithm. This means that if you need to load local modules, you have to prepend their path with ./ or ../ accordingly.

For example:

$ t6 -r ./my/local/module tests/**/*.js

Please note that all modules loaded using the -r flag will run before any tests, regardless of when they are specified. For example, t6 -r a b -r c will actually load a and c before loading b, since they are flagged as required modules.

things that go well with t6

t6 maintains a fairly minimal core. Additional features are usually added by using another module alongside t6.

pretty reporters

The default TAP output is good for machines and humans that are robots.

If you want a more colorful / pretty output there are lots of modules on npm that will output something pretty if you pipe TAP into them:

To use them, try node test/index.js | tap-spec or pipe it into one of the modules of your choice!

uncaught exceptions

By default, uncaught exceptions in your tests will not be intercepted, and will cause t6 to crash. If you find this behavior undesirable, use tape-catch to report any exceptions as TAP errors.

other

  • CoffeeScript support with https://www.npmjs.com/package/coffeetape
  • Promise support with https://www.npmjs.com/package/blue-tape or https://www.npmjs.com/package/tape-promise
  • ES6 support with https://www.npmjs.com/package/babel-tape-runner or https://www.npmjs.com/package/buble-tape-runner
  • Different test syntax with https://github.com/pguth/flip-tape (warning: mutates String.prototype)
  • Electron test runner with https://github.com/tundrax/electron-tap
  • Concurrency support with https://github.com/imsnif/mixed-tape

methods

The assertion methods in t6 are heavily influenced or copied from the methods in node-tap.

import test from "@aredridel/t6";

test([name], [opts], cb)

Create a new test with an optional name string and optional opts object. cb(t) fires with the new test object t once all preceding tests have finished. Tests execute serially.

Available opts options are:

  • opts.skip = true/false. See test.skip.
  • opts.timeout = 500. Set a timeout for the test, after which it will fail. See test.timeoutAfter.
  • opts.objectPrintDepth = 5. Configure max depth of expected / actual object printing. Environmental variable NODE_TAPE_OBJECT_PRINT_DEPTH can set the desired default depth for all tests; locally-set values will take precedence.
  • opts.todo = true/false. Test will be allowed to fail.

If you forget to t.plan() out how many assertions you are going to run and you don't call t.end() explicitly, your test will hang.

test.skip([name], [opts], cb)

Generate a new test that will be skipped over.

test.onFinish(fn)

The onFinish hook will get invoked when ALL t6 tests have finished right before t6 is about to print the test summary.

test.onFailure(fn)

The onFailure hook will get invoked whenever any t6 tests has failed.

t.plan(n)

Declare that n assertions should be run. t.end() will be called automatically after the nth assertion. If there are any more assertions after the nth, or after t.end() is called, they will generate errors.

t.end(err)

Declare the end of a test explicitly. If err is passed in t.end will assert that it is falsey.

t.fail(msg)

Generate a failing assertion with a message msg.

t.pass(msg)

Generate a passing assertion with a message msg.

t.timeoutAfter(ms)

Automatically timeout the test after X ms.

t.skip(msg)

Generate an assertion that will be skipped over.

t.ok(value, msg)

Assert that value is truthy with an optional description of the assertion msg.

Aliases: t.true(), t.assert()

t.notOk(value, msg)

Assert that value is falsy with an optional description of the assertion msg.

Aliases: t.false(), t.notok()

t.error(err, msg)

Assert that err is falsy. If err is non-falsy, use its err.message as the description message.

Aliases: t.ifError(), t.ifErr(), t.iferror()

t.equal(actual, expected, msg)

Assert that actual === expected with an optional description of the assertion msg.

Aliases: t.equals(), t.isEqual(), t.is(), t.strictEqual(), t.strictEquals()

t.notEqual(actual, expected, msg)

Assert that actual !== expected with an optional description of the assertion msg.

Aliases: t.notEquals(), t.notStrictEqual(), t.notStrictEquals(), t.isNotEqual(), t.isNot(), t.not(), t.doesNotEqual(), t.isInequal()

t.deepEqual(actual, expected, msg)

Assert that actual and expected have the same structure and nested values using node's deepEqual() algorithm with strict comparisons (===) on leaf nodes and an optional description of the assertion msg.

Aliases: t.deepEquals(), t.isEquivalent(), t.same()

t.notDeepEqual(actual, expected, msg)

Assert that actual and expected do not have the same structure and nested values using node's deepEqual() algorithm with strict comparisons (===) on leaf nodes and an optional description of the assertion msg.

Aliases: t.notDeepEquals, t.notEquivalent(), t.notDeeply(), t.notSame(), t.isNotDeepEqual(), t.isNotDeeply(), t.isNotEquivalent(), t.isInequivalent()

t.deepLooseEqual(actual, expected, msg)

Assert that actual and expected have the same structure and nested values using node's deepEqual() algorithm with loose comparisons (==) on leaf nodes and an optional description of the assertion msg.

Aliases: t.looseEqual(), t.looseEquals()

t.notDeepLooseEqual(actual, expected, msg)

Assert that actual and expected do not have the same structure and nested values using node's deepEqual() algorithm with loose comparisons (==) on leaf nodes and an optional description of the assertion msg.

Aliases: t.notLooseEqual(), t.notLooseEquals()

t.throws(fn, expected, msg)

Assert that the function call fn() throws an exception. expected, if present, must be a RegExp or Function. The RegExp matches the string representation of the exception, as generated by err.toString(). The Function is the exception thrown (e.g. Error). msg is an optional description of the assertion.

t.doesNotThrow(fn, expected, msg)

Assert that the function call fn() does not throw an exception. expected, if present, limits what should not be thrown. For example, set expected to /user/ to fail the test only if the string representation of the exception contains the word user. Any other exception would pass the test. If expected is omitted, any exception will fail the test. msg is an optional description of the assertion.

t.test(name, [opts], cb)

Create a subtest with a new test handle st from cb(st) inside the current test t. cb(st) will only fire when t finishes. Additional tests queued up after t will not be run until all subtests finish.

You may pass the same options that test() accepts.

t.comment(message)

Print a message without breaking the tap output. (Useful when using e.g. tap-colorize where output is buffered & console.log will print in incorrect order vis-a-vis tap output.)

var htest = test.createHarness()

Create a new test harness instance, which is a function like test(), but with a new pending stack and test state.

By default the TAP output goes to console.log(). You can pipe the output to someplace else if you htest.createStream().pipe() to a destination stream on the first tick.

test.only([name], [opts], cb)

Like test([name], [opts], cb) except if you use .only this is the only test case that will run for the entire process, all other test cases using t6 will be ignored.

var stream = test.createStream(opts)

Create a stream of output, bypassing the default output stream that writes messages to console.log(). By default stream will be a text stream of TAP output, but you can get an object stream instead by setting opts.objectMode to true.

tap stream reporter

You can create your own custom test reporter using this createStream() api:

import test fronm "@aredridel/t6";
import path from "path";

test.createStream().pipe(process.stdout);

process.argv.slice(2).forEach(function (file) {
    require(path.resolve(file));
});

You could substitute process.stdout for whatever other output stream you want, like a network connection or a file.

Pass in test files to run as arguments:

$ node tap.js test/x.js test/y.js
TAP version 13
# (anonymous)
not ok 1 should be equal
  ---
    operator: equal
    expected: "boop"
    actual:   "beep"
  ...
# (anonymous)
ok 2 should be equal
ok 3 (unnamed assert)
# wheee
ok 4 (unnamed assert)

1..4
# tests 4
# pass  3
# fail  1

object stream reporter

Here's how you can render an object stream instead of TAP:

import test from "@aredridel/t6";
import path from "path";

test.createStream({ objectMode: true }).on('data', function (row) {
    console.log(JSON.stringify(row))
});

process.argv.slice(2).forEach(function (file) {
    require(path.resolve(file));
});

The output for this runner is:

$ node object.js test/x.js test/y.js
{"type":"test","name":"(anonymous)","id":0}
{"id":0,"ok":false,"name":"should be equal","operator":"equal","actual":"beep","expected":"boop","error":{},"test":0,"type":"assert"}
{"type":"end","test":0}
{"type":"test","name":"(anonymous)","id":1}
{"id":0,"ok":true,"name":"should be equal","operator":"equal","actual":2,"expected":2,"test":1,"type":"assert"}
{"id":1,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":1,"type":"assert"}
{"type":"end","test":1}
{"type":"test","name":"wheee","id":2}
{"id":0,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":2,"type":"assert"}
{"type":"end","test":2}

install

With npm do:

npm install @aredridel/t6 --save-dev

license

MIT