Skip to content

Commit cd877fd

Browse files
authored
fix(node/test): basic support for t.skip and t.todo (#29222)
Adds basic support for `t.skip` and `t.todo`
1 parent 9188c79 commit cd877fd

File tree

4 files changed

+171
-163
lines changed

4 files changed

+171
-163
lines changed

ext/node/polyfills/testing.ts

+46-10
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ const {
77
ArrayPrototypeForEach,
88
SafePromiseAll,
99
SafePromisePrototypeFinally,
10+
Symbol,
1011
} = primordials;
11-
import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts";
12+
import { notImplemented } from "ext:deno_node/_utils.ts";
1213
import assert from "node:assert";
1314

1415
const methodsToCopy = [
@@ -49,11 +50,20 @@ export function run() {
4950

5051
function noop() {}
5152

53+
const skippedSymbol = Symbol("skipped");
54+
5255
class NodeTestContext {
5356
#denoContext: Deno.TestContext;
57+
#parent: NodeTestContext | undefined;
58+
#skipped = false;
5459

55-
constructor(t: Deno.TestContext) {
60+
constructor(t: Deno.TestContext, parent: NodeTestContext | undefined) {
5661
this.#denoContext = t;
62+
this.#parent = parent;
63+
}
64+
65+
get [skippedSymbol]() {
66+
return this.#skipped || (this.#parent?.[skippedSymbol] ?? false);
5767
}
5868

5969
get assert() {
@@ -86,23 +96,34 @@ class NodeTestContext {
8696
}
8797

8898
skip() {
89-
warnNotImplemented("test.TestContext.skip");
99+
this.#skipped = true;
90100
return null;
91101
}
92102

93103
todo() {
94-
warnNotImplemented("test.TestContext.todo");
104+
this.#skipped = true;
95105
return null;
96106
}
97107

98108
test(name, options, fn) {
99109
const prepared = prepareOptions(name, options, fn, {});
110+
// deno-lint-ignore no-this-alias
111+
const parentContext = this;
100112
return PromisePrototypeThen(
101113
this.#denoContext.step({
102114
name: prepared.name,
103115
fn: async (denoTestContext) => {
104-
const newNodeTextContext = new NodeTestContext(denoTestContext);
105-
await prepared.fn(newNodeTextContext);
116+
const newNodeTextContext = new NodeTestContext(
117+
denoTestContext,
118+
parentContext,
119+
);
120+
try {
121+
await prepared.fn(newNodeTextContext);
122+
} catch (err) {
123+
if (!newNodeTextContext[skippedSymbol]) {
124+
throw err;
125+
}
126+
}
106127
},
107128
ignore: prepared.options.todo || prepared.options.skip,
108129
sanitizeExit: false,
@@ -144,9 +165,20 @@ class TestSuite {
144165
const prepared = prepareOptions(name, options, fn, overrides);
145166
const step = this.#denoTestContext.step({
146167
name: prepared.name,
147-
fn: (denoTestContext) => {
148-
const newNodeTextContext = new NodeTestContext(denoTestContext);
149-
return prepared.fn(newNodeTextContext);
168+
fn: async (denoTestContext) => {
169+
const newNodeTextContext = new NodeTestContext(
170+
denoTestContext,
171+
undefined,
172+
);
173+
try {
174+
return await prepared.fn(newNodeTextContext);
175+
} catch (err) {
176+
if (newNodeTextContext[skippedSymbol]) {
177+
return undefined;
178+
} else {
179+
throw err;
180+
}
181+
}
150182
},
151183
ignore: prepared.options.todo || prepared.options.skip,
152184
sanitizeExit: false,
@@ -204,9 +236,13 @@ function prepareOptions(name, options, fn, overrides) {
204236

205237
function wrapTestFn(fn, resolve) {
206238
return async function (t) {
207-
const nodeTestContext = new NodeTestContext(t);
239+
const nodeTestContext = new NodeTestContext(t, undefined);
208240
try {
209241
await fn(nodeTestContext);
242+
} catch (err) {
243+
if (!nodeTestContext[skippedSymbol]) {
244+
throw err;
245+
}
210246
} finally {
211247
resolve();
212248
}

tests/specs/node/node_test_module/test.js

+14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ test("sync fail todo", (t) => {
2222
throw new Error("thrown from sync fail todo");
2323
});
2424

25+
test("todo thrown sub test", async (t) => {
26+
t.todo("this is a todo test and is not treated as a failure");
27+
await t.test("test", () => {
28+
throw new Error("this does not fail the test");
29+
});
30+
});
31+
2532
test("sync fail todo with message", (t) => {
2633
t.todo("this is a failing todo");
2734
throw new Error("thrown from sync fail todo with message");
@@ -35,6 +42,13 @@ test("sync skip pass with message", (t) => {
3542
t.skip("this is skipped");
3643
});
3744

45+
test("skip thrown sub test", async (t) => {
46+
t.skip("this is a skip test and is not treated as a failure");
47+
await t.test("test", () => {
48+
throw new Error("this does not fail the test");
49+
});
50+
});
51+
3852
test("sync pass", (t) => {
3953
t.diagnostic("this test should pass");
4054
});

0 commit comments

Comments
 (0)