diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2023-05-22 21:28:36 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-22 21:28:36 -0400 |
commit | bb37dfb5b79c0e5ae18d34f01313cb1f39d7a2dd (patch) | |
tree | eed3c2a5ed443933e6809b4c9541c75b651fb38f /cli/tests | |
parent | 58782589528dc442e2a1fdf6d98454cbf01ac2ad (diff) |
feat(lsp): support lockfile and node_modules directory (#19203)
This adds support for the lockfile and node_modules directory to the
lsp.
In the case of the node_modules directory, it is only enabled when
explicitly opted into via `"nodeModulesDir": true` in the configuration
file. This is to reduce the language server automatically modifying the
node_modules directory when the user doesn't want it to.
Closes #16510
Closes #16373
Diffstat (limited to 'cli/tests')
-rw-r--r-- | cli/tests/integration/inspector_tests.rs | 10 | ||||
-rw-r--r-- | cli/tests/integration/lsp_tests.rs | 144 |
2 files changed, 145 insertions, 9 deletions
diff --git a/cli/tests/integration/inspector_tests.rs b/cli/tests/integration/inspector_tests.rs index 8fa9ec85c..f94dd221b 100644 --- a/cli/tests/integration/inspector_tests.rs +++ b/cli/tests/integration/inspector_tests.rs @@ -18,6 +18,7 @@ use test_util as util; use test_util::TempDir; use tokio::net::TcpStream; use url::Url; +use util::assert_starts_with; use util::http_server; use util::DenoChild; @@ -217,15 +218,6 @@ impl InspectorTester { } } -macro_rules! assert_starts_with { - ($string:expr, $($test:expr),+) => { - let string = $string; // This might be a function call or something - if !($(string.starts_with($test))||+) { - panic!("{:?} does not start with {:?}", string, [$($test),+]); - } - } - } - fn assert_stderr( stderr_lines: &mut impl std::iter::Iterator<Item = String>, expected_lines: &[&str], diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs index 656ec9ade..db009999b 100644 --- a/cli/tests/integration/lsp_tests.rs +++ b/cli/tests/integration/lsp_tests.rs @@ -9,8 +9,10 @@ use deno_core::url::Url; use pretty_assertions::assert_eq; use std::fs; use std::process::Stdio; +use test_util::assert_starts_with; use test_util::deno_cmd_with_deno_dir; use test_util::env_vars_for_npm_tests; +use test_util::lsp::LspClient; use test_util::testdata_path; use test_util::TestContextBuilder; use tower_lsp::lsp_types as lsp; @@ -7540,3 +7542,145 @@ fn lsp_data_urls_with_jsx_compiler_option() { client.shutdown(); } + +#[test] +fn lsp_node_modules_dir() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + + // having a package.json should have no effect on whether + // a node_modules dir is created + temp_dir.write("package.json", "{}"); + + let mut client = 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": "import chalk from 'npm:chalk';\nimport path from 'node:path';\n\nconsole.log(chalk.green(path.join('a', 'b')));", + } + })); + let cache = |client: &mut LspClient| { + client.write_request( + "deno/cache", + json!({ + "referrer": { + "uri": file_uri, + }, + "uris": [ + { + "uri": "npm:chalk", + }, + { + "uri": "npm:@types/node", + } + ] + }), + ); + }; + + cache(&mut client); + + assert!(!temp_dir.path().join("node_modules").exists()); + + temp_dir.write( + temp_dir.path().join("deno.json"), + "{ \"nodeModulesDir\": true, \"lock\": false }\n", + ); + let refresh_config = |client: &mut LspClient| { + client.write_notification( + "workspace/didChangeConfiguration", + json!({ + "settings": { + "enable": true, + "config": "./deno.json", + } + }), + ); + + let request = json!([{ + "enable": true, + "config": "./deno.json", + "codeLens": { + "implementations": true, + "references": true + }, + "importMap": null, + "lint": false, + "suggest": { + "autoImports": true, + "completeFunctionCalls": false, + "names": true, + "paths": true, + "imports": {} + }, + "unstable": false + }]); + // one for the workspace + client.handle_configuration_request(request.clone()); + // one for the specifier + client.handle_configuration_request(request); + }; + refresh_config(&mut client); + + let diagnostics = client.read_diagnostics(); + assert_eq!(diagnostics.viewed().len(), 2); // not cached + + cache(&mut client); + + assert!(temp_dir.path().join("node_modules/chalk").exists()); + assert!(temp_dir.path().join("node_modules/@types/node").exists()); + assert!(!temp_dir.path().join("deno.lock").exists()); + + // now add a lockfile and cache + temp_dir.write( + temp_dir.path().join("deno.json"), + "{ \"nodeModulesDir\": true }\n", + ); + refresh_config(&mut client); + cache(&mut client); + + let diagnostics = client.read_diagnostics(); + assert_eq!(diagnostics.viewed().len(), 0, "{:#?}", diagnostics); + + assert!(temp_dir.path().join("deno.lock").exists()); + + // the declaration should be found in the node_modules directory + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": file_uri, + }, + "position": { "line": 0, "character": 7 }, // chalk + "context": { + "includeDeclaration": false + } + }), + ); + + // ensure that it's using the node_modules directory + let references = res.as_array().unwrap(); + assert_eq!(references.len(), 2, "references: {:#?}", references); + let uri = references[1] + .as_object() + .unwrap() + .get("uri") + .unwrap() + .as_str() + .unwrap(); + // canonicalize for mac + let path = temp_dir.path().join("node_modules").canonicalize().unwrap(); + assert_starts_with!( + uri, + ModuleSpecifier::from_file_path(&path).unwrap().as_str() + ); + + client.shutdown(); +} |