mirror of
https://github.com/kbwo/testing-language-server.git
synced 2025-07-24 03:15:00 +00:00
parent
1b74a7ad4f
commit
0ae8988cc5
4 changed files with 133 additions and 23 deletions
17
.vim/coc-settings.json
Normal file
17
.vim/coc-settings.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"testing.enable": true,
|
||||
"testing.fileTypes": ["rust"],
|
||||
"testing.adapterCommand": {
|
||||
"rust": [
|
||||
{
|
||||
"path": "testing-ls-adapter",
|
||||
"extra_args": ["--test-kind=cargo-test", "--workspace"],
|
||||
"include_patterns": ["/**/*.rs"],
|
||||
"exclude_patterns": ["/test_proj/**/*"],
|
||||
"workspace_dir": "."
|
||||
}
|
||||
]
|
||||
},
|
||||
"testing.server.path": "testing-language-server",
|
||||
"testing.trace.server": "verbose"
|
||||
}
|
|
@ -7,6 +7,7 @@ use crate::spec::RunFileTestResult;
|
|||
use crate::spec::RunFileTestResultItem;
|
||||
use crate::spec::WorkspaceAnalysis;
|
||||
use crate::util::format_uri;
|
||||
use crate::util::resolve_path;
|
||||
use crate::util::send_stdout;
|
||||
use glob::Pattern;
|
||||
use lsp_types::Diagnostic;
|
||||
|
@ -35,6 +36,7 @@ use serde::Deserialize;
|
|||
use serde_json::json;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::env::current_dir;
|
||||
use std::io::BufRead;
|
||||
use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
|
@ -46,7 +48,6 @@ use std::process::Output;
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InitializedOptions {
|
||||
adapter_command: HashMap<AdapterId, Vec<AdapterConfiguration>>,
|
||||
project_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub struct TestingLS {
|
||||
|
@ -71,18 +72,18 @@ impl TestingLS {
|
|||
}
|
||||
|
||||
fn project_dir(&self) -> Result<PathBuf, LSError> {
|
||||
let default_project_dir = self
|
||||
.initialize_params
|
||||
.clone()
|
||||
.workspace_folders
|
||||
.ok_or(LSError::Any(anyhow::anyhow!("No workspace folders found")))?;
|
||||
let default_workspace_uri = default_project_dir[0].uri.clone();
|
||||
let project_dir = self
|
||||
.options
|
||||
.project_dir
|
||||
.clone()
|
||||
.unwrap_or(default_workspace_uri.to_file_path().unwrap());
|
||||
Ok(project_dir)
|
||||
let cwd = current_dir();
|
||||
if let Ok(cwd) = cwd {
|
||||
Ok(cwd)
|
||||
} else {
|
||||
let default_project_dir = self
|
||||
.initialize_params
|
||||
.clone()
|
||||
.workspace_folders
|
||||
.ok_or(LSError::Any(anyhow::anyhow!("No workspace folders found")))?;
|
||||
let default_workspace_uri = default_project_dir[0].uri.clone();
|
||||
Ok(default_workspace_uri.to_file_path().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_loop(&mut self) -> Result<(), LSError> {
|
||||
|
@ -278,6 +279,8 @@ impl TestingLS {
|
|||
envs,
|
||||
include_patterns,
|
||||
exclude_patterns,
|
||||
workspace_dir,
|
||||
..
|
||||
} = &adapter;
|
||||
let file_paths =
|
||||
Self::project_files(&project_dir, include_patterns, exclude_patterns);
|
||||
|
@ -301,6 +304,19 @@ impl TestingLS {
|
|||
let adapter_result = String::from_utf8(output.stdout)
|
||||
.map_err(|err| LSError::Adapter(err.to_string()))?;
|
||||
let workspace: DetectWorkspaceResult = serde_json::from_str(&adapter_result)?;
|
||||
let workspace = if let Some(workspace_dir) = workspace_dir {
|
||||
let workspace_dir = resolve_path(&project_dir, workspace_dir)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
let target_paths = workspace
|
||||
.into_iter()
|
||||
.flat_map(|kv| kv.1)
|
||||
.collect::<Vec<_>>();
|
||||
HashMap::from([(workspace_dir.clone(), target_paths)])
|
||||
} else {
|
||||
workspace
|
||||
};
|
||||
self.workspaces_cache
|
||||
.push(WorkspaceAnalysis::new(adapter.clone(), workspace))
|
||||
}
|
||||
|
@ -572,7 +588,6 @@ mod tests {
|
|||
},
|
||||
options: InitializedOptions {
|
||||
adapter_command: HashMap::from([(String::from(".rs"), vec![])]),
|
||||
project_dir: None,
|
||||
},
|
||||
workspaces_cache: Vec::new(),
|
||||
};
|
||||
|
@ -593,9 +608,7 @@ mod tests {
|
|||
let adapter_conf = AdapterConfiguration {
|
||||
path: abs_path_of_rust_adapter,
|
||||
extra_args: vec!["--test-kind=cargo-test".to_string()],
|
||||
envs: HashMap::new(),
|
||||
include_patterns: vec![],
|
||||
exclude_patterns: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
let mut server = TestingLS {
|
||||
initialize_params: InitializeParams {
|
||||
|
@ -607,7 +620,6 @@ mod tests {
|
|||
},
|
||||
options: InitializedOptions {
|
||||
adapter_command: HashMap::from([(String::from(".rs"), vec![adapter_conf])]),
|
||||
project_dir: None,
|
||||
},
|
||||
workspaces_cache: Vec::new(),
|
||||
};
|
||||
|
@ -659,9 +671,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.to_string(),
|
||||
extra_args: vec!["--invalid-arg".to_string()],
|
||||
envs: HashMap::new(),
|
||||
include_patterns: vec![],
|
||||
exclude_patterns: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
let abs_path_of_test_proj = std::env::current_dir().unwrap().join("test_proj/rust");
|
||||
let files = TestingLS::project_files(
|
||||
|
@ -680,7 +690,6 @@ mod tests {
|
|||
},
|
||||
options: InitializedOptions {
|
||||
adapter_command: HashMap::from([(String::from(".rs"), vec![adapter_conf.clone()])]),
|
||||
project_dir: None,
|
||||
},
|
||||
workspaces_cache: Vec::new(),
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ impl WorkspaceAnalysis {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
#[derive(Debug, Deserialize, Clone, Serialize, Default)]
|
||||
pub struct AdapterConfiguration {
|
||||
pub path: String,
|
||||
#[serde(default)]
|
||||
|
@ -71,6 +71,7 @@ pub struct AdapterConfiguration {
|
|||
pub envs: HashMap<String, String>,
|
||||
pub include_patterns: Vec<String>,
|
||||
pub exclude_patterns: Vec<String>,
|
||||
pub workspace_dir: Option<String>,
|
||||
}
|
||||
|
||||
pub type DetectWorkspaceResult = HashMap<WorkspaceFilePath, Vec<FilePath>>;
|
||||
|
|
83
src/util.rs
83
src/util.rs
|
@ -2,6 +2,8 @@ use crate::error::LSError;
|
|||
use serde::Serialize;
|
||||
use std::io::stdout;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn send_stdout<T>(message: &T) -> Result<(), LSError>
|
||||
where
|
||||
|
@ -18,3 +20,84 @@ where
|
|||
pub fn format_uri(uri: &str) -> String {
|
||||
uri.replace("file://", "")
|
||||
}
|
||||
|
||||
pub fn resolve_path(base_dir: &Path, relative_path: &str) -> PathBuf {
|
||||
let absolute = if Path::new(relative_path).is_absolute() {
|
||||
PathBuf::from(relative_path)
|
||||
} else {
|
||||
base_dir.join(relative_path)
|
||||
};
|
||||
|
||||
let mut components = Vec::new();
|
||||
for component in absolute.components() {
|
||||
match component {
|
||||
std::path::Component::ParentDir => {
|
||||
components.pop();
|
||||
}
|
||||
std::path::Component::Normal(_) | std::path::Component::RootDir => {
|
||||
components.push(component);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
PathBuf::from_iter(components)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_resolve_path() {
|
||||
let base_dir = PathBuf::from("/Users/test/projects");
|
||||
|
||||
// relative path
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "github.com/hoge/fuga"),
|
||||
PathBuf::from("/Users/test/projects/github.com/hoge/fuga")
|
||||
);
|
||||
|
||||
// current directory
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "./github.com/hoge/fuga"),
|
||||
PathBuf::from("/Users/test/projects/github.com/hoge/fuga")
|
||||
);
|
||||
|
||||
// parent directory
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "../other/project"),
|
||||
PathBuf::from("/Users/test/other/project")
|
||||
);
|
||||
|
||||
// multiple ..
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "foo/bar/../../../baz"),
|
||||
PathBuf::from("/Users/test/baz")
|
||||
);
|
||||
|
||||
// absolute path
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "/absolute/path"),
|
||||
PathBuf::from("/absolute/path")
|
||||
);
|
||||
|
||||
// empty relative path
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, ""),
|
||||
PathBuf::from("/Users/test/projects")
|
||||
);
|
||||
|
||||
// ending /
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "github.com/hoge/fuga/"),
|
||||
PathBuf::from("/Users/test/projects/github.com/hoge/fuga")
|
||||
);
|
||||
|
||||
// complex path
|
||||
assert_eq!(
|
||||
resolve_path(&base_dir, "./foo/../bar/./baz/../qux/"),
|
||||
PathBuf::from("/Users/test/projects/bar/qux")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue