qunitx 1.2.6 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -20
- package/dist/.build-hash +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser/index.d.ts +20 -20
- package/dist/browser/index.js +52 -52
- package/dist/deno/index.d.ts +20 -19
- package/dist/deno/index.js +172 -186
- package/dist/deno/module.d.ts +2 -2
- package/dist/deno/module.js +11 -12
- package/dist/deno/test.d.ts +2 -2
- package/dist/deno/test.js +24 -25
- package/dist/node/index.d.ts +3 -2
- package/dist/node/index.js +1 -1
- package/dist/node/module.js +11 -12
- package/dist/node/test.js +23 -24
- package/dist/shared/assert.d.ts +2 -2
- package/dist/shared/assert.js +89 -55
- package/dist/shared/index.d.ts +1 -13
- package/dist/shared/index.js +11 -13
- package/dist/shared/module-context.d.ts +3 -3
- package/dist/shared/module-context.js +4 -4
- package/dist/shared/test-context.d.ts +10 -18
- package/dist/shared/test-context.js +26 -74
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
- package/shims/deno/index.ts +22 -21
- package/shims/deno/module.ts +15 -15
- package/shims/deno/test.ts +30 -29
- package/shims/shared/assert.ts +92 -56
- package/shims/shared/index.ts +14 -27
- package/shims/shared/module-context.ts +5 -5
- package/shims/shared/test-context.ts +27 -84
- package/shims/types.ts +1 -1
package/dist/deno/module.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { afterAll, beforeAll, describe } from "jsr:@std/testing/bdd";
|
|
2
2
|
import ModuleContext from "../shared/module-context.js";
|
|
3
3
|
function module(moduleName, runtimeOptions, moduleContent) {
|
|
4
4
|
const targetRuntimeOptions = moduleContent ? runtimeOptions : {};
|
|
@@ -8,12 +8,12 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
8
8
|
});
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
const targetModuleContent = moduleContent
|
|
11
|
+
const targetModuleContent = moduleContent ?? runtimeOptions;
|
|
12
12
|
const moduleContext = new ModuleContext(moduleName);
|
|
13
13
|
describe(moduleName, { ...targetRuntimeOptions }, function() {
|
|
14
14
|
const beforeHooks = [];
|
|
15
15
|
const afterHooks = [];
|
|
16
|
-
beforeAll(async
|
|
16
|
+
beforeAll(async () => {
|
|
17
17
|
const firstTest = moduleContext.tests[0];
|
|
18
18
|
const beforeAssert = firstTest ? firstTest.assert : moduleContext.assert;
|
|
19
19
|
for (const hook of beforeHooks) {
|
|
@@ -21,17 +21,16 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
afterAll(async () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const lastTest = moduleContext.tests[moduleContext.tests.length - 1];
|
|
24
|
+
const allAsyncOps = moduleContext.tests.flatMap((t) => t.asyncOps);
|
|
25
|
+
if (allAsyncOps.length > 0) await Promise.all(allAsyncOps);
|
|
26
|
+
const lastTest = moduleContext.tests.at(-1);
|
|
28
27
|
if (lastTest) {
|
|
29
|
-
for (
|
|
30
|
-
await
|
|
28
|
+
for (const hook of afterHooks.toReversed()) {
|
|
29
|
+
await hook.call(lastTest.userContext, lastTest.assert, { context: lastTest.userContext });
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
|
-
for (
|
|
34
|
-
|
|
32
|
+
for (const testCtx of moduleContext.tests) {
|
|
33
|
+
testCtx.finish();
|
|
35
34
|
}
|
|
36
35
|
});
|
|
37
36
|
targetModuleContent.call(moduleContext.userContext, {
|
|
@@ -47,7 +46,7 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
47
46
|
after(afterFn) {
|
|
48
47
|
afterHooks.push(afterFn);
|
|
49
48
|
}
|
|
50
|
-
}, { moduleName, options:
|
|
49
|
+
}, { moduleName, options: targetRuntimeOptions, context: moduleContext.userContext });
|
|
51
50
|
ModuleContext.currentModuleChain.pop();
|
|
52
51
|
});
|
|
53
52
|
}
|
package/dist/deno/test.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type Assert from '../shared/assert.d.ts';
|
|
2
|
-
export type { Assert };
|
|
3
|
-
export type { PushResultInfo } from '../types.d.ts';
|
|
4
2
|
/**
|
|
5
3
|
* Defines an individual test within a module for Deno's BDD test runner.
|
|
6
4
|
*
|
|
@@ -48,3 +46,5 @@ declare namespace test {
|
|
|
48
46
|
var todo: (testName: string, _testContent?: unknown) => void;
|
|
49
47
|
}
|
|
50
48
|
export default test;
|
|
49
|
+
export type { Assert };
|
|
50
|
+
export type { PushResultInfo } from '../types.d.ts';
|
package/dist/deno/test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { it } from "jsr:@std/testing/bdd";
|
|
2
|
-
import TestContext from "../shared/test-context.js";
|
|
3
2
|
import ModuleContext from "../shared/module-context.js";
|
|
3
|
+
import TestContext from "../shared/test-context.js";
|
|
4
4
|
function test(testName, runtimeOptions, testContent) {
|
|
5
5
|
const moduleContext = ModuleContext.lastModule;
|
|
6
6
|
if (!moduleContext) {
|
|
@@ -13,37 +13,36 @@ function test(testName, runtimeOptions, testContent) {
|
|
|
13
13
|
});
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
const targetTestContent = testContent
|
|
16
|
+
const targetTestContent = testContent ?? runtimeOptions;
|
|
17
17
|
const context = new TestContext(testName, moduleContext);
|
|
18
18
|
const userContext = Object.create(moduleContext.userContext);
|
|
19
19
|
context.userContext = userContext;
|
|
20
20
|
it(testName, { ...targetRuntimeOptions }, function() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
21
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
22
|
+
context.rejectTimeout = reject;
|
|
23
|
+
const hookMeta = { context: userContext };
|
|
24
|
+
(async () => {
|
|
25
|
+
try {
|
|
26
|
+
for (const mod of context.module.moduleChain) {
|
|
27
|
+
for (const hook of mod.beforeEachHooks) {
|
|
28
|
+
await hook.call(userContext, context.assert, hookMeta);
|
|
30
29
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
30
|
+
}
|
|
31
|
+
await targetTestContent.call(userContext, context.assert, { testName, options: targetRuntimeOptions, context: userContext });
|
|
32
|
+
await context.assert.waitForAsyncOps();
|
|
33
|
+
for (const mod of context.module.moduleChain.toReversed()) {
|
|
34
|
+
for (const hook of mod.afterEachHooks.toReversed()) {
|
|
35
|
+
await hook.call(userContext, context.assert, hookMeta);
|
|
38
36
|
}
|
|
39
|
-
resolve(result);
|
|
40
|
-
} catch (err) {
|
|
41
|
-
reject(err);
|
|
42
|
-
} finally {
|
|
43
|
-
context.clearTimeoutHandle();
|
|
44
37
|
}
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
resolve();
|
|
39
|
+
} catch (err) {
|
|
40
|
+
reject(err);
|
|
41
|
+
} finally {
|
|
42
|
+
context.clearTimeoutHandle();
|
|
43
|
+
}
|
|
44
|
+
})();
|
|
45
|
+
return promise;
|
|
47
46
|
});
|
|
48
47
|
}
|
|
49
48
|
test.skip = function skipTest(testName, _testContent) {
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import Assert from '../shared/assert.d.ts';
|
|
2
2
|
import Module from './module.d.ts';
|
|
3
3
|
import Test from './test.d.ts';
|
|
4
|
-
export { default as module } from './module.d.ts';
|
|
5
|
-
export { default as test } from './test.d.ts';
|
|
6
4
|
export { Assert };
|
|
5
|
+
export { default as module } from './module.d.ts';
|
|
7
6
|
export declare const skip: (testName: string, _testContent?: unknown) => void;
|
|
7
|
+
export { default as test } from './test.d.ts';
|
|
8
8
|
export declare const todo: (testName: string, testContent?: (assert: Assert, meta: {
|
|
9
9
|
testName: string;
|
|
10
10
|
options: unknown;
|
|
11
11
|
}) => void | Promise<void>) => void;
|
|
12
|
+
export type { HookFn, HooksObject, PushResultInfo, TestFn } from '../types.d.ts';
|
|
12
13
|
declare const _default: {
|
|
13
14
|
AssertionError: import("../types.d.ts").AssertionErrorConstructor;
|
|
14
15
|
module: typeof Module;
|
package/dist/node/index.js
CHANGED
|
@@ -15,8 +15,8 @@ Object.freeze(Assert);
|
|
|
15
15
|
Object.freeze(ModuleContext);
|
|
16
16
|
Object.freeze(TestContext);
|
|
17
17
|
import { default as default2 } from "./module.js";
|
|
18
|
-
import { default as default3 } from "./test.js";
|
|
19
18
|
const skip = Test.skip;
|
|
19
|
+
import { default as default3 } from "./test.js";
|
|
20
20
|
const todo = Test.todo;
|
|
21
21
|
var node_default = { AssertionError: Assert.AssertionError, module: Module, test: Test, config: {} };
|
|
22
22
|
export {
|
package/dist/node/module.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { after as afterAll, before as beforeAll, describe } from "node:test";
|
|
2
2
|
import ModuleContext from "../shared/module-context.js";
|
|
3
3
|
function module(moduleName, runtimeOptions, moduleContent) {
|
|
4
4
|
const targetRuntimeOptions = moduleContent ? runtimeOptions : {};
|
|
@@ -8,12 +8,12 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
8
8
|
});
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
const targetModuleContent = moduleContent
|
|
11
|
+
const targetModuleContent = moduleContent ?? runtimeOptions;
|
|
12
12
|
const moduleContext = new ModuleContext(moduleName);
|
|
13
13
|
describe(moduleName, { ...targetRuntimeOptions }, function() {
|
|
14
14
|
const beforeHooks = [];
|
|
15
15
|
const afterHooks = [];
|
|
16
|
-
beforeAll(async
|
|
16
|
+
beforeAll(async () => {
|
|
17
17
|
const firstTest = moduleContext.tests[0];
|
|
18
18
|
const beforeAssert = firstTest ? firstTest.assert : moduleContext.assert;
|
|
19
19
|
for (const hook of beforeHooks) {
|
|
@@ -21,17 +21,16 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
afterAll(async () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const lastTest = moduleContext.tests[moduleContext.tests.length - 1];
|
|
24
|
+
const allAsyncOps = moduleContext.tests.flatMap((t) => t.asyncOps);
|
|
25
|
+
if (allAsyncOps.length > 0) await Promise.all(allAsyncOps);
|
|
26
|
+
const lastTest = moduleContext.tests.at(-1);
|
|
28
27
|
if (lastTest) {
|
|
29
|
-
for (
|
|
30
|
-
await
|
|
28
|
+
for (const hook of afterHooks.toReversed()) {
|
|
29
|
+
await hook.call(lastTest.userContext, lastTest.assert, { context: lastTest.userContext });
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
|
-
for (
|
|
34
|
-
|
|
32
|
+
for (const testCtx of moduleContext.tests) {
|
|
33
|
+
testCtx.finish();
|
|
35
34
|
}
|
|
36
35
|
});
|
|
37
36
|
targetModuleContent.call(moduleContext.userContext, {
|
|
@@ -47,7 +46,7 @@ function module(moduleName, runtimeOptions, moduleContent) {
|
|
|
47
46
|
after(afterFn) {
|
|
48
47
|
afterHooks.push(afterFn);
|
|
49
48
|
}
|
|
50
|
-
}, { moduleName, options:
|
|
49
|
+
}, { moduleName, options: targetRuntimeOptions, context: moduleContext.userContext });
|
|
51
50
|
ModuleContext.currentModuleChain.pop();
|
|
52
51
|
});
|
|
53
52
|
}
|
package/dist/node/test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { it } from "node:test";
|
|
2
|
-
import TestContext from "../shared/test-context.js";
|
|
3
2
|
import ModuleContext from "../shared/module-context.js";
|
|
3
|
+
import TestContext from "../shared/test-context.js";
|
|
4
4
|
function test(testName, runtimeOptions, testContent) {
|
|
5
5
|
const moduleContext = ModuleContext.lastModule;
|
|
6
6
|
if (!moduleContext) {
|
|
@@ -19,32 +19,31 @@ function test(testName, runtimeOptions, testContent) {
|
|
|
19
19
|
context.userContext = userContext;
|
|
20
20
|
if (todo) moduleContext.tests.pop();
|
|
21
21
|
it(testName, { ...targetRuntimeOptions }, function() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
22
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
23
|
+
context.rejectTimeout = reject;
|
|
24
|
+
const hookMeta = { context: userContext };
|
|
25
|
+
(async () => {
|
|
26
|
+
try {
|
|
27
|
+
for (const mod of context.module.moduleChain) {
|
|
28
|
+
for (const hook of mod.beforeEachHooks) {
|
|
29
|
+
await hook.call(userContext, context.assert, hookMeta);
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
31
|
+
}
|
|
32
|
+
await targetTestContent.call(userContext, context.assert, { testName, options: targetRuntimeOptions, context: userContext });
|
|
33
|
+
await context.assert.waitForAsyncOps();
|
|
34
|
+
for (const mod of context.module.moduleChain.toReversed()) {
|
|
35
|
+
for (const hook of mod.afterEachHooks.toReversed()) {
|
|
36
|
+
await hook.call(userContext, context.assert, hookMeta);
|
|
39
37
|
}
|
|
40
|
-
resolve(result);
|
|
41
|
-
} catch (err) {
|
|
42
|
-
reject(err);
|
|
43
|
-
} finally {
|
|
44
|
-
context.clearTimeoutHandle();
|
|
45
38
|
}
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
resolve();
|
|
40
|
+
} catch (err) {
|
|
41
|
+
reject(err);
|
|
42
|
+
} finally {
|
|
43
|
+
context.clearTimeoutHandle();
|
|
44
|
+
}
|
|
45
|
+
})();
|
|
46
|
+
return promise;
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
49
|
test.skip = function skipTest(testName, _testContent) {
|
package/dist/shared/assert.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../../vendor/qunit.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AssertionErrorConstructor, InspectFn, ModuleState, PushResultInfo, QUnitObject, TestState } from '../types.d.ts';
|
|
3
3
|
/**
|
|
4
4
|
* The assertion object passed to every test callback and lifecycle hook.
|
|
5
5
|
*
|
|
@@ -31,7 +31,7 @@ export default class Assert {
|
|
|
31
31
|
/** @internal */
|
|
32
32
|
constructor(module: ModuleState | null, test?: TestState);
|
|
33
33
|
/** @internal */
|
|
34
|
-
_incrementAssertionCount
|
|
34
|
+
private _incrementAssertionCount;
|
|
35
35
|
/**
|
|
36
36
|
* Sets the number of milliseconds after which the current test will fail if not yet complete.
|
|
37
37
|
*
|
package/dist/shared/assert.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "../../vendor/qunit.js";
|
|
2
|
-
import { objectValues, objectValuesSubset,
|
|
2
|
+
import { objectValues, objectValuesSubset, validateException, validateExpectedExceptionArgs } from "./index.js";
|
|
3
|
+
const PENDING = /* @__PURE__ */ Symbol("pending");
|
|
3
4
|
class Assert {
|
|
4
5
|
/** @internal Set by each runtime shim before tests run. */
|
|
5
6
|
static QUnit;
|
|
@@ -11,7 +12,7 @@ class Assert {
|
|
|
11
12
|
test;
|
|
12
13
|
/** @internal */
|
|
13
14
|
constructor(module, test) {
|
|
14
|
-
this.test = test || module.
|
|
15
|
+
this.test = test || module.testContext;
|
|
15
16
|
}
|
|
16
17
|
/** @internal */
|
|
17
18
|
_incrementAssertionCount() {
|
|
@@ -53,19 +54,10 @@ class Assert {
|
|
|
53
54
|
* ```
|
|
54
55
|
*/
|
|
55
56
|
step(message) {
|
|
56
|
-
let assertionMessage = message;
|
|
57
|
-
let result = !!message;
|
|
58
57
|
this.test.steps.push(message);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
assertionMessage = "You must provide a string value to assert.step";
|
|
63
|
-
result = false;
|
|
64
|
-
}
|
|
65
|
-
this.pushResult({
|
|
66
|
-
result,
|
|
67
|
-
message: assertionMessage
|
|
68
|
-
});
|
|
58
|
+
const result = typeof message === "string" && message.length > 0;
|
|
59
|
+
const assertionMessage = result ? message : message === void 0 || message === "" ? "You must provide a message to assert.step" : "You must provide a string value to assert.step";
|
|
60
|
+
this.pushResult({ result, message: assertionMessage });
|
|
69
61
|
}
|
|
70
62
|
/**
|
|
71
63
|
* Asserts that the steps recorded via {@linkcode Assert.prototype.step} match the given array,
|
|
@@ -125,14 +117,9 @@ class Assert {
|
|
|
125
117
|
* ```
|
|
126
118
|
*/
|
|
127
119
|
async() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
this.test.asyncOps.push(done);
|
|
133
|
-
return () => {
|
|
134
|
-
resolveFn();
|
|
135
|
-
};
|
|
120
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
121
|
+
this.test.asyncOps.push(promise);
|
|
122
|
+
return resolve;
|
|
136
123
|
}
|
|
137
124
|
/** @internal Used by the test runner to wait for all async operations to complete. */
|
|
138
125
|
waitForAsyncOps() {
|
|
@@ -280,7 +267,7 @@ class Assert {
|
|
|
280
267
|
throw new Assert.AssertionError({
|
|
281
268
|
actual,
|
|
282
269
|
expected,
|
|
283
|
-
message: message || `
|
|
270
|
+
message: message || `Values are not equal:${formatDiff(actual, expected)}`,
|
|
284
271
|
operator: "==",
|
|
285
272
|
stackStartFn: this.equal
|
|
286
273
|
});
|
|
@@ -305,7 +292,7 @@ class Assert {
|
|
|
305
292
|
actual,
|
|
306
293
|
expected,
|
|
307
294
|
operator: "!=",
|
|
308
|
-
message: message || `
|
|
295
|
+
message: message || `Values are unexpectedly equal:${formatUnexpectedMatch(actual)}`,
|
|
309
296
|
stackStartFn: this.notEqual
|
|
310
297
|
});
|
|
311
298
|
}
|
|
@@ -334,7 +321,7 @@ class Assert {
|
|
|
334
321
|
throw new Assert.AssertionError({
|
|
335
322
|
actual: targetActual,
|
|
336
323
|
expected: targetExpected,
|
|
337
|
-
message: message || `
|
|
324
|
+
message: message || `Own properties are not equal:${formatDiff(targetActual, targetExpected)}`,
|
|
338
325
|
stackStartFn: this.propEqual
|
|
339
326
|
});
|
|
340
327
|
}
|
|
@@ -360,7 +347,7 @@ class Assert {
|
|
|
360
347
|
throw new Assert.AssertionError({
|
|
361
348
|
actual: targetActual,
|
|
362
349
|
expected: targetExpected,
|
|
363
|
-
message: message || `
|
|
350
|
+
message: message || `Own properties are unexpectedly equal:${formatUnexpectedMatch(targetActual)}`,
|
|
364
351
|
stackStartFn: this.notPropEqual
|
|
365
352
|
});
|
|
366
353
|
}
|
|
@@ -386,7 +373,7 @@ class Assert {
|
|
|
386
373
|
throw new Assert.AssertionError({
|
|
387
374
|
actual: targetActual,
|
|
388
375
|
expected: targetExpected,
|
|
389
|
-
message: message || `
|
|
376
|
+
message: message || `Object does not contain expected properties:${formatDiff(targetActual, targetExpected)}`,
|
|
390
377
|
stackStartFn: this.propContains
|
|
391
378
|
});
|
|
392
379
|
}
|
|
@@ -412,7 +399,7 @@ class Assert {
|
|
|
412
399
|
throw new Assert.AssertionError({
|
|
413
400
|
actual: targetActual,
|
|
414
401
|
expected: targetExpected,
|
|
415
|
-
message: message || `
|
|
402
|
+
message: message || `Object unexpectedly contains all expected properties:${formatUnexpectedMatch(targetActual)}`,
|
|
416
403
|
stackStartFn: this.notPropContains
|
|
417
404
|
});
|
|
418
405
|
}
|
|
@@ -436,7 +423,7 @@ class Assert {
|
|
|
436
423
|
throw new Assert.AssertionError({
|
|
437
424
|
actual,
|
|
438
425
|
expected,
|
|
439
|
-
message: message || `
|
|
426
|
+
message: message || `Values are not deeply equal:${formatDiff(actual, expected)}`,
|
|
440
427
|
operator: "deepEqual",
|
|
441
428
|
stackStartFn: this.deepEqual
|
|
442
429
|
});
|
|
@@ -460,7 +447,7 @@ class Assert {
|
|
|
460
447
|
throw new Assert.AssertionError({
|
|
461
448
|
actual,
|
|
462
449
|
expected,
|
|
463
|
-
message: message || `
|
|
450
|
+
message: message || `Values are unexpectedly deeply equal:${formatUnexpectedMatch(actual)}`,
|
|
464
451
|
operator: "notDeepEqual",
|
|
465
452
|
stackStartFn: this.notDeepEqual
|
|
466
453
|
});
|
|
@@ -484,7 +471,7 @@ class Assert {
|
|
|
484
471
|
throw new Assert.AssertionError({
|
|
485
472
|
actual,
|
|
486
473
|
expected,
|
|
487
|
-
message: message || `
|
|
474
|
+
message: message || `Values are not strictly equal:${formatDiff(actual, expected)}`,
|
|
488
475
|
operator: "strictEqual",
|
|
489
476
|
stackStartFn: this.strictEqual
|
|
490
477
|
});
|
|
@@ -508,7 +495,7 @@ class Assert {
|
|
|
508
495
|
throw new Assert.AssertionError({
|
|
509
496
|
actual,
|
|
510
497
|
expected,
|
|
511
|
-
message: message || `
|
|
498
|
+
message: message || `Values are unexpectedly strictly equal:${formatUnexpectedMatch(actual)}`,
|
|
512
499
|
operator: "notStrictEqual",
|
|
513
500
|
stackStartFn: this.notStrictEqual
|
|
514
501
|
});
|
|
@@ -530,7 +517,7 @@ class Assert {
|
|
|
530
517
|
* ```
|
|
531
518
|
*/
|
|
532
519
|
throws(blockFn, expectedInput, assertionMessage) {
|
|
533
|
-
this
|
|
520
|
+
this._incrementAssertionCount();
|
|
534
521
|
const [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, "throws");
|
|
535
522
|
if (typeof blockFn !== "function") {
|
|
536
523
|
throw new Assert.AssertionError({
|
|
@@ -540,20 +527,31 @@ class Assert {
|
|
|
540
527
|
stackStartFn: this.throws
|
|
541
528
|
});
|
|
542
529
|
}
|
|
530
|
+
let returnValue;
|
|
543
531
|
try {
|
|
544
|
-
blockFn();
|
|
532
|
+
returnValue = blockFn();
|
|
545
533
|
} catch (error) {
|
|
546
|
-
const [result,
|
|
534
|
+
const [result, , validatedMessage] = validateException(error, expected, message);
|
|
547
535
|
if (result === false) {
|
|
536
|
+
const expectedDesc = describeExpected(expected);
|
|
537
|
+
const receivedDesc = String(error);
|
|
548
538
|
throw new Assert.AssertionError({
|
|
549
|
-
actual:
|
|
550
|
-
expected:
|
|
551
|
-
message: validatedMessage,
|
|
539
|
+
actual: receivedDesc,
|
|
540
|
+
expected: expectedDesc,
|
|
541
|
+
message: validatedMessage || throwsFailMessage("throws", expectedDesc, receivedDesc),
|
|
552
542
|
stackStartFn: this.throws
|
|
553
543
|
});
|
|
554
544
|
}
|
|
555
545
|
return;
|
|
556
546
|
}
|
|
547
|
+
if (returnValue !== null && typeof returnValue === "object" && typeof returnValue.then === "function") {
|
|
548
|
+
throw new Assert.AssertionError({
|
|
549
|
+
actual: returnValue,
|
|
550
|
+
expected,
|
|
551
|
+
message: "Function passed to `assert.throws` returned a Promise \u2014 did you mean to use `assert.rejects`?",
|
|
552
|
+
stackStartFn: this.throws
|
|
553
|
+
});
|
|
554
|
+
}
|
|
557
555
|
throw new Assert.AssertionError({
|
|
558
556
|
actual: blockFn,
|
|
559
557
|
expected,
|
|
@@ -588,15 +586,13 @@ class Assert {
|
|
|
588
586
|
stackStartFn: this.rejects
|
|
589
587
|
});
|
|
590
588
|
}
|
|
591
|
-
let
|
|
592
|
-
let rejectionError;
|
|
589
|
+
let caught = PENDING;
|
|
593
590
|
try {
|
|
594
591
|
await promise;
|
|
595
592
|
} catch (error) {
|
|
596
|
-
|
|
597
|
-
rejectionError = error;
|
|
593
|
+
caught = error;
|
|
598
594
|
}
|
|
599
|
-
if (
|
|
595
|
+
if (caught === PENDING) {
|
|
600
596
|
throw new Assert.AssertionError({
|
|
601
597
|
actual: promise,
|
|
602
598
|
expected,
|
|
@@ -604,29 +600,67 @@ class Assert {
|
|
|
604
600
|
stackStartFn: this.rejects
|
|
605
601
|
});
|
|
606
602
|
}
|
|
607
|
-
const [result,
|
|
603
|
+
const [result, , validatedMessage] = validateException(caught, expected, message);
|
|
608
604
|
if (result === false) {
|
|
605
|
+
const expectedDesc = describeExpected(expected);
|
|
606
|
+
const receivedDesc = String(caught);
|
|
609
607
|
throw new Assert.AssertionError({
|
|
610
|
-
actual:
|
|
611
|
-
expected:
|
|
612
|
-
message: validatedMessage,
|
|
608
|
+
actual: receivedDesc,
|
|
609
|
+
expected: expectedDesc,
|
|
610
|
+
message: validatedMessage || throwsFailMessage("rejects", expectedDesc, receivedDesc),
|
|
613
611
|
stackStartFn: this.rejects
|
|
614
612
|
});
|
|
615
613
|
}
|
|
616
614
|
}
|
|
617
615
|
}
|
|
618
|
-
;
|
|
619
|
-
|
|
620
|
-
|
|
616
|
+
const INSPECT_OPTIONS = { depth: 10, colors: true, compact: false };
|
|
617
|
+
const inspect = (value) => Assert.inspect(value, INSPECT_OPTIONS);
|
|
618
|
+
function formatDiff(actual, expected) {
|
|
619
|
+
const aStr = inspect(actual), bStr = inspect(expected);
|
|
620
|
+
const aLines = aStr.split("\n"), bLines = bStr.split("\n");
|
|
621
|
+
if (aLines.length === 1 && bLines.length === 1) return `
|
|
621
622
|
|
|
622
|
-
${
|
|
623
|
+
Actual: ${aStr}
|
|
624
|
+
Expected: ${bStr}`;
|
|
625
|
+
const lines = lcsDiff(aLines, bLines).map(
|
|
626
|
+
([t, line]) => t === "=" ? ` ${line}` : t === "-" ? `- ${line}` : `+ ${line}`
|
|
627
|
+
);
|
|
628
|
+
return `
|
|
623
629
|
|
|
624
|
-
|
|
630
|
+
- Actual + Expected
|
|
625
631
|
|
|
626
|
-
${
|
|
632
|
+
${lines.join("\n")}`;
|
|
627
633
|
}
|
|
628
|
-
|
|
629
|
-
|
|
634
|
+
const formatUnexpectedMatch = (actual) => `
|
|
635
|
+
|
|
636
|
+
${inspect(actual)}`;
|
|
637
|
+
const describeExpected = (expected) => expected == null ? "(no pattern)" : typeof expected === "string" ? expected : typeof expected === "function" ? expected.name || String(expected) : String(expected);
|
|
638
|
+
const throwsFailMessage = (method, pattern, received) => `assert.${method}: thrown error did not match expected:
|
|
639
|
+
|
|
640
|
+
Pattern: ${pattern}
|
|
641
|
+
Received: ${received}`;
|
|
642
|
+
function lcsDiff(a, b) {
|
|
643
|
+
const m = a.length, n = b.length;
|
|
644
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
645
|
+
for (let i2 = 1; i2 <= m; i2++)
|
|
646
|
+
for (let j2 = 1; j2 <= n; j2++)
|
|
647
|
+
dp[i2][j2] = a[i2 - 1] === b[j2 - 1] ? dp[i2 - 1][j2 - 1] + 1 : Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
648
|
+
const result = [];
|
|
649
|
+
let i = m, j = n;
|
|
650
|
+
while (i > 0 || j > 0) {
|
|
651
|
+
if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {
|
|
652
|
+
result.push(["=", a[i - 1]]);
|
|
653
|
+
i--;
|
|
654
|
+
j--;
|
|
655
|
+
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
656
|
+
result.push(["+", b[j - 1]]);
|
|
657
|
+
j--;
|
|
658
|
+
} else {
|
|
659
|
+
result.push(["-", a[i - 1]]);
|
|
660
|
+
i--;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return result.reverse();
|
|
630
664
|
}
|
|
631
665
|
export {
|
|
632
666
|
Assert as default
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
export declare function objectType(obj: unknown): string;
|
|
2
2
|
export declare function objectValues(obj: unknown, allowArray?: boolean): unknown;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
4
|
* Recursively clone an object into a plain object, taking only the
|
|
6
|
-
* subset of own enumerable properties that exist a given model.
|
|
7
|
-
*
|
|
8
|
-
* @param {any} obj
|
|
9
|
-
* @param {any} model
|
|
10
|
-
* @return {Object}
|
|
5
|
+
* subset of own enumerable properties that exist in a given model.
|
|
11
6
|
*/
|
|
12
7
|
export declare function objectValuesSubset(obj: unknown, model: unknown): unknown;
|
|
13
8
|
export declare function validateExpectedExceptionArgs(expected: unknown, message: string | undefined, assertionMethod: string): [unknown, string | undefined];
|
|
14
9
|
export declare function validateException(actual: unknown, expected: unknown, message: string | undefined): [boolean, unknown, string | undefined];
|
|
15
|
-
declare const _default: {
|
|
16
|
-
objectValues: typeof objectValues;
|
|
17
|
-
objectValuesSubset: typeof objectValuesSubset;
|
|
18
|
-
validateExpectedExceptionArgs: typeof validateExpectedExceptionArgs;
|
|
19
|
-
validateException: typeof validateException;
|
|
20
|
-
};
|
|
21
|
-
export default _default;
|