a small zora like test runner for nodejs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = testResult => { | |
const isFailed = testResult.pass === false; | |
console.log(`${!isFailed ? 'ok' : 'no ok'} - ${testResult.description}`); | |
if (testResult.error) { | |
console.log(testResult.error.stack); | |
if (testResult.error.operator) { | |
console.log(`operator: ${testResult.error.operator}`); | |
} | |
if (testResult.error.expected) { | |
console.log(`expected: \n ${JSON.stringify(testResult.error.expected, null, 4)}`); | |
} | |
if (testResult.error.actual) { | |
console.log(`actual: \n ${JSON.stringify(testResult.error.actual, null, 4)}`); | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const testFunction = require('./test.js'); | |
const reporter = require('./reporter.js'); | |
const createHarness = () => { | |
const testList = []; | |
const test = (description, spec) => testFunction(description, spec, testList); | |
return { | |
test, | |
async report() { | |
for (const t of testList) { | |
for await (const a of t) { | |
reporter(a); | |
} | |
} | |
} | |
}; | |
}; | |
const defaultTestHarness = createHarness(); | |
process.nextTick(() => defaultTestHarness.report()); | |
module.exports = defaultTestHarness; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const testFunction = module.exports = (description, specFunction, testList) => { | |
let error = null; | |
let passing = true; | |
const subTestList = []; | |
// we return the routine so we can explicitly wait for it to complete (serial tests) | |
const subTest = (description, fn) => testFunction(description, fn, subTestList).execRoutine; | |
// eagerly run the test as soon as testFunction is called | |
const execRoutine = (async function () { | |
try { | |
await specFunction({test: subTest}); | |
} catch (e) { | |
passing = false; | |
error = e; | |
} | |
})(); | |
const testObject = Object.defineProperties({ | |
// we **report** test result with async iterators... in a non blocking way | |
[Symbol.asyncIterator]: async function* () { | |
await execRoutine; | |
for await (const t of subTestList) { | |
yield* t;// report sub test | |
passing = passing && t.pass; // mark parent test as failing in case a subtest fails (but don't bubble the error) | |
} | |
yield this; // report this test | |
} | |
}, { | |
execRoutine: {value: execRoutine}, | |
error: { | |
get() { | |
return error; | |
} | |
}, | |
description: { | |
value: description | |
}, | |
pass: { | |
get() { | |
return passing; | |
} | |
} | |
}); | |
// collect the test in the parent's test list | |
testList.push(testObject); | |
return testObject; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert').strict; | |
const {test} = require('./run.js'); | |
const wait = (time = 1000) => new Promise(resolve => setTimeout(() => resolve(), time)); | |
test(`some failing test`, t => { | |
assert.deepEqual([1, 2, 3], [1, 2, 4], `array should be equivalent`); | |
}); | |
test(`some nested test`, t => { | |
t.test(`inside`, () => { | |
assert.deepEqual({foo: 'bar'}, {foo: 'bar'}, `should match`); | |
}); | |
t.test(`failing inside`, () => { | |
assert.ok(false, `oh noooo`); | |
}); | |
}); | |
test(`some async test that shows concurrency`, async t => { | |
let foo = 'bar'; | |
t.test(`nested async`, async t => { | |
await wait(100); | |
assert.equal(foo, 'baz', 'see changed value although started before'); | |
foo = 'whatever'; | |
}); | |
t.test(`change foo faster`, t => { | |
assert.equal(foo, 'bar'); | |
foo = 'baz'; | |
}); | |
}); | |
test(`some serial test`, async t => { | |
let foo = 'bar'; | |
await t.test('nested inside', async t => { | |
await wait(100); | |
assert.equal(foo, 'bar', 'see the initial value of foo'); | |
foo = 'whatever'; | |
}); | |
t.test('run only once "nested inside" has finished', () => { | |
assert.equal(foo, 'whatever', 'see the changed value'); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment