summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml1
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/tests/integration/run_tests.rs4
-rw-r--r--cli/tests/testdata/error_cause_recursive_aggregate.ts.out1
-rw-r--r--cli/tests/testdata/error_cause_recursive_tail.ts.out2
-rw-r--r--cli/tests/testdata/eval/dyn_import_eval.out1
-rw-r--r--cli/tests/testdata/import_attributes/dynamic_error.out1
-rw-r--r--cli/tests/testdata/import_attributes/static_error.out1
-rw-r--r--cli/tests/testdata/import_attributes/static_export.out1
-rw-r--r--cli/tests/testdata/import_attributes/static_import.out1
-rw-r--r--cli/tests/testdata/info/031_info_ts_error.out1
-rw-r--r--cli/tests/testdata/info/065_import_map_info.out1
-rw-r--r--cli/tests/testdata/run/003_relative_import.ts.out1
-rw-r--r--cli/tests/testdata/run/020_json_modules.ts.out1
-rw-r--r--cli/tests/testdata/run/070_location.ts.out3
-rw-r--r--cli/tests/testdata/run/071_location_unset.ts.out3
-rw-r--r--cli/tests/testdata/run/079_location_authentication.ts.out2
-rw-r--r--cli/tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out1
-rw-r--r--cli/tests/testdata/run/error_026_remote_import_error.ts.out4
-rw-r--r--cli/tests/testdata/run/error_cause.ts.out2
-rw-r--r--cli/tests/testdata/run/error_cause_recursive.ts.out1
-rw-r--r--cli/tests/testdata/run/error_missing_module_named_import.ts.out1
-rw-r--r--cli/tests/testdata/run/fix_emittable_skipped.ts.out1
-rw-r--r--cli/tests/testdata/run/import_blob_url_error_stack.ts.out3
-rw-r--r--cli/tests/testdata/run/import_data_url_error_stack.ts.out3
-rw-r--r--cli/tests/testdata/run/import_extensionless.ts.out1
-rw-r--r--cli/tests/testdata/run/import_type.ts.out1
-rw-r--r--cli/tests/testdata/run/issue13562.ts.out1
-rw-r--r--cli/tests/testdata/run/mts_dmts_mjs.out1
-rw-r--r--cli/tests/testdata/run/private_field_presence.ts.out1
-rw-r--r--cli/tests/testdata/run/unbuffered_stderr.ts.out1
-rw-r--r--cli/tests/testdata/run/webstorage/serialization.ts.out1
-rw-r--r--cli/tests/testdata/task/deno_json/task_deno_exe_no_env.out1
-rw-r--r--cli/tests/testdata/task/deno_json/task_piped_stdin.out1
-rw-r--r--cli/tests/testdata/test/steps/failing_steps.dot.out1
-rw-r--r--cli/tests/testdata/test/steps/ignored_steps.dot.out1
-rw-r--r--cli/tests/testdata/workers/custom_inspect/main.out3
-rw-r--r--cli/tests/testdata/workers/error_worker_permissions_local.ts.out1
-rw-r--r--cli/tests/testdata/workers/error_worker_permissions_remote.ts.out1
-rw-r--r--test_util/Cargo.toml2
-rw-r--r--test_util/src/assertions.rs41
-rw-r--r--test_util/src/lib.rs403
43 files changed, 402 insertions, 105 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 42b608bb0..1b56cd78f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5455,6 +5455,7 @@ dependencies = [
"lazy-regex",
"libc",
"lsp-types",
+ "monch",
"nix 0.26.2",
"once_cell",
"os_pipe",
@@ -5471,6 +5472,7 @@ dependencies = [
"serde_json",
"tar",
"tempfile",
+ "termcolor",
"tokio",
"tokio-rustls",
"url",
diff --git a/Cargo.toml b/Cargo.toml
index 707a974ba..402b6e507 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -105,6 +105,7 @@ libc = "0.2.126"
log = "=0.4.20"
lsp-types = "=0.93.2" # used by tower-lsp and "proposed" feature is unstable in patch releases
memmem = "0.1.1"
+monch = "=0.4.3"
notify = "=5.0.0"
num-bigint = { version = "0.4", features = ["rand"] }
once_cell = "1.17.1"
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 42f868ef9..8906488e9 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -93,7 +93,7 @@ lazy-regex.workspace = true
libc.workspace = true
log = { workspace = true, features = ["serde"] }
lsp-types.workspace = true
-monch = "=0.4.3"
+monch.workspace = true
notify.workspace = true
once_cell.workspace = true
os_pipe.workspace = true
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 0edfe1c48..be9bc554a 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -870,7 +870,7 @@ itest!(lock_write_fetch {
itest!(lock_check_ok {
args:
- "run --lock=run/lock_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts",
+ "run --quiet --lock=run/lock_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts",
output: "run/003_relative_import.ts.out",
http_server: true,
});
@@ -917,7 +917,7 @@ itest!(lock_flag_overrides_config_file_lock_path {
itest!(lock_v2_check_ok {
args:
- "run --lock=run/lock_v2_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts",
+ "run --quiet --lock=run/lock_v2_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts",
output: "run/003_relative_import.ts.out",
http_server: true,
});
diff --git a/cli/tests/testdata/error_cause_recursive_aggregate.ts.out b/cli/tests/testdata/error_cause_recursive_aggregate.ts.out
index bf1e45e51..652403e4a 100644
--- a/cli/tests/testdata/error_cause_recursive_aggregate.ts.out
+++ b/cli/tests/testdata/error_cause_recursive_aggregate.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught AggregateError
Error: bar <ref *1>
at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:2:13
diff --git a/cli/tests/testdata/error_cause_recursive_tail.ts.out b/cli/tests/testdata/error_cause_recursive_tail.ts.out
index 48b65d3f4..e19fa39bc 100644
--- a/cli/tests/testdata/error_cause_recursive_tail.ts.out
+++ b/cli/tests/testdata/error_cause_recursive_tail.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught Error: baz
const baz = new Error("baz", { cause: bar });
^
@@ -8,4 +7,3 @@ Caused by: Error: bar <ref *1>
Caused by: Error: foo
at file:///[WILDCARD]/error_cause_recursive_tail.ts:1:13
Caused by: [Circular *1]
-[WILDCARD]
diff --git a/cli/tests/testdata/eval/dyn_import_eval.out b/cli/tests/testdata/eval/dyn_import_eval.out
index bbc53b558..89e16b478 100644
--- a/cli/tests/testdata/eval/dyn_import_eval.out
+++ b/cli/tests/testdata/eval/dyn_import_eval.out
@@ -1,2 +1 @@
-[WILDCARD]
[Module: null prototype] { isMod4: true }
diff --git a/cli/tests/testdata/import_attributes/dynamic_error.out b/cli/tests/testdata/import_attributes/dynamic_error.out
index 927eae0b8..d6e0c9115 100644
--- a/cli/tests/testdata/import_attributes/dynamic_error.out
+++ b/cli/tests/testdata/import_attributes/dynamic_error.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught (in promise) TypeError: Expected a "JavaScriptOrWasm" module but loaded a "JSON" module.
const data = await import("./data.json");
^
diff --git a/cli/tests/testdata/import_attributes/static_error.out b/cli/tests/testdata/import_attributes/static_error.out
index 171ae0c1a..29b24b965 100644
--- a/cli/tests/testdata/import_attributes/static_error.out
+++ b/cli/tests/testdata/import_attributes/static_error.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Expected a JavaScript or TypeScript module, but identified a Json module. Consider importing Json modules with an import attribute with the type of "json".
Specifier: [WILDCARD]/data.json
at [WILDCARD]static_error.ts:1:18
diff --git a/cli/tests/testdata/import_attributes/static_export.out b/cli/tests/testdata/import_attributes/static_export.out
index 42fbc066c..41af79d7c 100644
--- a/cli/tests/testdata/import_attributes/static_export.out
+++ b/cli/tests/testdata/import_attributes/static_export.out
@@ -1,2 +1 @@
-[WILDCARD]
{ a: "b", c: { d: 10 } }
diff --git a/cli/tests/testdata/import_attributes/static_import.out b/cli/tests/testdata/import_attributes/static_import.out
index b3b71cd8f..e57dffa99 100644
--- a/cli/tests/testdata/import_attributes/static_import.out
+++ b/cli/tests/testdata/import_attributes/static_import.out
@@ -1,3 +1,2 @@
-[WILDCARD]
{ a: "b", c: { d: 10 } }
{ a: "b", c: { d: 10 } }
diff --git a/cli/tests/testdata/info/031_info_ts_error.out b/cli/tests/testdata/info/031_info_ts_error.out
index 49df50012..81edd0032 100644
--- a/cli/tests/testdata/info/031_info_ts_error.out
+++ b/cli/tests/testdata/info/031_info_ts_error.out
@@ -1,4 +1,3 @@
-[WILDCARD]
local: [WILDCARD]031_info_ts_error.ts
type: TypeScript
dependencies: 0 unique
diff --git a/cli/tests/testdata/info/065_import_map_info.out b/cli/tests/testdata/info/065_import_map_info.out
index 657510b89..68d98f14a 100644
--- a/cli/tests/testdata/info/065_import_map_info.out
+++ b/cli/tests/testdata/info/065_import_map_info.out
@@ -1,4 +1,3 @@
-[WILDCARD]
local: [WILDCARD]test.ts
type: TypeScript
dependencies: 7 unique
diff --git a/cli/tests/testdata/run/003_relative_import.ts.out b/cli/tests/testdata/run/003_relative_import.ts.out
index 699b756ed..e965047ad 100644
--- a/cli/tests/testdata/run/003_relative_import.ts.out
+++ b/cli/tests/testdata/run/003_relative_import.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
Hello
diff --git a/cli/tests/testdata/run/020_json_modules.ts.out b/cli/tests/testdata/run/020_json_modules.ts.out
index 750363da2..948901724 100644
--- a/cli/tests/testdata/run/020_json_modules.ts.out
+++ b/cli/tests/testdata/run/020_json_modules.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Expected a JavaScript or TypeScript module, but identified a Json module. Consider importing Json modules with an import attribute with the type of "json".
Specifier: [WILDCARD]/subdir/config.json
[WILDCARD] \ No newline at end of file
diff --git a/cli/tests/testdata/run/070_location.ts.out b/cli/tests/testdata/run/070_location.ts.out
index 6827a555d..a03cf6477 100644
--- a/cli/tests/testdata/run/070_location.ts.out
+++ b/cli/tests/testdata/run/070_location.ts.out
@@ -1,4 +1,4 @@
-[WILDCARD][class Location]
+[class Location]
Object [Location] {}
Location {
hash: "#bat",
@@ -13,4 +13,3 @@ Location {
}
NotSupportedError: Cannot set "location".
NotSupportedError: Cannot set "location.hostname".
-[WILDCARD]
diff --git a/cli/tests/testdata/run/071_location_unset.ts.out b/cli/tests/testdata/run/071_location_unset.ts.out
index cf4a9d605..c9482011f 100644
--- a/cli/tests/testdata/run/071_location_unset.ts.out
+++ b/cli/tests/testdata/run/071_location_unset.ts.out
@@ -1,5 +1,4 @@
-[WILDCARD][class Location]
+[class Location]
Object [Location] {}
undefined
/bar
-[WILDCARD]
diff --git a/cli/tests/testdata/run/079_location_authentication.ts.out b/cli/tests/testdata/run/079_location_authentication.ts.out
index bb2458497..0dd73f999 100644
--- a/cli/tests/testdata/run/079_location_authentication.ts.out
+++ b/cli/tests/testdata/run/079_location_authentication.ts.out
@@ -1,3 +1 @@
-[WILDCARD]
https://baz/qux
-[WILDCARD]
diff --git a/cli/tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out b/cli/tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out
index 6e82ad410..7f35b8b4f 100644
--- a/cli/tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out
+++ b/cli/tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught (in promise) TypeError: Relative import path "unmapped" not prefixed with / or ./ or ../ and not in import map from "file://[WILDCARD]/092_import_map_unmapped_bare_specifier.ts"
at file://[WILDCARD]/092_import_map_unmapped_bare_specifier.ts:1:14
diff --git a/cli/tests/testdata/run/error_026_remote_import_error.ts.out b/cli/tests/testdata/run/error_026_remote_import_error.ts.out
index 84f926f24..cc88284af 100644
--- a/cli/tests/testdata/run/error_026_remote_import_error.ts.out
+++ b/cli/tests/testdata/run/error_026_remote_import_error.ts.out
@@ -1,7 +1,7 @@
-[WILDCARD]error: Uncaught Error: bad
+[WILDCARD]
+error: Uncaught Error: bad
throw Error("bad");
^
at foo (http://localhost:4545/run/error_001.ts:2:9)
at bar (http://localhost:4545/run/error_001.ts:6:3)
at http://localhost:4545/run/error_001.ts:9:1
-[WILDCARD]
diff --git a/cli/tests/testdata/run/error_cause.ts.out b/cli/tests/testdata/run/error_cause.ts.out
index 2aab020d9..6a8555646 100644
--- a/cli/tests/testdata/run/error_cause.ts.out
+++ b/cli/tests/testdata/run/error_cause.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught Error: foo
throw new Error("foo", { cause: new Error("bar", { cause: "deno" as any }) });
^
@@ -12,4 +11,3 @@ Caused by: Error: bar
at c (file:///[WILDCARD]/error_cause.ts:11:3)
at file:///[WILDCARD]/error_cause.ts:14:1
Caused by: "deno"
-[WILDCARD]
diff --git a/cli/tests/testdata/run/error_cause_recursive.ts.out b/cli/tests/testdata/run/error_cause_recursive.ts.out
index 3ae440cf7..9c381a974 100644
--- a/cli/tests/testdata/run/error_cause_recursive.ts.out
+++ b/cli/tests/testdata/run/error_cause_recursive.ts.out
@@ -1,4 +1,3 @@
-[WILDCARD]
error: Uncaught Error: bar <ref *1>
const y = new Error("bar", { cause: x });
^
diff --git a/cli/tests/testdata/run/error_missing_module_named_import.ts.out b/cli/tests/testdata/run/error_missing_module_named_import.ts.out
index 3dccaffb1..700377d65 100644
--- a/cli/tests/testdata/run/error_missing_module_named_import.ts.out
+++ b/cli/tests/testdata/run/error_missing_module_named_import.ts.out
@@ -1,3 +1,2 @@
-[WILDCARD]
error: Module not found "file://[WILDCARD]/does_not_exist.js".
at file:///[WILDCARD]/error_missing_module_named_import.ts:[WILDCARD]
diff --git a/cli/tests/testdata/run/fix_emittable_skipped.ts.out b/cli/tests/testdata/run/fix_emittable_skipped.ts.out
index 8b31d3dbc..865759299 100644
--- a/cli/tests/testdata/run/fix_emittable_skipped.ts.out
+++ b/cli/tests/testdata/run/fix_emittable_skipped.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
[Function (anonymous)]
diff --git a/cli/tests/testdata/run/import_blob_url_error_stack.ts.out b/cli/tests/testdata/run/import_blob_url_error_stack.ts.out
index 52b76fd5c..201556b8a 100644
--- a/cli/tests/testdata/run/import_blob_url_error_stack.ts.out
+++ b/cli/tests/testdata/run/import_blob_url_error_stack.ts.out
@@ -1,6 +1,5 @@
-[WILDCARD]error: Uncaught (in promise) Error: Hello 2
+error: Uncaught (in promise) Error: Hello 2
throw new Error(`Hello ${A.C}`);
^
at a (blob:null/[WILDCARD]:8:10)
at file:///[WILDCARD]/import_blob_url_error_stack.ts:13:1
-[WILDCARD]
diff --git a/cli/tests/testdata/run/import_data_url_error_stack.ts.out b/cli/tests/testdata/run/import_data_url_error_stack.ts.out
index ccd72e4ad..e79b52b30 100644
--- a/cli/tests/testdata/run/import_data_url_error_stack.ts.out
+++ b/cli/tests/testdata/run/import_data_url_error_stack.ts.out
@@ -1,6 +1,5 @@
-[WILDCARD]error: Uncaught Error: Hello 2
+error: Uncaught Error: Hello 2
throw new Error(`Hello ${A.C}`);
^
at a (data:application/typescript;base64,ZW51bSBBIHsKICBBLAog......JHtBLkN9YCk7CiB9CiA=:8:10)
at file:///[WILDCARD]/import_data_url_error_stack.ts:3:1
-[WILDCARD]
diff --git a/cli/tests/testdata/run/import_extensionless.ts.out b/cli/tests/testdata/run/import_extensionless.ts.out
index 699b756ed..e965047ad 100644
--- a/cli/tests/testdata/run/import_extensionless.ts.out
+++ b/cli/tests/testdata/run/import_extensionless.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
Hello
diff --git a/cli/tests/testdata/run/import_type.ts.out b/cli/tests/testdata/run/import_type.ts.out
index 188c5e25d..e35539e35 100644
--- a/cli/tests/testdata/run/import_type.ts.out
+++ b/cli/tests/testdata/run/import_type.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
B { a: "a" }
diff --git a/cli/tests/testdata/run/issue13562.ts.out b/cli/tests/testdata/run/issue13562.ts.out
index 699b756ed..e965047ad 100644
--- a/cli/tests/testdata/run/issue13562.ts.out
+++ b/cli/tests/testdata/run/issue13562.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
Hello
diff --git a/cli/tests/testdata/run/mts_dmts_mjs.out b/cli/tests/testdata/run/mts_dmts_mjs.out
index 5647bdfb9..789819226 100644
--- a/cli/tests/testdata/run/mts_dmts_mjs.out
+++ b/cli/tests/testdata/run/mts_dmts_mjs.out
@@ -1,2 +1 @@
-[WILDCARD]
a
diff --git a/cli/tests/testdata/run/private_field_presence.ts.out b/cli/tests/testdata/run/private_field_presence.ts.out
index f582fb47a..1d474d525 100644
--- a/cli/tests/testdata/run/private_field_presence.ts.out
+++ b/cli/tests/testdata/run/private_field_presence.ts.out
@@ -1,3 +1,2 @@
-[WILDCARD]
false
true
diff --git a/cli/tests/testdata/run/unbuffered_stderr.ts.out b/cli/tests/testdata/run/unbuffered_stderr.ts.out
index 500019738..c1b0730e0 100644
--- a/cli/tests/testdata/run/unbuffered_stderr.ts.out
+++ b/cli/tests/testdata/run/unbuffered_stderr.ts.out
@@ -1,2 +1 @@
-[WILDCARD]
x \ No newline at end of file
diff --git a/cli/tests/testdata/run/webstorage/serialization.ts.out b/cli/tests/testdata/run/webstorage/serialization.ts.out
index fea76aa43..b5581828f 100644
--- a/cli/tests/testdata/run/webstorage/serialization.ts.out
+++ b/cli/tests/testdata/run/webstorage/serialization.ts.out
@@ -1,3 +1,2 @@
-[WILDCARD]
Storage {[WILDCARD]
Storage { length: 1, hello: "deno" }
diff --git a/cli/tests/testdata/task/deno_json/task_deno_exe_no_env.out b/cli/tests/testdata/task/deno_json/task_deno_exe_no_env.out
index cf4a51b68..7ed6ff82d 100644
--- a/cli/tests/testdata/task/deno_json/task_deno_exe_no_env.out
+++ b/cli/tests/testdata/task/deno_json/task_deno_exe_no_env.out
@@ -1,2 +1 @@
-[WILDCARD]
5
diff --git a/cli/tests/testdata/task/deno_json/task_piped_stdin.out b/cli/tests/testdata/task/deno_json/task_piped_stdin.out
index f0a236c86..a0d636f15 100644
--- a/cli/tests/testdata/task/deno_json/task_piped_stdin.out
+++ b/cli/tests/testdata/task/deno_json/task_piped_stdin.out
@@ -1,3 +1,2 @@
-[WILDCARD]
Uint8Array(1) [ 49 ]
Uint8Array(1) [ 50 ]
diff --git a/cli/tests/testdata/test/steps/failing_steps.dot.out b/cli/tests/testdata/test/steps/failing_steps.dot.out
index 3895a967e..f8ba8d8e6 100644
--- a/cli/tests/testdata/test/steps/failing_steps.dot.out
+++ b/cli/tests/testdata/test/steps/failing_steps.dot.out
@@ -1,4 +1,3 @@
-[WILDCARD]
!
.
!
diff --git a/cli/tests/testdata/test/steps/ignored_steps.dot.out b/cli/tests/testdata/test/steps/ignored_steps.dot.out
index e3d3865d4..442a06c62 100644
--- a/cli/tests/testdata/test/steps/ignored_steps.dot.out
+++ b/cli/tests/testdata/test/steps/ignored_steps.dot.out
@@ -1,4 +1,3 @@
-[WILDCARD]
,
.
.
diff --git a/cli/tests/testdata/workers/custom_inspect/main.out b/cli/tests/testdata/workers/custom_inspect/main.out
index b34300c40..40d9b88ad 100644
--- a/cli/tests/testdata/workers/custom_inspect/main.out
+++ b/cli/tests/testdata/workers/custom_inspect/main.out
@@ -1,2 +1 @@
-[WILDCARD]ReadableStream { locked: false }
-[WILDCARD]
+ReadableStream { locked: false }
diff --git a/cli/tests/testdata/workers/error_worker_permissions_local.ts.out b/cli/tests/testdata/workers/error_worker_permissions_local.ts.out
index e6404e8e3..cacc8ae38 100644
--- a/cli/tests/testdata/workers/error_worker_permissions_local.ts.out
+++ b/cli/tests/testdata/workers/error_worker_permissions_local.ts.out
@@ -1,3 +1,2 @@
-[WILDCARD]
error: Uncaught (in worker "") Requires read access to "[WILDCARD]worker_types.ts", run again with the --allow-read flag
[WILDCARD]
diff --git a/cli/tests/testdata/workers/error_worker_permissions_remote.ts.out b/cli/tests/testdata/workers/error_worker_permissions_remote.ts.out
index 74c7c3974..afecff0a8 100644
--- a/cli/tests/testdata/workers/error_worker_permissions_remote.ts.out
+++ b/cli/tests/testdata/workers/error_worker_permissions_remote.ts.out
@@ -1,3 +1,2 @@
-[WILDCARD]
error: Uncaught (in worker "") Requires net access to "localhost:4545", run again with the --allow-net flag
[WILDCARD]
diff --git a/test_util/Cargo.toml b/test_util/Cargo.toml
index 6ea9d870d..47f7d1d52 100644
--- a/test_util/Cargo.toml
+++ b/test_util/Cargo.toml
@@ -26,6 +26,7 @@ hyper = { workspace = true, features = ["server", "http1", "http2", "runtime"] }
lazy-regex.workspace = true
libc.workspace = true
lsp-types.workspace = true
+monch.workspace = true
nix.workspace = true
once_cell.workspace = true
os_pipe.workspace = true
@@ -41,6 +42,7 @@ serde.workspace = true
serde_json.workspace = true
tar.workspace = true
tempfile.workspace = true
+termcolor.workspace = true
tokio.workspace = true
tokio-rustls.workspace = true
url.workspace = true
diff --git a/test_util/src/assertions.rs b/test_util/src/assertions.rs
index 239e0e99c..91ac9dd1c 100644
--- a/test_util/src/assertions.rs
+++ b/test_util/src/assertions.rs
@@ -1,5 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use crate::colors;
+
#[macro_export]
macro_rules! assert_starts_with {
($string:expr, $($test:expr),+) => {
@@ -52,11 +54,40 @@ macro_rules! assert_not_contains {
#[track_caller]
pub fn assert_wildcard_match(actual: &str, expected: &str) {
- if !expected.contains("[WILDCARD]") {
+ if !expected.contains("[WILDCARD]") && !expected.contains("[IGNORE_START]") {
pretty_assertions::assert_eq!(actual, expected);
- } else if !crate::wildcard_match(expected, actual) {
- println!("OUTPUT START\n{actual}\nOUTPUT END");
- println!("EXPECTED START\n{expected}\nEXPECTED END");
- panic!("pattern match failed");
+ } else {
+ match crate::wildcard_match_detailed(expected, actual) {
+ crate::WildcardMatchResult::Success => {
+ // ignore
+ }
+ crate::WildcardMatchResult::Fail(debug_output) => {
+ println!(
+ "{}{}{}",
+ colors::bold("-- "),
+ colors::bold_red("OUTPUT"),
+ colors::bold(" START --"),
+ );
+ println!("{}", actual);
+ println!("{}", colors::bold("-- OUTPUT END --"));
+ println!(
+ "{}{}{}",
+ colors::bold("-- "),
+ colors::bold_green("EXPECTED"),
+ colors::bold(" START --"),
+ );
+ println!("{}", expected);
+ println!("{}", colors::bold("-- EXPECTED END --"));
+ println!(
+ "{}{}{}",
+ colors::bold("-- "),
+ colors::bold_blue("DEBUG"),
+ colors::bold(" START --"),
+ );
+ println!("{debug_output}");
+ println!("{}", colors::bold("-- DEBUG END --"));
+ panic!("pattern match failed");
+ }
+ }
}
}
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index fa0cb8a84..0600867d7 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -2410,57 +2410,266 @@ impl<'a> CheckOutputIntegrationTest<'a> {
}
}
-pub fn wildcard_match(pattern: &str, s: &str) -> bool {
- pattern_match(pattern, s, "[WILDCARD]")
+pub fn wildcard_match(pattern: &str, text: &str) -> bool {
+ match wildcard_match_detailed(pattern, text) {
+ WildcardMatchResult::Success => true,
+ WildcardMatchResult::Fail(debug_output) => {
+ eprintln!("{}", debug_output);
+ false
+ }
+ }
}
-pub fn pattern_match(pattern: &str, s: &str, wildcard: &str) -> bool {
- // Normalize line endings
- let mut s = s.replace("\r\n", "\n");
- let pattern = pattern.replace("\r\n", "\n");
+pub enum WildcardMatchResult {
+ Success,
+ Fail(String),
+}
- if pattern == wildcard {
- return true;
+pub fn wildcard_match_detailed(
+ pattern: &str,
+ text: &str,
+) -> WildcardMatchResult {
+ fn annotate_whitespace(text: &str) -> String {
+ text.replace('\t', "\u{2192}").replace(' ', "\u{00B7}")
}
- let parts = pattern.split(wildcard).collect::<Vec<&str>>();
- if parts.len() == 1 {
- return pattern == s;
- }
+ // Normalize line endings
+ let original_text = text.replace("\r\n", "\n");
+ let mut current_text = original_text.as_str();
+ let pattern = pattern.replace("\r\n", "\n");
+ let mut output_lines = Vec::new();
- if !s.starts_with(parts[0]) {
- return false;
- }
+ let parts = parse_wildcard_pattern_text(&pattern).unwrap();
- // If the first line of the pattern is just a wildcard the newline character
- // needs to be pre-pended so it can safely match anything or nothing and
- // continue matching.
- if pattern.lines().next() == Some(wildcard) {
- s.insert(0, '\n');
+ let mut was_last_wildcard = false;
+ for (i, part) in parts.iter().enumerate() {
+ match part {
+ WildcardPatternPart::Wildcard => {
+ output_lines.push("<WILDCARD />".to_string());
+ }
+ WildcardPatternPart::Text(search_text) => {
+ let is_last = i + 1 == parts.len();
+ let search_index = if is_last && was_last_wildcard {
+ // search from the end of the file
+ current_text.rfind(search_text)
+ } else {
+ current_text.find(search_text)
+ };
+ match search_index {
+ Some(found_index) if was_last_wildcard || found_index == 0 => {
+ output_lines.push(format!(
+ "<FOUND>{}</FOUND>",
+ colors::gray(annotate_whitespace(search_text))
+ ));
+ current_text = &current_text[found_index + search_text.len()..];
+ }
+ Some(index) => {
+ output_lines.push(
+ "==== FOUND SEARCH TEXT IN WRONG POSITION ====".to_string(),
+ );
+ output_lines.push(colors::gray(annotate_whitespace(search_text)));
+ output_lines
+ .push("==== HAD UNKNOWN PRECEEDING TEXT ====".to_string());
+ output_lines
+ .push(colors::red(annotate_whitespace(&current_text[..index])));
+ return WildcardMatchResult::Fail(output_lines.join("\n"));
+ }
+ None => {
+ let mut max_found_index = 0;
+ for (index, _) in search_text.char_indices() {
+ let sub_string = &search_text[..index];
+ if let Some(found_index) = current_text.find(sub_string) {
+ if was_last_wildcard || found_index == 0 {
+ max_found_index = index;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ if !was_last_wildcard && max_found_index > 0 {
+ output_lines.push(format!(
+ "<FOUND>{}</FOUND>",
+ colors::gray(annotate_whitespace(
+ &search_text[..max_found_index]
+ ))
+ ));
+ }
+ output_lines
+ .push("==== COULD NOT FIND SEARCH TEXT ====".to_string());
+ output_lines.push(colors::green(annotate_whitespace(
+ if was_last_wildcard {
+ search_text
+ } else {
+ &search_text[max_found_index..]
+ },
+ )));
+ if was_last_wildcard && max_found_index > 0 {
+ output_lines.push(format!(
+ "==== MAX FOUND ====\n{}",
+ colors::red(annotate_whitespace(
+ &search_text[..max_found_index]
+ ))
+ ));
+ }
+ return WildcardMatchResult::Fail(output_lines.join("\n"));
+ }
+ }
+ }
+ WildcardPatternPart::UnorderedLines(expected_lines) => {
+ assert!(!was_last_wildcard, "unsupported");
+ let mut actual_lines = Vec::with_capacity(expected_lines.len());
+ for _ in 0..expected_lines.len() {
+ match current_text.find('\n') {
+ Some(end_line_index) => {
+ actual_lines.push(&current_text[..end_line_index]);
+ current_text = &current_text[end_line_index + 1..];
+ }
+ None => {
+ break;
+ }
+ }
+ }
+ actual_lines.sort_unstable();
+ let mut expected_lines = expected_lines.clone();
+ expected_lines.sort_unstable();
+
+ if actual_lines.len() != expected_lines.len() {
+ output_lines
+ .push("==== HAD WRONG NUMBER OF UNORDERED LINES ====".to_string());
+ output_lines.push("# ACTUAL".to_string());
+ output_lines.extend(
+ actual_lines
+ .iter()
+ .map(|l| colors::green(annotate_whitespace(l))),
+ );
+ output_lines.push("# EXPECTED".to_string());
+ output_lines.extend(
+ expected_lines
+ .iter()
+ .map(|l| colors::green(annotate_whitespace(l))),
+ );
+ return WildcardMatchResult::Fail(output_lines.join("\n"));
+ }
+ for (actual, expected) in actual_lines.iter().zip(expected_lines.iter())
+ {
+ if actual != expected {
+ output_lines
+ .push("==== UNORDERED LINE DID NOT MATCH ====".to_string());
+ output_lines.push(format!(
+ " ACTUAL: {}",
+ colors::red(annotate_whitespace(actual))
+ ));
+ output_lines.push(format!(
+ "EXPECTED: {}",
+ colors::green(annotate_whitespace(expected))
+ ));
+ return WildcardMatchResult::Fail(output_lines.join("\n"));
+ }
+ }
+ output_lines.push("# Found matching unordered lines".to_string());
+ }
+ }
+ was_last_wildcard = matches!(part, WildcardPatternPart::Wildcard);
}
- let mut t = s.split_at(parts[0].len());
+ if was_last_wildcard || current_text.is_empty() {
+ WildcardMatchResult::Success
+ } else {
+ output_lines.push("==== HAD TEXT AT END OF FILE ====".to_string());
+ output_lines.push(colors::red(annotate_whitespace(current_text)));
+ WildcardMatchResult::Fail(output_lines.join("\n"))
+ }
+}
+
+#[derive(Debug)]
+enum WildcardPatternPart<'a> {
+ Wildcard,
+ Text(&'a str),
+ UnorderedLines(Vec<&'a str>),
+}
+
+fn parse_wildcard_pattern_text(
+ text: &str,
+) -> Result<Vec<WildcardPatternPart>, monch::ParseErrorFailureError> {
+ use monch::*;
+
+ fn parse_unordered_lines(input: &str) -> ParseResult<Vec<&str>> {
+ const END_TEXT: &str = "\n[UNORDERED_END]\n";
+ let (input, _) = tag("[UNORDERED_START]\n")(input)?;
+ match input.find(END_TEXT) {
+ Some(end_index) => ParseResult::Ok((
+ &input[end_index + END_TEXT.len()..],
+ input[..end_index].lines().collect::<Vec<_>>(),
+ )),
+ None => ParseError::fail(input, "Could not find [UNORDERED_END]"),
+ }
+ }
+
+ enum InnerPart<'a> {
+ Wildcard,
+ UnorderedLines(Vec<&'a str>),
+ Char,
+ }
+
+ struct Parser<'a> {
+ current_input: &'a str,
+ last_text_input: &'a str,
+ parts: Vec<WildcardPatternPart<'a>>,
+ }
+
+ impl<'a> Parser<'a> {
+ fn parse(mut self) -> ParseResult<'a, Vec<WildcardPatternPart<'a>>> {
+ while !self.current_input.is_empty() {
+ let (next_input, inner_part) = or3(
+ map(tag("[WILDCARD]"), |_| InnerPart::Wildcard),
+ map(parse_unordered_lines, |lines| {
+ InnerPart::UnorderedLines(lines)
+ }),
+ map(next_char, |_| InnerPart::Char),
+ )(self.current_input)?;
+ match inner_part {
+ InnerPart::Wildcard => {
+ self.queue_previous_text(next_input);
+ self.parts.push(WildcardPatternPart::Wildcard);
+ }
+ InnerPart::UnorderedLines(expected_lines) => {
+ self.queue_previous_text(next_input);
+ self
+ .parts
+ .push(WildcardPatternPart::UnorderedLines(expected_lines));
+ }
+ InnerPart::Char => {
+ // ignore
+ }
+ }
+ self.current_input = next_input;
+ }
- for (i, part) in parts.iter().enumerate() {
- if i == 0 {
- continue;
- }
- dbg!(part, i);
- if i == parts.len() - 1 && (part.is_empty() || *part == "\n") {
- dbg!("exit 1 true", i);
- return true;
+ self.queue_previous_text("");
+
+ ParseResult::Ok(("", self.parts))
}
- if let Some(found) = t.1.find(*part) {
- dbg!("found ", found);
- t = t.1.split_at(found + part.len());
- } else {
- dbg!("exit false ", i);
- return false;
+
+ fn queue_previous_text(&mut self, next_input: &'a str) {
+ let previous_text = &self.last_text_input
+ [..self.last_text_input.len() - self.current_input.len()];
+ if !previous_text.is_empty() {
+ self.parts.push(WildcardPatternPart::Text(previous_text));
+ }
+ self.last_text_input = next_input;
}
}
- dbg!("end ", t.1.len());
- t.1.is_empty()
+ with_failure_handling(|input| {
+ Parser {
+ current_input: input,
+ last_text_input: input,
+ parts: Vec::new(),
+ }
+ .parse()
+ })(text)
}
pub fn with_pty(deno_args: &[&str], action: impl FnMut(Pty)) {
@@ -2604,6 +2813,67 @@ pub fn parse_max_mem(output: &str) -> Option<u64> {
None
}
+pub(crate) mod colors {
+ use std::io::Write;
+
+ use termcolor::Ansi;
+ use termcolor::Color;
+ use termcolor::ColorSpec;
+ use termcolor::WriteColor;
+
+ pub fn bold<S: AsRef<str>>(s: S) -> String {
+ let mut style_spec = ColorSpec::new();
+ style_spec.set_bold(true);
+ style(s, style_spec)
+ }
+
+ pub fn red<S: AsRef<str>>(s: S) -> String {
+ fg_color(s, Color::Red)
+ }
+
+ pub fn bold_red<S: AsRef<str>>(s: S) -> String {
+ bold_fg_color(s, Color::Red)
+ }
+
+ pub fn green<S: AsRef<str>>(s: S) -> String {
+ fg_color(s, Color::Green)
+ }
+
+ pub fn bold_green<S: AsRef<str>>(s: S) -> String {
+ bold_fg_color(s, Color::Green)
+ }
+
+ pub fn bold_blue<S: AsRef<str>>(s: S) -> String {
+ bold_fg_color(s, Color::Blue)
+ }
+
+ pub fn gray<S: AsRef<str>>(s: S) -> String {
+ fg_color(s, Color::Ansi256(245))
+ }
+
+ fn bold_fg_color<S: AsRef<str>>(s: S, color: Color) -> String {
+ let mut style_spec = ColorSpec::new();
+ style_spec.set_bold(true);
+ style_spec.set_fg(Some(color));
+ style(s, style_spec)
+ }
+
+ fn fg_color<S: AsRef<str>>(s: S, color: Color) -> String {
+ let mut style_spec = ColorSpec::new();
+ style_spec.set_fg(Some(color));
+ style(s, style_spec)
+ }
+
+ fn style<S: AsRef<str>>(s: S, colorspec: ColorSpec) -> String {
+ let mut v = Vec::new();
+ let mut ansi_writer = Ansi::new(&mut v);
+ ansi_writer.set_color(&colorspec).unwrap();
+ ansi_writer.write_all(s.as_ref().as_bytes()).unwrap();
+ ansi_writer.reset().unwrap();
+ String::from_utf8_lossy(&v).into_owned()
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -2690,6 +2960,15 @@ mod tests {
}
#[test]
+ fn parse_parse_wildcard_match_text() {
+ let result =
+ parse_wildcard_pattern_text("[UNORDERED_START]\ntesting\ntesting")
+ .err()
+ .unwrap();
+ assert_contains!(result.to_string(), "Could not find [UNORDERED_END]");
+ }
+
+ #[test]
fn test_wildcard_match() {
let fixtures = vec![
("foobarbaz", "foobarbaz", true),
@@ -2733,16 +3012,15 @@ mod tests {
}
#[test]
- fn test_pattern_match() {
+ fn test_wildcard_match2() {
// foo, bar, baz, qux, quux, quuz, corge, grault, garply, waldo, fred, plugh, xyzzy
- let wildcard = "[BAR]";
- assert!(pattern_match("foo[BAR]baz", "foobarbaz", wildcard));
- assert!(!pattern_match("foo[BAR]baz", "foobazbar", wildcard));
+ assert!(wildcard_match("foo[WILDCARD]baz", "foobarbaz"));
+ assert!(!wildcard_match("foo[WILDCARD]baz", "foobazbar"));
- let multiline_pattern = "[BAR]
+ let multiline_pattern = "[WILDCARD]
foo:
-[BAR]baz[BAR]";
+[WILDCARD]baz[WILDCARD]";
fn multi_line_builder(input: &str, leading_text: Option<&str>) -> String {
// If there is leading text add a newline so it's on it's own line
@@ -2767,31 +3045,52 @@ grault",
);
// Correct input & leading line
- assert!(pattern_match(
+ assert!(wildcard_match(
multiline_pattern,
&multi_line_builder("baz", Some("QUX=quux")),
- wildcard
));
- // Correct input & no leading line
- assert!(pattern_match(
+ // Should fail when leading line
+ assert!(!wildcard_match(
multiline_pattern,
&multi_line_builder("baz", None),
- wildcard
));
// Incorrect input & leading line
- assert!(!pattern_match(
+ assert!(!wildcard_match(
multiline_pattern,
&multi_line_builder("garply", Some("QUX=quux")),
- wildcard
));
// Incorrect input & no leading line
- assert!(!pattern_match(
+ assert!(!wildcard_match(
multiline_pattern,
&multi_line_builder("garply", None),
- wildcard
+ ));
+ }
+
+ #[test]
+ fn test_wildcard_match_unordered_lines() {
+ // matching
+ assert!(wildcard_match(
+ concat!("[UNORDERED_START]\n", "B\n", "A\n", "[UNORDERED_END]\n"),
+ concat!("A\n", "B\n",)
+ ));
+ // different line
+ assert!(!wildcard_match(
+ concat!("[UNORDERED_START]\n", "Ba\n", "A\n", "[UNORDERED_END]\n"),
+ concat!("A\n", "B\n",)
+ ));
+ // different number of lines
+ assert!(!wildcard_match(
+ concat!(
+ "[UNORDERED_START]\n",
+ "B\n",
+ "A\n",
+ "C\n",
+ "[UNORDERED_END]\n"
+ ),
+ concat!("A\n", "B\n",)
));
}