-
Notifications
You must be signed in to change notification settings - Fork 5k
node:test: pass a done() callback to (t, done) => {} style tests #32682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| const { test } = require("node:test"); | ||
| const assert = require("node:assert"); | ||
|
|
||
| let callCount = 0; | ||
|
|
||
| // Sync callback-style test: invokes done() to signal completion. | ||
| test("callback test resolves with done()", (t, done) => { | ||
| assert.equal(typeof done, "function"); | ||
| callCount++; | ||
| done(); | ||
| }); | ||
|
|
||
| // Async-but-callback-style test: the test function returns a promise that | ||
| // resolves BEFORE done() is called. This proves the runner waits for done() | ||
| // and does not auto-complete on promise resolution: `sawDone` is only true | ||
| // once the deferred done() actually runs, and it is asserted on the next | ||
| // microtask-draining tick via a second callback test below. | ||
| let sawDone = false; | ||
| test("callback test waits for done() even when the body returns a promise", (t, done) => { | ||
| // Returning a resolved promise must NOT complete the test; only done() may. | ||
| return Promise.resolve().then(() => { | ||
| setTimeout(() => { | ||
| callCount++; | ||
| sawDone = true; | ||
| done(); | ||
| }, 5); | ||
| }); | ||
| }); | ||
|
Comment on lines
+19
to
+28
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win Replace Line 22 uses ♻️ Proposed fix return Promise.resolve().then(() => {
- setTimeout(() => {
+ setImmediate(() => {
callCount++;
sawDone = true;
done();
- }, 5);
+ });
});🤖 Prompt for AI AgentsSource: Path instructions |
||
|
|
||
| // Runs after the previous test. If the runner had wrongly completed the | ||
| // prior test on promise-resolution (before done()), `sawDone` would still be | ||
| // false here, failing the assertion. | ||
| test("previous callback test only completed via done()", (t, done) => { | ||
| assert.equal(sawDone, true, "async callback test completed before done() was called"); | ||
| callCount++; | ||
| done(); | ||
| }); | ||
|
|
||
| // Existing (t) => {...} sync-style signature must keep working. | ||
| test("sync test without done() still passes", t => { | ||
| assert.equal(typeof t.name, "string"); | ||
| callCount++; | ||
| }); | ||
|
|
||
| // Existing async-function signature must keep working. | ||
| test("async test without done() still passes", async t => { | ||
| await Promise.resolve(); | ||
| callCount++; | ||
| }); | ||
|
|
||
| // Calling done() twice (or done() plus a thrown/rejected value) must not | ||
| // double-complete or double-count the test. | ||
| test("done() is idempotent", (t, done) => { | ||
| callCount++; | ||
| done(); | ||
| done(); | ||
| }); | ||
|
|
||
| process.on("exit", () => { | ||
| assert.equal(callCount, 6, `expected 6 test invocations, saw ${callCount}`); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| const { test } = require("node:test"); | ||
|
|
||
| // Callback-style test that reports failure via done(error) must fail. | ||
| test("callback test fails when done() is called with an error", (t, done) => { | ||
| done(new Error("boom")); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,21 @@ describe("node:test", () => { | |
| stderr: expect.stringContaining("0 fail"), | ||
| }); | ||
| }); | ||
|
|
||
| test("should pass a done() callback to tests whose function takes two parameters", async () => { | ||
| const { exitCode, stderr } = await runTests(["06-callback-tests.js"]); | ||
| expect({ exitCode, stderr }).toMatchObject({ | ||
| exitCode: 0, | ||
| stderr: expect.stringContaining("0 fail"), | ||
| }); | ||
|
Comment on lines
+56
to
+61
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win Add end-to-end coverage for the new callback error/idempotency paths. This only checks the all-pass case. The runtime change also introduced new callback-specific behavior for 🤖 Prompt for AI Agents |
||
| }); | ||
|
|
||
| test("should report failure when a callback-style test calls done(error)", async () => { | ||
| const { exitCode, stderr } = await runTests(["07-callback-done-error.js"]); | ||
| expect(exitCode).not.toBe(0); | ||
| expect(stderr).toContain("1 fail"); | ||
| expect(stderr).toContain("boom"); | ||
| }); | ||
| }); | ||
|
|
||
| async function runTests(filenames: string[]) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.