Compare commits

...

24 commits
v0.1.8 ... main

Author SHA1 Message Date
kbwo
c53cdb6a6b chore: v0.1.12 2025-01-29 22:53:29 +09:00
kbwo
df261d6756 fix: avoid incremental syncing
Basically, this LSP server diagnose code when saved
2025-01-29 22:52:50 +09:00
kbwo
48af0e012c chore: v0.1.11 2025-01-04 19:14:37 +09:00
kbwo
b8c0aa330c docs: update README 2025-01-04 19:14:18 +09:00
kbwo
03c298280b chore: remove debug log 2025-01-04 19:12:40 +09:00
kbwo
969010845a docs: update README 2025-01-04 19:12:28 +09:00
kbwo
87d463c36e chore(adpater); v0.1.2 2024-12-25 23:35:49 +09:00
kbwo
7b56fbcbe4 feat: remove "\n" prefix in node test diagnostic message 2024-12-25 23:35:07 +09:00
kbwo
855d2c0094 feat(adapter): add path field for server v0.1.10 2024-12-25 23:34:31 +09:00
kbwo
a766099b76 chore: v0.1.10 2024-12-25 23:32:06 +09:00
kbwo
4df71f69c0 feat: add path field to TestItem for demand from adapter 2024-12-25 23:31:26 +09:00
kbwo
5b8862fe5d chore: v0.1.9 2024-12-24 18:24:52 +09:00
kbwo
833bfbc1b7 fix: prevent diagnostics to be cleared when :edit in vim 2024-12-24 18:24:37 +09:00
kbwo
42354d8ec5 refactor(server): fix for clippy 2024-12-24 17:27:42 +09:00
kbwo
5a672ddf71 chore(adapter): 0.1.1 2024-12-24 17:12:17 +09:00
kbwo
caa4463119 Merge branch 'fix/adapter-types' 2024-12-24 17:11:52 +09:00
kbwo
942f0b4ed1 fix(adapter): return valid json type to server 2024-12-24 17:11:06 +09:00
Kodai Kabasawa
91db91a229
Merge pull request #53 from kbwo/feat/update-adapter-spec
adapter: Update specification
2024-12-07 23:28:10 +09:00
kbwo
6c75bbbd47 chore(adapter): v0.1.0 2024-12-07 23:25:23 +09:00
kbwo
1df3076259 refactor: delete unused variable 2024-12-07 23:24:54 +09:00
kbwo
787e92fe87 feat(adapter): use new interface of detect-workspace 2024-12-07 23:24:28 +09:00
kbwo
df0631a6d6 feat(adapter): use new interface of discover 2024-12-07 23:24:23 +09:00
kbwo
2fa914973f feat(adapter): use new interface of run-file-test 2024-12-07 23:24:17 +09:00
kbwo
1fae0f701a chore(adapter): update adapter dependency 2024-12-07 23:24:03 +09:00
18 changed files with 226 additions and 166 deletions

12
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
@ -723,9 +723,9 @@ dependencies = [
[[package]] [[package]]
name = "testing-language-server" name = "testing-language-server"
version = "0.1.7" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fae6ce9cb290e80814d1796e4207a0a0dc21c216807136d48b68c0f27be29b9" checksum = "70cedb2999008b364b1686c77a9e34531f1a31095f3177cfc11500d0ab5bd727"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -749,7 +749,7 @@ dependencies = [
[[package]] [[package]]
name = "testing-language-server" name = "testing-language-server"
version = "0.1.8" version = "0.1.12"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -773,7 +773,7 @@ dependencies = [
[[package]] [[package]]
name = "testing-ls-adapter" name = "testing-ls-adapter"
version = "0.0.11" version = "0.1.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -783,7 +783,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"tempfile", "tempfile",
"testing-language-server 0.1.7", "testing-language-server 0.1.10",
"tracing", "tracing",
"tracing-appender", "tracing-appender",
"tracing-subscriber", "tracing-subscriber",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "testing-language-server" name = "testing-language-server"
version = "0.1.8" version = "0.1.12"
edition = "2021" edition = "2021"
description = "LSP server for testing" description = "LSP server for testing"
license = "MIT" license = "MIT"

View file

@ -30,7 +30,7 @@ cargo install testing-ls-adapter
- [x] Realtime testing diagnostics - [x] Realtime testing diagnostics
- [x] [VSCode extension](https://github.com/kbwo/vscode-testing-ls) - [x] [VSCode extension](https://github.com/kbwo/vscode-testing-ls)
- [x] [coc.nvim extension](https://github.com/kbwo/coc-testing-ls) - [x] [coc.nvim extension](https://github.com/kbwo/coc-testing-ls)
- [x] For Neovim builtin LSP, see [demo/README.md](./demo/README.md) - [x] For Neovim builtin LSP, see [testing-ls.nvim](https://github.com/kbwo/testing-ls.nvim)
- [ ] More efficient checking of diagnostics - [ ] More efficient checking of diagnostics
- [ ] Useful commands in each extension - [ ] Useful commands in each extension
@ -102,28 +102,7 @@ You can see the example in [See more example](./.vim/coc-settings.json)
### Neovim (nvim-lspconfig) ### Neovim (nvim-lspconfig)
```lua See [testing-ls.nvim](https://github.com/kbwo/testing-ls.nvim)
local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')
local util = require "lspconfig/util"
configs.testing_ls = {
default_config = {
cmd = { "testing-language-server" },
filetypes = {},
root_dir = util.root_pattern(".testingls.toml", ".git" ),
},
docs = {
description = [[
https://github.com/kbwo/testing-language-server
Language Server for real-time testing.
]],
},
}
lspconfig.testing_ls.setup{}
```
### Helix ### Helix
See [language.toml](./demo/.helix/language.toml). See [language.toml](./demo/.helix/language.toml).

View file

@ -1,6 +1,6 @@
[package] [package]
name = "testing-ls-adapter" name = "testing-ls-adapter"
version = "0.0.11" version = "0.1.2"
edition = "2021" edition = "2021"
description = "testing-language-server adapter" description = "testing-language-server adapter"
license = "MIT" license = "MIT"
@ -8,7 +8,7 @@ license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
testing-language-server = "0.1.7" testing-language-server = "0.1.10"
lsp-types = { workspace = true } lsp-types = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
serde = { workspace = true } serde = { workspace = true }

View file

@ -8,8 +8,8 @@ pub struct Log;
impl Log { impl Log {
fn log_dir() -> PathBuf { fn log_dir() -> PathBuf {
let home_dir = dirs::home_dir().unwrap(); let home_dir = dirs::home_dir().unwrap();
let log_path = home_dir.join(".config/testing_language_server/adapter/logs");
log_path home_dir.join(".config/testing_language_server/adapter/logs")
} }
pub fn init() -> Result<WorkerGuard, anyhow::Error> { pub fn init() -> Result<WorkerGuard, anyhow::Error> {

View file

@ -7,7 +7,7 @@ use testing_language_server::spec::DetectWorkspaceResult;
use testing_language_server::spec::RunFileTestResult; use testing_language_server::spec::RunFileTestResult;
use testing_language_server::spec::DiscoverResult; use testing_language_server::spec::DiscoverResult;
use testing_language_server::spec::DiscoverResultItem; use testing_language_server::spec::FoundFileTests;
use testing_language_server::spec::TestItem; use testing_language_server::spec::TestItem;
use crate::model::Runner; use crate::model::Runner;
@ -28,11 +28,11 @@ impl Runner for CargoNextestRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
let tests = discover_rust_tests(&file_path)?; let tests = discover_rust_tests(&file_path)?;
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests, tests,
path: file_path, path: file_path,
}); });
@ -106,7 +106,7 @@ impl Runner for CargoNextestRunner {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
use testing_language_server::spec::{RunFileTestResultItem, TestItem}; use testing_language_server::spec::{FileDiagnostics, TestItem};
use crate::runner::util::MAX_CHAR_LENGTH; use crate::runner::util::MAX_CHAR_LENGTH;
@ -136,6 +136,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
let test_items: Vec<TestItem> = vec![TestItem { let test_items: Vec<TestItem> = vec![TestItem {
id: "rocks::dependency::tests::parse_dependency".to_string(), id: "rocks::dependency::tests::parse_dependency".to_string(),
name: "rocks::dependency::tests::parse_dependency".to_string(), name: "rocks::dependency::tests::parse_dependency".to_string(),
path: "/home/example/projects/rocks-lib/src/rocks/dependency.rs".to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 85, line: 85,
@ -171,24 +172,27 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
assert_eq!( assert_eq!(
diagnostics, diagnostics,
vec![RunFileTestResultItem { RunFileTestResult {
path: file_paths.first().unwrap().to_owned(), data: vec![FileDiagnostics {
diagnostics: vec![Diagnostic { path: file_paths.first().unwrap().to_owned(),
range: Range { diagnostics: vec![Diagnostic {
start: Position { range: Range {
line: 85, start: Position {
character: 63 line: 85,
character: 63
},
end: Position {
line: 85,
character: MAX_CHAR_LENGTH
}
}, },
end: Position { message: message.to_string(),
line: 85, severity: Some(DiagnosticSeverity::ERROR),
character: MAX_CHAR_LENGTH ..Diagnostic::default()
} }]
}, }],
message: message.to_string(), messages: vec!()
severity: Some(DiagnosticSeverity::ERROR), }
..Diagnostic::default()
}]
}]
) )
} }
@ -211,8 +215,10 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
.collect(); .collect();
let workspaces = detect_workspaces(&file_paths); let workspaces = detect_workspaces(&file_paths);
assert_eq!(workspaces.len(), 2); assert_eq!(workspaces.data.len(), 2);
assert!(workspaces.contains_key(absolute_path_of_demo.to_str().unwrap())); assert!(workspaces
assert!(workspaces.contains_key(current_dir.to_str().unwrap())); .data
.contains_key(absolute_path_of_demo.to_str().unwrap()));
assert!(workspaces.data.contains_key(current_dir.to_str().unwrap()));
} }
} }

View file

@ -7,7 +7,7 @@ use testing_language_server::spec::DetectWorkspaceResult;
use testing_language_server::spec::RunFileTestResult; use testing_language_server::spec::RunFileTestResult;
use testing_language_server::spec::DiscoverResult; use testing_language_server::spec::DiscoverResult;
use testing_language_server::spec::DiscoverResultItem; use testing_language_server::spec::FoundFileTests;
use testing_language_server::spec::TestItem; use testing_language_server::spec::TestItem;
use crate::model::Runner; use crate::model::Runner;
@ -28,11 +28,11 @@ impl Runner for CargoTestRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
let tests = discover_rust_tests(&file_path)?; let tests = discover_rust_tests(&file_path)?;
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests, tests,
path: file_path, path: file_path,
}); });
@ -101,7 +101,7 @@ impl Runner for CargoTestRunner {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
use testing_language_server::spec::RunFileTestResultItem; use testing_language_server::spec::FileDiagnostics;
use crate::runner::util::MAX_CHAR_LENGTH; use crate::runner::util::MAX_CHAR_LENGTH;
@ -131,6 +131,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
let test_items: Vec<TestItem> = vec![TestItem { let test_items: Vec<TestItem> = vec![TestItem {
id: "rocks::dependency::tests::parse_dependency".to_string(), id: "rocks::dependency::tests::parse_dependency".to_string(),
name: "rocks::dependency::tests::parse_dependency".to_string(), name: "rocks::dependency::tests::parse_dependency".to_string(),
path: "/home/example/projects/rocks-lib/src/rocks/dependency.rs".to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 85, line: 85,
@ -166,24 +167,27 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
assert_eq!( assert_eq!(
diagnostics, diagnostics,
vec![RunFileTestResultItem { RunFileTestResult {
path: file_paths.first().unwrap().to_owned(), data: vec![FileDiagnostics {
diagnostics: vec![Diagnostic { path: file_paths.first().unwrap().to_owned(),
range: Range { diagnostics: vec![Diagnostic {
start: Position { range: Range {
line: 85, start: Position {
character: 63 line: 85,
character: 63
},
end: Position {
line: 85,
character: MAX_CHAR_LENGTH
}
}, },
end: Position { message: message.to_string(),
line: 85, severity: Some(DiagnosticSeverity::ERROR),
character: MAX_CHAR_LENGTH ..Diagnostic::default()
} }]
}, }],
message: message.to_string(), messages: vec![]
severity: Some(DiagnosticSeverity::ERROR), }
..Diagnostic::default()
}]
}]
) )
} }
@ -206,8 +210,10 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
.collect(); .collect();
let workspaces = detect_workspaces(&file_paths); let workspaces = detect_workspaces(&file_paths);
assert_eq!(workspaces.len(), 2); assert_eq!(workspaces.data.len(), 2);
assert!(workspaces.contains_key(absolute_path_of_demo.to_str().unwrap())); assert!(workspaces
assert!(workspaces.contains_key(current_dir.to_str().unwrap())); .data
.contains_key(absolute_path_of_demo.to_str().unwrap()));
assert!(workspaces.data.contains_key(current_dir.to_str().unwrap()));
} }
} }

View file

@ -13,9 +13,9 @@ use testing_language_server::error::LSError;
use testing_language_server::spec::DetectWorkspaceResult; use testing_language_server::spec::DetectWorkspaceResult;
use testing_language_server::spec::DiscoverResult; use testing_language_server::spec::DiscoverResult;
use testing_language_server::spec::DiscoverResultItem; use testing_language_server::spec::FileDiagnostics;
use testing_language_server::spec::FoundFileTests;
use testing_language_server::spec::RunFileTestResult; use testing_language_server::spec::RunFileTestResult;
use testing_language_server::spec::RunFileTestResultItem;
use testing_language_server::spec::TestItem; use testing_language_server::spec::TestItem;
use crate::model::Runner; use crate::model::Runner;
@ -89,10 +89,13 @@ fn parse_diagnostics(
message += line; message += line;
} }
} }
Ok(result_map Ok(RunFileTestResult {
.into_iter() data: result_map
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics }) .into_iter()
.collect()) .map(|(path, diagnostics)| FileDiagnostics { path, diagnostics })
.collect(),
messages: vec![],
})
} }
fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult { fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult {
@ -161,9 +164,9 @@ impl Runner for DenoRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests: discover(&file_path)?, tests: discover(&file_path)?,
path: file_path, path: file_path,
}) })
@ -229,7 +232,7 @@ mod tests {
let target_file_path = "/home/demo/test/dneo/main_test.ts"; let target_file_path = "/home/demo/test/dneo/main_test.ts";
let diagnostics = let diagnostics =
parse_diagnostics(&test_result, workspace, &[target_file_path.to_string()]).unwrap(); parse_diagnostics(&test_result, workspace, &[target_file_path.to_string()]).unwrap();
assert_eq!(diagnostics.len(), 1); assert_eq!(diagnostics.data.len(), 1);
} }
#[test] #[test]
@ -242,8 +245,8 @@ mod tests {
.map(|file_path| file_path.to_str().unwrap().to_string()) .map(|file_path| file_path.to_str().unwrap().to_string())
.collect(); .collect();
let detect_result = detect_workspaces(file_paths); let detect_result = detect_workspaces(file_paths);
assert_eq!(detect_result.len(), 1); assert_eq!(detect_result.data.len(), 1);
detect_result.iter().for_each(|(workspace, _)| { detect_result.data.iter().for_each(|(workspace, _)| {
assert_eq!(workspace, absolute_path_of_demo.to_str().unwrap()); assert_eq!(workspace, absolute_path_of_demo.to_str().unwrap());
}); });
} }
@ -260,6 +263,7 @@ mod tests {
TestItem { TestItem {
id: String::from("addTest"), id: String::from("addTest"),
name: String::from("addTest"), name: String::from("addTest"),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 7, line: 7,
@ -284,6 +288,7 @@ mod tests {
TestItem { TestItem {
id: String::from("fail1"), id: String::from("fail1"),
name: String::from("fail1"), name: String::from("fail1"),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 11, line: 11,
@ -308,6 +313,7 @@ mod tests {
TestItem { TestItem {
id: String::from("fail2"), id: String::from("fail2"),
name: String::from("fail2"), name: String::from("fail2"),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 15, line: 15,

View file

@ -13,9 +13,9 @@ use std::process::Output;
use std::str::FromStr; use std::str::FromStr;
use testing_language_server::error::LSError; use testing_language_server::error::LSError;
use testing_language_server::spec::DiscoverResult; use testing_language_server::spec::DiscoverResult;
use testing_language_server::spec::DiscoverResultItem; use testing_language_server::spec::FileDiagnostics;
use testing_language_server::spec::FoundFileTests;
use testing_language_server::spec::RunFileTestResult; use testing_language_server::spec::RunFileTestResult;
use testing_language_server::spec::RunFileTestResultItem;
use testing_language_server::spec::TestItem; use testing_language_server::spec::TestItem;
use super::util::detect_workspaces_from_file_list; use super::util::detect_workspaces_from_file_list;
@ -130,10 +130,13 @@ fn parse_diagnostics(
} }
} }
Ok(result_map Ok(RunFileTestResult {
.into_iter() data: result_map
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics }) .into_iter()
.collect()) .map(|(path, diagnostics)| FileDiagnostics { path, diagnostics })
.collect(),
messages: vec![],
})
} }
fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> { fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
@ -232,11 +235,11 @@ impl Runner for GoTestRunner {
args: testing_language_server::spec::DiscoverArgs, args: testing_language_server::spec::DiscoverArgs,
) -> Result<(), testing_language_server::error::LSError> { ) -> Result<(), testing_language_server::error::LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
let tests = discover(&file_path)?; let tests = discover(&file_path)?;
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests, tests,
path: file_path, path: file_path,
}); });
@ -305,7 +308,7 @@ mod tests {
let target_file_path = "/home/demo/test/go/src/test/cases_test.go"; let target_file_path = "/home/demo/test/go/src/test/cases_test.go";
let result = let result =
parse_diagnostics(&contents, workspace, &[target_file_path.to_string()]).unwrap(); parse_diagnostics(&contents, workspace, &[target_file_path.to_string()]).unwrap();
let result = result.first().unwrap(); let result = result.data.first().unwrap();
assert_eq!(result.path, target_file_path); assert_eq!(result.path, target_file_path);
let diagnostic = result.diagnostics.first().unwrap(); let diagnostic = result.diagnostics.first().unwrap();
assert_eq!(diagnostic.range.start.line, 30); assert_eq!(diagnostic.range.start.line, 30);

View file

@ -8,9 +8,9 @@ use testing_language_server::error::LSError;
use testing_language_server::spec::DetectWorkspaceResult; use testing_language_server::spec::DetectWorkspaceResult;
use testing_language_server::spec::DiscoverResult; use testing_language_server::spec::DiscoverResult;
use testing_language_server::spec::DiscoverResultItem; use testing_language_server::spec::FileDiagnostics;
use testing_language_server::spec::FoundFileTests;
use testing_language_server::spec::RunFileTestResult; use testing_language_server::spec::RunFileTestResult;
use testing_language_server::spec::RunFileTestResultItem;
use testing_language_server::spec::TestItem; use testing_language_server::spec::TestItem;
use crate::model::Runner; use crate::model::Runner;
@ -67,10 +67,13 @@ fn parse_diagnostics(
}) })
} }
} }
Ok(result_map Ok(RunFileTestResult {
.into_iter() data: result_map
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics }) .into_iter()
.collect()) .map(|(path, diagnostics)| FileDiagnostics { path, diagnostics })
.collect(),
messages: vec![],
})
} }
fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult { fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult {
@ -159,9 +162,9 @@ impl Runner for JestRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests: discover(&file_path)?, tests: discover(&file_path)?,
path: file_path, path: file_path,
}) })
@ -229,7 +232,7 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
assert_eq!(diagnostics.len(), 2); assert_eq!(diagnostics.data.len(), 2);
} }
#[test] #[test]
@ -242,8 +245,8 @@ mod tests {
.map(|file_path| file_path.to_str().unwrap().to_string()) .map(|file_path| file_path.to_str().unwrap().to_string())
.collect(); .collect();
let detect_result = detect_workspaces(file_paths); let detect_result = detect_workspaces(file_paths);
assert_eq!(detect_result.len(), 1); assert_eq!(detect_result.data.len(), 1);
detect_result.iter().for_each(|(workspace, _)| { detect_result.data.iter().for_each(|(workspace, _)| {
assert_eq!(workspace, absolute_path_of_demo.to_str().unwrap()); assert_eq!(workspace, absolute_path_of_demo.to_str().unwrap());
}); });
} }
@ -258,6 +261,7 @@ mod tests {
vec![TestItem { vec![TestItem {
id: String::from("index::fail"), id: String::from("index::fail"),
name: String::from("index::fail"), name: String::from("index::fail"),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 1, line: 1,

View file

@ -4,8 +4,8 @@ use regex::Regex;
use testing_language_server::{ use testing_language_server::{
error::LSError, error::LSError,
spec::{ spec::{
DetectWorkspaceResult, DiscoverResult, DiscoverResultItem, RunFileTestResult, DetectWorkspaceResult, DiscoverResult, FileDiagnostics, FoundFileTests, RunFileTestResult,
RunFileTestResultItem, TestItem, TestItem,
}, },
}; };
use xml::{reader::XmlEvent, ParserConfig}; use xml::{reader::XmlEvent, ParserConfig};
@ -100,7 +100,8 @@ fn get_result_from_characters(
continue; continue;
} }
return Ok(ResultFromXml { return Ok(ResultFromXml {
message: error_text.to_string(), // remove prefix because it's like "\n"
message: error_text.strip_prefix("\n").unwrap().to_string(),
path: file_path.to_string(), path: file_path.to_string(),
line: caps[2].parse::<u32>().unwrap(), line: caps[2].parse::<u32>().unwrap(),
col: caps[3].parse::<u32>().unwrap(), col: caps[3].parse::<u32>().unwrap(),
@ -162,9 +163,9 @@ impl Runner for NodeTestRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests: discover(&file_path)?, tests: discover(&file_path)?,
path: file_path, path: file_path,
}) })
@ -194,14 +195,18 @@ impl Runner for NodeTestRunner {
} }
let stdout = String::from_utf8(stdout).unwrap(); let stdout = String::from_utf8(stdout).unwrap();
let result_from_xml = get_result_from_xml(&stdout, &file_paths)?; let result_from_xml = get_result_from_xml(&stdout, &file_paths)?;
let diagnostics: RunFileTestResult = result_from_xml let result_item: Vec<FileDiagnostics> = result_from_xml
.into_iter() .into_iter()
.map(|result_from_xml| { .map(|result_from_xml| {
let result_item: RunFileTestResultItem = result_from_xml.into(); let result_item: FileDiagnostics = result_from_xml.into();
result_item result_item
}) })
.collect(); .collect();
send_stdout(&diagnostics)?; let result = RunFileTestResult {
data: result_item,
messages: vec![],
};
send_stdout(&result)?;
Ok(()) Ok(())
} }
@ -266,6 +271,7 @@ mod tests {
TestItem { TestItem {
id: "synchronous passing test".to_string(), id: "synchronous passing test".to_string(),
name: "synchronous passing test".to_string(), name: "synchronous passing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 5, line: 5,
@ -290,6 +296,7 @@ mod tests {
TestItem { TestItem {
id: "synchronous failing test".to_string(), id: "synchronous failing test".to_string(),
name: "synchronous failing test".to_string(), name: "synchronous failing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 10, line: 10,
@ -314,6 +321,7 @@ mod tests {
TestItem { TestItem {
id: "asynchronous passing test".to_string(), id: "asynchronous passing test".to_string(),
name: "asynchronous passing test".to_string(), name: "asynchronous passing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 15, line: 15,
@ -338,6 +346,7 @@ mod tests {
TestItem { TestItem {
id: "asynchronous failing test".to_string(), id: "asynchronous failing test".to_string(),
name: "asynchronous failing test".to_string(), name: "asynchronous failing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 21, line: 21,
@ -362,6 +371,7 @@ mod tests {
TestItem { TestItem {
id: "failing test using Promises".to_string(), id: "failing test using Promises".to_string(),
name: "failing test using Promises".to_string(), name: "failing test using Promises".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 27, line: 27,
@ -386,6 +396,7 @@ mod tests {
TestItem { TestItem {
id: "callback passing test".to_string(), id: "callback passing test".to_string(),
name: "callback passing test".to_string(), name: "callback passing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 36, line: 36,
@ -410,6 +421,7 @@ mod tests {
TestItem { TestItem {
id: "callback failing test".to_string(), id: "callback failing test".to_string(),
name: "callback failing test".to_string(), name: "callback failing test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 42, line: 42,
@ -434,6 +446,7 @@ mod tests {
TestItem { TestItem {
id: "top level test".to_string(), id: "top level test".to_string(),
name: "top level test".to_string(), name: "top level test".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 51, line: 51,
@ -458,6 +471,7 @@ mod tests {
TestItem { TestItem {
id: "skip option".to_string(), id: "skip option".to_string(),
name: "skip option".to_string(), name: "skip option".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 63, line: 63,
@ -482,6 +496,7 @@ mod tests {
TestItem { TestItem {
id: "skip option with message".to_string(), id: "skip option with message".to_string(),
name: "skip option with message".to_string(), name: "skip option with message".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 68, line: 68,
@ -506,6 +521,7 @@ mod tests {
TestItem { TestItem {
id: "skip() method".to_string(), id: "skip() method".to_string(),
name: "skip() method".to_string(), name: "skip() method".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 72, line: 72,
@ -530,6 +546,7 @@ mod tests {
TestItem { TestItem {
id: "skip() method with message".to_string(), id: "skip() method with message".to_string(),
name: "skip() method with message".to_string(), name: "skip() method with message".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 77, line: 77,
@ -554,6 +571,7 @@ mod tests {
TestItem { TestItem {
id: "todo option".to_string(), id: "todo option".to_string(),
name: "todo option".to_string(), name: "todo option".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 84, line: 84,
@ -578,6 +596,7 @@ mod tests {
TestItem { TestItem {
id: "todo option with message".to_string(), id: "todo option with message".to_string(),
name: "todo option with message".to_string(), name: "todo option with message".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 90, line: 90,
@ -602,6 +621,7 @@ mod tests {
TestItem { TestItem {
id: "todo() method".to_string(), id: "todo() method".to_string(),
name: "todo() method".to_string(), name: "todo() method".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 94, line: 94,
@ -626,6 +646,7 @@ mod tests {
TestItem { TestItem {
id: "todo() method with message".to_string(), id: "todo() method with message".to_string(),
name: "todo() method with message".to_string(), name: "todo() method with message".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 98, line: 98,
@ -650,6 +671,7 @@ mod tests {
TestItem { TestItem {
id: "A thing::should work".to_string(), id: "A thing::should work".to_string(),
name: "A thing::should work".to_string(), name: "A thing::should work".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 105, line: 105,
@ -674,6 +696,7 @@ mod tests {
TestItem { TestItem {
id: "A thing::should be ok".to_string(), id: "A thing::should be ok".to_string(),
name: "A thing::should be ok".to_string(), name: "A thing::should be ok".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 109, line: 109,
@ -698,6 +721,7 @@ mod tests {
TestItem { TestItem {
id: "A thing::a nested thing::should work".to_string(), id: "A thing::a nested thing::should work".to_string(),
name: "A thing::a nested thing::should work".to_string(), name: "A thing::a nested thing::should work".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 114, line: 114,
@ -722,6 +746,7 @@ mod tests {
TestItem { TestItem {
id: "only: this test is run".to_string(), id: "only: this test is run".to_string(),
name: "only: this test is run".to_string(), name: "only: this test is run".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 123, line: 123,
@ -746,6 +771,7 @@ mod tests {
TestItem { TestItem {
id: "only: this test is not run".to_string(), id: "only: this test is not run".to_string(),
name: "only: this test is not run".to_string(), name: "only: this test is not run".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 142, line: 142,
@ -770,6 +796,7 @@ mod tests {
TestItem { TestItem {
id: "A suite::this test is run A ".to_string(), id: "A suite::this test is run A ".to_string(),
name: "A suite::this test is run A ".to_string(), name: "A suite::this test is run A ".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 149, line: 149,
@ -794,6 +821,7 @@ mod tests {
TestItem { TestItem {
id: "A suite::this test is not run B".to_string(), id: "A suite::this test is not run B".to_string(),
name: "A suite::this test is not run B".to_string(), name: "A suite::this test is not run B".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 153, line: 153,
@ -818,6 +846,7 @@ mod tests {
TestItem { TestItem {
id: "this test is run C".to_string(), id: "this test is run C".to_string(),
name: "this test is run C".to_string(), name: "this test is run C".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 161, line: 161,
@ -842,6 +871,7 @@ mod tests {
TestItem { TestItem {
id: "this test is run D".to_string(), id: "this test is run D".to_string(),
name: "this test is run D".to_string(), name: "this test is run D".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 165, line: 165,
@ -866,6 +896,7 @@ mod tests {
TestItem { TestItem {
id: "import from external file. this must be fail".to_string(), id: "import from external file. this must be fail".to_string(),
name: "import from external file. this must be fail".to_string(), name: "import from external file. this must be fail".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 170, line: 170,

View file

@ -3,8 +3,8 @@ use std::io::BufReader;
use std::process::Output; use std::process::Output;
use testing_language_server::error::LSError; use testing_language_server::error::LSError;
use testing_language_server::spec::{ use testing_language_server::spec::{
DetectWorkspaceResult, DiscoverResult, DiscoverResultItem, RunFileTestResult, DetectWorkspaceResult, DiscoverResult, FileDiagnostics, FoundFileTests, RunFileTestResult,
RunFileTestResultItem, TestItem, TestItem,
}; };
use xml::reader::{ParserConfig, XmlEvent}; use xml::reader::{ParserConfig, XmlEvent};
@ -125,9 +125,9 @@ impl Runner for PhpunitRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests: discover(&file_path)?, tests: discover(&file_path)?,
path: file_path, path: file_path,
}) })
@ -177,14 +177,18 @@ impl Runner for PhpunitRunner {
return Err(LSError::Adapter(String::from_utf8(stderr).unwrap())); return Err(LSError::Adapter(String::from_utf8(stderr).unwrap()));
} }
let result_from_xml = get_result_from_xml(log_path.to_str().unwrap())?; let result_from_xml = get_result_from_xml(log_path.to_str().unwrap())?;
let diagnostics: RunFileTestResult = result_from_xml let result_item: Vec<FileDiagnostics> = result_from_xml
.into_iter() .into_iter()
.map(|result_from_xml| { .map(|result_from_xml| {
let result_item: RunFileTestResultItem = result_from_xml.into(); let result_item: FileDiagnostics = result_from_xml.into();
result_item result_item
}) })
.collect(); .collect();
send_stdout(&diagnostics)?; let result = RunFileTestResult {
data: result_item,
messages: vec![],
};
send_stdout(&result)?;
Ok(()) Ok(())
} }
@ -236,6 +240,7 @@ mod tests {
TestItem { TestItem {
id: "CalculatorTest::testAdd".to_string(), id: "CalculatorTest::testAdd".to_string(),
name: "CalculatorTest::testAdd".to_string(), name: "CalculatorTest::testAdd".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 9, line: 9,
@ -260,6 +265,7 @@ mod tests {
TestItem { TestItem {
id: "CalculatorTest::testSubtract".to_string(), id: "CalculatorTest::testSubtract".to_string(),
name: "CalculatorTest::testSubtract".to_string(), name: "CalculatorTest::testSubtract".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 16, line: 16,
@ -284,6 +290,7 @@ mod tests {
TestItem { TestItem {
id: "CalculatorTest::testFail1".to_string(), id: "CalculatorTest::testFail1".to_string(),
name: "CalculatorTest::testFail1".to_string(), name: "CalculatorTest::testFail1".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 23, line: 23,

View file

@ -8,7 +8,7 @@ use std::sync::LazyLock;
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
use regex::Regex; use regex::Regex;
use serde::Serialize; use serde::Serialize;
use testing_language_server::spec::{RunFileTestResultItem, TestItem}; use testing_language_server::spec::{DetectWorkspaceResult, FileDiagnostics, TestItem};
use testing_language_server::{error::LSError, spec::RunFileTestResult}; use testing_language_server::{error::LSError, spec::RunFileTestResult};
use tree_sitter::{Language, Point, Query, QueryCursor}; use tree_sitter::{Language, Point, Query, QueryCursor};
@ -30,9 +30,10 @@ pub struct ResultFromXml {
pub col: u32, pub col: u32,
} }
impl Into<RunFileTestResultItem> for ResultFromXml { #[allow(clippy::from_over_into)]
fn into(self) -> RunFileTestResultItem { impl Into<FileDiagnostics> for ResultFromXml {
RunFileTestResultItem { fn into(self) -> FileDiagnostics {
FileDiagnostics {
path: self.path, path: self.path,
diagnostics: vec![Diagnostic { diagnostics: vec![Diagnostic {
message: self.message, message: self.message,
@ -73,7 +74,7 @@ fn detect_workspace_from_file(file_path: PathBuf, file_names: &[String]) -> Opti
pub fn detect_workspaces_from_file_list( pub fn detect_workspaces_from_file_list(
target_file_paths: &[String], target_file_paths: &[String],
file_names: &[String], file_names: &[String],
) -> HashMap<String, Vec<String>> { ) -> DetectWorkspaceResult {
let mut result_map: HashMap<String, Vec<String>> = HashMap::new(); let mut result_map: HashMap<String, Vec<String>> = HashMap::new();
let mut file_paths = target_file_paths.to_vec(); let mut file_paths = target_file_paths.to_vec();
file_paths.sort_by_key(|b| b.len()); file_paths.sort_by_key(|b| b.len());
@ -105,7 +106,7 @@ pub fn detect_workspaces_from_file_list(
} }
} }
} }
result_map DetectWorkspaceResult { data: result_map }
} }
pub fn send_stdout<T>(value: &T) -> Result<(), LSError> pub fn send_stdout<T>(value: &T) -> Result<(), LSError>
@ -239,6 +240,7 @@ pub fn discover_with_treesitter(
let test_item = TestItem { let test_item = TestItem {
id: test_id.clone(), id: test_id.clone(),
name: test_id, name: test_id,
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: test_start_position.row as u32, line: test_start_position.row as u32,
@ -292,18 +294,21 @@ pub fn parse_cargo_diagnostics(
// relaive path // relaive path
let relative_file_path = m.get(2).unwrap().as_str().to_string(); let relative_file_path = m.get(2).unwrap().as_str().to_string();
// name of the file without extension
let file_stem = Path::new(&relative_file_path)
.file_stem()
.unwrap()
.to_str()
.unwrap();
let executed_test_id = id_with_file.replace(&(file_stem.to_string() + "::"), "");
if let Some(file_path) = file_paths.iter().find(|path| { if let Some(file_path) = file_paths.iter().find(|path| {
path.contains(workspace_root.join(&relative_file_path).to_str().unwrap()) path.contains(workspace_root.join(&relative_file_path).to_str().unwrap())
}) { }) {
let matched_test_item = test_items.iter().find(|item| item.id == executed_test_id); let matched_test_item = test_items.iter().find(|item| {
let item_path = item.path.strip_prefix(workspace_root.to_str().unwrap()).unwrap_or(&item.path);
let item_path = item_path.strip_suffix(".rs").unwrap_or(item_path);
let item_path = item_path.replace('/', "::")
.replace("::src::lib", "")
.replace("::src::main", "")
.replace("::src::", "");
let exact_id = format!("{}::{}", item_path, item.id);
tracing::info!("DEBUGPRINT[7]: util.rs:301: item_path={:#?}, exact_id={:#?}, id_with_file={:#?}", item_path, exact_id, id_with_file);
exact_id == id_with_file
});
let lnum = m.get(3).unwrap().as_str().parse::<u32>().unwrap() - 1; let lnum = m.get(3).unwrap().as_str().parse::<u32>().unwrap() - 1;
let col = m.get(4).unwrap().as_str().parse::<u32>().unwrap() - 1; let col = m.get(4).unwrap().as_str().parse::<u32>().unwrap() - 1;
@ -357,7 +362,7 @@ pub fn parse_cargo_diagnostics(
..Diagnostic::default() ..Diagnostic::default()
}; };
result_map result_map
.entry(file_path.to_string()) .entry(test_item.path.to_string())
.or_default() .or_default()
.push(diagnostic); .push(diagnostic);
} }
@ -371,10 +376,15 @@ pub fn parse_cargo_diagnostics(
} }
} }
result_map let data = result_map
.into_iter() .into_iter()
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics }) .map(|(path, diagnostics)| FileDiagnostics { path, diagnostics })
.collect() .collect();
RunFileTestResult {
data,
messages: vec![],
}
} }
/// remove this function because duplicate implementation /// remove this function because duplicate implementation

View file

@ -7,9 +7,7 @@ use lsp_types::{Diagnostic, DiagnosticSeverity};
use serde_json::Value; use serde_json::Value;
use testing_language_server::{ use testing_language_server::{
error::LSError, error::LSError,
spec::{ spec::{DiscoverResult, FileDiagnostics, FoundFileTests, RunFileTestResult, TestItem},
DiscoverResult, DiscoverResultItem, RunFileTestResult, RunFileTestResultItem, TestItem,
},
}; };
use crate::model::Runner; use crate::model::Runner;
@ -124,21 +122,24 @@ fn parse_diagnostics(
}) })
} }
} }
Ok(result_map Ok(RunFileTestResult {
.into_iter() data: result_map
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics }) .into_iter()
.collect()) .map(|(path, diagnostics)| FileDiagnostics { path, diagnostics })
.collect(),
messages: vec![],
})
} }
impl Runner for VitestRunner { impl Runner for VitestRunner {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> { fn discover(&self, args: testing_language_server::spec::DiscoverArgs) -> Result<(), LSError> {
let file_paths = args.file_paths; let file_paths = args.file_paths;
let mut discover_results: DiscoverResult = vec![]; let mut discover_results: DiscoverResult = DiscoverResult { data: vec![] };
for file_path in file_paths { for file_path in file_paths {
let tests = discover(&file_path)?; let tests = discover(&file_path)?;
discover_results.push(DiscoverResultItem { discover_results.data.push(FoundFileTests {
tests, tests,
path: file_path, path: file_path,
}); });
@ -212,6 +213,7 @@ mod tests {
TestItem { TestItem {
id: "describe text::pass".to_string(), id: "describe text::pass".to_string(),
name: "describe text::pass".to_string(), name: "describe text::pass".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 4, line: 4,
@ -236,6 +238,7 @@ mod tests {
TestItem { TestItem {
id: "describe text::fail".to_string(), id: "describe text::fail".to_string(),
name: "describe text::fail".to_string(), name: "describe text::fail".to_string(),
path: file_path.to_string(),
start_position: Range { start_position: Range {
start: Position { start: Position {
line: 8, line: 8,

View file

@ -7,8 +7,8 @@ pub struct Log;
impl Log { impl Log {
fn log_dir() -> PathBuf { fn log_dir() -> PathBuf {
let home_dir = dirs::home_dir().unwrap(); let home_dir = dirs::home_dir().unwrap();
let log_path = home_dir.join(".config/testing_language_server/logs");
log_path home_dir.join(".config/testing_language_server/logs")
} }
pub fn init() -> Result<WorkerGuard, anyhow::Error> { pub fn init() -> Result<WorkerGuard, anyhow::Error> {

View file

@ -74,11 +74,10 @@ fn main_loop(server: &mut TestingLS) -> Result<(), LSError> {
handle.read_exact(&mut buf).unwrap(); handle.read_exact(&mut buf).unwrap();
let message = String::from_utf8(buf).unwrap(); let message = String::from_utf8(buf).unwrap();
let value: Value = serde_json::from_str(&message)?; let received_json: Value = serde_json::from_str(&message)?;
let method = &value["method"].as_str(); tracing::info!("received json={:#?}", received_json);
tracing::info!("method={:#?}", method); let method = &received_json["method"].as_str();
let params = &value["params"]; let params = &received_json["params"];
tracing::info!("params={:#?}", params);
if let Some(method) = method { if let Some(method) = method {
match *method { match *method {
@ -89,11 +88,11 @@ fn main_loop(server: &mut TestingLS) -> Result<(), LSError> {
} }
"initialize" => { "initialize" => {
let initialize_params = InitializeParams::deserialize(params)?; let initialize_params = InitializeParams::deserialize(params)?;
let id = value["id"].as_i64().unwrap(); let id = received_json["id"].as_i64().unwrap();
server.initialize(id, initialize_params)?; server.initialize(id, initialize_params)?;
} }
"shutdown" => { "shutdown" => {
let id = value["id"].as_i64().unwrap(); let id = received_json["id"].as_i64().unwrap();
server.shutdown(id)?; server.shutdown(id)?;
} }
"exit" => { "exit" => {
@ -125,7 +124,7 @@ fn main_loop(server: &mut TestingLS) -> Result<(), LSError> {
server.diagnose_workspace()?; server.diagnose_workspace()?;
} }
"$/discoverFileTest" => { "$/discoverFileTest" => {
let id = value["id"].as_i64().unwrap(); let id = received_json["id"].as_i64().unwrap();
let uri = extract_uri(params)?; let uri = extract_uri(params)?;
let result = server.discover_file(&uri)?; let result = server.discover_file(&uri)?;
send_stdout(&json!({ send_stdout(&json!({
@ -136,7 +135,7 @@ fn main_loop(server: &mut TestingLS) -> Result<(), LSError> {
} }
_ => { _ => {
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#responseMessage // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#responseMessage
let id = value["id"].as_i64(); let id = received_json["id"].as_i64();
if id.is_some() { if id.is_some() {
send_error( send_error(
id, id,

View file

@ -128,6 +128,7 @@ impl TestingLS {
workspace_diagnostics: true, workspace_diagnostics: true,
work_done_progress_options: WorkDoneProgressOptions::default(), work_done_progress_options: WorkDoneProgressOptions::default(),
})), })),
text_document_sync: Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::NONE)),
..ServerCapabilities::default() ..ServerCapabilities::default()
} }
} }

View file

@ -102,6 +102,11 @@ pub struct RunFileTestResult {
pub struct TestItem { pub struct TestItem {
pub id: String, pub id: String,
pub name: String, pub name: String,
/// Although FoundFileTests also has a `path` field, we keep the `path` field in TestItem
/// because sometimes we need to determine where a TestItem is located on its own
/// Example: In Rust tests, determining which file contains a test from IDs like relative::path::tests::id
/// TODO: Remove FoundFileTests.path once we confirm it's no longer needed
pub path: String,
pub start_position: Range, pub start_position: Range,
pub end_position: Range, pub end_position: Range,
} }