Skip to content

Instantly share code, notes, and snippets.

@lorenzofox3
Last active October 15, 2019 22:51
Show Gist options
  • Save lorenzofox3/7cf9f108cc3e3ec5fac18d7a52e12673 to your computer and use it in GitHub Desktop.
Save lorenzofox3/7cf9f108cc3e3ec5fac18d7a52e12673 to your computer and use it in GitHub Desktop.
nodejs test runner for zora
#!/usr/bin/env node
const path = require('path');
const {Console} = require('console');
const globby = require('globby');
const zora = require('zora');
const TSR = require('tap-mocha-reporter');
const {createHarness, mochaTapLike} = zora;
const DEFAULT_PATH = ['*.spec.js', './test/*.js'];
const harness = createHarness();
// decorator so ``test`` function support "only" with tag in description (also at nested level)
const test = (description, spec, ...rest) => {
if (process.env.RUN_ONLY && description.includes('#only') === false) {
return harness.skip(description, spec, ...rest);
}
const createDecoratedAssertion = a => {
const test = (description, spec, ...rest) => {
if (process.env.RUN_ONLY && description.includes('#only') === false) {
return a.test(description, () => {
}, {skip: true});
}
return a.test(description, function zora_spec_fn(assert) {
return spec(createDecoratedAssertion(assert));
}, ...rest);
};
return Object.assign(Object.create(a), {test});
};
// we need to name function win "zora_spec_fn" to have correct stacktrace location
return harness.test(description, function zora_spec_fn(a) {
return spec(createDecoratedAssertion(a));
}, ...rest);
};
// note we mutate the zora object so zora can be a peer dependency an one can write is testing program as usual with ``require('zora')``
// you might want to re export ``test`` under a different package (coming with this cli test runner for example - let's say zora-node) but in this case if your testing program is also
// meant to run in a browser environment you might need to pre process it before.
Object.assign(zora, {
test
});
const argsSpec = {
// can use custom reporter based on the list accepted by tap-mocha reporter
'--reporter': String,
// whether your program use esm modules
'--esm': Boolean,
// aliases
'-r': '--reporter'
};
const createReporterStream = (value) => {
switch (value) {
case 'tap':
return process.stdout;
case 'classic':
case 'doc':
case 'dot':
case 'dump':
case 'json':
case 'jsonstream':
case 'landing':
case 'list':
case 'markdown':
case 'min':
case 'nyan':
case 'progress':
case 'silent':
case 'spec':
case 'xunit':
return TSR(value);
default:
throw new Error(`unknown reporter ${value}`);
}
};
(async () => {
const arg = require('arg');
const {_: files, ['--reporter']: reporter = 'classic', ['--esm']: isESM} = arg(argsSpec, {
permissive: false,
argv: process.argv.slice(2)
});
// use provided test file patterns or use conventional default
const testFiles = await globby((files.length ? files : DEFAULT_PATH).map(p => path.resolve(process.cwd(), p)));
// overwrite global console so it goes through the reporter stream
const reporterStream = createReporterStream(reporter);
console = new Console({
stdout: reporterStream
});
const requireFn = isESM ? require('esm')(module) : require;
try {
for (const f of testFiles) {
requireFn(f);
}
await harness.report(mochaTapLike);
} catch (e) {
console.error(e);
process.exit(1);
} finally {
// exit code of 1 in case of failure
process.exit(harness.pass ? 0 : 1);
}
})();
const {test} = require('zora');
test('a cjs test', t => {
t.ok(true);
t.eq('foo', 'bar', `foo === bar ?`);
});
import {test} from 'zora';
test('should run as only #only', t => {
t.ok(true, 'assertion runs');
t.test('should not run', t => {
t.fail('should not run');
});
t.test('this one yes should run #only', t => {
t.ok('true', ' I have run');
t.test('nested should not run', t => {
t.fail('should not run');
});
t.test('nested should run #only', t => {
t.ok(true, 'yes I ran');
});
});
});
test('should not run', t => {
t.fail('should not run');
});
{
"name": "zora-node",
"version": "1.0.0",
"description": "",
"main": "bin.js",
"dependencies": {},
"devDependencies": {
"arg": "^4.1.1",
"c8": "^5.0.4",
"esm": "^3.2.25",
"globby": "^10.0.1",
"tap-mocha-reporter": "^5.0.0",
"zora": "^3.0.3"
},
"bin": {
"zn": "./bin.js"
},
"scripts": {
"cli": "node ./bin.js",
"test": "npm run cli -- --esm",
"test:only": "RUN_ONLY=true npm t",
"test:cjs": "npm run cli -- ./cjs.spec.js",
"test:coverage": "c8 --include src.js npm t"
},
"author": "",
"license": "ISC"
}
export const square = x => x ** 2;
import * as zora from 'zora';
import {square} from './src.js';
const {test: describe} = zora;
describe('some test about square', ({test: it}) => {
it('a test', t => {
t.eq(square(1), 1, `1 * 1 = 1`);
});
it('another test', t => {
t.eq(square(2), 4, `2 * 2 = 4`);
});
});
import * as zora from 'zora';
import {square} from './src.js';
const {test: describe} = zora;
describe('square for 0', t => {
t.eq(square(0), 0, '0 * 0 = 0');
});
describe('square 3 - failing', t => {
t.eq(square(3), 8, '3 * 3 = 9');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment