diff options
Diffstat (limited to 'cli/tests')
-rw-r--r-- | cli/tests/integration/mod.rs | 2 | ||||
-rw-r--r-- | cli/tests/integration/vendor_tests.rs | 372 | ||||
-rw-r--r-- | cli/tests/testdata/vendor/dynamic.ts | 3 | ||||
-rw-r--r-- | cli/tests/testdata/vendor/dynamic_non_analyzable.ts | 4 | ||||
-rw-r--r-- | cli/tests/testdata/vendor/logger.ts | 5 | ||||
-rw-r--r-- | cli/tests/testdata/vendor/query_reexport.ts | 1 |
6 files changed, 387 insertions, 0 deletions
diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs index cc6770472..2a1e69bd1 100644 --- a/cli/tests/integration/mod.rs +++ b/cli/tests/integration/mod.rs @@ -84,6 +84,8 @@ mod run; mod test; #[path = "upgrade_tests.rs"] mod upgrade; +#[path = "vendor_tests.rs"] +mod vendor; #[path = "watcher_tests.rs"] mod watcher; #[path = "worker_tests.rs"] diff --git a/cli/tests/integration/vendor_tests.rs b/cli/tests/integration/vendor_tests.rs new file mode 100644 index 000000000..4aa883a7e --- /dev/null +++ b/cli/tests/integration/vendor_tests.rs @@ -0,0 +1,372 @@ +// 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::fs; +use std::path::PathBuf; +use std::process::Stdio; +use tempfile::TempDir; +use test_util as util; +use util::http_server; + +#[test] +fn output_dir_exists() { + let t = TempDir::new().unwrap(); + let vendor_dir = t.path().join("vendor"); + fs::write(t.path().join("mod.ts"), "").unwrap(); + fs::create_dir_all(&vendor_dir).unwrap(); + fs::write(vendor_dir.join("mod.ts"), "").unwrap(); + + 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 import_map_output_dir() { + let t = TempDir::new().unwrap(); + let vendor_dir = t.path().join("vendor"); + fs::write(t.path().join("mod.ts"), "").unwrap(); + fs::create_dir_all(&vendor_dir).unwrap(); + let import_map_path = vendor_dir.join("import_map.json"); + fs::write( + &import_map_path, + "{ \"imports\": { \"https://localhost/\": \"./localhost/\" }}", + ) + .unwrap(); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("--force") + .arg("--import-map") + .arg(import_map_path) + .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(), + "error: Using an import map found in the output directory is not supported.", + ); + assert!(!output.status.success()); +} + +#[test] +fn standard_test() { + let _server = http_server(); + let t = TempDir::new().unwrap(); + let vendor_dir = t.path().join("vendor2"); + fs::write( + t.path().join("my_app.ts"), + "import {Logger} from 'http://localhost:4545/vendor/query_reexport.ts?testing'; new Logger().log('outputted');", + ).unwrap(); + + 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", "my_app.ts"), + ) + ); + 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( + &fs::read_to_string(vendor_dir.join("import_map.json")).unwrap(), + ) + .unwrap(); + assert_eq!( + import_map, + json!({ + "imports": { + "http://localhost:4545/": "./localhost_4545/", + "http://localhost:4545/vendor/query_reexport.ts?testing": "./localhost_4545/vendor/query_reexport.ts", + }, + "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("--no-check") + .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 remote_module_test() { + let _server = http_server(); + let t = TempDir::new().unwrap(); + 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/", "main.ts"), + ) + ); + 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( + &fs::read_to_string(vendor_dir.join("import_map.json")).unwrap(), + ) + .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() { + let _server = http_server(); + let t = TempDir::new().unwrap(); + let vendor_dir = t.path().join("vendor"); + fs::write( + t.path().join("mod.ts"), + "import {Logger} from 'http://localhost:4545/vendor/logger.ts';", + ) + .unwrap(); + fs::write( + t.path().join("imports.json"), + r#"{ "imports": { "http://localhost:4545/vendor/": "./logger/" } }"#, + ) + .unwrap(); + fs::create_dir(t.path().join("logger")).unwrap(); + fs::write(t.path().join("logger/logger.ts"), "export class Logger {}") + .unwrap(); + + let status = util::deno_cmd() + .current_dir(t.path()) + .arg("vendor") + .arg("mod.ts") + .arg("--import-map") + .arg("imports.json") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + // it should not have found any remote dependencies because + // the provided import map mapped it to a local directory + assert!(!vendor_dir.join("import_map.json").exists()); +} + +#[test] +fn dynamic_import() { + let _server = http_server(); + let t = TempDir::new().unwrap(); + let vendor_dir = t.path().join("vendor"); + fs::write( + t.path().join("mod.ts"), + "import {Logger} from 'http://localhost:4545/vendor/dynamic.ts'; new Logger().log('outputted');", + ).unwrap(); + + 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( + &fs::read_to_string(vendor_dir.join("import_map.json")).unwrap(), + ) + .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("--no-check") + .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().unwrap(); + fs::write( + t.path().join("mod.ts"), + "import {Logger} from 'http://localhost:4545/vendor/dynamic_non_analyzable.ts'; new Logger().log('outputted');", + ).unwrap(); + + 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/", "mod.ts"), + ) + ); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), ""); + assert!(output.status.success()); +} + +fn success_text(module_count: &str, dir: &str, entry_point: &str) -> String { + format!( + concat!( + "Vendored {} into {} directory.\n\n", + "To use vendored modules, specify the `--import-map` flag when invoking deno subcommands:\n", + " deno run -A --import-map {} {}" + ), + module_count, + dir, + PathBuf::from(dir).join("import_map.json").display(), + entry_point, + ) +} diff --git a/cli/tests/testdata/vendor/dynamic.ts b/cli/tests/testdata/vendor/dynamic.ts new file mode 100644 index 000000000..e2cbb0e59 --- /dev/null +++ b/cli/tests/testdata/vendor/dynamic.ts @@ -0,0 +1,3 @@ +const { Logger } = await import("./logger.ts"); + +export { Logger }; diff --git a/cli/tests/testdata/vendor/dynamic_non_analyzable.ts b/cli/tests/testdata/vendor/dynamic_non_analyzable.ts new file mode 100644 index 000000000..1847939f6 --- /dev/null +++ b/cli/tests/testdata/vendor/dynamic_non_analyzable.ts @@ -0,0 +1,4 @@ +const value = (() => "./logger.ts")(); +const { Logger } = await import(value); + +export { Logger }; diff --git a/cli/tests/testdata/vendor/logger.ts b/cli/tests/testdata/vendor/logger.ts new file mode 100644 index 000000000..97f603a48 --- /dev/null +++ b/cli/tests/testdata/vendor/logger.ts @@ -0,0 +1,5 @@ +export class Logger { + log(text: string) { + console.log(text); + } +} diff --git a/cli/tests/testdata/vendor/query_reexport.ts b/cli/tests/testdata/vendor/query_reexport.ts new file mode 100644 index 000000000..5dfafb532 --- /dev/null +++ b/cli/tests/testdata/vendor/query_reexport.ts @@ -0,0 +1 @@ +export * from "./logger.ts?test"; |