@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.
Files changed (137) hide show
  1. package/LICENSE +21 -0
  2. package/esm/core/mod.js +55 -0
  3. package/esm/core/src/api.js +31 -0
  4. package/esm/core/src/collect.js +24 -0
  5. package/esm/core/src/component-api.js +47 -0
  6. package/esm/core/src/content-context.js +23 -0
  7. package/esm/core/src/deno-compiler.js +51 -0
  8. package/esm/core/src/errors.js +13 -0
  9. package/esm/core/src/eval-context.js +13 -0
  10. package/esm/core/src/eval-handler.js +79 -0
  11. package/esm/core/src/eval-interpolate.js +63 -0
  12. package/esm/core/src/eval-transform.js +378 -0
  13. package/esm/core/src/execute.js +378 -0
  14. package/esm/core/src/expand.js +988 -0
  15. package/esm/core/src/frontmatter.js +98 -0
  16. package/esm/core/src/heal.js +29 -0
  17. package/esm/core/src/interpolate.js +39 -0
  18. package/esm/core/src/modifiers/daemon.js +60 -0
  19. package/esm/core/src/modifiers/persist.js +35 -0
  20. package/esm/core/src/modifiers/timeout.js +55 -0
  21. package/esm/core/src/modifiers.js +113 -0
  22. package/esm/core/src/output/normalize.js +33 -0
  23. package/esm/core/src/output/terminal.js +20 -0
  24. package/esm/core/src/render.js +30 -0
  25. package/esm/core/src/replay-stream.js +58 -0
  26. package/esm/core/src/sample-api.js +45 -0
  27. package/esm/core/src/scanner.js +632 -0
  28. package/esm/core/src/temp-file-compiler.js +68 -0
  29. package/esm/core/src/types.js +7 -0
  30. package/esm/core/src/validate.js +82 -0
  31. package/esm/durable-streams/combinators.js +227 -0
  32. package/esm/durable-streams/context.js +13 -0
  33. package/esm/durable-streams/divergence.js +56 -0
  34. package/esm/durable-streams/each.js +193 -0
  35. package/esm/durable-streams/effect.js +273 -0
  36. package/esm/durable-streams/ephemeral.js +80 -0
  37. package/esm/durable-streams/errors.js +92 -0
  38. package/esm/durable-streams/http-stream.js +207 -0
  39. package/esm/durable-streams/mod.js +34 -0
  40. package/esm/durable-streams/operations.js +88 -0
  41. package/esm/durable-streams/replay-guard.js +87 -0
  42. package/esm/durable-streams/replay-index.js +132 -0
  43. package/esm/durable-streams/run.js +137 -0
  44. package/esm/durable-streams/serialize.js +65 -0
  45. package/esm/durable-streams/stream.js +56 -0
  46. package/esm/durable-streams/types.js +10 -0
  47. package/esm/package.json +3 -0
  48. package/esm/runtime/apis.js +237 -0
  49. package/esm/runtime/find-free-port.js +33 -0
  50. package/esm/runtime/mod.js +20 -0
  51. package/esm/testing/npm/src/_dnt.polyfills.js +1 -0
  52. package/esm/testing/npm/src/_dnt.shims.js +57 -0
  53. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +47 -0
  54. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/array_includes.js +65 -0
  55. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/assert.js +23 -0
  56. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +30 -0
  57. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/equal.js +194 -0
  58. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/equals.js +61 -0
  59. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/exists.js +27 -0
  60. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/fail.js +20 -0
  61. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/false.js +23 -0
  62. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/greater.js +29 -0
  63. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +29 -0
  64. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/instance_of.js +52 -0
  65. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/is_error.js +53 -0
  66. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/less.js +28 -0
  67. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +29 -0
  68. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/match.js +26 -0
  69. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/mod.js +45 -0
  70. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_equals.js +39 -0
  71. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +29 -0
  72. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_match.js +26 -0
  73. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +32 -0
  74. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/object_match.js +177 -0
  75. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/rejects.js +53 -0
  76. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +58 -0
  77. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/string_includes.js +26 -0
  78. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/throws.js +44 -0
  79. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +20 -0
  80. package/esm/testing/npm/src/deps/jsr.io/@std/assert/1.0.19/unreachable.js +20 -0
  81. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/build_message.js +116 -0
  82. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/diff.js +277 -0
  83. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/diff_str.js +181 -0
  84. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/format.js +70 -0
  85. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/styles.js +207 -0
  86. package/esm/testing/npm/src/deps/jsr.io/@std/internal/1.0.14/types.js +3 -0
  87. package/esm/testing/npm/src/mod.js +27 -0
  88. package/esm/testing/npm/src/src/assertions.js +250 -0
  89. package/esm/testing/npm/src/src/handlers.js +245 -0
  90. package/esm/testing/npm/src/src/journal.js +152 -0
  91. package/esm/testing/npm/src/src/test-api.js +33 -0
  92. package/esm/testing/npm/src/src/use-testing.js +79 -0
  93. package/esm/testing/npm/src/src/vocabulary.js +111 -0
  94. package/package.json +35 -0
  95. package/types/_dnt.polyfills.d.ts +6 -0
  96. package/types/_dnt.shims.d.ts +1 -0
  97. package/types/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +29 -0
  98. package/types/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +28 -0
  99. package/types/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +16 -0
  100. package/types/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +25 -0
  101. package/types/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +24 -0
  102. package/types/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +36 -0
  103. package/types/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +17 -0
  104. package/types/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +14 -0
  105. package/types/deps/jsr.io/@std/assert/1.0.19/false.d.ts +18 -0
  106. package/types/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +19 -0
  107. package/types/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +19 -0
  108. package/types/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +22 -0
  109. package/types/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +24 -0
  110. package/types/deps/jsr.io/@std/assert/1.0.19/less.d.ts +18 -0
  111. package/types/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +19 -0
  112. package/types/deps/jsr.io/@std/assert/1.0.19/match.d.ts +17 -0
  113. package/types/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +43 -0
  114. package/types/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +26 -0
  115. package/types/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +19 -0
  116. package/types/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +17 -0
  117. package/types/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +22 -0
  118. package/types/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +28 -0
  119. package/types/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +41 -0
  120. package/types/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +23 -0
  121. package/types/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +17 -0
  122. package/types/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +44 -0
  123. package/types/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +14 -0
  124. package/types/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +14 -0
  125. package/types/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +79 -0
  126. package/types/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +139 -0
  127. package/types/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +98 -0
  128. package/types/deps/jsr.io/@std/internal/1.0.14/format.d.ts +28 -0
  129. package/types/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +158 -0
  130. package/types/deps/jsr.io/@std/internal/1.0.14/types.d.ts +24 -0
  131. package/types/mod.d.ts +29 -0
  132. package/types/src/assertions.d.ts +55 -0
  133. package/types/src/handlers.d.ts +18 -0
  134. package/types/src/journal.d.ts +29 -0
  135. package/types/src/test-api.d.ts +54 -0
  136. package/types/src/use-testing.d.ts +25 -0
  137. 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
+ }