|
7 | 7 | ArrayPrototypeForEach,
|
8 | 8 | SafePromiseAll,
|
9 | 9 | SafePromisePrototypeFinally,
|
| 10 | + Symbol, |
10 | 11 | } = primordials;
|
11 |
| -import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts"; |
| 12 | +import { notImplemented } from "ext:deno_node/_utils.ts"; |
12 | 13 | import assert from "node:assert";
|
13 | 14 |
|
14 | 15 | const methodsToCopy = [
|
@@ -49,11 +50,20 @@ export function run() {
|
49 | 50 |
|
50 | 51 | function noop() {}
|
51 | 52 |
|
| 53 | +const skippedSymbol = Symbol("skipped"); |
| 54 | + |
52 | 55 | class NodeTestContext {
|
53 | 56 | #denoContext: Deno.TestContext;
|
| 57 | + #parent: NodeTestContext | undefined; |
| 58 | + #skipped = false; |
54 | 59 |
|
55 |
| - constructor(t: Deno.TestContext) { |
| 60 | + constructor(t: Deno.TestContext, parent: NodeTestContext | undefined) { |
56 | 61 | this.#denoContext = t;
|
| 62 | + this.#parent = parent; |
| 63 | + } |
| 64 | + |
| 65 | + get [skippedSymbol]() { |
| 66 | + return this.#skipped || (this.#parent?.[skippedSymbol] ?? false); |
57 | 67 | }
|
58 | 68 |
|
59 | 69 | get assert() {
|
@@ -86,23 +96,34 @@ class NodeTestContext {
|
86 | 96 | }
|
87 | 97 |
|
88 | 98 | skip() {
|
89 |
| - warnNotImplemented("test.TestContext.skip"); |
| 99 | + this.#skipped = true; |
90 | 100 | return null;
|
91 | 101 | }
|
92 | 102 |
|
93 | 103 | todo() {
|
94 |
| - warnNotImplemented("test.TestContext.todo"); |
| 104 | + this.#skipped = true; |
95 | 105 | return null;
|
96 | 106 | }
|
97 | 107 |
|
98 | 108 | test(name, options, fn) {
|
99 | 109 | const prepared = prepareOptions(name, options, fn, {});
|
| 110 | + // deno-lint-ignore no-this-alias |
| 111 | + const parentContext = this; |
100 | 112 | return PromisePrototypeThen(
|
101 | 113 | this.#denoContext.step({
|
102 | 114 | name: prepared.name,
|
103 | 115 | 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 | + } |
106 | 127 | },
|
107 | 128 | ignore: prepared.options.todo || prepared.options.skip,
|
108 | 129 | sanitizeExit: false,
|
@@ -144,9 +165,20 @@ class TestSuite {
|
144 | 165 | const prepared = prepareOptions(name, options, fn, overrides);
|
145 | 166 | const step = this.#denoTestContext.step({
|
146 | 167 | 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 | + } |
150 | 182 | },
|
151 | 183 | ignore: prepared.options.todo || prepared.options.skip,
|
152 | 184 | sanitizeExit: false,
|
@@ -204,9 +236,13 @@ function prepareOptions(name, options, fn, overrides) {
|
204 | 236 |
|
205 | 237 | function wrapTestFn(fn, resolve) {
|
206 | 238 | return async function (t) {
|
207 |
| - const nodeTestContext = new NodeTestContext(t); |
| 239 | + const nodeTestContext = new NodeTestContext(t, undefined); |
208 | 240 | try {
|
209 | 241 | await fn(nodeTestContext);
|
| 242 | + } catch (err) { |
| 243 | + if (!nodeTestContext[skippedSymbol]) { |
| 244 | + throw err; |
| 245 | + } |
210 | 246 | } finally {
|
211 | 247 | resolve();
|
212 | 248 | }
|
|
0 commit comments