Skip to content

Commit

Permalink
fix: wait for async task
Browse files Browse the repository at this point in the history
  • Loading branch information
climba03003 committed Apr 12, 2024
1 parent f2cbd92 commit dcad03d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
28 changes: 28 additions & 0 deletions packages/unit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# @kakang/unit

This package is a wrapper over the `node:test` module,
which provides the ability to use `node:assert` directly
inside the unit test. It also provides `plan` feature,
to ensure the test you specify are all run.

## Usage

```js
import { test } from '@kakang/unit'

test('test', (t) => {
// .test also asserted
// .equal and .test is counted as 2
t.plan(2)

const expect = 1
const actual = 1
t.equal(actual, expect)

// To ease the usage, unless `node:test`
// nested `test` nolonger required to await
t.test('sub test', async (t) => {
t.plan(1) // it should fail
})
})
```
33 changes: 28 additions & 5 deletions packages/unit/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ interface DeferredPromise<T = unknown> {
resolve: (...args: any[]) => void
reject: (...args: any[]) => void
}
function createDeferredPromise (): DeferredPromise {
const promise: any = {}
function createDeferredPromise (replace: any = {}): DeferredPromise {
const promise: any = replace
promise.promise = new Promise((resolve, reject) => {
promise.resolve = resolve
promise.reject = reject
Expand All @@ -86,14 +86,19 @@ function wrapTest (testFn: any): Test {
const fn: TestFn = args.pop() // TestFn must be the last one

const customFn: ExtendedTestFn = async function (context) {
const { promises: contextPromises, teardown } = wrapContext(context)
const {
promises: contextPromises,
teardown,
completed
} = wrapContext(context)

// either return promise or using done
const promise = createDeferredPromise()
const fnPromise = fn(context as never as TestContext, () => {
promise.resolve()
})

await completed.promise
// resolve sub context
await Promise.all(contextPromises)
// resolve current context
Expand All @@ -108,8 +113,13 @@ function wrapTest (testFn: any): Test {
return test
}

function wrapContext (context: ExtendedTestContext): { promises: Array<Promise<unknown>>, teardown: () => void } {
function wrapContext (context: ExtendedTestContext): {
promises: Array<Promise<unknown>>
teardown: () => void
completed: DeferredPromise
} {
const promises: Array<Promise<unknown>> = []
const completed: DeferredPromise = {} as any
let expect = -1
let actual = 0

Expand All @@ -119,8 +129,19 @@ function wrapContext (context: ExtendedTestContext): { promises: Array<Promise<u
}
}

const validate = (): void => {
if (expect > -1 && actual === expect) {
completed?.resolve()
}
}

context.plan = function plan (num: number) {
expect = num
if (num > -1) {
createDeferredPromise(completed)
} else {
completed?.resolve()
}
}

const contextTest = context.test.bind(context)
Expand All @@ -129,6 +150,7 @@ function wrapContext (context: ExtendedTestContext): { promises: Array<Promise<u
promises.push(promise)
await promise
actual++
validate()
}
context.test = test

Expand All @@ -137,10 +159,11 @@ function wrapContext (context: ExtendedTestContext): { promises: Array<Promise<u
(context as any)[method] = (...args: any[]) => {
actual++
const res = (assert as any)[method](...args)
validate()
return res
}
}
}

return { promises, teardown }
return { promises, teardown, completed }
}
12 changes: 12 additions & 0 deletions packages/unit/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ test('sub path with callback', async (t) => {
})
})

test('should wait for async task', (t) => {
t.plan(1)

t.test('equal', (t) => {
t.plan(1)

setImmediate(() => {
t.equal(true, true)
})
})
})

test('use assert inside test', (t) => {
t.plan(1)

Expand Down

0 comments on commit dcad03d

Please sign in to comment.