mirror of
https://github.com/kbwo/testing-language-server.git
synced 2025-08-03 15:18:16 +00:00
refactor(adapter): unify repetitive code patterns
This commit is contained in:
parent
bb1a163f98
commit
d8bd53d4ca
6 changed files with 36 additions and 304 deletions
|
@ -15,8 +15,6 @@ use super::util::detect_workspaces_from_file_paths;
|
|||
use super::util::discover_rust_tests;
|
||||
use super::util::parse_cargo_diagnostics;
|
||||
|
||||
// If the character value is greater than the line length it defaults back to the line length.
|
||||
|
||||
fn parse_diagnostics(
|
||||
contents: &str,
|
||||
workspace_root: PathBuf,
|
||||
|
|
|
@ -17,14 +17,12 @@ use testing_language_server::spec::DiscoverResultItem;
|
|||
use testing_language_server::spec::RunFileTestResult;
|
||||
use testing_language_server::spec::RunFileTestResultItem;
|
||||
use testing_language_server::spec::TestItem;
|
||||
use tree_sitter::Point;
|
||||
use tree_sitter::Query;
|
||||
use tree_sitter::QueryCursor;
|
||||
|
||||
use crate::model::Runner;
|
||||
|
||||
use super::util::clean_ansi;
|
||||
use super::util::detect_workspaces_from_file_paths;
|
||||
use super::util::discover_with_treesitter;
|
||||
use super::util::MAX_CHAR_LENGTH;
|
||||
|
||||
fn get_position_from_output(line: &str) -> Option<(String, u32, u32)> {
|
||||
|
@ -101,16 +99,9 @@ fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult {
|
|||
}
|
||||
|
||||
fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(&tree_sitter_javascript::language())
|
||||
.expect("Error loading JavaScript grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
// from https://github.com/MarkEmmons/neotest-deno/blob/7136b9342aeecb675c7c16a0bde327d7fcb00a1c/lua/neotest-deno/init.lua#L93
|
||||
// license: https://github.com/MarkEmmons/neotest-deno/blob/main/LICENSE
|
||||
let query_string = r#"
|
||||
let query = r#"
|
||||
;; Deno.test
|
||||
(call_expression
|
||||
function: (member_expression) @func_name (#match? @func_name "^Deno.test$")
|
||||
|
@ -159,66 +150,7 @@ fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
|||
]
|
||||
) @test.definition
|
||||
"#;
|
||||
let query = Query::new(&tree_sitter_javascript::language(), query_string)
|
||||
.expect("Error creating query");
|
||||
let mut cursor = QueryCursor::new();
|
||||
cursor.set_byte_range(tree.root_node().byte_range());
|
||||
let source = source_code.as_bytes();
|
||||
let matches = cursor.matches(&query, tree.root_node(), source);
|
||||
for m in matches {
|
||||
eprintln!("DEBUGPRINT[3]: deno.rs:170: m={:#?}", m);
|
||||
let mut namespace_name = "";
|
||||
let mut test_start_position = Point::default();
|
||||
let mut test_end_position = Point::default();
|
||||
for capture in m.captures {
|
||||
let capture_name = query.capture_names()[capture.index as usize];
|
||||
let value = capture.node.utf8_text(source)?;
|
||||
let start_position = capture.node.start_position();
|
||||
let end_position = capture.node.end_position();
|
||||
match capture_name {
|
||||
"namespace.name" => {
|
||||
namespace_name = value;
|
||||
}
|
||||
"test.definition" => {
|
||||
test_start_position = start_position;
|
||||
test_end_position = end_position;
|
||||
}
|
||||
"test.name" => {
|
||||
let test_name = value;
|
||||
let test_item = TestItem {
|
||||
id: format!("{}:{}", namespace_name, test_name),
|
||||
name: test_name.to_string(),
|
||||
start_position: Range {
|
||||
start: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: test_start_position.column as u32,
|
||||
},
|
||||
end: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: MAX_CHAR_LENGTH,
|
||||
},
|
||||
},
|
||||
end_position: Range {
|
||||
start: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: 0,
|
||||
},
|
||||
end: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: test_end_position.column as u32,
|
||||
},
|
||||
},
|
||||
};
|
||||
test_items.push(test_item);
|
||||
test_start_position = Point::default();
|
||||
test_end_position = Point::default();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(test_items)
|
||||
discover_with_treesitter(file_path, &tree_sitter_javascript::language(), query)
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
|
|
|
@ -17,14 +17,10 @@ use testing_language_server::spec::DiscoverResultItem;
|
|||
use testing_language_server::spec::RunFileTestResult;
|
||||
use testing_language_server::spec::RunFileTestResultItem;
|
||||
use testing_language_server::spec::TestItem;
|
||||
use tree_sitter::Point;
|
||||
use tree_sitter::Query;
|
||||
use tree_sitter::QueryCursor;
|
||||
|
||||
use super::util::detect_workspaces_from_file_paths;
|
||||
|
||||
// If the character value is greater than the line length it defaults back to the line length.
|
||||
const MAX_CHAR_LENGTH: u32 = 10000;
|
||||
use super::util::discover_with_treesitter;
|
||||
use super::util::MAX_CHAR_LENGTH;
|
||||
|
||||
#[derive(Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -140,16 +136,9 @@ fn parse_diagnostics(
|
|||
}
|
||||
|
||||
fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(&tree_sitter_go::language())
|
||||
.expect("Error loading Rust grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
// from https://github.com/nvim-neotest/neotest-go/blob/92950ad7be2ca02a41abca5c6600ff6ffaf5b5d6/lua/neotest-go/init.lua#L54
|
||||
// license: https://github.com/nvim-neotest/neotest-go/blob/92950ad7be2ca02a41abca5c6600ff6ffaf5b5d6/README.md
|
||||
let query_string = r#"
|
||||
let query = r#"
|
||||
;;query
|
||||
((function_declaration
|
||||
name: (identifier) @test.name)
|
||||
|
@ -230,66 +219,7 @@ fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
|||
((identifier) @test.key.name1
|
||||
(#eq? @test.key.name @test.key.name1))))))))
|
||||
"#;
|
||||
let query =
|
||||
Query::new(&tree_sitter_go::language(), query_string).expect("Error creating query");
|
||||
|
||||
let mut cursor = QueryCursor::new();
|
||||
cursor.set_byte_range(tree.root_node().byte_range());
|
||||
let source = source_code.as_bytes();
|
||||
let matches = cursor.matches(&query, tree.root_node(), source);
|
||||
for m in matches {
|
||||
let mut namespace_name = "";
|
||||
let mut test_start_position = Point::default();
|
||||
let mut test_end_position = Point::default();
|
||||
for capture in m.captures {
|
||||
let capture_name = query.capture_names()[capture.index as usize];
|
||||
let value = capture.node.utf8_text(source)?;
|
||||
let start_position = capture.node.start_position();
|
||||
let end_position = capture.node.end_position();
|
||||
match capture_name {
|
||||
"namespace.name" => {
|
||||
namespace_name = value;
|
||||
}
|
||||
"test.definition" => {
|
||||
test_start_position = start_position;
|
||||
test_end_position = end_position;
|
||||
}
|
||||
"test.name" => {
|
||||
let test_name = value;
|
||||
let test_item = TestItem {
|
||||
id: format!("{}:{}", namespace_name, test_name),
|
||||
name: test_name.to_string(),
|
||||
start_position: Range {
|
||||
start: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: test_start_position.column as u32,
|
||||
},
|
||||
end: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: MAX_CHAR_LENGTH,
|
||||
},
|
||||
},
|
||||
end_position: Range {
|
||||
start: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: 0,
|
||||
},
|
||||
end: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: test_end_position.column as u32,
|
||||
},
|
||||
},
|
||||
};
|
||||
test_items.push(test_item);
|
||||
test_start_position = Point::default();
|
||||
test_end_position = Point::default();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(test_items)
|
||||
discover_with_treesitter(file_path, &tree_sitter_go::language(), query)
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use crate::runner::util::send_stdout;
|
||||
use lsp_types::Diagnostic;
|
||||
use lsp_types::DiagnosticSeverity;
|
||||
use lsp_types::Position;
|
||||
use lsp_types::Range;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
@ -15,17 +13,13 @@ use testing_language_server::spec::DiscoverResultItem;
|
|||
use testing_language_server::spec::RunFileTestResult;
|
||||
use testing_language_server::spec::RunFileTestResultItem;
|
||||
use testing_language_server::spec::TestItem;
|
||||
use tree_sitter::Point;
|
||||
use tree_sitter::Query;
|
||||
use tree_sitter::QueryCursor;
|
||||
|
||||
use crate::model::Runner;
|
||||
|
||||
use super::util::clean_ansi;
|
||||
use super::util::detect_workspaces_from_file_paths;
|
||||
|
||||
// If the character value is greater than the line length it defaults back to the line length.
|
||||
const MAX_CHAR_LENGTH: u32 = 10000;
|
||||
use super::util::discover_with_treesitter;
|
||||
use super::util::MAX_CHAR_LENGTH;
|
||||
|
||||
fn parse_diagnostics(
|
||||
test_result: &str,
|
||||
|
@ -84,16 +78,9 @@ fn detect_workspaces(file_paths: Vec<String>) -> DetectWorkspaceResult {
|
|||
}
|
||||
|
||||
fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(&tree_sitter_javascript::language())
|
||||
.expect("Error loading JavaScript grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
// from https://github.com/nvim-neotest/neotest-jest/blob/514fd4eae7da15fd409133086bb8e029b65ac43f/lua/neotest-jest/init.lua#L162
|
||||
// license: https://github.com/nvim-neotest/neotest-jest/blob/514fd4eae7da15fd409133086bb8e029b65ac43f/LICENSE.md
|
||||
let query_string = r#"
|
||||
let query = r#"
|
||||
; -- Namespaces --
|
||||
; Matches: `describe('context', () => {})`
|
||||
((call_expression
|
||||
|
@ -162,65 +149,7 @@ fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
|||
arguments: (arguments (string (string_fragment) @test.name) [(arrow_function) (function_expression)])
|
||||
)) @test.definition
|
||||
"#;
|
||||
let query = Query::new(&tree_sitter_javascript::language(), query_string)
|
||||
.expect("Error creating query");
|
||||
let mut cursor = QueryCursor::new();
|
||||
cursor.set_byte_range(tree.root_node().byte_range());
|
||||
let source = source_code.as_bytes();
|
||||
let matches = cursor.matches(&query, tree.root_node(), source);
|
||||
for m in matches {
|
||||
let mut namespace_name = "";
|
||||
let mut test_start_position = Point::default();
|
||||
let mut test_end_position = Point::default();
|
||||
for capture in m.captures {
|
||||
let capture_name = query.capture_names()[capture.index as usize];
|
||||
let value = capture.node.utf8_text(source)?;
|
||||
let start_position = capture.node.start_position();
|
||||
let end_position = capture.node.end_position();
|
||||
match capture_name {
|
||||
"namespace.name" => {
|
||||
namespace_name = value;
|
||||
}
|
||||
"test.definition" => {
|
||||
test_start_position = start_position;
|
||||
test_end_position = end_position;
|
||||
}
|
||||
"test.name" => {
|
||||
let test_name = value;
|
||||
let test_item = TestItem {
|
||||
id: format!("{}:{}", namespace_name, test_name),
|
||||
name: test_name.to_string(),
|
||||
start_position: Range {
|
||||
start: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: test_start_position.column as u32,
|
||||
},
|
||||
end: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: MAX_CHAR_LENGTH,
|
||||
},
|
||||
},
|
||||
end_position: Range {
|
||||
start: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: 0,
|
||||
},
|
||||
end: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: test_end_position.column as u32,
|
||||
},
|
||||
},
|
||||
};
|
||||
test_items.push(test_item);
|
||||
test_start_position = Point::default();
|
||||
test_end_position = Point::default();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(test_items)
|
||||
discover_with_treesitter(file_path, &tree_sitter_javascript::language(), query)
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
|
|
|
@ -7,7 +7,7 @@ use regex::Regex;
|
|||
use serde::Serialize;
|
||||
use testing_language_server::spec::{RunFileTestResultItem, TestItem};
|
||||
use testing_language_server::{error::LSError, spec::RunFileTestResult};
|
||||
use tree_sitter::{Point, Query, QueryCursor};
|
||||
use tree_sitter::{Language, Point, Query, QueryCursor};
|
||||
|
||||
// If the character value is greater than the line length it defaults back to the line length.
|
||||
pub const MAX_CHAR_LENGTH: u32 = 10000;
|
||||
|
@ -76,16 +76,9 @@ pub fn clean_ansi(input: &str) -> String {
|
|||
}
|
||||
|
||||
pub fn discover_rust_tests(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(&tree_sitter_rust::language())
|
||||
.expect("Error loading Rust grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
// from https://github.com/rouge8/neotest-rust/blob/0418811e1e3499b2501593f2e131d02f5e6823d4/lua/neotest-rust/init.lua#L167
|
||||
// license: https://github.com/rouge8/neotest-rust/blob/0418811e1e3499b2501593f2e131d02f5e6823d4/LICENSE
|
||||
let query_string = r#"
|
||||
let query = r#"
|
||||
(
|
||||
(attribute_item
|
||||
[
|
||||
|
@ -119,8 +112,22 @@ pub fn discover_rust_tests(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
|||
)
|
||||
(mod_item name: (identifier) @namespace.name)? @namespace.definition
|
||||
"#;
|
||||
let query =
|
||||
Query::new(&tree_sitter_rust::language(), query_string).expect("Error creating query");
|
||||
discover_with_treesitter(file_path, &tree_sitter_rust::language(), query)
|
||||
}
|
||||
|
||||
pub fn discover_with_treesitter(
|
||||
file_path: &str,
|
||||
language: &Language,
|
||||
query: &str,
|
||||
) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(language)
|
||||
.expect("Error loading Rust grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
let query = Query::new(language, query).expect("Error creating query");
|
||||
|
||||
let mut cursor = QueryCursor::new();
|
||||
cursor.set_byte_range(tree.root_node().byte_range());
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
fs::{self, File},
|
||||
};
|
||||
|
||||
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
|
||||
use lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
use serde_json::Value;
|
||||
use tempfile::tempdir;
|
||||
use testing_language_server::{
|
||||
|
@ -12,25 +12,20 @@ use testing_language_server::{
|
|||
DiscoverResult, DiscoverResultItem, RunFileTestResult, RunFileTestResultItem, TestItem,
|
||||
},
|
||||
};
|
||||
use tree_sitter::{Point, Query, QueryCursor};
|
||||
|
||||
use crate::model::Runner;
|
||||
|
||||
use super::util::{clean_ansi, detect_workspaces_from_file_paths, send_stdout, MAX_CHAR_LENGTH};
|
||||
use super::util::{
|
||||
clean_ansi, detect_workspaces_from_file_paths, discover_with_treesitter, send_stdout,
|
||||
MAX_CHAR_LENGTH,
|
||||
};
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||
pub struct VitestRunner;
|
||||
|
||||
fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
let mut test_items: Vec<TestItem> = vec![];
|
||||
parser
|
||||
.set_language(&tree_sitter_javascript::language())
|
||||
.expect("Error loading Rust grammar");
|
||||
let source_code = std::fs::read_to_string(file_path)?;
|
||||
let tree = parser.parse(&source_code, None).unwrap();
|
||||
// from https://github.com/marilari88/neotest-vitest/blob/353364aa05b94b09409cbef21b79c97c5564e2ce/lua/neotest-vitest/init.lua#L101
|
||||
let query_string = r#"
|
||||
let query = r#"
|
||||
; -- Namespaces --
|
||||
; Matches: `describe('context')`
|
||||
((call_expression
|
||||
|
@ -77,66 +72,7 @@ fn discover(file_path: &str) -> Result<Vec<TestItem>, LSError> {
|
|||
arguments: (arguments (string (string_fragment) @test.name) (arrow_function))
|
||||
)) @test.definition
|
||||
"#;
|
||||
let query = Query::new(&tree_sitter_javascript::language(), query_string)
|
||||
.expect("Error creating query");
|
||||
|
||||
let mut cursor = QueryCursor::new();
|
||||
cursor.set_byte_range(tree.root_node().byte_range());
|
||||
let source = source_code.as_bytes();
|
||||
let matches = cursor.matches(&query, tree.root_node(), source);
|
||||
for m in matches {
|
||||
let mut namespace_name = "";
|
||||
let mut test_start_position = Point::default();
|
||||
let mut test_end_position = Point::default();
|
||||
for capture in m.captures {
|
||||
let capture_name = query.capture_names()[capture.index as usize];
|
||||
let value = capture.node.utf8_text(source)?;
|
||||
let start_position = capture.node.start_position();
|
||||
let end_position = capture.node.end_position();
|
||||
match capture_name {
|
||||
"namespace.name" => {
|
||||
namespace_name = value;
|
||||
}
|
||||
"test.definition" => {
|
||||
test_start_position = start_position;
|
||||
test_end_position = end_position;
|
||||
}
|
||||
"test.name" => {
|
||||
let test_name = value;
|
||||
let test_item = TestItem {
|
||||
id: format!("{}:{}", namespace_name, test_name),
|
||||
name: test_name.to_string(),
|
||||
start_position: Range {
|
||||
start: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: test_start_position.column as u32,
|
||||
},
|
||||
end: Position {
|
||||
line: test_start_position.row as u32,
|
||||
character: MAX_CHAR_LENGTH,
|
||||
},
|
||||
},
|
||||
end_position: Range {
|
||||
start: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: 0,
|
||||
},
|
||||
end: Position {
|
||||
line: test_end_position.row as u32,
|
||||
character: test_end_position.column as u32,
|
||||
},
|
||||
},
|
||||
};
|
||||
test_items.push(test_item);
|
||||
test_start_position = Point::default();
|
||||
test_end_position = Point::default();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(test_items)
|
||||
discover_with_treesitter(file_path, &tree_sitter_javascript::language(), query)
|
||||
}
|
||||
|
||||
fn parse_diagnostics(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue