diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-03-13 12:21:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-13 16:21:13 +0000 |
commit | b3ca3b2f25931afb350027bde87dc3d4f9a741b0 (patch) | |
tree | e8d4f1211310e4998cd21882b96d0a799a83de87 /tests/specs | |
parent | eccdb0e99acd66cce38fc8535aeab221a8a6fffa (diff) |
chore: rough first pass on spec tests (#22877)
Diffstat (limited to 'tests/specs')
41 files changed, 645 insertions, 0 deletions
diff --git a/tests/specs/README.md b/tests/specs/README.md new file mode 100644 index 000000000..bbd9b880c --- /dev/null +++ b/tests/specs/README.md @@ -0,0 +1,92 @@ +# specs + +These are integration tests that execute the `deno` binary. They supersede the +`itest` macro found in the `tests/integration` folder and are the preferred way +of writing tests that use the `deno` binary. + +## Structure + +Tests must have the following directory structure: + +``` +tests/specs/<category_name>/<test_name>/__test__.json +``` + +## Test filtering + +To run a specific test, run: + +``` +cargo test specs::category_name::test_name +``` + +Or just the following, though it might run other tests: + +``` +cargo test test_name +``` + +## `__test__.json` file + +This file describes the test to execute and the steps to execute. A basic +example looks like: + +```json +{ + "args": "run main.js", + "output": "main.out" +} +``` + +This will run `deno run main.js` then assert that the output matches the text in +`main.out`. + +Or another example that runs multiple steps: + +```json +{ + "tempDir": true, + "steps": [{ + "args": "cache main.ts", + "output": "cache.out" + }, { + "args": "run main.ts", + "output": "error.out", + "exitCode": 1 + }] +} +``` + +### Top level properties + +- `base` - The base config to use for the test. Options: + - `jsr` - Uses env vars for jsr. + - `npm` - Uses env vars for npm. +- `tempDir` (boolean) - Copy all the non-test files to a temporary directory and + execute the command in that temporary directory. + - By default, tests are executed with a current working directory of the test, + but this may not be desirable for tests such as ones that create a + node_modules directory. + +### Step properties + +When writing a single step, these may be at the top level rather than nested in +a "steps" array. + +- `args` - A string (that will be spilt on whitespace into an args array) or an + array of arguments. +- `output` - Path to use to assert the output. +- `clean` (boolean) - Whether to empty the deno_dir before running the step. +- `exitCode` (number) - Expected exit code. + +## `.out` files + +`.out` files are used to assert the output when running a test or test step. + +Within the file, you can use the following for matching: + +- `[WILDCARD]` - match any text at the wildcard +- `[WILDLINE]` - match any text on the current line +- `[WILDCHARS(5)]` - match any of the next 5 characters +- `[UNORDERED_START]` followed by many lines then `[UNORDERED_END]` will match + the lines in any order (useful for non-deterministic output) diff --git a/tests/specs/import_map/import_map_config/__test__.json b/tests/specs/import_map/import_map_config/__test__.json new file mode 100644 index 000000000..b0463a231 --- /dev/null +++ b/tests/specs/import_map/import_map_config/__test__.json @@ -0,0 +1,28 @@ +{ + "steps": [{ + "args": "run --quiet --reload --import-map=import_map.json test.ts", + "output": "run.out" + }, { + "args": "run --quiet --reload --import-map=import_map_invalid.json --config=config.json test.ts", + "output": "flag_has_precedence.out", + "exitCode": 1 + }, { + "args": "run --reload --config=config.json test.ts", + "output": "config.out" + }, { + "cleanDenoDir": true, + "args": "cache --quiet --reload --import-map=import_map.json test.ts", + "output": "cache.out" + }, { + "cleanDenoDir": true, + "args": "info --quiet --import-map=import_map.json test.ts", + "output": "info.out" + }, { + "args": "run --quiet --reload --import-map=import_map.json unmapped_bare_specifier.ts", + "output": "unmapped_bare_specifier.out", + "exitCode": 1 + }, { + "args": "run --quiet --reload --import-map import_map.json import_data_url.ts", + "output": "import_data_url.out" + }] +} diff --git a/tests/specs/import_map/import_map_config/cache.out b/tests/specs/import_map/import_map_config/cache.out new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/specs/import_map/import_map_config/cache.out diff --git a/tests/specs/import_map/import_map_config/config.json b/tests/specs/import_map/import_map_config/config.json new file mode 100644 index 000000000..b296a63c7 --- /dev/null +++ b/tests/specs/import_map/import_map_config/config.json @@ -0,0 +1,15 @@ +{ + "importMap": "./import_map.json", + "imports": { + "moment": "./moment/moment.ts", + "moment/": "./moment/", + "lodash": "./lodash/lodash.ts", + "lodash/": "./lodash/", + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + "scope/": { + "moment": "./scoped_moment.ts" + } + } +} diff --git a/tests/specs/import_map/import_map_config/config.out b/tests/specs/import_map/import_map_config/config.out new file mode 100644 index 000000000..72df124a2 --- /dev/null +++ b/tests/specs/import_map/import_map_config/config.out @@ -0,0 +1,8 @@ +Warning "importMap" setting is ignored when "imports" or "scopes" are specified in the config file. +Hello from remapped moment! +Hello from remapped moment dir! +Hello from remapped lodash! +Hello from remapped lodash dir! +Hello from remapped Vue! +Hello from scoped moment! +Hello from scoped! diff --git a/tests/specs/import_map/import_map_config/flag_has_precedence.out b/tests/specs/import_map/import_map_config/flag_has_precedence.out new file mode 100644 index 000000000..e9b183ee6 --- /dev/null +++ b/tests/specs/import_map/import_map_config/flag_has_precedence.out @@ -0,0 +1 @@ +error: Relative import path [WILDCARD] not prefixed with / or ./ or ../ and not in import map [WILDCARD] diff --git a/tests/specs/import_map/import_map_config/import_data_url.out b/tests/specs/import_map/import_map_config/import_data_url.out new file mode 100644 index 000000000..bfa0b9d94 --- /dev/null +++ b/tests/specs/import_map/import_map_config/import_data_url.out @@ -0,0 +1,3 @@ +a +{ "0": "A", "1": "B", "2": "C", A: 0, B: 1, C: 2 } +0 diff --git a/tests/specs/import_map/import_map_config/import_data_url.ts b/tests/specs/import_map/import_map_config/import_data_url.ts new file mode 100644 index 000000000..258514a5e --- /dev/null +++ b/tests/specs/import_map/import_map_config/import_data_url.ts @@ -0,0 +1,12 @@ +// export const a = "a"; + +// export enum A { +// A, +// B, +// C, +// } +import * as a from "data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo="; + +console.log(a.a); +console.log(a.A); +console.log(a.A.A); diff --git a/tests/specs/import_map/import_map_config/import_map.json b/tests/specs/import_map/import_map_config/import_map.json new file mode 100644 index 000000000..601874aab --- /dev/null +++ b/tests/specs/import_map/import_map_config/import_map.json @@ -0,0 +1,14 @@ +{ + "imports": { + "moment": "./moment/moment.ts", + "moment/": "./moment/", + "lodash": "./lodash/lodash.ts", + "lodash/": "./lodash/", + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + "scope/": { + "moment": "./scoped_moment.ts" + } + } +} diff --git a/tests/specs/import_map/import_map_config/import_map_invalid.json b/tests/specs/import_map/import_map_config/import_map_invalid.json new file mode 100644 index 000000000..a09d280c5 --- /dev/null +++ b/tests/specs/import_map/import_map_config/import_map_invalid.json @@ -0,0 +1,7 @@ +{ + "imports": { + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + } +} diff --git a/tests/specs/import_map/import_map_config/info.out b/tests/specs/import_map/import_map_config/info.out new file mode 100644 index 000000000..68d98f14a --- /dev/null +++ b/tests/specs/import_map/import_map_config/info.out @@ -0,0 +1,6 @@ +local: [WILDCARD]test.ts +type: TypeScript +dependencies: 7 unique +size: [WILDCARD] + +[WILDCARD] diff --git a/tests/specs/import_map/import_map_config/lodash/lodash.ts b/tests/specs/import_map/import_map_config/lodash/lodash.ts new file mode 100644 index 000000000..2ec04ed3c --- /dev/null +++ b/tests/specs/import_map/import_map_config/lodash/lodash.ts @@ -0,0 +1 @@ +console.log("Hello from remapped lodash!"); diff --git a/tests/specs/import_map/import_map_config/lodash/other_file.ts b/tests/specs/import_map/import_map_config/lodash/other_file.ts new file mode 100644 index 000000000..714adae3f --- /dev/null +++ b/tests/specs/import_map/import_map_config/lodash/other_file.ts @@ -0,0 +1 @@ +console.log("Hello from remapped lodash dir!"); diff --git a/tests/specs/import_map/import_map_config/moment/moment.ts b/tests/specs/import_map/import_map_config/moment/moment.ts new file mode 100644 index 000000000..2b54a431e --- /dev/null +++ b/tests/specs/import_map/import_map_config/moment/moment.ts @@ -0,0 +1 @@ +console.log("Hello from remapped moment!"); diff --git a/tests/specs/import_map/import_map_config/moment/other_file.ts b/tests/specs/import_map/import_map_config/moment/other_file.ts new file mode 100644 index 000000000..24f3a0226 --- /dev/null +++ b/tests/specs/import_map/import_map_config/moment/other_file.ts @@ -0,0 +1 @@ +console.log("Hello from remapped moment dir!"); diff --git a/tests/specs/import_map/import_map_config/run.out b/tests/specs/import_map/import_map_config/run.out new file mode 100644 index 000000000..e9b9160e9 --- /dev/null +++ b/tests/specs/import_map/import_map_config/run.out @@ -0,0 +1,7 @@ +Hello from remapped moment! +Hello from remapped moment dir! +Hello from remapped lodash! +Hello from remapped lodash dir! +Hello from remapped Vue! +Hello from scoped moment! +Hello from scoped! diff --git a/tests/specs/import_map/import_map_config/scope/scoped.ts b/tests/specs/import_map/import_map_config/scope/scoped.ts new file mode 100644 index 000000000..9a0b5d8e3 --- /dev/null +++ b/tests/specs/import_map/import_map_config/scope/scoped.ts @@ -0,0 +1,2 @@ +import "moment"; +console.log("Hello from scoped!"); diff --git a/tests/specs/import_map/import_map_config/scoped_moment.ts b/tests/specs/import_map/import_map_config/scoped_moment.ts new file mode 100644 index 000000000..9f67f88d4 --- /dev/null +++ b/tests/specs/import_map/import_map_config/scoped_moment.ts @@ -0,0 +1 @@ +console.log("Hello from scoped moment!"); diff --git a/tests/specs/import_map/import_map_config/test.ts b/tests/specs/import_map/import_map_config/test.ts new file mode 100644 index 000000000..9b09e9953 --- /dev/null +++ b/tests/specs/import_map/import_map_config/test.ts @@ -0,0 +1,6 @@ +import "moment"; +import "moment/other_file.ts"; +import "lodash"; +import "lodash/other_file.ts"; +import "https://www.unpkg.com/vue/dist/vue.runtime.esm.js"; +import "./scope/scoped.ts"; diff --git a/tests/specs/import_map/import_map_config/unmapped_bare_specifier.out b/tests/specs/import_map/import_map_config/unmapped_bare_specifier.out new file mode 100644 index 000000000..6980fc16b --- /dev/null +++ b/tests/specs/import_map/import_map_config/unmapped_bare_specifier.out @@ -0,0 +1,6 @@ +error: Uncaught (in promise) TypeError: Relative import path "unmapped" not prefixed with / or ./ or ../ and not in import map from "file://[WILDCARD]/unmapped_bare_specifier.ts" + at file://[WILDCARD]/unmapped_bare_specifier.ts:1:14 + +await import("unmapped"); +^ + at async file://[WILDCARD]/unmapped_bare_specifier.ts:1:1 diff --git a/tests/specs/import_map/import_map_config/unmapped_bare_specifier.ts b/tests/specs/import_map/import_map_config/unmapped_bare_specifier.ts new file mode 100644 index 000000000..87684430d --- /dev/null +++ b/tests/specs/import_map/import_map_config/unmapped_bare_specifier.ts @@ -0,0 +1 @@ +await import("unmapped"); diff --git a/tests/specs/import_map/import_map_config/vue.ts b/tests/specs/import_map/import_map_config/vue.ts new file mode 100644 index 000000000..76dbe1917 --- /dev/null +++ b/tests/specs/import_map/import_map_config/vue.ts @@ -0,0 +1 @@ +console.log("Hello from remapped Vue!"); diff --git a/tests/specs/info/ts_error/__test__.json b/tests/specs/info/ts_error/__test__.json new file mode 100644 index 000000000..9ec9b6044 --- /dev/null +++ b/tests/specs/info/ts_error/__test__.json @@ -0,0 +1,4 @@ +{ + "args": "info info_ts_error.ts", + "output": "info_ts_error.out" +} diff --git a/tests/specs/info/ts_error/info_ts_error.out b/tests/specs/info/ts_error/info_ts_error.out new file mode 100644 index 000000000..d2e7aeb14 --- /dev/null +++ b/tests/specs/info/ts_error/info_ts_error.out @@ -0,0 +1,6 @@ +local: [WILDCARD]info_ts_error.ts +type: TypeScript +dependencies: 0 unique +size: [WILDCARD] + +[WILDCARD]info_ts_error.ts ([WILDCARD]) diff --git a/tests/specs/info/ts_error/info_ts_error.ts b/tests/specs/info/ts_error/info_ts_error.ts new file mode 100644 index 000000000..9b7492dbe --- /dev/null +++ b/tests/specs/info/ts_error/info_ts_error.ts @@ -0,0 +1 @@ +const _foo: string = 1; diff --git a/tests/specs/mod.rs b/tests/specs/mod.rs new file mode 100644 index 000000000..831b94430 --- /dev/null +++ b/tests/specs/mod.rs @@ -0,0 +1,279 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use std::collections::HashSet; + +use deno_core::anyhow::Context; +use deno_core::serde_json; +use deno_terminal::colors; +use serde::Deserialize; +use test_util::tests_path; +use test_util::PathRef; +use test_util::TestContextBuilder; + +pub fn main() { + let maybe_filter = parse_cli_arg_filter(); + let categories = filter(collect_tests(), maybe_filter.as_deref()); + let total_tests = categories.iter().map(|c| c.tests.len()).sum::<usize>(); + let mut failures = Vec::new(); + let _http_guard = test_util::http_server(); + // todo(dsherret): the output should be changed to be terse + // when it passes, but verbose on failure + for category in &categories { + eprintln!(); + eprintln!(" {} {}", colors::green_bold("Running"), category.name); + for test in &category.tests { + eprintln!(); + eprintln!("==== Starting {} ====", test.name); + let result = std::panic::catch_unwind(|| run_test(test)); + let success = result.is_ok(); + if !success { + failures.push(&test.name); + } + eprintln!( + "==== {} {} ====", + if success { + "Finished".to_string() + } else { + colors::red("^^FAILED^^").to_string() + }, + test.name + ); + } + } + + eprintln!(); + if !failures.is_empty() { + eprintln!("spec failures:"); + for failure in &failures { + eprintln!(" {}", failure); + } + eprintln!(); + panic!("{} failed of {}", failures.len(), total_tests); + } + eprintln!("{} tests passed", total_tests); +} + +fn parse_cli_arg_filter() -> Option<String> { + let args: Vec<String> = std::env::args().collect(); + let maybe_filter = + args.get(1).filter(|s| !s.starts_with('-') && !s.is_empty()); + maybe_filter.cloned() +} + +fn run_test(test: &Test) { + let metadata = &test.metadata; + let mut builder = TestContextBuilder::new(); + let cwd = &test.cwd; + + if test.metadata.temp_dir { + builder = builder.use_temp_cwd(); + } else { + builder = builder.cwd(cwd.to_string_lossy()); + } + + if let Some(base) = &metadata.base { + match base.as_str() { + "npm" => { + builder = builder.add_npm_env_vars(); + } + "jsr" => { + builder = builder.add_jsr_env_vars(); + } + _ => panic!("Unknown test base: {}", base), + } + } + + let context = builder.build(); + + if test.metadata.temp_dir { + // copy all the files in the cwd to a temp directory + // excluding the metadata and assertion files + let temp_dir = context.temp_dir().path(); + let assertion_paths = test.resolve_test_and_assertion_files(); + cwd.copy_to_recursive_with_exclusions(temp_dir, &assertion_paths); + } + + for step in &metadata.steps { + if step.clean_deno_dir { + context.deno_dir().path().remove_dir_all(); + } + + let test_output_path = cwd.join(&step.output); + if !test_output_path.to_string_lossy().ends_with(".out") { + panic!( + "Use the .out extension for output files (invalid: {})", + test_output_path + ); + } + let expected_output = test_output_path.read_to_string(); + let command = context.new_command(); + let command = match &step.args { + VecOrString::Vec(args) => command.args_vec(args), + VecOrString::String(text) => command.args(text), + }; + let output = command.run(); + output.assert_matches_text(expected_output); + output.assert_exit_code(step.exit_code); + } +} + +#[derive(Clone, Deserialize)] +#[serde(untagged)] +enum VecOrString { + Vec(Vec<String>), + String(String), +} + +#[derive(Clone, Deserialize)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +struct MultiTestMetaData { + /// Whether to copy all the non-assertion files in the current + /// test directory to a temporary directory before running the + /// steps. + #[serde(default)] + pub temp_dir: bool, + /// The base environment to use for the test. + #[serde(default)] + pub base: Option<String>, + pub steps: Vec<StepMetaData>, +} + +#[derive(Clone, Deserialize)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +struct SingleTestMetaData { + #[serde(default)] + pub base: Option<String>, + #[serde(default)] + pub temp_dir: bool, + #[serde(flatten)] + pub step: StepMetaData, +} + +impl SingleTestMetaData { + pub fn into_multi(self) -> MultiTestMetaData { + MultiTestMetaData { + base: self.base, + temp_dir: self.temp_dir, + steps: vec![self.step], + } + } +} + +#[derive(Clone, Deserialize)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +struct StepMetaData { + /// Whether to clean the deno_dir before running the step. + #[serde(default)] + pub clean_deno_dir: bool, + pub args: VecOrString, + pub output: String, + #[serde(default)] + pub exit_code: i32, +} + +#[derive(Clone)] +struct Test { + pub name: String, + pub cwd: PathRef, + pub metadata: MultiTestMetaData, +} + +impl Test { + pub fn resolve_test_and_assertion_files(&self) -> HashSet<PathRef> { + let mut result = HashSet::with_capacity(self.metadata.steps.len() + 1); + result.insert(self.cwd.join("__test__.json")); + result.extend( + self + .metadata + .steps + .iter() + .map(|step| self.cwd.join(&step.output)), + ); + result + } +} + +struct TestCategory { + pub name: String, + pub tests: Vec<Test>, +} + +fn filter( + categories: Vec<TestCategory>, + maybe_filter: Option<&str>, +) -> Vec<TestCategory> { + if categories.iter().all(|c| c.tests.is_empty()) { + panic!("no tests found"); + } + match maybe_filter { + Some(filter) => categories + .into_iter() + .map(|mut c| { + c.tests.retain(|t| t.name.contains(filter)); + c + }) + .collect(), + None => categories, + } +} + +fn collect_tests() -> Vec<TestCategory> { + let specs_dir = tests_path().join("specs"); + let mut result = Vec::new(); + for entry in specs_dir.read_dir() { + let entry = entry.unwrap(); + let file_type = entry + .file_type() + .context(entry.path().to_string_lossy().to_string()) + .unwrap(); + if !file_type.is_dir() { + continue; + } + + let mut category = TestCategory { + name: format!("specs::{}", entry.file_name().to_string_lossy()), + tests: Vec::new(), + }; + + let category_path = PathRef::new(entry.path()); + for entry in category_path.read_dir() { + let entry = entry.unwrap(); + let file_type = entry + .file_type() + .context(entry.path().to_string_lossy().to_string()) + .unwrap(); + if !file_type.is_dir() { + continue; + } + + let test_dir = PathRef::new(entry.path()); + let metadata_path = test_dir.join("__test__.json"); + let metadata_value = metadata_path.read_jsonc_value(); + // checking for "steps" leads to a more targeted error message + // instead of when deserializing an untagged enum + let metadata = if metadata_value + .as_object() + .and_then(|o| o.get("steps")) + .is_some() + { + serde_json::from_value::<MultiTestMetaData>(metadata_value) + } else { + serde_json::from_value::<SingleTestMetaData>(metadata_value) + .map(|s| s.into_multi()) + } + .with_context(|| format!("Failed to parse {}", metadata_path)) + .unwrap(); + category.tests.push(Test { + name: format!( + "{}::{}", + category.name, + entry.file_name().to_string_lossy() + ), + cwd: test_dir, + metadata, + }); + } + result.push(category); + } + result +} diff --git a/tests/specs/npm/conditional_exports/__test__.json b/tests/specs/npm/conditional_exports/__test__.json new file mode 100644 index 000000000..72b058cbf --- /dev/null +++ b/tests/specs/npm/conditional_exports/__test__.json @@ -0,0 +1,5 @@ +{ + "base": "npm", + "args": "run --allow-read main.js", + "output": "main.out" +} diff --git a/tests/specs/npm/conditional_exports/main.js b/tests/specs/npm/conditional_exports/main.js new file mode 100644 index 000000000..52b78bc22 --- /dev/null +++ b/tests/specs/npm/conditional_exports/main.js @@ -0,0 +1,15 @@ +import mod from "npm:@denotest/conditional-exports"; +import foo from "npm:@denotest/conditional-exports/foo.js"; +import client from "npm:@denotest/conditional-exports/client"; +import clientFoo from "npm:@denotest/conditional-exports/client/foo"; +import clientBar from "npm:@denotest/conditional-exports/client/bar"; +import clientM from "npm:@denotest/conditional-exports/client/m"; +import supportsESM from "npm:supports-esm"; + +console.log(mod); +console.log(foo); +console.log(client); +console.log(clientFoo); +console.log(clientBar); +console.log(clientM); +console.log(supportsESM); diff --git a/tests/specs/npm/conditional_exports/main.out b/tests/specs/npm/conditional_exports/main.out new file mode 100644 index 000000000..dbd1b87fe --- /dev/null +++ b/tests/specs/npm/conditional_exports/main.out @@ -0,0 +1,19 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports +Download http://localhost:4545/npm/registry/supports-esm +Download http://localhost:4545/npm/registry/has-package-exports +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports/1.0.0.tgz +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz +Download http://localhost:4545/npm/registry/has-package-exports/has-package-exports-1.3.0.tgz +Download http://localhost:4545/npm/registry/supports-esm/supports-esm-1.0.0.tgz +[UNORDERED_END] +{ hello: "from esm" } +{ hello: "from foo" } +{ hello: "from esm client" } +{ hello: "from esm client foo" } +{ hello: "from esm client bar" } +{ hello: "from esm client m" } +true diff --git a/tests/specs/npm/conditional_exports_node_modules_dir/__test__.json b/tests/specs/npm/conditional_exports_node_modules_dir/__test__.json new file mode 100644 index 000000000..09ea8b23b --- /dev/null +++ b/tests/specs/npm/conditional_exports_node_modules_dir/__test__.json @@ -0,0 +1,6 @@ +{ + "base": "npm", + "tempDir": true, + "args": "run --allow-read --node-modules-dir main.js", + "output": "main.out" +} diff --git a/tests/specs/npm/conditional_exports_node_modules_dir/main.js b/tests/specs/npm/conditional_exports_node_modules_dir/main.js new file mode 100644 index 000000000..52b78bc22 --- /dev/null +++ b/tests/specs/npm/conditional_exports_node_modules_dir/main.js @@ -0,0 +1,15 @@ +import mod from "npm:@denotest/conditional-exports"; +import foo from "npm:@denotest/conditional-exports/foo.js"; +import client from "npm:@denotest/conditional-exports/client"; +import clientFoo from "npm:@denotest/conditional-exports/client/foo"; +import clientBar from "npm:@denotest/conditional-exports/client/bar"; +import clientM from "npm:@denotest/conditional-exports/client/m"; +import supportsESM from "npm:supports-esm"; + +console.log(mod); +console.log(foo); +console.log(client); +console.log(clientFoo); +console.log(clientBar); +console.log(clientM); +console.log(supportsESM); diff --git a/tests/specs/npm/conditional_exports_node_modules_dir/main.out b/tests/specs/npm/conditional_exports_node_modules_dir/main.out new file mode 100644 index 000000000..460aec0f1 --- /dev/null +++ b/tests/specs/npm/conditional_exports_node_modules_dir/main.out @@ -0,0 +1,23 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports +Download http://localhost:4545/npm/registry/supports-esm +Download http://localhost:4545/npm/registry/has-package-exports +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports/1.0.0.tgz +Initialize @denotest/conditional-exports@1.0.0 +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz +Initialize @ljharb/has-package-exports-patterns@0.0.2 +Download http://localhost:4545/npm/registry/has-package-exports/has-package-exports-1.3.0.tgz +Initialize has-package-exports@1.3.0 +Download http://localhost:4545/npm/registry/supports-esm/supports-esm-1.0.0.tgz +Initialize supports-esm@1.0.0 +[UNORDERED_END] +{ hello: "from esm" } +{ hello: "from foo" } +{ hello: "from esm client" } +{ hello: "from esm client foo" } +{ hello: "from esm client bar" } +{ hello: "from esm client m" } +true diff --git a/tests/specs/npm/es_module/__test__.json b/tests/specs/npm/es_module/__test__.json new file mode 100644 index 000000000..f720a2bc0 --- /dev/null +++ b/tests/specs/npm/es_module/__test__.json @@ -0,0 +1,22 @@ +{ + "base": "npm", + "steps": [{ + "args": "run --allow-read --allow-env main.js", + "output": "main.out" + }, { + "cleanDenoDir": true, + "args": "test --allow-read --allow-env test.js", + "output": "test.out" + }, { + "cleanDenoDir": true, + "args": [ + "eval", + "import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk esm loads'));" + ], + "output": "main.out" + }, { + "args": "bundle --quiet main.js", + "output": "bundle.out", + "exitCode": 1 + }] +} diff --git a/tests/specs/npm/es_module/bundle.out b/tests/specs/npm/es_module/bundle.out new file mode 100644 index 000000000..c749a236a --- /dev/null +++ b/tests/specs/npm/es_module/bundle.out @@ -0,0 +1 @@ +error: npm specifiers have not yet been implemented for this subcommand (https://github.com/denoland/deno/issues/15960). Found: npm:/chalk@5.0.1 diff --git a/tests/specs/npm/es_module/main.js b/tests/specs/npm/es_module/main.js new file mode 100644 index 000000000..0f1fa2590 --- /dev/null +++ b/tests/specs/npm/es_module/main.js @@ -0,0 +1,9 @@ +import chalk from "npm:chalk@5"; + +if (import.meta.main) { + console.log(chalk.green("chalk esm loads")); +} + +export function test(value) { + return chalk.red(value); +} diff --git a/tests/specs/npm/es_module/main.out b/tests/specs/npm/es_module/main.out new file mode 100644 index 000000000..2010a5b73 --- /dev/null +++ b/tests/specs/npm/es_module/main.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +chalk esm loads diff --git a/tests/specs/npm/es_module/test.js b/tests/specs/npm/es_module/test.js new file mode 100644 index 000000000..b9c91c715 --- /dev/null +++ b/tests/specs/npm/es_module/test.js @@ -0,0 +1,5 @@ +import { test } from "./main.js"; + +Deno.test("test", () => { + console.log(test("test")); +}); diff --git a/tests/specs/npm/es_module/test.out b/tests/specs/npm/es_module/test.out new file mode 100644 index 000000000..0ed0fbd3c --- /dev/null +++ b/tests/specs/npm/es_module/test.out @@ -0,0 +1,11 @@ +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +running 1 test from ./test.js +test ... +------- output ------- +test +----- output end ----- +test ... ok ([WILDCARD]s) + +ok | 1 passed | 0 failed ([WILDCARD]s) + diff --git a/tests/specs/run/redirect_javascript/__test__.json b/tests/specs/run/redirect_javascript/__test__.json new file mode 100644 index 000000000..1fd0b4cb1 --- /dev/null +++ b/tests/specs/run/redirect_javascript/__test__.json @@ -0,0 +1,4 @@ +{ + "args": "run --quiet --reload main.js", + "output": "main.out" +} diff --git a/tests/specs/run/redirect_javascript/main.js b/tests/specs/run/redirect_javascript/main.js new file mode 100644 index 000000000..226a6b622 --- /dev/null +++ b/tests/specs/run/redirect_javascript/main.js @@ -0,0 +1,2 @@ +import { value } from "http://localhost:4547/redirects/redirect3.js"; +console.log(value); diff --git a/tests/specs/run/redirect_javascript/main.out b/tests/specs/run/redirect_javascript/main.out new file mode 100644 index 000000000..290864299 --- /dev/null +++ b/tests/specs/run/redirect_javascript/main.out @@ -0,0 +1 @@ +3 imports 1 |