@netlify/plugin-nextjs 4.40.1 → 4.40.2
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/lib/helpers/edge.js +1 -0
- package/lib/templates/vendor.js +20 -0
- package/package.json +7 -4
- package/src/templates/edge/next-dev.js +3 -3
- package/src/templates/edge/shims.js +6 -6
- package/src/templates/edge-shared/next-utils.ts +3 -3
- package/src/templates/edge-shared/utils.ts +1 -1
- package/src/templates/vendor/deno.land/std@0.134.0/fmt/colors.ts +536 -0
- package/src/templates/vendor/deno.land/std@0.134.0/testing/_diff.ts +360 -0
- package/src/templates/vendor/deno.land/std@0.134.0/testing/asserts.ts +866 -0
- package/src/templates/vendor/deno.land/std@0.175.0/_util/asserts.ts +25 -0
- package/src/templates/vendor/deno.land/std@0.175.0/_util/os.ts +23 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/abortable.ts +149 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/deadline.ts +30 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/debounce.ts +79 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/deferred.ts +48 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/delay.ts +67 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/mod.ts +18 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/mux_async_iterator.ts +97 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/pool.ts +95 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/retry.ts +81 -0
- package/src/templates/vendor/deno.land/std@0.175.0/async/tee.ts +100 -0
- package/src/templates/vendor/deno.land/std@0.175.0/bytes/index_of_needle.ts +49 -0
- package/src/templates/vendor/deno.land/std@0.175.0/crypto/timing_safe_equal.ts +29 -0
- package/src/templates/vendor/deno.land/std@0.175.0/datetime/to_imf.ts +45 -0
- package/src/templates/vendor/deno.land/std@0.175.0/encoding/base64.ts +144 -0
- package/src/templates/vendor/deno.land/std@0.175.0/encoding/base64url.ts +70 -0
- package/src/templates/vendor/deno.land/std@0.175.0/flags/mod.ts +785 -0
- package/src/templates/vendor/deno.land/std@0.175.0/fmt/colors.ts +569 -0
- package/src/templates/vendor/deno.land/std@0.175.0/fmt/printf.ts +939 -0
- package/src/templates/vendor/deno.land/std@0.175.0/http/cookie.ts +403 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_core.ts +77 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_events.d.ts +848 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_events.mjs +1033 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_global.d.ts +66 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_next_tick.ts +173 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_process/exiting.ts +4 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_process/process.ts +131 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_process/stdio.mjs +7 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_process/streams.mjs +146 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_stream.d.ts +1488 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_stream.mjs +746 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_util/_util_callbackify.ts +129 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/_utils.ts +206 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/assert.ts +940 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/assertion_error.ts +579 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/async_hooks.ts +331 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/buffer.ts +13 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/events.ts +14 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/buffer.d.ts +2074 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/buffer.mjs +2607 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/crypto/_keys.ts +16 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/crypto/constants.ts +5 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/error_codes.ts +7 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/errors.ts +2867 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/fixed_queue.ts +123 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/hide_stack_frames.ts +16 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/net.ts +95 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/normalize_encoding.mjs +72 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/options.ts +45 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/primordials.mjs +30 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/process/per_thread.mjs +272 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/readline/callbacks.mjs +137 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/readline/utils.mjs +580 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/destroy.mjs +320 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/end-of-stream.mjs +229 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/utils.mjs +242 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/comparisons.ts +669 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/debuglog.ts +118 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/inspect.mjs +2237 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/types.ts +113 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util.mjs +143 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal/validators.mjs +317 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_libuv_winerror.ts +229 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_listen.ts +16 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_node.ts +18 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_timingSafeEqual.ts +12 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_utils.ts +86 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_winerror.ts +16873 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/ares.ts +66 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/async_wrap.ts +152 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/buffer.ts +130 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/cares_wrap.ts +541 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/config.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/connection_wrap.ts +80 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/constants.ts +900 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/contextify.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/credentials.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/crypto.ts +14 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/errors.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs_dir.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs_event_wrap.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/handle_wrap.ts +50 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/heap_utils.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/http_parser.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/icu.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/inspector.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/js_stream.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/messaging.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/mod.ts +108 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/module_wrap.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/native_module.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/natives.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/node_file.ts +84 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/node_options.ts +39 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/options.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/os.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/performance.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/pipe_wrap.ts +392 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/process_methods.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/report.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/serdes.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/signal_wrap.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/spawn_sync.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/stream_wrap.ts +354 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/string_decoder.ts +15 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/symbols.ts +27 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/task_queue.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tcp_wrap.ts +488 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/timers.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tls_wrap.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/trace_events.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tty_wrap.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/types.ts +186 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/udp_wrap.ts +496 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/url.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/util.ts +126 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/uv.ts +437 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/v8.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/worker.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/zlib.ts +3 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/process.ts +705 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/stream.ts +37 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/string_decoder.ts +337 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/util/types.ts +4 -0
- package/src/templates/vendor/deno.land/std@0.175.0/node/util.ts +289 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/_constants.ts +49 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/_interface.ts +30 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/_util.ts +194 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/common.ts +40 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/glob.ts +418 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/mod.ts +53 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/posix.ts +487 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/separator.ts +7 -0
- package/src/templates/vendor/deno.land/std@0.175.0/path/win32.ts +962 -0
- package/src/templates/vendor/deno.land/std@0.175.0/streams/write_all.ts +64 -0
- package/src/templates/vendor/deno.land/std@0.175.0/testing/_diff.ts +440 -0
- package/src/templates/vendor/deno.land/std@0.175.0/testing/_format.ts +23 -0
- package/src/templates/vendor/deno.land/std@0.175.0/testing/asserts.ts +906 -0
- package/src/templates/vendor/deno.land/std@0.175.0/types.d.ts +89 -0
- package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/index.ts +133 -0
- package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/asyncify.js +112 -0
- package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/html_rewriter.d.ts +88 -0
- package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/html_rewriter.js +974 -0
- package/src/templates/vendor/deno.land/x/path_to_regexp@v6.2.1/index.ts +621 -0
- package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/compiled/cookie.js +13 -0
- package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/server/web/spec-extension/request.js +12 -0
- package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/server/web/spec-extension/response.js +5 -0
- package/src/templates/vendor/import_map.json +13 -0
- package/src/templates/vendor/raw.githubusercontent.com/worker-tools/resolvable-promise/master/index.ts +50 -0
|
@@ -0,0 +1,906 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
|
|
3
|
+
/** A library of assertion functions.
|
|
4
|
+
* If the assertion is false an `AssertionError` will be thrown which will
|
|
5
|
+
* result in pretty-printed diff of failing assertion.
|
|
6
|
+
*
|
|
7
|
+
* This module is browser compatible, but do not rely on good formatting of
|
|
8
|
+
* values for AssertionError messages in browsers.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { red, stripColor } from "../fmt/colors.ts";
|
|
14
|
+
import { buildMessage, diff, diffstr } from "./_diff.ts";
|
|
15
|
+
import { format } from "./_format.ts";
|
|
16
|
+
|
|
17
|
+
const CAN_NOT_DISPLAY = "[Cannot display]";
|
|
18
|
+
|
|
19
|
+
export class AssertionError extends Error {
|
|
20
|
+
override name = "AssertionError";
|
|
21
|
+
constructor(message: string) {
|
|
22
|
+
super(message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isKeyedCollection(x: unknown): x is Set<unknown> {
|
|
27
|
+
return [Symbol.iterator, "size"].every((k) => k in (x as Set<unknown>));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Deep equality comparison used in assertions
|
|
32
|
+
* @param c actual value
|
|
33
|
+
* @param d expected value
|
|
34
|
+
*/
|
|
35
|
+
export function equal(c: unknown, d: unknown): boolean {
|
|
36
|
+
const seen = new Map();
|
|
37
|
+
return (function compare(a: unknown, b: unknown): boolean {
|
|
38
|
+
// Have to render RegExp & Date for string comparison
|
|
39
|
+
// unless it's mistreated as object
|
|
40
|
+
if (
|
|
41
|
+
a &&
|
|
42
|
+
b &&
|
|
43
|
+
((a instanceof RegExp && b instanceof RegExp) ||
|
|
44
|
+
(a instanceof URL && b instanceof URL))
|
|
45
|
+
) {
|
|
46
|
+
return String(a) === String(b);
|
|
47
|
+
}
|
|
48
|
+
if (a instanceof Date && b instanceof Date) {
|
|
49
|
+
const aTime = a.getTime();
|
|
50
|
+
const bTime = b.getTime();
|
|
51
|
+
// Check for NaN equality manually since NaN is not
|
|
52
|
+
// equal to itself.
|
|
53
|
+
if (Number.isNaN(aTime) && Number.isNaN(bTime)) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return aTime === bTime;
|
|
57
|
+
}
|
|
58
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
59
|
+
return Number.isNaN(a) && Number.isNaN(b) || a === b;
|
|
60
|
+
}
|
|
61
|
+
if (Object.is(a, b)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (a && typeof a === "object" && b && typeof b === "object") {
|
|
65
|
+
if (a && b && !constructorsEqual(a, b)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (a instanceof WeakMap || b instanceof WeakMap) {
|
|
69
|
+
if (!(a instanceof WeakMap && b instanceof WeakMap)) return false;
|
|
70
|
+
throw new TypeError("cannot compare WeakMap instances");
|
|
71
|
+
}
|
|
72
|
+
if (a instanceof WeakSet || b instanceof WeakSet) {
|
|
73
|
+
if (!(a instanceof WeakSet && b instanceof WeakSet)) return false;
|
|
74
|
+
throw new TypeError("cannot compare WeakSet instances");
|
|
75
|
+
}
|
|
76
|
+
if (seen.get(a) === b) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
seen.set(a, b);
|
|
83
|
+
if (isKeyedCollection(a) && isKeyedCollection(b)) {
|
|
84
|
+
if (a.size !== b.size) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let unmatchedEntries = a.size;
|
|
89
|
+
|
|
90
|
+
for (const [aKey, aValue] of a.entries()) {
|
|
91
|
+
for (const [bKey, bValue] of b.entries()) {
|
|
92
|
+
/* Given that Map keys can be references, we need
|
|
93
|
+
* to ensure that they are also deeply equal */
|
|
94
|
+
if (
|
|
95
|
+
(aKey === aValue && bKey === bValue && compare(aKey, bKey)) ||
|
|
96
|
+
(compare(aKey, bKey) && compare(aValue, bValue))
|
|
97
|
+
) {
|
|
98
|
+
unmatchedEntries--;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return unmatchedEntries === 0;
|
|
105
|
+
}
|
|
106
|
+
const merged = { ...a, ...b };
|
|
107
|
+
for (
|
|
108
|
+
const key of [
|
|
109
|
+
...Object.getOwnPropertyNames(merged),
|
|
110
|
+
...Object.getOwnPropertySymbols(merged),
|
|
111
|
+
]
|
|
112
|
+
) {
|
|
113
|
+
type Key = keyof typeof merged;
|
|
114
|
+
if (!compare(a && a[key as Key], b && b[key as Key])) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (((key in a) && (!(key in b))) || ((key in b) && (!(key in a)))) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (a instanceof WeakRef || b instanceof WeakRef) {
|
|
122
|
+
if (!(a instanceof WeakRef && b instanceof WeakRef)) return false;
|
|
123
|
+
return compare(a.deref(), b.deref());
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
})(c, d);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// deno-lint-ignore ban-types
|
|
132
|
+
function constructorsEqual(a: object, b: object) {
|
|
133
|
+
return a.constructor === b.constructor ||
|
|
134
|
+
a.constructor === Object && !b.constructor ||
|
|
135
|
+
!a.constructor && b.constructor === Object;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Make an assertion, error will be thrown if `expr` does not have truthy value. */
|
|
139
|
+
export function assert(expr: unknown, msg = ""): asserts expr {
|
|
140
|
+
if (!expr) {
|
|
141
|
+
throw new AssertionError(msg);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Make an assertion, error will be thrown if `expr` have truthy value. */
|
|
146
|
+
type Falsy = false | 0 | 0n | "" | null | undefined;
|
|
147
|
+
export function assertFalse(expr: unknown, msg = ""): asserts expr is Falsy {
|
|
148
|
+
if (expr) {
|
|
149
|
+
throw new AssertionError(msg);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Make an assertion that `actual` and `expected` are equal, deeply. If not
|
|
155
|
+
* deeply equal, then throw.
|
|
156
|
+
*
|
|
157
|
+
* Type parameter can be specified to ensure values under comparison have the same type.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
162
|
+
*
|
|
163
|
+
* Deno.test("example", function (): void {
|
|
164
|
+
* assertEquals("world", "world");
|
|
165
|
+
* assertEquals({ hello: "world" }, { hello: "world" });
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export function assertEquals<T>(actual: T, expected: T, msg?: string) {
|
|
170
|
+
if (equal(actual, expected)) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
let message = "";
|
|
174
|
+
const actualString = format(actual);
|
|
175
|
+
const expectedString = format(expected);
|
|
176
|
+
try {
|
|
177
|
+
const stringDiff = (typeof actual === "string") &&
|
|
178
|
+
(typeof expected === "string");
|
|
179
|
+
const diffResult = stringDiff
|
|
180
|
+
? diffstr(actual as string, expected as string)
|
|
181
|
+
: diff(actualString.split("\n"), expectedString.split("\n"));
|
|
182
|
+
const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
|
|
183
|
+
message = `Values are not equal:\n${diffMsg}`;
|
|
184
|
+
} catch {
|
|
185
|
+
message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`;
|
|
186
|
+
}
|
|
187
|
+
if (msg) {
|
|
188
|
+
message = msg;
|
|
189
|
+
}
|
|
190
|
+
throw new AssertionError(message);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Make an assertion that `actual` and `expected` are not equal, deeply.
|
|
195
|
+
* If not then throw.
|
|
196
|
+
*
|
|
197
|
+
* Type parameter can be specified to ensure values under comparison have the same type.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```ts
|
|
201
|
+
* import { assertNotEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
202
|
+
*
|
|
203
|
+
* assertNotEquals<number>(1, 2)
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export function assertNotEquals<T>(actual: T, expected: T, msg?: string) {
|
|
207
|
+
if (!equal(actual, expected)) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
let actualString: string;
|
|
211
|
+
let expectedString: string;
|
|
212
|
+
try {
|
|
213
|
+
actualString = String(actual);
|
|
214
|
+
} catch {
|
|
215
|
+
actualString = "[Cannot display]";
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
expectedString = String(expected);
|
|
219
|
+
} catch {
|
|
220
|
+
expectedString = "[Cannot display]";
|
|
221
|
+
}
|
|
222
|
+
if (!msg) {
|
|
223
|
+
msg = `actual: ${actualString} expected not to be: ${expectedString}`;
|
|
224
|
+
}
|
|
225
|
+
throw new AssertionError(msg);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Make an assertion that `actual` and `expected` are strictly equal. If
|
|
230
|
+
* not then throw.
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* import { assertStrictEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
235
|
+
*
|
|
236
|
+
* Deno.test("isStrictlyEqual", function (): void {
|
|
237
|
+
* const a = {};
|
|
238
|
+
* const b = a;
|
|
239
|
+
* assertStrictEquals(a, b);
|
|
240
|
+
* });
|
|
241
|
+
*
|
|
242
|
+
* // This test fails
|
|
243
|
+
* Deno.test("isNotStrictlyEqual", function (): void {
|
|
244
|
+
* const a = {};
|
|
245
|
+
* const b = {};
|
|
246
|
+
* assertStrictEquals(a, b);
|
|
247
|
+
* });
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export function assertStrictEquals<T>(
|
|
251
|
+
actual: unknown,
|
|
252
|
+
expected: T,
|
|
253
|
+
msg?: string,
|
|
254
|
+
): asserts actual is T {
|
|
255
|
+
if (Object.is(actual, expected)) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let message: string;
|
|
260
|
+
|
|
261
|
+
if (msg) {
|
|
262
|
+
message = msg;
|
|
263
|
+
} else {
|
|
264
|
+
const actualString = format(actual);
|
|
265
|
+
const expectedString = format(expected);
|
|
266
|
+
|
|
267
|
+
if (actualString === expectedString) {
|
|
268
|
+
const withOffset = actualString
|
|
269
|
+
.split("\n")
|
|
270
|
+
.map((l) => ` ${l}`)
|
|
271
|
+
.join("\n");
|
|
272
|
+
message =
|
|
273
|
+
`Values have the same structure but are not reference-equal:\n\n${
|
|
274
|
+
red(withOffset)
|
|
275
|
+
}\n`;
|
|
276
|
+
} else {
|
|
277
|
+
try {
|
|
278
|
+
const stringDiff = (typeof actual === "string") &&
|
|
279
|
+
(typeof expected === "string");
|
|
280
|
+
const diffResult = stringDiff
|
|
281
|
+
? diffstr(actual as string, expected as string)
|
|
282
|
+
: diff(actualString.split("\n"), expectedString.split("\n"));
|
|
283
|
+
const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
|
|
284
|
+
message = `Values are not strictly equal:\n${diffMsg}`;
|
|
285
|
+
} catch {
|
|
286
|
+
message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
throw new AssertionError(message);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Make an assertion that `actual` and `expected` are not strictly equal.
|
|
296
|
+
* If the values are strictly equal then throw.
|
|
297
|
+
*
|
|
298
|
+
* ```ts
|
|
299
|
+
* import { assertNotStrictEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
300
|
+
*
|
|
301
|
+
* assertNotStrictEquals(1, 1)
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
export function assertNotStrictEquals<T>(
|
|
305
|
+
actual: T,
|
|
306
|
+
expected: T,
|
|
307
|
+
msg?: string,
|
|
308
|
+
) {
|
|
309
|
+
if (!Object.is(actual, expected)) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
throw new AssertionError(
|
|
314
|
+
msg ?? `Expected "actual" to be strictly unequal to: ${format(actual)}\n`,
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Make an assertion that `actual` and `expected` are almost equal numbers through
|
|
320
|
+
* a given tolerance. It can be used to take into account IEEE-754 double-precision
|
|
321
|
+
* floating-point representation limitations.
|
|
322
|
+
* If the values are not almost equal then throw.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* import { assertAlmostEquals, assertThrows } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
327
|
+
*
|
|
328
|
+
* assertAlmostEquals(0.1, 0.2);
|
|
329
|
+
*
|
|
330
|
+
* // Using a custom tolerance value
|
|
331
|
+
* assertAlmostEquals(0.1 + 0.2, 0.3, 1e-16);
|
|
332
|
+
* assertThrows(() => assertAlmostEquals(0.1 + 0.2, 0.3, 1e-17));
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
export function assertAlmostEquals(
|
|
336
|
+
actual: number,
|
|
337
|
+
expected: number,
|
|
338
|
+
tolerance = 1e-7,
|
|
339
|
+
msg?: string,
|
|
340
|
+
) {
|
|
341
|
+
if (Object.is(actual, expected)) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const delta = Math.abs(expected - actual);
|
|
345
|
+
if (delta <= tolerance) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const f = (n: number) => Number.isInteger(n) ? n : n.toExponential();
|
|
349
|
+
throw new AssertionError(
|
|
350
|
+
msg ??
|
|
351
|
+
`actual: "${f(actual)}" expected to be close to "${f(expected)}": \
|
|
352
|
+
delta "${f(delta)}" is greater than "${f(tolerance)}"`,
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// deno-lint-ignore no-explicit-any
|
|
357
|
+
type AnyConstructor = new (...args: any[]) => any;
|
|
358
|
+
type GetConstructorType<T extends AnyConstructor> = T extends // deno-lint-ignore no-explicit-any
|
|
359
|
+
new (...args: any) => infer C ? C
|
|
360
|
+
: never;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Make an assertion that `obj` is an instance of `type`.
|
|
364
|
+
* If not then throw.
|
|
365
|
+
*/
|
|
366
|
+
export function assertInstanceOf<T extends AnyConstructor>(
|
|
367
|
+
actual: unknown,
|
|
368
|
+
expectedType: T,
|
|
369
|
+
msg = "",
|
|
370
|
+
): asserts actual is GetConstructorType<T> {
|
|
371
|
+
if (!msg) {
|
|
372
|
+
const expectedTypeStr = expectedType.name;
|
|
373
|
+
|
|
374
|
+
let actualTypeStr = "";
|
|
375
|
+
if (actual === null) {
|
|
376
|
+
actualTypeStr = "null";
|
|
377
|
+
} else if (actual === undefined) {
|
|
378
|
+
actualTypeStr = "undefined";
|
|
379
|
+
} else if (typeof actual === "object") {
|
|
380
|
+
actualTypeStr = actual.constructor?.name ?? "Object";
|
|
381
|
+
} else {
|
|
382
|
+
actualTypeStr = typeof actual;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (expectedTypeStr == actualTypeStr) {
|
|
386
|
+
msg = `Expected object to be an instance of "${expectedTypeStr}".`;
|
|
387
|
+
} else if (actualTypeStr == "function") {
|
|
388
|
+
msg =
|
|
389
|
+
`Expected object to be an instance of "${expectedTypeStr}" but was not an instanced object.`;
|
|
390
|
+
} else {
|
|
391
|
+
msg =
|
|
392
|
+
`Expected object to be an instance of "${expectedTypeStr}" but was "${actualTypeStr}".`;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
assert(actual instanceof expectedType, msg);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Make an assertion that `obj` is not an instance of `type`.
|
|
400
|
+
* If so, then throw.
|
|
401
|
+
*/
|
|
402
|
+
export function assertNotInstanceOf<A, T>(
|
|
403
|
+
actual: A,
|
|
404
|
+
// deno-lint-ignore no-explicit-any
|
|
405
|
+
unexpectedType: new (...args: any[]) => T,
|
|
406
|
+
msg = `Expected object to not be an instance of "${typeof unexpectedType}"`,
|
|
407
|
+
): asserts actual is Exclude<A, T> {
|
|
408
|
+
assertFalse(actual instanceof unexpectedType, msg);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Make an assertion that actual is not null or undefined.
|
|
413
|
+
* If not then throw.
|
|
414
|
+
*/
|
|
415
|
+
export function assertExists<T>(
|
|
416
|
+
actual: T,
|
|
417
|
+
msg?: string,
|
|
418
|
+
): asserts actual is NonNullable<T> {
|
|
419
|
+
if (actual === undefined || actual === null) {
|
|
420
|
+
if (!msg) {
|
|
421
|
+
msg = `actual: "${actual}" expected to not be null or undefined`;
|
|
422
|
+
}
|
|
423
|
+
throw new AssertionError(msg);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Make an assertion that actual includes expected. If not
|
|
429
|
+
* then throw.
|
|
430
|
+
*/
|
|
431
|
+
export function assertStringIncludes(
|
|
432
|
+
actual: string,
|
|
433
|
+
expected: string,
|
|
434
|
+
msg?: string,
|
|
435
|
+
) {
|
|
436
|
+
if (!actual.includes(expected)) {
|
|
437
|
+
if (!msg) {
|
|
438
|
+
msg = `actual: "${actual}" expected to contain: "${expected}"`;
|
|
439
|
+
}
|
|
440
|
+
throw new AssertionError(msg);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Make an assertion that `actual` includes the `expected` values.
|
|
446
|
+
* If not then an error will be thrown.
|
|
447
|
+
*
|
|
448
|
+
* Type parameter can be specified to ensure values under comparison have the same type.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```ts
|
|
452
|
+
* import { assertArrayIncludes } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
453
|
+
*
|
|
454
|
+
* assertArrayIncludes<number>([1, 2], [2])
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
457
|
+
export function assertArrayIncludes<T>(
|
|
458
|
+
actual: ArrayLike<T>,
|
|
459
|
+
expected: ArrayLike<T>,
|
|
460
|
+
msg?: string,
|
|
461
|
+
) {
|
|
462
|
+
const missing: unknown[] = [];
|
|
463
|
+
for (let i = 0; i < expected.length; i++) {
|
|
464
|
+
let found = false;
|
|
465
|
+
for (let j = 0; j < actual.length; j++) {
|
|
466
|
+
if (equal(expected[i], actual[j])) {
|
|
467
|
+
found = true;
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (!found) {
|
|
472
|
+
missing.push(expected[i]);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (missing.length === 0) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (!msg) {
|
|
479
|
+
msg = `actual: "${format(actual)}" expected to include: "${
|
|
480
|
+
format(expected)
|
|
481
|
+
}"\nmissing: ${format(missing)}`;
|
|
482
|
+
}
|
|
483
|
+
throw new AssertionError(msg);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Make an assertion that `actual` match RegExp `expected`. If not
|
|
488
|
+
* then throw.
|
|
489
|
+
*/
|
|
490
|
+
export function assertMatch(
|
|
491
|
+
actual: string,
|
|
492
|
+
expected: RegExp,
|
|
493
|
+
msg?: string,
|
|
494
|
+
) {
|
|
495
|
+
if (!expected.test(actual)) {
|
|
496
|
+
if (!msg) {
|
|
497
|
+
msg = `actual: "${actual}" expected to match: "${expected}"`;
|
|
498
|
+
}
|
|
499
|
+
throw new AssertionError(msg);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Make an assertion that `actual` not match RegExp `expected`. If match
|
|
505
|
+
* then throw.
|
|
506
|
+
*/
|
|
507
|
+
export function assertNotMatch(
|
|
508
|
+
actual: string,
|
|
509
|
+
expected: RegExp,
|
|
510
|
+
msg?: string,
|
|
511
|
+
) {
|
|
512
|
+
if (expected.test(actual)) {
|
|
513
|
+
if (!msg) {
|
|
514
|
+
msg = `actual: "${actual}" expected to not match: "${expected}"`;
|
|
515
|
+
}
|
|
516
|
+
throw new AssertionError(msg);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Make an assertion that `actual` object is a subset of `expected` object, deeply.
|
|
522
|
+
* If not, then throw.
|
|
523
|
+
*/
|
|
524
|
+
export function assertObjectMatch(
|
|
525
|
+
// deno-lint-ignore no-explicit-any
|
|
526
|
+
actual: Record<PropertyKey, any>,
|
|
527
|
+
expected: Record<PropertyKey, unknown>,
|
|
528
|
+
) {
|
|
529
|
+
type loose = Record<PropertyKey, unknown>;
|
|
530
|
+
|
|
531
|
+
function filter(a: loose, b: loose) {
|
|
532
|
+
const seen = new WeakMap();
|
|
533
|
+
return fn(a, b);
|
|
534
|
+
|
|
535
|
+
function fn(a: loose, b: loose): loose {
|
|
536
|
+
// Prevent infinite loop with circular references with same filter
|
|
537
|
+
if ((seen.has(a)) && (seen.get(a) === b)) {
|
|
538
|
+
return a;
|
|
539
|
+
}
|
|
540
|
+
seen.set(a, b);
|
|
541
|
+
// Filter keys and symbols which are present in both actual and expected
|
|
542
|
+
const filtered = {} as loose;
|
|
543
|
+
const entries = [
|
|
544
|
+
...Object.getOwnPropertyNames(a),
|
|
545
|
+
...Object.getOwnPropertySymbols(a),
|
|
546
|
+
]
|
|
547
|
+
.filter((key) => key in b)
|
|
548
|
+
.map((key) => [key, a[key as string]]) as Array<[string, unknown]>;
|
|
549
|
+
for (const [key, value] of entries) {
|
|
550
|
+
// On array references, build a filtered array and filter nested objects inside
|
|
551
|
+
if (Array.isArray(value)) {
|
|
552
|
+
const subset = (b as loose)[key];
|
|
553
|
+
if (Array.isArray(subset)) {
|
|
554
|
+
filtered[key] = fn({ ...value }, { ...subset });
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
} // On regexp references, keep value as it to avoid loosing pattern and flags
|
|
558
|
+
else if (value instanceof RegExp) {
|
|
559
|
+
filtered[key] = value;
|
|
560
|
+
continue;
|
|
561
|
+
} // On nested objects references, build a filtered object recursively
|
|
562
|
+
else if (typeof value === "object") {
|
|
563
|
+
const subset = (b as loose)[key];
|
|
564
|
+
if ((typeof subset === "object") && (subset)) {
|
|
565
|
+
// When both operands are maps, build a filtered map with common keys and filter nested objects inside
|
|
566
|
+
if ((value instanceof Map) && (subset instanceof Map)) {
|
|
567
|
+
filtered[key] = new Map(
|
|
568
|
+
[...value].filter(([k]) => subset.has(k)).map((
|
|
569
|
+
[k, v],
|
|
570
|
+
) => [k, typeof v === "object" ? fn(v, subset.get(k)) : v]),
|
|
571
|
+
);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
// When both operands are set, build a filtered set with common values
|
|
575
|
+
if ((value instanceof Set) && (subset instanceof Set)) {
|
|
576
|
+
filtered[key] = new Set([...value].filter((v) => subset.has(v)));
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
filtered[key] = fn(value as loose, subset as loose);
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
filtered[key] = value;
|
|
584
|
+
}
|
|
585
|
+
return filtered;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return assertEquals(
|
|
589
|
+
// get the intersection of "actual" and "expected"
|
|
590
|
+
// side effect: all the instances' constructor field is "Object" now.
|
|
591
|
+
filter(actual, expected),
|
|
592
|
+
// set (nested) instances' constructor field to be "Object" without changing expected value.
|
|
593
|
+
// see https://github.com/denoland/deno_std/pull/1419
|
|
594
|
+
filter(expected, expected),
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Forcefully throws a failed assertion
|
|
600
|
+
*/
|
|
601
|
+
export function fail(msg?: string): never {
|
|
602
|
+
assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Make an assertion that `error` is an `Error`.
|
|
607
|
+
* If not then an error will be thrown.
|
|
608
|
+
* An error class and a string that should be included in the
|
|
609
|
+
* error message can also be asserted.
|
|
610
|
+
*/
|
|
611
|
+
export function assertIsError<E extends Error = Error>(
|
|
612
|
+
error: unknown,
|
|
613
|
+
// deno-lint-ignore no-explicit-any
|
|
614
|
+
ErrorClass?: new (...args: any[]) => E,
|
|
615
|
+
msgIncludes?: string,
|
|
616
|
+
msg?: string,
|
|
617
|
+
): asserts error is E {
|
|
618
|
+
if (error instanceof Error === false) {
|
|
619
|
+
throw new AssertionError(`Expected "error" to be an Error object.`);
|
|
620
|
+
}
|
|
621
|
+
if (ErrorClass && !(error instanceof ErrorClass)) {
|
|
622
|
+
msg = `Expected error to be instance of "${ErrorClass.name}", but was "${
|
|
623
|
+
typeof error === "object" ? error?.constructor?.name : "[not an object]"
|
|
624
|
+
}"${msg ? `: ${msg}` : "."}`;
|
|
625
|
+
throw new AssertionError(msg);
|
|
626
|
+
}
|
|
627
|
+
if (
|
|
628
|
+
msgIncludes && (!(error instanceof Error) ||
|
|
629
|
+
!stripColor(error.message).includes(stripColor(msgIncludes)))
|
|
630
|
+
) {
|
|
631
|
+
msg = `Expected error message to include "${msgIncludes}", but got "${
|
|
632
|
+
error instanceof Error ? error.message : "[not an Error]"
|
|
633
|
+
}"${msg ? `: ${msg}` : "."}`;
|
|
634
|
+
throw new AssertionError(msg);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Executes a function, expecting it to throw. If it does not, then it
|
|
640
|
+
* throws.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```ts
|
|
644
|
+
* import { assertThrows } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
645
|
+
*
|
|
646
|
+
* Deno.test("doesThrow", function (): void {
|
|
647
|
+
* assertThrows((): void => {
|
|
648
|
+
* throw new TypeError("hello world!");
|
|
649
|
+
* });
|
|
650
|
+
* });
|
|
651
|
+
*
|
|
652
|
+
* // This test will not pass.
|
|
653
|
+
* Deno.test("fails", function (): void {
|
|
654
|
+
* assertThrows((): void => {
|
|
655
|
+
* console.log("Hello world");
|
|
656
|
+
* });
|
|
657
|
+
* });
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
export function assertThrows(
|
|
661
|
+
fn: () => unknown,
|
|
662
|
+
msg?: string,
|
|
663
|
+
): unknown;
|
|
664
|
+
/**
|
|
665
|
+
* Executes a function, expecting it to throw. If it does not, then it
|
|
666
|
+
* throws. An error class and a string that should be included in the
|
|
667
|
+
* error message can also be asserted.
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
*
|
|
671
|
+
* ```ts
|
|
672
|
+
* import { assertThrows } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
673
|
+
*
|
|
674
|
+
* Deno.test("doesThrow", function (): void {
|
|
675
|
+
* assertThrows((): void => {
|
|
676
|
+
* throw new TypeError("hello world!");
|
|
677
|
+
* }, TypeError);
|
|
678
|
+
* assertThrows(
|
|
679
|
+
* (): void => {
|
|
680
|
+
* throw new TypeError("hello world!");
|
|
681
|
+
* },
|
|
682
|
+
* TypeError,
|
|
683
|
+
* "hello",
|
|
684
|
+
* );
|
|
685
|
+
* });
|
|
686
|
+
*
|
|
687
|
+
* // This test will not pass.
|
|
688
|
+
* Deno.test("fails", function (): void {
|
|
689
|
+
* assertThrows((): void => {
|
|
690
|
+
* console.log("Hello world");
|
|
691
|
+
* });
|
|
692
|
+
* });
|
|
693
|
+
* ```
|
|
694
|
+
*/
|
|
695
|
+
export function assertThrows<E extends Error = Error>(
|
|
696
|
+
fn: () => unknown,
|
|
697
|
+
// deno-lint-ignore no-explicit-any
|
|
698
|
+
ErrorClass: new (...args: any[]) => E,
|
|
699
|
+
msgIncludes?: string,
|
|
700
|
+
msg?: string,
|
|
701
|
+
): E;
|
|
702
|
+
export function assertThrows<E extends Error = Error>(
|
|
703
|
+
fn: () => unknown,
|
|
704
|
+
errorClassOrMsg?:
|
|
705
|
+
// deno-lint-ignore no-explicit-any
|
|
706
|
+
| (new (...args: any[]) => E)
|
|
707
|
+
| string,
|
|
708
|
+
msgIncludesOrMsg?: string,
|
|
709
|
+
msg?: string,
|
|
710
|
+
): E | Error | unknown {
|
|
711
|
+
// deno-lint-ignore no-explicit-any
|
|
712
|
+
let ErrorClass: (new (...args: any[]) => E) | undefined = undefined;
|
|
713
|
+
let msgIncludes: string | undefined = undefined;
|
|
714
|
+
let err;
|
|
715
|
+
|
|
716
|
+
if (typeof errorClassOrMsg !== "string") {
|
|
717
|
+
if (
|
|
718
|
+
errorClassOrMsg === undefined ||
|
|
719
|
+
errorClassOrMsg.prototype instanceof Error ||
|
|
720
|
+
errorClassOrMsg.prototype === Error.prototype
|
|
721
|
+
) {
|
|
722
|
+
// deno-lint-ignore no-explicit-any
|
|
723
|
+
ErrorClass = errorClassOrMsg as new (...args: any[]) => E;
|
|
724
|
+
msgIncludes = msgIncludesOrMsg;
|
|
725
|
+
} else {
|
|
726
|
+
msg = msgIncludesOrMsg;
|
|
727
|
+
}
|
|
728
|
+
} else {
|
|
729
|
+
msg = errorClassOrMsg;
|
|
730
|
+
}
|
|
731
|
+
let doesThrow = false;
|
|
732
|
+
const msgToAppendToError = msg ? `: ${msg}` : ".";
|
|
733
|
+
try {
|
|
734
|
+
fn();
|
|
735
|
+
} catch (error) {
|
|
736
|
+
if (ErrorClass) {
|
|
737
|
+
if (error instanceof Error === false) {
|
|
738
|
+
throw new AssertionError("A non-Error object was thrown.");
|
|
739
|
+
}
|
|
740
|
+
assertIsError(
|
|
741
|
+
error,
|
|
742
|
+
ErrorClass,
|
|
743
|
+
msgIncludes,
|
|
744
|
+
msg,
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
err = error;
|
|
748
|
+
doesThrow = true;
|
|
749
|
+
}
|
|
750
|
+
if (!doesThrow) {
|
|
751
|
+
msg = `Expected function to throw${msgToAppendToError}`;
|
|
752
|
+
throw new AssertionError(msg);
|
|
753
|
+
}
|
|
754
|
+
return err;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Executes a function which returns a promise, expecting it to reject.
|
|
759
|
+
*
|
|
760
|
+
* @example
|
|
761
|
+
* ```ts
|
|
762
|
+
* import { assertRejects } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
763
|
+
*
|
|
764
|
+
* Deno.test("doesThrow", async function () {
|
|
765
|
+
* await assertRejects(
|
|
766
|
+
* async () => {
|
|
767
|
+
* throw new TypeError("hello world!");
|
|
768
|
+
* },
|
|
769
|
+
* );
|
|
770
|
+
* await assertRejects(
|
|
771
|
+
* async () => {
|
|
772
|
+
* return Promise.reject(new Error());
|
|
773
|
+
* },
|
|
774
|
+
* );
|
|
775
|
+
* });
|
|
776
|
+
*
|
|
777
|
+
* // This test will not pass.
|
|
778
|
+
* Deno.test("fails", async function () {
|
|
779
|
+
* await assertRejects(
|
|
780
|
+
* async () => {
|
|
781
|
+
* console.log("Hello world");
|
|
782
|
+
* },
|
|
783
|
+
* );
|
|
784
|
+
* });
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
export function assertRejects(
|
|
788
|
+
fn: () => PromiseLike<unknown>,
|
|
789
|
+
msg?: string,
|
|
790
|
+
): Promise<unknown>;
|
|
791
|
+
/**
|
|
792
|
+
* Executes a function which returns a promise, expecting it to reject.
|
|
793
|
+
* If it does not, then it throws. An error class and a string that should be
|
|
794
|
+
* included in the error message can also be asserted.
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```ts
|
|
798
|
+
* import { assertRejects } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
|
|
799
|
+
*
|
|
800
|
+
* Deno.test("doesThrow", async function () {
|
|
801
|
+
* await assertRejects(async () => {
|
|
802
|
+
* throw new TypeError("hello world!");
|
|
803
|
+
* }, TypeError);
|
|
804
|
+
* await assertRejects(
|
|
805
|
+
* async () => {
|
|
806
|
+
* throw new TypeError("hello world!");
|
|
807
|
+
* },
|
|
808
|
+
* TypeError,
|
|
809
|
+
* "hello",
|
|
810
|
+
* );
|
|
811
|
+
* });
|
|
812
|
+
*
|
|
813
|
+
* // This test will not pass.
|
|
814
|
+
* Deno.test("fails", async function () {
|
|
815
|
+
* await assertRejects(
|
|
816
|
+
* async () => {
|
|
817
|
+
* console.log("Hello world");
|
|
818
|
+
* },
|
|
819
|
+
* );
|
|
820
|
+
* });
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
export function assertRejects<E extends Error = Error>(
|
|
824
|
+
fn: () => PromiseLike<unknown>,
|
|
825
|
+
// deno-lint-ignore no-explicit-any
|
|
826
|
+
ErrorClass: new (...args: any[]) => E,
|
|
827
|
+
msgIncludes?: string,
|
|
828
|
+
msg?: string,
|
|
829
|
+
): Promise<E>;
|
|
830
|
+
export async function assertRejects<E extends Error = Error>(
|
|
831
|
+
fn: () => PromiseLike<unknown>,
|
|
832
|
+
errorClassOrMsg?:
|
|
833
|
+
// deno-lint-ignore no-explicit-any
|
|
834
|
+
| (new (...args: any[]) => E)
|
|
835
|
+
| string,
|
|
836
|
+
msgIncludesOrMsg?: string,
|
|
837
|
+
msg?: string,
|
|
838
|
+
): Promise<E | Error | unknown> {
|
|
839
|
+
// deno-lint-ignore no-explicit-any
|
|
840
|
+
let ErrorClass: (new (...args: any[]) => E) | undefined = undefined;
|
|
841
|
+
let msgIncludes: string | undefined = undefined;
|
|
842
|
+
let err;
|
|
843
|
+
|
|
844
|
+
if (typeof errorClassOrMsg !== "string") {
|
|
845
|
+
if (
|
|
846
|
+
errorClassOrMsg === undefined ||
|
|
847
|
+
errorClassOrMsg.prototype instanceof Error ||
|
|
848
|
+
errorClassOrMsg.prototype === Error.prototype
|
|
849
|
+
) {
|
|
850
|
+
// deno-lint-ignore no-explicit-any
|
|
851
|
+
ErrorClass = errorClassOrMsg as new (...args: any[]) => E;
|
|
852
|
+
msgIncludes = msgIncludesOrMsg;
|
|
853
|
+
}
|
|
854
|
+
} else {
|
|
855
|
+
msg = errorClassOrMsg;
|
|
856
|
+
}
|
|
857
|
+
let doesThrow = false;
|
|
858
|
+
let isPromiseReturned = false;
|
|
859
|
+
const msgToAppendToError = msg ? `: ${msg}` : ".";
|
|
860
|
+
try {
|
|
861
|
+
const possiblePromise = fn();
|
|
862
|
+
if (
|
|
863
|
+
possiblePromise &&
|
|
864
|
+
typeof possiblePromise === "object" &&
|
|
865
|
+
typeof possiblePromise.then === "function"
|
|
866
|
+
) {
|
|
867
|
+
isPromiseReturned = true;
|
|
868
|
+
await possiblePromise;
|
|
869
|
+
}
|
|
870
|
+
} catch (error) {
|
|
871
|
+
if (!isPromiseReturned) {
|
|
872
|
+
throw new AssertionError(
|
|
873
|
+
`Function throws when expected to reject${msgToAppendToError}`,
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
if (ErrorClass) {
|
|
877
|
+
if (error instanceof Error === false) {
|
|
878
|
+
throw new AssertionError("A non-Error object was rejected.");
|
|
879
|
+
}
|
|
880
|
+
assertIsError(
|
|
881
|
+
error,
|
|
882
|
+
ErrorClass,
|
|
883
|
+
msgIncludes,
|
|
884
|
+
msg,
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
err = error;
|
|
888
|
+
doesThrow = true;
|
|
889
|
+
}
|
|
890
|
+
if (!doesThrow) {
|
|
891
|
+
throw new AssertionError(
|
|
892
|
+
`Expected function to reject${msgToAppendToError}`,
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
return err;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/** Use this to stub out methods that will throw when invoked. */
|
|
899
|
+
export function unimplemented(msg?: string): never {
|
|
900
|
+
throw new AssertionError(msg || "unimplemented");
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/** Use this to assert unreachable code. */
|
|
904
|
+
export function unreachable(): never {
|
|
905
|
+
throw new AssertionError("unreachable");
|
|
906
|
+
}
|