mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
test_runner: fix hooks test context
Signed-off-by: Moshe Atlow <moshe@atlow.co.il> PR-URL: https://github.com/nodejs/node/pull/63285 Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
1 parent
fa1e1f4fd4
commit
57508024c3
4 files changed
+91
-17
No files matched your search
@@ -21,7 +21,7 @@ const {
|
||||
},
|
||||
} = require('internal/errors');
|
||||
const { exitCodes: { kGenericUserError } } = internalBinding('errors');
|
||||
const { kCancelledByParent, Test, Suite, TestContext, SuiteContext } = require('internal/test_runner/test');
|
||||
const { kCancelledByParent, Test, Suite } = require('internal/test_runner/test');
|
||||
const {
|
||||
parseCommandLine,
|
||||
reporterScope,
|
||||
@@ -439,16 +439,7 @@ function getTestContext() {
|
||||
if (test === undefined || test === reporterScope) {
|
||||
return undefined;
|
||||
}
|
||||
// For hooks (hookType is set), return the test/suite being hooked (the parent)
|
||||
const actualTest = test.hookType !== undefined ? test.parent : test;
|
||||
if (actualTest === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
// Return SuiteContext for suites, TestContext for tests
|
||||
if (actualTest instanceof Suite) {
|
||||
return new SuiteContext(actualTest);
|
||||
}
|
||||
return new TestContext(actualTest);
|
||||
return test.getCtx();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1233,8 +1233,14 @@ class Test extends AsyncResource {
|
||||
}
|
||||
}
|
||||
|
||||
#ctx;
|
||||
getCtx() {
|
||||
this.#ctx ??= new TestContext(this);
|
||||
return this.#ctx;
|
||||
}
|
||||
|
||||
getRunArgs() {
|
||||
const ctx = new TestContext(this);
|
||||
const ctx = this.getCtx();
|
||||
return { __proto__: null, ctx, args: [ctx] };
|
||||
}
|
||||
|
||||
@@ -1703,6 +1709,11 @@ class TestHook extends Test {
|
||||
this.#args = args;
|
||||
return super.run();
|
||||
}
|
||||
|
||||
getCtx() {
|
||||
return this.parentTest.getCtx();
|
||||
}
|
||||
|
||||
getRunArgs() {
|
||||
return this.#args;
|
||||
}
|
||||
@@ -1794,6 +1805,12 @@ class Suite extends Test {
|
||||
this.buildPhaseFinished = true;
|
||||
}
|
||||
|
||||
#ctx;
|
||||
getCtx() {
|
||||
this.#ctx ??= new TestContext(this);
|
||||
return this.#ctx;
|
||||
}
|
||||
|
||||
getRunArgs() {
|
||||
const ctx = new SuiteContext(this);
|
||||
return { __proto__: null, ctx, args: [ctx] };
|
||||
@@ -1866,6 +1883,4 @@ module.exports = {
|
||||
kUnwrapErrors,
|
||||
Suite,
|
||||
Test,
|
||||
TestContext,
|
||||
SuiteContext,
|
||||
};
|
||||
@@ -1,7 +1,16 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('node:assert');
|
||||
const { test, getTestContext, describe, it } = require('node:test');
|
||||
const {
|
||||
test,
|
||||
getTestContext,
|
||||
describe,
|
||||
it,
|
||||
before,
|
||||
after,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
} = require('node:test');
|
||||
|
||||
// Outside a test — must return undefined
|
||||
assert.strictEqual(getTestContext(), undefined);
|
||||
@@ -40,6 +49,63 @@ describe('getTestContext returns SuiteContext in suite', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTestContext inside hooks', () => {
|
||||
const suiteName = 'getTestContext inside hooks';
|
||||
|
||||
before(common.mustCall((t) => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, suiteName);
|
||||
assert.strictEqual(ctx.name, t.name);
|
||||
}));
|
||||
|
||||
beforeEach(common.mustCall(() => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, suiteName);
|
||||
}));
|
||||
|
||||
afterEach(common.mustCall(() => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, suiteName);
|
||||
}));
|
||||
|
||||
after(common.mustCall((t) => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, suiteName);
|
||||
assert.strictEqual(ctx.name, t.name);
|
||||
}));
|
||||
|
||||
it('runs inside the suite', () => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, 'runs inside the suite');
|
||||
});
|
||||
});
|
||||
|
||||
test('getTestContext inside test-level hooks returns the parent test', async (t) => {
|
||||
const parentName = t.name;
|
||||
t.beforeEach(common.mustCall(() => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, parentName);
|
||||
}));
|
||||
|
||||
t.afterEach(common.mustCall(() => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, parentName);
|
||||
}));
|
||||
|
||||
await t.test('child', () => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
assert.strictEqual(ctx.name, 'child');
|
||||
});
|
||||
});
|
||||
|
||||
test('getTestContext works in test body during async operations', async (t) => {
|
||||
const ctx = getTestContext();
|
||||
assert.ok(ctx !== undefined);
|
||||
|
||||
@@ -63,7 +63,9 @@ function isMustCallOrMustCallAtLeast(str) {
|
||||
}
|
||||
|
||||
function isMustCallOrTest(str) {
|
||||
return str === 'test' || str === 'it' || isMustCallOrMustCallAtLeast(str);
|
||||
return str === 'test' || str === 'it' || str === 'describe' || str === 'suite' ||
|
||||
str === 'before' || str === 'after' || str === 'beforeEach' || str === 'afterEach' ||
|
||||
isMustCallOrMustCallAtLeast(str);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reference in new issue
Block a user