@executablemd/testing 0.3.1
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/LICENSE +21 -0
- package/esm/core/mod.js +55 -0
- package/esm/core/src/api.js +31 -0
- package/esm/core/src/collect.js +24 -0
- package/esm/core/src/component-api.js +47 -0
- package/esm/core/src/content-context.js +23 -0
- package/esm/core/src/deno-compiler.js +51 -0
- package/esm/core/src/errors.js +13 -0
- package/esm/core/src/eval-context.js +13 -0
- package/esm/core/src/eval-handler.js +79 -0
- package/esm/core/src/eval-interpolate.js +63 -0
- package/esm/core/src/eval-transform.js +378 -0
- package/esm/core/src/execute.js +378 -0
- package/esm/core/src/expand.js +988 -0
- package/esm/core/src/frontmatter.js +98 -0
- package/esm/core/src/heal.js +29 -0
- package/esm/core/src/interpolate.js +39 -0
- package/esm/core/src/modifiers/daemon.js +60 -0
- package/esm/core/src/modifiers/persist.js +35 -0
- package/esm/core/src/modifiers/timeout.js +55 -0
- package/esm/core/src/modifiers.js +113 -0
- package/esm/core/src/output/normalize.js +33 -0
- package/esm/core/src/output/terminal.js +20 -0
- package/esm/core/src/render.js +30 -0
- package/esm/core/src/replay-stream.js +58 -0
- package/esm/core/src/sample-api.js +45 -0
- package/esm/core/src/scanner.js +632 -0
- package/esm/core/src/temp-file-compiler.js +68 -0
- package/esm/core/src/types.js +7 -0
- package/esm/core/src/validate.js +82 -0
- package/esm/durable-streams/combinators.js +227 -0
- package/esm/durable-streams/context.js +13 -0
- package/esm/durable-streams/divergence.js +56 -0
- package/esm/durable-streams/each.js +193 -0
- package/esm/durable-streams/effect.js +273 -0
- package/esm/durable-streams/ephemeral.js +80 -0
- package/esm/durable-streams/errors.js +92 -0
- package/esm/durable-streams/http-stream.js +207 -0
- package/esm/durable-streams/mod.js +34 -0
- package/esm/durable-streams/operations.js +88 -0
- package/esm/durable-streams/replay-guard.js +87 -0
- package/esm/durable-streams/replay-index.js +132 -0
- package/esm/durable-streams/run.js +137 -0
- package/esm/durable-streams/serialize.js +65 -0
- package/esm/durable-streams/stream.js +56 -0
- package/esm/durable-streams/types.js +10 -0
- package/esm/package.json +3 -0
- package/esm/runtime/apis.js +237 -0
- package/esm/runtime/find-free-port.js +33 -0
- package/esm/runtime/mod.js +20 -0
- package/esm/testing/npm/src/_dnt.polyfills.js +1 -0
- package/esm/testing/npm/src/_dnt.shims.js +57 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +47 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/array_includes.js +65 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/assert.js +23 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +30 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/equal.js +194 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/equals.js +61 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/exists.js +27 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/fail.js +20 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/false.js +23 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/greater.js +29 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +29 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/instance_of.js +52 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/is_error.js +53 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/less.js +28 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +29 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/match.js +26 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/mod.js +45 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_equals.js +39 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +29 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_match.js +26 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +32 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/object_match.js +177 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/rejects.js +53 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +58 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/string_includes.js +26 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/throws.js +44 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +20 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/unreachable.js +20 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/build_message.js +116 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/diff.js +277 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/diff_str.js +181 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/format.js +70 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/styles.js +207 -0
- package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/types.js +3 -0
- package/esm/testing/npm/src/mod.js +27 -0
- package/esm/testing/npm/src/src/assertions.js +250 -0
- package/esm/testing/npm/src/src/handlers.js +245 -0
- package/esm/testing/npm/src/src/journal.js +152 -0
- package/esm/testing/npm/src/src/test-api.js +33 -0
- package/esm/testing/npm/src/src/use-testing.js +79 -0
- package/esm/testing/npm/src/src/vocabulary.js +111 -0
- package/package.json +35 -0
- package/types/_dnt.polyfills.d.ts +6 -0
- package/types/_dnt.shims.d.ts +1 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +29 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +28 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +16 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +25 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +24 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +36 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +17 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +14 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/false.d.ts +18 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +19 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +19 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +22 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +24 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/less.d.ts +18 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +19 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/match.d.ts +17 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +43 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +26 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +19 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +17 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +22 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +28 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +41 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +23 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +17 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +44 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +14 -0
- package/types/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +14 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +79 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +139 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +98 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/format.d.ts +28 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +158 -0
- package/types/deps/jsr.io/@std/internal/1.0.14/types.d.ts +24 -0
- package/types/mod.d.ts +29 -0
- package/types/src/assertions.d.ts +55 -0
- package/types/src/handlers.d.ts +18 -0
- package/types/src/journal.d.ts +29 -0
- package/types/src/test-api.d.ts +54 -0
- package/types/src/use-testing.d.ts +25 -0
- package/types/src/vocabulary.d.ts +34 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { assertFalse } from "./false.js";
|
|
4
|
+
/**
|
|
5
|
+
* Make an assertion that `obj` is not an instance of `type`.
|
|
6
|
+
* If so, then throw.
|
|
7
|
+
*
|
|
8
|
+
* @example Usage
|
|
9
|
+
* ```ts ignore
|
|
10
|
+
* import { assertNotInstanceOf } from "@std/assert";
|
|
11
|
+
*
|
|
12
|
+
* assertNotInstanceOf(new Date(), Number); // Doesn't throw
|
|
13
|
+
* assertNotInstanceOf(new Date(), Date); // Throws
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @typeParam A The type of the object to check.
|
|
17
|
+
* @typeParam T The type of the class to check against.
|
|
18
|
+
* @param actual The object to check.
|
|
19
|
+
* @param unexpectedType The class constructor to check against.
|
|
20
|
+
* @param msg The optional message to display if the assertion fails.
|
|
21
|
+
*/
|
|
22
|
+
export function assertNotInstanceOf(actual,
|
|
23
|
+
// deno-lint-ignore no-explicit-any
|
|
24
|
+
unexpectedType, msg) {
|
|
25
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
26
|
+
msg =
|
|
27
|
+
`Expected object to not be an instance of "${typeof unexpectedType}"${msgSuffix}`;
|
|
28
|
+
assertFalse(actual instanceof unexpectedType, msg);
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
/**
|
|
5
|
+
* Make an assertion that `actual` not match RegExp `expected`. If match
|
|
6
|
+
* then throw.
|
|
7
|
+
*
|
|
8
|
+
* @example Usage
|
|
9
|
+
* ```ts ignore
|
|
10
|
+
* import { assertNotMatch } from "@std/assert";
|
|
11
|
+
*
|
|
12
|
+
* assertNotMatch("Denosaurus", /Raptor/); // Doesn't throw
|
|
13
|
+
* assertNotMatch("Raptor", /Raptor/); // Throws
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param actual The actual value to match.
|
|
17
|
+
* @param expected The expected value to not match.
|
|
18
|
+
* @param msg The optional message to display if the assertion fails.
|
|
19
|
+
*/
|
|
20
|
+
export function assertNotMatch(actual, expected, msg) {
|
|
21
|
+
if (!expected.test(actual))
|
|
22
|
+
return;
|
|
23
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
24
|
+
msg = `Expected actual: "${actual}" to not match: "${expected}"${msgSuffix}`;
|
|
25
|
+
throw new AssertionError(msg);
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
import { format } from "../../internal/1.0.14/format.js";
|
|
5
|
+
/**
|
|
6
|
+
* Make an assertion that `actual` and `expected` are not strictly equal, using
|
|
7
|
+
* {@linkcode Object.is} for equality comparison. If the values are strictly
|
|
8
|
+
* equal then throw.
|
|
9
|
+
*
|
|
10
|
+
* @example Usage
|
|
11
|
+
* ```ts ignore
|
|
12
|
+
* import { assertNotStrictEquals } from "@std/assert";
|
|
13
|
+
*
|
|
14
|
+
* assertNotStrictEquals(1, 1); // Throws
|
|
15
|
+
* assertNotStrictEquals(1, 2); // Doesn't throw
|
|
16
|
+
*
|
|
17
|
+
* assertNotStrictEquals(0, 0); // Throws
|
|
18
|
+
* assertNotStrictEquals(0, -0); // Doesn't throw
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @typeParam T The type of the values to compare.
|
|
22
|
+
* @param actual The actual value to compare.
|
|
23
|
+
* @param expected The expected value to compare.
|
|
24
|
+
* @param msg The optional message to display if the assertion fails.
|
|
25
|
+
*/
|
|
26
|
+
export function assertNotStrictEquals(actual, expected, msg) {
|
|
27
|
+
if (!Object.is(actual, expected)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
31
|
+
throw new AssertionError(`Expected "actual" to not be strictly equal to: ${format(actual)}${msgSuffix}\n`);
|
|
32
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { assertEquals } from "./equals.js";
|
|
4
|
+
/**
|
|
5
|
+
* Make an assertion that `expected` object is a subset of `actual` object,
|
|
6
|
+
* deeply. If not, then throw a diff of the objects, with mismatching
|
|
7
|
+
* properties highlighted.
|
|
8
|
+
*
|
|
9
|
+
* @example Usage
|
|
10
|
+
* ```ts ignore
|
|
11
|
+
* import { assertObjectMatch } from "@std/assert";
|
|
12
|
+
*
|
|
13
|
+
* assertObjectMatch({ foo: "bar" }, { foo: "bar" }); // Doesn't throw
|
|
14
|
+
* assertObjectMatch({ foo: "bar" }, { foo: "baz" }); // Throws
|
|
15
|
+
* assertObjectMatch({ foo: 1, bar: 2 }, { foo: 1 }); // Doesn't throw
|
|
16
|
+
* assertObjectMatch({ foo: 1 }, { foo: 1, bar: 2 }); // Throws
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Usage with nested objects
|
|
20
|
+
* ```ts ignore
|
|
21
|
+
* import { assertObjectMatch } from "@std/assert";
|
|
22
|
+
*
|
|
23
|
+
* assertObjectMatch({ foo: { bar: 3, baz: 4 } }, { foo: { bar: 3 } }); // Doesn't throw
|
|
24
|
+
* assertObjectMatch({ foo: { bar: 3 } }, { foo: { bar: 3, baz: 4 } }); // Throws
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @param actual The actual value to be matched.
|
|
28
|
+
* @param expected The expected value to match.
|
|
29
|
+
* @param msg The optional message to display if the assertion fails.
|
|
30
|
+
*/
|
|
31
|
+
export function assertObjectMatch(
|
|
32
|
+
// deno-lint-ignore no-explicit-any
|
|
33
|
+
actual, expected, msg) {
|
|
34
|
+
return assertEquals(
|
|
35
|
+
// get the intersection of "actual" and "expected"
|
|
36
|
+
// side effect: all the instances' constructor field is "Object" now.
|
|
37
|
+
filter(actual, expected),
|
|
38
|
+
// set (nested) instances' constructor field to be "Object" without changing expected value.
|
|
39
|
+
// see https://github.com/denoland/std/pull/1419
|
|
40
|
+
filter(expected, expected), msg);
|
|
41
|
+
}
|
|
42
|
+
function isObject(val) {
|
|
43
|
+
return typeof val === "object" && val !== null;
|
|
44
|
+
}
|
|
45
|
+
function defineProperty(target, key, value) {
|
|
46
|
+
return Object.defineProperty(target, key, {
|
|
47
|
+
value,
|
|
48
|
+
configurable: true,
|
|
49
|
+
enumerable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function filter(a, b) {
|
|
54
|
+
const seen = new WeakMap();
|
|
55
|
+
return filterObject(a, b);
|
|
56
|
+
function filterObject(a, b) {
|
|
57
|
+
// Prevent infinite loop with circular references with same filter
|
|
58
|
+
const memo = seen.get(a);
|
|
59
|
+
if (memo && (memo === b))
|
|
60
|
+
return a;
|
|
61
|
+
try {
|
|
62
|
+
seen.set(a, b);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (err instanceof TypeError) {
|
|
66
|
+
throw new TypeError(`Cannot assertObjectMatch ${a === null ? null : `type ${typeof a}`}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Filter keys and symbols which are present in both actual and expected
|
|
70
|
+
const filtered = {};
|
|
71
|
+
const keysA = Reflect.ownKeys(a);
|
|
72
|
+
const keysB = Reflect.ownKeys(b);
|
|
73
|
+
const entries = keysA.filter((key) => keysB.includes(key))
|
|
74
|
+
.map((key) => [key, a[key]]);
|
|
75
|
+
if (keysA.length && keysB.length && !entries.length) {
|
|
76
|
+
// If both objects are not empty but don't have the same keys or symbols,
|
|
77
|
+
// returns the entries in object a.
|
|
78
|
+
for (const key of keysA)
|
|
79
|
+
defineProperty(filtered, key, a[key]);
|
|
80
|
+
return filtered;
|
|
81
|
+
}
|
|
82
|
+
for (const [key, value] of entries) {
|
|
83
|
+
// On regexp references, keep value as it to avoid losing pattern and flags
|
|
84
|
+
if (value instanceof RegExp) {
|
|
85
|
+
defineProperty(filtered, key, value);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// On date references, keep value as it to avoid losing the timestamp
|
|
89
|
+
if (value instanceof Date) {
|
|
90
|
+
defineProperty(filtered, key, value);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const subset = b[key];
|
|
94
|
+
// On array references, build a filtered array and filter nested objects inside
|
|
95
|
+
if (Array.isArray(value) && Array.isArray(subset)) {
|
|
96
|
+
defineProperty(filtered, key, filterArray(value, subset));
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// On nested objects references, build a filtered object recursively
|
|
100
|
+
if (isObject(value) && isObject(subset)) {
|
|
101
|
+
// When both operands are maps, build a filtered map with common keys and filter nested objects inside
|
|
102
|
+
if ((value instanceof Map) && (subset instanceof Map)) {
|
|
103
|
+
defineProperty(filtered, key, new Map([...value].filter(([k]) => subset.has(k)).map(([k, v]) => {
|
|
104
|
+
const v2 = subset.get(k);
|
|
105
|
+
if (isObject(v) && isObject(v2)) {
|
|
106
|
+
return [k, filterObject(v, v2)];
|
|
107
|
+
}
|
|
108
|
+
return [k, v];
|
|
109
|
+
})));
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// When both operands are set, build a filtered set with common values
|
|
113
|
+
if ((value instanceof Set) && (subset instanceof Set)) {
|
|
114
|
+
defineProperty(filtered, key, value.intersection(subset));
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
defineProperty(filtered, key, filterObject(value, subset));
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
defineProperty(filtered, key, value);
|
|
121
|
+
}
|
|
122
|
+
return filtered;
|
|
123
|
+
}
|
|
124
|
+
function filterArray(a, b) {
|
|
125
|
+
// Prevent infinite loop with circular references with same filter
|
|
126
|
+
const memo = seen.get(a);
|
|
127
|
+
if (memo && (memo === b))
|
|
128
|
+
return a;
|
|
129
|
+
seen.set(a, b);
|
|
130
|
+
const filtered = [];
|
|
131
|
+
const count = Math.min(a.length, b.length);
|
|
132
|
+
for (let i = 0; i < count; ++i) {
|
|
133
|
+
const value = a[i];
|
|
134
|
+
const subset = b[i];
|
|
135
|
+
// On regexp references, keep value as it to avoid losing pattern and flags
|
|
136
|
+
if (value instanceof RegExp) {
|
|
137
|
+
filtered.push(value);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
// On date references, keep value as it to avoid losing the timestamp
|
|
141
|
+
if (value instanceof Date) {
|
|
142
|
+
filtered.push(value);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// On array references, build a filtered array and filter nested objects inside
|
|
146
|
+
if (Array.isArray(value) && Array.isArray(subset)) {
|
|
147
|
+
filtered.push(filterArray(value, subset));
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// On nested objects references, build a filtered object recursively
|
|
151
|
+
if (isObject(value) && isObject(subset)) {
|
|
152
|
+
// When both operands are maps, build a filtered map with common keys and filter nested objects inside
|
|
153
|
+
if ((value instanceof Map) && (subset instanceof Map)) {
|
|
154
|
+
const map = new Map([...value].filter(([k]) => subset.has(k))
|
|
155
|
+
.map(([k, v]) => {
|
|
156
|
+
const v2 = subset.get(k);
|
|
157
|
+
if (isObject(v) && isObject(v2)) {
|
|
158
|
+
return [k, filterObject(v, v2)];
|
|
159
|
+
}
|
|
160
|
+
return [k, v];
|
|
161
|
+
}));
|
|
162
|
+
filtered.push(map);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// When both operands are set, build a filtered set with common values
|
|
166
|
+
if ((value instanceof Set) && (subset instanceof Set)) {
|
|
167
|
+
filtered.push(value.intersection(subset));
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
filtered.push(filterObject(value, subset));
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
filtered.push(value);
|
|
174
|
+
}
|
|
175
|
+
return filtered;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
import { assertIsError } from "./is_error.js";
|
|
5
|
+
export async function assertRejects(fn, errorClassOrMsg, msgIncludesOrMsg, msg) {
|
|
6
|
+
// deno-lint-ignore no-explicit-any
|
|
7
|
+
let ErrorClass;
|
|
8
|
+
let msgIncludes;
|
|
9
|
+
let err;
|
|
10
|
+
if (typeof errorClassOrMsg !== "string") {
|
|
11
|
+
if (errorClassOrMsg === undefined ||
|
|
12
|
+
errorClassOrMsg.prototype instanceof Error ||
|
|
13
|
+
errorClassOrMsg.prototype === Error.prototype) {
|
|
14
|
+
ErrorClass = errorClassOrMsg;
|
|
15
|
+
msgIncludes = msgIncludesOrMsg;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
msg = errorClassOrMsg;
|
|
20
|
+
}
|
|
21
|
+
let doesThrow = false;
|
|
22
|
+
let isPromiseReturned = false;
|
|
23
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
24
|
+
try {
|
|
25
|
+
const possiblePromise = fn();
|
|
26
|
+
if (possiblePromise &&
|
|
27
|
+
typeof possiblePromise === "object" &&
|
|
28
|
+
typeof possiblePromise.then === "function") {
|
|
29
|
+
isPromiseReturned = true;
|
|
30
|
+
await possiblePromise;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (!isPromiseReturned) {
|
|
38
|
+
throw new AssertionError(`Function throws when expected to reject${msgSuffix}`);
|
|
39
|
+
}
|
|
40
|
+
if (ErrorClass) {
|
|
41
|
+
if (!(error instanceof Error)) {
|
|
42
|
+
throw new AssertionError(`A non-Error object was rejected${msgSuffix}`);
|
|
43
|
+
}
|
|
44
|
+
assertIsError(error, ErrorClass, msgIncludes, msg);
|
|
45
|
+
}
|
|
46
|
+
err = error;
|
|
47
|
+
doesThrow = true;
|
|
48
|
+
}
|
|
49
|
+
if (!doesThrow) {
|
|
50
|
+
throw new AssertionError(`Expected function to reject${msgSuffix}`);
|
|
51
|
+
}
|
|
52
|
+
return err;
|
|
53
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { buildMessage } from "../../internal/1.0.14/build_message.js";
|
|
4
|
+
import { diff } from "../../internal/1.0.14/diff.js";
|
|
5
|
+
import { diffStr } from "../../internal/1.0.14/diff_str.js";
|
|
6
|
+
import { format } from "../../internal/1.0.14/format.js";
|
|
7
|
+
import { red } from "../../internal/1.0.14/styles.js";
|
|
8
|
+
import { AssertionError } from "./assertion_error.js";
|
|
9
|
+
/**
|
|
10
|
+
* Make an assertion that `actual` and `expected` are strictly equal, using
|
|
11
|
+
* {@linkcode Object.is} for equality comparison. If not, then throw.
|
|
12
|
+
*
|
|
13
|
+
* @example Usage
|
|
14
|
+
* ```ts ignore
|
|
15
|
+
* import { assertStrictEquals } from "@std/assert";
|
|
16
|
+
*
|
|
17
|
+
* const a = {};
|
|
18
|
+
* const b = a;
|
|
19
|
+
* assertStrictEquals(a, b); // Doesn't throw
|
|
20
|
+
*
|
|
21
|
+
* const c = {};
|
|
22
|
+
* const d = {};
|
|
23
|
+
* assertStrictEquals(c, d); // Throws
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @typeParam T The type of the expected value.
|
|
27
|
+
* @param actual The actual value to compare.
|
|
28
|
+
* @param expected The expected value to compare.
|
|
29
|
+
* @param msg The optional message to display if the assertion fails.
|
|
30
|
+
*/
|
|
31
|
+
export function assertStrictEquals(actual, expected, msg) {
|
|
32
|
+
if (Object.is(actual, expected)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
36
|
+
let message;
|
|
37
|
+
const actualString = format(actual);
|
|
38
|
+
const expectedString = format(expected);
|
|
39
|
+
if (actualString === expectedString) {
|
|
40
|
+
const withOffset = actualString
|
|
41
|
+
.split("\n")
|
|
42
|
+
.map((l) => ` ${l}`)
|
|
43
|
+
.join("\n");
|
|
44
|
+
message =
|
|
45
|
+
`Values have the same structure but are not reference-equal${msgSuffix}\n\n${red(withOffset)}\n`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const stringDiff = (typeof actual === "string") &&
|
|
49
|
+
(typeof expected === "string");
|
|
50
|
+
const diffResult = stringDiff
|
|
51
|
+
? diffStr(actual, expected)
|
|
52
|
+
: diff(actualString.split("\n"), expectedString.split("\n"));
|
|
53
|
+
const diffMsg = buildMessage(diffResult, { stringDiff }, arguments[3])
|
|
54
|
+
.join("\n");
|
|
55
|
+
message = `Values are not strictly equal${msgSuffix}\n${diffMsg}`;
|
|
56
|
+
}
|
|
57
|
+
throw new AssertionError(message);
|
|
58
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
/**
|
|
5
|
+
* Make an assertion that actual includes expected. If not
|
|
6
|
+
* then throw.
|
|
7
|
+
*
|
|
8
|
+
* @example Usage
|
|
9
|
+
* ```ts ignore
|
|
10
|
+
* import { assertStringIncludes } from "@std/assert";
|
|
11
|
+
*
|
|
12
|
+
* assertStringIncludes("Hello", "ello"); // Doesn't throw
|
|
13
|
+
* assertStringIncludes("Hello", "world"); // Throws
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param actual The actual string to check for inclusion.
|
|
17
|
+
* @param expected The expected string to check for inclusion.
|
|
18
|
+
* @param msg The optional message to display if the assertion fails.
|
|
19
|
+
*/
|
|
20
|
+
export function assertStringIncludes(actual, expected, msg) {
|
|
21
|
+
if (actual.includes(expected))
|
|
22
|
+
return;
|
|
23
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
24
|
+
msg = `Expected actual: "${actual}" to contain: "${expected}"${msgSuffix}`;
|
|
25
|
+
throw new AssertionError(msg);
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { assertIsError } from "./is_error.js";
|
|
4
|
+
import { AssertionError } from "./assertion_error.js";
|
|
5
|
+
export function assertThrows(fn, errorClassOrMsg, msgIncludesOrMsg, msg) {
|
|
6
|
+
// deno-lint-ignore no-explicit-any
|
|
7
|
+
let ErrorClass;
|
|
8
|
+
let msgIncludes;
|
|
9
|
+
let err;
|
|
10
|
+
if (typeof errorClassOrMsg !== "string") {
|
|
11
|
+
if (errorClassOrMsg === undefined ||
|
|
12
|
+
errorClassOrMsg?.prototype instanceof Error ||
|
|
13
|
+
errorClassOrMsg?.prototype === Error.prototype) {
|
|
14
|
+
ErrorClass = errorClassOrMsg;
|
|
15
|
+
msgIncludes = msgIncludesOrMsg;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
msg = msgIncludesOrMsg;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
msg = errorClassOrMsg;
|
|
23
|
+
}
|
|
24
|
+
let doesThrow = false;
|
|
25
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
26
|
+
try {
|
|
27
|
+
fn();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (ErrorClass) {
|
|
31
|
+
if (error instanceof Error === false) {
|
|
32
|
+
throw new AssertionError(`A non-Error object was thrown${msgSuffix}`);
|
|
33
|
+
}
|
|
34
|
+
assertIsError(error, ErrorClass, msgIncludes, msg);
|
|
35
|
+
}
|
|
36
|
+
err = error;
|
|
37
|
+
doesThrow = true;
|
|
38
|
+
}
|
|
39
|
+
if (!doesThrow) {
|
|
40
|
+
msg = `Expected function to throw${msgSuffix}`;
|
|
41
|
+
throw new AssertionError(msg);
|
|
42
|
+
}
|
|
43
|
+
return err;
|
|
44
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
/**
|
|
5
|
+
* Use this to stub out methods that will throw when invoked.
|
|
6
|
+
*
|
|
7
|
+
* @example Usage
|
|
8
|
+
* ```ts ignore
|
|
9
|
+
* import { unimplemented } from "@std/assert";
|
|
10
|
+
*
|
|
11
|
+
* unimplemented(); // Throws
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @param msg Optional message to include in the error.
|
|
15
|
+
* @returns Never returns, always throws.
|
|
16
|
+
*/
|
|
17
|
+
export function unimplemented(msg) {
|
|
18
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
19
|
+
throw new AssertionError(`Unimplemented${msgSuffix}`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
/**
|
|
5
|
+
* Use this to assert unreachable code.
|
|
6
|
+
*
|
|
7
|
+
* @example Usage
|
|
8
|
+
* ```ts ignore
|
|
9
|
+
* import { unreachable } from "@std/assert";
|
|
10
|
+
*
|
|
11
|
+
* unreachable(); // Throws
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @param msg Optional message to include in the error.
|
|
15
|
+
* @returns Never returns, always throws.
|
|
16
|
+
*/
|
|
17
|
+
export function unreachable(msg) {
|
|
18
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
19
|
+
throw new AssertionError(`Unreachable${msgSuffix}`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { bgGreen, bgRed, bold, gray, green, red, white } from "./styles.js";
|
|
4
|
+
/**
|
|
5
|
+
* Colors the output of assertion diffs.
|
|
6
|
+
*
|
|
7
|
+
* @param diffType Difference type, either added or removed.
|
|
8
|
+
* @param background If true, colors the background instead of the text.
|
|
9
|
+
*
|
|
10
|
+
* @returns A function that colors the input string.
|
|
11
|
+
*
|
|
12
|
+
* @example Usage
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createColor } from "@std/internal";
|
|
15
|
+
* import { assertEquals } from "@std/assert";
|
|
16
|
+
* import { bold, green, red, white } from "@std/fmt/colors";
|
|
17
|
+
*
|
|
18
|
+
* assertEquals(createColor("added")("foo"), green(bold("foo")));
|
|
19
|
+
* assertEquals(createColor("removed")("foo"), red(bold("foo")));
|
|
20
|
+
* assertEquals(createColor("common")("foo"), white("foo"));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function createColor(diffType,
|
|
24
|
+
/**
|
|
25
|
+
* TODO(@littledivy): Remove this when we can detect true color terminals. See
|
|
26
|
+
* https://github.com/denoland/std/issues/2575.
|
|
27
|
+
*/
|
|
28
|
+
background = false) {
|
|
29
|
+
switch (diffType) {
|
|
30
|
+
case "added":
|
|
31
|
+
return (s) => background ? bgGreen(white(s)) : green(bold(s));
|
|
32
|
+
case "removed":
|
|
33
|
+
return (s) => background ? bgRed(white(s)) : red(bold(s));
|
|
34
|
+
case "truncation":
|
|
35
|
+
return gray;
|
|
36
|
+
default:
|
|
37
|
+
return white;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Prefixes `+` or `-` in diff output.
|
|
42
|
+
*
|
|
43
|
+
* @param diffType Difference type, either added or removed
|
|
44
|
+
*
|
|
45
|
+
* @returns A string representing the sign.
|
|
46
|
+
*
|
|
47
|
+
* @example Usage
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { createSign } from "@std/internal";
|
|
50
|
+
* import { assertEquals } from "@std/assert";
|
|
51
|
+
*
|
|
52
|
+
* assertEquals(createSign("added"), "+ ");
|
|
53
|
+
* assertEquals(createSign("removed"), "- ");
|
|
54
|
+
* assertEquals(createSign("common"), " ");
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function createSign(diffType) {
|
|
58
|
+
switch (diffType) {
|
|
59
|
+
case "added":
|
|
60
|
+
return "+ ";
|
|
61
|
+
case "removed":
|
|
62
|
+
return "- ";
|
|
63
|
+
default:
|
|
64
|
+
return " ";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Builds a message based on the provided diff result.
|
|
69
|
+
*
|
|
70
|
+
* @param diffResult The diff result array.
|
|
71
|
+
* @param options Optional parameters for customizing the message.
|
|
72
|
+
* @param truncateDiff Function to truncate the diff (default is no truncation).
|
|
73
|
+
*
|
|
74
|
+
* @returns An array of strings representing the built message.
|
|
75
|
+
*
|
|
76
|
+
* @example Usage
|
|
77
|
+
* ```ts no-assert
|
|
78
|
+
* import { diffStr, buildMessage } from "@std/internal";
|
|
79
|
+
*
|
|
80
|
+
* diffStr("Hello, world!", "Hello, world");
|
|
81
|
+
* // [
|
|
82
|
+
* // "",
|
|
83
|
+
* // "",
|
|
84
|
+
* // " [Diff] Actual / Expected",
|
|
85
|
+
* // "",
|
|
86
|
+
* // "",
|
|
87
|
+
* // "- Hello, world!",
|
|
88
|
+
* // "+ Hello, world",
|
|
89
|
+
* // "",
|
|
90
|
+
* // ]
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export function buildMessage(diffResult, options = {}, truncateDiff) {
|
|
94
|
+
if (truncateDiff != null) {
|
|
95
|
+
diffResult = truncateDiff(diffResult, options.stringDiff ?? false);
|
|
96
|
+
}
|
|
97
|
+
const { stringDiff = false } = options;
|
|
98
|
+
const messages = [
|
|
99
|
+
"",
|
|
100
|
+
"",
|
|
101
|
+
` ${gray(bold("[Diff]"))} ${red(bold("Actual"))} / ${green(bold("Expected"))}`,
|
|
102
|
+
"",
|
|
103
|
+
"",
|
|
104
|
+
];
|
|
105
|
+
const diffMessages = diffResult.map((result) => {
|
|
106
|
+
const color = createColor(result.type);
|
|
107
|
+
const line = result.type === "added" || result.type === "removed"
|
|
108
|
+
? result.details?.map((detail) => detail.type !== "common"
|
|
109
|
+
? createColor(detail.type, true)(detail.value)
|
|
110
|
+
: detail.value).join("") ?? result.value
|
|
111
|
+
: result.value;
|
|
112
|
+
return color(`${createSign(result.type)}${line}`);
|
|
113
|
+
});
|
|
114
|
+
messages.push(...(stringDiff ? [diffMessages.join("")] : diffMessages), "");
|
|
115
|
+
return messages;
|
|
116
|
+
}
|