diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-07-18 18:16:35 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-18 18:16:35 -0400 |
commit | 3bda8eb4fe059fd79a522c9277a5a872f75dc270 (patch) | |
tree | 172d04d91223694c494b754d39c44ac5851575ac /tests/integration/lsp_tests.rs | |
parent | 1722e0aebfd830b7cbc0824ace5de0517072d0dc (diff) |
fix(lsp): support npm workspaces and fix some resolution issues (#24627)
Makes the lsp use the same code as the rest of the cli.
Diffstat (limited to 'tests/integration/lsp_tests.rs')
-rw-r--r-- | tests/integration/lsp_tests.rs | 211 |
1 files changed, 179 insertions, 32 deletions
diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 2e2e00942..ae859a650 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -11917,6 +11917,11 @@ fn lsp_node_modules_dir() { assert!(!temp_dir.path().join("node_modules").exists()); + // a lockfile will be created here because someone did an explicit cache + let lockfile_path = temp_dir.path().join("deno.lock"); + assert!(lockfile_path.exists()); + lockfile_path.remove_file(); + temp_dir.write( temp_dir.path().join("deno.json"), "{ \"nodeModulesDir\": true, \"lock\": false }\n", @@ -11950,7 +11955,7 @@ fn lsp_node_modules_dir() { 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()); + assert!(!lockfile_path.exists()); // was disabled // now add a lockfile and cache temp_dir.write( @@ -11963,7 +11968,7 @@ fn lsp_node_modules_dir() { let diagnostics = client.read_diagnostics(); assert_eq!(diagnostics.all().len(), 0, "{:#?}", diagnostics); - assert!(temp_dir.path().join("deno.lock").exists()); + assert!(lockfile_path.exists()); // the declaration should be found in the node_modules directory let res = client.write_request( @@ -13315,9 +13320,9 @@ fn lsp_deno_json_workspace_fmt_config() { json!([{ "range": { "start": { "line": 0, "character": 12 }, - "end": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 16 }, }, - "newText": "''", + "newText": "'')", }]) ); // `project2/file.ts` should use the fmt settings from `deno.json`, since it @@ -13449,6 +13454,15 @@ fn lsp_deno_json_workspace_lint_config() { "code": "ban-untagged-todo", "source": "deno-lint", "message": "TODO should be tagged with (@username) or (#issue)\nAdd a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123)", + }, { + "range": { + "start": { "line": 2, "character": 14 }, + "end": { "line": 2, "character": 28 }, + }, + "severity": 2, + "code": "camelcase", + "source": "deno-lint", + "message": "Identifier 'snake_case_var' is not in camel case.\nConsider renaming `snake_case_var` to `snakeCaseVar`", }], "version": 1, }) @@ -13513,8 +13527,8 @@ fn lsp_deno_json_workspace_import_map() { temp_dir.write("project1/foo1.ts", ""); temp_dir.write( "project1/project2/deno.json", - // Should ignore and inherit import map from `project1/deno.json`. json!({ + // should overwrite the "foo" entry in the parent for this scope "imports": { "foo": "./foo2.ts", }, @@ -13524,36 +13538,74 @@ fn lsp_deno_json_workspace_import_map() { temp_dir.write("project1/project2/foo2.ts", ""); let mut client = context.new_lsp_command().build(); client.initialize_default(); - client.did_open(json!({ - "textDocument": { - "uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(), - "languageId": "typescript", - "version": 1, - "text": "import \"foo\";\n", - }, - })); - let res = client.write_request( - "textDocument/hover", - json!({ + + // project1 resolution + { + client.did_open(json!({ "textDocument": { - "uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(), - }, - "position": { "line": 0, "character": 7 }, - }), - ); - assert_eq!( - res, - json!({ - "contents": { - "kind": "markdown", - "value": format!("**Resolved Dependency**\n\n**Code**: file​{}\n", temp_dir.uri().join("project1/foo1.ts").unwrap().as_str().trim_start_matches("file")), + "uri": temp_dir.uri().join("project1/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import \"foo\";\n", }, - "range": { - "start": { "line": 0, "character": 7 }, - "end": { "line": 0, "character": 12 }, + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("project1/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 7 }, + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": format!("**Resolved Dependency**\n\n**Code**: file​{}\n", temp_dir.uri().join("project1/foo1.ts").unwrap().as_str().trim_start_matches("file")), + }, + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 12 }, + }, + }) + ); + } + + // project1/project2 resolution + { + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import \"foo\";\n", }, - }) - ); + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 7 }, + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": format!("**Resolved Dependency**\n\n**Code**: file​{}\n", temp_dir.uri().join("project1/project2/foo2.ts").unwrap().as_str().trim_start_matches("file")), + }, + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 12 }, + }, + }) + ); + } client.shutdown(); } @@ -13828,6 +13880,101 @@ fn lsp_deno_json_workspace_jsr_resolution() { } #[test] +fn lsp_npm_workspace() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "package.json", + json!({ + "workspaces": ["packages/*"] + }) + .to_string(), + ); + { + temp_dir.create_dir_all("packages/add"); + temp_dir.write( + "packages/add/package.json", + json!({ + "name": "add", + "version": "1.0.0", + "exports": "./index.ts" + }) + .to_string(), + ); + temp_dir.write( + "packages/add/index.ts", + "export function add(a: number, b: number): number { return a + b; }", + ); + } + { + temp_dir.create_dir_all("packages/subtract"); + temp_dir.write( + "packages/subtract/package.json", + json!({ + "name": "add", + "version": "1.0.0", + "exports": "./index.ts", + "dependencies": { + "add": "^1.0.0" + } + }) + .to_string(), + ); + } + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("packages/subtract/index.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import { add } from 'add';\nexport function subtract(a: number, b: number): number { return add(a, -b); }", + }, + })); + assert_eq!(json!(diagnostics.all()), json!([])); + let res = client.write_request( + "textDocument/definition", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("packages/subtract/index.ts").unwrap(), + }, + "position": { "line": 0, "character": 9 }, + }), + ); + // The temp dir is symlinked on the CI + assert_eq!( + res, + json!([{ + "targetUri": temp_dir.uri().join("packages/add/index.ts").unwrap(), + "targetRange": { + "start": { + "line": 0, + "character": 0, + }, + "end": { + "line": 0, + "character": 67, + }, + }, + "targetSelectionRange": { + "start": { + "line": 0, + "character": 16, + }, + "end": { + "line": 0, + "character": 19, + }, + }, + }]), + ); + client.shutdown(); +} + +#[test] fn lsp_import_unstable_bare_node_builtins_auto_discovered() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); |