mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
Merge branch 'main' into repl_restart
This commit is contained in:
commit
d4787b57ea
369 changed files with 40061 additions and 32907 deletions
0
SECURITY.md → .github/SECURITY.md
vendored
0
SECURITY.md → .github/SECURITY.md
vendored
91
Cargo.lock
generated
91
Cargo.lock
generated
|
@ -768,7 +768,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno"
|
||||
version = "1.28.2"
|
||||
version = "1.28.3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"base32",
|
||||
|
@ -884,7 +884,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_bench_util"
|
||||
version = "0.73.0"
|
||||
version = "0.74.0"
|
||||
dependencies = [
|
||||
"bencher",
|
||||
"deno_core",
|
||||
|
@ -894,7 +894,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_broadcast_channel"
|
||||
version = "0.73.0"
|
||||
version = "0.74.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
|
@ -904,7 +904,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_cache"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
|
@ -916,14 +916,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_console"
|
||||
version = "0.79.0"
|
||||
version = "0.80.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_core"
|
||||
version = "0.161.0"
|
||||
version = "0.162.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
@ -948,7 +948,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_crypto"
|
||||
version = "0.93.0"
|
||||
version = "0.94.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
@ -982,9 +982,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_doc"
|
||||
version = "0.49.1"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa3bb0abda350b6523cfc96e0b14c55037fd7b5a901fcc40cb87ef9a1abb6d92"
|
||||
checksum = "7a5f0f24f690e9c0c1d22fe9c9da68b65d7378a5c10afe4a61398134eb031e21"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"deno_ast",
|
||||
|
@ -1000,9 +1000,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_emit"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7be76420d8eaac9d82295eb51cb2c0aebd326d305a2ecbeab6582343fb1b743c"
|
||||
checksum = "c721cb4e2ca7d94702f6987c2050aedfd270d18f87020080e396865a65dd957e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
@ -1014,7 +1014,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_fetch"
|
||||
version = "0.102.0"
|
||||
version = "0.103.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"data-url",
|
||||
|
@ -1031,7 +1031,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ffi"
|
||||
version = "0.66.0"
|
||||
version = "0.67.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"dlopen",
|
||||
|
@ -1044,7 +1044,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_flash"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_tls",
|
||||
|
@ -1063,19 +1063,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.38.0"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65eb6b2223b71a759b12bc21ee35842193d3703157950d1411c0243239f072eb"
|
||||
checksum = "87b3758993b62cf234fac6e922b2217aac6c3086d6d9a4fa36ddf7779abb0890"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"data-url",
|
||||
"deno_ast",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.1",
|
||||
"regex",
|
||||
"ring",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sourcemap",
|
||||
|
@ -1084,7 +1083,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_http"
|
||||
version = "0.73.0"
|
||||
version = "0.74.0"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64",
|
||||
|
@ -1125,7 +1124,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_napi"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"libloading",
|
||||
|
@ -1133,7 +1132,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_net"
|
||||
version = "0.71.0"
|
||||
version = "0.72.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_tls",
|
||||
|
@ -1147,7 +1146,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_node"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"once_cell",
|
||||
|
@ -1158,7 +1157,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.39.0"
|
||||
version = "0.40.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pmutil",
|
||||
|
@ -1174,7 +1173,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_runtime"
|
||||
version = "0.87.0"
|
||||
version = "0.88.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"deno_broadcast_channel",
|
||||
|
@ -1225,9 +1224,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_task_shell"
|
||||
version = "0.7.3"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a071a6407ade5107091a2481a502e7e6a9a96c5a631c71748058c5a28928fcd3"
|
||||
checksum = "532b383a071a05144c712614d62f08a2f9fad48dd62d6d457ed3884b049357da"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
|
@ -1240,7 +1239,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_tls"
|
||||
version = "0.66.0"
|
||||
version = "0.67.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"once_cell",
|
||||
|
@ -1254,7 +1253,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_url"
|
||||
version = "0.79.0"
|
||||
version = "0.80.0"
|
||||
dependencies = [
|
||||
"deno_bench_util",
|
||||
"deno_core",
|
||||
|
@ -1266,7 +1265,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_web"
|
||||
version = "0.110.0"
|
||||
version = "0.111.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64-simd",
|
||||
|
@ -1283,7 +1282,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webgpu"
|
||||
version = "0.80.0"
|
||||
version = "0.81.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"serde",
|
||||
|
@ -1294,14 +1293,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webidl"
|
||||
version = "0.79.0"
|
||||
version = "0.80.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_websocket"
|
||||
version = "0.84.0"
|
||||
version = "0.85.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_tls",
|
||||
|
@ -1315,7 +1314,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webstorage"
|
||||
version = "0.74.0"
|
||||
version = "0.75.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_web",
|
||||
|
@ -1445,15 +1444,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-plugin-markdown"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49cf3bc0cb9cc526a894b1d5af07c2ce2af1fa56b765990845ec781ab4cd1c91"
|
||||
checksum = "999e8891976e3b15b519b920db4ac70c6a85f0c6f0e0ddb6ef3b247373e8984d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dprint-core",
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"serde",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1659,9 +1659,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "eszip"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fdf9b31295c768c806cbc0d08d98868b4382684b002d216a16eb661bb8e8575"
|
||||
checksum = "d8119eb19b5b7f9c6b6da550781249bb05562fbdadb10f80f0a3afb96dde4944"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
@ -2844,7 +2844,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "napi_sym"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
|
@ -3023,9 +3023,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.14.0"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
|
@ -3977,7 +3977,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_v8"
|
||||
version = "0.72.0"
|
||||
version = "0.73.0"
|
||||
dependencies = [
|
||||
"bencher",
|
||||
"bytes",
|
||||
|
@ -5155,9 +5155,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
|||
|
||||
[[package]]
|
||||
name = "trybuild"
|
||||
version = "1.0.71"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea496675d71016e9bc76aa42d87f16aefd95447cc5818e671e12b2d7e269075d"
|
||||
checksum = "db29f438342820400f2d9acfec0d363e987a38b2950bdb50a7069ed17b2148ee"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"once_cell",
|
||||
|
@ -5387,14 +5387,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "v8"
|
||||
version = "0.55.0"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46cd4f562bce7520fbb511850c5488366264caf346be221cf7e908f51ac33dbc"
|
||||
checksum = "8e9b88668afedf6ec9f8f6d30b446f622498da2ef0b3991a52e10f0ea8c6cc09"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fslock",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"which",
|
||||
]
|
||||
|
||||
|
|
54
Cargo.toml
54
Cargo.toml
|
@ -5,7 +5,7 @@ resolver = "2"
|
|||
members = [
|
||||
"bench_util",
|
||||
"cli",
|
||||
"cli/napi_sym",
|
||||
"cli/napi/sym",
|
||||
"core",
|
||||
"ops",
|
||||
"runtime",
|
||||
|
@ -40,36 +40,36 @@ license = "MIT"
|
|||
repository = "https://github.com/denoland/deno"
|
||||
|
||||
[workspace.dependencies]
|
||||
v8 = { version = "0.55.0", default-features = false }
|
||||
v8 = { version = "0.58.0", default-features = false }
|
||||
deno_ast = { version = "0.21.0", features = ["transpiling"] }
|
||||
|
||||
deno_core = { version = "0.161.0", path = "./core" }
|
||||
deno_ops = { version = "0.39.0", path = "./ops" }
|
||||
serde_v8 = { version = "0.72.0", path = "./serde_v8" }
|
||||
deno_runtime = { version = "0.87.0", path = "./runtime" }
|
||||
napi_sym = { version = "0.9.0", path = "./cli/napi_sym" }
|
||||
deno_bench_util = { version = "0.73.0", path = "./bench_util" }
|
||||
deno_core = { version = "0.162.0", path = "./core" }
|
||||
deno_ops = { version = "0.40.0", path = "./ops" }
|
||||
serde_v8 = { version = "0.73.0", path = "./serde_v8" }
|
||||
deno_runtime = { version = "0.88.0", path = "./runtime" }
|
||||
napi_sym = { version = "0.10.0", path = "./cli/napi/sym" }
|
||||
deno_bench_util = { version = "0.74.0", path = "./bench_util" }
|
||||
test_util = { path = "./test_util" }
|
||||
|
||||
# exts
|
||||
deno_broadcast_channel = { version = "0.73.0", path = "./ext/broadcast_channel" }
|
||||
deno_cache = { version = "0.11.0", path = "./ext/cache" }
|
||||
deno_console = { version = "0.79.0", path = "./ext/console" }
|
||||
deno_crypto = { version = "0.93.0", path = "./ext/crypto" }
|
||||
deno_fetch = { version = "0.102.0", path = "./ext/fetch" }
|
||||
deno_ffi = { version = "0.66.0", path = "./ext/ffi" }
|
||||
deno_flash = { version = "0.15.0", path = "./ext/flash" }
|
||||
deno_http = { version = "0.73.0", path = "./ext/http" }
|
||||
deno_net = { version = "0.71.0", path = "./ext/net" }
|
||||
deno_node = { version = "0.16.0", path = "./ext/node" }
|
||||
deno_tls = { version = "0.66.0", path = "./ext/tls" }
|
||||
deno_url = { version = "0.79.0", path = "./ext/url" }
|
||||
deno_web = { version = "0.110.0", path = "./ext/web" }
|
||||
deno_webgpu = { version = "0.80.0", path = "./ext/webgpu" }
|
||||
deno_webidl = { version = "0.79.0", path = "./ext/webidl" }
|
||||
deno_websocket = { version = "0.84.0", path = "./ext/websocket" }
|
||||
deno_webstorage = { version = "0.74.0", path = "./ext/webstorage" }
|
||||
deno_napi = { version = "0.9.0", path = "./ext/napi" }
|
||||
deno_broadcast_channel = { version = "0.74.0", path = "./ext/broadcast_channel" }
|
||||
deno_cache = { version = "0.12.0", path = "./ext/cache" }
|
||||
deno_console = { version = "0.80.0", path = "./ext/console" }
|
||||
deno_crypto = { version = "0.94.0", path = "./ext/crypto" }
|
||||
deno_fetch = { version = "0.103.0", path = "./ext/fetch" }
|
||||
deno_ffi = { version = "0.67.0", path = "./ext/ffi" }
|
||||
deno_flash = { version = "0.16.0", path = "./ext/flash" }
|
||||
deno_http = { version = "0.74.0", path = "./ext/http" }
|
||||
deno_net = { version = "0.72.0", path = "./ext/net" }
|
||||
deno_node = { version = "0.17.0", path = "./ext/node" }
|
||||
deno_tls = { version = "0.67.0", path = "./ext/tls" }
|
||||
deno_url = { version = "0.80.0", path = "./ext/url" }
|
||||
deno_web = { version = "0.111.0", path = "./ext/web" }
|
||||
deno_webgpu = { version = "0.81.0", path = "./ext/webgpu" }
|
||||
deno_webidl = { version = "0.80.0", path = "./ext/webidl" }
|
||||
deno_websocket = { version = "0.85.0", path = "./ext/websocket" }
|
||||
deno_webstorage = { version = "0.75.0", path = "./ext/webstorage" }
|
||||
deno_napi = { version = "0.10.0", path = "./ext/napi" }
|
||||
|
||||
anyhow = "1.0.57"
|
||||
async-trait = "0.1.51"
|
||||
|
@ -89,7 +89,7 @@ libc = "=0.2.126"
|
|||
log = "=0.4.17"
|
||||
lzzzz = "1.0"
|
||||
notify = "=5.0.0"
|
||||
once_cell = "=1.14.0"
|
||||
once_cell = "=1.16.0"
|
||||
os_pipe = "=1.0.1"
|
||||
parking_lot = "0.12.0"
|
||||
percent-encoding = "=2.2.0"
|
||||
|
|
34
Releases.md
34
Releases.md
|
@ -6,6 +6,40 @@ https://github.com/denoland/deno/releases
|
|||
We also have one-line install commands at:
|
||||
https://github.com/denoland/deno_install
|
||||
|
||||
### 1.28.3 / 2022.12.01
|
||||
|
||||
- Revert "fix(ext/flash): graceful server startup/shutdown with unsettl…
|
||||
(#16839)
|
||||
- feat(core): send "executionContextDestroyed" notification on program end
|
||||
(#16831)
|
||||
- feat(core): show unresolved promise origin (#16650)
|
||||
- feat(core): support initializing extensions with and without JS (#16789)
|
||||
- feat(ops): fast calls for Wasm (#16776)
|
||||
- feat(ops): support raw pointer arguments (#16826)
|
||||
- feat(unstable): rework Deno.Command (#16812)
|
||||
- fix(cli/js): improve resource sanitizer messages (#16798)
|
||||
- fix(coverage): Error if the emit cache is invalid (#16850)
|
||||
- fix(ext/ffi): Null buffer pointer value is inconsistent (#16625)
|
||||
- fix(ext/node): allow absolute path in createRequire (#16853)
|
||||
- fix(ext/web): fix typings for readable stream readers (#16191)
|
||||
- fix(fmt/markdown): fix emoji width calculation in tables (#16870)
|
||||
- fix(inspector): send "isDefault" in aux data (#16836)
|
||||
- fix(lsp): analyze fs dependencies of dependencies to find npm package
|
||||
requirements (#16866)
|
||||
- fix(npm): allow to inspect npm modules with --inspect-brk (#16841)
|
||||
- fix(npm): better error message when attempting to use typescript in npm
|
||||
packages (#16813)
|
||||
- fix(npm): don't resolve JS files when resolving types (#16854)
|
||||
- fix(npm): ensure npm package downloaded once per run when using `--reload`
|
||||
(#16842)
|
||||
- fix(npm): improve package.json exports support for types (#16880)
|
||||
- fix(ops): circular dependency in deno_ops test (#16809)
|
||||
- fix(repl): more reliable history handling (#16797)
|
||||
- fix(repl): respect --quiet flag (#16875)
|
||||
- fix(runtime): feature-flag snapshot from snapshot (#16843)
|
||||
- fix(task): output encoding issues on windows (#16794)
|
||||
- perf(ops): Reenable fast unit result optimization (#16827)
|
||||
|
||||
### 1.28.2 / 2022.11.24
|
||||
|
||||
- feat(cli): add warning for incorrectly ordered flags (#16734)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno_bench_util"
|
||||
version = "0.73.0"
|
||||
version = "0.74.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::profiling::is_profiling;
|
|||
|
||||
pub fn create_js_runtime(setup: impl FnOnce() -> Vec<Extension>) -> JsRuntime {
|
||||
JsRuntime::new(RuntimeOptions {
|
||||
extensions: setup(),
|
||||
extensions_with_js: setup(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno"
|
||||
version = "1.28.2"
|
||||
version = "1.28.3"
|
||||
authors.workspace = true
|
||||
default-run = "deno"
|
||||
edition.workspace = true
|
||||
|
@ -26,7 +26,7 @@ harness = false
|
|||
path = "./bench/lsp_bench_standalone.rs"
|
||||
|
||||
[build-dependencies]
|
||||
deno_runtime.workspace = true
|
||||
deno_runtime = { workspace = true, features = ["snapshot_from_snapshot"] }
|
||||
deno_core.workspace = true
|
||||
regex.workspace = true
|
||||
serde.workspace = true
|
||||
|
@ -43,12 +43,12 @@ winres.workspace = true
|
|||
[dependencies]
|
||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||
deno_core.workspace = true
|
||||
deno_doc = "0.49.1"
|
||||
deno_emit = "0.11.0"
|
||||
deno_graph = "0.38.0"
|
||||
deno_doc = "0.51.0"
|
||||
deno_emit = "0.12.0"
|
||||
deno_graph = "0.39.0"
|
||||
deno_lint = { version = "0.35.0", features = ["docs"] }
|
||||
deno_runtime.workspace = true
|
||||
deno_task_shell = "0.7.3"
|
||||
deno_task_shell = "0.8.1"
|
||||
napi_sym.workspace = true
|
||||
|
||||
atty.workspace = true
|
||||
|
@ -62,11 +62,11 @@ clap_complete_fig = "=3.1.5"
|
|||
data-url.workspace = true
|
||||
dissimilar = "=1.0.4"
|
||||
dprint-plugin-json = "=0.16.0"
|
||||
dprint-plugin-markdown = "=0.14.2"
|
||||
dprint-plugin-markdown = "=0.14.3"
|
||||
dprint-plugin-typescript = "=0.78.0"
|
||||
encoding_rs.workspace = true
|
||||
env_logger = "=0.9.0"
|
||||
eszip = "=0.30.0"
|
||||
eszip = "=0.31.0"
|
||||
fancy-regex = "=0.10.0"
|
||||
flate2.workspace = true
|
||||
http.workspace = true
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
use crate::args::ConfigFlag;
|
||||
use crate::args::Flags;
|
||||
use crate::args::TaskFlags;
|
||||
use crate::fs_util;
|
||||
use crate::fs_util::canonicalize_path;
|
||||
use crate::fs_util::specifier_parent;
|
||||
use crate::fs_util::specifier_to_file_path;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
use crate::util::path::specifier_parent;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
|
@ -467,7 +466,7 @@ impl ConfigFile {
|
|||
..
|
||||
}) = &flags.subcommand
|
||||
{
|
||||
let task_cwd = fs_util::canonicalize_path(&PathBuf::from(path))?;
|
||||
let task_cwd = canonicalize_path(&PathBuf::from(path))?;
|
||||
if let Some(path) = Self::discover_from(&task_cwd, &mut checked)? {
|
||||
return Ok(Some(path));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ pub struct LintFlags {
|
|||
pub struct ReplFlags {
|
||||
pub eval_files: Option<Vec<String>>,
|
||||
pub eval: Option<String>,
|
||||
pub is_default_command: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
|
||||
|
@ -245,6 +246,7 @@ impl Default for DenoSubcommand {
|
|||
DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: None,
|
||||
is_default_command: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -624,6 +626,7 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::Result<Flags> {
|
|||
ReplFlags {
|
||||
eval_files: None,
|
||||
eval: None,
|
||||
is_default_command: true,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -632,15 +635,18 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::Result<Flags> {
|
|||
}
|
||||
|
||||
fn handle_repl_flags(flags: &mut Flags, repl_flags: ReplFlags) {
|
||||
// If user runs just `deno` binary we enter REPL and allow all permissions.
|
||||
if repl_flags.is_default_command {
|
||||
flags.allow_net = Some(vec![]);
|
||||
flags.allow_env = Some(vec![]);
|
||||
flags.allow_run = Some(vec![]);
|
||||
flags.allow_read = Some(vec![]);
|
||||
flags.allow_sys = Some(vec![]);
|
||||
flags.allow_write = Some(vec![]);
|
||||
flags.allow_ffi = Some(vec![]);
|
||||
flags.allow_hrtime = true;
|
||||
}
|
||||
flags.subcommand = DenoSubcommand::Repl(repl_flags);
|
||||
flags.allow_net = Some(vec![]);
|
||||
flags.allow_env = Some(vec![]);
|
||||
flags.allow_run = Some(vec![]);
|
||||
flags.allow_read = Some(vec![]);
|
||||
flags.allow_sys = Some(vec![]);
|
||||
flags.allow_write = Some(vec![]);
|
||||
flags.allow_ffi = Some(vec![]);
|
||||
flags.allow_hrtime = true;
|
||||
}
|
||||
|
||||
fn clap_root(version: &str) -> Command {
|
||||
|
@ -797,12 +803,20 @@ Future runs of this module will trigger no downloads or compilation unless \
|
|||
|
||||
fn check_subcommand<'a>() -> Command<'a> {
|
||||
compile_args_without_check_args(Command::new("check"))
|
||||
.arg(
|
||||
Arg::new("remote")
|
||||
.long("remote")
|
||||
.help("Type-check all modules, including remote")
|
||||
.conflicts_with("no-remote")
|
||||
.arg(
|
||||
Arg::new("all")
|
||||
.long("all")
|
||||
.help("Type-check all code, including remote modules and npm packages")
|
||||
.conflicts_with("no-remote")
|
||||
)
|
||||
.arg(
|
||||
// past alias for --all
|
||||
Arg::new("remote")
|
||||
.long("remote")
|
||||
.help("Type-check all modules, including remote")
|
||||
.conflicts_with("no-remote")
|
||||
.hide(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::new("file")
|
||||
.takes_value(true)
|
||||
|
@ -1456,7 +1470,7 @@ Ignore linting a file by adding an ignore comment at the top of the file:
|
|||
}
|
||||
|
||||
fn repl_subcommand<'a>() -> Command<'a> {
|
||||
runtime_args(Command::new("repl"), false, true)
|
||||
runtime_args(Command::new("repl"), true, true)
|
||||
.about("Read Eval Print Loop")
|
||||
.arg(
|
||||
Arg::new("eval-file")
|
||||
|
@ -1475,7 +1489,6 @@ fn repl_subcommand<'a>() -> Command<'a> {
|
|||
.takes_value(true)
|
||||
.value_name("code"),
|
||||
)
|
||||
.arg(unsafely_ignore_certificate_errors_arg())
|
||||
}
|
||||
|
||||
fn run_subcommand<'a>() -> Command<'a> {
|
||||
|
@ -2343,7 +2356,7 @@ fn check_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
.unwrap()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
if matches.is_present("remote") {
|
||||
if matches.is_present("all") || matches.is_present("remote") {
|
||||
flags.type_check_mode = TypeCheckMode::All;
|
||||
}
|
||||
flags.subcommand = DenoSubcommand::Check(CheckFlags { files });
|
||||
|
@ -2646,7 +2659,7 @@ fn lint_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
}
|
||||
|
||||
fn repl_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||
runtime_args_parse(flags, matches, false, true);
|
||||
runtime_args_parse(flags, matches, true, true);
|
||||
unsafely_ignore_certificate_errors_parse(flags, matches);
|
||||
|
||||
let eval_files: Option<Vec<String>> = matches
|
||||
|
@ -2658,6 +2671,7 @@ fn repl_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
ReplFlags {
|
||||
eval_files,
|
||||
eval: matches.value_of("eval").map(ToOwned::to_owned),
|
||||
is_default_command: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -4001,26 +4015,28 @@ mod tests {
|
|||
}
|
||||
);
|
||||
|
||||
let r = flags_from_vec(svec!["deno", "check", "--remote", "script.ts"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Check(CheckFlags {
|
||||
files: svec!["script.ts"],
|
||||
}),
|
||||
type_check_mode: TypeCheckMode::All,
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
for all_flag in ["--remote", "--all"] {
|
||||
let r = flags_from_vec(svec!["deno", "check", all_flag, "script.ts"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Check(CheckFlags {
|
||||
files: svec!["script.ts"],
|
||||
}),
|
||||
type_check_mode: TypeCheckMode::All,
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
|
||||
let r = flags_from_vec(svec![
|
||||
"deno",
|
||||
"check",
|
||||
"--remote",
|
||||
"--no-remote",
|
||||
"script.ts"
|
||||
]);
|
||||
assert_eq!(r.unwrap_err().kind(), clap::ErrorKind::ArgumentConflict);
|
||||
let r = flags_from_vec(svec![
|
||||
"deno",
|
||||
"check",
|
||||
all_flag,
|
||||
"--no-remote",
|
||||
"script.ts"
|
||||
]);
|
||||
assert_eq!(r.unwrap_err().kind(), clap::ErrorKind::ArgumentConflict);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -4266,7 +4282,8 @@ mod tests {
|
|||
Flags {
|
||||
subcommand: DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: None
|
||||
eval: None,
|
||||
is_default_command: true,
|
||||
}),
|
||||
allow_net: Some(vec![]),
|
||||
unsafely_ignore_certificate_errors: None,
|
||||
|
@ -4285,13 +4302,14 @@ mod tests {
|
|||
#[test]
|
||||
fn repl_with_flags() {
|
||||
#[rustfmt::skip]
|
||||
let r = flags_from_vec(svec!["deno", "repl", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--v8-flags=--help", "--seed", "1", "--inspect=127.0.0.1:9229", "--unsafely-ignore-certificate-errors"]);
|
||||
let r = flags_from_vec(svec!["deno", "repl", "-A", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--v8-flags=--help", "--seed", "1", "--inspect=127.0.0.1:9229", "--unsafely-ignore-certificate-errors"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: None
|
||||
eval: None,
|
||||
is_default_command: false,
|
||||
}),
|
||||
import_map_path: Some("import_map.json".to_string()),
|
||||
no_remote: true,
|
||||
|
@ -4306,6 +4324,7 @@ mod tests {
|
|||
v8_flags: svec!["--help", "--random-seed=1"],
|
||||
seed: Some(1),
|
||||
inspect: Some("127.0.0.1:9229".parse().unwrap()),
|
||||
allow_all: true,
|
||||
allow_net: Some(vec![]),
|
||||
allow_env: Some(vec![]),
|
||||
allow_run: Some(vec![]),
|
||||
|
@ -4323,22 +4342,16 @@ mod tests {
|
|||
#[test]
|
||||
fn repl_with_eval_flag() {
|
||||
#[rustfmt::skip]
|
||||
let r = flags_from_vec(svec!["deno", "repl", "--eval", "console.log('hello');"]);
|
||||
let r = flags_from_vec(svec!["deno", "repl", "--allow-write", "--eval", "console.log('hello');"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: Some("console.log('hello');".to_string()),
|
||||
is_default_command: false,
|
||||
}),
|
||||
allow_net: Some(vec![]),
|
||||
allow_env: Some(vec![]),
|
||||
allow_run: Some(vec![]),
|
||||
allow_read: Some(vec![]),
|
||||
allow_sys: Some(vec![]),
|
||||
allow_write: Some(vec![]),
|
||||
allow_ffi: Some(vec![]),
|
||||
allow_hrtime: true,
|
||||
type_check_mode: TypeCheckMode::None,
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -4359,15 +4372,8 @@ mod tests {
|
|||
"https://examples.deno.land/hello-world.ts".to_string()
|
||||
]),
|
||||
eval: None,
|
||||
is_default_command: false,
|
||||
}),
|
||||
allow_net: Some(vec![]),
|
||||
allow_env: Some(vec![]),
|
||||
allow_run: Some(vec![]),
|
||||
allow_read: Some(vec![]),
|
||||
allow_sys: Some(vec![]),
|
||||
allow_write: Some(vec![]),
|
||||
allow_ffi: Some(vec![]),
|
||||
allow_hrtime: true,
|
||||
type_check_mode: TypeCheckMode::None,
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -5162,16 +5168,9 @@ mod tests {
|
|||
subcommand: DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: Some("console.log('hello');".to_string()),
|
||||
is_default_command: false,
|
||||
}),
|
||||
unsafely_ignore_certificate_errors: Some(vec![]),
|
||||
allow_net: Some(vec![]),
|
||||
allow_env: Some(vec![]),
|
||||
allow_run: Some(vec![]),
|
||||
allow_read: Some(vec![]),
|
||||
allow_sys: Some(vec![]),
|
||||
allow_write: Some(vec![]),
|
||||
allow_ffi: Some(vec![]),
|
||||
allow_hrtime: true,
|
||||
type_check_mode: TypeCheckMode::None,
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -5236,7 +5235,8 @@ mod tests {
|
|||
Flags {
|
||||
subcommand: DenoSubcommand::Repl(ReplFlags {
|
||||
eval_files: None,
|
||||
eval: None
|
||||
eval: None,
|
||||
is_default_command: false,
|
||||
}),
|
||||
unsafely_ignore_certificate_errors: Some(svec![
|
||||
"deno.land",
|
||||
|
@ -5246,14 +5246,6 @@ mod tests {
|
|||
"[::1]",
|
||||
"1.2.3.4"
|
||||
]),
|
||||
allow_net: Some(vec![]),
|
||||
allow_env: Some(vec![]),
|
||||
allow_run: Some(vec![]),
|
||||
allow_read: Some(vec![]),
|
||||
allow_sys: Some(vec![]),
|
||||
allow_write: Some(vec![]),
|
||||
allow_ffi: Some(vec![]),
|
||||
allow_hrtime: true,
|
||||
type_check_mode: TypeCheckMode::None,
|
||||
..Flags::default()
|
||||
}
|
||||
|
|
|
@ -2,24 +2,20 @@
|
|||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use log::debug;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::args::ConfigFile;
|
||||
use crate::npm::NpmPackageId;
|
||||
use crate::npm::NpmPackageReq;
|
||||
use crate::npm::NpmResolutionPackage;
|
||||
use crate::tools::fmt::format_json;
|
||||
use crate::util;
|
||||
use crate::Flags;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -95,15 +91,6 @@ pub struct Lockfile {
|
|||
}
|
||||
|
||||
impl Lockfile {
|
||||
pub fn as_maybe_locker(
|
||||
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||
) -> Option<Rc<RefCell<dyn deno_graph::source::Locker>>> {
|
||||
lockfile.as_ref().map(|lf| {
|
||||
Rc::new(RefCell::new(Locker(Some(lf.clone()))))
|
||||
as Rc<RefCell<dyn deno_graph::source::Locker>>
|
||||
})
|
||||
}
|
||||
|
||||
pub fn discover(
|
||||
flags: &Flags,
|
||||
maybe_config_file: Option<&ConfigFile>,
|
||||
|
@ -260,7 +247,7 @@ impl Lockfile {
|
|||
/// is not included, insert it.
|
||||
fn check_or_insert(&mut self, specifier: &str, code: &str) -> bool {
|
||||
if let Some(lockfile_checksum) = self.content.remote.get(specifier) {
|
||||
let compiled_checksum = crate::checksum::gen(&[code.as_bytes()]);
|
||||
let compiled_checksum = util::checksum::gen(&[code.as_bytes()]);
|
||||
lockfile_checksum == &compiled_checksum
|
||||
} else {
|
||||
self.insert(specifier, code);
|
||||
|
@ -269,7 +256,7 @@ impl Lockfile {
|
|||
}
|
||||
|
||||
fn insert(&mut self, specifier: &str, code: &str) {
|
||||
let checksum = crate::checksum::gen(&[code.as_bytes()]);
|
||||
let checksum = util::checksum::gen(&[code.as_bytes()]);
|
||||
self.content.remote.insert(specifier.to_string(), checksum);
|
||||
self.has_content_changed = true;
|
||||
}
|
||||
|
@ -341,33 +328,6 @@ Use \"--lock-write\" flag to regenerate the lockfile at \"{}\".",
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Locker(Option<Arc<Mutex<Lockfile>>>);
|
||||
|
||||
impl deno_graph::source::Locker for Locker {
|
||||
fn check_or_insert(
|
||||
&mut self,
|
||||
specifier: &ModuleSpecifier,
|
||||
source: &str,
|
||||
) -> bool {
|
||||
if let Some(lock_file) = &self.0 {
|
||||
let mut lock_file = lock_file.lock();
|
||||
lock_file.check_or_insert_remote(specifier.as_str(), source)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn get_checksum(&self, content: &str) -> String {
|
||||
crate::checksum::gen(&[content.as_bytes()])
|
||||
}
|
||||
|
||||
fn get_filename(&self) -> Option<String> {
|
||||
let lock_file = self.0.as_ref()?.lock();
|
||||
lock_file.filename.to_str().map(|s| s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
133
cli/args/mod.rs
133
cli/args/mod.rs
|
@ -22,6 +22,10 @@ pub use config_file::TsConfig;
|
|||
pub use config_file::TsConfigForEmit;
|
||||
pub use config_file::TsConfigType;
|
||||
pub use config_file::TsTypeLib;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls_native_certs::load_native_certs;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use deno_runtime::deno_tls::webpki_roots;
|
||||
pub use flags::*;
|
||||
pub use lockfile::Lockfile;
|
||||
pub use lockfile::LockfileError;
|
||||
|
@ -40,16 +44,130 @@ use deno_runtime::inspector_server::InspectorServer;
|
|||
use deno_runtime::permissions::PermissionsOptions;
|
||||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::io::BufReader;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cache::DenoDir;
|
||||
use crate::file_fetcher::get_root_cert_store;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::fs_util;
|
||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||
use crate::version;
|
||||
|
||||
/// Indicates how cached source files should be handled.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum CacheSetting {
|
||||
/// Only the cached files should be used. Any files not in the cache will
|
||||
/// error. This is the equivalent of `--cached-only` in the CLI.
|
||||
Only,
|
||||
/// No cached source files should be used, and all files should be reloaded.
|
||||
/// This is the equivalent of `--reload` in the CLI.
|
||||
ReloadAll,
|
||||
/// Only some cached resources should be used. This is the equivalent of
|
||||
/// `--reload=https://deno.land/std` or
|
||||
/// `--reload=https://deno.land/std,https://deno.land/x/example`.
|
||||
ReloadSome(Vec<String>),
|
||||
/// The usability of a cached value is determined by analyzing the cached
|
||||
/// headers and other metadata associated with a cached response, reloading
|
||||
/// any cached "non-fresh" cached responses.
|
||||
RespectHeaders,
|
||||
/// The cached source files should be used for local modules. This is the
|
||||
/// default behavior of the CLI.
|
||||
Use,
|
||||
}
|
||||
|
||||
impl CacheSetting {
|
||||
pub fn should_use_for_npm_package(&self, package_name: &str) -> bool {
|
||||
match self {
|
||||
CacheSetting::ReloadAll => false,
|
||||
CacheSetting::ReloadSome(list) => {
|
||||
if list.iter().any(|i| i == "npm:") {
|
||||
return false;
|
||||
}
|
||||
let specifier = format!("npm:{}", package_name);
|
||||
if list.contains(&specifier) {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create and populate a root cert store based on the passed options and
|
||||
/// environment.
|
||||
pub fn get_root_cert_store(
|
||||
maybe_root_path: Option<PathBuf>,
|
||||
maybe_ca_stores: Option<Vec<String>>,
|
||||
maybe_ca_file: Option<String>,
|
||||
) -> Result<RootCertStore, AnyError> {
|
||||
let mut root_cert_store = RootCertStore::empty();
|
||||
let ca_stores: Vec<String> = maybe_ca_stores
|
||||
.or_else(|| {
|
||||
let env_ca_store = env::var("DENO_TLS_CA_STORE").ok()?;
|
||||
Some(
|
||||
env_ca_store
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| vec!["mozilla".to_string()]);
|
||||
|
||||
for store in ca_stores.iter() {
|
||||
match store.as_str() {
|
||||
"mozilla" => {
|
||||
root_cert_store.add_server_trust_anchors(
|
||||
webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}),
|
||||
);
|
||||
}
|
||||
"system" => {
|
||||
let roots = load_native_certs().expect("could not load platform certs");
|
||||
for root in roots {
|
||||
root_cert_store
|
||||
.add(&rustls::Certificate(root.0))
|
||||
.expect("Failed to add platform cert to root cert store");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!("Unknown certificate store \"{}\" specified (allowed: \"system,mozilla\")", store));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ca_file = maybe_ca_file.or_else(|| env::var("DENO_CERT").ok());
|
||||
if let Some(ca_file) = ca_file {
|
||||
let ca_file = if let Some(root) = &maybe_root_path {
|
||||
root.join(&ca_file)
|
||||
} else {
|
||||
PathBuf::from(ca_file)
|
||||
};
|
||||
let certfile = std::fs::File::open(&ca_file)?;
|
||||
let mut reader = BufReader::new(certfile);
|
||||
|
||||
match rustls_pemfile::certs(&mut reader) {
|
||||
Ok(certs) => {
|
||||
root_cert_store.add_parsable_certificates(&certs);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(anyhow!(
|
||||
"Unable to add pem file to certificate store: {}",
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(root_cert_store)
|
||||
}
|
||||
|
||||
/// Overrides for the options below that when set will
|
||||
/// use these values over the values derived from the
|
||||
/// CLI flags or config file.
|
||||
|
@ -176,7 +294,7 @@ impl CliOptions {
|
|||
} else {
|
||||
std::env::current_dir()?.join("node_modules")
|
||||
};
|
||||
Ok(Some(fs_util::canonicalize_path_maybe_not_exists(&path)?))
|
||||
Ok(Some(canonicalize_path_maybe_not_exists(&path)?))
|
||||
}
|
||||
|
||||
pub fn resolve_root_cert_store(&self) -> Result<RootCertStore, AnyError> {
|
||||
|
@ -342,6 +460,13 @@ impl CliOptions {
|
|||
self.flags.log_level
|
||||
}
|
||||
|
||||
pub fn is_quiet(&self) -> bool {
|
||||
self
|
||||
.log_level()
|
||||
.map(|l| l == log::Level::Error)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn location_flag(&self) -> Option<&Url> {
|
||||
self.flags.location.as_ref()
|
||||
}
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
const count = 100000;
|
||||
|
||||
const start = Date.now();
|
||||
for (let i = 0; i < count; i++) console.log("Hello World");
|
||||
const elapsed = Date.now() - start;
|
||||
const rate = Math.floor(count / (elapsed / 1000));
|
||||
console.log(`time ${elapsed} ms rate ${rate}`);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
? Deno.args
|
||||
: [process.argv[2], process.argv[3]];
|
||||
|
||||
total = total ? parseInt(total, 0) : 50;
|
||||
count = count ? parseInt(count, 10) : 1000000;
|
||||
count = count ? parseInt(count, 10) : 10000000;
|
||||
|
||||
function bench(fun) {
|
||||
const start = Date.now();
|
||||
|
@ -13,7 +12,7 @@ function bench(fun) {
|
|||
const elapsed = Date.now() - start;
|
||||
const rate = Math.floor(count / (elapsed / 1000));
|
||||
console.log(`time ${elapsed} ms rate ${rate}`);
|
||||
if (--total) queueMicrotask(() => bench(fun));
|
||||
if (--total) bench(fun);
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
|
9
cli/bench/stdio/README.md
Normal file
9
cli/bench/stdio/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
## `stdio` benchmarks
|
||||
|
||||
Compile the C baseline and run the benchmark:
|
||||
|
||||
```bash
|
||||
cc stdio.c -o stdio -O3
|
||||
time dd if=/dev/zero bs=65536 count=500000 | ./stdio
|
||||
time dd if=/dev/zero bs=65536 count=500000 | deno run stdio.js
|
||||
```
|
29
cli/bench/stdio/stdio.c
Normal file
29
cli/bench/stdio/stdio.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
// From https://github.com/just-js/benchmarks/tree/main/01-stdio
|
||||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned int blocksize = 65536;
|
||||
if (argc == 2) {
|
||||
blocksize = atoi(argv[1]);
|
||||
}
|
||||
char buf[blocksize];
|
||||
unsigned long size = 0;
|
||||
unsigned int reads = 0;
|
||||
int n = read(STDIN_FILENO, buf, blocksize);
|
||||
while (n > 0) {
|
||||
reads++;
|
||||
size += n;
|
||||
n = read(STDIN_FILENO, buf, blocksize);
|
||||
}
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "read: %s (%i)\n", strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stdout, "size %lu reads %u blocksize %u\n", size, reads, blocksize);
|
||||
}
|
16
cli/bench/stdio/stdio.js
Normal file
16
cli/bench/stdio/stdio.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// From https://github.com/just-js/benchmarks/tree/main/01-stdio
|
||||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
const blocksize = parseInt(Deno.args[0] || 65536);
|
||||
const buf = new Uint8Array(blocksize);
|
||||
let size = 0;
|
||||
let reads = 0;
|
||||
|
||||
let n = Deno.stdin.readSync(buf);
|
||||
while (n > 0) {
|
||||
reads++;
|
||||
size += n;
|
||||
n = Deno.stdin.readSync(buf);
|
||||
}
|
||||
if (n < 0) throw new Error("Bad Read");
|
||||
console.log(`size ${size} reads ${reads} blocksize ${blocksize}`);
|
21
cli/bench/webstorage.js
Normal file
21
cli/bench/webstorage.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// Note: when benchmarking across different Deno version, make sure to clear
|
||||
// the DENO_DIR cache.
|
||||
let [total, count] = typeof Deno !== "undefined" ? Deno.args : [];
|
||||
|
||||
total = total ? parseInt(total, 0) : 50;
|
||||
count = count ? parseInt(count, 10) : 1000000;
|
||||
|
||||
function bench(fun) {
|
||||
const start = Date.now();
|
||||
for (let i = 0; i < count; i++) fun(i);
|
||||
const elapsed = Date.now() - start;
|
||||
const rate = Math.floor(count / (elapsed / 1000));
|
||||
console.log(`time ${elapsed} ms rate ${rate}`);
|
||||
if (--total) queueMicrotask(() => bench(fun));
|
||||
}
|
||||
|
||||
localStorage.clear();
|
||||
localStorage.setItem("foo", "bar");
|
||||
bench(() => localStorage.getItem("foo"));
|
35
cli/build.rs
35
cli/build.rs
|
@ -130,6 +130,10 @@ mod ts {
|
|||
path_dts.join(format!("lib.{}.d.ts", name)).display()
|
||||
);
|
||||
}
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
cwd.join("js").join("40_testing.js").display()
|
||||
);
|
||||
|
||||
// create a copy of the vector that includes any op crate libs to be passed
|
||||
// to the JavaScript compiler to build into the snapshot
|
||||
|
@ -243,6 +247,7 @@ mod ts {
|
|||
Ok(())
|
||||
})
|
||||
.build()],
|
||||
extensions_with_js: vec![],
|
||||
additional_files: files,
|
||||
compression_cb: Some(Box::new(|vec, snapshot_slice| {
|
||||
vec.extend_from_slice(
|
||||
|
@ -254,17 +259,24 @@ mod ts {
|
|||
}
|
||||
|
||||
pub(crate) fn version() -> String {
|
||||
std::fs::read_to_string("tsc/00_typescript.js")
|
||||
.unwrap()
|
||||
.lines()
|
||||
.find(|l| l.contains("ts.version = "))
|
||||
.expect(
|
||||
"Failed to find the pattern `ts.version = ` in typescript source code",
|
||||
)
|
||||
.chars()
|
||||
.skip_while(|c| !char::is_numeric(*c))
|
||||
.take_while(|c| *c != '"')
|
||||
.collect::<String>()
|
||||
let file_text = std::fs::read_to_string("tsc/00_typescript.js").unwrap();
|
||||
let mut version = String::new();
|
||||
for line in file_text.lines() {
|
||||
let major_minor_text = "ts.versionMajorMinor = \"";
|
||||
let version_text = "ts.version = \"\".concat(ts.versionMajorMinor, \"";
|
||||
if version.is_empty() {
|
||||
if let Some(index) = line.find(major_minor_text) {
|
||||
let remaining_line = &line[index + major_minor_text.len()..];
|
||||
version
|
||||
.push_str(&remaining_line[..remaining_line.find('"').unwrap()]);
|
||||
}
|
||||
} else if let Some(index) = line.find(version_text) {
|
||||
let remaining_line = &line[index + version_text.len()..];
|
||||
version.push_str(&remaining_line[..remaining_line.find('"').unwrap()]);
|
||||
return version;
|
||||
}
|
||||
}
|
||||
panic!("Could not find ts version.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,6 +316,7 @@ fn create_cli_snapshot(snapshot_path: PathBuf, files: Vec<PathBuf>) {
|
|||
snapshot_path,
|
||||
startup_snapshot: Some(deno_runtime::js::deno_isolate_init()),
|
||||
extensions,
|
||||
extensions_with_js: vec![],
|
||||
additional_files: files,
|
||||
compression_cb: Some(Box::new(|vec, snapshot_slice| {
|
||||
lzzzz::lz4_hc::compress_to_vec(
|
||||
|
|
7
cli/cache/disk_cache.rs
vendored
7
cli/cache/disk_cache.rs
vendored
|
@ -1,7 +1,8 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::fs_util;
|
||||
use crate::http_cache::url_to_filename;
|
||||
use super::http_cache::url_to_filename;
|
||||
use super::CACHE_PERM;
|
||||
use crate::util::fs::atomic_write_file;
|
||||
|
||||
use deno_core::url::Host;
|
||||
use deno_core::url::Url;
|
||||
|
@ -144,7 +145,7 @@ impl DiskCache {
|
|||
Some(parent) => self.ensure_dir_exists(parent),
|
||||
None => Ok(()),
|
||||
}?;
|
||||
fs_util::atomic_write_file(&path, data, crate::http_cache::CACHE_PERM)
|
||||
atomic_write_file(&path, data, CACHE_PERM)
|
||||
.map_err(|e| with_io_context(&e, format!("{:#?}", &path)))
|
||||
}
|
||||
}
|
||||
|
|
29
cli/cache/emit.rs
vendored
29
cli/cache/emit.rs
vendored
|
@ -44,7 +44,7 @@ impl EmitCache {
|
|||
pub fn get_emit_code(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
expected_source_hash: Option<u64>,
|
||||
expected_source_hash: u64,
|
||||
) -> Option<String> {
|
||||
let meta_filename = self.get_meta_filename(specifier)?;
|
||||
let emit_filename = self.get_emit_filename(specifier)?;
|
||||
|
@ -52,10 +52,8 @@ impl EmitCache {
|
|||
// load and verify the meta data file is for this source and CLI version
|
||||
let bytes = self.disk_cache.get(&meta_filename).ok()?;
|
||||
let meta: EmitMetadata = serde_json::from_slice(&bytes).ok()?;
|
||||
if let Some(expected_source_hash) = expected_source_hash {
|
||||
if meta.source_hash != expected_source_hash.to_string() {
|
||||
return None;
|
||||
}
|
||||
if meta.source_hash != expected_source_hash.to_string() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// load and verify the emit is for the meta data
|
||||
|
@ -173,31 +171,26 @@ mod test {
|
|||
let specifier2 =
|
||||
ModuleSpecifier::from_file_path(temp_dir.path().join("file2.ts"))
|
||||
.unwrap();
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(1)), None);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 1), None);
|
||||
let emit_code1 = "text1".to_string();
|
||||
let emit_code2 = "text2".to_string();
|
||||
cache.set_emit_code(&specifier1, 10, &emit_code1);
|
||||
cache.set_emit_code(&specifier2, 2, &emit_code2);
|
||||
// providing the incorrect source hash
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(5)), None);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
||||
// providing the correct source hash
|
||||
assert_eq!(
|
||||
cache.get_emit_code(&specifier1, Some(10)),
|
||||
Some(emit_code1.clone()),
|
||||
);
|
||||
assert_eq!(cache.get_emit_code(&specifier2, Some(2)), Some(emit_code2));
|
||||
// providing no hash
|
||||
assert_eq!(
|
||||
cache.get_emit_code(&specifier1, None),
|
||||
cache.get_emit_code(&specifier1, 10),
|
||||
Some(emit_code1.clone()),
|
||||
);
|
||||
assert_eq!(cache.get_emit_code(&specifier2, 2), Some(emit_code2));
|
||||
|
||||
// try changing the cli version (should not load previous ones)
|
||||
let cache = EmitCache {
|
||||
disk_cache: disk_cache.clone(),
|
||||
cli_version: "2.0.0".to_string(),
|
||||
};
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(10)), None);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 10), None);
|
||||
cache.set_emit_code(&specifier1, 5, &emit_code1);
|
||||
|
||||
// recreating the cache should still load the data because the CLI version is the same
|
||||
|
@ -205,12 +198,12 @@ mod test {
|
|||
disk_cache,
|
||||
cli_version: "2.0.0".to_string(),
|
||||
};
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(5)), Some(emit_code1));
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 5), Some(emit_code1));
|
||||
|
||||
// adding when already exists should not cause issue
|
||||
let emit_code3 = "asdf".to_string();
|
||||
cache.set_emit_code(&specifier1, 20, &emit_code3);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(5)), None);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, Some(20)), Some(emit_code3));
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
||||
assert_eq!(cache.get_emit_code(&specifier1, 20), Some(emit_code3));
|
||||
}
|
||||
}
|
||||
|
|
27
cli/http_cache.rs → cli/cache/http_cache.rs
vendored
27
cli/http_cache.rs → cli/cache/http_cache.rs
vendored
|
@ -3,8 +3,8 @@
|
|||
//! as defined in RFC 7234 (<https://tools.ietf.org/html/rfc7234>).
|
||||
//! Currently it's a very simplified version to fulfill Deno needs
|
||||
//! at hand.
|
||||
use crate::fs_util;
|
||||
use crate::http_util::HeadersMap;
|
||||
use crate::util;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde::Deserialize;
|
||||
|
@ -19,7 +19,7 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub const CACHE_PERM: u32 = 0o644;
|
||||
use super::CACHE_PERM;
|
||||
|
||||
/// Turn base of url (scheme, hostname, port) into a valid filename.
|
||||
/// This method replaces port part with a special string token (because
|
||||
|
@ -68,31 +68,32 @@ pub fn url_to_filename(url: &Url) -> Option<PathBuf> {
|
|||
// NOTE: fragment is omitted on purpose - it's not taken into
|
||||
// account when caching - it denotes parts of webpage, which
|
||||
// in case of static resources doesn't make much sense
|
||||
let hashed_filename = crate::checksum::gen(&[rest_str.as_bytes()]);
|
||||
let hashed_filename = util::checksum::gen(&[rest_str.as_bytes()]);
|
||||
cache_filename.push(hashed_filename);
|
||||
Some(cache_filename)
|
||||
}
|
||||
|
||||
/// Cached metadata about a url.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Metadata {
|
||||
pub struct CachedUrlMetadata {
|
||||
pub headers: HeadersMap,
|
||||
pub url: String,
|
||||
#[serde(default = "SystemTime::now")]
|
||||
pub now: SystemTime,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
impl CachedUrlMetadata {
|
||||
pub fn write(&self, cache_filename: &Path) -> Result<(), AnyError> {
|
||||
let metadata_filename = Self::filename(cache_filename);
|
||||
let json = serde_json::to_string_pretty(self)?;
|
||||
fs_util::atomic_write_file(&metadata_filename, json, CACHE_PERM)?;
|
||||
util::fs::atomic_write_file(&metadata_filename, json, CACHE_PERM)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read(cache_filename: &Path) -> Result<Metadata, AnyError> {
|
||||
let metadata_filename = Metadata::filename(cache_filename);
|
||||
pub fn read(cache_filename: &Path) -> Result<Self, AnyError> {
|
||||
let metadata_filename = Self::filename(cache_filename);
|
||||
let metadata = fs::read_to_string(metadata_filename)?;
|
||||
let metadata: Metadata = serde_json::from_str(&metadata)?;
|
||||
let metadata: Self = serde_json::from_str(&metadata)?;
|
||||
Ok(metadata)
|
||||
}
|
||||
|
||||
|
@ -149,10 +150,10 @@ impl HttpCache {
|
|||
url_to_filename(url)
|
||||
.ok_or_else(|| generic_error("Can't convert url to filename."))?,
|
||||
);
|
||||
let metadata_filename = Metadata::filename(&cache_filename);
|
||||
let metadata_filename = CachedUrlMetadata::filename(&cache_filename);
|
||||
let file = File::open(cache_filename)?;
|
||||
let metadata = fs::read_to_string(metadata_filename)?;
|
||||
let metadata: Metadata = serde_json::from_str(&metadata)?;
|
||||
let metadata: CachedUrlMetadata = serde_json::from_str(&metadata)?;
|
||||
Ok((file, metadata.headers, metadata.now))
|
||||
}
|
||||
|
||||
|
@ -172,9 +173,9 @@ impl HttpCache {
|
|||
.expect("Cache filename should have a parent dir");
|
||||
self.ensure_dir_exists(parent_filename)?;
|
||||
// Cache content
|
||||
fs_util::atomic_write_file(&cache_filename, content, CACHE_PERM)?;
|
||||
util::fs::atomic_write_file(&cache_filename, content, CACHE_PERM)?;
|
||||
|
||||
let metadata = Metadata {
|
||||
let metadata = CachedUrlMetadata {
|
||||
now: SystemTime::now(),
|
||||
url: url.to_string(),
|
||||
headers: headers_map,
|
6
cli/cache/mod.rs
vendored
6
cli/cache/mod.rs
vendored
|
@ -19,6 +19,7 @@ mod common;
|
|||
mod deno_dir;
|
||||
mod disk_cache;
|
||||
mod emit;
|
||||
mod http_cache;
|
||||
mod incremental;
|
||||
mod node;
|
||||
mod parsed_source;
|
||||
|
@ -28,10 +29,15 @@ pub use common::FastInsecureHasher;
|
|||
pub use deno_dir::DenoDir;
|
||||
pub use disk_cache::DiskCache;
|
||||
pub use emit::EmitCache;
|
||||
pub use http_cache::CachedUrlMetadata;
|
||||
pub use http_cache::HttpCache;
|
||||
pub use incremental::IncrementalCache;
|
||||
pub use node::NodeAnalysisCache;
|
||||
pub use parsed_source::ParsedSourceCache;
|
||||
|
||||
/// Permissions used to save a file in the disk caches.
|
||||
pub const CACHE_PERM: u32 = 0o644;
|
||||
|
||||
/// A "wrapper" for the FileFetcher and DiskCache for the Deno CLI that provides
|
||||
/// a concise interface to the DENO_DIR when building module graphs.
|
||||
pub struct FetchCacher {
|
||||
|
|
|
@ -5,7 +5,7 @@ use once_cell::sync::Lazy;
|
|||
|
||||
// WARNING: Ensure this is the only deno_std version reference as this
|
||||
// is automatically updated by the version bump workflow.
|
||||
static CURRENT_STD_URL_STR: &str = "https://deno.land/std@0.166.0/";
|
||||
static CURRENT_STD_URL_STR: &str = "https://deno.land/std@0.167.0/";
|
||||
|
||||
pub static CURRENT_STD_URL: Lazy<Url> =
|
||||
Lazy::new(|| Url::parse(CURRENT_STD_URL_STR).unwrap());
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::sync::Arc;
|
|||
/// A hashing function that takes the source code and emit options
|
||||
/// hash then generates a string hash which can be stored to
|
||||
/// determine if the cached emit is valid or not.
|
||||
fn get_source_hash(source_text: &str, emit_options_hash: u64) -> u64 {
|
||||
pub fn get_source_hash(source_text: &str, emit_options_hash: u64) -> u64 {
|
||||
FastInsecureHasher::new()
|
||||
.write_str(source_text)
|
||||
.write_u64(emit_options_hash)
|
||||
|
@ -30,9 +30,7 @@ pub fn emit_parsed_source(
|
|||
) -> Result<String, AnyError> {
|
||||
let source_hash = get_source_hash(source, emit_config_hash);
|
||||
|
||||
if let Some(emit_code) =
|
||||
emit_cache.get_emit_code(specifier, Some(source_hash))
|
||||
{
|
||||
if let Some(emit_code) = emit_cache.get_emit_code(specifier, source_hash) {
|
||||
Ok(emit_code)
|
||||
} else {
|
||||
// this will use a cached version if it exists
|
||||
|
|
|
@ -26,8 +26,7 @@ fn get_diagnostic_class(_: &Diagnostic) -> &'static str {
|
|||
fn get_module_graph_error_class(err: &ModuleGraphError) -> &'static str {
|
||||
match err {
|
||||
ModuleGraphError::LoadingErr(_, err) => get_error_class_name(err.as_ref()),
|
||||
ModuleGraphError::InvalidSource(_, _)
|
||||
| ModuleGraphError::InvalidTypeAssertion { .. } => "SyntaxError",
|
||||
ModuleGraphError::InvalidTypeAssertion { .. } => "SyntaxError",
|
||||
ModuleGraphError::ParseErr(_, diagnostic) => {
|
||||
get_diagnostic_class(diagnostic)
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::args::CacheSetting;
|
||||
use crate::auth_tokens::AuthTokens;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::colors;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::http_util::CacheSemantics;
|
||||
use crate::http_util::FetchOnceArgs;
|
||||
use crate::http_util::FetchOnceResult;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::progress_bar::ProgressBar;
|
||||
use crate::text_encoding;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
use crate::util::text_encoding;
|
||||
|
||||
use data_url::DataUrl;
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::uri_error;
|
||||
|
@ -21,11 +21,6 @@ use deno_core::futures;
|
|||
use deno_core::futures::future::FutureExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::rustls_native_certs::load_native_certs;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use deno_runtime::deno_tls::webpki_roots;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use log::debug;
|
||||
|
@ -34,7 +29,6 @@ use std::collections::HashMap;
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::future::Future;
|
||||
use std::io::BufReader;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::pin::Pin;
|
||||
|
@ -82,86 +76,6 @@ impl FileCache {
|
|||
}
|
||||
}
|
||||
|
||||
/// Indicates how cached source files should be handled.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum CacheSetting {
|
||||
/// Only the cached files should be used. Any files not in the cache will
|
||||
/// error. This is the equivalent of `--cached-only` in the CLI.
|
||||
Only,
|
||||
/// No cached source files should be used, and all files should be reloaded.
|
||||
/// This is the equivalent of `--reload` in the CLI.
|
||||
ReloadAll,
|
||||
/// Only some cached resources should be used. This is the equivalent of
|
||||
/// `--reload=https://deno.land/std` or
|
||||
/// `--reload=https://deno.land/std,https://deno.land/x/example`.
|
||||
ReloadSome(Vec<String>),
|
||||
/// The usability of a cached value is determined by analyzing the cached
|
||||
/// headers and other metadata associated with a cached response, reloading
|
||||
/// any cached "non-fresh" cached responses.
|
||||
RespectHeaders,
|
||||
/// The cached source files should be used for local modules. This is the
|
||||
/// default behavior of the CLI.
|
||||
Use,
|
||||
}
|
||||
|
||||
impl CacheSetting {
|
||||
/// Returns if the cache should be used for a given specifier.
|
||||
pub fn should_use(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
http_cache: &HttpCache,
|
||||
) -> bool {
|
||||
match self {
|
||||
CacheSetting::ReloadAll => false,
|
||||
CacheSetting::Use | CacheSetting::Only => true,
|
||||
CacheSetting::RespectHeaders => {
|
||||
if let Ok((_, headers, cache_time)) = http_cache.get(specifier) {
|
||||
let cache_semantics =
|
||||
CacheSemantics::new(headers, cache_time, SystemTime::now());
|
||||
cache_semantics.should_use()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
CacheSetting::ReloadSome(list) => {
|
||||
let mut url = specifier.clone();
|
||||
url.set_fragment(None);
|
||||
if list.contains(&url.as_str().to_string()) {
|
||||
return false;
|
||||
}
|
||||
url.set_query(None);
|
||||
let mut path = PathBuf::from(url.as_str());
|
||||
loop {
|
||||
if list.contains(&path.to_str().unwrap().to_string()) {
|
||||
return false;
|
||||
}
|
||||
if !path.pop() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn should_use_for_npm_package(&self, package_name: &str) -> bool {
|
||||
match self {
|
||||
CacheSetting::ReloadAll => false,
|
||||
CacheSetting::ReloadSome(list) => {
|
||||
if list.contains(&"npm:".to_string()) {
|
||||
return false;
|
||||
}
|
||||
let specifier = format!("npm:{}", package_name);
|
||||
if list.contains(&specifier) {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch a source file from the local file system.
|
||||
fn fetch_local(specifier: &ModuleSpecifier) -> Result<File, AnyError> {
|
||||
let local = specifier.to_file_path().map_err(|_| {
|
||||
|
@ -182,80 +96,6 @@ fn fetch_local(specifier: &ModuleSpecifier) -> Result<File, AnyError> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Create and populate a root cert store based on the passed options and
|
||||
/// environment.
|
||||
pub fn get_root_cert_store(
|
||||
maybe_root_path: Option<PathBuf>,
|
||||
maybe_ca_stores: Option<Vec<String>>,
|
||||
maybe_ca_file: Option<String>,
|
||||
) -> Result<RootCertStore, AnyError> {
|
||||
let mut root_cert_store = RootCertStore::empty();
|
||||
let ca_stores: Vec<String> = maybe_ca_stores
|
||||
.or_else(|| {
|
||||
let env_ca_store = env::var("DENO_TLS_CA_STORE").ok()?;
|
||||
Some(
|
||||
env_ca_store
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| vec!["mozilla".to_string()]);
|
||||
|
||||
for store in ca_stores.iter() {
|
||||
match store.as_str() {
|
||||
"mozilla" => {
|
||||
root_cert_store.add_server_trust_anchors(
|
||||
webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}),
|
||||
);
|
||||
}
|
||||
"system" => {
|
||||
let roots = load_native_certs().expect("could not load platform certs");
|
||||
for root in roots {
|
||||
root_cert_store
|
||||
.add(&rustls::Certificate(root.0))
|
||||
.expect("Failed to add platform cert to root cert store");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!("Unknown certificate store \"{}\" specified (allowed: \"system,mozilla\")", store));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ca_file = maybe_ca_file.or_else(|| env::var("DENO_CERT").ok());
|
||||
if let Some(ca_file) = ca_file {
|
||||
let ca_file = if let Some(root) = &maybe_root_path {
|
||||
root.join(&ca_file)
|
||||
} else {
|
||||
PathBuf::from(ca_file)
|
||||
};
|
||||
let certfile = fs::File::open(&ca_file)?;
|
||||
let mut reader = BufReader::new(certfile);
|
||||
|
||||
match rustls_pemfile::certs(&mut reader) {
|
||||
Ok(certs) => {
|
||||
root_cert_store.add_parsable_certificates(&certs);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(anyhow!(
|
||||
"Unable to add pem file to certificate store: {}",
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(root_cert_store)
|
||||
}
|
||||
|
||||
/// Returns the decoded body and content-type of a provided
|
||||
/// data URL.
|
||||
pub fn get_source_from_data_url(
|
||||
|
@ -571,7 +411,7 @@ impl FileFetcher {
|
|||
return futures::future::err(err).boxed();
|
||||
}
|
||||
|
||||
if self.cache_setting.should_use(specifier, &self.http_cache) {
|
||||
if self.should_use_cache(specifier) {
|
||||
match self.fetch_cached(specifier, redirect_limit) {
|
||||
Ok(Some(file)) => {
|
||||
return futures::future::ok(file).boxed();
|
||||
|
@ -654,6 +494,41 @@ impl FileFetcher {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
/// Returns if the cache should be used for a given specifier.
|
||||
fn should_use_cache(&self, specifier: &ModuleSpecifier) -> bool {
|
||||
match &self.cache_setting {
|
||||
CacheSetting::ReloadAll => false,
|
||||
CacheSetting::Use | CacheSetting::Only => true,
|
||||
CacheSetting::RespectHeaders => {
|
||||
if let Ok((_, headers, cache_time)) = self.http_cache.get(specifier) {
|
||||
let cache_semantics =
|
||||
CacheSemantics::new(headers, cache_time, SystemTime::now());
|
||||
cache_semantics.should_use()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
CacheSetting::ReloadSome(list) => {
|
||||
let mut url = specifier.clone();
|
||||
url.set_fragment(None);
|
||||
if list.contains(&url.as_str().to_string()) {
|
||||
return false;
|
||||
}
|
||||
url.set_query(None);
|
||||
let mut path = PathBuf::from(url.as_str());
|
||||
loop {
|
||||
if list.contains(&path.to_str().unwrap().to_string()) {
|
||||
return false;
|
||||
}
|
||||
if !path.pop() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch a source file and asynchronously return it.
|
||||
pub async fn fetch(
|
||||
&self,
|
||||
|
@ -754,6 +629,7 @@ impl FileFetcher {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::cache::CachedUrlMetadata;
|
||||
use crate::http_util::HttpClient;
|
||||
|
||||
use super::*;
|
||||
|
@ -1175,8 +1051,7 @@ mod tests {
|
|||
.http_cache
|
||||
.get_cache_filename(&specifier)
|
||||
.unwrap();
|
||||
let mut metadata =
|
||||
crate::http_cache::Metadata::read(&cache_filename).unwrap();
|
||||
let mut metadata = CachedUrlMetadata::read(&cache_filename).unwrap();
|
||||
metadata.headers = HashMap::new();
|
||||
metadata
|
||||
.headers
|
||||
|
@ -1265,8 +1140,7 @@ mod tests {
|
|||
.await;
|
||||
assert!(result.is_ok());
|
||||
|
||||
let metadata_filename =
|
||||
crate::http_cache::Metadata::filename(&cache_filename);
|
||||
let metadata_filename = CachedUrlMetadata::filename(&cache_filename);
|
||||
let metadata_file = fs::File::open(metadata_filename).unwrap();
|
||||
let metadata_file_metadata = metadata_file.metadata().unwrap();
|
||||
let metadata_file_modified_01 = metadata_file_metadata.modified().unwrap();
|
||||
|
@ -1285,8 +1159,7 @@ mod tests {
|
|||
.await;
|
||||
assert!(result.is_ok());
|
||||
|
||||
let metadata_filename =
|
||||
crate::http_cache::Metadata::filename(&cache_filename);
|
||||
let metadata_filename = CachedUrlMetadata::filename(&cache_filename);
|
||||
let metadata_file = fs::File::open(metadata_filename).unwrap();
|
||||
let metadata_file_metadata = metadata_file.metadata().unwrap();
|
||||
let metadata_file_modified_02 = metadata_file_metadata.modified().unwrap();
|
||||
|
@ -1438,7 +1311,7 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
|
||||
let metadata_filename =
|
||||
crate::http_cache::Metadata::filename(&redirected_cache_filename);
|
||||
CachedUrlMetadata::filename(&redirected_cache_filename);
|
||||
let metadata_file = fs::File::open(metadata_filename).unwrap();
|
||||
let metadata_file_metadata = metadata_file.metadata().unwrap();
|
||||
let metadata_file_modified_01 = metadata_file_metadata.modified().unwrap();
|
||||
|
@ -1458,7 +1331,7 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
|
||||
let metadata_filename =
|
||||
crate::http_cache::Metadata::filename(&redirected_cache_filename);
|
||||
CachedUrlMetadata::filename(&redirected_cache_filename);
|
||||
let metadata_file = fs::File::open(metadata_filename).unwrap();
|
||||
let metadata_file_metadata = metadata_file.metadata().unwrap();
|
||||
let metadata_file_modified_02 = metadata_file_metadata.modified().unwrap();
|
||||
|
|
1209
cli/fs_util.rs
1209
cli/fs_util.rs
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::args::Lockfile;
|
||||
use crate::args::TsTypeLib;
|
||||
use crate::colors;
|
||||
use crate::errors::get_error_class_name;
|
||||
|
@ -80,23 +81,23 @@ impl GraphData {
|
|||
let mut has_npm_specifier_in_graph = false;
|
||||
|
||||
for (specifier, result) in graph.specifiers() {
|
||||
if NpmPackageReference::from_specifier(&specifier).is_ok() {
|
||||
if NpmPackageReference::from_specifier(specifier).is_ok() {
|
||||
has_npm_specifier_in_graph = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if !reload && self.modules.contains_key(&specifier) {
|
||||
if !reload && self.modules.contains_key(specifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(found) = graph.redirects.get(&specifier) {
|
||||
if let Some(found) = graph.redirects.get(specifier) {
|
||||
let module_entry = ModuleEntry::Redirect(found.clone());
|
||||
self.modules.insert(specifier.clone(), module_entry);
|
||||
continue;
|
||||
}
|
||||
match result {
|
||||
Ok((_, _, media_type)) => {
|
||||
let module = graph.get(&specifier).unwrap();
|
||||
let module = graph.get(specifier).unwrap();
|
||||
let code = match &module.maybe_source {
|
||||
Some(source) => source.clone(),
|
||||
None => continue,
|
||||
|
@ -134,11 +135,11 @@ impl GraphData {
|
|||
checked_libs: Default::default(),
|
||||
maybe_types,
|
||||
};
|
||||
self.modules.insert(specifier, module_entry);
|
||||
self.modules.insert(specifier.clone(), module_entry);
|
||||
}
|
||||
Err(error) => {
|
||||
let module_entry = ModuleEntry::Error(error);
|
||||
self.modules.insert(specifier, module_entry);
|
||||
let module_entry = ModuleEntry::Error(error.clone());
|
||||
self.modules.insert(specifier.clone(), module_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,10 +476,23 @@ pub fn graph_valid(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Calls `graph.lock()` and exits on errors.
|
||||
pub fn graph_lock_or_exit(graph: &ModuleGraph) {
|
||||
if let Err(err) = graph.lock() {
|
||||
log::error!("{} {}", colors::red("error:"), err);
|
||||
std::process::exit(10);
|
||||
/// Checks the lockfile against the graph and and exits on errors.
|
||||
pub fn graph_lock_or_exit(graph: &ModuleGraph, lockfile: &mut Lockfile) {
|
||||
for module in graph.modules() {
|
||||
if let Some(source) = &module.maybe_source {
|
||||
if !lockfile.check_or_insert_remote(module.specifier.as_str(), source) {
|
||||
let err = format!(
|
||||
concat!(
|
||||
"The source code is invalid, as it does not match the expected hash in the lock file.\n",
|
||||
" Specifier: {}\n",
|
||||
" Lock file: {}",
|
||||
),
|
||||
module.specifier,
|
||||
lockfile.filename.display(),
|
||||
);
|
||||
log::error!("{} {}", colors::red("error:"), err);
|
||||
std::process::exit(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -708,7 +708,7 @@
|
|||
);
|
||||
}
|
||||
testDesc.origin = getTestOrigin();
|
||||
const jsError = Deno.core.destructureError(new Error());
|
||||
const jsError = core.destructureError(new Error());
|
||||
testDesc.location = {
|
||||
fileName: jsError.frames[1].fileName,
|
||||
lineNumber: jsError.frames[1].lineNumber,
|
||||
|
@ -1086,6 +1086,9 @@
|
|||
}
|
||||
|
||||
for (const desc of filtered) {
|
||||
if (ops.op_tests_should_stop()) {
|
||||
break;
|
||||
}
|
||||
ops.op_dispatch_test_event({ wait: desc.id });
|
||||
const earlier = DateNow();
|
||||
const result = await runTest(desc);
|
||||
|
@ -1290,7 +1293,7 @@
|
|||
stepDesc.sanitizeResources ??= desc.sanitizeResources;
|
||||
stepDesc.sanitizeExit ??= desc.sanitizeExit;
|
||||
stepDesc.origin = getTestOrigin();
|
||||
const jsError = Deno.core.destructureError(new Error());
|
||||
const jsError = core.destructureError(new Error());
|
||||
stepDesc.location = {
|
||||
fileName: jsError.frames[1].fileName,
|
||||
lineNumber: jsError.frames[1].lineNumber,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::http_cache;
|
||||
use crate::cache::CachedUrlMetadata;
|
||||
use crate::cache::HttpCache;
|
||||
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::ModuleSpecifier;
|
||||
|
@ -49,14 +50,14 @@ struct Metadata {
|
|||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct CacheMetadata {
|
||||
cache: http_cache::HttpCache,
|
||||
cache: HttpCache,
|
||||
metadata: Arc<Mutex<HashMap<ModuleSpecifier, Metadata>>>,
|
||||
}
|
||||
|
||||
impl CacheMetadata {
|
||||
pub fn new(location: &Path) -> Self {
|
||||
Self {
|
||||
cache: http_cache::HttpCache::new(location),
|
||||
cache: HttpCache::new(location),
|
||||
metadata: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -87,8 +88,7 @@ impl CacheMetadata {
|
|||
return None;
|
||||
}
|
||||
let cache_filename = self.cache.get_cache_filename(specifier)?;
|
||||
let specifier_metadata =
|
||||
http_cache::Metadata::read(&cache_filename).ok()?;
|
||||
let specifier_metadata = CachedUrlMetadata::read(&cache_filename).ok()?;
|
||||
let values = Arc::new(parse_metadata(&specifier_metadata.headers));
|
||||
let version = calculate_fs_version(&cache_filename);
|
||||
let mut metadata_map = self.metadata.lock();
|
||||
|
@ -98,7 +98,7 @@ impl CacheMetadata {
|
|||
}
|
||||
|
||||
pub fn set_location(&mut self, location: &Path) {
|
||||
self.cache = http_cache::HttpCache::new(location);
|
||||
self.cache = HttpCache::new(location);
|
||||
self.metadata.lock().clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ use super::lsp_custom;
|
|||
use super::registries::ModuleRegistry;
|
||||
use super::tsc;
|
||||
|
||||
use crate::fs_util::is_supported_ext;
|
||||
use crate::fs_util::relative_specifier;
|
||||
use crate::fs_util::specifier_to_file_path;
|
||||
use crate::util::path::is_supported_ext;
|
||||
use crate::util::path::relative_specifier;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
|
||||
use deno_ast::LineAndColumnIndex;
|
||||
use deno_ast::SourceTextInfo;
|
||||
|
@ -505,7 +505,7 @@ fn get_workspace_completions(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::lsp::documents::Documents;
|
||||
use crate::lsp::documents::LanguageId;
|
||||
use deno_core::resolve_url;
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
use super::client::Client;
|
||||
use super::logging::lsp_log;
|
||||
use crate::fs_util;
|
||||
use crate::util::path::ensure_directory_specifier;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
|
@ -549,11 +550,11 @@ impl Config {
|
|||
workspace: &ModuleSpecifier,
|
||||
enabled_paths: Vec<String>,
|
||||
) -> bool {
|
||||
let workspace = fs_util::ensure_directory_specifier(workspace.clone());
|
||||
let workspace = ensure_directory_specifier(workspace.clone());
|
||||
let key = workspace.to_string();
|
||||
let mut touched = false;
|
||||
if !enabled_paths.is_empty() {
|
||||
if let Ok(workspace_path) = fs_util::specifier_to_file_path(&workspace) {
|
||||
if let Ok(workspace_path) = specifier_to_file_path(&workspace) {
|
||||
let mut paths = Vec::new();
|
||||
for path in &enabled_paths {
|
||||
let fs_path = workspace_path.join(path);
|
||||
|
|
|
@ -6,21 +6,20 @@ use super::tsc;
|
|||
use super::tsc::AssetDocument;
|
||||
|
||||
use crate::args::ConfigFile;
|
||||
use crate::cache::CachedUrlMetadata;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::file_fetcher::get_source_from_bytes;
|
||||
use crate::file_fetcher::map_content_type;
|
||||
use crate::file_fetcher::SUPPORTED_SCHEMES;
|
||||
use crate::fs_util::specifier_to_file_path;
|
||||
use crate::http_cache;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::node;
|
||||
use crate::node::node_resolve_npm_reference;
|
||||
use crate::node::NodeResolution;
|
||||
use crate::node::NodeResolutionMode;
|
||||
use crate::npm::NpmPackageReference;
|
||||
use crate::npm::NpmPackageReq;
|
||||
use crate::npm::NpmPackageResolver;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::text_encoding;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
use crate::util::text_encoding;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ParsedSource;
|
||||
|
@ -33,10 +32,12 @@ use deno_core::url;
|
|||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::GraphImport;
|
||||
use deno_graph::Resolved;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs;
|
||||
use std::ops::Range;
|
||||
use std::path::Path;
|
||||
|
@ -610,7 +611,7 @@ impl SpecifierResolver {
|
|||
) -> Option<ModuleSpecifier> {
|
||||
let cache_filename = self.cache.get_cache_filename(specifier)?;
|
||||
if redirect_limit > 0 && cache_filename.is_file() {
|
||||
let headers = http_cache::Metadata::read(&cache_filename)
|
||||
let headers = CachedUrlMetadata::read(&cache_filename)
|
||||
.ok()
|
||||
.map(|m| m.headers)?;
|
||||
if let Some(location) = headers.get("location") {
|
||||
|
@ -633,6 +634,23 @@ struct FileSystemDocuments {
|
|||
}
|
||||
|
||||
impl FileSystemDocuments {
|
||||
pub fn get(
|
||||
&mut self,
|
||||
cache: &HttpCache,
|
||||
maybe_resolver: Option<&dyn deno_graph::source::Resolver>,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Option<Document> {
|
||||
let fs_version = get_document_path(cache, specifier)
|
||||
.and_then(|path| calculate_fs_version(&path));
|
||||
let file_system_doc = self.docs.get(specifier);
|
||||
if file_system_doc.map(|d| d.fs_version().to_string()) != fs_version {
|
||||
// attempt to update the file on the file system
|
||||
self.refresh_document(cache, maybe_resolver, specifier)
|
||||
} else {
|
||||
file_system_doc.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds or updates a document by reading the document from the file system
|
||||
/// returning the document.
|
||||
fn refresh_document(
|
||||
|
@ -657,8 +675,7 @@ impl FileSystemDocuments {
|
|||
)
|
||||
} else {
|
||||
let cache_filename = cache.get_cache_filename(specifier)?;
|
||||
let specifier_metadata =
|
||||
http_cache::Metadata::read(&cache_filename).ok()?;
|
||||
let specifier_metadata = CachedUrlMetadata::read(&cache_filename).ok()?;
|
||||
let maybe_content_type =
|
||||
specifier_metadata.headers.get("content-type").cloned();
|
||||
let maybe_headers = Some(&specifier_metadata.headers);
|
||||
|
@ -710,7 +727,7 @@ pub struct Documents {
|
|||
/// settings.
|
||||
maybe_resolver: Option<CliResolver>,
|
||||
/// The npm package requirements.
|
||||
npm_reqs: HashSet<NpmPackageReq>,
|
||||
npm_reqs: Arc<HashSet<NpmPackageReq>>,
|
||||
/// Resolves a specifier to its final redirected to specifier.
|
||||
specifier_resolver: Arc<SpecifierResolver>,
|
||||
}
|
||||
|
@ -725,7 +742,7 @@ impl Documents {
|
|||
file_system_docs: Default::default(),
|
||||
imports: Default::default(),
|
||||
maybe_resolver: None,
|
||||
npm_reqs: HashSet::new(),
|
||||
npm_reqs: Default::default(),
|
||||
specifier_resolver: Arc::new(SpecifierResolver::new(location)),
|
||||
}
|
||||
}
|
||||
|
@ -863,7 +880,7 @@ impl Documents {
|
|||
/// Returns a collection of npm package requirements.
|
||||
pub fn npm_package_reqs(&mut self) -> HashSet<NpmPackageReq> {
|
||||
self.calculate_dependents_if_dirty();
|
||||
self.npm_reqs.clone()
|
||||
(*self.npm_reqs).clone()
|
||||
}
|
||||
|
||||
/// Return a document for the specifier.
|
||||
|
@ -873,19 +890,7 @@ impl Documents {
|
|||
Some(document.clone())
|
||||
} else {
|
||||
let mut file_system_docs = self.file_system_docs.lock();
|
||||
let fs_version = get_document_path(&self.cache, &specifier)
|
||||
.and_then(|path| calculate_fs_version(&path));
|
||||
let file_system_doc = file_system_docs.docs.get(&specifier);
|
||||
if file_system_doc.map(|d| d.fs_version().to_string()) != fs_version {
|
||||
// attempt to update the file on the file system
|
||||
file_system_docs.refresh_document(
|
||||
&self.cache,
|
||||
self.get_maybe_resolver(),
|
||||
&specifier,
|
||||
)
|
||||
} else {
|
||||
file_system_doc.cloned()
|
||||
}
|
||||
file_system_docs.get(&self.cache, self.get_maybe_resolver(), &specifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -938,7 +943,7 @@ impl Documents {
|
|||
/// tsc when type checking.
|
||||
pub fn resolve(
|
||||
&self,
|
||||
specifiers: Vec<String>,
|
||||
specifiers: &[String],
|
||||
referrer: &ModuleSpecifier,
|
||||
maybe_npm_resolver: Option<&NpmPackageResolver>,
|
||||
) -> Option<Vec<Option<(ModuleSpecifier, MediaType)>>> {
|
||||
|
@ -950,9 +955,9 @@ impl Documents {
|
|||
// we're in an npm package, so use node resolution
|
||||
results.push(Some(NodeResolution::into_specifier_and_media_type(
|
||||
node::node_resolve(
|
||||
&specifier,
|
||||
specifier,
|
||||
referrer,
|
||||
node::NodeResolutionMode::Types,
|
||||
NodeResolutionMode::Types,
|
||||
npm_resolver,
|
||||
)
|
||||
.ok()
|
||||
|
@ -963,13 +968,13 @@ impl Documents {
|
|||
}
|
||||
// handle npm:<package> urls
|
||||
if specifier.starts_with("asset:") {
|
||||
if let Ok(specifier) = ModuleSpecifier::parse(&specifier) {
|
||||
if let Ok(specifier) = ModuleSpecifier::parse(specifier) {
|
||||
let media_type = MediaType::from(&specifier);
|
||||
results.push(Some((specifier, media_type)));
|
||||
} else {
|
||||
results.push(None);
|
||||
}
|
||||
} else if let Some(dep) = dependencies.deps.get(&specifier) {
|
||||
} else if let Some(dep) = dependencies.deps.get(specifier) {
|
||||
if let Resolved::Ok { specifier, .. } = &dep.maybe_type {
|
||||
results.push(self.resolve_dependency(specifier, maybe_npm_resolver));
|
||||
} else if let Resolved::Ok { specifier, .. } = &dep.maybe_code {
|
||||
|
@ -978,12 +983,12 @@ impl Documents {
|
|||
results.push(None);
|
||||
}
|
||||
} else if let Some(Resolved::Ok { specifier, .. }) =
|
||||
self.resolve_imports_dependency(&specifier)
|
||||
self.resolve_imports_dependency(specifier)
|
||||
{
|
||||
// clone here to avoid double borrow of self
|
||||
let specifier = specifier.clone();
|
||||
results.push(self.resolve_dependency(&specifier, maybe_npm_resolver));
|
||||
} else if let Ok(npm_ref) = NpmPackageReference::from_str(&specifier) {
|
||||
} else if let Ok(npm_ref) = NpmPackageReference::from_str(specifier) {
|
||||
results.push(maybe_npm_resolver.map(|npm_resolver| {
|
||||
NodeResolution::into_specifier_and_media_type(
|
||||
node_resolve_npm_reference(
|
||||
|
@ -1076,46 +1081,74 @@ impl Documents {
|
|||
/// document and the value is a set of specifiers that depend on that
|
||||
/// document.
|
||||
fn calculate_dependents_if_dirty(&mut self) {
|
||||
#[derive(Default)]
|
||||
struct DocAnalyzer {
|
||||
dependents_map: HashMap<ModuleSpecifier, HashSet<ModuleSpecifier>>,
|
||||
analyzed_specifiers: HashSet<ModuleSpecifier>,
|
||||
pending_specifiers: VecDeque<ModuleSpecifier>,
|
||||
npm_reqs: HashSet<NpmPackageReq>,
|
||||
}
|
||||
|
||||
impl DocAnalyzer {
|
||||
fn add(&mut self, dep: &ModuleSpecifier, specifier: &ModuleSpecifier) {
|
||||
if !self.analyzed_specifiers.contains(dep) {
|
||||
self.analyzed_specifiers.insert(dep.clone());
|
||||
// perf: ensure this is not added to unless this specifier has never
|
||||
// been analyzed in order to not cause an extra file system lookup
|
||||
self.pending_specifiers.push_back(dep.clone());
|
||||
if let Ok(reference) = NpmPackageReference::from_specifier(dep) {
|
||||
self.npm_reqs.insert(reference.req);
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
.dependents_map
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
.insert(specifier.clone());
|
||||
}
|
||||
|
||||
fn analyze_doc(&mut self, specifier: &ModuleSpecifier, doc: &Document) {
|
||||
self.analyzed_specifiers.insert(specifier.clone());
|
||||
for dependency in doc.dependencies().values() {
|
||||
if let Some(dep) = dependency.get_code() {
|
||||
self.add(dep, specifier);
|
||||
}
|
||||
if let Some(dep) = dependency.get_type() {
|
||||
self.add(dep, specifier);
|
||||
}
|
||||
}
|
||||
if let Resolved::Ok { specifier: dep, .. } =
|
||||
doc.maybe_types_dependency()
|
||||
{
|
||||
self.add(&dep, specifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut file_system_docs = self.file_system_docs.lock();
|
||||
if !file_system_docs.dirty && !self.dirty {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut dependents_map: HashMap<ModuleSpecifier, HashSet<ModuleSpecifier>> =
|
||||
HashMap::new();
|
||||
// favour documents that are open in case a document exists in both collections
|
||||
let mut doc_analyzer = DocAnalyzer::default();
|
||||
// favor documents that are open in case a document exists in both collections
|
||||
let documents = file_system_docs.docs.iter().chain(self.open_docs.iter());
|
||||
for (specifier, doc) in documents {
|
||||
for dependency in doc.dependencies().values() {
|
||||
if let Some(dep) = dependency.get_code() {
|
||||
dependents_map
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
.insert(specifier.clone());
|
||||
}
|
||||
if let Some(dep) = dependency.get_type() {
|
||||
dependents_map
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
.insert(specifier.clone());
|
||||
}
|
||||
}
|
||||
if let Resolved::Ok { specifier: dep, .. } = doc.maybe_types_dependency()
|
||||
doc_analyzer.analyze_doc(specifier, doc);
|
||||
}
|
||||
|
||||
let maybe_resolver = self.get_maybe_resolver();
|
||||
while let Some(specifier) = doc_analyzer.pending_specifiers.pop_front() {
|
||||
if let Some(doc) =
|
||||
file_system_docs.get(&self.cache, maybe_resolver, &specifier)
|
||||
{
|
||||
dependents_map
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
.insert(specifier.clone());
|
||||
doc_analyzer.analyze_doc(&specifier, &doc);
|
||||
}
|
||||
}
|
||||
let mut npm_reqs = HashSet::new();
|
||||
for specifier in dependents_map.keys() {
|
||||
if let Ok(reference) = NpmPackageReference::from_specifier(specifier) {
|
||||
npm_reqs.insert(reference.req);
|
||||
}
|
||||
}
|
||||
self.dependents_map = Arc::new(dependents_map);
|
||||
self.npm_reqs = npm_reqs;
|
||||
|
||||
self.dependents_map = Arc::new(doc_analyzer.dependents_map);
|
||||
self.npm_reqs = Arc::new(doc_analyzer.npm_reqs);
|
||||
self.dirty = false;
|
||||
file_system_docs.dirty = false;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ use super::tsc::Assets;
|
|||
use super::tsc::AssetsSnapshot;
|
||||
use super::tsc::TsServer;
|
||||
use super::urls;
|
||||
use crate::args::get_root_cert_store;
|
||||
use crate::args::CacheSetting;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::ConfigFile;
|
||||
use crate::args::Flags;
|
||||
|
@ -64,10 +66,7 @@ use crate::args::FmtConfig;
|
|||
use crate::args::LintConfig;
|
||||
use crate::args::TsConfig;
|
||||
use crate::cache::DenoDir;
|
||||
use crate::file_fetcher::get_root_cert_store;
|
||||
use crate::file_fetcher::get_source_from_data_url;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::fs_util;
|
||||
use crate::graph_util::graph_valid;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::npm::NpmCache;
|
||||
|
@ -75,9 +74,12 @@ use crate::npm::NpmPackageResolver;
|
|||
use crate::npm::RealNpmRegistryApi;
|
||||
use crate::proc_state::import_map_from_text;
|
||||
use crate::proc_state::ProcState;
|
||||
use crate::progress_bar::ProgressBar;
|
||||
use crate::tools::fmt::format_file;
|
||||
use crate::tools::fmt::format_parsed_source;
|
||||
use crate::util::fs::remove_dir_all_if_exists;
|
||||
use crate::util::path::ensure_directory_specifier;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LanguageServer(Arc<tokio::sync::Mutex<Inner>>);
|
||||
|
@ -238,22 +240,20 @@ fn create_lsp_npm_resolver(
|
|||
http_client: HttpClient,
|
||||
) -> NpmPackageResolver {
|
||||
let registry_url = RealNpmRegistryApi::default_url();
|
||||
// Use an "only" cache setting in order to make the
|
||||
// user do an explicit "cache" command and prevent
|
||||
// the cache from being filled with lots of packages while
|
||||
// the user is typing.
|
||||
let cache_setting = CacheSetting::Only;
|
||||
let progress_bar = ProgressBar::default();
|
||||
let npm_cache = NpmCache::from_deno_dir(
|
||||
dir,
|
||||
cache_setting.clone(),
|
||||
// Use an "only" cache setting in order to make the
|
||||
// user do an explicit "cache" command and prevent
|
||||
// the cache from being filled with lots of packages while
|
||||
// the user is typing.
|
||||
CacheSetting::Only,
|
||||
http_client.clone(),
|
||||
progress_bar.clone(),
|
||||
);
|
||||
let api = RealNpmRegistryApi::new(
|
||||
registry_url,
|
||||
npm_cache.clone(),
|
||||
cache_setting,
|
||||
http_client,
|
||||
progress_bar,
|
||||
);
|
||||
|
@ -409,7 +409,7 @@ impl Inner {
|
|||
// file open and not a workspace. In those situations we can't
|
||||
// automatically discover the configuration
|
||||
if let Some(root_uri) = &self.config.root_uri {
|
||||
let root_path = fs_util::specifier_to_file_path(root_uri)?;
|
||||
let root_path = specifier_to_file_path(root_uri)?;
|
||||
let mut checked = std::collections::HashSet::new();
|
||||
let maybe_config = ConfigFile::discover_from(&root_path, &mut checked)?;
|
||||
Ok(maybe_config.map(|c| {
|
||||
|
@ -483,7 +483,7 @@ impl Inner {
|
|||
let cache_url = if let Ok(url) = Url::from_file_path(cache_str) {
|
||||
Ok(url)
|
||||
} else if let Some(root_uri) = &self.config.root_uri {
|
||||
let root_path = fs_util::specifier_to_file_path(root_uri)?;
|
||||
let root_path = specifier_to_file_path(root_uri)?;
|
||||
let cache_path = root_path.join(cache_str);
|
||||
Url::from_file_path(cache_path).map_err(|_| {
|
||||
anyhow!("Bad file path for import path: {:?}", cache_str)
|
||||
|
@ -494,7 +494,7 @@ impl Inner {
|
|||
cache_str
|
||||
))
|
||||
}?;
|
||||
let cache_path = fs_util::specifier_to_file_path(&cache_url)?;
|
||||
let cache_path = specifier_to_file_path(&cache_url)?;
|
||||
lsp_log!(
|
||||
" Resolved cache path: \"{}\"",
|
||||
cache_path.to_string_lossy()
|
||||
|
@ -523,7 +523,7 @@ impl Inner {
|
|||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
.and_then(|uri| specifier_to_file_path(uri).ok());
|
||||
let root_cert_store = Some(get_root_cert_store(
|
||||
maybe_root_path,
|
||||
workspace_settings.certificate_stores.clone(),
|
||||
|
@ -571,7 +571,7 @@ impl Inner {
|
|||
anyhow!("Bad data url for import map: {}", import_map_str)
|
||||
})?)
|
||||
} else if let Some(root_uri) = &self.config.root_uri {
|
||||
let root_path = fs_util::specifier_to_file_path(root_uri)?;
|
||||
let root_path = specifier_to_file_path(root_uri)?;
|
||||
let import_map_path = root_path.join(&import_map_str);
|
||||
Some(Url::from_file_path(import_map_path).map_err(|_| {
|
||||
anyhow!("Bad file path for import map: {}", import_map_str)
|
||||
|
@ -614,7 +614,7 @@ impl Inner {
|
|||
let import_map_json = if import_map_url.scheme() == "data" {
|
||||
get_source_from_data_url(&import_map_url)?.0
|
||||
} else {
|
||||
let import_map_path = fs_util::specifier_to_file_path(&import_map_url)?;
|
||||
let import_map_path = specifier_to_file_path(&import_map_url)?;
|
||||
lsp_log!(
|
||||
" Resolved import map: \"{}\"",
|
||||
import_map_path.to_string_lossy()
|
||||
|
@ -770,7 +770,7 @@ impl Inner {
|
|||
self.config.root_uri = params
|
||||
.root_uri
|
||||
.map(|s| self.url_map.normalize_url(&s))
|
||||
.map(fs_util::ensure_directory_specifier);
|
||||
.map(ensure_directory_specifier);
|
||||
|
||||
if let Some(value) = params.initialization_options {
|
||||
self.config.set_workspace_settings(value).map_err(|err| {
|
||||
|
@ -1139,11 +1139,10 @@ impl Inner {
|
|||
_ => return Ok(None),
|
||||
};
|
||||
let mark = self.performance.mark("formatting", Some(¶ms));
|
||||
let file_path =
|
||||
fs_util::specifier_to_file_path(&specifier).map_err(|err| {
|
||||
error!("{}", err);
|
||||
LspError::invalid_request()
|
||||
})?;
|
||||
let file_path = specifier_to_file_path(&specifier).map_err(|err| {
|
||||
error!("{}", err);
|
||||
LspError::invalid_request()
|
||||
})?;
|
||||
|
||||
let fmt_options = if let Some(fmt_config) = self.maybe_fmt_config.as_ref() {
|
||||
// skip formatting any files ignored by the config file
|
||||
|
@ -2065,7 +2064,7 @@ impl Inner {
|
|||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
.and_then(|uri| specifier_to_file_path(uri).ok());
|
||||
let mut resolved_items = Vec::<CallHierarchyIncomingCall>::new();
|
||||
for item in incoming_calls.iter() {
|
||||
if let Some(resolved) = item.try_resolve_call_hierarchy_incoming_call(
|
||||
|
@ -2111,7 +2110,7 @@ impl Inner {
|
|||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
.and_then(|uri| specifier_to_file_path(uri).ok());
|
||||
let mut resolved_items = Vec::<CallHierarchyOutgoingCall>::new();
|
||||
for item in outgoing_calls.iter() {
|
||||
if let Some(resolved) = item.try_resolve_call_hierarchy_outgoing_call(
|
||||
|
@ -2164,7 +2163,7 @@ impl Inner {
|
|||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
.and_then(|uri| specifier_to_file_path(uri).ok());
|
||||
let mut resolved_items = Vec::<CallHierarchyItem>::new();
|
||||
match one_or_many {
|
||||
tsc::OneOrMany::One(item) => {
|
||||
|
@ -3012,7 +3011,7 @@ impl Inner {
|
|||
}
|
||||
|
||||
async fn reload_import_registries(&mut self) -> LspResult<Option<Value>> {
|
||||
fs_util::remove_dir_all_if_exists(&self.module_registries_location)
|
||||
remove_dir_all_if_exists(&self.module_registries_location)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to remove registries cache: {}", err);
|
||||
|
|
|
@ -12,10 +12,10 @@ use super::path_to_regex::StringOrNumber;
|
|||
use super::path_to_regex::StringOrVec;
|
||||
use super::path_to_regex::Token;
|
||||
|
||||
use crate::args::CacheSetting;
|
||||
use crate::cache::DenoDir;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::file_fetcher::FileFetcher;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::http_util::HttpClient;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use super::lsp_custom;
|
||||
|
||||
use crate::checksum;
|
||||
use crate::lsp::analysis::source_range_to_lsp_range;
|
||||
use crate::lsp::client::TestingNotification;
|
||||
use crate::util::checksum;
|
||||
|
||||
use deno_ast::SourceRange;
|
||||
use deno_ast::SourceTextInfo;
|
||||
|
|
|
@ -6,7 +6,6 @@ use super::lsp_custom;
|
|||
|
||||
use crate::args::flags_from_vec;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::checksum;
|
||||
use crate::lsp::client::Client;
|
||||
use crate::lsp::client::TestingNotification;
|
||||
use crate::lsp::config;
|
||||
|
@ -14,7 +13,9 @@ use crate::lsp::logging::lsp_log;
|
|||
use crate::ops;
|
||||
use crate::proc_state;
|
||||
use crate::tools::test;
|
||||
use crate::tools::test::FailFastTracker;
|
||||
use crate::tools::test::TestEventSender;
|
||||
use crate::util::checksum;
|
||||
use crate::worker::create_main_worker_for_test_or_bench;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
|
@ -144,25 +145,29 @@ impl LspTestFilter {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn test_specifier(
|
||||
ps: proc_state::ProcState,
|
||||
permissions: Permissions,
|
||||
specifier: ModuleSpecifier,
|
||||
mode: test::TestMode,
|
||||
sender: &TestEventSender,
|
||||
sender: TestEventSender,
|
||||
fail_fast_tracker: FailFastTracker,
|
||||
token: CancellationToken,
|
||||
filter: test::TestFilter,
|
||||
) -> Result<(), AnyError> {
|
||||
if !token.is_cancelled() {
|
||||
let stdout = StdioPipe::File(sender.stdout());
|
||||
let stderr = StdioPipe::File(sender.stderr());
|
||||
let mut worker = create_main_worker_for_test_or_bench(
|
||||
&ps,
|
||||
specifier.clone(),
|
||||
permissions,
|
||||
vec![ops::testing::init(sender.clone(), filter)],
|
||||
vec![ops::testing::init(sender, fail_fast_tracker, filter)],
|
||||
Stdio {
|
||||
stdin: StdioPipe::Inherit,
|
||||
stdout: StdioPipe::File(sender.stdout()),
|
||||
stderr: StdioPipe::File(sender.stderr()),
|
||||
stdout,
|
||||
stderr,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
@ -262,19 +267,17 @@ impl TestRun {
|
|||
)
|
||||
.await?;
|
||||
|
||||
let (sender, mut receiver) = mpsc::unbounded_channel::<test::TestEvent>();
|
||||
let sender = TestEventSender::new(sender);
|
||||
|
||||
let (concurrent_jobs, fail_fast) =
|
||||
if let DenoSubcommand::Test(test_flags) = ps.options.sub_command() {
|
||||
(
|
||||
test_flags.concurrent_jobs.into(),
|
||||
test_flags.fail_fast.map(|count| count.into()),
|
||||
)
|
||||
(test_flags.concurrent_jobs.into(), test_flags.fail_fast)
|
||||
} else {
|
||||
unreachable!("Should always be Test subcommand.");
|
||||
};
|
||||
|
||||
let (sender, mut receiver) = mpsc::unbounded_channel::<test::TestEvent>();
|
||||
let sender = TestEventSender::new(sender);
|
||||
let fail_fast_tracker = FailFastTracker::new(fail_fast);
|
||||
|
||||
let mut queue = self.queue.iter().collect::<Vec<&ModuleSpecifier>>();
|
||||
queue.sort();
|
||||
|
||||
|
@ -288,6 +291,7 @@ impl TestRun {
|
|||
let ps = ps.clone();
|
||||
let permissions = permissions.clone();
|
||||
let mut sender = sender.clone();
|
||||
let fail_fast_tracker = fail_fast_tracker.clone();
|
||||
let lsp_filter = self.filters.get(&specifier);
|
||||
let filter = test::TestFilter {
|
||||
substring: None,
|
||||
|
@ -305,13 +309,17 @@ impl TestRun {
|
|||
let tests = tests_.clone();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
if fail_fast_tracker.should_stop() {
|
||||
return Ok(());
|
||||
}
|
||||
let origin = specifier.to_string();
|
||||
let file_result = run_local(test_specifier(
|
||||
ps,
|
||||
permissions,
|
||||
specifier,
|
||||
test::TestMode::Executable,
|
||||
&sender,
|
||||
sender.clone(),
|
||||
fail_fast_tracker,
|
||||
token,
|
||||
filter,
|
||||
));
|
||||
|
@ -427,12 +435,6 @@ impl TestRun {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(count) = fail_fast {
|
||||
if summary.failed >= count {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let elapsed = Instant::now().duration_since(earlier);
|
||||
|
|
|
@ -18,10 +18,10 @@ use super::urls::LspUrlMap;
|
|||
use super::urls::INVALID_SPECIFIER;
|
||||
|
||||
use crate::args::TsConfig;
|
||||
use crate::fs_util::relative_specifier;
|
||||
use crate::fs_util::specifier_to_file_path;
|
||||
use crate::tsc;
|
||||
use crate::tsc::ResolveArgs;
|
||||
use crate::util::path::relative_specifier;
|
||||
use crate::util::path::specifier_to_file_path;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::custom_error;
|
||||
|
@ -2726,7 +2726,7 @@ fn op_resolve(
|
|||
let referrer = state.normalize_specifier(&args.base)?;
|
||||
|
||||
let result = if let Some(resolved) = state.state_snapshot.documents.resolve(
|
||||
args.specifiers,
|
||||
&args.specifiers,
|
||||
&referrer,
|
||||
state.state_snapshot.maybe_npm_resolver.as_ref(),
|
||||
) {
|
||||
|
@ -3445,7 +3445,7 @@ pub fn request(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::http_util::HeadersMap;
|
||||
use crate::lsp::config::WorkspaceSettings;
|
||||
use crate::lsp::documents::Documents;
|
||||
|
@ -3913,7 +3913,7 @@ mod tests {
|
|||
|
||||
// You might have found this assertion starts failing after upgrading TypeScript.
|
||||
// Just update the new number of assets (declaration files) for this number.
|
||||
assert_eq!(assets.len(), 71);
|
||||
assert_eq!(assets.len(), 72);
|
||||
|
||||
// get some notification when the size of the assets grows
|
||||
let mut total_size = 0;
|
||||
|
|
|
@ -56,7 +56,7 @@ fn hash_data_specifier(specifier: &ModuleSpecifier) -> String {
|
|||
file_name_str.push('?');
|
||||
file_name_str.push_str(query);
|
||||
}
|
||||
crate::checksum::gen(&[file_name_str.as_bytes()])
|
||||
crate::util::checksum::gen(&[file_name_str.as_bytes()])
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
|
49
cli/main.rs
49
cli/main.rs
|
@ -3,20 +3,13 @@
|
|||
mod args;
|
||||
mod auth_tokens;
|
||||
mod cache;
|
||||
mod checksum;
|
||||
mod deno_std;
|
||||
mod diff;
|
||||
mod display;
|
||||
mod emit;
|
||||
mod errors;
|
||||
mod file_fetcher;
|
||||
mod file_watcher;
|
||||
mod fs_util;
|
||||
mod graph_util;
|
||||
mod http_cache;
|
||||
mod http_util;
|
||||
mod js;
|
||||
mod logger;
|
||||
mod lsp;
|
||||
mod module_loader;
|
||||
mod napi;
|
||||
|
@ -24,15 +17,12 @@ mod node;
|
|||
mod npm;
|
||||
mod ops;
|
||||
mod proc_state;
|
||||
mod progress_bar;
|
||||
mod resolver;
|
||||
mod standalone;
|
||||
mod text_encoding;
|
||||
mod tools;
|
||||
mod tsc;
|
||||
mod unix_util;
|
||||
mod util;
|
||||
mod version;
|
||||
mod windows_util;
|
||||
mod worker;
|
||||
|
||||
use crate::args::flags_from_vec;
|
||||
|
@ -63,14 +53,14 @@ use crate::args::UpgradeFlags;
|
|||
use crate::args::VendorFlags;
|
||||
use crate::cache::TypeCheckCache;
|
||||
use crate::file_fetcher::File;
|
||||
use crate::file_watcher::ResolutionResult;
|
||||
use crate::graph_util::graph_lock_or_exit;
|
||||
use crate::proc_state::ProcState;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::tools::check;
|
||||
use crate::util::display;
|
||||
use crate::util::file_watcher::ResolutionResult;
|
||||
|
||||
use args::CliOptions;
|
||||
use args::Lockfile;
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::generic_error;
|
||||
|
@ -324,7 +314,6 @@ async fn create_graph_and_maybe_check(
|
|||
Permissions::allow_all(),
|
||||
Permissions::allow_all(),
|
||||
);
|
||||
let maybe_locker = Lockfile::as_maybe_locker(ps.lockfile.clone());
|
||||
let maybe_imports = ps.options.to_maybe_imports()?;
|
||||
let maybe_cli_resolver = CliResolver::maybe_new(
|
||||
ps.options.to_maybe_jsx_import_source_config(),
|
||||
|
@ -341,7 +330,6 @@ async fn create_graph_and_maybe_check(
|
|||
is_dynamic: false,
|
||||
imports: maybe_imports,
|
||||
resolver: maybe_graph_resolver,
|
||||
locker: maybe_locker,
|
||||
module_analyzer: Some(&*analyzer),
|
||||
reporter: None,
|
||||
},
|
||||
|
@ -362,7 +350,9 @@ async fn create_graph_and_maybe_check(
|
|||
ps.npm_resolver
|
||||
.add_package_reqs(graph_data.npm_package_reqs().clone())
|
||||
.await?;
|
||||
graph_lock_or_exit(&graph);
|
||||
if let Some(lockfile) = &ps.lockfile {
|
||||
graph_lock_or_exit(&graph, &mut lockfile.lock());
|
||||
}
|
||||
|
||||
if ps.options.type_check_mode() != TypeCheckMode::None {
|
||||
let ts_config_result =
|
||||
|
@ -442,7 +432,6 @@ async fn bundle_command(
|
|||
|
||||
let mut paths_to_watch: Vec<PathBuf> = graph
|
||||
.specifiers()
|
||||
.iter()
|
||||
.filter_map(|(_, r)| {
|
||||
r.as_ref().ok().and_then(|(s, _, _)| s.to_file_path().ok())
|
||||
})
|
||||
|
@ -482,7 +471,7 @@ async fn bundle_command(
|
|||
if let Some(out_file) = out_file.as_ref() {
|
||||
let output_bytes = bundle_output.code.as_bytes();
|
||||
let output_len = output_bytes.len();
|
||||
fs_util::write_file(out_file, output_bytes, 0o644)?;
|
||||
util::fs::write_file(out_file, output_bytes, 0o644)?;
|
||||
info!(
|
||||
"{} {:?} ({})",
|
||||
colors::green("Emit"),
|
||||
|
@ -498,7 +487,7 @@ async fn bundle_command(
|
|||
"map".to_string()
|
||||
};
|
||||
let map_out_file = out_file.with_extension(ext);
|
||||
fs_util::write_file(&map_out_file, map_bytes, 0o644)?;
|
||||
util::fs::write_file(&map_out_file, map_bytes, 0o644)?;
|
||||
info!(
|
||||
"{} {:?} ({})",
|
||||
colors::green("Emit"),
|
||||
|
@ -515,10 +504,10 @@ async fn bundle_command(
|
|||
};
|
||||
|
||||
if cli_options.watch_paths().is_some() {
|
||||
file_watcher::watch_func(
|
||||
util::file_watcher::watch_func(
|
||||
resolver,
|
||||
operation,
|
||||
file_watcher::PrintConfig {
|
||||
util::file_watcher::PrintConfig {
|
||||
job_name: "Bundle".to_string(),
|
||||
clear_screen: !cli_options.no_clear_screen(),
|
||||
},
|
||||
|
@ -542,9 +531,8 @@ fn error_for_any_npm_specifier(
|
|||
) -> Result<(), AnyError> {
|
||||
let first_npm_specifier = graph
|
||||
.specifiers()
|
||||
.values()
|
||||
.filter_map(|r| match r {
|
||||
Ok((specifier, kind, _)) if *kind == deno_graph::ModuleKind::External => {
|
||||
.filter_map(|(_, r)| match r {
|
||||
Ok((specifier, kind, _)) if kind == deno_graph::ModuleKind::External => {
|
||||
Some(specifier.clone())
|
||||
}
|
||||
_ => None,
|
||||
|
@ -590,8 +578,7 @@ async fn repl_command(
|
|||
) -> Result<i32, AnyError> {
|
||||
let main_module = resolve_url_or_path("./$deno$repl.ts").unwrap();
|
||||
let ps = ProcState::build(flags).await?;
|
||||
tools::repl::run(&ps, main_module, repl_flags.eval_files, repl_flags.eval)
|
||||
.await
|
||||
tools::repl::run(&ps, main_module, repl_flags).await
|
||||
}
|
||||
|
||||
async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
|
||||
|
@ -648,11 +635,11 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
|||
})
|
||||
};
|
||||
|
||||
file_watcher::watch_func2(
|
||||
util::file_watcher::watch_func2(
|
||||
receiver,
|
||||
operation,
|
||||
(sender, main_module),
|
||||
file_watcher::PrintConfig {
|
||||
util::file_watcher::PrintConfig {
|
||||
job_name: "Process".to_string(),
|
||||
clear_screen: !flags.no_clear_screen,
|
||||
},
|
||||
|
@ -940,8 +927,8 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
|
|||
pub fn main() {
|
||||
setup_panic_hook();
|
||||
|
||||
unix_util::raise_fd_limit();
|
||||
windows_util::ensure_stdio_open();
|
||||
util::unix::raise_fd_limit();
|
||||
util::windows::ensure_stdio_open();
|
||||
#[cfg(windows)]
|
||||
colors::enable_ansi(); // For Windows 10
|
||||
|
||||
|
@ -972,7 +959,7 @@ pub fn main() {
|
|||
init_v8_flags(&flags.v8_flags);
|
||||
}
|
||||
|
||||
logger::init(flags.log_level);
|
||||
util::logger::init(flags.log_level);
|
||||
|
||||
get_subcommand(flags).await
|
||||
};
|
||||
|
|
|
@ -5,8 +5,8 @@ use crate::emit::emit_parsed_source;
|
|||
use crate::graph_util::ModuleEntry;
|
||||
use crate::node;
|
||||
use crate::proc_state::ProcState;
|
||||
use crate::text_encoding::code_without_source_map;
|
||||
use crate::text_encoding::source_map_from_code;
|
||||
use crate::util::text_encoding::code_without_source_map;
|
||||
use crate::util::text_encoding::source_map_from_code;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
|
|
|
@ -59,7 +59,7 @@ fn napi_add_env_cleanup_hook(
|
|||
_hook: extern "C" fn(*const c_void),
|
||||
_data: *const c_void,
|
||||
) -> Result {
|
||||
eprintln!("napi_add_env_cleanup_hook is currently not supported");
|
||||
log::info!("napi_add_env_cleanup_hook is currently not supported");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ fn napi_remove_env_cleanup_hook(
|
|||
_hook: extern "C" fn(*const c_void),
|
||||
_data: *const c_void,
|
||||
) -> Result {
|
||||
eprintln!("napi_remove_env_cleanup_hook is currently not supported");
|
||||
log::info!("napi_remove_env_cleanup_hook is currently not supported");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -737,7 +737,7 @@ fn napi_make_callback(
|
|||
}
|
||||
|
||||
if !async_context.is_null() {
|
||||
eprintln!("napi_make_callback: async_context is not supported");
|
||||
log::info!("napi_make_callback: async_context is not supported");
|
||||
}
|
||||
|
||||
let recv = transmute::<napi_value, v8::Local<v8::Value>>(recv);
|
||||
|
@ -1006,7 +1006,7 @@ fn napi_add_finalizer(
|
|||
_finalize_hint: *const c_void,
|
||||
_result: *mut napi_ref,
|
||||
) -> Result {
|
||||
eprintln!("napi_add_finalizer is not yet supported.");
|
||||
log::info!("napi_add_finalizer is not yet supported.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1260,11 +1260,10 @@ fn napi_delete_reference(env: *mut Env, _nref: napi_ref) -> Result {
|
|||
}
|
||||
|
||||
#[napi_sym::napi_sym]
|
||||
fn napi_detach_arraybuffer(env: *mut Env, value: napi_value) -> Result {
|
||||
let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
|
||||
fn napi_detach_arraybuffer(_env: *mut Env, value: napi_value) -> Result {
|
||||
let value = transmute::<napi_value, v8::Local<v8::Value>>(value);
|
||||
let ab = v8::Local::<v8::ArrayBuffer>::try_from(value).unwrap();
|
||||
ab.detach(v8::undefined(&mut env.scope()).into());
|
||||
ab.detach(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "napi_sym"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
|
@ -20,7 +20,7 @@ pub fn napi_sym(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
let name = &func.sig.ident;
|
||||
assert!(
|
||||
exports.symbols.contains(&name.to_string()),
|
||||
"tools/napi/symbol_exports.json is out of sync!"
|
||||
"tools/napi/sym/symbol_exports.json is out of sync!"
|
||||
);
|
||||
|
||||
let block = &func.block;
|
|
@ -27,12 +27,12 @@ use deno_runtime::deno_node::package_imports_resolve;
|
|||
use deno_runtime::deno_node::package_resolve;
|
||||
use deno_runtime::deno_node::path_to_declaration_path;
|
||||
use deno_runtime::deno_node::NodeModuleKind;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
use deno_runtime::deno_node::PackageJson;
|
||||
use deno_runtime::deno_node::PathClean;
|
||||
use deno_runtime::deno_node::RequireNpmResolver;
|
||||
use deno_runtime::deno_node::DEFAULT_CONDITIONS;
|
||||
use deno_runtime::deno_node::NODE_GLOBAL_THIS_NAME;
|
||||
use deno_runtime::deno_node::TYPES_CONDITIONS;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -95,25 +95,15 @@ impl NodeResolution {
|
|||
},
|
||||
)
|
||||
}
|
||||
maybe_response => {
|
||||
let specifier = match maybe_response {
|
||||
Some(response) => response.into_url(),
|
||||
None => {
|
||||
ModuleSpecifier::parse("deno:///missing_dependency.d.ts").unwrap()
|
||||
}
|
||||
};
|
||||
(specifier, MediaType::Dts)
|
||||
}
|
||||
Some(resolution) => (resolution.into_url(), MediaType::Dts),
|
||||
None => (
|
||||
ModuleSpecifier::parse("deno:///missing_dependency.d.ts").unwrap(),
|
||||
MediaType::Dts,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum NodeResolutionMode {
|
||||
Execution,
|
||||
Types,
|
||||
}
|
||||
|
||||
struct NodeModulePolyfill {
|
||||
/// Name of the module like "assert" or "timers/promises"
|
||||
name: &'static str,
|
||||
|
@ -480,8 +470,13 @@ pub fn node_resolve(
|
|||
}
|
||||
}
|
||||
|
||||
let conditions = mode_conditions(mode);
|
||||
let url = module_resolve(specifier, referrer, conditions, npm_resolver)?;
|
||||
let url = module_resolve(
|
||||
specifier,
|
||||
referrer,
|
||||
DEFAULT_CONDITIONS,
|
||||
mode,
|
||||
npm_resolver,
|
||||
)?;
|
||||
let url = match url {
|
||||
Some(url) => url,
|
||||
None => return Ok(None),
|
||||
|
@ -492,7 +487,10 @@ pub fn node_resolve(
|
|||
let path = url.to_file_path().unwrap();
|
||||
// todo(16370): the module kind is not correct here. I think we need
|
||||
// typescript to tell us if the referrer is esm or cjs
|
||||
let path = path_to_declaration_path(path, NodeModuleKind::Esm);
|
||||
let path = match path_to_declaration_path(path, NodeModuleKind::Esm) {
|
||||
Some(path) => path,
|
||||
None => return Ok(None),
|
||||
};
|
||||
ModuleSpecifier::from_file_path(path).unwrap()
|
||||
}
|
||||
};
|
||||
|
@ -519,7 +517,8 @@ pub fn node_resolve_npm_reference(
|
|||
.unwrap_or_else(|| ".".to_string()),
|
||||
&package_folder,
|
||||
node_module_kind,
|
||||
mode_conditions(mode),
|
||||
DEFAULT_CONDITIONS,
|
||||
mode,
|
||||
npm_resolver,
|
||||
)
|
||||
.with_context(|| {
|
||||
|
@ -532,7 +531,10 @@ pub fn node_resolve_npm_reference(
|
|||
let resolved_path = match mode {
|
||||
NodeResolutionMode::Execution => resolved_path,
|
||||
NodeResolutionMode::Types => {
|
||||
path_to_declaration_path(resolved_path, node_module_kind)
|
||||
match path_to_declaration_path(resolved_path, node_module_kind) {
|
||||
Some(path) => path,
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
};
|
||||
let url = ModuleSpecifier::from_file_path(resolved_path).unwrap();
|
||||
|
@ -542,13 +544,6 @@ pub fn node_resolve_npm_reference(
|
|||
Ok(Some(resolve_response))
|
||||
}
|
||||
|
||||
fn mode_conditions(mode: NodeResolutionMode) -> &'static [&'static str] {
|
||||
match mode {
|
||||
NodeResolutionMode::Execution => DEFAULT_CONDITIONS,
|
||||
NodeResolutionMode::Types => TYPES_CONDITIONS,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_resolve_binary_export(
|
||||
pkg_req: &NpmPackageReq,
|
||||
bin_name: Option<&str>,
|
||||
|
@ -636,17 +631,22 @@ pub fn load_cjs_module_from_ext_node(
|
|||
js_runtime: &mut JsRuntime,
|
||||
module: &str,
|
||||
main: bool,
|
||||
inspect_brk: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
fn escape_for_single_quote_string(text: &str) -> String {
|
||||
text.replace('\\', r"\\").replace('\'', r"\'")
|
||||
}
|
||||
|
||||
let source_code = &format!(
|
||||
r#"(function loadCjsModule(module) {{
|
||||
r#"(function loadCjsModule(module, inspectBrk) {{
|
||||
if (inspectBrk) {{
|
||||
Deno[Deno.internal].require.setInspectBrk();
|
||||
}}
|
||||
Deno[Deno.internal].require.Module._load(module, null, {main});
|
||||
}})('{module}');"#,
|
||||
}})('{module}', {inspect_brk});"#,
|
||||
main = main,
|
||||
module = escape_for_single_quote_string(module),
|
||||
inspect_brk = inspect_brk,
|
||||
);
|
||||
|
||||
js_runtime.execute_script(&located_script_name!(), source_code)?;
|
||||
|
@ -658,6 +658,7 @@ fn package_config_resolve(
|
|||
package_dir: &Path,
|
||||
referrer_kind: NodeModuleKind,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
npm_resolver: &dyn RequireNpmResolver,
|
||||
) -> Result<Option<PathBuf>, AnyError> {
|
||||
let package_json_path = package_dir.join("package.json");
|
||||
|
@ -672,15 +673,15 @@ fn package_config_resolve(
|
|||
&referrer,
|
||||
referrer_kind,
|
||||
conditions,
|
||||
mode,
|
||||
npm_resolver,
|
||||
);
|
||||
match result {
|
||||
Ok(found) => return Ok(Some(found)),
|
||||
Err(exports_err) => {
|
||||
let is_types = conditions == TYPES_CONDITIONS;
|
||||
if is_types && package_subpath == "." {
|
||||
if mode.is_types() && package_subpath == "." {
|
||||
if let Ok(Some(path)) =
|
||||
legacy_main_resolve(&package_config, referrer_kind, conditions)
|
||||
legacy_main_resolve(&package_config, referrer_kind, mode)
|
||||
{
|
||||
return Ok(Some(path));
|
||||
} else {
|
||||
|
@ -692,7 +693,7 @@ fn package_config_resolve(
|
|||
}
|
||||
}
|
||||
if package_subpath == "." {
|
||||
return legacy_main_resolve(&package_config, referrer_kind, conditions);
|
||||
return legacy_main_resolve(&package_config, referrer_kind, mode);
|
||||
}
|
||||
|
||||
Ok(Some(package_dir.join(package_subpath)))
|
||||
|
@ -778,18 +779,21 @@ fn module_resolve(
|
|||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
npm_resolver: &dyn RequireNpmResolver,
|
||||
) -> Result<Option<ModuleSpecifier>, AnyError> {
|
||||
// note: if we're here, the referrer is an esm module
|
||||
let url = if should_be_treated_as_relative_or_absolute_path(specifier) {
|
||||
let resolved_specifier = referrer.join(specifier)?;
|
||||
if conditions == TYPES_CONDITIONS {
|
||||
if mode.is_types() {
|
||||
let file_path = to_file_path(&resolved_specifier);
|
||||
// todo(dsherret): the node module kind is not correct and we
|
||||
// should use the value provided by typescript instead
|
||||
let declaration_path =
|
||||
path_to_declaration_path(file_path, NodeModuleKind::Esm);
|
||||
Some(ModuleSpecifier::from_file_path(declaration_path).unwrap())
|
||||
declaration_path.map(|declaration_path| {
|
||||
ModuleSpecifier::from_file_path(declaration_path).unwrap()
|
||||
})
|
||||
} else {
|
||||
Some(resolved_specifier)
|
||||
}
|
||||
|
@ -800,6 +804,7 @@ fn module_resolve(
|
|||
referrer,
|
||||
NodeModuleKind::Esm,
|
||||
conditions,
|
||||
mode,
|
||||
npm_resolver,
|
||||
)
|
||||
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())?,
|
||||
|
@ -812,6 +817,7 @@ fn module_resolve(
|
|||
referrer,
|
||||
NodeModuleKind::Esm,
|
||||
conditions,
|
||||
mode,
|
||||
npm_resolver,
|
||||
)?
|
||||
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())
|
||||
|
@ -943,6 +949,7 @@ pub fn translate_cjs_to_esm(
|
|||
// FIXME(bartlomieju): check if these conditions are okay, probably
|
||||
// should be `deno-require`, because `deno` is already used in `esm_resolver.rs`
|
||||
&["deno", "require", "default"],
|
||||
NodeResolutionMode::Execution,
|
||||
npm_resolver,
|
||||
)?;
|
||||
let reexport_specifier =
|
||||
|
@ -1013,6 +1020,7 @@ fn resolve(
|
|||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
npm_resolver: &dyn RequireNpmResolver,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
if specifier.starts_with('/') {
|
||||
|
@ -1037,7 +1045,7 @@ fn resolve(
|
|||
let module_dir = npm_resolver.resolve_package_folder_from_package(
|
||||
package_specifier.as_str(),
|
||||
&referrer_path,
|
||||
conditions,
|
||||
mode,
|
||||
)?;
|
||||
|
||||
let package_json_path = module_dir.join("package.json");
|
||||
|
@ -1053,6 +1061,7 @@ fn resolve(
|
|||
referrer,
|
||||
NodeModuleKind::Esm,
|
||||
conditions,
|
||||
mode,
|
||||
npm_resolver,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::url::Url;
|
||||
|
||||
use crate::args::CacheSetting;
|
||||
use crate::cache::DenoDir;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::fs_util;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::progress_bar::ProgressBar;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
use crate::util::fs::hard_link_dir_recursive;
|
||||
use crate::util::path::root_url_to_safe_local_dirname;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
||||
use super::registry::NpmPackageVersionDistInfo;
|
||||
use super::semver::NpmVersion;
|
||||
|
@ -159,7 +164,7 @@ impl ReadonlyNpmCache {
|
|||
std::fs::create_dir_all(root_dir)
|
||||
.with_context(|| format!("Error creating {}", root_dir.display()))?;
|
||||
}
|
||||
Ok(crate::fs_util::canonicalize_path(root_dir)?)
|
||||
Ok(canonicalize_path(root_dir)?)
|
||||
}
|
||||
|
||||
// this may fail on readonly file systems, so just ignore if so
|
||||
|
@ -224,7 +229,7 @@ impl ReadonlyNpmCache {
|
|||
pub fn registry_folder(&self, registry_url: &Url) -> PathBuf {
|
||||
self
|
||||
.root_dir
|
||||
.join(fs_util::root_url_to_safe_local_dirname(registry_url))
|
||||
.join(root_url_to_safe_local_dirname(registry_url))
|
||||
}
|
||||
|
||||
pub fn resolve_package_folder_id_from_specifier(
|
||||
|
@ -249,7 +254,7 @@ impl ReadonlyNpmCache {
|
|||
.root_dir_url
|
||||
.join(&format!(
|
||||
"{}/",
|
||||
fs_util::root_url_to_safe_local_dirname(registry_url)
|
||||
root_url_to_safe_local_dirname(registry_url)
|
||||
.to_string_lossy()
|
||||
.replace('\\', "/")
|
||||
))
|
||||
|
@ -317,6 +322,8 @@ pub struct NpmCache {
|
|||
cache_setting: CacheSetting,
|
||||
http_client: HttpClient,
|
||||
progress_bar: ProgressBar,
|
||||
/// ensures a package is only downloaded once per run
|
||||
previously_reloaded_packages: Arc<Mutex<HashSet<String>>>,
|
||||
}
|
||||
|
||||
impl NpmCache {
|
||||
|
@ -331,6 +338,7 @@ impl NpmCache {
|
|||
cache_setting,
|
||||
http_client,
|
||||
progress_bar,
|
||||
previously_reloaded_packages: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,6 +346,26 @@ impl NpmCache {
|
|||
self.readonly.clone()
|
||||
}
|
||||
|
||||
pub fn cache_setting(&self) -> &CacheSetting {
|
||||
&self.cache_setting
|
||||
}
|
||||
|
||||
/// Checks if the cache should be used for the provided name and version.
|
||||
/// NOTE: Subsequent calls for the same package will always return `true`
|
||||
/// to ensure a package is only downloaded once per run of the CLI. This
|
||||
/// prevents downloads from re-occurring when someone has `--reload` and
|
||||
/// and imports a dynamic import that imports the same package again for example.
|
||||
fn should_use_global_cache_for_package(
|
||||
&self,
|
||||
package: (&str, &NpmVersion),
|
||||
) -> bool {
|
||||
self.cache_setting.should_use_for_npm_package(package.0)
|
||||
|| !self
|
||||
.previously_reloaded_packages
|
||||
.lock()
|
||||
.insert(format!("{}@{}", package.0, package.1))
|
||||
}
|
||||
|
||||
pub async fn ensure_package(
|
||||
&self,
|
||||
package: (&str, &NpmVersion),
|
||||
|
@ -352,10 +380,6 @@ impl NpmCache {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn should_use_cache_for_npm_package(&self, package_name: &str) -> bool {
|
||||
self.cache_setting.should_use_for_npm_package(package_name)
|
||||
}
|
||||
|
||||
async fn ensure_package_inner(
|
||||
&self,
|
||||
package: (&str, &NpmVersion),
|
||||
|
@ -367,11 +391,11 @@ impl NpmCache {
|
|||
package.1,
|
||||
registry_url,
|
||||
);
|
||||
if package_folder.exists()
|
||||
if self.should_use_global_cache_for_package(package)
|
||||
&& package_folder.exists()
|
||||
// if this file exists, then the package didn't successfully extract
|
||||
// the first time, or another process is currently extracting the zip file
|
||||
&& !package_folder.join(NPM_PACKAGE_SYNC_LOCK_FILENAME).exists()
|
||||
&& self.should_use_cache_for_npm_package(package.0)
|
||||
{
|
||||
return Ok(());
|
||||
} else if self.cache_setting == CacheSetting::Only {
|
||||
|
@ -435,12 +459,7 @@ impl NpmCache {
|
|||
with_folder_sync_lock(
|
||||
(id.name.as_str(), &id.version),
|
||||
&package_folder,
|
||||
|| {
|
||||
fs_util::hard_link_dir_recursive(
|
||||
&original_package_folder,
|
||||
&package_folder,
|
||||
)
|
||||
},
|
||||
|| hard_link_dir_recursive(&original_package_folder, &package_folder),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::PathBuf;
|
||||
|
@ -20,11 +21,11 @@ use deno_core::url::Url;
|
|||
use deno_runtime::colors;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::fs_util;
|
||||
use crate::http_cache::CACHE_PERM;
|
||||
use crate::args::CacheSetting;
|
||||
use crate::cache::CACHE_PERM;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::progress_bar::ProgressBar;
|
||||
use crate::util::fs::atomic_write_file;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
||||
use super::cache::NpmCache;
|
||||
use super::resolution::NpmVersionMatcher;
|
||||
|
@ -248,7 +249,6 @@ impl RealNpmRegistryApi {
|
|||
pub fn new(
|
||||
base_url: Url,
|
||||
cache: NpmCache,
|
||||
cache_setting: CacheSetting,
|
||||
http_client: HttpClient,
|
||||
progress_bar: ProgressBar,
|
||||
) -> Self {
|
||||
|
@ -256,7 +256,7 @@ impl RealNpmRegistryApi {
|
|||
base_url,
|
||||
cache,
|
||||
mem_cache: Default::default(),
|
||||
cache_setting,
|
||||
previously_reloaded_packages: Default::default(),
|
||||
http_client,
|
||||
progress_bar,
|
||||
}))
|
||||
|
@ -286,7 +286,7 @@ struct RealNpmRegistryApiInner {
|
|||
base_url: Url,
|
||||
cache: NpmCache,
|
||||
mem_cache: Mutex<HashMap<String, Option<Arc<NpmPackageInfo>>>>,
|
||||
cache_setting: CacheSetting,
|
||||
previously_reloaded_packages: Mutex<HashSet<String>>,
|
||||
http_client: HttpClient,
|
||||
progress_bar: ProgressBar,
|
||||
}
|
||||
|
@ -296,12 +296,16 @@ impl RealNpmRegistryApiInner {
|
|||
&self,
|
||||
name: &str,
|
||||
) -> Result<Option<Arc<NpmPackageInfo>>, AnyError> {
|
||||
let maybe_info = self.mem_cache.lock().get(name).cloned();
|
||||
if let Some(info) = maybe_info {
|
||||
Ok(info)
|
||||
let maybe_maybe_info = self.mem_cache.lock().get(name).cloned();
|
||||
if let Some(maybe_info) = maybe_maybe_info {
|
||||
Ok(maybe_info)
|
||||
} else {
|
||||
let mut maybe_package_info = None;
|
||||
if self.cache_setting.should_use_for_npm_package(name) {
|
||||
if self.cache.cache_setting().should_use_for_npm_package(name)
|
||||
// if this has been previously reloaded, then try loading from the
|
||||
// file system cache
|
||||
|| !self.previously_reloaded_packages.lock().insert(name.to_string())
|
||||
{
|
||||
// attempt to load from the file cache
|
||||
maybe_package_info = self.load_file_cached_package_info(name);
|
||||
}
|
||||
|
@ -401,7 +405,7 @@ impl RealNpmRegistryApiInner {
|
|||
let file_cache_path = self.get_package_file_cache_path(name);
|
||||
let file_text = serde_json::to_string(&package_info)?;
|
||||
std::fs::create_dir_all(file_cache_path.parent().unwrap())?;
|
||||
fs_util::atomic_write_file(&file_cache_path, file_text, CACHE_PERM)?;
|
||||
atomic_write_file(&file_cache_path, file_text, CACHE_PERM)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -409,15 +413,14 @@ impl RealNpmRegistryApiInner {
|
|||
&self,
|
||||
name: &str,
|
||||
) -> Result<Option<NpmPackageInfo>, AnyError> {
|
||||
if self.cache_setting == CacheSetting::Only {
|
||||
if *self.cache.cache_setting() == CacheSetting::Only {
|
||||
return Err(custom_error(
|
||||
"NotCached",
|
||||
format!(
|
||||
"An npm specifier not found in cache: \"{}\", --cached-only is specified.",
|
||||
name
|
||||
)
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
let package_url = self.get_package_url(name);
|
||||
|
|
|
@ -947,7 +947,6 @@ mod tests {
|
|||
is_dynamic: false,
|
||||
imports: None,
|
||||
resolver: None,
|
||||
locker: None,
|
||||
module_analyzer: Some(&analyzer),
|
||||
reporter: None,
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::futures;
|
||||
use deno_core::futures::future::BoxFuture;
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
|
||||
use crate::args::Lockfile;
|
||||
use crate::npm::cache::should_sync_download;
|
||||
|
@ -29,7 +30,7 @@ pub trait InnerNpmPackageResolver: Send + Sync {
|
|||
&self,
|
||||
name: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
|
||||
fn resolve_package_folder_from_specifier(
|
||||
|
|
|
@ -12,17 +12,17 @@ use deno_core::error::AnyError;
|
|||
use deno_core::futures::future::BoxFuture;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_node::PackageJson;
|
||||
use deno_runtime::deno_node::TYPES_CONDITIONS;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
|
||||
use crate::args::Lockfile;
|
||||
use crate::fs_util;
|
||||
use crate::npm::cache::NpmPackageCacheFolderId;
|
||||
use crate::npm::resolution::NpmResolution;
|
||||
use crate::npm::resolution::NpmResolutionSnapshot;
|
||||
use crate::npm::resolvers::common::cache_packages;
|
||||
use crate::npm::NpmCache;
|
||||
use crate::npm::NpmPackageId;
|
||||
use crate::npm::NpmPackageReq;
|
||||
use crate::npm::NpmResolutionPackage;
|
||||
use crate::npm::RealNpmRegistryApi;
|
||||
|
||||
use super::common::ensure_registry_read_permission;
|
||||
|
@ -62,6 +62,17 @@ impl GlobalNpmPackageResolver {
|
|||
.cache
|
||||
.package_folder_for_id(&folder_id, &self.registry_url)
|
||||
}
|
||||
|
||||
fn resolve_types_package(
|
||||
&self,
|
||||
package_name: &str,
|
||||
referrer_pkg_id: &NpmPackageCacheFolderId,
|
||||
) -> Result<NpmResolutionPackage, AnyError> {
|
||||
let types_name = types_package_name(package_name);
|
||||
self
|
||||
.resolution
|
||||
.resolve_package_from_package(&types_name, referrer_pkg_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl InnerNpmPackageResolver for GlobalNpmPackageResolver {
|
||||
|
@ -77,35 +88,25 @@ impl InnerNpmPackageResolver for GlobalNpmPackageResolver {
|
|||
&self,
|
||||
name: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
let referrer_pkg_id = self
|
||||
.cache
|
||||
.resolve_package_folder_id_from_specifier(referrer, &self.registry_url)?;
|
||||
let pkg_result = self
|
||||
.resolution
|
||||
.resolve_package_from_package(name, &referrer_pkg_id);
|
||||
if conditions == TYPES_CONDITIONS && !name.starts_with("@types/") {
|
||||
// When doing types resolution, the package must contain a "types"
|
||||
// entry, or else it will then search for a @types package
|
||||
if let Ok(pkg) = pkg_result {
|
||||
let package_folder = self.package_folder(&pkg.id);
|
||||
let package_json = PackageJson::load_skip_read_permission(
|
||||
package_folder.join("package.json"),
|
||||
)?;
|
||||
if package_json.types.is_some() {
|
||||
return Ok(package_folder);
|
||||
}
|
||||
let pkg = if mode.is_types() && !name.starts_with("@types/") {
|
||||
// attempt to resolve the types package first, then fallback to the regular package
|
||||
match self.resolve_types_package(name, &referrer_pkg_id) {
|
||||
Ok(pkg) => pkg,
|
||||
Err(_) => self
|
||||
.resolution
|
||||
.resolve_package_from_package(name, &referrer_pkg_id)?,
|
||||
}
|
||||
|
||||
let name = types_package_name(name);
|
||||
let pkg = self
|
||||
.resolution
|
||||
.resolve_package_from_package(&name, &referrer_pkg_id)?;
|
||||
Ok(self.package_folder(&pkg.id))
|
||||
} else {
|
||||
Ok(self.package_folder(&pkg_result?.id))
|
||||
}
|
||||
self
|
||||
.resolution
|
||||
.resolve_package_from_package(name, &referrer_pkg_id)?
|
||||
};
|
||||
Ok(self.package_folder(&pkg.id))
|
||||
}
|
||||
|
||||
fn resolve_package_folder_from_specifier(
|
||||
|
@ -125,7 +126,7 @@ impl InnerNpmPackageResolver for GlobalNpmPackageResolver {
|
|||
|
||||
fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError> {
|
||||
let package_folder = self.package_folder(package_id);
|
||||
Ok(fs_util::dir_size(&package_folder)?)
|
||||
Ok(crate::util::fs::dir_size(&package_folder)?)
|
||||
}
|
||||
|
||||
fn has_packages(&self) -> bool {
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::util::fs::symlink_dir;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
|
@ -18,12 +19,11 @@ use deno_core::futures::future::BoxFuture;
|
|||
use deno_core::futures::FutureExt;
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_core::futures;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
use deno_runtime::deno_node::PackageJson;
|
||||
use deno_runtime::deno_node::TYPES_CONDITIONS;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use crate::args::Lockfile;
|
||||
use crate::fs_util;
|
||||
use crate::npm::cache::mixed_case_package_name_encode;
|
||||
use crate::npm::cache::should_sync_download;
|
||||
use crate::npm::cache::NpmPackageCacheFolderId;
|
||||
|
@ -34,6 +34,8 @@ use crate::npm::NpmPackageId;
|
|||
use crate::npm::NpmPackageReq;
|
||||
use crate::npm::NpmResolutionPackage;
|
||||
use crate::npm::RealNpmRegistryApi;
|
||||
use crate::util::fs::copy_dir_recursive;
|
||||
use crate::util::fs::hard_link_dir_recursive;
|
||||
|
||||
use super::common::ensure_registry_read_permission;
|
||||
use super::common::types_package_name;
|
||||
|
@ -150,7 +152,7 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver {
|
|||
&self,
|
||||
name: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
let local_path = self.resolve_folder_for_specifier(referrer)?;
|
||||
let package_root_path = self.resolve_package_root(&local_path);
|
||||
|
@ -160,7 +162,7 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver {
|
|||
let sub_dir = join_package_name(current_folder, name);
|
||||
if sub_dir.is_dir() {
|
||||
// if doing types resolution, only resolve the package if it specifies a types property
|
||||
if conditions == TYPES_CONDITIONS && !name.starts_with("@types/") {
|
||||
if mode.is_types() && !name.starts_with("@types/") {
|
||||
let package_json = PackageJson::load_skip_read_permission(
|
||||
sub_dir.join("package.json"),
|
||||
)?;
|
||||
|
@ -173,7 +175,7 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver {
|
|||
}
|
||||
|
||||
// if doing type resolution, check for the existance of a @types package
|
||||
if conditions == TYPES_CONDITIONS && !name.starts_with("@types/") {
|
||||
if mode.is_types() && !name.starts_with("@types/") {
|
||||
let sub_dir =
|
||||
join_package_name(current_folder, &types_package_name(name));
|
||||
if sub_dir.is_dir() {
|
||||
|
@ -203,7 +205,7 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver {
|
|||
fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError> {
|
||||
let package_folder_path = self.get_package_id_folder(package_id)?;
|
||||
|
||||
Ok(fs_util::dir_size(&package_folder_path)?)
|
||||
Ok(crate::util::fs::dir_size(&package_folder_path)?)
|
||||
}
|
||||
|
||||
fn has_packages(&self) -> bool {
|
||||
|
@ -291,7 +293,9 @@ async fn sync_resolution_with_fs(
|
|||
get_package_folder_id_folder_name(&package.get_package_cache_folder_id());
|
||||
let folder_path = deno_local_registry_dir.join(&folder_name);
|
||||
let initialized_file = folder_path.join(".initialized");
|
||||
if !cache.should_use_cache_for_npm_package(&package.id.name)
|
||||
if !cache
|
||||
.cache_setting()
|
||||
.should_use_for_npm_package(&package.id.name)
|
||||
|| !initialized_file.exists()
|
||||
{
|
||||
let cache = cache.clone();
|
||||
|
@ -316,7 +320,7 @@ async fn sync_resolution_with_fs(
|
|||
®istry_url,
|
||||
);
|
||||
// for now copy, but in the future consider hard linking
|
||||
fs_util::copy_dir_recursive(&cache_folder, &package_path)?;
|
||||
copy_dir_recursive(&cache_folder, &package_path)?;
|
||||
// write out a file that indicates this folder has been initialized
|
||||
fs::write(initialized_file, "")?;
|
||||
Ok(())
|
||||
|
@ -354,7 +358,7 @@ async fn sync_resolution_with_fs(
|
|||
.join("node_modules"),
|
||||
&package.id.name,
|
||||
);
|
||||
fs_util::hard_link_dir_recursive(&source_path, &package_path)?;
|
||||
hard_link_dir_recursive(&source_path, &package_path)?;
|
||||
// write out a file that indicates this folder has been initialized
|
||||
fs::write(initialized_file, "")?;
|
||||
}
|
||||
|
@ -465,7 +469,7 @@ fn symlink_package_dir(
|
|||
#[cfg(windows)]
|
||||
return junction_or_symlink_dir(old_path, new_path);
|
||||
#[cfg(not(windows))]
|
||||
fs_util::symlink_dir(old_path, new_path)
|
||||
symlink_dir(old_path, new_path)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
@ -475,6 +479,7 @@ fn junction_or_symlink_dir(
|
|||
) -> Result<(), AnyError> {
|
||||
// Use junctions because they're supported on ntfs file systems without
|
||||
// needing to elevate privileges on Windows
|
||||
|
||||
match junction::create(old_path, new_path) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(junction_err) => {
|
||||
|
@ -484,7 +489,7 @@ fn junction_or_symlink_dir(
|
|||
log::warn!("Error creating junction. {:#}", junction_err);
|
||||
}
|
||||
|
||||
match fs_util::symlink_dir(old_path, new_path) {
|
||||
match symlink_dir(old_path, new_path) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(symlink_err) => bail!(
|
||||
concat!(
|
||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::error::custom_error;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde_json;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
use deno_runtime::deno_node::PathClean;
|
||||
use deno_runtime::deno_node::RequireNpmResolver;
|
||||
use global::GlobalNpmPackageResolver;
|
||||
|
@ -23,7 +24,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::args::Lockfile;
|
||||
use crate::fs_util;
|
||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||
|
||||
use self::common::InnerNpmPackageResolver;
|
||||
use self::local::LocalNpmPackageResolver;
|
||||
|
@ -187,8 +188,12 @@ impl NpmPackageResolver {
|
|||
let path = self
|
||||
.inner
|
||||
.resolve_package_folder_from_deno_module(pkg_req)?;
|
||||
let path = fs_util::canonicalize_path_maybe_not_exists(&path)?;
|
||||
log::debug!("Resolved {} to {}", pkg_req, path.display());
|
||||
let path = canonicalize_path_maybe_not_exists(&path)?;
|
||||
log::debug!(
|
||||
"Resolved package folder of {} to {}",
|
||||
pkg_req,
|
||||
path.display()
|
||||
);
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
|
@ -197,11 +202,11 @@ impl NpmPackageResolver {
|
|||
&self,
|
||||
name: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
let path = self
|
||||
.inner
|
||||
.resolve_package_folder_from_package(name, referrer, conditions)?;
|
||||
.resolve_package_folder_from_package(name, referrer, mode)?;
|
||||
log::debug!("Resolved {} from {} to {}", name, referrer, path.display());
|
||||
Ok(path)
|
||||
}
|
||||
|
@ -216,7 +221,11 @@ impl NpmPackageResolver {
|
|||
let path = self
|
||||
.inner
|
||||
.resolve_package_folder_from_specifier(specifier)?;
|
||||
log::debug!("Resolved {} to {}", specifier, path.display());
|
||||
log::debug!(
|
||||
"Resolved package folder of {} to {}",
|
||||
specifier,
|
||||
path.display()
|
||||
);
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
|
@ -330,10 +339,10 @@ impl RequireNpmResolver for NpmPackageResolver {
|
|||
&self,
|
||||
specifier: &str,
|
||||
referrer: &std::path::Path,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
let referrer = path_to_specifier(referrer)?;
|
||||
self.resolve_package_folder_from_package(specifier, &referrer, conditions)
|
||||
self.resolve_package_folder_from_package(specifier, &referrer, mode)
|
||||
}
|
||||
|
||||
fn resolve_package_folder_from_path(
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::tools::test::FailFastTracker;
|
||||
use crate::tools::test::TestDescription;
|
||||
use crate::tools::test::TestEvent;
|
||||
use crate::tools::test::TestEventSender;
|
||||
use crate::tools::test::TestFilter;
|
||||
use crate::tools::test::TestLocation;
|
||||
use crate::tools::test::TestResult;
|
||||
use crate::tools::test::TestStepDescription;
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
|
@ -23,7 +25,11 @@ use std::sync::atomic::AtomicUsize;
|
|||
use std::sync::atomic::Ordering;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn init(sender: TestEventSender, filter: TestFilter) -> Extension {
|
||||
pub fn init(
|
||||
sender: TestEventSender,
|
||||
fail_fast_tracker: FailFastTracker,
|
||||
filter: TestFilter,
|
||||
) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
op_pledge_test_permissions::decl(),
|
||||
|
@ -32,9 +38,11 @@ pub fn init(sender: TestEventSender, filter: TestFilter) -> Extension {
|
|||
op_register_test::decl(),
|
||||
op_register_test_step::decl(),
|
||||
op_dispatch_test_event::decl(),
|
||||
op_tests_should_stop::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(sender.clone());
|
||||
state.put(fail_fast_tracker.clone());
|
||||
state.put(filter.clone());
|
||||
Ok(())
|
||||
})
|
||||
|
@ -178,7 +186,18 @@ fn op_dispatch_test_event(
|
|||
state: &mut OpState,
|
||||
event: TestEvent,
|
||||
) -> Result<(), AnyError> {
|
||||
if matches!(
|
||||
event,
|
||||
TestEvent::Result(_, TestResult::Cancelled | TestResult::Failed(_), _)
|
||||
) {
|
||||
state.borrow::<FailFastTracker>().add_failure();
|
||||
}
|
||||
let mut sender = state.borrow::<TestEventSender>().clone();
|
||||
sender.send(event).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_tests_should_stop(state: &mut OpState) -> bool {
|
||||
state.borrow::<FailFastTracker>().should_stop()
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use crate::cache;
|
|||
use crate::cache::DenoDir;
|
||||
use crate::cache::EmitCache;
|
||||
use crate::cache::FastInsecureHasher;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::cache::NodeAnalysisCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::cache::TypeCheckCache;
|
||||
|
@ -19,7 +20,6 @@ use crate::file_fetcher::FileFetcher;
|
|||
use crate::graph_util::graph_lock_or_exit;
|
||||
use crate::graph_util::GraphData;
|
||||
use crate::graph_util::ModuleEntry;
|
||||
use crate::http_cache;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::node;
|
||||
use crate::node::NodeResolution;
|
||||
|
@ -28,9 +28,9 @@ use crate::npm::NpmCache;
|
|||
use crate::npm::NpmPackageReference;
|
||||
use crate::npm::NpmPackageResolver;
|
||||
use crate::npm::RealNpmRegistryApi;
|
||||
use crate::progress_bar::ProgressBar;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::tools::check;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
|
@ -53,6 +53,7 @@ use deno_graph::source::Resolver;
|
|||
use deno_graph::ModuleKind;
|
||||
use deno_graph::Resolved;
|
||||
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||
use deno_runtime::deno_node::NodeResolutionMode;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
|
@ -153,7 +154,7 @@ impl ProcState {
|
|||
let compiled_wasm_module_store = CompiledWasmModuleStore::default();
|
||||
let dir = cli_options.resolve_deno_dir()?;
|
||||
let deps_cache_location = dir.deps_folder_path();
|
||||
let http_cache = http_cache::HttpCache::new(&deps_cache_location);
|
||||
let http_cache = HttpCache::new(&deps_cache_location);
|
||||
let root_cert_store = cli_options.resolve_root_cert_store()?;
|
||||
let cache_usage = cli_options.cache_setting();
|
||||
let progress_bar = ProgressBar::default();
|
||||
|
@ -225,7 +226,6 @@ impl ProcState {
|
|||
let api = RealNpmRegistryApi::new(
|
||||
registry_url,
|
||||
npm_cache.clone(),
|
||||
cli_options.cache_setting(),
|
||||
http_client,
|
||||
progress_bar.clone(),
|
||||
);
|
||||
|
@ -329,7 +329,6 @@ impl ProcState {
|
|||
root_permissions.clone(),
|
||||
dynamic_permissions.clone(),
|
||||
);
|
||||
let maybe_locker = Lockfile::as_maybe_locker(self.lockfile.clone());
|
||||
let maybe_imports = self.options.to_maybe_imports()?;
|
||||
let maybe_resolver =
|
||||
self.maybe_resolver.as_ref().map(|r| r.as_graph_resolver());
|
||||
|
@ -383,16 +382,16 @@ impl ProcState {
|
|||
is_dynamic,
|
||||
imports: maybe_imports,
|
||||
resolver: maybe_resolver,
|
||||
locker: maybe_locker,
|
||||
module_analyzer: Some(&*analyzer),
|
||||
reporter: maybe_file_watcher_reporter,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
// If there was a locker, validate the integrity of all the modules in the
|
||||
// locker.
|
||||
graph_lock_or_exit(&graph);
|
||||
// If there is a lockfile, validate the integrity of all the modules.
|
||||
if let Some(lockfile) = &self.lockfile {
|
||||
graph_lock_or_exit(&graph, &mut lockfile.lock());
|
||||
}
|
||||
|
||||
// Determine any modules that have already been emitted this session and
|
||||
// should be skipped.
|
||||
|
@ -515,7 +514,7 @@ impl ProcState {
|
|||
.handle_node_resolve_result(node::node_resolve(
|
||||
specifier,
|
||||
&referrer,
|
||||
node::NodeResolutionMode::Execution,
|
||||
NodeResolutionMode::Execution,
|
||||
&self.npm_resolver,
|
||||
))
|
||||
.with_context(|| {
|
||||
|
@ -548,7 +547,7 @@ impl ProcState {
|
|||
return self
|
||||
.handle_node_resolve_result(node::node_resolve_npm_reference(
|
||||
&reference,
|
||||
node::NodeResolutionMode::Execution,
|
||||
NodeResolutionMode::Execution,
|
||||
&self.npm_resolver,
|
||||
))
|
||||
.with_context(|| format!("Could not resolve '{}'.", reference));
|
||||
|
@ -639,7 +638,6 @@ impl ProcState {
|
|||
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
||||
loader: &mut dyn Loader,
|
||||
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||
let maybe_locker = Lockfile::as_maybe_locker(self.lockfile.clone());
|
||||
let maybe_imports = self.options.to_maybe_imports()?;
|
||||
|
||||
let maybe_cli_resolver = CliResolver::maybe_new(
|
||||
|
@ -657,7 +655,6 @@ impl ProcState {
|
|||
is_dynamic: false,
|
||||
imports: maybe_imports,
|
||||
resolver: maybe_graph_resolver,
|
||||
locker: maybe_locker,
|
||||
module_analyzer: Some(&*analyzer),
|
||||
reporter: None,
|
||||
},
|
||||
|
|
200
cli/tests/bench_tests.rs
Normal file
200
cli/tests/bench_tests.rs
Normal file
|
@ -0,0 +1,200 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use test_util as util;
|
||||
|
||||
mod bench {
|
||||
use super::*;
|
||||
|
||||
itest!(overloads {
|
||||
args: "bench bench/overloads.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/overloads.out",
|
||||
});
|
||||
|
||||
itest!(meta {
|
||||
args: "bench bench/meta.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/meta.out",
|
||||
});
|
||||
|
||||
itest!(pass {
|
||||
args: "bench bench/pass.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/pass.out",
|
||||
});
|
||||
|
||||
itest!(ignore {
|
||||
args: "bench bench/ignore.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/ignore.out",
|
||||
});
|
||||
|
||||
itest!(ignore_permissions {
|
||||
args: "bench bench/ignore_permissions.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/ignore_permissions.out",
|
||||
});
|
||||
|
||||
itest!(fail {
|
||||
args: "bench bench/fail.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/fail.out",
|
||||
});
|
||||
|
||||
itest!(collect {
|
||||
args: "bench --ignore=bench/collect/ignore bench/collect",
|
||||
exit_code: 0,
|
||||
output: "bench/collect.out",
|
||||
});
|
||||
|
||||
itest!(load_unload {
|
||||
args: "bench bench/load_unload.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/load_unload.out",
|
||||
});
|
||||
|
||||
itest!(interval {
|
||||
args: "bench bench/interval.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/interval.out",
|
||||
});
|
||||
|
||||
itest!(quiet {
|
||||
args: "bench --quiet bench/quiet.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/quiet.out",
|
||||
});
|
||||
|
||||
itest!(only {
|
||||
args: "bench bench/only.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/only.out",
|
||||
});
|
||||
|
||||
itest!(multifile_summary {
|
||||
args: "bench bench/group_baseline.ts bench/pass.ts bench/group_baseline.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/multifile_summary.out",
|
||||
});
|
||||
|
||||
itest!(no_check {
|
||||
args: "bench --no-check bench/no_check.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_check.out",
|
||||
});
|
||||
|
||||
itest!(allow_all {
|
||||
args: "bench --allow-all bench/allow_all.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/allow_all.out",
|
||||
});
|
||||
|
||||
itest!(allow_none {
|
||||
args: "bench bench/allow_none.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/allow_none.out",
|
||||
});
|
||||
|
||||
itest!(exit_sanitizer {
|
||||
args: "bench bench/exit_sanitizer.ts",
|
||||
output: "bench/exit_sanitizer.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(clear_timeout {
|
||||
args: "bench bench/clear_timeout.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/clear_timeout.out",
|
||||
});
|
||||
|
||||
itest!(finally_timeout {
|
||||
args: "bench bench/finally_timeout.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/finally_timeout.out",
|
||||
});
|
||||
|
||||
itest!(group_baseline {
|
||||
args: "bench bench/group_baseline.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/group_baseline.out",
|
||||
});
|
||||
|
||||
itest!(unresolved_promise {
|
||||
args: "bench bench/unresolved_promise.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/unresolved_promise.out",
|
||||
});
|
||||
|
||||
itest!(unhandled_rejection {
|
||||
args: "bench bench/unhandled_rejection.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/unhandled_rejection.out",
|
||||
});
|
||||
|
||||
itest!(filter {
|
||||
args: "bench --filter=foo bench/filter",
|
||||
exit_code: 0,
|
||||
output: "bench/filter.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_by_default {
|
||||
args: "bench --quiet bench/no_prompt_by_default.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_prompt_by_default.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_with_denied_perms {
|
||||
args: "bench --quiet --allow-read bench/no_prompt_with_denied_perms.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_prompt_with_denied_perms.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "bench --quiet bench/check_local_by_default.ts",
|
||||
output: "bench/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "bench --quiet bench/check_local_by_default2.ts",
|
||||
output: "bench/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn recursive_permissions_pledge() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bench")
|
||||
.arg("bench/recursive_permissions_pledge.js")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert!(String::from_utf8(output.stderr).unwrap().contains(
|
||||
"pledge test permissions called before restoring previous pledge"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_protocol() {
|
||||
let file_url =
|
||||
Url::from_file_path(util::testdata_path().join("bench/file_protocol.ts"))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
(util::CheckOutputIntegrationTest {
|
||||
args_vec: vec!["bench", &file_url],
|
||||
exit_code: 0,
|
||||
output: "bench/file_protocol.out",
|
||||
..Default::default()
|
||||
})
|
||||
.run();
|
||||
}
|
||||
}
|
473
cli/tests/bundle_tests.rs
Normal file
473
cli/tests/bundle_tests.rs
Normal file
|
@ -0,0 +1,473 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_ends_with;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod bundle {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bundle_exports() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod1 = util::testdata_path().join("subdir/mod1.ts");
|
||||
assert!(mod1.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_exports_no_check() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod1 = util::testdata_path().join("subdir/mod1.ts");
|
||||
assert!(mod1.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_circular() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let circular1_path = util::testdata_path().join("subdir/circular1.ts");
|
||||
assert!(circular1_path.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle_path = t.path().join("circular1.bundle.js");
|
||||
|
||||
// run this twice to ensure it works even when cached
|
||||
for _ in 0..2 {
|
||||
let mut deno = util::deno_cmd_with_deno_dir(&t)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(&circular1_path)
|
||||
.arg(&bundle_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle_path.is_file());
|
||||
}
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&t)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the the bundle program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"f2\nf1",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_single_module() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let single_module = util::testdata_path().join("subdir/single_module.ts");
|
||||
assert!(single_module.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("single_module.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(single_module)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the the bundle program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello world!",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_tla() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let tla_import = util::testdata_path().join("subdir/tla.ts");
|
||||
assert!(tla_import.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("tla.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(tla_import)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { foo } from \"./tla.bundle.js\";
|
||||
console.log(foo); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_js() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod6 = util::testdata_path().join("subdir/mod6.js");
|
||||
assert!(mod6.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod6.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod6)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_dynamic_import() {
|
||||
let _g = util::http_server();
|
||||
let dynamic_import = util::testdata_path().join("bundle/dynamic_import.ts");
|
||||
assert!(dynamic_import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("bundle_dynamic_import.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(dynamic_import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--allow-net")
|
||||
.arg("--quiet")
|
||||
.arg(&output_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_import_map() {
|
||||
let import = util::testdata_path().join("bundle/import_map/main.ts");
|
||||
let import_map_path =
|
||||
util::testdata_path().join("bundle/import_map/import_map.json");
|
||||
assert!(import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("import_map.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--import-map")
|
||||
.arg(import_map_path)
|
||||
.arg(import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./import_map.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_import_map_no_check() {
|
||||
let import = util::testdata_path().join("bundle/import_map/main.ts");
|
||||
let import_map_path =
|
||||
util::testdata_path().join("bundle/import_map/import_map.json");
|
||||
assert!(import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("import_map.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--import-map")
|
||||
.arg(import_map_path)
|
||||
.arg(import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./import_map.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_json_module() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod7 = util::testdata_path().join("subdir/mod7.js");
|
||||
assert!(mod7.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod7.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod7)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
// ensure the output looks right
|
||||
assert_contains!(String::from_utf8(output.stdout).unwrap(), "with space",);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_json_module_escape_sub() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod8 = util::testdata_path().join("subdir/mod8.js");
|
||||
assert!(mod8.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod8.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod8)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
// make sure the output looks right and the escapes were effective
|
||||
assert_contains!(
|
||||
String::from_utf8(output.stdout).unwrap(),
|
||||
"${globalThis}`and string literal`",
|
||||
);
|
||||
}
|
||||
|
||||
itest!(lockfile_check_error {
|
||||
args: "bundle --lock=bundle/lockfile/check_error.json http://127.0.0.1:4545/subdir/mod1.ts",
|
||||
output: "bundle/lockfile/check_error.out",
|
||||
exit_code: 10,
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(bundle {
|
||||
args: "bundle subdir/mod1.ts",
|
||||
output: "bundle/bundle.test.out",
|
||||
});
|
||||
|
||||
itest!(bundle_jsx {
|
||||
args: "bundle run/jsx_import_from_ts.ts",
|
||||
output: "bundle/jsx.out",
|
||||
});
|
||||
|
||||
itest!(error_bundle_with_bare_import {
|
||||
args: "bundle bundle/bare_imports/error_with_bare_import.ts",
|
||||
output: "bundle/bare_imports/error_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(ts_decorators_bundle {
|
||||
args: "bundle bundle/decorators/ts_decorators.ts",
|
||||
output: "bundle/decorators/ts_decorators.out",
|
||||
});
|
||||
|
||||
itest!(bundle_export_specifier_with_alias {
|
||||
args: "bundle bundle/file_tests-fixture16.ts",
|
||||
output: "bundle/fixture16.out",
|
||||
});
|
||||
|
||||
itest!(bundle_ignore_directives {
|
||||
args: "bundle subdir/mod1.ts",
|
||||
output: "bundle/ignore_directives.test.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default_no_errors {
|
||||
args: "bundle --quiet bundle/check_local_by_default/no_errors.ts",
|
||||
output: "bundle/check_local_by_default/no_errors.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default_type_error {
|
||||
args: "bundle --quiet bundle/check_local_by_default/type_error.ts",
|
||||
output: "bundle/check_local_by_default/type_error.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
}
|
102
cli/tests/cache_tests.rs
Normal file
102
cli/tests/cache_tests.rs
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
mod cache {
|
||||
use super::*;
|
||||
itest!(_036_import_map_fetch {
|
||||
args:
|
||||
"cache --quiet --reload --import-map=import_maps/import_map.json import_maps/test.ts",
|
||||
output: "cache/036_import_map_fetch.out",
|
||||
});
|
||||
|
||||
itest!(_037_fetch_multiple {
|
||||
args: "cache --reload --check=all run/fetch/test.ts run/fetch/other.ts",
|
||||
http_server: true,
|
||||
output: "cache/037_fetch_multiple.out",
|
||||
});
|
||||
|
||||
itest!(_095_cache_with_bare_import {
|
||||
args: "cache cache/095_cache_with_bare_import.ts",
|
||||
output: "cache/095_cache_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(cache_extensionless {
|
||||
args: "cache --reload --check=all http://localhost:4545/subdir/no_js_ext",
|
||||
output: "cache/cache_extensionless.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(cache_random_extension {
|
||||
args:
|
||||
"cache --reload --check=all http://localhost:4545/subdir/no_js_ext@1.0.0",
|
||||
output: "cache/cache_random_extension.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(performance_stats {
|
||||
args: "cache --reload --check=all --log-level debug run/002_hello.ts",
|
||||
output: "cache/performance_stats.out",
|
||||
});
|
||||
|
||||
itest!(redirect_cache {
|
||||
http_server: true,
|
||||
args:
|
||||
"cache --reload --check=all http://localhost:4548/subdir/redirects/a.ts",
|
||||
output: "cache/redirect_cache.out",
|
||||
});
|
||||
|
||||
itest!(ignore_require {
|
||||
args: "cache --reload --no-check cache/ignore_require.js",
|
||||
output_str: Some(""),
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
// This test only runs on linux, because it hardcodes the XDG_CACHE_HOME env var
|
||||
// which is only used on linux.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn relative_home_dir() {
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
let deno_dir = TempDir::new_in(&util::testdata_path());
|
||||
let path = deno_dir.path().strip_prefix(util::testdata_path()).unwrap();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd();
|
||||
let output = deno_cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.env("XDG_CACHE_HOME", path)
|
||||
.env_remove("HOME")
|
||||
.env_remove("DENO_DIR")
|
||||
.arg("cache")
|
||||
.arg("--reload")
|
||||
.arg("--no-check")
|
||||
.arg("run/002_hello.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"");
|
||||
}
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "cache --quiet cache/check_local_by_default.ts",
|
||||
output: "cache/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "cache --quiet cache/check_local_by_default2.ts",
|
||||
output: "cache/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(json_import {
|
||||
// should not error
|
||||
args: "cache --quiet cache/json_import/main.ts",
|
||||
});
|
||||
}
|
321
cli/tests/cert_tests.rs
Normal file
321
cli/tests/cert_tests.rs
Normal file
|
@ -0,0 +1,321 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use deno_runtime::deno_net::ops_tls::TlsStream;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use std::io::BufReader;
|
||||
use std::io::Cursor;
|
||||
use std::io::Read;
|
||||
use std::process::Command;
|
||||
use std::sync::Arc;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use tokio::task::LocalSet;
|
||||
|
||||
mod cert {
|
||||
use super::*;
|
||||
itest_flaky!(cafile_url_imports {
|
||||
args:
|
||||
"run --quiet --reload --cert tls/RootCA.pem cert/cafile_url_imports.ts",
|
||||
output: "cert/cafile_url_imports.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_ts_fetch {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --cert tls/RootCA.pem cert/cafile_ts_fetch.ts",
|
||||
output: "cert/cafile_ts_fetch.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_eval {
|
||||
args: "eval --cert tls/RootCA.pem fetch('https://localhost:5545/cert/cafile_ts_fetch.ts.out').then(r=>r.text()).then(t=>console.log(t.trimEnd()))",
|
||||
output: "cert/cafile_ts_fetch.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_info {
|
||||
args:
|
||||
"info --quiet --cert tls/RootCA.pem https://localhost:5545/cert/cafile_info.ts",
|
||||
output: "cert/cafile_info.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_url_imports_unsafe_ssl {
|
||||
args: "run --quiet --reload --unsafely-ignore-certificate-errors=localhost cert/cafile_url_imports.ts",
|
||||
output: "cert/cafile_url_imports_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_ts_fetch_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors cert/cafile_ts_fetch.ts",
|
||||
output: "cert/cafile_ts_fetch_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(deno_land_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/deno_land_unsafe_ssl.ts",
|
||||
output: "cert/deno_land_unsafe_ssl.ts.out",
|
||||
});
|
||||
|
||||
itest!(ip_address_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=1.1.1.1 cert/ip_address_unsafe_ssl.ts",
|
||||
output: "cert/ip_address_unsafe_ssl.ts.out",
|
||||
});
|
||||
|
||||
itest!(localhost_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/cafile_url_imports.ts",
|
||||
output: "cert/localhost_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_env_fetch() {
|
||||
use deno_core::url::Url;
|
||||
let _g = util::http_server();
|
||||
let deno_dir = TempDir::new();
|
||||
let module_url =
|
||||
Url::parse("https://localhost:5545/cert/cafile_url_imports.ts").unwrap();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.env("DENO_CERT", cafile)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg(module_url.to_string())
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_fetch() {
|
||||
use deno_core::url::Url;
|
||||
let _g = util::http_server();
|
||||
let deno_dir = TempDir::new();
|
||||
let module_url =
|
||||
Url::parse("http://localhost:4545/cert/cafile_url_imports.ts").unwrap();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg(module_url.to_string())
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
assert!(output.status.success());
|
||||
let out = std::str::from_utf8(&output.stdout).unwrap();
|
||||
assert_eq!(out, "");
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_install_remote_module() {
|
||||
let _g = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let deno_dir = TempDir::new();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
|
||||
let install_output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("install")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg("-n")
|
||||
.arg("echo_test")
|
||||
.arg("https://localhost:5545/echo.ts")
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
println!("{}", std::str::from_utf8(&install_output.stdout).unwrap());
|
||||
eprintln!("{}", std::str::from_utf8(&install_output.stderr).unwrap());
|
||||
assert!(install_output.status.success());
|
||||
|
||||
let mut echo_test_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
echo_test_path = echo_test_path.with_extension("cmd");
|
||||
}
|
||||
assert!(echo_test_path.exists());
|
||||
|
||||
let output = Command::new(echo_test_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
assert!(stdout.ends_with("foo"));
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_bundle_remote_exports() {
|
||||
let _g = util::http_server();
|
||||
|
||||
// First we have to generate a bundle of some remote module that has exports.
|
||||
let mod1 = "https://localhost:5545/subdir/mod1.ts";
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.expect("failed to spawn script");
|
||||
let status = deno.wait().expect("failed to wait for the child process");
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.expect("error writing file");
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
// check the output of the test.ts program.
|
||||
assert!(std::str::from_utf8(&output.stdout)
|
||||
.unwrap()
|
||||
.trim()
|
||||
.ends_with("Hello"));
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn listen_tls_alpn() {
|
||||
// TLS streams require the presence of an ambient local task set to gracefully
|
||||
// close dropped connections in the background.
|
||||
LocalSet::new()
|
||||
.run_until(async {
|
||||
let mut child = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--unstable")
|
||||
.arg("--quiet")
|
||||
.arg("--allow-net")
|
||||
.arg("--allow-read")
|
||||
.arg("./cert/listen_tls_alpn.ts")
|
||||
.arg("4504")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdout = child.stdout.as_mut().unwrap();
|
||||
let mut msg = [0; 5];
|
||||
let read = stdout.read(&mut msg).unwrap();
|
||||
assert_eq!(read, 5);
|
||||
assert_eq!(&msg, b"READY");
|
||||
|
||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||
"./testdata/tls/RootCA.crt"
|
||||
)));
|
||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
root_store.add_parsable_certificates(&certs);
|
||||
let mut cfg = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
cfg.alpn_protocols.push(b"foobar".to_vec());
|
||||
let cfg = Arc::new(cfg);
|
||||
|
||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
||||
|
||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4504")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut tls_stream =
|
||||
TlsStream::new_client_side(tcp_stream, cfg, hostname);
|
||||
|
||||
tls_stream.handshake().await.unwrap();
|
||||
|
||||
let (_, rustls_connection) = tls_stream.get_ref();
|
||||
let alpn = rustls_connection.alpn_protocol().unwrap();
|
||||
assert_eq!(alpn, b"foobar");
|
||||
|
||||
let status = child.wait().unwrap();
|
||||
assert!(status.success());
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn listen_tls_alpn_fail() {
|
||||
// TLS streams require the presence of an ambient local task set to gracefully
|
||||
// close dropped connections in the background.
|
||||
LocalSet::new()
|
||||
.run_until(async {
|
||||
let mut child = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--unstable")
|
||||
.arg("--quiet")
|
||||
.arg("--allow-net")
|
||||
.arg("--allow-read")
|
||||
.arg("./cert/listen_tls_alpn_fail.ts")
|
||||
.arg("4505")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdout = child.stdout.as_mut().unwrap();
|
||||
let mut msg = [0; 5];
|
||||
let read = stdout.read(&mut msg).unwrap();
|
||||
assert_eq!(read, 5);
|
||||
assert_eq!(&msg, b"READY");
|
||||
|
||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||
"./testdata/tls/RootCA.crt"
|
||||
)));
|
||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
root_store.add_parsable_certificates(&certs);
|
||||
let mut cfg = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
cfg.alpn_protocols.push(b"boofar".to_vec());
|
||||
let cfg = Arc::new(cfg);
|
||||
|
||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
||||
|
||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4505")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut tls_stream =
|
||||
TlsStream::new_client_side(tcp_stream, cfg, hostname);
|
||||
|
||||
tls_stream.handshake().await.unwrap_err();
|
||||
|
||||
let (_, rustls_connection) = tls_stream.get_ref();
|
||||
assert!(rustls_connection.alpn_protocol().is_none());
|
||||
|
||||
let status = child.wait().unwrap();
|
||||
assert!(status.success());
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
212
cli/tests/check_tests.rs
Normal file
212
cli/tests/check_tests.rs
Normal file
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
use test_util as util;
|
||||
use util::TempDir;
|
||||
|
||||
mod check {
|
||||
use super::*;
|
||||
itest!(_095_check_with_bare_import {
|
||||
args: "check cache/095_cache_with_bare_import.ts",
|
||||
output: "cache/095_cache_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_extensionless {
|
||||
args: "check --reload http://localhost:4545/subdir/no_js_ext",
|
||||
output: "cache/cache_extensionless.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_random_extension {
|
||||
args: "check --reload http://localhost:4545/subdir/no_js_ext@1.0.0",
|
||||
output: "cache/cache_random_extension.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_all {
|
||||
args: "check --quiet --all check/check_all.ts",
|
||||
output: "check/check_all.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_all_local {
|
||||
args: "check --quiet check/check_all.ts",
|
||||
output_str: Some(""),
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(module_detection_force {
|
||||
args: "check --quiet check/module_detection_force/main.ts",
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/denoland/deno/issues/14937.
|
||||
itest!(declaration_header_file_with_no_exports {
|
||||
args: "check --quiet check/declaration_header_file_with_no_exports.ts",
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
itest!(check_npm_install_diagnostics {
|
||||
args: "check --quiet check/npm_install_diagnostics/main.ts",
|
||||
output: "check/npm_install_diagnostics/main.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_export_equals_declaration_file {
|
||||
args: "check --quiet check/export_equals_declaration_file/main.ts",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn cache_switching_config_then_no_config() {
|
||||
let deno_dir = util::new_deno_dir();
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(does_type_checking(&deno_dir, false));
|
||||
|
||||
// should now not do type checking even when it changes
|
||||
// configs because it previously did
|
||||
assert!(!does_type_checking(&deno_dir, true));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
|
||||
fn does_type_checking(deno_dir: &util::TempDir, with_config: bool) -> bool {
|
||||
let mut cmd = util::deno_cmd_with_deno_dir(deno_dir);
|
||||
cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("check")
|
||||
.arg("check/cache_config_on_off/main.ts");
|
||||
if with_config {
|
||||
cmd
|
||||
.arg("--config")
|
||||
.arg("check/cache_config_on_off/deno.json");
|
||||
}
|
||||
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.contains("Check")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reload_flag() {
|
||||
// should do type checking whenever someone specifies --reload
|
||||
let deno_dir = util::new_deno_dir();
|
||||
assert!(does_type_checking(&deno_dir, false));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
|
||||
fn does_type_checking(deno_dir: &util::TempDir, reload: bool) -> bool {
|
||||
let mut cmd = util::deno_cmd_with_deno_dir(deno_dir);
|
||||
cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("check")
|
||||
.arg("check/cache_config_on_off/main.ts");
|
||||
if reload {
|
||||
cmd.arg("--reload");
|
||||
}
|
||||
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.contains("Check")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_declarations_ns() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("test")
|
||||
.arg("--doc")
|
||||
.arg(util::root_path().join("cli/tsc/dts/lib.deno.ns.d.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_declarations_unstable() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("test")
|
||||
.arg("--doc")
|
||||
.arg("--unstable")
|
||||
.arg(util::root_path().join("cli/tsc/dts/lib.deno.unstable.d.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_core() {
|
||||
let deno_dir = TempDir::new();
|
||||
let test_file = deno_dir.path().join("test_deno_core_types.ts");
|
||||
std::fs::write(
|
||||
&test_file,
|
||||
format!(
|
||||
"import \"{}\";",
|
||||
deno_core::resolve_path(
|
||||
util::root_path()
|
||||
.join("core/lib.deno_core.d.ts")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap()
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.arg("run")
|
||||
.arg(test_file.to_str().unwrap())
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ts_no_recheck_on_redirect() {
|
||||
let deno_dir = util::new_deno_dir();
|
||||
let e = util::deno_exe_path();
|
||||
|
||||
let redirect_ts = util::testdata_path().join("run/017_import_redirect.ts");
|
||||
assert!(redirect_ts.is_file());
|
||||
let mut cmd = Command::new(e.clone());
|
||||
cmd.env("DENO_DIR", deno_dir.path());
|
||||
let mut initial = cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(redirect_ts.clone())
|
||||
.spawn()
|
||||
.expect("failed to span script");
|
||||
let status_initial =
|
||||
initial.wait().expect("failed to wait for child process");
|
||||
assert!(status_initial.success());
|
||||
|
||||
let mut cmd = Command::new(e);
|
||||
cmd.env("DENO_DIR", deno_dir.path());
|
||||
let output = cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(redirect_ts)
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
|
||||
assert!(std::str::from_utf8(&output.stderr).unwrap().is_empty());
|
||||
}
|
||||
}
|
536
cli/tests/compile_tests.rs
Normal file
536
cli/tests/compile_tests.rs
Normal file
|
@ -0,0 +1,536 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs::File;
|
||||
use std::process::Command;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod compile {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn compile() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
// try this twice to ensure it works with the cache
|
||||
for _ in 0..2 {
|
||||
let output = util::deno_cmd_with_deno_dir(&dir)
|
||||
.current_dir(util::root_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./test_util/std/examples/welcome.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(&exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, "Welcome to Deno!\n".as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_args() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.arg("a")
|
||||
.arg("b")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.arg("foo")
|
||||
.arg("--bar")
|
||||
.arg("--unstable")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"a\nb\nfoo\n--bar\n--unstable\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("error.exe")
|
||||
} else {
|
||||
dir.path().join("error")
|
||||
};
|
||||
let testdata_path = util::testdata_path();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(&testdata_path)
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_error.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(output.stdout, b"");
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let stderr = util::strip_ansi_codes(&stderr).to_string();
|
||||
// On Windows, we cannot assert the file path (because '\').
|
||||
// Instead we just check for relevant output.
|
||||
assert!(stderr.contains("error: Uncaught Error: boom!"));
|
||||
assert!(stderr.contains("throw new Error(\"boom!\");"));
|
||||
assert!(stderr.contains("\n at boom (file://"));
|
||||
assert!(stderr.contains("standalone_error.ts:2:11"));
|
||||
assert!(stderr.contains("at foo (file://"));
|
||||
assert!(stderr.contains("standalone_error.ts:5:5"));
|
||||
assert!(stderr.contains("standalone_error.ts:7:1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_error_module_with_imports() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("error.exe")
|
||||
} else {
|
||||
dir.path().join("error")
|
||||
};
|
||||
let testdata_path = util::testdata_path();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(&testdata_path)
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_error_module_with_imports_1.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
println!("{:#?}", &output);
|
||||
assert_eq!(output.stdout, b"hello\n");
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let stderr = util::strip_ansi_codes(&stderr).to_string();
|
||||
// On Windows, we cannot assert the file path (because '\').
|
||||
// Instead we just check for relevant output.
|
||||
assert!(stderr.contains("error: Uncaught Error: boom!"));
|
||||
assert!(stderr.contains("throw new Error(\"boom!\");"));
|
||||
assert!(stderr.contains("\n at file://"));
|
||||
assert!(stderr.contains("standalone_error_module_with_imports_2.ts:2:7"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_load_datauri() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("load_datauri.exe")
|
||||
} else {
|
||||
dir.path().join("load_datauri")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_import_datauri.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello Deno!\n");
|
||||
}
|
||||
|
||||
// https://github.com/denoland/deno/issues/13704
|
||||
#[test]
|
||||
fn standalone_follow_redirects() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("follow_redirects.exe")
|
||||
} else {
|
||||
dir.path().join("follow_redirects")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_follow_redirects.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_file_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let output_path = if cfg!(windows) {
|
||||
dir.path().join(r"args\")
|
||||
} else {
|
||||
dir.path().join("args/")
|
||||
};
|
||||
let file_path = dir.path().join("args");
|
||||
File::create(&file_path).unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&output_path)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because its parent directory ",
|
||||
"is an existing file. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name.\n",
|
||||
),
|
||||
file_path.display(),
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_directory_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
std::fs::create_dir(&exe).unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because a directory exists with ",
|
||||
"the same name. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name."
|
||||
),
|
||||
exe.display()
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_conflict_file_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
std::fs::write(&exe, b"SHOULD NOT BE OVERWRITTEN").unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because the file already exists ",
|
||||
"and cannot be overwritten. Please delete the existing file or ",
|
||||
"use the `--output <file-path` flag to provide an alternative name."
|
||||
),
|
||||
exe.display()
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
dbg!(&stderr);
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
assert!(std::fs::read(&exe)
|
||||
.unwrap()
|
||||
.eq(b"SHOULD NOT BE OVERWRITTEN"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_and_overwrite_file() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert!(&exe.exists());
|
||||
|
||||
let recompile_output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(recompile_output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_runtime_flags() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("flags.exe")
|
||||
} else {
|
||||
dir.path().join("flags")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg("--seed")
|
||||
.arg("1")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_runtime_flags.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let stdout_str = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(util::strip_ansi_codes(&stdout_str), "0.147205063401058\n");
|
||||
let stderr_str = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(util::strip_ansi_codes(&stderr_str)
|
||||
.contains("PermissionDenied: Requires write access"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_import_map() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("import_map.exe")
|
||||
} else {
|
||||
dir.path().join("import_map")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg("--import-map")
|
||||
.arg("compile/standalone_import_map.json")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_import_map.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
// https://github.com/denoland/deno/issues/12670
|
||||
fn skip_rebundle() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("hello_world.exe")
|
||||
} else {
|
||||
dir.path().join("hello_world")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./run/001_hello.js")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
//no "Bundle testdata_path/run/001_hello.js" in output
|
||||
assert!(!String::from_utf8(output.stderr).unwrap().contains("Bundle"));
|
||||
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, "Hello World\n".as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default() {
|
||||
let _guard = util::http_server();
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg(util::testdata_path().join("./compile/check_local_by_default.ts"))
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default2() {
|
||||
let _guard = util::http_server();
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg(util::testdata_path().join("./compile/check_local_by_default2.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stdout.is_empty());
|
||||
assert!(stderr.contains(
|
||||
r#"error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'."#
|
||||
));
|
||||
}
|
||||
}
|
382
cli/tests/coverage_tests.rs
Normal file
382
cli/tests/coverage_tests.rs
Normal file
|
@ -0,0 +1,382 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod coverage {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn branch() {
|
||||
run_coverage_text("branch", "ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex() {
|
||||
run_coverage_text("complex", "ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_blankline() {
|
||||
run_coverage_text("final_blankline", "js");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_snaps() {
|
||||
no_snaps_included("no_snaps_included", "ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_if_invalid_cache() {
|
||||
let deno_dir = TempDir::new();
|
||||
let deno_dir_path = deno_dir.path();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let invalid_cache_path =
|
||||
util::testdata_path().join("coverage/invalid_cache");
|
||||
let mod_before_path = util::testdata_path()
|
||||
.join(&invalid_cache_path)
|
||||
.join("mod_before.ts");
|
||||
let mod_after_path = util::testdata_path()
|
||||
.join(&invalid_cache_path)
|
||||
.join("mod_after.ts");
|
||||
let mod_test_path = util::testdata_path()
|
||||
.join(&invalid_cache_path)
|
||||
.join("mod.test.ts");
|
||||
|
||||
let mod_temp_path = deno_dir_path.join("mod.ts");
|
||||
let mod_test_temp_path = deno_dir_path.join("mod.test.ts");
|
||||
|
||||
// Write the inital mod.ts file
|
||||
std::fs::copy(mod_before_path, &mod_temp_path).unwrap();
|
||||
// And the test file
|
||||
std::fs::copy(mod_test_path, &mod_test_temp_path).unwrap();
|
||||
|
||||
// Generate coverage
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(deno_dir_path)
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
// Modify the file between deno test and deno coverage, thus invalidating the cache
|
||||
std::fs::copy(mod_after_path, mod_temp_path).unwrap();
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(deno_dir_path)
|
||||
.arg("coverage")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
assert!(output.stdout.is_empty());
|
||||
|
||||
// Expect error
|
||||
let error =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stderr).unwrap())
|
||||
.to_string();
|
||||
assert!(error.contains("error: Missing transpiled source code"));
|
||||
assert!(error.contains("Before generating coverage report, run `deno test --coverage` to ensure consistent state."));
|
||||
}
|
||||
|
||||
fn run_coverage_text(test_name: &str, extension: &str) {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("-A")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg(format!("coverage/{}_test.{}", test_name, extension))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path()
|
||||
.join(format!("coverage/{}_expected.out", test_name)),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--lcov")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path()
|
||||
.join(format!("coverage/{}_expected.lcov", test_name)),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multifile_coverage() {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg("coverage/multifile/")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/multifile/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--lcov")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/multifile/expected.lcov"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
fn no_snaps_included(test_name: &str, extension: &str) {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg(format!(
|
||||
"coverage/no_snaps_included/{}_test.{}",
|
||||
test_name, extension
|
||||
))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg("--include=no_snaps_included.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_snaps_included/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_transpiled_lines() {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg("coverage/no_transpiled_lines/")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--include=no_transpiled_lines/index.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_transpiled_lines/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--lcov")
|
||||
.arg("--include=no_transpiled_lines/index.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_transpiled_lines/expected.lcov"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
}
|
79
cli/tests/doc_tests.rs
Normal file
79
cli/tests/doc_tests.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use util::assert_contains;
|
||||
|
||||
mod doc {
|
||||
use super::*;
|
||||
|
||||
itest!(deno_doc_builtin {
|
||||
args: "doc",
|
||||
output: "doc/deno_doc_builtin.out",
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn deno_doc() {
|
||||
let dir = TempDir::new();
|
||||
// try this twice to ensure it works with the cache
|
||||
for _ in 0..2 {
|
||||
let output = util::deno_cmd_with_deno_dir(&dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("doc")
|
||||
.arg("doc/deno_doc.ts")
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_contains!(
|
||||
std::str::from_utf8(&output.stdout).unwrap(),
|
||||
"function foo"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
itest!(deno_doc_import_map {
|
||||
args:
|
||||
"doc --unstable --import-map=doc/import_map.json doc/use_import_map.js",
|
||||
output: "doc/use_import_map.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_hint {
|
||||
args: "doc doc/types_hint.ts",
|
||||
output: "doc/types_hint.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_ref {
|
||||
args: "doc doc/types_ref.js",
|
||||
output: "doc/types_ref.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_header {
|
||||
args: "doc --reload doc/types_header.ts",
|
||||
output: "doc/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(_060_deno_doc_displays_all_overloads_in_details_view {
|
||||
args:
|
||||
"doc doc/060_deno_doc_displays_all_overloads_in_details_view.ts NS.test",
|
||||
output: "doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_header_direct {
|
||||
args: "doc --reload http://127.0.0.1:4545/xTypeScriptTypes.js",
|
||||
output: "doc/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(deno_doc_invalid_url {
|
||||
args: "doc https://raw.githubusercontent.com%2Fdyedgreen%2Fdeno-sqlite%2Frework_api%2Fmod.ts",
|
||||
output: "doc/invalid_url.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
}
|
86
cli/tests/eval_tests.rs
Normal file
86
cli/tests/eval_tests.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
|
||||
mod eval {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn eval_p() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("eval")
|
||||
.arg("-p")
|
||||
.arg("1+2")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout_str = util::strip_ansi_codes(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
);
|
||||
assert_eq!("3", stdout_str);
|
||||
}
|
||||
|
||||
// Make sure that snapshot flags don't affect runtime.
|
||||
#[test]
|
||||
fn eval_randomness() {
|
||||
let mut numbers = Vec::with_capacity(10);
|
||||
for _ in 0..10 {
|
||||
let output = util::deno_cmd()
|
||||
.arg("eval")
|
||||
.arg("-p")
|
||||
.arg("Math.random()")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout_str = util::strip_ansi_codes(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
);
|
||||
numbers.push(stdout_str.to_string());
|
||||
}
|
||||
numbers.dedup();
|
||||
assert!(numbers.len() > 1);
|
||||
}
|
||||
|
||||
itest!(eval_basic {
|
||||
args: "eval console.log(\"hello\")",
|
||||
output_str: Some("hello\n"),
|
||||
});
|
||||
|
||||
// Ugly parentheses due to whitespace delimiting problem.
|
||||
itest!(eval_ts {
|
||||
args: "eval --quiet --ext=ts console.log((123)as(number))", // 'as' is a TS keyword only
|
||||
output_str: Some("123\n"),
|
||||
});
|
||||
|
||||
itest!(dyn_import_eval {
|
||||
args: "eval import('./subdir/mod4.js').then(console.log)",
|
||||
output: "eval/dyn_import_eval.out",
|
||||
});
|
||||
|
||||
// Cannot write the expression to evaluate as "console.log(typeof gc)"
|
||||
// because itest! splits args on whitespace.
|
||||
itest!(v8_flags_eval {
|
||||
args: "eval --v8-flags=--expose-gc console.log(typeof(gc))",
|
||||
output: "run/v8_flags.js.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "eval --quiet import('http://localhost:4545/subdir/type_error.ts').then(console.log);",
|
||||
output: "eval/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "eval --quiet import('./eval/check_local_by_default2.ts').then(console.log);",
|
||||
output: "eval/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
});
|
||||
}
|
50
cli/tests/flags_tests.rs
Normal file
50
cli/tests/flags_tests.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
|
||||
mod flags {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn help_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("--help")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_short_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("-V")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_long_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("--version")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
itest!(types {
|
||||
args: "types",
|
||||
output: "types/types.out",
|
||||
});
|
||||
}
|
257
cli/tests/fmt_tests.rs
Normal file
257
cli/tests/fmt_tests.rs
Normal file
|
@ -0,0 +1,257 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod fmt {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fmt_test() {
|
||||
let t = TempDir::new();
|
||||
let testdata_fmt_dir = util::testdata_path().join("fmt");
|
||||
let fixed_js = testdata_fmt_dir.join("badly_formatted_fixed.js");
|
||||
let badly_formatted_original_js =
|
||||
testdata_fmt_dir.join("badly_formatted.mjs");
|
||||
let badly_formatted_js = t.path().join("badly_formatted.js");
|
||||
let badly_formatted_js_str = badly_formatted_js.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_js, &badly_formatted_js).unwrap();
|
||||
|
||||
let fixed_md = testdata_fmt_dir.join("badly_formatted_fixed.md");
|
||||
let badly_formatted_original_md =
|
||||
testdata_fmt_dir.join("badly_formatted.md");
|
||||
let badly_formatted_md = t.path().join("badly_formatted.md");
|
||||
let badly_formatted_md_str = badly_formatted_md.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_md, &badly_formatted_md).unwrap();
|
||||
|
||||
let fixed_json = testdata_fmt_dir.join("badly_formatted_fixed.json");
|
||||
let badly_formatted_original_json =
|
||||
testdata_fmt_dir.join("badly_formatted.json");
|
||||
let badly_formatted_json = t.path().join("badly_formatted.json");
|
||||
let badly_formatted_json_str = badly_formatted_json.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_json, &badly_formatted_json)
|
||||
.unwrap();
|
||||
// First, check formatting by ignoring the badly formatted file.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg(format!(
|
||||
"--ignore={},{},{}",
|
||||
badly_formatted_js_str,
|
||||
badly_formatted_md_str,
|
||||
badly_formatted_json_str
|
||||
))
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
// No target files found
|
||||
assert!(!status.success());
|
||||
|
||||
// Check without ignore.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(!status.success());
|
||||
|
||||
// Format the source file.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let expected_js = std::fs::read_to_string(fixed_js).unwrap();
|
||||
let expected_md = std::fs::read_to_string(fixed_md).unwrap();
|
||||
let expected_json = std::fs::read_to_string(fixed_json).unwrap();
|
||||
let actual_js = std::fs::read_to_string(badly_formatted_js).unwrap();
|
||||
let actual_md = std::fs::read_to_string(badly_formatted_md).unwrap();
|
||||
let actual_json = std::fs::read_to_string(badly_formatted_json).unwrap();
|
||||
assert_eq!(expected_js, actual_js);
|
||||
assert_eq!(expected_md, actual_md);
|
||||
assert_eq!(expected_json, actual_json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_stdin_error() {
|
||||
use std::io::Write;
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("fmt")
|
||||
.arg("-")
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdin = deno.stdin.as_mut().unwrap();
|
||||
let invalid_js = b"import { example }";
|
||||
stdin.write_all(invalid_js).unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
// Error message might change. Just check stdout empty, stderr not.
|
||||
assert!(output.stdout.is_empty());
|
||||
assert!(!output.stderr.is_empty());
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_ignore_unexplicit_files() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("fmt")
|
||||
.arg("--check")
|
||||
.arg("--ignore=./")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
"error: No target files found.\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_auto_ignore_git_and_node_modules() {
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
fn create_bad_json(t: PathBuf) {
|
||||
let bad_json_path = t.join("bad.json");
|
||||
let mut bad_json_file = File::create(bad_json_path).unwrap();
|
||||
writeln!(bad_json_file, "bad json").unwrap();
|
||||
}
|
||||
let temp_dir = TempDir::new();
|
||||
let t = temp_dir.path().join("target");
|
||||
let nest_git = t.join("nest").join(".git");
|
||||
let git_dir = t.join(".git");
|
||||
let nest_node_modules = t.join("nest").join("node_modules");
|
||||
let node_modules_dir = t.join("node_modules");
|
||||
create_dir_all(&nest_git).unwrap();
|
||||
create_dir_all(&git_dir).unwrap();
|
||||
create_dir_all(&nest_node_modules).unwrap();
|
||||
create_dir_all(&node_modules_dir).unwrap();
|
||||
create_bad_json(nest_git);
|
||||
create_bad_json(git_dir);
|
||||
create_bad_json(nest_node_modules);
|
||||
create_bad_json(node_modules_dir);
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(t)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("fmt")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
"error: No target files found.\n"
|
||||
);
|
||||
}
|
||||
|
||||
itest!(fmt_quiet_check_fmt_dir {
|
||||
args: "fmt --check --quiet fmt/regular/",
|
||||
output_str: Some(""),
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_formatted_files {
|
||||
args: "fmt --check fmt/regular/formatted1.js fmt/regular/formatted2.ts fmt/regular/formatted3.markdown fmt/regular/formatted4.jsonc",
|
||||
output: "fmt/expected_fmt_check_formatted_files.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_ignore {
|
||||
args: "fmt --check --ignore=fmt/regular/formatted1.js fmt/regular/",
|
||||
output: "fmt/expected_fmt_check_ignore.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_parse_error {
|
||||
args: "fmt --check fmt/parse_error/parse_error.ts",
|
||||
output: "fmt/fmt_check_parse_error.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(fmt_stdin {
|
||||
args: "fmt -",
|
||||
input: Some("const a = 1\n"),
|
||||
output_str: Some("const a = 1;\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_markdown {
|
||||
args: "fmt --ext=md -",
|
||||
input: Some("# Hello Markdown\n```ts\nconsole.log( \"text\")\n```\n\n```cts\nconsole.log( 5 )\n```"),
|
||||
output_str: Some("# Hello Markdown\n\n```ts\nconsole.log(\"text\");\n```\n\n```cts\nconsole.log(5);\n```\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_json {
|
||||
args: "fmt --ext=json -",
|
||||
input: Some("{ \"key\": \"value\"}"),
|
||||
output_str: Some("{ \"key\": \"value\" }\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_check_formatted {
|
||||
args: "fmt --check -",
|
||||
input: Some("const a = 1;\n"),
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_check_not_formatted {
|
||||
args: "fmt --check -",
|
||||
input: Some("const a = 1\n"),
|
||||
output_str: Some("Not formatted stdin\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_with_config {
|
||||
args: "fmt --config fmt/with_config/deno.jsonc fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
itest!(fmt_with_config_default {
|
||||
args: "fmt fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
// Check if CLI flags take precedence
|
||||
itest!(fmt_with_config_and_flags {
|
||||
args: "fmt --config fmt/with_config/deno.jsonc --ignore=fmt/with_config/subdir/a.ts,fmt/with_config/subdir/b.ts",
|
||||
output: "fmt/fmt_with_config_and_flags.out",
|
||||
});
|
||||
|
||||
itest!(fmt_with_malformed_config {
|
||||
args: "fmt --config fmt/deno.malformed.jsonc",
|
||||
output: "fmt/fmt_with_malformed_config.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(fmt_with_malformed_config2 {
|
||||
args: "fmt --config fmt/deno.malformed2.jsonc",
|
||||
output: "fmt/fmt_with_malformed_config2.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
}
|
136
cli/tests/info_tests.rs
Normal file
136
cli/tests/info_tests.rs
Normal file
|
@ -0,0 +1,136 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
mod integration;
|
||||
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod init {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn info_with_compiled_source() {
|
||||
let _g = util::http_server();
|
||||
let module_path = "http://127.0.0.1:4545/run/048_media_types_jsx.ts";
|
||||
let t = TempDir::new();
|
||||
|
||||
let mut deno = util::deno_cmd()
|
||||
.env("DENO_DIR", t.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg(module_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.env("DENO_DIR", t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("info")
|
||||
.arg(module_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let str_output = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
eprintln!("{}", str_output);
|
||||
// check the output of the test.ts program.
|
||||
assert!(str_output.contains("emit: "));
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
itest!(multiple_imports {
|
||||
args: "info http://127.0.0.1:4545/run/019_media_types.ts",
|
||||
output: "info/multiple_imports.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(info_ts_error {
|
||||
args: "info info/031_info_ts_error.ts",
|
||||
output: "info/031_info_ts_error.out",
|
||||
});
|
||||
|
||||
itest!(info_flag {
|
||||
args: "info",
|
||||
output: "info/041_info_flag.out",
|
||||
});
|
||||
|
||||
itest!(info_flag_location {
|
||||
args: "info --location https://deno.land",
|
||||
output: "info/041_info_flag_location.out",
|
||||
});
|
||||
|
||||
itest!(info_json {
|
||||
args: "info --json --unstable",
|
||||
output: "info/info_json.out",
|
||||
});
|
||||
|
||||
itest!(info_json_location {
|
||||
args: "info --json --unstable --location https://deno.land",
|
||||
output: "info/info_json_location.out",
|
||||
});
|
||||
|
||||
itest!(info_flag_script_jsx {
|
||||
args: "info http://127.0.0.1:4545/run/048_media_types_jsx.ts",
|
||||
output: "info/049_info_flag_script_jsx.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(json_file {
|
||||
args: "info --quiet --json --unstable info/json_output/main.ts",
|
||||
output: "info/json_output/main.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(import_map_info {
|
||||
args:
|
||||
"info --quiet --import-map=import_maps/import_map.json import_maps/test.ts",
|
||||
output: "info/065_import_map_info.out",
|
||||
});
|
||||
|
||||
itest!(info_json_deps_order {
|
||||
args: "info --unstable --json info/076_info_json_deps_order.ts",
|
||||
output: "info/076_info_json_deps_order.out",
|
||||
});
|
||||
|
||||
itest!(info_missing_module {
|
||||
args: "info info/error_009_missing_js_module.js",
|
||||
output: "info/info_missing_module.out",
|
||||
});
|
||||
|
||||
itest!(info_recursive_modules {
|
||||
args: "info --quiet info/info_recursive_imports_test.ts",
|
||||
output: "info/info_recursive_imports_test.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(info_type_import {
|
||||
args: "info info/info_type_import.ts",
|
||||
output: "info/info_type_import.out",
|
||||
});
|
||||
|
||||
itest!(_054_info_local_imports {
|
||||
args: "info --quiet run/005_more_imports.ts",
|
||||
output: "info/054_info_local_imports.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
// Tests for AssertionError where "data" is unexpectedly null when
|
||||
// a file contains only triple slash references (#11196)
|
||||
itest!(data_null_error {
|
||||
args: "info info/data_null_error/mod.ts",
|
||||
output: "info/data_null_error/data_null_error.out",
|
||||
});
|
||||
|
||||
itest!(types_header_direct {
|
||||
args: "info --reload run/type_directives_01.ts",
|
||||
output: "info/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(with_config_override {
|
||||
args: "info info/with_config/test.ts --config info/with_config/deno-override.json --import-map info/with_config/import_map.json",
|
||||
output: "info/with_config/with_config.out",
|
||||
});
|
||||
}
|
163
cli/tests/init_tests.rs
Normal file
163
cli/tests/init_tests.rs
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::process::Stdio;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use util::assert_contains;
|
||||
|
||||
mod init {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_without_dir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert_contains!(stderr, "Project initialized");
|
||||
assert!(!stderr.contains("cd"));
|
||||
assert_contains!(stderr, "deno run main.ts");
|
||||
assert_contains!(stderr, "deno test");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_with_dir_arg() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.arg("my_dir")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert_contains!(stderr, "Project initialized");
|
||||
assert_contains!(stderr, "cd my_dir");
|
||||
assert_contains!(stderr, "deno run main.ts");
|
||||
assert_contains!(stderr, "deno test");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("my_dir/main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.arg("my_dir/main_test.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_with_quiet_arg() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.arg("--quiet")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(stdout, "");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
||||
}
|
1323
cli/tests/inspector_tests.rs
Normal file
1323
cli/tests/inspector_tests.rs
Normal file
File diff suppressed because it is too large
Load diff
220
cli/tests/install_tests.rs
Normal file
220
cli/tests/install_tests.rs
Normal file
|
@ -0,0 +1,220 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use test_util as util;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_ends_with;
|
||||
use test_util::TempDir;
|
||||
|
||||
mod install {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn install_basic() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg("--check")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let mut file_path = temp_dir.path().join(".deno/bin/echo_test");
|
||||
assert!(file_path.exists());
|
||||
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
// ensure there's a trailing newline so the shell script can be
|
||||
// more versatile.
|
||||
assert_eq!(content.chars().last().unwrap(), '\n');
|
||||
|
||||
if cfg!(windows) {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#""run" "--check" "http://localhost:4545/echo.ts""#
|
||||
);
|
||||
} else {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#"run --check 'http://localhost:4545/echo.ts'"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_custom_dir_env_var() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path()) // different cwd
|
||||
.arg("install")
|
||||
.arg("--check")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", temp_dir_str.as_str()),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let mut file_path = temp_dir.path().join("bin/echo_test");
|
||||
assert!(file_path.exists());
|
||||
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
if cfg!(windows) {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#""run" "--check" "http://localhost:4545/echo.ts""#
|
||||
);
|
||||
} else {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#"run --check 'http://localhost:4545/echo.ts'"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn installer_test_local_module_run() {
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("install")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg(util::testdata_path().join("echo.ts"))
|
||||
.arg("hello")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let mut file_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
assert!(file_path.exists());
|
||||
// NOTE: using file_path here instead of exec_name, because tests
|
||||
// shouldn't mess with user's PATH env variable
|
||||
let output = Command::new(file_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.unwrap();
|
||||
let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
assert_ends_with!(stdout_str, "hello, foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn installer_test_remote_module_run() {
|
||||
let _g = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("install")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.arg("hello")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let mut file_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
assert!(file_path.exists());
|
||||
let output = Command::new(file_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"hello, foo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg(util::testdata_path().join("./install/check_local_by_default.ts"))
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default2() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg(util::testdata_path().join("./install/check_local_by_default2.ts"))
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("NO_COLOR", "1"),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
}
|
|
@ -1,195 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use deno_core::url::Url;
|
||||
use test_util as util;
|
||||
|
||||
itest!(overloads {
|
||||
args: "bench bench/overloads.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/overloads.out",
|
||||
});
|
||||
|
||||
itest!(meta {
|
||||
args: "bench bench/meta.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/meta.out",
|
||||
});
|
||||
|
||||
itest!(pass {
|
||||
args: "bench bench/pass.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/pass.out",
|
||||
});
|
||||
|
||||
itest!(ignore {
|
||||
args: "bench bench/ignore.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/ignore.out",
|
||||
});
|
||||
|
||||
itest!(ignore_permissions {
|
||||
args: "bench bench/ignore_permissions.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/ignore_permissions.out",
|
||||
});
|
||||
|
||||
itest!(fail {
|
||||
args: "bench bench/fail.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/fail.out",
|
||||
});
|
||||
|
||||
itest!(collect {
|
||||
args: "bench --ignore=bench/collect/ignore bench/collect",
|
||||
exit_code: 0,
|
||||
output: "bench/collect.out",
|
||||
});
|
||||
|
||||
itest!(load_unload {
|
||||
args: "bench bench/load_unload.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/load_unload.out",
|
||||
});
|
||||
|
||||
itest!(interval {
|
||||
args: "bench bench/interval.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/interval.out",
|
||||
});
|
||||
|
||||
itest!(quiet {
|
||||
args: "bench --quiet bench/quiet.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/quiet.out",
|
||||
});
|
||||
|
||||
itest!(only {
|
||||
args: "bench bench/only.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/only.out",
|
||||
});
|
||||
|
||||
itest!(multifile_summary {
|
||||
args: "bench bench/group_baseline.ts bench/pass.ts bench/group_baseline.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/multifile_summary.out",
|
||||
});
|
||||
|
||||
itest!(no_check {
|
||||
args: "bench --no-check bench/no_check.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_check.out",
|
||||
});
|
||||
|
||||
itest!(allow_all {
|
||||
args: "bench --allow-all bench/allow_all.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/allow_all.out",
|
||||
});
|
||||
|
||||
itest!(allow_none {
|
||||
args: "bench bench/allow_none.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/allow_none.out",
|
||||
});
|
||||
|
||||
itest!(exit_sanitizer {
|
||||
args: "bench bench/exit_sanitizer.ts",
|
||||
output: "bench/exit_sanitizer.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(clear_timeout {
|
||||
args: "bench bench/clear_timeout.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/clear_timeout.out",
|
||||
});
|
||||
|
||||
itest!(finally_timeout {
|
||||
args: "bench bench/finally_timeout.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/finally_timeout.out",
|
||||
});
|
||||
|
||||
itest!(group_baseline {
|
||||
args: "bench bench/group_baseline.ts",
|
||||
exit_code: 0,
|
||||
output: "bench/group_baseline.out",
|
||||
});
|
||||
|
||||
itest!(unresolved_promise {
|
||||
args: "bench bench/unresolved_promise.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/unresolved_promise.out",
|
||||
});
|
||||
|
||||
itest!(unhandled_rejection {
|
||||
args: "bench bench/unhandled_rejection.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/unhandled_rejection.out",
|
||||
});
|
||||
|
||||
itest!(filter {
|
||||
args: "bench --filter=foo bench/filter",
|
||||
exit_code: 0,
|
||||
output: "bench/filter.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_by_default {
|
||||
args: "bench --quiet bench/no_prompt_by_default.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_prompt_by_default.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_with_denied_perms {
|
||||
args: "bench --quiet --allow-read bench/no_prompt_with_denied_perms.ts",
|
||||
exit_code: 1,
|
||||
output: "bench/no_prompt_with_denied_perms.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "bench --quiet bench/check_local_by_default.ts",
|
||||
output: "bench/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "bench --quiet bench/check_local_by_default2.ts",
|
||||
output: "bench/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn recursive_permissions_pledge() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bench")
|
||||
.arg("bench/recursive_permissions_pledge.js")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert!(String::from_utf8(output.stderr).unwrap().contains(
|
||||
"pledge test permissions called before restoring previous pledge"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_protocol() {
|
||||
let file_url =
|
||||
Url::from_file_path(util::testdata_path().join("bench/file_protocol.ts"))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
(util::CheckOutputIntegrationTest {
|
||||
args_vec: vec!["bench", &file_url],
|
||||
exit_code: 0,
|
||||
output: "bench/file_protocol.out",
|
||||
..Default::default()
|
||||
})
|
||||
.run();
|
||||
}
|
|
@ -1,468 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use test_util as util;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_ends_with;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn bundle_exports() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod1 = util::testdata_path().join("subdir/mod1.ts");
|
||||
assert!(mod1.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_exports_no_check() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod1 = util::testdata_path().join("subdir/mod1.ts");
|
||||
assert!(mod1.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_circular() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let circular1_path = util::testdata_path().join("subdir/circular1.ts");
|
||||
assert!(circular1_path.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle_path = t.path().join("circular1.bundle.js");
|
||||
|
||||
// run this twice to ensure it works even when cached
|
||||
for _ in 0..2 {
|
||||
let mut deno = util::deno_cmd_with_deno_dir(&t)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(&circular1_path)
|
||||
.arg(&bundle_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle_path.is_file());
|
||||
}
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&t)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the the bundle program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"f2\nf1",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_single_module() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let single_module = util::testdata_path().join("subdir/single_module.ts");
|
||||
assert!(single_module.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("single_module.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(single_module)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the the bundle program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello world!",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_tla() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let tla_import = util::testdata_path().join("subdir/tla.ts");
|
||||
assert!(tla_import.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("tla.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(tla_import)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { foo } from \"./tla.bundle.js\";
|
||||
console.log(foo); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_js() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod6 = util::testdata_path().join("subdir/mod6.js");
|
||||
assert!(mod6.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod6.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod6)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_dynamic_import() {
|
||||
let _g = util::http_server();
|
||||
let dynamic_import = util::testdata_path().join("bundle/dynamic_import.ts");
|
||||
assert!(dynamic_import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("bundle_dynamic_import.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(dynamic_import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--allow-net")
|
||||
.arg("--quiet")
|
||||
.arg(&output_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_import_map() {
|
||||
let import = util::testdata_path().join("bundle/import_map/main.ts");
|
||||
let import_map_path =
|
||||
util::testdata_path().join("bundle/import_map/import_map.json");
|
||||
assert!(import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("import_map.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--import-map")
|
||||
.arg(import_map_path)
|
||||
.arg(import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./import_map.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_import_map_no_check() {
|
||||
let import = util::testdata_path().join("bundle/import_map/main.ts");
|
||||
let import_map_path =
|
||||
util::testdata_path().join("bundle/import_map/import_map.json");
|
||||
assert!(import.is_file());
|
||||
let t = TempDir::new();
|
||||
let output_path = t.path().join("import_map.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--import-map")
|
||||
.arg(import_map_path)
|
||||
.arg(import)
|
||||
.arg(&output_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(output_path.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./import_map.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check the output of the test.ts program.
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"Hello",
|
||||
);
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_json_module() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod7 = util::testdata_path().join("subdir/mod7.js");
|
||||
assert!(mod7.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod7.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod7)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
// ensure the output looks right
|
||||
assert_contains!(String::from_utf8(output.stdout).unwrap(), "with space",);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundle_json_module_escape_sub() {
|
||||
// First we have to generate a bundle of some module that has exports.
|
||||
let mod8 = util::testdata_path().join("subdir/mod8.js");
|
||||
assert!(mod8.is_file());
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod8.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg(mod8)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg(&bundle)
|
||||
.output()
|
||||
.unwrap();
|
||||
// check that nothing went to stderr
|
||||
assert_eq!(output.stderr, b"");
|
||||
// make sure the output looks right and the escapes were effective
|
||||
assert_contains!(
|
||||
String::from_utf8(output.stdout).unwrap(),
|
||||
"${globalThis}`and string literal`",
|
||||
);
|
||||
}
|
||||
|
||||
itest!(lockfile_check_error {
|
||||
args: "bundle --lock=bundle/lockfile/check_error.json http://127.0.0.1:4545/subdir/mod1.ts",
|
||||
output: "bundle/lockfile/check_error.out",
|
||||
exit_code: 10,
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(bundle {
|
||||
args: "bundle subdir/mod1.ts",
|
||||
output: "bundle/bundle.test.out",
|
||||
});
|
||||
|
||||
itest!(bundle_jsx {
|
||||
args: "bundle run/jsx_import_from_ts.ts",
|
||||
output: "bundle/jsx.out",
|
||||
});
|
||||
|
||||
itest!(error_bundle_with_bare_import {
|
||||
args: "bundle bundle/bare_imports/error_with_bare_import.ts",
|
||||
output: "bundle/bare_imports/error_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(ts_decorators_bundle {
|
||||
args: "bundle bundle/decorators/ts_decorators.ts",
|
||||
output: "bundle/decorators/ts_decorators.out",
|
||||
});
|
||||
|
||||
itest!(bundle_export_specifier_with_alias {
|
||||
args: "bundle bundle/file_tests-fixture16.ts",
|
||||
output: "bundle/fixture16.out",
|
||||
});
|
||||
|
||||
itest!(bundle_ignore_directives {
|
||||
args: "bundle subdir/mod1.ts",
|
||||
output: "bundle/ignore_directives.test.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default_no_errors {
|
||||
args: "bundle --quiet bundle/check_local_by_default/no_errors.ts",
|
||||
output: "bundle/check_local_by_default/no_errors.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default_type_error {
|
||||
args: "bundle --quiet bundle/check_local_by_default/type_error.ts",
|
||||
output: "bundle/check_local_by_default/type_error.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
|
@ -1,99 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
|
||||
itest!(_036_import_map_fetch {
|
||||
args:
|
||||
"cache --quiet --reload --import-map=import_maps/import_map.json import_maps/test.ts",
|
||||
output: "cache/036_import_map_fetch.out",
|
||||
});
|
||||
|
||||
itest!(_037_fetch_multiple {
|
||||
args: "cache --reload --check=all run/fetch/test.ts run/fetch/other.ts",
|
||||
http_server: true,
|
||||
output: "cache/037_fetch_multiple.out",
|
||||
});
|
||||
|
||||
itest!(_095_cache_with_bare_import {
|
||||
args: "cache cache/095_cache_with_bare_import.ts",
|
||||
output: "cache/095_cache_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(cache_extensionless {
|
||||
args: "cache --reload --check=all http://localhost:4545/subdir/no_js_ext",
|
||||
output: "cache/cache_extensionless.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(cache_random_extension {
|
||||
args:
|
||||
"cache --reload --check=all http://localhost:4545/subdir/no_js_ext@1.0.0",
|
||||
output: "cache/cache_random_extension.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(performance_stats {
|
||||
args: "cache --reload --check=all --log-level debug run/002_hello.ts",
|
||||
output: "cache/performance_stats.out",
|
||||
});
|
||||
|
||||
itest!(redirect_cache {
|
||||
http_server: true,
|
||||
args:
|
||||
"cache --reload --check=all http://localhost:4548/subdir/redirects/a.ts",
|
||||
output: "cache/redirect_cache.out",
|
||||
});
|
||||
|
||||
itest!(ignore_require {
|
||||
args: "cache --reload --no-check cache/ignore_require.js",
|
||||
output_str: Some(""),
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
// This test only runs on linux, because it hardcodes the XDG_CACHE_HOME env var
|
||||
// which is only used on linux.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn relative_home_dir() {
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
let deno_dir = TempDir::new_in(&util::testdata_path());
|
||||
let path = deno_dir.path().strip_prefix(util::testdata_path()).unwrap();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd();
|
||||
let output = deno_cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.env("XDG_CACHE_HOME", path)
|
||||
.env_remove("HOME")
|
||||
.env_remove("DENO_DIR")
|
||||
.arg("cache")
|
||||
.arg("--reload")
|
||||
.arg("--no-check")
|
||||
.arg("run/002_hello.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"");
|
||||
}
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "cache --quiet cache/check_local_by_default.ts",
|
||||
output: "cache/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "cache --quiet cache/check_local_by_default2.ts",
|
||||
output: "cache/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(json_import {
|
||||
// should not error
|
||||
args: "cache --quiet cache/json_import/main.ts",
|
||||
});
|
|
@ -1,316 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use deno_runtime::deno_net::ops_tls::TlsStream;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use std::io::BufReader;
|
||||
use std::io::Cursor;
|
||||
use std::io::Read;
|
||||
use std::process::Command;
|
||||
use std::sync::Arc;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use tokio::task::LocalSet;
|
||||
|
||||
itest_flaky!(cafile_url_imports {
|
||||
args: "run --quiet --reload --cert tls/RootCA.pem cert/cafile_url_imports.ts",
|
||||
output: "cert/cafile_url_imports.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_ts_fetch {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --cert tls/RootCA.pem cert/cafile_ts_fetch.ts",
|
||||
output: "cert/cafile_ts_fetch.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_eval {
|
||||
args: "eval --cert tls/RootCA.pem fetch('https://localhost:5545/cert/cafile_ts_fetch.ts.out').then(r=>r.text()).then(t=>console.log(t.trimEnd()))",
|
||||
output: "cert/cafile_ts_fetch.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_info {
|
||||
args:
|
||||
"info --quiet --cert tls/RootCA.pem https://localhost:5545/cert/cafile_info.ts",
|
||||
output: "cert/cafile_info.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_url_imports_unsafe_ssl {
|
||||
args: "run --quiet --reload --unsafely-ignore-certificate-errors=localhost cert/cafile_url_imports.ts",
|
||||
output: "cert/cafile_url_imports_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest_flaky!(cafile_ts_fetch_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors cert/cafile_ts_fetch.ts",
|
||||
output: "cert/cafile_ts_fetch_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(deno_land_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/deno_land_unsafe_ssl.ts",
|
||||
output: "cert/deno_land_unsafe_ssl.ts.out",
|
||||
});
|
||||
|
||||
itest!(ip_address_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=1.1.1.1 cert/ip_address_unsafe_ssl.ts",
|
||||
output: "cert/ip_address_unsafe_ssl.ts.out",
|
||||
});
|
||||
|
||||
itest!(localhost_unsafe_ssl {
|
||||
args:
|
||||
"run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/cafile_url_imports.ts",
|
||||
output: "cert/localhost_unsafe_ssl.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_env_fetch() {
|
||||
use deno_core::url::Url;
|
||||
let _g = util::http_server();
|
||||
let deno_dir = TempDir::new();
|
||||
let module_url =
|
||||
Url::parse("https://localhost:5545/cert/cafile_url_imports.ts").unwrap();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.env("DENO_CERT", cafile)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg(module_url.to_string())
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_fetch() {
|
||||
use deno_core::url::Url;
|
||||
let _g = util::http_server();
|
||||
let deno_dir = TempDir::new();
|
||||
let module_url =
|
||||
Url::parse("http://localhost:4545/cert/cafile_url_imports.ts").unwrap();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg(module_url.to_string())
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
assert!(output.status.success());
|
||||
let out = std::str::from_utf8(&output.stdout).unwrap();
|
||||
assert_eq!(out, "");
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_install_remote_module() {
|
||||
let _g = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let deno_dir = TempDir::new();
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
|
||||
let install_output = Command::new(util::deno_exe_path())
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("install")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg("-n")
|
||||
.arg("echo_test")
|
||||
.arg("https://localhost:5545/echo.ts")
|
||||
.output()
|
||||
.expect("Failed to spawn script");
|
||||
println!("{}", std::str::from_utf8(&install_output.stdout).unwrap());
|
||||
eprintln!("{}", std::str::from_utf8(&install_output.stderr).unwrap());
|
||||
assert!(install_output.status.success());
|
||||
|
||||
let mut echo_test_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
echo_test_path = echo_test_path.with_extension("cmd");
|
||||
}
|
||||
assert!(echo_test_path.exists());
|
||||
|
||||
let output = Command::new(echo_test_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
assert!(stdout.ends_with("foo"));
|
||||
}
|
||||
|
||||
#[flaky_test::flaky_test]
|
||||
fn cafile_bundle_remote_exports() {
|
||||
let _g = util::http_server();
|
||||
|
||||
// First we have to generate a bundle of some remote module that has exports.
|
||||
let mod1 = "https://localhost:5545/subdir/mod1.ts";
|
||||
let cafile = util::testdata_path().join("tls/RootCA.pem");
|
||||
let t = TempDir::new();
|
||||
let bundle = t.path().join("mod1.bundle.js");
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("bundle")
|
||||
.arg("--cert")
|
||||
.arg(cafile)
|
||||
.arg(mod1)
|
||||
.arg(&bundle)
|
||||
.spawn()
|
||||
.expect("failed to spawn script");
|
||||
let status = deno.wait().expect("failed to wait for the child process");
|
||||
assert!(status.success());
|
||||
assert!(bundle.is_file());
|
||||
|
||||
// Now we try to use that bundle from another module.
|
||||
let test = t.path().join("test.js");
|
||||
std::fs::write(
|
||||
&test,
|
||||
"
|
||||
import { printHello3 } from \"./mod1.bundle.js\";
|
||||
printHello3(); ",
|
||||
)
|
||||
.expect("error writing file");
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(&test)
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
// check the output of the test.ts program.
|
||||
assert!(std::str::from_utf8(&output.stdout)
|
||||
.unwrap()
|
||||
.trim()
|
||||
.ends_with("Hello"));
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn listen_tls_alpn() {
|
||||
// TLS streams require the presence of an ambient local task set to gracefully
|
||||
// close dropped connections in the background.
|
||||
LocalSet::new()
|
||||
.run_until(async {
|
||||
let mut child = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--unstable")
|
||||
.arg("--quiet")
|
||||
.arg("--allow-net")
|
||||
.arg("--allow-read")
|
||||
.arg("./cert/listen_tls_alpn.ts")
|
||||
.arg("4504")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdout = child.stdout.as_mut().unwrap();
|
||||
let mut msg = [0; 5];
|
||||
let read = stdout.read(&mut msg).unwrap();
|
||||
assert_eq!(read, 5);
|
||||
assert_eq!(&msg, b"READY");
|
||||
|
||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||
"../testdata/tls/RootCA.crt"
|
||||
)));
|
||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
root_store.add_parsable_certificates(&certs);
|
||||
let mut cfg = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
cfg.alpn_protocols.push(b"foobar".to_vec());
|
||||
let cfg = Arc::new(cfg);
|
||||
|
||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
||||
|
||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4504")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut tls_stream =
|
||||
TlsStream::new_client_side(tcp_stream, cfg, hostname);
|
||||
|
||||
tls_stream.handshake().await.unwrap();
|
||||
|
||||
let (_, rustls_connection) = tls_stream.get_ref();
|
||||
let alpn = rustls_connection.alpn_protocol().unwrap();
|
||||
assert_eq!(alpn, b"foobar");
|
||||
|
||||
let status = child.wait().unwrap();
|
||||
assert!(status.success());
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn listen_tls_alpn_fail() {
|
||||
// TLS streams require the presence of an ambient local task set to gracefully
|
||||
// close dropped connections in the background.
|
||||
LocalSet::new()
|
||||
.run_until(async {
|
||||
let mut child = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--unstable")
|
||||
.arg("--quiet")
|
||||
.arg("--allow-net")
|
||||
.arg("--allow-read")
|
||||
.arg("./cert/listen_tls_alpn_fail.ts")
|
||||
.arg("4505")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdout = child.stdout.as_mut().unwrap();
|
||||
let mut msg = [0; 5];
|
||||
let read = stdout.read(&mut msg).unwrap();
|
||||
assert_eq!(read, 5);
|
||||
assert_eq!(&msg, b"READY");
|
||||
|
||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||
"../testdata/tls/RootCA.crt"
|
||||
)));
|
||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
root_store.add_parsable_certificates(&certs);
|
||||
let mut cfg = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
cfg.alpn_protocols.push(b"boofar".to_vec());
|
||||
let cfg = Arc::new(cfg);
|
||||
|
||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
||||
|
||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4505")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut tls_stream =
|
||||
TlsStream::new_client_side(tcp_stream, cfg, hostname);
|
||||
|
||||
tls_stream.handshake().await.unwrap_err();
|
||||
|
||||
let (_, rustls_connection) = tls_stream.get_ref();
|
||||
assert!(rustls_connection.alpn_protocol().is_none());
|
||||
|
||||
let status = child.wait().unwrap();
|
||||
assert!(status.success());
|
||||
})
|
||||
.await;
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
|
||||
use crate::itest;
|
||||
|
||||
use test_util as util;
|
||||
use util::TempDir;
|
||||
|
||||
itest!(_095_check_with_bare_import {
|
||||
args: "check cache/095_cache_with_bare_import.ts",
|
||||
output: "cache/095_cache_with_bare_import.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_extensionless {
|
||||
args: "check --reload http://localhost:4545/subdir/no_js_ext",
|
||||
output: "cache/cache_extensionless.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_random_extension {
|
||||
args: "check --reload http://localhost:4545/subdir/no_js_ext@1.0.0",
|
||||
output: "cache/cache_random_extension.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_all {
|
||||
args: "check --quiet --remote check/check_all.ts",
|
||||
output: "check/check_all.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_all_local {
|
||||
args: "check --quiet check/check_all.ts",
|
||||
output_str: Some(""),
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(module_detection_force {
|
||||
args: "check --quiet check/module_detection_force/main.ts",
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/denoland/deno/issues/14937.
|
||||
itest!(declaration_header_file_with_no_exports {
|
||||
args: "check --quiet check/declaration_header_file_with_no_exports.ts",
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
itest!(check_npm_install_diagnostics {
|
||||
args: "check --quiet check/npm_install_diagnostics/main.ts",
|
||||
output: "check/npm_install_diagnostics/main.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_export_equals_declaration_file {
|
||||
args: "check --quiet check/export_equals_declaration_file/main.ts",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn cache_switching_config_then_no_config() {
|
||||
let deno_dir = util::new_deno_dir();
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(does_type_checking(&deno_dir, false));
|
||||
|
||||
// should now not do type checking even when it changes
|
||||
// configs because it previously did
|
||||
assert!(!does_type_checking(&deno_dir, true));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
|
||||
fn does_type_checking(deno_dir: &util::TempDir, with_config: bool) -> bool {
|
||||
let mut cmd = util::deno_cmd_with_deno_dir(deno_dir);
|
||||
cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("check")
|
||||
.arg("check/cache_config_on_off/main.ts");
|
||||
if with_config {
|
||||
cmd
|
||||
.arg("--config")
|
||||
.arg("check/cache_config_on_off/deno.json");
|
||||
}
|
||||
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.contains("Check")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reload_flag() {
|
||||
// should do type checking whenever someone specifies --reload
|
||||
let deno_dir = util::new_deno_dir();
|
||||
assert!(does_type_checking(&deno_dir, false));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(does_type_checking(&deno_dir, true));
|
||||
assert!(!does_type_checking(&deno_dir, false));
|
||||
|
||||
fn does_type_checking(deno_dir: &util::TempDir, reload: bool) -> bool {
|
||||
let mut cmd = util::deno_cmd_with_deno_dir(deno_dir);
|
||||
cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("check")
|
||||
.arg("check/cache_config_on_off/main.ts");
|
||||
if reload {
|
||||
cmd.arg("--reload");
|
||||
}
|
||||
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.contains("Check")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_declarations_ns() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("test")
|
||||
.arg("--doc")
|
||||
.arg(util::root_path().join("cli/tsc/dts/lib.deno.ns.d.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_declarations_unstable() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("test")
|
||||
.arg("--doc")
|
||||
.arg("--unstable")
|
||||
.arg(util::root_path().join("cli/tsc/dts/lib.deno.unstable.d.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typecheck_core() {
|
||||
let deno_dir = TempDir::new();
|
||||
let test_file = deno_dir.path().join("test_deno_core_types.ts");
|
||||
std::fs::write(
|
||||
&test_file,
|
||||
format!(
|
||||
"import \"{}\";",
|
||||
deno_core::resolve_path(
|
||||
util::root_path()
|
||||
.join("core/lib.deno_core.d.ts")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap()
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.arg("run")
|
||||
.arg(test_file.to_str().unwrap())
|
||||
.output()
|
||||
.unwrap();
|
||||
println!("stdout: {}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("stderr: {}", String::from_utf8(output.stderr).unwrap());
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ts_no_recheck_on_redirect() {
|
||||
let deno_dir = util::new_deno_dir();
|
||||
let e = util::deno_exe_path();
|
||||
|
||||
let redirect_ts = util::testdata_path().join("run/017_import_redirect.ts");
|
||||
assert!(redirect_ts.is_file());
|
||||
let mut cmd = Command::new(e.clone());
|
||||
cmd.env("DENO_DIR", deno_dir.path());
|
||||
let mut initial = cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(redirect_ts.clone())
|
||||
.spawn()
|
||||
.expect("failed to span script");
|
||||
let status_initial =
|
||||
initial.wait().expect("failed to wait for child process");
|
||||
assert!(status_initial.success());
|
||||
|
||||
let mut cmd = Command::new(e);
|
||||
cmd.env("DENO_DIR", deno_dir.path());
|
||||
let output = cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg(redirect_ts)
|
||||
.output()
|
||||
.expect("failed to spawn script");
|
||||
|
||||
assert!(std::str::from_utf8(&output.stderr).unwrap().is_empty());
|
||||
}
|
|
@ -1,533 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs::File;
|
||||
use std::process::Command;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn compile() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
// try this twice to ensure it works with the cache
|
||||
for _ in 0..2 {
|
||||
let output = util::deno_cmd_with_deno_dir(&dir)
|
||||
.current_dir(util::root_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./test_util/std/examples/welcome.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(&exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, "Welcome to Deno!\n".as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_args() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.arg("a")
|
||||
.arg("b")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.arg("foo")
|
||||
.arg("--bar")
|
||||
.arg("--unstable")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"a\nb\nfoo\n--bar\n--unstable\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("error.exe")
|
||||
} else {
|
||||
dir.path().join("error")
|
||||
};
|
||||
let testdata_path = util::testdata_path();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(&testdata_path)
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_error.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(output.stdout, b"");
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let stderr = util::strip_ansi_codes(&stderr).to_string();
|
||||
// On Windows, we cannot assert the file path (because '\').
|
||||
// Instead we just check for relevant output.
|
||||
assert!(stderr.contains("error: Uncaught Error: boom!"));
|
||||
assert!(stderr.contains("throw new Error(\"boom!\");"));
|
||||
assert!(stderr.contains("\n at boom (file://"));
|
||||
assert!(stderr.contains("standalone_error.ts:2:11"));
|
||||
assert!(stderr.contains("at foo (file://"));
|
||||
assert!(stderr.contains("standalone_error.ts:5:5"));
|
||||
assert!(stderr.contains("standalone_error.ts:7:1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_error_module_with_imports() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("error.exe")
|
||||
} else {
|
||||
dir.path().join("error")
|
||||
};
|
||||
let testdata_path = util::testdata_path();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(&testdata_path)
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_error_module_with_imports_1.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
println!("{:#?}", &output);
|
||||
assert_eq!(output.stdout, b"hello\n");
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
let stderr = util::strip_ansi_codes(&stderr).to_string();
|
||||
// On Windows, we cannot assert the file path (because '\').
|
||||
// Instead we just check for relevant output.
|
||||
assert!(stderr.contains("error: Uncaught Error: boom!"));
|
||||
assert!(stderr.contains("throw new Error(\"boom!\");"));
|
||||
assert!(stderr.contains("\n at file://"));
|
||||
assert!(stderr.contains("standalone_error_module_with_imports_2.ts:2:7"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_load_datauri() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("load_datauri.exe")
|
||||
} else {
|
||||
dir.path().join("load_datauri")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_import_datauri.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello Deno!\n");
|
||||
}
|
||||
|
||||
// https://github.com/denoland/deno/issues/13704
|
||||
#[test]
|
||||
fn standalone_follow_redirects() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("follow_redirects.exe")
|
||||
} else {
|
||||
dir.path().join("follow_redirects")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_follow_redirects.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_file_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let output_path = if cfg!(windows) {
|
||||
dir.path().join(r"args\")
|
||||
} else {
|
||||
dir.path().join("args/")
|
||||
};
|
||||
let file_path = dir.path().join("args");
|
||||
File::create(&file_path).unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&output_path)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because its parent directory ",
|
||||
"is an existing file. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name.\n",
|
||||
),
|
||||
file_path.display(),
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_directory_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
std::fs::create_dir(&exe).unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because a directory exists with ",
|
||||
"the same name. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name."
|
||||
),
|
||||
exe.display()
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_conflict_file_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
std::fs::write(&exe, b"SHOULD NOT BE OVERWRITTEN").unwrap();
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let expected_stderr = format!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because the file already exists ",
|
||||
"and cannot be overwritten. Please delete the existing file or ",
|
||||
"use the `--output <file-path` flag to provide an alternative name."
|
||||
),
|
||||
exe.display()
|
||||
);
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
dbg!(&stderr);
|
||||
assert!(stderr.contains(&expected_stderr));
|
||||
assert!(std::fs::read(&exe)
|
||||
.unwrap()
|
||||
.eq(b"SHOULD NOT BE OVERWRITTEN"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_and_overwrite_file() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("args.exe")
|
||||
} else {
|
||||
dir.path().join("args")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert!(&exe.exists());
|
||||
|
||||
let recompile_output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/args.ts")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(recompile_output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_runtime_flags() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("flags.exe")
|
||||
} else {
|
||||
dir.path().join("flags")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg("--seed")
|
||||
.arg("1")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_runtime_flags.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let stdout_str = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(util::strip_ansi_codes(&stdout_str), "0.147205063401058\n");
|
||||
let stderr_str = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(util::strip_ansi_codes(&stderr_str)
|
||||
.contains("PermissionDenied: Requires write access"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_import_map() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("import_map.exe")
|
||||
} else {
|
||||
dir.path().join("import_map")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg("--import-map")
|
||||
.arg("compile/standalone_import_map.json")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./compile/standalone_import_map.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
// https://github.com/denoland/deno/issues/12670
|
||||
fn skip_rebundle() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("hello_world.exe")
|
||||
} else {
|
||||
dir.path().join("hello_world")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./run/001_hello.js")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
|
||||
//no "Bundle testdata_path/run/001_hello.js" in output
|
||||
assert!(!String::from_utf8(output.stderr).unwrap().contains("Bundle"));
|
||||
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, "Hello World\n".as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default() {
|
||||
let _guard = util::http_server();
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg(util::testdata_path().join("./compile/check_local_by_default.ts"))
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default2() {
|
||||
let _guard = util::http_server();
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("welcome.exe")
|
||||
} else {
|
||||
dir.path().join("welcome")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg(util::testdata_path().join("./compile/check_local_by_default2.ts"))
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(stdout.is_empty());
|
||||
assert!(stderr.contains(
|
||||
r#"error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'."#
|
||||
));
|
||||
}
|
|
@ -1,315 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn branch() {
|
||||
run_coverage_text("branch", "ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex() {
|
||||
run_coverage_text("complex", "ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_blankline() {
|
||||
run_coverage_text("final_blankline", "js");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_snaps() {
|
||||
no_snaps_included("no_snaps_included", "ts");
|
||||
}
|
||||
|
||||
fn run_coverage_text(test_name: &str, extension: &str) {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("-A")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg(format!("coverage/{}_test.{}", test_name, extension))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join(format!("coverage/{}_expected.out", test_name)),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--lcov")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join(format!("coverage/{}_expected.lcov", test_name)),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multifile_coverage() {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg("coverage/multifile/")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/multifile/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--lcov")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/multifile/expected.lcov"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
fn no_snaps_included(test_name: &str, extension: &str) {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-read")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg(format!(
|
||||
"coverage/no_snaps_included/{}_test.{}",
|
||||
test_name, extension
|
||||
))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--unstable")
|
||||
.arg("--include=no_snaps_included.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Verify there's no "Check" being printed
|
||||
assert!(output.stderr.is_empty());
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_snaps_included/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_transpiled_lines() {
|
||||
let deno_dir = TempDir::new();
|
||||
let tempdir = TempDir::new();
|
||||
let tempdir = tempdir.path().join("cov");
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--quiet")
|
||||
.arg(format!("--coverage={}", tempdir.to_str().unwrap()))
|
||||
.arg("coverage/no_transpiled_lines/")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--include=no_transpiled_lines/index.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_transpiled_lines/expected.out"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
let output = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("coverage")
|
||||
.arg("--lcov")
|
||||
.arg("--include=no_transpiled_lines/index.ts")
|
||||
.arg(format!("{}/", tempdir.to_str().unwrap()))
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let actual =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
|
||||
.to_string();
|
||||
|
||||
let expected = fs::read_to_string(
|
||||
util::testdata_path().join("coverage/no_transpiled_lines/expected.lcov"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !util::wildcard_match(&expected, &actual) {
|
||||
println!("OUTPUT\n{}\nOUTPUT", actual);
|
||||
println!("EXPECTED\n{}\nEXPECTED", expected);
|
||||
panic!("pattern match failed");
|
||||
}
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use util::assert_contains;
|
||||
|
||||
use crate::itest;
|
||||
|
||||
itest!(deno_doc_builtin {
|
||||
args: "doc",
|
||||
output: "doc/deno_doc_builtin.out",
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn deno_doc() {
|
||||
let dir = TempDir::new();
|
||||
// try this twice to ensure it works with the cache
|
||||
for _ in 0..2 {
|
||||
let output = util::deno_cmd_with_deno_dir(&dir)
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("doc")
|
||||
.arg("doc/deno_doc.ts")
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_contains!(
|
||||
std::str::from_utf8(&output.stdout).unwrap(),
|
||||
"function foo"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
itest!(deno_doc_import_map {
|
||||
args: "doc --unstable --import-map=doc/import_map.json doc/use_import_map.js",
|
||||
output: "doc/use_import_map.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_hint {
|
||||
args: "doc doc/types_hint.ts",
|
||||
output: "doc/types_hint.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_ref {
|
||||
args: "doc doc/types_ref.js",
|
||||
output: "doc/types_ref.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_header {
|
||||
args: "doc --reload doc/types_header.ts",
|
||||
output: "doc/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(_060_deno_doc_displays_all_overloads_in_details_view {
|
||||
args:
|
||||
"doc doc/060_deno_doc_displays_all_overloads_in_details_view.ts NS.test",
|
||||
output: "doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out",
|
||||
});
|
||||
|
||||
itest!(deno_doc_types_header_direct {
|
||||
args: "doc --reload http://127.0.0.1:4545/xTypeScriptTypes.js",
|
||||
output: "doc/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(deno_doc_invalid_url {
|
||||
args: "doc https://raw.githubusercontent.com%2Fdyedgreen%2Fdeno-sqlite%2Frework_api%2Fmod.ts",
|
||||
output: "doc/invalid_url.out",
|
||||
exit_code: 1,
|
||||
});
|
|
@ -1,80 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use test_util as util;
|
||||
|
||||
#[test]
|
||||
fn eval_p() {
|
||||
let output = util::deno_cmd()
|
||||
.arg("eval")
|
||||
.arg("-p")
|
||||
.arg("1+2")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout_str =
|
||||
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap().trim());
|
||||
assert_eq!("3", stdout_str);
|
||||
}
|
||||
|
||||
// Make sure that snapshot flags don't affect runtime.
|
||||
#[test]
|
||||
fn eval_randomness() {
|
||||
let mut numbers = Vec::with_capacity(10);
|
||||
for _ in 0..10 {
|
||||
let output = util::deno_cmd()
|
||||
.arg("eval")
|
||||
.arg("-p")
|
||||
.arg("Math.random()")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout_str = util::strip_ansi_codes(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
);
|
||||
numbers.push(stdout_str.to_string());
|
||||
}
|
||||
numbers.dedup();
|
||||
assert!(numbers.len() > 1);
|
||||
}
|
||||
|
||||
itest!(eval_basic {
|
||||
args: "eval console.log(\"hello\")",
|
||||
output_str: Some("hello\n"),
|
||||
});
|
||||
|
||||
// Ugly parentheses due to whitespace delimiting problem.
|
||||
itest!(eval_ts {
|
||||
args: "eval --quiet --ext=ts console.log((123)as(number))", // 'as' is a TS keyword only
|
||||
output_str: Some("123\n"),
|
||||
});
|
||||
|
||||
itest!(dyn_import_eval {
|
||||
args: "eval import('./subdir/mod4.js').then(console.log)",
|
||||
output: "eval/dyn_import_eval.out",
|
||||
});
|
||||
|
||||
// Cannot write the expression to evaluate as "console.log(typeof gc)"
|
||||
// because itest! splits args on whitespace.
|
||||
itest!(v8_flags_eval {
|
||||
args: "eval --v8-flags=--expose-gc console.log(typeof(gc))",
|
||||
output: "run/v8_flags.js.out",
|
||||
});
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "eval --quiet import('http://localhost:4545/subdir/type_error.ts').then(console.log);",
|
||||
output: "eval/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "eval --quiet import('./eval/check_local_by_default2.ts').then(console.log);",
|
||||
output: "eval/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
});
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use test_util as util;
|
||||
|
||||
#[test]
|
||||
fn help_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("--help")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_short_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("-V")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_long_flag() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("--version")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
itest!(types {
|
||||
args: "types",
|
||||
output: "types/types.out",
|
||||
});
|
|
@ -1,248 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn fmt_test() {
|
||||
let t = TempDir::new();
|
||||
let testdata_fmt_dir = util::testdata_path().join("fmt");
|
||||
let fixed_js = testdata_fmt_dir.join("badly_formatted_fixed.js");
|
||||
let badly_formatted_original_js =
|
||||
testdata_fmt_dir.join("badly_formatted.mjs");
|
||||
let badly_formatted_js = t.path().join("badly_formatted.js");
|
||||
let badly_formatted_js_str = badly_formatted_js.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_js, &badly_formatted_js).unwrap();
|
||||
|
||||
let fixed_md = testdata_fmt_dir.join("badly_formatted_fixed.md");
|
||||
let badly_formatted_original_md = testdata_fmt_dir.join("badly_formatted.md");
|
||||
let badly_formatted_md = t.path().join("badly_formatted.md");
|
||||
let badly_formatted_md_str = badly_formatted_md.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_md, &badly_formatted_md).unwrap();
|
||||
|
||||
let fixed_json = testdata_fmt_dir.join("badly_formatted_fixed.json");
|
||||
let badly_formatted_original_json =
|
||||
testdata_fmt_dir.join("badly_formatted.json");
|
||||
let badly_formatted_json = t.path().join("badly_formatted.json");
|
||||
let badly_formatted_json_str = badly_formatted_json.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_json, &badly_formatted_json).unwrap();
|
||||
// First, check formatting by ignoring the badly formatted file.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg(format!(
|
||||
"--ignore={},{},{}",
|
||||
badly_formatted_js_str, badly_formatted_md_str, badly_formatted_json_str
|
||||
))
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
// No target files found
|
||||
assert!(!status.success());
|
||||
|
||||
// Check without ignore.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(!status.success());
|
||||
|
||||
// Format the source file.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(&testdata_fmt_dir)
|
||||
.arg("fmt")
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.arg(badly_formatted_json_str)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let expected_js = std::fs::read_to_string(fixed_js).unwrap();
|
||||
let expected_md = std::fs::read_to_string(fixed_md).unwrap();
|
||||
let expected_json = std::fs::read_to_string(fixed_json).unwrap();
|
||||
let actual_js = std::fs::read_to_string(badly_formatted_js).unwrap();
|
||||
let actual_md = std::fs::read_to_string(badly_formatted_md).unwrap();
|
||||
let actual_json = std::fs::read_to_string(badly_formatted_json).unwrap();
|
||||
assert_eq!(expected_js, actual_js);
|
||||
assert_eq!(expected_md, actual_md);
|
||||
assert_eq!(expected_json, actual_json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_stdin_error() {
|
||||
use std::io::Write;
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("fmt")
|
||||
.arg("-")
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let stdin = deno.stdin.as_mut().unwrap();
|
||||
let invalid_js = b"import { example }";
|
||||
stdin.write_all(invalid_js).unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
// Error message might change. Just check stdout empty, stderr not.
|
||||
assert!(output.stdout.is_empty());
|
||||
assert!(!output.stderr.is_empty());
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_ignore_unexplicit_files() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("fmt")
|
||||
.arg("--check")
|
||||
.arg("--ignore=./")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
"error: No target files found.\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_auto_ignore_git_and_node_modules() {
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
fn create_bad_json(t: PathBuf) {
|
||||
let bad_json_path = t.join("bad.json");
|
||||
let mut bad_json_file = File::create(bad_json_path).unwrap();
|
||||
writeln!(bad_json_file, "bad json").unwrap();
|
||||
}
|
||||
let temp_dir = TempDir::new();
|
||||
let t = temp_dir.path().join("target");
|
||||
let nest_git = t.join("nest").join(".git");
|
||||
let git_dir = t.join(".git");
|
||||
let nest_node_modules = t.join("nest").join("node_modules");
|
||||
let node_modules_dir = t.join("node_modules");
|
||||
create_dir_all(&nest_git).unwrap();
|
||||
create_dir_all(&git_dir).unwrap();
|
||||
create_dir_all(&nest_node_modules).unwrap();
|
||||
create_dir_all(&node_modules_dir).unwrap();
|
||||
create_bad_json(nest_git);
|
||||
create_bad_json(git_dir);
|
||||
create_bad_json(nest_node_modules);
|
||||
create_bad_json(node_modules_dir);
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(t)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("fmt")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
"error: No target files found.\n"
|
||||
);
|
||||
}
|
||||
|
||||
itest!(fmt_quiet_check_fmt_dir {
|
||||
args: "fmt --check --quiet fmt/regular/",
|
||||
output_str: Some(""),
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_formatted_files {
|
||||
args: "fmt --check fmt/regular/formatted1.js fmt/regular/formatted2.ts fmt/regular/formatted3.markdown fmt/regular/formatted4.jsonc",
|
||||
output: "fmt/expected_fmt_check_formatted_files.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_ignore {
|
||||
args: "fmt --check --ignore=fmt/regular/formatted1.js fmt/regular/",
|
||||
output: "fmt/expected_fmt_check_ignore.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(fmt_check_parse_error {
|
||||
args: "fmt --check fmt/parse_error/parse_error.ts",
|
||||
output: "fmt/fmt_check_parse_error.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(fmt_stdin {
|
||||
args: "fmt -",
|
||||
input: Some("const a = 1\n"),
|
||||
output_str: Some("const a = 1;\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_markdown {
|
||||
args: "fmt --ext=md -",
|
||||
input: Some("# Hello Markdown\n```ts\nconsole.log( \"text\")\n```\n\n```cts\nconsole.log( 5 )\n```"),
|
||||
output_str: Some("# Hello Markdown\n\n```ts\nconsole.log(\"text\");\n```\n\n```cts\nconsole.log(5);\n```\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_json {
|
||||
args: "fmt --ext=json -",
|
||||
input: Some("{ \"key\": \"value\"}"),
|
||||
output_str: Some("{ \"key\": \"value\" }\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_check_formatted {
|
||||
args: "fmt --check -",
|
||||
input: Some("const a = 1;\n"),
|
||||
output_str: Some(""),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_check_not_formatted {
|
||||
args: "fmt --check -",
|
||||
input: Some("const a = 1\n"),
|
||||
output_str: Some("Not formatted stdin\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_with_config {
|
||||
args: "fmt --config fmt/with_config/deno.jsonc fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
itest!(fmt_with_config_default {
|
||||
args: "fmt fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
// Check if CLI flags take precedence
|
||||
itest!(fmt_with_config_and_flags {
|
||||
args: "fmt --config fmt/with_config/deno.jsonc --ignore=fmt/with_config/subdir/a.ts,fmt/with_config/subdir/b.ts",
|
||||
output: "fmt/fmt_with_config_and_flags.out",
|
||||
});
|
||||
|
||||
itest!(fmt_with_malformed_config {
|
||||
args: "fmt --config fmt/deno.malformed.jsonc",
|
||||
output: "fmt/fmt_with_malformed_config.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(fmt_with_malformed_config2 {
|
||||
args: "fmt --config fmt/deno.malformed2.jsonc",
|
||||
output: "fmt/fmt_with_malformed_config2.out",
|
||||
exit_code: 1,
|
||||
});
|
|
@ -1,132 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn info_with_compiled_source() {
|
||||
let _g = util::http_server();
|
||||
let module_path = "http://127.0.0.1:4545/run/048_media_types_jsx.ts";
|
||||
let t = TempDir::new();
|
||||
|
||||
let mut deno = util::deno_cmd()
|
||||
.env("DENO_DIR", t.path())
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("cache")
|
||||
.arg(module_path)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let status = deno.wait().unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let output = util::deno_cmd()
|
||||
.env("DENO_DIR", t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("info")
|
||||
.arg(module_path)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let str_output = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
eprintln!("{}", str_output);
|
||||
// check the output of the test.ts program.
|
||||
assert!(str_output.contains("emit: "));
|
||||
assert_eq!(output.stderr, b"");
|
||||
}
|
||||
|
||||
itest!(multiple_imports {
|
||||
args: "info http://127.0.0.1:4545/run/019_media_types.ts",
|
||||
output: "info/multiple_imports.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(info_ts_error {
|
||||
args: "info info/031_info_ts_error.ts",
|
||||
output: "info/031_info_ts_error.out",
|
||||
});
|
||||
|
||||
itest!(info_flag {
|
||||
args: "info",
|
||||
output: "info/041_info_flag.out",
|
||||
});
|
||||
|
||||
itest!(info_flag_location {
|
||||
args: "info --location https://deno.land",
|
||||
output: "info/041_info_flag_location.out",
|
||||
});
|
||||
|
||||
itest!(info_json {
|
||||
args: "info --json --unstable",
|
||||
output: "info/info_json.out",
|
||||
});
|
||||
|
||||
itest!(info_json_location {
|
||||
args: "info --json --unstable --location https://deno.land",
|
||||
output: "info/info_json_location.out",
|
||||
});
|
||||
|
||||
itest!(info_flag_script_jsx {
|
||||
args: "info http://127.0.0.1:4545/run/048_media_types_jsx.ts",
|
||||
output: "info/049_info_flag_script_jsx.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(json_file {
|
||||
args: "info --quiet --json --unstable info/json_output/main.ts",
|
||||
output: "info/json_output/main.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(import_map_info {
|
||||
args:
|
||||
"info --quiet --import-map=import_maps/import_map.json import_maps/test.ts",
|
||||
output: "info/065_import_map_info.out",
|
||||
});
|
||||
|
||||
itest!(info_json_deps_order {
|
||||
args: "info --unstable --json info/076_info_json_deps_order.ts",
|
||||
output: "info/076_info_json_deps_order.out",
|
||||
});
|
||||
|
||||
itest!(info_missing_module {
|
||||
args: "info info/error_009_missing_js_module.js",
|
||||
output: "info/info_missing_module.out",
|
||||
});
|
||||
|
||||
itest!(info_recursive_modules {
|
||||
args: "info --quiet info/info_recursive_imports_test.ts",
|
||||
output: "info/info_recursive_imports_test.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(info_type_import {
|
||||
args: "info info/info_type_import.ts",
|
||||
output: "info/info_type_import.out",
|
||||
});
|
||||
|
||||
itest!(_054_info_local_imports {
|
||||
args: "info --quiet run/005_more_imports.ts",
|
||||
output: "info/054_info_local_imports.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
// Tests for AssertionError where "data" is unexpectedly null when
|
||||
// a file contains only triple slash references (#11196)
|
||||
itest!(data_null_error {
|
||||
args: "info info/data_null_error/mod.ts",
|
||||
output: "info/data_null_error/data_null_error.out",
|
||||
});
|
||||
|
||||
itest!(types_header_direct {
|
||||
args: "info --reload run/type_directives_01.ts",
|
||||
output: "info/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(with_config_override {
|
||||
args: "info info/with_config/test.ts --config info/with_config/deno-override.json --import-map info/with_config/import_map.json",
|
||||
output: "info/with_config/with_config.out",
|
||||
});
|
|
@ -1,159 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::process::Stdio;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use util::assert_contains;
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_without_dir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert_contains!(stderr, "Project initialized");
|
||||
assert!(!stderr.contains("cd"));
|
||||
assert_contains!(stderr, "deno run main.ts");
|
||||
assert_contains!(stderr, "deno test");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_with_dir_arg() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.arg("my_dir")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stderr = String::from_utf8(output.stderr).unwrap();
|
||||
assert_contains!(stderr, "Project initialized");
|
||||
assert_contains!(stderr, "cd my_dir");
|
||||
assert_contains!(stderr, "deno run main.ts");
|
||||
assert_contains!(stderr, "deno test");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("my_dir/main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.arg("my_dir/main_test.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_subcommand_with_quiet_arg() {
|
||||
let temp_dir = TempDir::new();
|
||||
let cwd = temp_dir.path();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.arg("init")
|
||||
.arg("--quiet")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_eq!(stdout, "");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("main.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Add 2 + 3 = 5\n");
|
||||
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let output = deno_cmd
|
||||
.current_dir(cwd)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("test")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
assert_contains!(stdout, "1 passed");
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,210 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use test_util as util;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_ends_with;
|
||||
use test_util::TempDir;
|
||||
|
||||
#[test]
|
||||
fn install_basic() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg("--check")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let mut file_path = temp_dir.path().join(".deno/bin/echo_test");
|
||||
assert!(file_path.exists());
|
||||
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
// ensure there's a trailing newline so the shell script can be
|
||||
// more versatile.
|
||||
assert_eq!(content.chars().last().unwrap(), '\n');
|
||||
|
||||
if cfg!(windows) {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#""run" "--check" "http://localhost:4545/echo.ts""#
|
||||
);
|
||||
} else {
|
||||
assert_contains!(content, r#"run --check 'http://localhost:4545/echo.ts'"#);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_custom_dir_env_var() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path()) // different cwd
|
||||
.arg("install")
|
||||
.arg("--check")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", temp_dir_str.as_str()),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
let mut file_path = temp_dir.path().join("bin/echo_test");
|
||||
assert!(file_path.exists());
|
||||
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
if cfg!(windows) {
|
||||
assert_contains!(
|
||||
content,
|
||||
r#""run" "--check" "http://localhost:4545/echo.ts""#
|
||||
);
|
||||
} else {
|
||||
assert_contains!(content, r#"run --check 'http://localhost:4545/echo.ts'"#);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn installer_test_local_module_run() {
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("install")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg(util::testdata_path().join("echo.ts"))
|
||||
.arg("hello")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let mut file_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
assert!(file_path.exists());
|
||||
// NOTE: using file_path here instead of exec_name, because tests
|
||||
// shouldn't mess with user's PATH env variable
|
||||
let output = Command::new(file_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.unwrap();
|
||||
let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
assert_ends_with!(stdout_str, "hello, foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn installer_test_remote_module_run() {
|
||||
let _g = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("install")
|
||||
.arg("--name")
|
||||
.arg("echo_test")
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg("http://localhost:4545/echo.ts")
|
||||
.arg("hello")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let mut file_path = bin_dir.join("echo_test");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
assert!(file_path.exists());
|
||||
let output = Command::new(file_path)
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("foo")
|
||||
.env("PATH", util::target_dir())
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_ends_with!(
|
||||
std::str::from_utf8(&output.stdout).unwrap().trim(),
|
||||
"hello, foo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg(util::testdata_path().join("./install/check_local_by_default.ts"))
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_local_by_default2() {
|
||||
let _guard = util::http_server();
|
||||
let temp_dir = TempDir::new();
|
||||
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(temp_dir.path())
|
||||
.arg("install")
|
||||
.arg(util::testdata_path().join("./install/check_local_by_default2.ts"))
|
||||
.envs([
|
||||
("HOME", temp_dir_str.as_str()),
|
||||
("NO_COLOR", "1"),
|
||||
("USERPROFILE", temp_dir_str.as_str()),
|
||||
("DENO_INSTALL_ROOT", ""),
|
||||
])
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use test_util as util;
|
||||
|
||||
#[test]
|
||||
fn ignore_unexplicit_files() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("lint")
|
||||
.arg("--unstable")
|
||||
.arg("--ignore=./")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
"error: No target files found.\n"
|
||||
);
|
||||
}
|
||||
|
||||
itest!(all {
|
||||
args: "lint lint/without_config/file1.js lint/without_config/file2.ts lint/without_config/ignored_file.ts",
|
||||
output: "lint/expected.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(quiet {
|
||||
args: "lint --quiet lint/without_config/file1.js",
|
||||
output: "lint/expected_quiet.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(json {
|
||||
args:
|
||||
"lint --json lint/without_config/file1.js lint/without_config/file2.ts lint/without_config/ignored_file.ts lint/without_config/malformed.js",
|
||||
output: "lint/expected_json.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(compact {
|
||||
args:
|
||||
"lint --compact lint/without_config/file1.js lint/without_config/ignored_file.tss",
|
||||
output: "lint/expected_compact.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(ignore {
|
||||
args:
|
||||
"lint --ignore=lint/without_config/file1.js,lint/without_config/malformed.js,lint/without_config/lint_with_config/ lint/without_config/",
|
||||
output: "lint/expected_ignore.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(glob {
|
||||
args: "lint --ignore=lint/without_config/malformed.js,lint/with_config/ lint/without_config/",
|
||||
output: "lint/expected_glob.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(stdin {
|
||||
args: "lint -",
|
||||
input: Some("let _a: any;"),
|
||||
output: "lint/expected_from_stdin.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(stdin_json {
|
||||
args: "lint --json -",
|
||||
input: Some("let _a: any;"),
|
||||
output: "lint/expected_from_stdin_json.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(rules {
|
||||
args: "lint --rules",
|
||||
output: "lint/expected_rules.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
// Make sure that the rules are printed if quiet option is enabled.
|
||||
itest!(rules_quiet {
|
||||
args: "lint --rules -q",
|
||||
output: "lint/expected_rules.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(lint_with_config {
|
||||
args: "lint --config lint/Deno.jsonc lint/with_config/",
|
||||
output: "lint/with_config.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(lint_with_report_config {
|
||||
args: "lint --config lint/Deno.compact.format.jsonc lint/with_config/",
|
||||
output: "lint/with_report_config_compact.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
// Check if CLI flags take precedence
|
||||
itest!(lint_with_report_config_override {
|
||||
args: "lint --config lint/Deno.compact.format.jsonc lint/with_config/ --json",
|
||||
output: "lint/with_report_config_override.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(lint_with_config_and_flags {
|
||||
args: "lint --config lint/Deno.jsonc --ignore=lint/with_config/a.ts",
|
||||
output: "lint/with_config_and_flags.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(lint_with_config_without_tags {
|
||||
args: "lint --config lint/Deno.no_tags.jsonc lint/with_config/",
|
||||
output: "lint/with_config_without_tags.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(lint_with_malformed_config {
|
||||
args: "lint --config lint/Deno.malformed.jsonc",
|
||||
output: "lint/with_malformed_config.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(lint_with_malformed_config2 {
|
||||
args: "lint --config lint/Deno.malformed2.jsonc",
|
||||
output: "lint/with_malformed_config2.out",
|
||||
exit_code: 1,
|
||||
});
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,5 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use test_util as util;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! itest(
|
||||
($name:ident {$( $key:ident: $value:expr,)*}) => {
|
||||
|
@ -31,96 +29,3 @@ macro_rules! itest_flaky(
|
|||
}
|
||||
}
|
||||
);
|
||||
|
||||
// These files have `_tests.rs` suffix to make it easier to tell which file is
|
||||
// the test (ex. `lint_tests.rs`) and which is the implementation (ex. `lint.rs`)
|
||||
// when both are open, especially for two tabs in VS Code
|
||||
|
||||
#[path = "bench_tests.rs"]
|
||||
mod bench;
|
||||
#[path = "bundle_tests.rs"]
|
||||
mod bundle;
|
||||
#[path = "cache_tests.rs"]
|
||||
mod cache;
|
||||
#[path = "cert_tests.rs"]
|
||||
mod cert;
|
||||
#[path = "check_tests.rs"]
|
||||
mod check;
|
||||
#[path = "compile_tests.rs"]
|
||||
mod compile;
|
||||
#[path = "coverage_tests.rs"]
|
||||
mod coverage;
|
||||
#[path = "doc_tests.rs"]
|
||||
mod doc;
|
||||
#[path = "eval_tests.rs"]
|
||||
mod eval;
|
||||
#[path = "flags_tests.rs"]
|
||||
mod flags;
|
||||
#[path = "fmt_tests.rs"]
|
||||
mod fmt;
|
||||
#[path = "info_tests.rs"]
|
||||
mod info;
|
||||
#[path = "init_tests.rs"]
|
||||
mod init;
|
||||
#[path = "inspector_tests.rs"]
|
||||
mod inspector;
|
||||
#[path = "install_tests.rs"]
|
||||
mod install;
|
||||
#[path = "lint_tests.rs"]
|
||||
mod lint;
|
||||
#[path = "lsp_tests.rs"]
|
||||
mod lsp;
|
||||
#[path = "npm_tests.rs"]
|
||||
mod npm;
|
||||
#[path = "repl_tests.rs"]
|
||||
mod repl;
|
||||
#[path = "run_tests.rs"]
|
||||
mod run;
|
||||
#[path = "task_tests.rs"]
|
||||
mod task;
|
||||
#[path = "test_tests.rs"]
|
||||
mod test;
|
||||
#[path = "upgrade_tests.rs"]
|
||||
mod upgrade;
|
||||
#[path = "vendor_tests.rs"]
|
||||
mod vendor;
|
||||
#[path = "watcher_tests.rs"]
|
||||
mod watcher;
|
||||
#[path = "worker_tests.rs"]
|
||||
mod worker;
|
||||
|
||||
#[test]
|
||||
fn js_unit_tests_lint() {
|
||||
let status = util::deno_cmd()
|
||||
.arg("lint")
|
||||
.arg("--unstable")
|
||||
.arg(util::tests_path().join("unit"))
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn js_unit_tests() {
|
||||
let _g = util::http_server();
|
||||
|
||||
// Note that the unit tests are not safe for concurrency and must be run with a concurrency limit
|
||||
// of one because there are some chdir tests in there.
|
||||
// TODO(caspervonb) split these tests into two groups: parallel and serial.
|
||||
let mut deno = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("test")
|
||||
.arg("--unstable")
|
||||
.arg("--location=http://js-unit-tests/foo/bar")
|
||||
.arg("--no-prompt")
|
||||
.arg("-A")
|
||||
.arg(util::tests_path().join("unit"))
|
||||
.spawn()
|
||||
.expect("failed to spawn script");
|
||||
|
||||
let status = deno.wait().expect("failed to wait for the child process");
|
||||
assert_eq!(Some(0), status.code());
|
||||
assert!(status.success());
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,877 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use test_util as util;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_ends_with;
|
||||
use test_util::assert_not_contains;
|
||||
|
||||
#[test]
|
||||
fn pty_multiline() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("(\n1 + 2\n)");
|
||||
console.write_line("{\nfoo: \"foo\"\n}");
|
||||
console.write_line("`\nfoo\n`");
|
||||
console.write_line("`\n\\`\n`");
|
||||
console.write_line("'{'");
|
||||
console.write_line("'('");
|
||||
console.write_line("'['");
|
||||
console.write_line("/{/");
|
||||
console.write_line("/\\(/");
|
||||
console.write_line("/\\[/");
|
||||
console.write_line("console.log(\"{test1} abc {test2} def {{test3}}\".match(/{([^{].+?)}/));");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, '3');
|
||||
assert_contains!(output, "{ foo: \"foo\" }");
|
||||
assert_contains!(output, "\"\\nfoo\\n\"");
|
||||
assert_contains!(output, "\"\\n`\\n\"");
|
||||
assert_contains!(output, "\"{\"");
|
||||
assert_contains!(output, "\"(\"");
|
||||
assert_contains!(output, "\"[\"");
|
||||
assert_contains!(output, "/{/");
|
||||
assert_contains!(output, "/\\(/");
|
||||
assert_contains!(output, "/\\[/");
|
||||
assert_contains!(output, "[ \"{test1}\", \"test1\" ]");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_null() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("null");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "null");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_unpaired_braces() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line(")");
|
||||
console.write_line("]");
|
||||
console.write_line("}");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Unexpected token `)`");
|
||||
assert_contains!(output, "Unexpected token `]`");
|
||||
assert_contains!(output, "Unexpected token `}`");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_bad_input() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("'\\u{1f3b5}'[0]");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Unterminated string literal");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_syntax_error_input() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("('\\u')");
|
||||
console.write_line("'");
|
||||
console.write_line("[{'a'}];");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(
|
||||
output,
|
||||
"Bad character escape sequence, expected 4 hex characters"
|
||||
);
|
||||
assert_contains!(output, "Unterminated string constant");
|
||||
assert_contains!(output, "Expected a semicolon");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_symbol() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("Symbol.it\t");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Symbol(Symbol.iterator)");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_declarations() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("class MyClass {}");
|
||||
console.write_line("My\t");
|
||||
console.write_line("let myVar;");
|
||||
console.write_line("myV\t");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "> MyClass");
|
||||
assert_contains!(output, "> myVar");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_primitives() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("let func = function test(){}");
|
||||
console.write_line("func.appl\t");
|
||||
console.write_line("let str = ''");
|
||||
console.write_line("str.leng\t");
|
||||
console.write_line("false.valueO\t");
|
||||
console.write_line("5n.valueO\t");
|
||||
console.write_line("let num = 5");
|
||||
console.write_line("num.toStrin\t");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "> func.apply");
|
||||
assert_contains!(output, "> str.length");
|
||||
assert_contains!(output, "> 5n.valueOf");
|
||||
assert_contains!(output, "> false.valueOf");
|
||||
assert_contains!(output, "> num.toString");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_expression() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_text("Deno.\t\t");
|
||||
console.write_text("y");
|
||||
console.write_line("");
|
||||
console.write_line("close();");
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Display all");
|
||||
assert_contains!(output, "core");
|
||||
assert_contains!(output, "args");
|
||||
assert_contains!(output, "exit");
|
||||
assert_contains!(output, "symlink");
|
||||
assert_contains!(output, "permissions");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_imports() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
// single quotes
|
||||
console.write_line("import './run/001_hel\t'");
|
||||
// double quotes
|
||||
console.write_line("import { output } from \"./run/045_out\t\"");
|
||||
console.write_line("output('testing output');");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Hello World");
|
||||
assert_contains!(
|
||||
output,
|
||||
// on windows, could contain either (it's flaky)
|
||||
"\ntesting output",
|
||||
"testing output\u{1b}",
|
||||
);
|
||||
});
|
||||
|
||||
// ensure when the directory changes that the suggestions come from the cwd
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("Deno.chdir('./subdir');");
|
||||
console.write_line("import '../run/001_hel\t'");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "Hello World");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_complete_imports_no_panic_empty_specifier() {
|
||||
// does not panic when tabbing when empty
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("import '\t';");
|
||||
console.write_line("close();");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_ignore_symbols() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("Array.Symbol\t");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "undefined");
|
||||
assert_not_contains!(
|
||||
output,
|
||||
"Uncaught TypeError: Array.Symbol is not a function"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_assign_global_this() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("globalThis = 42;");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
assert_not_contains!(output, "panicked");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_emoji() {
|
||||
// windows was having issues displaying this
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line(r#"console.log('\u{1F995}');"#);
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
// only one for the output (since input is escaped)
|
||||
let emoji_count = output.chars().filter(|c| *c == '🦕').count();
|
||||
assert_eq!(emoji_count, 1);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn console_log() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["console.log('hello')", "'world'"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "hello\nundefined\n\"world\"\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_literal() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["{}", "{ foo: 'bar' }"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "{}\n{ foo: \"bar\" }\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_expression() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["{};", "{\"\"}"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\n\"\"\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn await_resolve() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["await Promise.resolve('done')"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "\"done\"\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn await_timeout() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["await new Promise((r) => setTimeout(r, 0, 'done'))"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "\"done\"\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_redeclaration() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["let foo = 0;", "foo", "let foo = 1;", "foo"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\n0\nundefined\n1\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repl_cwd() {
|
||||
let (_out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["Deno.cwd()"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typescript() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
"function add(a: number, b: number) { return a + b }",
|
||||
"const result: number = add(1, 2) as number;",
|
||||
"result",
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\nundefined\n3\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typescript_declarations() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
"namespace Test { export enum Values { A, B, C } }",
|
||||
"Test.Values.A",
|
||||
"Test.Values.C",
|
||||
"interface MyInterface { prop: string; }",
|
||||
"type MyTypeAlias = string;",
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
let expected_end_text = "undefined\n0\n2\nundefined\nundefined\n";
|
||||
assert_ends_with!(out, expected_end_text);
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typescript_decorators() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
"function dec(target) { target.prototype.test = () => 2; }",
|
||||
"@dec class Test {}",
|
||||
"new Test().test()",
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\n[Function: Test]\n2\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eof() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["1 + 2"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "3\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn strict() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
"let a = {};",
|
||||
"Object.preventExtensions(a);",
|
||||
"a.c = 1;",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(
|
||||
out,
|
||||
"Uncaught TypeError: Cannot add property c, object is not extensible"
|
||||
);
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn close_command() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["close()", "'ignored'"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
assert_not_contains!(out, "ignored");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["Deno.writeFileSync"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "[Function: writeFileSync]\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn multiline() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["(\n1 + 2\n)"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "3\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import() {
|
||||
let (out, _) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["import('./subdir/auto_print_hello.ts')"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "hello!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_declarations() {
|
||||
let (out, _) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["import './subdir/auto_print_hello.ts';"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "hello!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exports_stripped() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["export default 5;", "export class Test {}"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "5\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_eval_unterminated() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["eval('{')"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "Unexpected end of input");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unpaired_braces() {
|
||||
for right_brace in &[")", "]", "}"] {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![right_brace]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "Unexpected token");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reference_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["not_a_variable"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "not_a_variable is not defined");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syntax_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
"syntax error",
|
||||
"2", // ensure it keeps accepting input after
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "parse error: Expected ';', '}' or <eof> at 1:8\n2\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syntax_error_jsx() {
|
||||
// JSX is not supported in the REPL
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["const element = <div />;"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "Unexpected token `>`");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["console()"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "console is not a function");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn variable() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["var a = 123;", "a"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\n123\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lexical_scoped_variable() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["let a = 123;", "a"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "undefined\n123\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_deno_dir() {
|
||||
use std::fs::{read_dir, remove_dir_all};
|
||||
const DENO_DIR: &str = "nonexistent";
|
||||
let test_deno_dir = test_util::testdata_path().join(DENO_DIR);
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["1"]),
|
||||
Some(vec![
|
||||
("DENO_DIR".to_owned(), DENO_DIR.to_owned()),
|
||||
("NO_COLOR".to_owned(), "1".to_owned()),
|
||||
]),
|
||||
false,
|
||||
);
|
||||
assert!(read_dir(&test_deno_dir).is_ok());
|
||||
remove_dir_all(&test_deno_dir).unwrap();
|
||||
assert_ends_with!(out, "1\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_last_eval() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["1", "_"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "1\n1\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_last_thrown() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["throw 1", "_error"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(out, "Uncaught 1\n1\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assign_underscore() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["_ = 1", "2", "_"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
assert_ends_with!(
|
||||
out,
|
||||
"Last evaluation result is no longer saved to _.\n1\n2\n1\n"
|
||||
);
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assign_underscore_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["_error = 1", "throw 2", "_error"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
println!("{}", out);
|
||||
assert_ends_with!(
|
||||
out,
|
||||
"Last thrown error is no longer saved to _error.\n1\nUncaught 2\n1\n"
|
||||
);
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_inspect() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
r#"const o = {
|
||||
[Symbol.for("Deno.customInspect")]() {
|
||||
throw new Error('Oops custom inspect error');
|
||||
},
|
||||
};"#,
|
||||
"o",
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
|
||||
assert_contains!(out, "Oops custom inspect error");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_flag_valid_input() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval", "const t = 10;"],
|
||||
Some(vec!["t * 500;"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "5000");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_flag_parse_error() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval", "const %"],
|
||||
Some(vec!["250 * 10"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(
|
||||
test_util::strip_ansi_codes(&out),
|
||||
"error in --eval flag. parse error: Unexpected token `%`."
|
||||
);
|
||||
assert_contains!(out, "2500"); // should not prevent input
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_flag_runtime_error() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval", "throw new Error('Testing')"],
|
||||
Some(vec!["250 * 10"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "error in --eval flag. Uncaught Error: Testing");
|
||||
assert_contains!(out, "2500"); // should not prevent input
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_file_flag_valid_input() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval-file=./run/001_hello.js"],
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "Hello World");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_file_flag_call_defined_function() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval-file=./tsc/d.ts"],
|
||||
Some(vec!["v4()"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_contains!(out, "hello");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_file_flag_http_input() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval-file=http://127.0.0.1:4545/tsc/d.ts"],
|
||||
Some(vec!["v4()"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
assert_contains!(out, "hello");
|
||||
assert!(err.contains("Download"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_file_flag_multiple_files() {
|
||||
let (out, err) = util::run_and_collect_output_with_args(
|
||||
true,
|
||||
vec!["repl", "--eval-file=http://127.0.0.1:4545/repl/import_type.ts,./tsc/d.ts,http://127.0.0.1:4545/type_definitions/foo.js"],
|
||||
Some(vec!["b.method1=v4", "b.method1()+foo.toUpperCase()"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
assert_contains!(out, "helloFOO");
|
||||
assert_contains!(err, "Download");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_clear_function() {
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("console.log('hello');");
|
||||
console.write_line("clear();");
|
||||
console.write_line("const clear = 1234 + 2000;");
|
||||
console.write_line("clear;");
|
||||
console.write_line("close();");
|
||||
|
||||
let output = console.read_all_output();
|
||||
if cfg!(windows) {
|
||||
// Windows will overwrite what's in the console buffer before
|
||||
// we read from it. It contains this string repeated many times
|
||||
// to clear the screen.
|
||||
assert_contains!(output, "\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K");
|
||||
} else {
|
||||
assert_contains!(output, "hello");
|
||||
assert_contains!(output, "[1;1H");
|
||||
}
|
||||
assert_contains!(output, "undefined");
|
||||
assert_contains!(output, "const clear = 1234 + 2000;");
|
||||
assert_contains!(output, "3234");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_tab_handler() {
|
||||
// If the last character is **not** whitespace, we show the completions
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("a\t\t");
|
||||
console.write_line("close();");
|
||||
let output = console.read_all_output();
|
||||
assert_contains!(output, "addEventListener");
|
||||
assert_contains!(output, "alert");
|
||||
assert_contains!(output, "atob");
|
||||
});
|
||||
// If the last character is whitespace, we just insert a tab
|
||||
util::with_pty(&["repl"], |mut console| {
|
||||
console.write_line("a; \t\t"); // last character is whitespace
|
||||
console.write_line("close();");
|
||||
let output = console.read_all_output();
|
||||
assert_not_contains!(output, "addEventListener");
|
||||
assert_not_contains!(output, "alert");
|
||||
assert_not_contains!(output, "atob");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repl_report_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec![
|
||||
r#"console.log(1); reportError(new Error("foo")); console.log(2);"#,
|
||||
]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
|
||||
// TODO(nayeemrmn): The REPL should report event errors and rejections.
|
||||
assert_contains!(out, "1\n2\nundefined\n");
|
||||
assert!(err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pty_aggregate_error() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
true,
|
||||
"repl",
|
||||
Some(vec!["await Promise.any([])"]),
|
||||
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
|
||||
false,
|
||||
);
|
||||
|
||||
assert_contains!(out, "AggregateError");
|
||||
assert!(err.is_empty());
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,132 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
|
||||
// Most of the tests for this are in deno_task_shell.
|
||||
// These tests are intended to only test integration.
|
||||
|
||||
itest!(task_no_args {
|
||||
args: "task -q --config task/deno.json",
|
||||
output: "task/task_no_args.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(task_cwd {
|
||||
args: "task -q --config task/deno.json --cwd .. echo_cwd",
|
||||
output: "task/task_cwd.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(task_init_cwd {
|
||||
args: "task -q --config task/deno.json --cwd .. echo_init_cwd",
|
||||
output: "task/task_init_cwd.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(task_init_cwd_already_set {
|
||||
args: "task -q --config task/deno.json echo_init_cwd",
|
||||
output: "task/task_init_cwd_already_set.out",
|
||||
envs: vec![
|
||||
("NO_COLOR".to_string(), "1".to_string()),
|
||||
("INIT_CWD".to_string(), "HELLO".to_string())
|
||||
],
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(task_cwd_resolves_config_from_specified_dir {
|
||||
args: "task -q --cwd task",
|
||||
output: "task/task_no_args.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(task_non_existent {
|
||||
args: "task --config task/deno.json non_existent",
|
||||
output: "task/task_non_existent.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn task_emoji() {
|
||||
// this bug only appears when using a pty/tty
|
||||
let args = "task --config task/deno.json echo_emoji";
|
||||
use test_util::PtyData::*;
|
||||
test_util::test_pty2(args, vec![Output("Task echo_emoji echo 🔥\r\n🔥")]);
|
||||
}
|
||||
|
||||
itest!(task_boolean_logic {
|
||||
args: "task -q --config task/deno.json boolean_logic",
|
||||
output: "task/task_boolean_logic.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
itest!(task_exit_code_5 {
|
||||
args: "task --config task/deno.json exit_code_5",
|
||||
output: "task/task_exit_code_5.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
exit_code: 5,
|
||||
});
|
||||
|
||||
itest!(task_additional_args {
|
||||
args: "task -q --config task/deno.json echo 2",
|
||||
output: "task/task_additional_args.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
itest!(task_additional_args_no_shell_expansion {
|
||||
args_vec: vec![
|
||||
"task",
|
||||
"-q",
|
||||
"--config",
|
||||
"task/deno.json",
|
||||
"echo",
|
||||
"$(echo 5)"
|
||||
],
|
||||
output: "task/task_additional_args_no_shell_expansion.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
itest!(task_additional_args_nested_strings {
|
||||
args_vec: vec![
|
||||
"task",
|
||||
"-q",
|
||||
"--config",
|
||||
"task/deno.json",
|
||||
"echo",
|
||||
"string \"quoted string\""
|
||||
],
|
||||
output: "task/task_additional_args_nested_strings.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
itest!(task_additional_args_no_logic {
|
||||
args_vec: vec![
|
||||
"task",
|
||||
"-q",
|
||||
"--config",
|
||||
"task/deno.json",
|
||||
"echo",
|
||||
"||",
|
||||
"echo",
|
||||
"5"
|
||||
],
|
||||
output: "task/task_additional_args_no_logic.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
itest!(task_deno_exe_no_env {
|
||||
args_vec: vec!["task", "-q", "--config", "task/deno.json", "deno_echo"],
|
||||
output: "task/task_deno_exe_no_env.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
env_clear: true,
|
||||
});
|
||||
|
||||
itest!(task_piped_stdin {
|
||||
args_vec: vec!["task", "-q", "--config", "task/deno.json", "piped"],
|
||||
output: "task/task_piped_stdin.out",
|
||||
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||
});
|
|
@ -1,449 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
use deno_core::url::Url;
|
||||
use test_util as util;
|
||||
|
||||
#[test]
|
||||
fn no_color() {
|
||||
let (out, _) = util::run_and_collect_output(
|
||||
false,
|
||||
"test test/no_color.ts",
|
||||
None,
|
||||
Some(vec![("NO_COLOR".to_owned(), "true".to_owned())]),
|
||||
false,
|
||||
);
|
||||
// ANSI escape codes should be stripped.
|
||||
assert!(out.contains("success ... ok"));
|
||||
assert!(out.contains("fail ... FAILED"));
|
||||
assert!(out.contains("ignored ... ignored"));
|
||||
assert!(out.contains("FAILED | 1 passed | 1 failed | 1 ignored"));
|
||||
}
|
||||
|
||||
itest!(overloads {
|
||||
args: "test test/overloads.ts",
|
||||
exit_code: 0,
|
||||
output: "test/overloads.out",
|
||||
});
|
||||
|
||||
itest!(meta {
|
||||
args: "test test/meta.ts",
|
||||
exit_code: 0,
|
||||
output: "test/meta.out",
|
||||
});
|
||||
|
||||
itest!(pass {
|
||||
args: "test test/pass.ts",
|
||||
exit_code: 0,
|
||||
output: "test/pass.out",
|
||||
});
|
||||
|
||||
itest!(ignore {
|
||||
args: "test test/ignore.ts",
|
||||
exit_code: 0,
|
||||
output: "test/ignore.out",
|
||||
});
|
||||
|
||||
itest!(ignore_permissions {
|
||||
args: "test --unstable test/ignore_permissions.ts",
|
||||
exit_code: 0,
|
||||
output: "test/ignore_permissions.out",
|
||||
});
|
||||
|
||||
itest!(fail {
|
||||
args: "test test/fail.ts",
|
||||
exit_code: 1,
|
||||
output: "test/fail.out",
|
||||
});
|
||||
|
||||
itest!(collect {
|
||||
args: "test --ignore=test/collect/ignore test/collect",
|
||||
exit_code: 0,
|
||||
output: "test/collect.out",
|
||||
});
|
||||
|
||||
itest!(test_with_config {
|
||||
args: "test --config test/collect/deno.jsonc test/collect",
|
||||
exit_code: 0,
|
||||
output: "test/collect.out",
|
||||
});
|
||||
|
||||
itest!(test_with_config2 {
|
||||
args: "test --config test/collect/deno2.jsonc test/collect",
|
||||
exit_code: 0,
|
||||
output: "test/collect2.out",
|
||||
});
|
||||
|
||||
itest!(test_with_malformed_config {
|
||||
args: "test --config test/collect/deno.malformed.jsonc",
|
||||
exit_code: 1,
|
||||
output: "test/collect_with_malformed_config.out",
|
||||
});
|
||||
|
||||
itest!(parallel_flag {
|
||||
args: "test test/short-pass.ts --parallel",
|
||||
exit_code: 0,
|
||||
output: "test/short-pass.out",
|
||||
});
|
||||
|
||||
itest!(parallel_flag_with_env_variable {
|
||||
args: "test test/short-pass.ts --parallel",
|
||||
envs: vec![("DENO_JOBS".to_owned(), "2".to_owned())],
|
||||
exit_code: 0,
|
||||
output: "test/short-pass.out",
|
||||
});
|
||||
|
||||
itest!(jobs_flag {
|
||||
args: "test test/short-pass.ts --jobs",
|
||||
exit_code: 0,
|
||||
output: "test/short-pass-jobs-flag-warning.out",
|
||||
});
|
||||
|
||||
itest!(jobs_flag_with_numeric_value {
|
||||
args: "test test/short-pass.ts --jobs=2",
|
||||
exit_code: 0,
|
||||
output: "test/short-pass-jobs-flag-warning.out",
|
||||
});
|
||||
|
||||
itest!(load_unload {
|
||||
args: "test test/load_unload.ts",
|
||||
exit_code: 0,
|
||||
output: "test/load_unload.out",
|
||||
});
|
||||
|
||||
itest!(interval {
|
||||
args: "test test/interval.ts",
|
||||
exit_code: 0,
|
||||
output: "test/interval.out",
|
||||
});
|
||||
|
||||
itest!(doc {
|
||||
args: "test --doc --allow-all test/doc.ts",
|
||||
exit_code: 1,
|
||||
output: "test/doc.out",
|
||||
});
|
||||
|
||||
itest!(doc_only {
|
||||
args: "test --doc --allow-all test/doc_only",
|
||||
exit_code: 0,
|
||||
output: "test/doc_only.out",
|
||||
});
|
||||
|
||||
itest!(markdown {
|
||||
args: "test --doc --allow-all test/markdown.md",
|
||||
exit_code: 1,
|
||||
output: "test/markdown.out",
|
||||
});
|
||||
|
||||
itest!(markdown_windows {
|
||||
args: "test --doc --allow-all test/markdown_windows.md",
|
||||
exit_code: 1,
|
||||
output: "test/markdown_windows.out",
|
||||
});
|
||||
|
||||
itest!(markdown_full_block_names {
|
||||
args: "test --doc --allow-all test/markdown_full_block_names.md",
|
||||
exit_code: 1,
|
||||
output: "test/markdown_full_block_names.out",
|
||||
});
|
||||
|
||||
itest!(markdown_ignore_html_comment {
|
||||
args: "test --doc --allow-all test/markdown_with_comment.md",
|
||||
exit_code: 1,
|
||||
output: "test/markdown_with_comment.out",
|
||||
});
|
||||
|
||||
itest!(text {
|
||||
args: "test --doc --allow-all test/text.md",
|
||||
exit_code: 0,
|
||||
output: "test/text.out",
|
||||
});
|
||||
|
||||
itest!(quiet {
|
||||
args: "test --quiet test/quiet.ts",
|
||||
exit_code: 0,
|
||||
output: "test/quiet.out",
|
||||
});
|
||||
|
||||
itest!(fail_fast {
|
||||
args: "test --fail-fast test/fail_fast.ts",
|
||||
exit_code: 1,
|
||||
output: "test/fail_fast.out",
|
||||
});
|
||||
|
||||
itest!(only {
|
||||
args: "test test/only.ts",
|
||||
exit_code: 1,
|
||||
output: "test/only.out",
|
||||
});
|
||||
|
||||
itest!(no_check {
|
||||
args: "test --no-check test/no_check.ts",
|
||||
exit_code: 1,
|
||||
output: "test/no_check.out",
|
||||
});
|
||||
|
||||
itest!(no_run {
|
||||
args: "test --unstable --no-run test/no_run.ts",
|
||||
output: "test/no_run.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(allow_all {
|
||||
args: "test --unstable --allow-all test/allow_all.ts",
|
||||
exit_code: 0,
|
||||
output: "test/allow_all.out",
|
||||
});
|
||||
|
||||
itest!(allow_none {
|
||||
args: "test --unstable test/allow_none.ts",
|
||||
exit_code: 1,
|
||||
output: "test/allow_none.out",
|
||||
});
|
||||
|
||||
itest!(ops_sanitizer_unstable {
|
||||
args: "test --unstable --trace-ops test/ops_sanitizer_unstable.ts",
|
||||
exit_code: 1,
|
||||
output: "test/ops_sanitizer_unstable.out",
|
||||
});
|
||||
|
||||
itest!(ops_sanitizer_timeout_failure {
|
||||
args: "test test/ops_sanitizer_timeout_failure.ts",
|
||||
output: "test/ops_sanitizer_timeout_failure.out",
|
||||
});
|
||||
|
||||
itest!(ops_sanitizer_multiple_timeout_tests {
|
||||
args: "test --trace-ops test/ops_sanitizer_multiple_timeout_tests.ts",
|
||||
exit_code: 1,
|
||||
output: "test/ops_sanitizer_multiple_timeout_tests.out",
|
||||
});
|
||||
|
||||
itest!(ops_sanitizer_multiple_timeout_tests_no_trace {
|
||||
args: "test test/ops_sanitizer_multiple_timeout_tests.ts",
|
||||
exit_code: 1,
|
||||
output: "test/ops_sanitizer_multiple_timeout_tests_no_trace.out",
|
||||
});
|
||||
|
||||
// TODO(@littledivy): re-enable this test, recent optimizations made output non deterministic.
|
||||
// https://github.com/denoland/deno/issues/14268
|
||||
//
|
||||
// itest!(ops_sanitizer_missing_details {
|
||||
// args: "test --allow-write --allow-read test/ops_sanitizer_missing_details.ts",
|
||||
// exit_code: 1,
|
||||
// output: "test/ops_sanitizer_missing_details.out",
|
||||
// });
|
||||
|
||||
itest!(ops_sanitizer_nexttick {
|
||||
args: "test test/ops_sanitizer_nexttick.ts",
|
||||
output: "test/ops_sanitizer_nexttick.out",
|
||||
});
|
||||
|
||||
itest!(resource_sanitizer {
|
||||
args: "test --allow-read test/resource_sanitizer.ts",
|
||||
exit_code: 1,
|
||||
output: "test/resource_sanitizer.out",
|
||||
});
|
||||
|
||||
itest!(exit_sanitizer {
|
||||
args: "test test/exit_sanitizer.ts",
|
||||
output: "test/exit_sanitizer.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(clear_timeout {
|
||||
args: "test test/clear_timeout.ts",
|
||||
exit_code: 0,
|
||||
output: "test/clear_timeout.out",
|
||||
});
|
||||
|
||||
itest!(finally_timeout {
|
||||
args: "test test/finally_timeout.ts",
|
||||
exit_code: 1,
|
||||
output: "test/finally_timeout.out",
|
||||
});
|
||||
|
||||
itest!(unresolved_promise {
|
||||
args: "test test/unresolved_promise.ts",
|
||||
exit_code: 1,
|
||||
output: "test/unresolved_promise.out",
|
||||
});
|
||||
|
||||
itest!(unhandled_rejection {
|
||||
args: "test test/unhandled_rejection.ts",
|
||||
exit_code: 1,
|
||||
output: "test/unhandled_rejection.out",
|
||||
});
|
||||
|
||||
itest!(filter {
|
||||
args: "test --filter=foo test/filter",
|
||||
exit_code: 0,
|
||||
output: "test/filter.out",
|
||||
});
|
||||
|
||||
itest!(shuffle {
|
||||
args: "test --shuffle test/shuffle",
|
||||
exit_code: 0,
|
||||
output_str: Some("[WILDCARD]"),
|
||||
});
|
||||
|
||||
itest!(shuffle_with_seed {
|
||||
args: "test --shuffle=42 test/shuffle",
|
||||
exit_code: 0,
|
||||
output: "test/shuffle.out",
|
||||
});
|
||||
|
||||
itest!(aggregate_error {
|
||||
args: "test --quiet test/aggregate_error.ts",
|
||||
exit_code: 1,
|
||||
output: "test/aggregate_error.out",
|
||||
});
|
||||
|
||||
itest!(steps_passing_steps {
|
||||
args: "test test/steps/passing_steps.ts",
|
||||
exit_code: 0,
|
||||
output: "test/steps/passing_steps.out",
|
||||
});
|
||||
|
||||
itest!(steps_failing_steps {
|
||||
args: "test test/steps/failing_steps.ts",
|
||||
exit_code: 1,
|
||||
output: "test/steps/failing_steps.out",
|
||||
});
|
||||
|
||||
itest!(steps_ignored_steps {
|
||||
args: "test test/steps/ignored_steps.ts",
|
||||
exit_code: 0,
|
||||
output: "test/steps/ignored_steps.out",
|
||||
});
|
||||
|
||||
itest!(steps_invalid_usage {
|
||||
args: "test test/steps/invalid_usage.ts",
|
||||
exit_code: 1,
|
||||
output: "test/steps/invalid_usage.out",
|
||||
});
|
||||
|
||||
itest!(steps_output_within {
|
||||
args: "test test/steps/output_within.ts",
|
||||
exit_code: 0,
|
||||
output: "test/steps/output_within.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_by_default {
|
||||
args: "test --quiet test/no_prompt_by_default.ts",
|
||||
exit_code: 1,
|
||||
output: "test/no_prompt_by_default.out",
|
||||
});
|
||||
|
||||
itest!(no_prompt_with_denied_perms {
|
||||
args: "test --quiet --allow-read test/no_prompt_with_denied_perms.ts",
|
||||
exit_code: 1,
|
||||
output: "test/no_prompt_with_denied_perms.out",
|
||||
});
|
||||
|
||||
itest!(test_with_custom_jsx {
|
||||
args: "test --quiet --allow-read test/hello_world.ts --config=test/deno_custom_jsx.json",
|
||||
exit_code: 0,
|
||||
output: "test/hello_world.out",
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn captured_output() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--allow-run")
|
||||
.arg("--allow-read")
|
||||
.arg("--unstable")
|
||||
.arg("test/captured_output.ts")
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
|
||||
let output_start = "------- output -------";
|
||||
let output_end = "----- output end -----";
|
||||
assert!(output.status.success());
|
||||
let output_text = String::from_utf8(output.stdout).unwrap();
|
||||
let start = output_text.find(output_start).unwrap() + output_start.len();
|
||||
let end = output_text.find(output_end).unwrap();
|
||||
// replace zero width space that may appear in test output due
|
||||
// to test runner output flusher
|
||||
let output_text = output_text[start..end]
|
||||
.replace('\u{200B}', "")
|
||||
.trim()
|
||||
.to_string();
|
||||
let mut lines = output_text.lines().collect::<Vec<_>>();
|
||||
// the output is racy on either stdout or stderr being flushed
|
||||
// from the runtime into the rust code, so sort it... the main
|
||||
// thing here to ensure is that we're capturing the output in
|
||||
// this block on stdout
|
||||
lines.sort_unstable();
|
||||
assert_eq!(lines.join(" "), "0 1 2 3 4 5 6 7 8 9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recursive_permissions_pledge() {
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("test/recursive_permissions_pledge.js")
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert!(String::from_utf8(output.stderr).unwrap().contains(
|
||||
"pledge test permissions called before restoring previous pledge"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_protocol() {
|
||||
let file_url =
|
||||
Url::from_file_path(util::testdata_path().join("test/file_protocol.ts"))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
(util::CheckOutputIntegrationTest {
|
||||
args_vec: vec!["test", &file_url],
|
||||
exit_code: 0,
|
||||
output: "test/file_protocol.out",
|
||||
..Default::default()
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
itest!(uncaught_errors {
|
||||
args: "test --quiet test/uncaught_errors_1.ts test/uncaught_errors_2.ts test/uncaught_errors_3.ts",
|
||||
output: "test/uncaught_errors.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default {
|
||||
args: "test --quiet test/check_local_by_default.ts",
|
||||
output: "test/check_local_by_default.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(check_local_by_default2 {
|
||||
args: "test --quiet test/check_local_by_default2.ts",
|
||||
output: "test/check_local_by_default2.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(non_error_thrown {
|
||||
args: "test --quiet test/non_error_thrown.ts",
|
||||
output: "test/non_error_thrown.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(parallel_output {
|
||||
args: "test --parallel --reload test/parallel_output.ts",
|
||||
output: "test/parallel_output.out",
|
||||
exit_code: 1,
|
||||
});
|
|
@ -1,193 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::process::{Command, Stdio};
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_in_tmpdir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
let status = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--force")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
// TODO(ry) assert!(mtime1 < mtime2);
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_with_space_in_path() {
|
||||
let temp_dir = TempDir::new_with_prefix("directory with spaces");
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let status = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--force")
|
||||
.env("TMP", temp_dir.path())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_with_version_in_tmpdir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
let status = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--force")
|
||||
.arg("--version")
|
||||
.arg("1.11.5")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let upgraded_deno_version = String::from_utf8(
|
||||
Command::new(&exe_path).arg("-V").output().unwrap().stdout,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(upgraded_deno_version.contains("1.11.5"));
|
||||
let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
// TODO(ry) assert!(mtime1 < mtime2);
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_with_canary_in_tmpdir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
let status = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--canary")
|
||||
.arg("--version")
|
||||
.arg("e6685f0f01b8a11a5eaff020f5babcfde76b3038")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let upgraded_deno_version = String::from_utf8(
|
||||
Command::new(&exe_path).arg("-V").output().unwrap().stdout,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(upgraded_deno_version.contains("e6685f0"));
|
||||
let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
// TODO(ry) assert!(mtime1 < mtime2);
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_with_out_in_tmpdir() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let new_exe_path = temp_dir.path().join("foo");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
let status = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--version")
|
||||
.arg("1.11.5")
|
||||
.arg("--output")
|
||||
.arg(new_exe_path.to_str().unwrap())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
assert!(new_exe_path.exists());
|
||||
let mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
|
||||
assert_eq!(mtime1, mtime2); // Original exe_path was not changed.
|
||||
|
||||
let v = String::from_utf8(
|
||||
Command::new(&new_exe_path)
|
||||
.arg("-V")
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(v.contains("1.11.5"));
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_invalid_stable_version() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let output = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--version")
|
||||
.arg("foobar")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
"error: Invalid semver passed\n",
|
||||
util::strip_ansi_codes(&String::from_utf8(output.stderr).unwrap())
|
||||
);
|
||||
}
|
||||
|
||||
// Warning: this test requires internet access.
|
||||
// TODO(#7412): reenable. test is flaky
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn upgrade_invalid_canary_version() {
|
||||
let temp_dir = TempDir::new();
|
||||
let exe_path = temp_dir.path().join("deno");
|
||||
let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
|
||||
assert!(exe_path.exists());
|
||||
let output = Command::new(&exe_path)
|
||||
.arg("upgrade")
|
||||
.arg("--canary")
|
||||
.arg("--version")
|
||||
.arg("foobar")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(!output.status.success());
|
||||
assert_eq!(
|
||||
"error: Invalid commit hash passed\n",
|
||||
util::strip_ansi_codes(&String::from_utf8(output.stderr).unwrap())
|
||||
);
|
||||
}
|
|
@ -1,574 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Stdio;
|
||||
use test_util as util;
|
||||
use test_util::TempDir;
|
||||
use util::http_server;
|
||||
use util::new_deno_dir;
|
||||
|
||||
#[test]
|
||||
fn output_dir_exists() {
|
||||
let t = TempDir::new();
|
||||
t.write("mod.ts", "");
|
||||
t.create_dir_all("vendor");
|
||||
t.write("vendor/mod.ts", "");
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
concat!(
|
||||
"error: Output directory was not empty. Please specify an empty ",
|
||||
"directory or use --force to ignore this error and potentially ",
|
||||
"overwrite its contents.",
|
||||
),
|
||||
);
|
||||
assert!(!output.status.success());
|
||||
|
||||
// ensure it errors when using the `--output` arg too
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("--output")
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
concat!(
|
||||
"error: Output directory was not empty. Please specify an empty ",
|
||||
"directory or use --force to ignore this error and potentially ",
|
||||
"overwrite its contents.",
|
||||
),
|
||||
);
|
||||
assert!(!output.status.success());
|
||||
|
||||
// now use `--force`
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.arg("--force")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standard_test() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
let vendor_dir = t.path().join("vendor2");
|
||||
t.write(
|
||||
"my_app.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/query_reexport.ts?testing'; new Logger().log('outputted');",
|
||||
);
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.arg("vendor")
|
||||
.arg("my_app.ts")
|
||||
.arg("--output")
|
||||
.arg("vendor2")
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
concat!(
|
||||
"Download http://localhost:4545/vendor/query_reexport.ts?testing\n",
|
||||
"Download http://localhost:4545/vendor/logger.ts?test\n",
|
||||
"{}",
|
||||
),
|
||||
success_text("2 modules", "vendor2", true),
|
||||
)
|
||||
);
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
|
||||
assert!(output.status.success());
|
||||
|
||||
assert!(vendor_dir.exists());
|
||||
assert!(!t.path().join("vendor").exists());
|
||||
let import_map: serde_json::Value =
|
||||
serde_json::from_str(&t.read_to_string("vendor2/import_map.json")).unwrap();
|
||||
assert_eq!(
|
||||
import_map,
|
||||
json!({
|
||||
"imports": {
|
||||
"http://localhost:4545/vendor/query_reexport.ts?testing": "./localhost_4545/vendor/query_reexport.ts",
|
||||
"http://localhost:4545/": "./localhost_4545/",
|
||||
},
|
||||
"scopes": {
|
||||
"./localhost_4545/": {
|
||||
"./localhost_4545/vendor/logger.ts?test": "./localhost_4545/vendor/logger.ts"
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// try running the output with `--no-remote`
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("--no-remote")
|
||||
.arg("--check")
|
||||
.arg("--quiet")
|
||||
.arg("--import-map")
|
||||
.arg("vendor2/import_map.json")
|
||||
.arg("my_app.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), "");
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_map_output_dir() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
t.write("mod.ts", "");
|
||||
t.create_dir_all("vendor");
|
||||
t.write(
|
||||
"vendor/import_map.json",
|
||||
// will be ignored
|
||||
"{ \"imports\": { \"https://localhost:4545/\": \"./localhost/\" }}",
|
||||
);
|
||||
t.write(
|
||||
"deno.json",
|
||||
"{ \"import_map\": \"./vendor/import_map.json\" }",
|
||||
);
|
||||
t.write(
|
||||
"my_app.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/logger.ts'; new Logger().log('outputted');",
|
||||
);
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("--force")
|
||||
.arg("--import-map")
|
||||
.arg("vendor/import_map.json")
|
||||
.arg("my_app.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
concat!(
|
||||
"Ignoring import map. Specifying an import map file ({}) in the deno ",
|
||||
"vendor output directory is not supported. If you wish to use an ",
|
||||
"import map while vendoring, please specify one located outside this ",
|
||||
"directory.\n",
|
||||
"Download http://localhost:4545/vendor/logger.ts\n",
|
||||
"{}",
|
||||
),
|
||||
PathBuf::from("vendor").join("import_map.json").display(),
|
||||
success_text_updated_deno_json("1 module", "vendor/"),
|
||||
)
|
||||
);
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_module_test() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
let vendor_dir = t.path().join("vendor");
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("http://localhost:4545/vendor/query_reexport.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
concat!(
|
||||
"Download http://localhost:4545/vendor/query_reexport.ts\n",
|
||||
"Download http://localhost:4545/vendor/logger.ts?test\n",
|
||||
"{}",
|
||||
),
|
||||
success_text("2 modules", "vendor/", true),
|
||||
)
|
||||
);
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
|
||||
assert!(output.status.success());
|
||||
assert!(vendor_dir.exists());
|
||||
assert!(vendor_dir
|
||||
.join("localhost_4545/vendor/query_reexport.ts")
|
||||
.exists());
|
||||
assert!(vendor_dir.join("localhost_4545/vendor/logger.ts").exists());
|
||||
let import_map: serde_json::Value =
|
||||
serde_json::from_str(&t.read_to_string("vendor/import_map.json")).unwrap();
|
||||
assert_eq!(
|
||||
import_map,
|
||||
json!({
|
||||
"imports": {
|
||||
"http://localhost:4545/": "./localhost_4545/",
|
||||
},
|
||||
"scopes": {
|
||||
"./localhost_4545/": {
|
||||
"./localhost_4545/vendor/logger.ts?test": "./localhost_4545/vendor/logger.ts",
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn existing_import_map_no_remote() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
t.write(
|
||||
"mod.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/logger.ts';",
|
||||
);
|
||||
let import_map_filename = "imports2.json";
|
||||
let import_map_text =
|
||||
r#"{ "imports": { "http://localhost:4545/vendor/": "./logger/" } }"#;
|
||||
t.write(import_map_filename, import_map_text);
|
||||
t.create_dir_all("logger");
|
||||
t.write("logger/logger.ts", "export class Logger {}");
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.arg("--import-map")
|
||||
.arg(import_map_filename)
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
success_text("0 modules", "vendor/", false)
|
||||
);
|
||||
assert!(output.status.success());
|
||||
// it should not have found any remote dependencies because
|
||||
// the provided import map mapped it to a local directory
|
||||
assert_eq!(t.read_to_string(import_map_filename), import_map_text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn existing_import_map_mixed_with_remote() {
|
||||
let _server = http_server();
|
||||
let deno_dir = new_deno_dir();
|
||||
let t = TempDir::new();
|
||||
t.write(
|
||||
"mod.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/logger.ts';",
|
||||
);
|
||||
|
||||
let status = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.current_dir(t.path())
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
|
||||
assert_eq!(
|
||||
t.read_to_string("vendor/import_map.json"),
|
||||
r#"{
|
||||
"imports": {
|
||||
"http://localhost:4545/": "./localhost_4545/"
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
// make the import map specific to support vendoring mod.ts in the next step
|
||||
t.write(
|
||||
"vendor/import_map.json",
|
||||
r#"{
|
||||
"imports": {
|
||||
"http://localhost:4545/vendor/logger.ts": "./localhost_4545/vendor/logger.ts"
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
t.write(
|
||||
"mod.ts",
|
||||
concat!(
|
||||
"import {Logger} from 'http://localhost:4545/vendor/logger.ts';\n",
|
||||
"import {Logger as OtherLogger} from 'http://localhost:4545/vendor/mod.ts';\n",
|
||||
),
|
||||
);
|
||||
|
||||
// now vendor with the existing import map in a separate vendor directory
|
||||
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||
.env("NO_COLOR", "1")
|
||||
.current_dir(t.path())
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.arg("--import-map")
|
||||
.arg("vendor/import_map.json")
|
||||
.arg("--output")
|
||||
.arg("vendor2")
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
concat!("Download http://localhost:4545/vendor/mod.ts\n", "{}",),
|
||||
success_text("1 module", "vendor2", true),
|
||||
)
|
||||
);
|
||||
assert!(output.status.success());
|
||||
|
||||
// tricky scenario here where the output directory now contains a mapping
|
||||
// back to the previous vendor location
|
||||
assert_eq!(
|
||||
t.read_to_string("vendor2/import_map.json"),
|
||||
r#"{
|
||||
"imports": {
|
||||
"http://localhost:4545/vendor/logger.ts": "../vendor/localhost_4545/vendor/logger.ts",
|
||||
"http://localhost:4545/": "./localhost_4545/"
|
||||
},
|
||||
"scopes": {
|
||||
"./localhost_4545/": {
|
||||
"./localhost_4545/vendor/logger.ts": "../vendor/localhost_4545/vendor/logger.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
// ensure it runs
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.arg("run")
|
||||
.arg("--check")
|
||||
.arg("--no-remote")
|
||||
.arg("--import-map")
|
||||
.arg("vendor2/import_map.json")
|
||||
.arg("mod.ts")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dynamic_import() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
t.write(
|
||||
"mod.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/dynamic.ts'; new Logger().log('outputted');",
|
||||
);
|
||||
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.arg("vendor")
|
||||
.arg("mod.ts")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
let import_map: serde_json::Value =
|
||||
serde_json::from_str(&t.read_to_string("vendor/import_map.json")).unwrap();
|
||||
assert_eq!(
|
||||
import_map,
|
||||
json!({
|
||||
"imports": {
|
||||
"http://localhost:4545/": "./localhost_4545/",
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// try running the output with `--no-remote`
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("--allow-read=.")
|
||||
.arg("--no-remote")
|
||||
.arg("--check")
|
||||
.arg("--quiet")
|
||||
.arg("--import-map")
|
||||
.arg("vendor/import_map.json")
|
||||
.arg("mod.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), "");
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dynamic_non_analyzable_import() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
t.write(
|
||||
"mod.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/dynamic_non_analyzable.ts'; new Logger().log('outputted');",
|
||||
);
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("vendor")
|
||||
.arg("--reload")
|
||||
.arg("mod.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
// todo(https://github.com/denoland/deno_graph/issues/138): it should warn about
|
||||
// how it couldn't analyze the dynamic import
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
"Download http://localhost:4545/vendor/dynamic_non_analyzable.ts\n{}",
|
||||
success_text("1 module", "vendor/", true),
|
||||
)
|
||||
);
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_existing_config_test() {
|
||||
let _server = http_server();
|
||||
let t = TempDir::new();
|
||||
t.write(
|
||||
"my_app.ts",
|
||||
"import {Logger} from 'http://localhost:4545/vendor/logger.ts'; new Logger().log('outputted');",
|
||||
);
|
||||
t.write("deno.json", "{\n}");
|
||||
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.arg("vendor")
|
||||
.arg("my_app.ts")
|
||||
.arg("--output")
|
||||
.arg("vendor2")
|
||||
.env("NO_COLOR", "1")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
format!(
|
||||
"Download http://localhost:4545/vendor/logger.ts\n{}",
|
||||
success_text_updated_deno_json("1 module", "vendor2",)
|
||||
)
|
||||
);
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
|
||||
assert!(output.status.success());
|
||||
|
||||
// try running the output with `--no-remote` and not specifying a `--vendor`
|
||||
let deno = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("run")
|
||||
.arg("--no-remote")
|
||||
.arg("--check")
|
||||
.arg("--quiet")
|
||||
.arg("my_app.ts")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = deno.wait_with_output().unwrap();
|
||||
assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), "");
|
||||
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
fn success_text(module_count: &str, dir: &str, has_import_map: bool) -> String {
|
||||
let mut text = format!("Vendored {} into {} directory.", module_count, dir);
|
||||
if has_import_map {
|
||||
let f = format!(
|
||||
concat!(
|
||||
"\n\nTo use vendored modules, specify the `--import-map {}import_map.json` flag when ",
|
||||
r#"invoking Deno subcommands or add an `"importMap": "<path_to_vendored_import_map>"` "#,
|
||||
"entry to a deno.json file.",
|
||||
),
|
||||
if dir != "vendor/" {
|
||||
format!("{}{}", dir.trim_end_matches('/'), if cfg!(windows) { '\\' } else {'/'})
|
||||
} else {
|
||||
dir.to_string()
|
||||
}
|
||||
);
|
||||
write!(text, "{}", f).unwrap();
|
||||
}
|
||||
text
|
||||
}
|
||||
|
||||
fn success_text_updated_deno_json(module_count: &str, dir: &str) -> String {
|
||||
format!(
|
||||
concat!(
|
||||
"Vendored {} into {} directory.\n\n",
|
||||
"Updated your local Deno configuration file with a reference to the ",
|
||||
"new vendored import map at {}import_map.json. Invoking Deno subcommands will ",
|
||||
"now automatically resolve using the vendored modules. You may override ",
|
||||
"this by providing the `--import-map <other-import-map>` flag or by ",
|
||||
"manually editing your Deno configuration file.",
|
||||
),
|
||||
module_count,
|
||||
dir,
|
||||
if dir != "vendor/" {
|
||||
format!(
|
||||
"{}{}",
|
||||
dir.trim_end_matches('/'),
|
||||
if cfg!(windows) { '\\' } else { '/' }
|
||||
)
|
||||
} else {
|
||||
dir.to_string()
|
||||
}
|
||||
)
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,112 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::itest;
|
||||
|
||||
itest!(workers {
|
||||
args: "test --reload --location http://127.0.0.1:4545/ -A --unstable workers/test.ts",
|
||||
output: "workers/test.ts.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
itest!(worker_error {
|
||||
args: "run -A workers/worker_error.ts",
|
||||
output: "workers/worker_error.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_nested_error {
|
||||
args: "run -A workers/worker_nested_error.ts",
|
||||
output: "workers/worker_nested_error.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_async_error {
|
||||
args: "run -A --quiet --reload workers/worker_async_error.ts",
|
||||
output: "workers/worker_async_error.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_message_handler_error {
|
||||
args: "run -A --quiet --reload workers/worker_message_handler_error.ts",
|
||||
output: "workers/worker_message_handler_error.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(nonexistent_worker {
|
||||
args: "run --allow-read workers/nonexistent_worker.ts",
|
||||
output: "workers/nonexistent_worker.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(_084_worker_custom_inspect {
|
||||
args: "run --allow-read workers/custom_inspect/main.ts",
|
||||
output: "workers/custom_inspect/main.out",
|
||||
});
|
||||
|
||||
itest!(error_worker_permissions_local {
|
||||
args: "run --reload workers/error_worker_permissions_local.ts",
|
||||
output: "workers/error_worker_permissions_local.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(error_worker_permissions_remote {
|
||||
args: "run --reload workers/error_worker_permissions_remote.ts",
|
||||
http_server: true,
|
||||
output: "workers/error_worker_permissions_remote.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_remote_remote {
|
||||
args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_remote_remote.ts",
|
||||
output: "workers/permissions_remote_remote.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_dynamic_remote {
|
||||
args: "run --quiet --reload --allow-net --unstable workers/permissions_dynamic_remote.ts",
|
||||
output: "workers/permissions_dynamic_remote.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_data_remote {
|
||||
args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_remote.ts",
|
||||
output: "workers/permissions_data_remote.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_blob_remote {
|
||||
args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_remote.ts",
|
||||
output: "workers/permissions_blob_remote.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_data_local {
|
||||
args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_local.ts",
|
||||
output: "workers/permissions_data_local.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_permissions_blob_local {
|
||||
args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_local.ts",
|
||||
output: "workers/permissions_blob_local.ts.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(worker_terminate_tla_crash {
|
||||
args: "run --quiet --reload workers/terminate_tla_crash.js",
|
||||
output: "workers/terminate_tla_crash.js.out",
|
||||
});
|
||||
|
||||
itest!(worker_error_event {
|
||||
args: "run --quiet -A workers/error_event.ts",
|
||||
output: "workers/error_event.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue