1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

tests: move integration tests to a single module (#17380)

Effectively reverts changes done in
https://github.com/denoland/deno/pull/16816
This commit is contained in:
Bartek Iwańczuk 2023-01-13 02:59:13 +01:00 committed by GitHub
parent 919a0cd679
commit 9e282155b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 20223 additions and 20345 deletions

View file

@ -1,218 +0,0 @@
// Copyright 2018-2023 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,
});
itest!(bench_with_config {
args: "bench --config bench/collect/deno.jsonc bench/collect",
exit_code: 0,
output: "bench/collect.out",
});
itest!(bench_with_config2 {
args: "bench --config bench/collect/deno2.jsonc bench/collect",
exit_code: 0,
output: "bench/collect2.out",
});
itest!(bench_with_malformed_config {
args: "bench --config bench/collect/deno.malformed.jsonc",
exit_code: 1,
output: "bench/collect_with_malformed_config.out",
});
#[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();
}
}

View file

@ -1,478 +0,0 @@
// Copyright 2018-2023 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,
});
itest!(bundle_shebang_file {
args: "bundle subdir/shebang_file.js",
output: "bundle/shebang_file.bundle.out",
});
}

View file

@ -1,102 +0,0 @@
// Copyright 2018-2023 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",
});
}

View file

@ -1,321 +0,0 @@
// Copyright 2018-2023 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;
}
}

View file

@ -1,224 +0,0 @@
// Copyright 2018-2023 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,
});
itest!(check_static_response_json {
args: "check --quiet check/response_json.ts",
exit_code: 0,
});
itest!(check_no_error_truncation {
args: "check --quiet check/no_error_truncation/main.ts --config check/no_error_truncation/deno.json",
output: "check/no_error_truncation/main.out",
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
exit_code: 1,
});
#[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());
}
}

View file

@ -1,569 +0,0 @@
// Copyright 2018-2023 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());
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]
fn standalone_import_map_config_file() {
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("--config")
.arg("compile/standalone_import_map_config.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"'."#
));
}
}

View file

@ -1,382 +0,0 @@
// Copyright 2018-2023 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());
}
}

View file

@ -1,79 +0,0 @@
// Copyright 2018-2023 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,
});
}

View file

@ -1,86 +0,0 @@
// Copyright 2018-2023 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,
});
}

View file

@ -1,50 +0,0 @@
// Copyright 2018-2023 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",
});
}

View file

@ -1,257 +0,0 @@
// Copyright 2018-2023 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,
});
}

View file

@ -1,135 +0,0 @@
// Copyright 2018-2023 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();
// 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",
});
}

View file

@ -1,209 +0,0 @@
// Copyright 2018-2023 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 task dev");
assert_contains!(stderr, "deno test");
assert_contains!(stderr, "deno bench");
assert!(cwd.join("deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}
#[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 task dev");
assert_contains!(stderr, "deno test");
assert_contains!(stderr, "deno bench");
assert!(cwd.join("my_dir/deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.arg("my_dir/main_bench.ts")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}
#[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, "");
assert!(cwd.join("deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,247 +0,0 @@
// Copyright 2018-2023 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();
// ensure a lockfile doesn't get created or updated locally
temp_dir.write("deno.json", "{}");
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());
// no lockfile should be created locally
assert!(!temp_dir.path().join("deno.lock").exists());
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" "--no-config" "http://localhost:4545/echo.ts""#
);
} else {
assert_contains!(
content,
r#"run --check --no-config 'http://localhost:4545/echo.ts'"#
);
}
// now uninstall
let status = util::deno_cmd()
.current_dir(temp_dir.path())
.arg("uninstall")
.arg("echo_test")
.envs([
("HOME", temp_dir_str.as_str()),
("USERPROFILE", temp_dir_str.as_str()),
("DENO_INSTALL_ROOT", ""),
])
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
// ensure local lockfile still doesn't exist
assert!(!temp_dir.path().join("deno.lock").exists());
// ensure uninstall occurred
assert!(!file_path.exists());
}
#[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" "--no-config" "http://localhost:4545/echo.ts""#
);
} else {
assert_contains!(
content,
r#"run --check --no-config '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());
}
}

View file

@ -0,0 +1,212 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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,
});
itest!(bench_with_config {
args: "bench --config bench/collect/deno.jsonc bench/collect",
exit_code: 0,
output: "bench/collect.out",
});
itest!(bench_with_config2 {
args: "bench --config bench/collect/deno2.jsonc bench/collect",
exit_code: 0,
output: "bench/collect2.out",
});
itest!(bench_with_malformed_config {
args: "bench --config bench/collect/deno.malformed.jsonc",
exit_code: 1,
output: "bench/collect_with_malformed_config.out",
});
#[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();
}

View file

@ -0,0 +1,472 @@
// Copyright 2018-2023 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::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,
});
itest!(bundle_shebang_file {
args: "bundle subdir/shebang_file.js",
output: "bundle/shebang_file.bundle.out",
});

View file

@ -0,0 +1,97 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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",
});

View file

@ -0,0 +1,315 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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;
}

View file

@ -0,0 +1,219 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::process::Command;
use std::process::Stdio;
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 --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,
});
itest!(check_static_response_json {
args: "check --quiet check/response_json.ts",
exit_code: 0,
});
itest!(check_no_error_truncation {
args: "check --quiet check/no_error_truncation/main.ts --config check/no_error_truncation/deno.json",
output: "check/no_error_truncation/main.out",
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
exit_code: 1,
});
#[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());
}

View file

@ -0,0 +1,566 @@
// Copyright 2018-2023 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());
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]
fn standalone_import_map_config_file() {
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("--config")
.arg("compile/standalone_import_map_config.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"'."#
));
}

View file

@ -0,0 +1,376 @@
// Copyright 2018-2023 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");
}
#[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());
}

View file

@ -0,0 +1,72 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use test_util as util;
use test_util::TempDir;
use util::assert_contains;
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,
});

View file

@ -0,0 +1,79 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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,
});

View file

@ -0,0 +1,44 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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",
});

View file

@ -0,0 +1,247 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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,
});

View file

@ -0,0 +1,129 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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();
// 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",
});

View file

@ -0,0 +1,205 @@
// Copyright 2018-2023 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 task dev");
assert_contains!(stderr, "deno test");
assert_contains!(stderr, "deno bench");
assert!(cwd.join("deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}
#[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 task dev");
assert_contains!(stderr, "deno test");
assert_contains!(stderr, "deno bench");
assert!(cwd.join("my_dir/deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.arg("my_dir/main_bench.ts")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}
#[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, "");
assert!(cwd.join("deno.jsonc").exists());
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");
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
let output = deno_cmd
.current_dir(cwd)
.env("NO_COLOR", "1")
.arg("bench")
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,243 @@
// Copyright 2018-2023 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();
// ensure a lockfile doesn't get created or updated locally
temp_dir.write("deno.json", "{}");
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());
// no lockfile should be created locally
assert!(!temp_dir.path().join("deno.lock").exists());
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" "--no-config" "http://localhost:4545/echo.ts""#
);
} else {
assert_contains!(
content,
r#"run --check --no-config 'http://localhost:4545/echo.ts'"#
);
}
// now uninstall
let status = util::deno_cmd()
.current_dir(temp_dir.path())
.arg("uninstall")
.arg("echo_test")
.envs([
("HOME", temp_dir_str.as_str()),
("USERPROFILE", temp_dir_str.as_str()),
("DENO_INSTALL_ROOT", ""),
])
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
// ensure local lockfile still doesn't exist
assert!(!temp_dir.path().join("deno.lock").exists());
// ensure uninstall occurred
assert!(!file_path.exists());
}
#[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" "--no-config" "http://localhost:4545/echo.ts""#
);
} else {
assert_contains!(
content,
r#"run --check --no-config '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());
}

View file

@ -0,0 +1,39 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use test_util as util;
#[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());
}

View file

@ -0,0 +1,132 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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

View file

@ -29,3 +29,62 @@ 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 = "js_unit_tests.rs"]
mod js_unit_tests;
#[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;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,959 @@
// Copyright 2018-2023 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() {
for right_brace in &[")", "]", "}"] {
util::with_pty(&["repl"], |mut console| {
console.write_line(right_brace);
console.write_line("close();");
let output = console.read_all_output();
assert_contains!(output, "Expression expected");
});
}
}
#[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", "-A"], |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 any (it's flaky)
"\ntesting output",
"testing output\u{1b}",
"\r\n\u{1b}[?25htesting output",
);
});
// ensure when the directory changes that the suggestions come from the cwd
util::with_pty(&["repl", "-A"], |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_with_args(
true,
vec![],
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_with_args(
true,
vec!["repl", "--allow-read"],
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, "Expression expected");
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, "Expression expected");
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", "--allow-read", "--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());
}
#[test]
fn repl_with_quiet_flag() {
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet"],
Some(vec!["await Promise.resolve('done')"]),
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
false,
);
assert!(!out.contains("Deno"));
assert!(!out.contains("exit using ctrl+d, ctrl+c, or close()"));
assert_ends_with!(out, "\"done\"\n");
assert!(err.is_empty());
}
#[test]
fn npm_packages() {
let mut env_vars = util::env_vars_for_npm_tests();
env_vars.push(("NO_COLOR".to_owned(), "1".to_owned()));
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![
r#"import chalk from "npm:chalk";"#,
"chalk.red('hel' + 'lo')",
]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "hello");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![
r#"const chalk = await import("npm:chalk");"#,
"chalk.default.red('hel' + 'lo')",
]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "hello");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![r#"export {} from "npm:chalk";"#]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "Module {");
assert_contains!(out, "Chalk: [Function: Chalk],");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![r#"import foo from "npm:asdfawe52345asdf""#]),
Some(env_vars),
true,
);
assert_contains!(
out,
"error: npm package 'asdfawe52345asdf' does not exist"
);
assert!(err.is_empty());
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,130 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// 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())],
});

View file

@ -0,0 +1,454 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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",
});
itest!(trace_ops_catch_error {
args: "test -A --trace-ops test/trace_ops_caught_error/main.ts",
exit_code: 0,
output: "test/trace_ops_caught_error/main.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,
});

View file

@ -0,0 +1,193 @@
// Copyright 2018-2023 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())
);
}

View file

@ -0,0 +1,574 @@
// Copyright 2018-2023 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

View file

@ -0,0 +1,110 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
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,
});

View file

@ -0,0 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// The tests exist in a sub folder instead of as separate files in
// this directory so that cargo doesn't compile each file as a new crate.
mod integration;

View file

@ -1,45 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod integration;
use test_util as util;
mod js {
use super::*;
#[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());
}
}

View file

@ -1,139 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod integration;
use test_util as util;
mod lint {
use super::*;
#[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

File diff suppressed because it is too large Load diff

View file

@ -1,966 +0,0 @@
// Copyright 2018-2023 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;
mod repl {
use super::*;
#[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() {
for right_brace in &[")", "]", "}"] {
util::with_pty(&["repl"], |mut console| {
console.write_line(right_brace);
console.write_line("close();");
let output = console.read_all_output();
assert_contains!(output, "Expression expected");
});
}
}
#[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", "-A"], |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 any (it's flaky)
"\ntesting output",
"testing output\u{1b}",
"\r\n\u{1b}[?25htesting output",
);
});
// ensure when the directory changes that the suggestions come from the cwd
util::with_pty(&["repl", "-A"], |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_with_args(
true,
vec![],
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_with_args(
true,
vec!["repl", "--allow-read"],
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, "Expression expected");
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, "Expression expected");
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", "--allow-read", "--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());
}
#[test]
fn repl_with_quiet_flag() {
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet"],
Some(vec!["await Promise.resolve('done')"]),
Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]),
false,
);
assert!(!out.contains("Deno"));
assert!(!out.contains("exit using ctrl+d, ctrl+c, or close()"));
assert_ends_with!(out, "\"done\"\n");
assert!(err.is_empty());
}
#[test]
fn npm_packages() {
let mut env_vars = util::env_vars_for_npm_tests();
env_vars.push(("NO_COLOR".to_owned(), "1".to_owned()));
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![
r#"import chalk from "npm:chalk";"#,
"chalk.red('hel' + 'lo')",
]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "hello");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![
r#"const chalk = await import("npm:chalk");"#,
"chalk.default.red('hel' + 'lo')",
]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "hello");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![r#"export {} from "npm:chalk";"#]),
Some(env_vars.clone()),
true,
);
assert_contains!(out, "Module {");
assert_contains!(out, "Chalk: [Function: Chalk],");
assert!(err.is_empty());
}
{
let (out, err) = util::run_and_collect_output_with_args(
true,
vec!["repl", "--quiet", "--allow-read", "--allow-env"],
Some(vec![r#"import foo from "npm:asdfawe52345asdf""#]),
Some(env_vars),
true,
);
assert_contains!(
out,
"error: npm package 'asdfawe52345asdf' does not exist"
);
assert!(err.is_empty());
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,136 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod integration;
// Most of the tests for this are in deno_task_shell.
// These tests are intended to only test integration.
mod task {
use super::*;
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())],
});
}

View file

@ -1,459 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod integration;
use deno_core::url::Url;
use test_util as util;
mod test {
use super::*;
#[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",
});
itest!(trace_ops_catch_error {
args: "test -A --trace-ops test/trace_ops_caught_error/main.ts",
exit_code: 0,
output: "test/trace_ops_caught_error/main.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,
});
}

View file

@ -1,197 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::process::{Command, Stdio};
use test_util as util;
use test_util::TempDir;
mod upgrade {
use super::*;
// 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())
);
}
}

View file

@ -1,583 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod vendor {
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

View file

@ -1,116 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
mod integration;
mod worker {
use super::*;
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,
});
}