mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
4f80d83774
This changes the lockfile to not store JSR specifiers in the "remote" section. Instead a single JSR integrity is stored per package in the lockfile, which is a hash of the version's `x.x.x_meta.json` file, which contains hashes for every file in the package. The hashes in this file are then compared against when loading. Additionally, when using `{ "vendor": true }` in a deno.json, the files can be modified without causing lockfile errors—the checksum is only checked when copying into the vendor folder and not afterwards (eventually we should add this behaviour for non-jsr specifiers as well). As part of this change, the `vendor` folder creation is not always automatic in the LSP and running an explicit cache command is necessary. The code required to track checksums in the LSP would have been too complex for this PR, so that all goes through deno_graph now. The vendoring is still automatic when running from the CLI.
2751 lines
86 KiB
Rust
2751 lines
86 KiB
Rust
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
|
|
use deno_core::serde_json;
|
|
use deno_core::serde_json::json;
|
|
use deno_core::serde_json::Value;
|
|
use pretty_assertions::assert_eq;
|
|
use test_util as util;
|
|
use test_util::itest;
|
|
use util::assert_contains;
|
|
use util::env_vars_for_npm_tests;
|
|
use util::http_server;
|
|
use util::TestContextBuilder;
|
|
|
|
// NOTE: See how to make test npm packages at ./testdata/npm/README.md
|
|
|
|
itest!(es_module {
|
|
args: "run --allow-read --allow-env npm/esm/main.js",
|
|
output: "npm/esm/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(es_module_eval {
|
|
args_vec: vec![
|
|
"eval",
|
|
"import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk esm loads'));",
|
|
],
|
|
output: "npm/esm/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(es_module_deno_test {
|
|
args: "test --allow-read --allow-env npm/esm/test.js",
|
|
output: "npm/esm/test.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(esm_import_cjs_default {
|
|
args: "run --allow-read --allow-env --quiet --check=all npm/esm_import_cjs_default/main.ts",
|
|
output: "npm/esm_import_cjs_default/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_with_deps {
|
|
args: "run --allow-read --allow-env npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_sub_path {
|
|
args: "run --allow-read npm/cjs_sub_path/main.js",
|
|
output: "npm/cjs_sub_path/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_local_global_decls {
|
|
args: "run --allow-read npm/cjs_local_global_decls/main.ts",
|
|
output: "npm/cjs_local_global_decls/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_reexport_collision {
|
|
args: "run -A --quiet npm/cjs_reexport_collision/main.ts",
|
|
output: "npm/cjs_reexport_collision/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_this_in_exports {
|
|
args: "run --allow-read --quiet npm/cjs_this_in_exports/main.js",
|
|
output: "npm/cjs_this_in_exports/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(cjs_invalid_name_exports {
|
|
args: "run --allow-read --quiet npm/cjs-invalid-name-exports/main.ts",
|
|
output: "npm/cjs-invalid-name-exports/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_require_esm_error {
|
|
args: "run --allow-read --quiet npm/cjs_require_esm_error/main.ts",
|
|
output: "npm/cjs_require_esm_error/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(cjs_require_esm_mjs_error {
|
|
args: "run --allow-read --quiet npm/cjs_require_esm_mjs_error/main.ts",
|
|
output: "npm/cjs_require_esm_mjs_error/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(require_esm_error {
|
|
args: "run --allow-read --quiet node/require_esm_error/main.ts",
|
|
output: "node/require_esm_error/main.out",
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(dynamic_import_deno_ts_from_npm {
|
|
args: "run --allow-read --quiet npm/dynamic_import_deno_ts_from_npm/main.ts",
|
|
output: "npm/dynamic_import_deno_ts_from_npm/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(translate_cjs_to_esm {
|
|
args: "run -A --quiet npm/translate_cjs_to_esm/main.js",
|
|
output: "npm/translate_cjs_to_esm/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(compare_globals {
|
|
args: "run --allow-read --check=all npm/compare_globals/main.ts",
|
|
output: "npm/compare_globals/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(conditional_exports {
|
|
args: "run --allow-read npm/conditional_exports/main.js",
|
|
output: "npm/conditional_exports/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(conditional_exports_node_modules_dir {
|
|
args:
|
|
"run --allow-read --node-modules-dir $TESTDATA/npm/conditional_exports/main.js",
|
|
output: "npm/conditional_exports/main_node_modules.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(dual_cjs_esm {
|
|
args: "run -A --quiet npm/dual_cjs_esm/main.ts",
|
|
output: "npm/dual_cjs_esm/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(child_process_fork_test {
|
|
args: "run -A --quiet npm/child_process_fork_test/main.ts",
|
|
output: "npm/child_process_fork_test/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_module_export_assignment {
|
|
args: "run -A --quiet --check=all npm/cjs_module_export_assignment/main.ts",
|
|
output: "npm/cjs_module_export_assignment/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cjs_module_export_assignment_number {
|
|
args:
|
|
"run -A --quiet --check=all npm/cjs_module_export_assignment_number/main.ts",
|
|
output: "npm/cjs_module_export_assignment_number/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(mixed_case_package_name_global_dir {
|
|
args: "run npm/mixed_case_package_name/global.ts",
|
|
output: "npm/mixed_case_package_name/global.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(mixed_case_package_name_local_dir {
|
|
args:
|
|
"run --node-modules-dir -A $TESTDATA/npm/mixed_case_package_name/local.ts",
|
|
output: "npm/mixed_case_package_name/local.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(local_dir_resolves_symlinks {
|
|
args: "run -A index.js",
|
|
output: "npm/local_dir_resolves_symlinks/index.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
cwd: Some("npm/local_dir_resolves_symlinks/"),
|
|
copy_temp_dir: Some("npm/local_dir_resolves_symlinks/"),
|
|
http_server: true,
|
|
});
|
|
|
|
// FIXME(bartlomieju): npm: specifiers are not handled in dynamic imports
|
|
// at the moment
|
|
// itest!(dynamic_import {
|
|
// args: "run --allow-read --allow-env npm/dynamic_import/main.ts",
|
|
// output: "npm/dynamic_import/main.out",
|
|
// envs: env_vars_for_npm_tests(),
|
|
// http_server: true,
|
|
// });
|
|
|
|
itest!(dynamic_import_reload_same_package {
|
|
args: "run -A --reload npm/dynamic_import_reload_same_package/main.ts",
|
|
output: "npm/dynamic_import_reload_same_package/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(dynamic_import_invalid_package_name {
|
|
args: "run -A --reload npm/dynamic_import_invalid_package_name/main.ts",
|
|
output: "npm/dynamic_import_invalid_package_name/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(env_var_re_export_dev {
|
|
args: "run --allow-read --allow-env --quiet npm/env_var_re_export/main.js",
|
|
output_str: Some("dev\n"),
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(env_var_re_export_prod {
|
|
args: "run --allow-read --allow-env --quiet npm/env_var_re_export/main.js",
|
|
output_str: Some("prod\n"),
|
|
envs: {
|
|
let mut vars = env_vars_for_npm_tests();
|
|
vars.push(("NODE_ENV".to_string(), "production".to_string()));
|
|
vars
|
|
},
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(cached_only {
|
|
args: "run --cached-only npm/cached_only/main.ts",
|
|
output: "npm/cached_only/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(import_map {
|
|
args: "run --allow-read --allow-env --import-map npm/import_map/import_map.json npm/import_map/main.js",
|
|
output: "npm/import_map/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(lock_file_integrity_failure {
|
|
args: "run --allow-read --allow-env --lock npm/lock_file/lock.json npm/lock_file/main.js",
|
|
output: "npm/lock_file/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 10,
|
|
});
|
|
|
|
itest!(sub_paths {
|
|
args: "run -A --quiet npm/sub_paths/main.jsx",
|
|
output: "npm/sub_paths/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(remote_npm_specifier {
|
|
args: "run --quiet -A npm/remote_npm_specifier/main.ts",
|
|
output: "npm/remote_npm_specifier/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 0,
|
|
});
|
|
|
|
itest!(tarball_with_global_header {
|
|
args: "run -A --quiet npm/tarball_with_global_header/main.js",
|
|
output: "npm/tarball_with_global_header/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(node_modules_deno_node_modules {
|
|
args: "run --quiet npm/node_modules_deno_node_modules/main.ts",
|
|
output: "npm/node_modules_deno_node_modules/main.out",
|
|
copy_temp_dir: Some("npm/node_modules_deno_node_modules/"),
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(node_modules_deno_node_modules_local {
|
|
args:
|
|
"run --quiet --node-modules-dir npm/node_modules_deno_node_modules/main.ts",
|
|
output: "npm/node_modules_deno_node_modules/main.out",
|
|
copy_temp_dir: Some("npm/node_modules_deno_node_modules/"),
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(nonexistent_file {
|
|
args: "run -A --quiet npm/nonexistent_file/main.js",
|
|
output: "npm/nonexistent_file/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(nonexistent_file_node_modules_dir {
|
|
// there was a bug where the message was different when using a node_modules dir
|
|
args: "run -A --quiet --node-modules-dir npm/nonexistent_file/main.js",
|
|
output: "npm/nonexistent_file/main.out",
|
|
copy_temp_dir: Some("npm/nonexistent_file/"),
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(invalid_package_name {
|
|
args: "run -A --quiet npm/invalid_package_name/main.js",
|
|
output: "npm/invalid_package_name/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(require_json {
|
|
args: "run -A --quiet npm/require_json/main.js",
|
|
output: "npm/require_json/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(error_version_after_subpath {
|
|
args: "run -A --quiet npm/error_version_after_subpath/main.js",
|
|
output: "npm/error_version_after_subpath/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(deno_cache {
|
|
args: "cache --reload npm:chalk npm:mkdirp",
|
|
output: "npm/deno_cache.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(check_all {
|
|
args: "check --all npm/check_errors/main.ts",
|
|
output: "npm/check_errors/main_all.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(check_local {
|
|
args: "check npm/check_errors/main.ts",
|
|
output: "npm/check_errors/main_local.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_general {
|
|
args: "check --quiet npm/types/main.ts",
|
|
output: "npm/types/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_ambient_module {
|
|
args: "check --quiet npm/types_ambient_module/main.ts",
|
|
output: "npm/types_ambient_module/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_ambient_module_import_map {
|
|
args: "check --quiet --import-map=npm/types_ambient_module/import_map.json npm/types_ambient_module/main_import_map.ts",
|
|
output: "npm/types_ambient_module/main_import_map.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(no_types_cjs {
|
|
args: "check --quiet npm/no_types_cjs/main.ts",
|
|
output_str: Some(""),
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(no_types_in_conditional_exports {
|
|
args: "run --check npm/no_types_in_conditional_exports/main.ts",
|
|
output: "npm/no_types_in_conditional_exports/main.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(types_entry_value_not_exists {
|
|
args: "check --all npm/types_entry_value_not_exists/main.ts",
|
|
output: "npm/types_entry_value_not_exists/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_exports_import_types {
|
|
args: "check --all npm/types_exports_import_types/main.ts",
|
|
output: "npm/types_exports_import_types/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_no_types_entry {
|
|
args: "check --all npm/types_no_types_entry/main.ts",
|
|
output: "npm/types_no_types_entry/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(types_d_ext {
|
|
args: "check --all npm/d_ext/main.ts",
|
|
output: "npm/d_ext/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(typescript_file_in_package {
|
|
args: "run npm/typescript_file_in_package/main.ts",
|
|
output: "npm/typescript_file_in_package/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(permissions_outside_package {
|
|
args: "run --allow-read npm/permissions_outside_package/main.ts",
|
|
output: "npm/permissions_outside_package/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(run_existing_npm_package {
|
|
args: "run --allow-read --node-modules-dir npm:@denotest/bin",
|
|
output: "npm/run_existing_npm_package/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
cwd: Some("npm/run_existing_npm_package/"),
|
|
copy_temp_dir: Some("npm/run_existing_npm_package/"),
|
|
});
|
|
|
|
itest!(run_existing_npm_package_with_subpath {
|
|
args:
|
|
"run --allow-read --node-modules-dir npm:@denotest/bin/cli-esm dev --help",
|
|
output: "npm/run_existing_npm_package_with_subpath/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
cwd: Some("npm/run_existing_npm_package_with_subpath/"),
|
|
copy_temp_dir: Some("npm/run_existing_npm_package_with_subpath/"),
|
|
});
|
|
|
|
#[test]
|
|
fn parallel_downloading() {
|
|
let (out, _err) = util::run_and_collect_output_with_args(
|
|
true,
|
|
vec![
|
|
"run",
|
|
"--allow-read",
|
|
"--allow-env",
|
|
"npm/cjs_with_deps/main.js",
|
|
],
|
|
None,
|
|
// don't use the sync env var
|
|
Some(env_vars_for_npm_tests()),
|
|
true,
|
|
);
|
|
assert!(out.contains("chalk cjs loads"));
|
|
}
|
|
|
|
#[test]
|
|
fn cached_only_after_first_run() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("npm/cached_only_after_first_run/main1.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--cached-only")
|
|
.arg("npm/cached_only_after_first_run/main2.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(
|
|
stderr,
|
|
"An npm specifier not found in cache: \"ansi-styles\", --cached-only is specified."
|
|
);
|
|
assert!(stdout.is_empty());
|
|
assert!(!output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--cached-only")
|
|
.arg("npm/cached_only_after_first_run/main1.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert!(output.status.success());
|
|
assert!(stderr.is_empty());
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
}
|
|
|
|
#[test]
|
|
fn reload_flag() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("npm/reload/main.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--reload")
|
|
.arg("npm/reload/main.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--reload=npm:")
|
|
.arg("npm/reload/main.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--reload=npm:chalk")
|
|
.arg("npm/reload/main.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--reload=npm:foobar")
|
|
.arg("npm/reload/main.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert!(stderr.is_empty());
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
}
|
|
|
|
#[test]
|
|
fn no_npm_after_first_run() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--no-npm")
|
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(
|
|
stderr,
|
|
"error: npm specifiers were requested; but --no-npm is specified\n at file:///"
|
|
);
|
|
assert!(stdout.is_empty());
|
|
assert!(!output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(stderr, "Download");
|
|
assert_contains!(stdout, "[Function: chalk] createChalk");
|
|
assert!(output.status.success());
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(util::testdata_path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--no-npm")
|
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert_contains!(
|
|
stderr,
|
|
"error: npm specifiers were requested; but --no-npm is specified\n at file:///"
|
|
);
|
|
assert!(stdout.is_empty());
|
|
assert!(!output.status.success());
|
|
}
|
|
|
|
#[test]
|
|
fn deno_run_cjs_module() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(deno_dir.path())
|
|
.arg("run")
|
|
.arg("--allow-read")
|
|
.arg("--allow-env")
|
|
.arg("--allow-write")
|
|
.arg("npm:mkdirp@1.0.4")
|
|
.arg("test_dir")
|
|
.env("NO_COLOR", "1")
|
|
.envs(env_vars_for_npm_tests())
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
assert!(output.status.success());
|
|
|
|
assert!(deno_dir.path().join("test_dir").exists());
|
|
}
|
|
|
|
itest!(deno_run_cowsay {
|
|
args: "run -A --quiet npm:cowsay@1.5.0 Hello",
|
|
output: "npm/deno_run_cowsay.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_cowsay_with_node_modules_dir {
|
|
args: "run -A --quiet --node-modules-dir npm:cowsay@1.5.0 Hello",
|
|
temp_cwd: true,
|
|
output: "npm/deno_run_cowsay.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_cowsay_explicit {
|
|
args: "run -A --quiet npm:cowsay@1.5.0/cowsay Hello",
|
|
output: "npm/deno_run_cowsay.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_cowthink {
|
|
args: "run -A --quiet npm:cowsay@1.5.0/cowthink Hello",
|
|
output: "npm/deno_run_cowthink.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_esm {
|
|
args: "run -A --quiet npm:@denotest/bin/cli-esm this is a test",
|
|
output: "npm/deno_run_esm.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_esm_no_bin_entrypoint {
|
|
args: "run -A --quiet npm:@denotest/bin@0.6.0/cli.mjs this is a test",
|
|
output: "npm/deno_run_esm.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_cjs_no_bin_entrypoint {
|
|
args: "run -A --quiet npm:@denotest/bin@0.6.0/cli-cjs.js this is a test",
|
|
output: "npm/deno_run_cjs.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_special_chars {
|
|
args: "run -A --quiet npm:@denotest/special-chars-in-bin-name/\\foo\" this is a test",
|
|
output: "npm/deno_run_special_chars_in_bin_name.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_no_ext {
|
|
args: "run -A --quiet npm:@denotest/bin/cli-no-ext this is a test",
|
|
output: "npm/deno_run_no_ext.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(deno_run_bin_cjs {
|
|
args: "run -A --quiet npm:@denotest/bin/cli-cjs this is a test",
|
|
output: "npm/deno_run_cjs.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
#[test]
|
|
fn deno_run_bin_lockfile() {
|
|
let context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let temp_dir = context.temp_dir();
|
|
temp_dir.write("deno.json", "{}");
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --quiet npm:@denotest/bin/cli-esm this is a test")
|
|
.run();
|
|
output.assert_matches_file("npm/deno_run_esm.out");
|
|
assert!(temp_dir.path().join("deno.lock").exists());
|
|
}
|
|
|
|
itest!(deno_run_non_existent {
|
|
args: "run npm:mkdirp@0.5.125",
|
|
output: "npm/deno_run_non_existent.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(deno_run_no_bin_entrypoint {
|
|
args: "run -A --quiet npm:@denotest/esm-basic",
|
|
output: "npm/deno_run_no_bin_entrypoint.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(deno_run_no_bin_entrypoint_non_existent_subpath {
|
|
args: "run -A --quiet npm:@denotest/esm-basic/non-existent.js",
|
|
output: "npm/deno_run_no_bin_entrypoint_non_existent_subpath.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(directory_import_folder_index_js {
|
|
args: "run npm/directory_import/folder_index_js.ts",
|
|
output: "npm/directory_import/folder_index_js.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(directory_import_folder_no_index {
|
|
args: "run npm/directory_import/folder_no_index.ts",
|
|
output: "npm/directory_import/folder_no_index.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(builtin_module_module {
|
|
args: "run --allow-read --quiet npm/builtin_module_module/main.js",
|
|
output: "npm/builtin_module_module/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(node_modules_dir_require_added_node_modules_folder {
|
|
args:
|
|
"run --node-modules-dir -A --quiet $TESTDATA/npm/require_added_nm_folder/main.js",
|
|
output: "npm/require_added_nm_folder/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 0,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(node_modules_dir_require_main_entry {
|
|
args: "run --node-modules-dir -A --quiet $TESTDATA/npm/require_main/main.js",
|
|
output: "npm/require_main/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 0,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(node_modules_dir_with_deps {
|
|
args: "run --allow-read --allow-env --node-modules-dir $TESTDATA/npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main_node_modules.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(node_modules_dir_yargs {
|
|
args: "run --allow-read --allow-env --node-modules-dir $TESTDATA/npm/cjs_yargs/main.js",
|
|
output: "npm/cjs_yargs/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
#[test]
|
|
fn node_modules_dir_cache() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(deno_dir.path())
|
|
.arg("cache")
|
|
.arg("--node-modules-dir")
|
|
.arg("--quiet")
|
|
.arg(util::testdata_path().join("npm/dual_cjs_esm/main.ts"))
|
|
.envs(env_vars_for_npm_tests())
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
assert!(output.status.success());
|
|
|
|
let node_modules = deno_dir.path().join("node_modules");
|
|
assert!(node_modules
|
|
.join(
|
|
".deno/@denotest+dual-cjs-esm@1.0.0/node_modules/@denotest/dual-cjs-esm"
|
|
)
|
|
.exists());
|
|
assert!(node_modules.join("@denotest/dual-cjs-esm").exists());
|
|
|
|
// now try deleting the folder with the package source in the npm cache dir
|
|
let package_global_cache_dir = deno_dir
|
|
.path()
|
|
.join("npm")
|
|
.join("localhost_4545")
|
|
.join("npm")
|
|
.join("registry")
|
|
.join("@denotest")
|
|
.join("dual-cjs-esm")
|
|
.join("1.0.0");
|
|
assert!(package_global_cache_dir.exists());
|
|
std::fs::remove_dir_all(&package_global_cache_dir).unwrap();
|
|
|
|
// run the output, and it shouldn't bother recreating the directory
|
|
// because it already has everything cached locally in the node_modules folder
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(deno_dir.path())
|
|
.arg("run")
|
|
.arg("--node-modules-dir")
|
|
.arg("--quiet")
|
|
.arg("-A")
|
|
.arg(util::testdata_path().join("npm/dual_cjs_esm/main.ts"))
|
|
.envs(env_vars_for_npm_tests())
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
assert!(output.status.success());
|
|
|
|
// this won't exist, but actually the parent directory
|
|
// will because it still re-downloads the registry information
|
|
assert!(!package_global_cache_dir.exists());
|
|
}
|
|
|
|
#[test]
|
|
fn ensure_registry_files_local() {
|
|
// ensures the registry files all point at local tarballs
|
|
let registry_dir_path = util::testdata_path().join("npm").join("registry");
|
|
for entry in std::fs::read_dir(®istry_dir_path).unwrap() {
|
|
let entry = entry.unwrap();
|
|
if entry.metadata().unwrap().is_dir() {
|
|
let registry_json_path = registry_dir_path
|
|
.join(entry.file_name())
|
|
.join("registry.json");
|
|
if registry_json_path.exists() {
|
|
let file_text = std::fs::read_to_string(®istry_json_path).unwrap();
|
|
if file_text.contains("https://registry.npmjs.org/") {
|
|
panic!(
|
|
"file {} contained a reference to the npm registry",
|
|
registry_json_path
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
itest!(bundle_errors {
|
|
args: "bundle --quiet npm/esm/main.js",
|
|
output_str: Some("error: npm specifiers have not yet been implemented for this subcommand (https://github.com/denoland/deno/issues/15960). Found: npm:/chalk@5.0.1\n"),
|
|
exit_code: 1,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(info_chalk_display {
|
|
args: "info --quiet npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main_info.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(info_chalk_display_node_modules_dir {
|
|
args: "info --quiet --node-modules-dir $TESTDATA/npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main_info.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(info_chalk_json {
|
|
args: "info --quiet --json npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main_info_json.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(info_chalk_json_node_modules_dir {
|
|
args:
|
|
"info --quiet --node-modules-dir --json $TESTDATA/npm/cjs_with_deps/main.js",
|
|
output: "npm/cjs_with_deps/main_info_json.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
temp_cwd: true,
|
|
});
|
|
|
|
itest!(info_cli_chalk_display {
|
|
args: "info --quiet npm:chalk@4",
|
|
output: "npm/info/chalk.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(info_cli_chalk_json {
|
|
args: "info --quiet --json npm:chalk@4",
|
|
output: "npm/info/chalk_json.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
#[test]
|
|
fn lock_file_missing_top_level_package() {
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
let temp_dir = util::TempDir::new();
|
|
|
|
// write empty config file
|
|
temp_dir.write("deno.json", "{}");
|
|
|
|
// Lock file that is automatically picked up has been intentionally broken,
|
|
// by removing "cowsay" package from it. This test ensures that npm resolver
|
|
// snapshot can be successfully hydrated in such situation
|
|
let lock_file_content = r#"{
|
|
"version": "2",
|
|
"remote": {},
|
|
"npm": {
|
|
"specifiers": { "cowsay": "cowsay@1.5.0" },
|
|
"packages": {
|
|
"ansi-regex@3.0.1": {
|
|
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
|
|
"dependencies": {}
|
|
},
|
|
"ansi-regex@5.0.1": {
|
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
|
"dependencies": {}
|
|
},
|
|
"ansi-styles@4.3.0": {
|
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
|
"dependencies": { "color-convert": "color-convert@2.0.1" }
|
|
},
|
|
"camelcase@5.3.1": {
|
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
|
"dependencies": {}
|
|
},
|
|
"cliui@6.0.0": {
|
|
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
|
"dependencies": {
|
|
"string-width": "string-width@4.2.3",
|
|
"strip-ansi": "strip-ansi@6.0.1",
|
|
"wrap-ansi": "wrap-ansi@6.2.0"
|
|
}
|
|
},
|
|
"color-convert@2.0.1": {
|
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
|
"dependencies": { "color-name": "color-name@1.1.4" }
|
|
},
|
|
"color-name@1.1.4": {
|
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
|
"dependencies": {}
|
|
},
|
|
"decamelize@1.2.0": {
|
|
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
|
"dependencies": {}
|
|
},
|
|
"emoji-regex@8.0.0": {
|
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
|
"dependencies": {}
|
|
},
|
|
"find-up@4.1.0": {
|
|
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
|
"dependencies": {
|
|
"locate-path": "locate-path@5.0.0",
|
|
"path-exists": "path-exists@4.0.0"
|
|
}
|
|
},
|
|
"get-caller-file@2.0.5": {
|
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
|
"dependencies": {}
|
|
},
|
|
"get-stdin@8.0.0": {
|
|
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
|
|
"dependencies": {}
|
|
},
|
|
"is-fullwidth-code-point@2.0.0": {
|
|
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
|
|
"dependencies": {}
|
|
},
|
|
"is-fullwidth-code-point@3.0.0": {
|
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
|
"dependencies": {}
|
|
},
|
|
"locate-path@5.0.0": {
|
|
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
|
"dependencies": { "p-locate": "p-locate@4.1.0" }
|
|
},
|
|
"p-limit@2.3.0": {
|
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
|
"dependencies": { "p-try": "p-try@2.2.0" }
|
|
},
|
|
"p-locate@4.1.0": {
|
|
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
|
"dependencies": { "p-limit": "p-limit@2.3.0" }
|
|
},
|
|
"p-try@2.2.0": {
|
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
|
"dependencies": {}
|
|
},
|
|
"path-exists@4.0.0": {
|
|
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
|
"dependencies": {}
|
|
},
|
|
"require-directory@2.1.1": {
|
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
|
"dependencies": {}
|
|
},
|
|
"require-main-filename@2.0.0": {
|
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
|
"dependencies": {}
|
|
},
|
|
"set-blocking@2.0.0": {
|
|
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
|
"dependencies": {}
|
|
},
|
|
"string-width@2.1.1": {
|
|
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
|
"dependencies": {
|
|
"is-fullwidth-code-point": "is-fullwidth-code-point@2.0.0",
|
|
"strip-ansi": "strip-ansi@4.0.0"
|
|
}
|
|
},
|
|
"string-width@4.2.3": {
|
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
|
"dependencies": {
|
|
"emoji-regex": "emoji-regex@8.0.0",
|
|
"is-fullwidth-code-point": "is-fullwidth-code-point@3.0.0",
|
|
"strip-ansi": "strip-ansi@6.0.1"
|
|
}
|
|
},
|
|
"strip-ansi@4.0.0": {
|
|
"integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
|
|
"dependencies": { "ansi-regex": "ansi-regex@3.0.1" }
|
|
},
|
|
"strip-ansi@6.0.1": {
|
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
|
"dependencies": { "ansi-regex": "ansi-regex@5.0.1" }
|
|
},
|
|
"strip-final-newline@2.0.0": {
|
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
|
"dependencies": {}
|
|
},
|
|
"which-module@2.0.0": {
|
|
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
|
"dependencies": {}
|
|
},
|
|
"wrap-ansi@6.2.0": {
|
|
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
|
"dependencies": {
|
|
"ansi-styles": "ansi-styles@4.3.0",
|
|
"string-width": "string-width@4.2.3",
|
|
"strip-ansi": "strip-ansi@6.0.1"
|
|
}
|
|
},
|
|
"y18n@4.0.3": {
|
|
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
|
"dependencies": {}
|
|
},
|
|
"yargs-parser@18.1.3": {
|
|
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
|
"dependencies": {
|
|
"camelcase": "camelcase@5.3.1",
|
|
"decamelize": "decamelize@1.2.0"
|
|
}
|
|
},
|
|
"yargs@15.4.1": {
|
|
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
|
"dependencies": {
|
|
"cliui": "cliui@6.0.0",
|
|
"decamelize": "decamelize@1.2.0",
|
|
"find-up": "find-up@4.1.0",
|
|
"get-caller-file": "get-caller-file@2.0.5",
|
|
"require-directory": "require-directory@2.1.1",
|
|
"require-main-filename": "require-main-filename@2.0.0",
|
|
"set-blocking": "set-blocking@2.0.0",
|
|
"string-width": "string-width@4.2.3",
|
|
"which-module": "which-module@2.0.0",
|
|
"y18n": "y18n@4.0.3",
|
|
"yargs-parser": "yargs-parser@18.1.3"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"#;
|
|
temp_dir.write("deno.lock", lock_file_content);
|
|
let main_contents = r#"
|
|
import cowsay from "npm:cowsay";
|
|
console.log(cowsay);
|
|
"#;
|
|
temp_dir.write("main.ts", main_contents);
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(temp_dir.path())
|
|
.arg("run")
|
|
.arg("--quiet")
|
|
.arg("--lock")
|
|
.arg("deno.lock")
|
|
.arg("-A")
|
|
.arg("main.ts")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
assert!(!output.status.success());
|
|
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert_eq!(
|
|
stderr,
|
|
concat!(
|
|
"error: failed reading lockfile 'deno.lock'\n",
|
|
"\n",
|
|
"Caused by:\n",
|
|
" 0: The lockfile is corrupt. You can recreate it with --lock-write\n",
|
|
" 1: Could not find 'cowsay@1.5.0' in the list of packages.\n"
|
|
)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn lock_file_lock_write() {
|
|
// https://github.com/denoland/deno/issues/16666
|
|
// Ensure that --lock-write still adds npm packages to the lockfile
|
|
let _server = http_server();
|
|
|
|
let deno_dir = util::new_deno_dir();
|
|
let temp_dir = util::TempDir::new();
|
|
|
|
// write empty config file
|
|
temp_dir.write("deno.json", "{}");
|
|
|
|
// write a lock file with borked integrity
|
|
let lock_file_content = r#"{
|
|
"version": "3",
|
|
"packages": {
|
|
"specifiers": {
|
|
"npm:cowsay@1.5.0": "npm:cowsay@1.5.0"
|
|
},
|
|
"npm": {
|
|
"ansi-regex@3.0.1": {
|
|
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
|
|
"dependencies": {}
|
|
},
|
|
"ansi-regex@5.0.1": {
|
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
|
"dependencies": {}
|
|
},
|
|
"ansi-styles@4.3.0": {
|
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
|
"dependencies": {
|
|
"color-convert": "color-convert@2.0.1"
|
|
}
|
|
},
|
|
"camelcase@5.3.1": {
|
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
|
"dependencies": {}
|
|
},
|
|
"cliui@6.0.0": {
|
|
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
|
"dependencies": {
|
|
"string-width": "string-width@4.2.3",
|
|
"strip-ansi": "strip-ansi@6.0.1",
|
|
"wrap-ansi": "wrap-ansi@6.2.0"
|
|
}
|
|
},
|
|
"color-convert@2.0.1": {
|
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
|
"dependencies": {
|
|
"color-name": "color-name@1.1.4"
|
|
}
|
|
},
|
|
"color-name@1.1.4": {
|
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
|
"dependencies": {}
|
|
},
|
|
"cowsay@1.5.0": {
|
|
"integrity": "sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==",
|
|
"dependencies": {
|
|
"get-stdin": "get-stdin@8.0.0",
|
|
"string-width": "string-width@2.1.1",
|
|
"strip-final-newline": "strip-final-newline@2.0.0",
|
|
"yargs": "yargs@15.4.1"
|
|
}
|
|
},
|
|
"decamelize@1.2.0": {
|
|
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
|
"dependencies": {}
|
|
},
|
|
"emoji-regex@8.0.0": {
|
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
|
"dependencies": {}
|
|
},
|
|
"find-up@4.1.0": {
|
|
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
|
"dependencies": {
|
|
"locate-path": "locate-path@5.0.0",
|
|
"path-exists": "path-exists@4.0.0"
|
|
}
|
|
},
|
|
"get-caller-file@2.0.5": {
|
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
|
"dependencies": {}
|
|
},
|
|
"get-stdin@8.0.0": {
|
|
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
|
|
"dependencies": {}
|
|
},
|
|
"is-fullwidth-code-point@2.0.0": {
|
|
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
|
|
"dependencies": {}
|
|
},
|
|
"is-fullwidth-code-point@3.0.0": {
|
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
|
"dependencies": {}
|
|
},
|
|
"locate-path@5.0.0": {
|
|
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
|
"dependencies": {
|
|
"p-locate": "p-locate@4.1.0"
|
|
}
|
|
},
|
|
"p-limit@2.3.0": {
|
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
|
"dependencies": {
|
|
"p-try": "p-try@2.2.0"
|
|
}
|
|
},
|
|
"p-locate@4.1.0": {
|
|
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
|
"dependencies": {
|
|
"p-limit": "p-limit@2.3.0"
|
|
}
|
|
},
|
|
"p-try@2.2.0": {
|
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
|
"dependencies": {}
|
|
},
|
|
"path-exists@4.0.0": {
|
|
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
|
"dependencies": {}
|
|
},
|
|
"require-directory@2.1.1": {
|
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
|
"dependencies": {}
|
|
},
|
|
"require-main-filename@2.0.0": {
|
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
|
"dependencies": {}
|
|
},
|
|
"set-blocking@2.0.0": {
|
|
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
|
"dependencies": {}
|
|
},
|
|
"string-width@2.1.1": {
|
|
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
|
"dependencies": {
|
|
"is-fullwidth-code-point": "is-fullwidth-code-point@2.0.0",
|
|
"strip-ansi": "strip-ansi@4.0.0"
|
|
}
|
|
},
|
|
"string-width@4.2.3": {
|
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
|
"dependencies": {
|
|
"emoji-regex": "emoji-regex@8.0.0",
|
|
"is-fullwidth-code-point": "is-fullwidth-code-point@3.0.0",
|
|
"strip-ansi": "strip-ansi@6.0.1"
|
|
}
|
|
},
|
|
"strip-ansi@4.0.0": {
|
|
"integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
|
|
"dependencies": {
|
|
"ansi-regex": "ansi-regex@3.0.1"
|
|
}
|
|
},
|
|
"strip-ansi@6.0.1": {
|
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
|
"dependencies": {
|
|
"ansi-regex": "ansi-regex@5.0.1"
|
|
}
|
|
},
|
|
"strip-final-newline@2.0.0": {
|
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
|
"dependencies": {}
|
|
},
|
|
"which-module@2.0.0": {
|
|
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
|
"dependencies": {}
|
|
},
|
|
"wrap-ansi@6.2.0": {
|
|
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
|
"dependencies": {
|
|
"ansi-styles": "ansi-styles@4.3.0",
|
|
"string-width": "string-width@4.2.3",
|
|
"strip-ansi": "strip-ansi@6.0.1"
|
|
}
|
|
},
|
|
"y18n@4.0.3": {
|
|
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
|
"dependencies": {}
|
|
},
|
|
"yargs-parser@18.1.3": {
|
|
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
|
"dependencies": {
|
|
"camelcase": "camelcase@5.3.1",
|
|
"decamelize": "decamelize@1.2.0"
|
|
}
|
|
},
|
|
"yargs@15.4.1": {
|
|
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
|
"dependencies": {
|
|
"cliui": "cliui@6.0.0",
|
|
"decamelize": "decamelize@1.2.0",
|
|
"find-up": "find-up@4.1.0",
|
|
"get-caller-file": "get-caller-file@2.0.5",
|
|
"require-directory": "require-directory@2.1.1",
|
|
"require-main-filename": "require-main-filename@2.0.0",
|
|
"set-blocking": "set-blocking@2.0.0",
|
|
"string-width": "string-width@4.2.3",
|
|
"which-module": "which-module@2.0.0",
|
|
"y18n": "y18n@4.0.3",
|
|
"yargs-parser": "yargs-parser@18.1.3"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"remote": {}
|
|
}
|
|
"#;
|
|
temp_dir.write("deno.lock", lock_file_content);
|
|
|
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
|
.current_dir(temp_dir.path())
|
|
.arg("cache")
|
|
.arg("--lock-write")
|
|
.arg("--quiet")
|
|
.arg("npm:cowsay@1.5.0")
|
|
.envs(env_vars_for_npm_tests())
|
|
.piped_output()
|
|
.spawn()
|
|
.unwrap();
|
|
let output = deno.wait_with_output().unwrap();
|
|
assert!(output.status.success());
|
|
assert_eq!(output.status.code(), Some(0));
|
|
|
|
let stdout = String::from_utf8(output.stdout).unwrap();
|
|
assert!(stdout.is_empty());
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert!(stderr.is_empty());
|
|
assert_eq!(
|
|
lock_file_content,
|
|
std::fs::read_to_string(temp_dir.path().join("deno.lock")).unwrap()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn auto_discover_lock_file() {
|
|
let context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
|
|
let temp_dir = context.temp_dir();
|
|
|
|
// write empty config file
|
|
temp_dir.write("deno.json", "{}");
|
|
|
|
// write a lock file with borked integrity
|
|
let lock_file_content = r#"{
|
|
"version": "3",
|
|
"packages": {
|
|
"specifiers": { "npm:@denotest/bin": "npm:@denotest/bin@1.0.0" },
|
|
"npm": {
|
|
"@denotest/bin@1.0.0": {
|
|
"integrity": "sha512-foobar",
|
|
"dependencies": {}
|
|
}
|
|
}
|
|
},
|
|
"remote": {}
|
|
}"#;
|
|
temp_dir.write("deno.lock", lock_file_content);
|
|
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A npm:@denotest/bin/cli-esm test")
|
|
.run();
|
|
output
|
|
.assert_matches_text(
|
|
r#"Download http://localhost:4545/npm/registry/@denotest/bin
|
|
error: Integrity check failed for package: "npm:@denotest/bin@1.0.0". Unable to verify that the package
|
|
is the same as when the lockfile was generated.
|
|
|
|
Actual: sha512-[WILDCARD]
|
|
Expected: sha512-foobar
|
|
|
|
This could be caused by:
|
|
* the lock file may be corrupt
|
|
* the source itself may be corrupt
|
|
|
|
Use "--lock-write" flag to regenerate the lockfile at "[WILDCARD]deno.lock".
|
|
"#)
|
|
.assert_exit_code(10);
|
|
}
|
|
|
|
#[test]
|
|
fn peer_deps_with_copied_folders_and_lockfile() {
|
|
let context = TestContextBuilder::for_npm()
|
|
.use_copy_temp_dir("npm/peer_deps_with_copied_folders")
|
|
.cwd("npm/peer_deps_with_copied_folders")
|
|
.build();
|
|
|
|
let deno_dir = context.deno_dir();
|
|
let temp_dir = context.temp_dir();
|
|
let temp_dir_sub_path =
|
|
temp_dir.path().join("npm/peer_deps_with_copied_folders");
|
|
|
|
// write empty config file
|
|
temp_dir.write("npm/peer_deps_with_copied_folders/deno.json", "{}");
|
|
|
|
let output = context.new_command().args("run -A main.ts").run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_file("npm/peer_deps_with_copied_folders/main.out");
|
|
|
|
assert!(temp_dir_sub_path.join("deno.lock").exists());
|
|
let grandchild_path = deno_dir
|
|
.path()
|
|
.join("npm")
|
|
.join("localhost_4545")
|
|
.join("npm")
|
|
.join("registry")
|
|
.join("@denotest")
|
|
.join("peer-dep-test-grandchild");
|
|
assert!(grandchild_path.join("1.0.0").exists());
|
|
assert!(grandchild_path.join("1.0.0_1").exists()); // copy folder, which is hardlinked
|
|
|
|
// run again
|
|
let output = context.new_command().args("run -A main.ts").run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_text("1\n2\n");
|
|
|
|
// run with reload
|
|
let output = context.new_command().args("run -A --reload main.ts").run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_file("npm/peer_deps_with_copied_folders/main.out");
|
|
|
|
// now run with local node modules
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --node-modules-dir main.ts")
|
|
.run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_file(
|
|
"npm/peer_deps_with_copied_folders/main_node_modules.out",
|
|
);
|
|
|
|
let deno_folder = temp_dir_sub_path.join("node_modules").join(".deno");
|
|
assert!(deno_folder
|
|
.join("@denotest+peer-dep-test-grandchild@1.0.0")
|
|
.exists());
|
|
assert!(deno_folder
|
|
.join("@denotest+peer-dep-test-grandchild@1.0.0_1")
|
|
.exists()); // copy folder
|
|
|
|
// now again run with local node modules
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --node-modules-dir main.ts")
|
|
.run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_text("1\n2\n");
|
|
|
|
// now ensure it works with reloading
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --reload --node-modules-dir main.ts")
|
|
.run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_file(
|
|
"npm/peer_deps_with_copied_folders/main_node_modules_reload.out",
|
|
);
|
|
|
|
// now ensure it works with reloading and no lockfile
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --reload --node-modules-dir --no-lock main.ts")
|
|
.run();
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_file(
|
|
"npm/peer_deps_with_copied_folders/main_node_modules_reload.out",
|
|
);
|
|
}
|
|
|
|
itest!(info_peer_deps {
|
|
args: "info --quiet npm/peer_deps_with_copied_folders/main.ts",
|
|
output: "npm/peer_deps_with_copied_folders/main_info.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(info_peer_deps_json {
|
|
args: "info --quiet --json npm/peer_deps_with_copied_folders/main.ts",
|
|
output: "npm/peer_deps_with_copied_folders/main_info_json.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(create_require {
|
|
args: "run --reload --allow-read npm/create_require/main.ts",
|
|
output: "npm/create_require/main.out",
|
|
exit_code: 0,
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(node_modules_import_run {
|
|
args: "run --quiet main.ts",
|
|
output: "npm/node_modules_import/main.out",
|
|
http_server: true,
|
|
copy_temp_dir: Some("npm/node_modules_import/"),
|
|
cwd: Some("npm/node_modules_import/"),
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 0,
|
|
});
|
|
|
|
itest!(node_modules_import_check {
|
|
args: "check --quiet main.ts",
|
|
output: "npm/node_modules_import/main_check.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
cwd: Some("npm/node_modules_import/"),
|
|
copy_temp_dir: Some("npm/node_modules_import/"),
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(non_existent_dep {
|
|
args: "cache npm:@denotest/non-existent-dep",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
output_str: Some(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/non-existent-dep\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/non-existent\n",
|
|
"[UNORDERED_END]\n",
|
|
"error: npm package '@denotest/non-existent' does not exist.\n"
|
|
)),
|
|
});
|
|
|
|
itest!(non_existent_dep_version {
|
|
args: "cache npm:@denotest/non-existent-dep-version",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
output_str: Some(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/non-existent-dep-version\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"[UNORDERED_END]\n",
|
|
// does two downloads because when failing once it max tries to
|
|
// get the latest version a second time
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/non-existent-dep-version\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"[UNORDERED_END]\n",
|
|
"error: Could not find npm package '@denotest/esm-basic' matching '=99.99.99'.\n"
|
|
)),
|
|
});
|
|
|
|
#[test]
|
|
fn reload_info_not_found_cache_but_exists_remote() {
|
|
fn remove_version(registry_json: &mut Value, version: &str) {
|
|
registry_json
|
|
.as_object_mut()
|
|
.unwrap()
|
|
.get_mut("versions")
|
|
.unwrap()
|
|
.as_object_mut()
|
|
.unwrap()
|
|
.remove(version);
|
|
}
|
|
|
|
fn remove_version_for_package(
|
|
deno_dir: &util::TempDir,
|
|
package: &str,
|
|
version: &str,
|
|
) {
|
|
let registry_json_path =
|
|
format!("npm/localhost_4545/npm/registry/{}/registry.json", package);
|
|
let mut registry_json: Value =
|
|
serde_json::from_str(&deno_dir.read_to_string(®istry_json_path))
|
|
.unwrap();
|
|
remove_version(&mut registry_json, version);
|
|
// for the purpose of this test, just remove the dist-tag as it might contain this version
|
|
registry_json
|
|
.as_object_mut()
|
|
.unwrap()
|
|
.get_mut("dist-tags")
|
|
.unwrap()
|
|
.as_object_mut()
|
|
.unwrap()
|
|
.remove("latest");
|
|
deno_dir.write(
|
|
®istry_json_path,
|
|
serde_json::to_string(®istry_json).unwrap(),
|
|
);
|
|
}
|
|
|
|
// This tests that when a local machine doesn't have a version
|
|
// specified in a dependency that exists in the npm registry
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let deno_dir = test_context.deno_dir();
|
|
let temp_dir = test_context.temp_dir();
|
|
temp_dir.write(
|
|
"main.ts",
|
|
"import 'npm:@denotest/esm-import-cjs-default@1.0.0';",
|
|
);
|
|
|
|
// cache successfully to the deno_dir
|
|
let output = test_context
|
|
.new_command()
|
|
.args("cache main.ts npm:@denotest/esm-basic@1.0.0")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export/1.0.0.tgz\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default/1.0.0.tgz\n",
|
|
"[UNORDERED_END]\n",
|
|
));
|
|
|
|
// test in dependency
|
|
{
|
|
// modify the package information in the cache to remove the latest version
|
|
remove_version_for_package(
|
|
deno_dir,
|
|
"@denotest/cjs-default-export",
|
|
"1.0.0",
|
|
);
|
|
|
|
// should error when `--cache-only` is used now because the version is not in the cache
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --cached-only main.ts")
|
|
.run();
|
|
output.assert_exit_code(1);
|
|
output.assert_matches_text("error: Could not find npm package '@denotest/cjs-default-export' matching '^1.0.0'.\n");
|
|
|
|
// now try running without it, it should download the package now
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"[UNORDERED_END]\n",
|
|
"Node esm importing node cjs\n[WILDCARD]",
|
|
));
|
|
output.assert_exit_code(0);
|
|
}
|
|
|
|
// test in npm specifier
|
|
{
|
|
// now remove the information for the top level package
|
|
remove_version_for_package(
|
|
deno_dir,
|
|
"@denotest/esm-import-cjs-default",
|
|
"1.0.0",
|
|
);
|
|
|
|
// should error for --cached-only
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --cached-only main.ts")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"error: Could not find npm package '@denotest/esm-import-cjs-default' matching '1.0.0'.\n",
|
|
" at file:///[WILDCARD]/main.ts:1:8\n",
|
|
));
|
|
output.assert_exit_code(1);
|
|
|
|
// now try running, it should work
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"[UNORDERED_END]\n",
|
|
"Node esm importing node cjs\n[WILDCARD]",
|
|
));
|
|
output.assert_exit_code(0);
|
|
}
|
|
|
|
// test matched specifier in package.json
|
|
{
|
|
// write out a package.json and a new main.ts with a bare specifier
|
|
temp_dir.write("main.ts", "import '@denotest/esm-import-cjs-default';");
|
|
temp_dir.write(
|
|
"package.json",
|
|
r#"{ "dependencies": { "@denotest/esm-import-cjs-default": "1.0.0" }}"#,
|
|
);
|
|
|
|
// remove the top level package information again
|
|
remove_version_for_package(
|
|
deno_dir,
|
|
"@denotest/esm-import-cjs-default",
|
|
"1.0.0",
|
|
);
|
|
|
|
// should error for --cached-only
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --cached-only main.ts")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"error: Could not find npm package '@denotest/esm-import-cjs-default' matching '1.0.0'.\n",
|
|
));
|
|
output.assert_exit_code(1);
|
|
|
|
// now try running, it should work
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"[UNORDERED_END]\n",
|
|
"[UNORDERED_START]\n",
|
|
"Initialize @denotest/cjs-default-export@1.0.0\n",
|
|
"Initialize @denotest/esm-import-cjs-default@1.0.0\n",
|
|
"[UNORDERED_END]\n",
|
|
"Node esm importing node cjs\n[WILDCARD]",
|
|
));
|
|
output.assert_exit_code(0);
|
|
}
|
|
|
|
// temp other dependency in package.json
|
|
{
|
|
// write out a package.json that has another dependency
|
|
temp_dir.write(
|
|
"package.json",
|
|
r#"{ "dependencies": { "@denotest/esm-import-cjs-default": "1.0.0", "@denotest/esm-basic": "1.0.0" }}"#,
|
|
);
|
|
|
|
// remove the dependency's version
|
|
remove_version_for_package(deno_dir, "@denotest/esm-basic", "1.0.0");
|
|
|
|
// should error for --cached-only
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --cached-only main.ts")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"error: Could not find npm package '@denotest/esm-basic' matching '1.0.0'.\n",
|
|
));
|
|
output.assert_exit_code(1);
|
|
|
|
// now try running, it should work and only initialize the new package
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"[UNORDERED_END]\n",
|
|
"Initialize @denotest/esm-basic@1.0.0\n",
|
|
"Node esm importing node cjs\n[WILDCARD]",
|
|
));
|
|
output.assert_exit_code(0);
|
|
}
|
|
|
|
// now try using a lockfile
|
|
{
|
|
// create it
|
|
temp_dir.write("deno.json", r#"{}"#);
|
|
test_context.new_command().args("cache main.ts").run();
|
|
assert!(temp_dir.path().join("deno.lock").exists());
|
|
|
|
// remove a version found in the lockfile
|
|
remove_version_for_package(deno_dir, "@denotest/esm-basic", "1.0.0");
|
|
|
|
// should error for --cached-only
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --cached-only main.ts")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"error: failed reading lockfile '[WILDCARD]deno.lock'\n",
|
|
"\n",
|
|
"Caused by:\n",
|
|
" 0: Could not find '@denotest/esm-basic@1.0.0' specified in the lockfile.\n",
|
|
" 1: Could not find version '1.0.0' for npm package '@denotest/esm-basic'.\n",
|
|
));
|
|
output.assert_exit_code(1);
|
|
|
|
// now try running, it should work and only initialize the new package
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(concat!(
|
|
"[UNORDERED_START]\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
|
|
"[UNORDERED_END]\n",
|
|
"Node esm importing node cjs\n[WILDCARD]",
|
|
));
|
|
output.assert_exit_code(0);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn binary_package_with_optional_dependencies() {
|
|
let context = TestContextBuilder::for_npm()
|
|
.use_copy_temp_dir("npm/binary_package")
|
|
.cwd("npm/binary_package")
|
|
.build();
|
|
|
|
let temp_dir = context.temp_dir();
|
|
let temp_dir_path = temp_dir.path();
|
|
let project_path = temp_dir_path.join("npm/binary_package");
|
|
|
|
// write empty config file so a lockfile gets created
|
|
temp_dir.write("npm/binary_package/deno.json", "{}");
|
|
|
|
// run it twice, with the first time creating the lockfile and the second using it
|
|
for i in 0..2 {
|
|
if i == 1 {
|
|
assert!(project_path.join("deno.lock").exists());
|
|
}
|
|
|
|
let output = context
|
|
.new_command()
|
|
.args("run -A --node-modules-dir main.js")
|
|
.run();
|
|
|
|
#[cfg(target_os = "windows")]
|
|
{
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_text(
|
|
"[WILDCARD]Hello from binary package on windows[WILDCARD]",
|
|
);
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
|
|
.exists());
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac")
|
|
.exists());
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
{
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_text(
|
|
"[WILDCARD]Hello from binary package on mac[WILDCARD]",
|
|
);
|
|
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
|
|
.exists());
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux")
|
|
.exists());
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac")
|
|
.exists());
|
|
}
|
|
|
|
#[cfg(target_os = "linux")]
|
|
{
|
|
output.assert_exit_code(0);
|
|
output.assert_matches_text(
|
|
"[WILDCARD]Hello from binary package on linux[WILDCARD]",
|
|
);
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
|
|
.exists());
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows")
|
|
.exists());
|
|
assert!(project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux")
|
|
.exists());
|
|
assert!(!project_path
|
|
.join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac")
|
|
.exists());
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn node_modules_dir_config_file() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let temp_dir = test_context.temp_dir();
|
|
let node_modules_dir = temp_dir.path().join("node_modules");
|
|
let rm_node_modules = || std::fs::remove_dir_all(&node_modules_dir).unwrap();
|
|
|
|
temp_dir.write("deno.json", r#"{ "nodeModulesDir": true }"#);
|
|
temp_dir.write("main.ts", "import 'npm:@denotest/esm-basic';");
|
|
|
|
let deno_cache_cmd = test_context.new_command().args("cache --quiet main.ts");
|
|
deno_cache_cmd.run();
|
|
assert!(node_modules_dir.exists());
|
|
|
|
// now try adding a vendor flag, it should exist
|
|
rm_node_modules();
|
|
temp_dir.write("deno.json", r#"{ "vendor": true }"#);
|
|
deno_cache_cmd.run();
|
|
assert!(node_modules_dir.exists());
|
|
|
|
rm_node_modules();
|
|
temp_dir.write("deno.json", r#"{ "nodeModulesDir": false }"#);
|
|
|
|
deno_cache_cmd.run();
|
|
assert!(!node_modules_dir.exists());
|
|
|
|
temp_dir.write("package.json", r#"{}"#);
|
|
deno_cache_cmd.run();
|
|
assert!(!node_modules_dir.exists());
|
|
|
|
test_context
|
|
.new_command()
|
|
.args("cache --quiet --node-modules-dir main.ts")
|
|
.run();
|
|
assert!(node_modules_dir.exists());
|
|
|
|
// should override the `--vendor` flag
|
|
rm_node_modules();
|
|
test_context
|
|
.new_command()
|
|
.args("cache --quiet --node-modules-dir=false --vendor main.ts")
|
|
.run();
|
|
assert!(!node_modules_dir.exists());
|
|
}
|
|
|
|
#[test]
|
|
fn top_level_install_package_json_explicit_opt_in() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let temp_dir = test_context.temp_dir();
|
|
let node_modules_dir = temp_dir.path().join("node_modules");
|
|
let rm_created_files = || {
|
|
std::fs::remove_dir_all(&node_modules_dir).unwrap();
|
|
std::fs::remove_file(temp_dir.path().join("deno.lock")).unwrap();
|
|
};
|
|
|
|
// when the node_modules_dir is explicitly opted into, we should always
|
|
// ensure a top level package.json install occurs
|
|
temp_dir.write("deno.json", "{ \"nodeModulesDir\": true }");
|
|
temp_dir.write(
|
|
"package.json",
|
|
"{ \"dependencies\": { \"@denotest/esm-basic\": \"1.0\" }}",
|
|
);
|
|
|
|
temp_dir.write("main.ts", "console.log(5);");
|
|
let output = test_context.new_command().args("cache main.ts").run();
|
|
output.assert_matches_text(
|
|
concat!(
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
|
|
"Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n",
|
|
"Initialize @denotest/esm-basic@1.0.0\n",
|
|
)
|
|
);
|
|
|
|
rm_created_files();
|
|
let output = test_context
|
|
.new_command()
|
|
.args_vec(["eval", "console.log(5)"])
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"Initialize @denotest/esm-basic@1.0.0\n",
|
|
"5\n"
|
|
));
|
|
|
|
rm_created_files();
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run -")
|
|
.stdin_text("console.log(5)")
|
|
.run();
|
|
output.assert_matches_text(concat!(
|
|
"Initialize @denotest/esm-basic@1.0.0\n",
|
|
"5\n"
|
|
));
|
|
|
|
// now ensure this is cached in the lsp
|
|
rm_created_files();
|
|
let mut client = test_context.new_lsp_command().build();
|
|
client.initialize_default();
|
|
let file_uri = temp_dir.uri().join("file.ts").unwrap();
|
|
client.did_open(json!({
|
|
"textDocument": {
|
|
"uri": file_uri,
|
|
"languageId": "typescript",
|
|
"version": 1,
|
|
"text": "",
|
|
}
|
|
}));
|
|
client.write_request(
|
|
"workspace/executeCommand",
|
|
json!({
|
|
"command": "deno.cache",
|
|
"arguments": [[], file_uri],
|
|
}),
|
|
);
|
|
|
|
assert!(node_modules_dir.join("@denotest").exists());
|
|
}
|
|
|
|
itest!(reserved_word_exports {
|
|
args: "run npm/reserved_word_exports/main.ts",
|
|
output: "npm/reserved_word_exports/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(import_json {
|
|
args: "run -A --quiet npm/import_json/main.js",
|
|
output: "npm/import_json/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(dynamic_import_json {
|
|
args: "run -A --quiet npm/import_json/main.js",
|
|
output: "npm/import_json/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(check_package_file_dts_dmts_dcts {
|
|
args: "check npm/file_dts_dmts_dcts/main.ts",
|
|
output: "npm/file_dts_dmts_dcts/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 1,
|
|
});
|
|
|
|
itest!(require_resolve_url_paths {
|
|
args: "run -A --quiet --node-modules-dir url_paths.ts",
|
|
output: "npm/require_resolve_url/url_paths.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
exit_code: 0,
|
|
cwd: Some("npm/require_resolve_url/"),
|
|
copy_temp_dir: Some("npm/require_resolve_url/"),
|
|
});
|
|
|
|
#[test]
|
|
fn byonm_cjs_esm_packages() {
|
|
let test_context = TestContextBuilder::for_npm()
|
|
.env("DENO_UNSTABLE_BYONM", "1")
|
|
.use_temp_cwd()
|
|
.build();
|
|
let dir = test_context.temp_dir();
|
|
|
|
test_context.run_npm("init -y");
|
|
test_context.run_npm("install @denotest/esm-basic @denotest/cjs-default-export @denotest/dual-cjs-esm chalk@4 chai@4.3");
|
|
|
|
dir.write(
|
|
"main.ts",
|
|
r#"
|
|
import { getValue, setValue } from "@denotest/esm-basic";
|
|
|
|
setValue(2);
|
|
console.log(getValue());
|
|
|
|
import cjsDefault from "@denotest/cjs-default-export";
|
|
console.log(cjsDefault.default());
|
|
console.log(cjsDefault.named());
|
|
|
|
import { getKind } from "@denotest/dual-cjs-esm";
|
|
console.log(getKind());
|
|
|
|
|
|
"#,
|
|
);
|
|
let output = test_context.new_command().args("run --check main.ts").run();
|
|
output
|
|
.assert_matches_text("Check file:///[WILDCARD]/main.ts\n2\n1\n2\nesm\n");
|
|
|
|
// should not have created the .deno directory
|
|
assert!(!dir.path().join("node_modules/.deno").exists());
|
|
|
|
// try chai
|
|
dir.write(
|
|
"chai.ts",
|
|
r#"import { expect } from "chai";
|
|
|
|
const timeout = setTimeout(() => {}, 0);
|
|
expect(timeout).to.be.a("number");
|
|
clearTimeout(timeout);"#,
|
|
);
|
|
test_context.new_command().args("run chai.ts").run();
|
|
|
|
// try chalk cjs
|
|
dir.write(
|
|
"chalk.ts",
|
|
"import chalk from 'chalk'; console.log(chalk.green('chalk cjs loads'));",
|
|
);
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --allow-read chalk.ts")
|
|
.run();
|
|
output.assert_matches_text("chalk cjs loads\n");
|
|
|
|
// try using an npm specifier for chalk that matches the version we installed
|
|
dir.write(
|
|
"chalk.ts",
|
|
"import chalk from 'npm:chalk@4'; console.log(chalk.green('chalk cjs loads'));",
|
|
);
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --allow-read chalk.ts")
|
|
.run();
|
|
output.assert_matches_text("chalk cjs loads\n");
|
|
|
|
// try with one that doesn't match the package.json
|
|
dir.write(
|
|
"chalk.ts",
|
|
"import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk cjs loads'));",
|
|
);
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --allow-read chalk.ts")
|
|
.run();
|
|
output.assert_matches_text(
|
|
r#"error: Could not find a matching package for 'npm:chalk@5' in '[WILDCARD]package.json'. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno.
|
|
at file:///[WILDCARD]chalk.ts:1:19
|
|
"#);
|
|
output.assert_exit_code(1);
|
|
}
|
|
|
|
#[test]
|
|
fn byonm_import_map() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let dir = test_context.temp_dir();
|
|
dir.write(
|
|
"deno.json",
|
|
r#"{
|
|
"imports": {
|
|
"basic": "npm:@denotest/esm-basic"
|
|
},
|
|
"unstable": [ "byonm" ]
|
|
}"#,
|
|
);
|
|
dir.write(
|
|
"package.json",
|
|
r#"{
|
|
"name": "my-project",
|
|
"version": "1.0.0",
|
|
"type": "module",
|
|
"dependencies": {
|
|
"@denotest/esm-basic": "^1.0"
|
|
}
|
|
}"#,
|
|
);
|
|
test_context.run_npm("install");
|
|
|
|
dir.write(
|
|
"main.ts",
|
|
r#"
|
|
// import map should resolve
|
|
import { getValue } from "basic";
|
|
// and resolving via node resolution
|
|
import { setValue } from "@denotest/esm-basic";
|
|
|
|
setValue(5);
|
|
console.log(getValue());
|
|
"#,
|
|
);
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text("5\n");
|
|
let output = test_context.new_command().args("check main.ts").run();
|
|
output.assert_matches_text("Check file:///[WILDCARD]/main.ts\n");
|
|
}
|
|
|
|
#[test]
|
|
fn byonm_package_specifier_not_installed_and_invalid_subpath() {
|
|
let test_context = TestContextBuilder::for_npm()
|
|
.env("DENO_UNSTABLE_BYONM", "1")
|
|
.use_temp_cwd()
|
|
.build();
|
|
let dir = test_context.temp_dir();
|
|
dir.path().join("package.json").write_json(&json!({
|
|
"dependencies": {
|
|
"chalk": "4",
|
|
"@denotest/conditional-exports-strict": "1"
|
|
}
|
|
}));
|
|
dir.write(
|
|
"main.ts",
|
|
"import chalk from 'chalk'; console.log(chalk.green('hi'));",
|
|
);
|
|
|
|
// no npm install has been run, so this should give an informative error
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(
|
|
r#"error: Could not resolve "chalk", but found it in a package.json. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`?
|
|
at file:///[WILDCARD]/main.ts:1:19
|
|
"#,
|
|
);
|
|
output.assert_exit_code(1);
|
|
|
|
// now test for an invalid sub path after doing an npm install
|
|
dir.write(
|
|
"main.ts",
|
|
"import '@denotest/conditional-exports-strict/test';",
|
|
);
|
|
|
|
test_context.run_npm("install");
|
|
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(
|
|
r#"error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDCARD]' imported from '[WILDCARD]main.ts'
|
|
at file:///[WILDCARD]/main.ts:1:8
|
|
"#,
|
|
);
|
|
output.assert_exit_code(1);
|
|
}
|
|
|
|
#[test]
|
|
fn byonm_package_npm_specifier_not_installed_and_invalid_subpath() {
|
|
let test_context = TestContextBuilder::for_npm()
|
|
.env("DENO_UNSTABLE_BYONM", "1")
|
|
.use_temp_cwd()
|
|
.build();
|
|
let dir = test_context.temp_dir();
|
|
dir.path().join("package.json").write_json(&json!({
|
|
"dependencies": {
|
|
"chalk": "4",
|
|
"@denotest/conditional-exports-strict": "1"
|
|
}
|
|
}));
|
|
dir.write(
|
|
"main.ts",
|
|
"import chalk from 'npm:chalk'; console.log(chalk.green('hi'));",
|
|
);
|
|
|
|
// no npm install has been run, so this should give an informative error
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(
|
|
r#"error: Could not find '[WILDCARD]package.json'. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`?
|
|
at file:///[WILDCARD]/main.ts:1:19
|
|
"#,
|
|
);
|
|
output.assert_exit_code(1);
|
|
|
|
// now test for an invalid sub path after doing an npm install
|
|
dir.write(
|
|
"main.ts",
|
|
"import 'npm:@denotest/conditional-exports-strict/test';",
|
|
);
|
|
|
|
test_context.run_npm("install");
|
|
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text(
|
|
r#"error: Failed resolving package subpath './test' for '[WILDCARD]package.json'
|
|
at file:///[WILDCARD]/main.ts:1:8
|
|
"#,
|
|
);
|
|
output.assert_exit_code(1);
|
|
}
|
|
|
|
#[test]
|
|
fn byonm_npm_workspaces() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let dir = test_context.temp_dir();
|
|
dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#);
|
|
|
|
dir.write(
|
|
"package.json",
|
|
r#"{
|
|
"name": "my-workspace",
|
|
"workspaces": [
|
|
"project-a",
|
|
"project-b"
|
|
]
|
|
}
|
|
"#,
|
|
);
|
|
|
|
let project_a_dir = dir.path().join("project-a");
|
|
project_a_dir.create_dir_all();
|
|
project_a_dir.join("package.json").write_json(&json!({
|
|
"name": "project-a",
|
|
"version": "1.0.0",
|
|
"main": "./index.js",
|
|
"type": "module",
|
|
"dependencies": {
|
|
"chai": "^4.2",
|
|
"project-b": "^1"
|
|
}
|
|
}));
|
|
project_a_dir.join("index.js").write(
|
|
r#"
|
|
import { expect } from "chai";
|
|
|
|
const timeout = setTimeout(() => {}, 0);
|
|
expect(timeout).to.be.a("number");
|
|
clearTimeout(timeout);
|
|
|
|
export function add(a, b) {
|
|
return a + b;
|
|
}
|
|
"#,
|
|
);
|
|
project_a_dir
|
|
.join("index.d.ts")
|
|
.write("export function add(a: number, b: number): number;");
|
|
|
|
let project_b_dir = dir.path().join("project-b");
|
|
project_b_dir.create_dir_all();
|
|
project_b_dir.join("package.json").write_json(&json!({
|
|
"name": "project-b",
|
|
"version": "1.0.0",
|
|
"type": "module",
|
|
"dependencies": {
|
|
"@denotest/esm-basic": "^1.0",
|
|
}
|
|
}));
|
|
project_b_dir.join("main.ts").write(
|
|
r#"
|
|
import { getValue, setValue } from "@denotest/esm-basic";
|
|
|
|
setValue(5);
|
|
console.log(getValue());
|
|
|
|
import { add } from "project-a";
|
|
console.log(add(1, 2));
|
|
"#,
|
|
);
|
|
|
|
test_context.run_npm("install");
|
|
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run ./project-b/main.ts")
|
|
.run();
|
|
output.assert_matches_text("5\n3\n");
|
|
let output = test_context
|
|
.new_command()
|
|
.args("check ./project-b/main.ts")
|
|
.run();
|
|
output.assert_matches_text("Check file:///[WILDCARD]/project-b/main.ts\n");
|
|
|
|
// Now a file in the main directory should just be able to
|
|
// import it via node resolution even though a package.json
|
|
// doesn't exist here
|
|
dir.write(
|
|
"main.ts",
|
|
r#"
|
|
import { getValue, setValue } from "@denotest/esm-basic";
|
|
|
|
setValue(7);
|
|
console.log(getValue());
|
|
"#,
|
|
);
|
|
let output = test_context.new_command().args("run main.ts").run();
|
|
output.assert_matches_text("7\n");
|
|
let output = test_context.new_command().args("check main.ts").run();
|
|
output.assert_matches_text("Check file:///[WILDCARD]/main.ts\n");
|
|
}
|
|
|
|
#[test]
|
|
fn cjs_export_analysis_require_re_export() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let dir = test_context.temp_dir();
|
|
dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#);
|
|
|
|
dir.write(
|
|
"package.json",
|
|
r#"{ "name": "test", "packages": { "my-package": "1.0.0" } }"#,
|
|
);
|
|
dir.write(
|
|
"main.js",
|
|
"import { value1, value2 } from 'my-package';\nconsole.log(value1);\nconsole.log(value2)\n",
|
|
);
|
|
|
|
let node_modules_dir = dir.path().join("node_modules");
|
|
|
|
// create a package at node_modules/.multipart/name/nested without a package.json
|
|
{
|
|
let pkg_dir = node_modules_dir
|
|
.join(".multipart")
|
|
.join("name")
|
|
.join("nested");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir.join("index.js").write("module.exports.value1 = 5;");
|
|
}
|
|
// create a package at node_modules/.multipart/other with a package.json
|
|
{
|
|
let pkg_dir = node_modules_dir.join(".multipart").join("other");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir.join("index.js").write("module.exports.value2 = 6;");
|
|
}
|
|
// create a package at node_modules/my-package that requires them both
|
|
{
|
|
let pkg_dir = node_modules_dir.join("my-package");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir.join("package.json").write_json(&json!({
|
|
"name": "my-package",
|
|
"version": "1.0.0",
|
|
}));
|
|
pkg_dir
|
|
.join("index.js")
|
|
.write("module.exports = { ...require('.multipart/name/nested/index'), ...require('.multipart/other/index.js') }");
|
|
}
|
|
|
|
// the cjs export analysis was previously failing, but it should
|
|
// resolve these exports similar to require
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --allow-read main.js")
|
|
.run();
|
|
output.assert_matches_text("5\n6\n");
|
|
}
|
|
|
|
#[test]
|
|
fn cjs_rexport_analysis_json() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let dir = test_context.temp_dir();
|
|
dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#);
|
|
|
|
dir.write(
|
|
"package.json",
|
|
r#"{ "name": "test", "packages": { "my-package": "1.0.0" } }"#,
|
|
);
|
|
dir.write(
|
|
"main.js",
|
|
"import data from 'my-package';\nconsole.log(data);\n",
|
|
);
|
|
|
|
let node_modules_dir = dir.path().join("node_modules");
|
|
|
|
// create a package that has a json file at index.json and data.json then folder/index.json
|
|
{
|
|
let pkg_dir = node_modules_dir.join("data-package");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir.join("package.json").write_json(&json!({
|
|
"name": "data-package",
|
|
"version": "1.0.0",
|
|
}));
|
|
pkg_dir.join("index.json").write(r#"{ "value": 2 }"#);
|
|
pkg_dir.join("data.json").write(r#"{ "value": 3 }"#);
|
|
let folder = pkg_dir.join("folder");
|
|
folder.create_dir_all();
|
|
folder.join("index.json").write(r#"{ "value": 4 }"#);
|
|
}
|
|
// create a package at node_modules/my-package that re-exports a json file
|
|
{
|
|
let pkg_dir = node_modules_dir.join("my-package");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir.join("package.json").write_json(&json!({
|
|
"name": "my-package",
|
|
"version": "1.0.0",
|
|
}));
|
|
pkg_dir.join("data.json").write(r#"{ "value": 1 }"#);
|
|
pkg_dir.join("index.js").write(
|
|
"module.exports = {
|
|
data1: require('./data'),
|
|
data2: require('data-package'),
|
|
data3: require('data-package/data'),
|
|
data4: require('data-package/folder'),
|
|
};",
|
|
);
|
|
}
|
|
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --allow-read main.js")
|
|
.run();
|
|
output.assert_matches_text(
|
|
"{
|
|
data1: { value: 1 },
|
|
data2: { value: 2 },
|
|
data3: { value: 3 },
|
|
data4: { value: 4 }
|
|
}
|
|
",
|
|
);
|
|
}
|
|
|
|
itest!(imports_package_json {
|
|
args: "run --node-modules-dir=false npm/imports_package_json/main.js",
|
|
output: "npm/imports_package_json/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(imports_package_json_import_not_defined {
|
|
args:
|
|
"run --node-modules-dir=false npm/imports_package_json/import_not_defined.js",
|
|
output: "npm/imports_package_json/import_not_defined.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 1,
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(imports_package_json_sub_path_import_not_defined {
|
|
args:
|
|
"run --node-modules-dir=false npm/imports_package_json/sub_path_import_not_defined.js",
|
|
output: "npm/imports_package_json/sub_path_import_not_defined.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 1,
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(different_nested_dep_node_modules_dir_false {
|
|
args: "run --quiet --node-modules-dir=false npm/different_nested_dep/main.js",
|
|
output: "npm/different_nested_dep/main.out",
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 0,
|
|
http_server: true,
|
|
});
|
|
|
|
itest!(different_nested_dep_node_modules_dir_true {
|
|
args: "run --quiet --node-modules-dir=true main.js",
|
|
output: "npm/different_nested_dep/main.out",
|
|
copy_temp_dir: Some("npm/different_nested_dep/"),
|
|
cwd: Some("npm/different_nested_dep/"),
|
|
envs: env_vars_for_npm_tests(),
|
|
exit_code: 0,
|
|
http_server: true,
|
|
});
|
|
|
|
#[test]
|
|
fn different_nested_dep_byonm() {
|
|
let test_context = TestContextBuilder::for_npm()
|
|
.use_copy_temp_dir("npm/different_nested_dep")
|
|
.cwd("npm/different_nested_dep/")
|
|
.build();
|
|
|
|
test_context.run_npm("install");
|
|
|
|
let output = test_context
|
|
.new_command()
|
|
.args("run --unstable-byonm main.js")
|
|
.run();
|
|
output.assert_matches_file("npm/different_nested_dep/main.out");
|
|
}
|
|
|
|
#[test]
|
|
fn run_cjs_in_node_modules_folder() {
|
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
|
let temp_dir = test_context.temp_dir();
|
|
temp_dir.write("package.json", "{}");
|
|
temp_dir.write("deno.json", r#"{ "unstable": ["byonm"] }"#);
|
|
let pkg_dir = temp_dir.path().join("node_modules/package");
|
|
pkg_dir.create_dir_all();
|
|
pkg_dir
|
|
.join("package.json")
|
|
.write(r#"{ "name": "package" }"#);
|
|
pkg_dir
|
|
.join("main.js")
|
|
.write("console.log('hi'); module.exports = 'hi';");
|
|
test_context
|
|
.new_command()
|
|
.args("run node_modules/package/main.js")
|
|
.run()
|
|
.assert_matches_text("hi\n");
|
|
}
|