Skip to content

Commit

Permalink
feat: correctly track tape test .plan/.end and report mismatches
Browse files Browse the repository at this point in the history
  • Loading branch information
ChALkeR committed Jul 9, 2024
1 parent 7b6f86b commit a96fdb0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
20 changes: 20 additions & 0 deletions __test__/tape.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,23 @@ test('this is a child test', (t) => {
t.equal(myThing, 5, 'this passes if the values are equal')
t.end()
})

test('test with an end', (t) => {
t.pass('this is fine')
t.end()
})

test('timing test', function (t) {
t.plan(3)
t.equal(typeof Date.now, 'function')
var start = Date.now()
setTimeout(() => t.ok(Date.now() - start >= 50), 50)
t.equal(1, 1)
})

const someAsyncThing = (x, t) => new Promise((resolve) => setTimeout(() => resolve(x * 2), t))

test('test using promises', async function (t) {
const result = await someAsyncThing(21, 50)
t.equal(result, 42)
})
35 changes: 29 additions & 6 deletions src/tape.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,32 @@ const aliases = {
// match/notMatch are confusing as operate on strings in some impls and objs in others. we skip them
}

function tapeWrapAssert(t) {
// Note: we must use t.assert instead of assert everywhere as we have t.plan
function tapeWrapAssert(t, callback) {
// Auto-call api.end() on planned test count reaching zero
let planned = null
let happened = 0
const track = (...calls) => {
happened += calls.length
if (planned === happened) api.end()
if (planned !== null) assert(planned >= happened, `plan (${planned}) < count (${happened})`)
}

// Note: we must use t.assert instead of assert everywhere as we have t.plan
const api = {
test: tapeWrap(t.test.bind(t)),
plan: (...r) => t.plan(...r),
plan: (count) => {
assert.equal(typeof count, 'number') // can not use t.assert here
planned = count + happened
t.plan(planned)
track()
},
skip: (...r) => t.skip(...r),
todo: (...r) => t.todo(...r),
comment: (...r) => t.diagnostic(...r),
end: () => {},
end: () => {
if (callback) callback()
api.end = () => {}
},
}

// Copy implementations from here if they exist, preferring over t.assert
Expand All @@ -83,19 +99,26 @@ function tapeWrapAssert(t) {

for (const [key, names] of Object.entries(aliases)) {
const impl = Object.hasOwn(base, key) ? base[key] : (...r) => t.assert[key](...r)
Object.assign(api, Object.fromEntries(names.map((name) => [name, impl])))
Object.assign(api, Object.fromEntries(names.map((name) => [name, (...r) => track(impl(...r))])))
}

return api
}

const AsyncFunction = (async () => {}).constructor

function tapeWrap(test) {
const tap = (name, ...args) => {
const fn = args.pop()
assert(args.length <= 1)
const [opts = {}] = args
verifyOptions(opts)
test(name, opts, (t) => fn(tapeWrapAssert(t)))
assert(fn instanceof Function)
if (fn instanceof AsyncFunction) {
test(name, opts, (t) => fn(tapeWrapAssert(t)))
} else {
test(name, opts, (t, callback) => fn(tapeWrapAssert(t, callback)))
}
}

tap.skip = (...args) => test.skip(...args)
Expand Down

0 comments on commit a96fdb0

Please sign in to comment.