summaryrefslogtreecommitdiff
path: root/tests/integration/lsp_tests.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-07-18 18:16:35 -0400
committerGitHub <noreply@github.com>2024-07-18 18:16:35 -0400
commit3bda8eb4fe059fd79a522c9277a5a872f75dc270 (patch)
tree172d04d91223694c494b754d39c44ac5851575ac /tests/integration/lsp_tests.rs
parent1722e0aebfd830b7cbc0824ace5de0517072d0dc (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.rs211
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&#8203;{}\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&#8203;{}\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&#8203;{}\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();