mirror of
https://github.com/kbwo/testing-language-server.git
synced 2025-07-24 11:23:42 +00:00
commit
b8b04b59ab
24 changed files with 947 additions and 17 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -566,13 +566,18 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"dirs",
|
||||
"lsp-types",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"testing-language-server 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"tree-sitter",
|
||||
"tree-sitter-go",
|
||||
"tree-sitter-javascript",
|
||||
"tree-sitter-rust",
|
||||
]
|
||||
|
@ -717,6 +722,16 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-go"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55cb318be5ccf75f44e054acf6898a5c95d59b53443eed578e16be0cd7ec037f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-javascript"
|
||||
version = "0.21.0"
|
||||
|
|
|
@ -19,3 +19,8 @@ tree-sitter-rust = "0.21.2"
|
|||
anyhow = { workspace = true }
|
||||
tempfile = "3.10.1"
|
||||
tree-sitter-javascript = "0.21.0"
|
||||
tree-sitter-go = "0.21.0"
|
||||
tracing-appender = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, default-features = false }
|
||||
dirs = "5.0.1"
|
||||
|
|
14
crates/adapter/src/log.rs
Normal file
14
crates/adapter/src/log.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
|
||||
pub struct Log;
|
||||
|
||||
impl Log {
|
||||
pub fn init() -> Result<WorkerGuard, anyhow::Error> {
|
||||
let home_dir = dirs::home_dir().unwrap();
|
||||
let log_path = home_dir.join(".config/testing_ls_adapter/logs");
|
||||
let file_appender = tracing_appender::rolling::daily(log_path, "prefix.log");
|
||||
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
|
||||
tracing_subscriber::fmt().with_writer(non_blocking).init();
|
||||
Ok(guard)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use crate::model::AvailableTestKind;
|
||||
use crate::model::Runner;
|
||||
use anyhow::anyhow;
|
||||
use clap::Parser;
|
||||
use log::Log;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
|
@ -9,18 +11,18 @@ use testing_language_server::spec::AdapterCommands;
|
|||
use testing_language_server::spec::DetectWorkspaceArgs;
|
||||
use testing_language_server::spec::DiscoverArgs;
|
||||
use testing_language_server::spec::RunFileTestArgs;
|
||||
pub mod log;
|
||||
pub mod model;
|
||||
pub mod runner;
|
||||
|
||||
fn pick_test_from_extra(
|
||||
extra: &mut [String],
|
||||
) -> Result<(Vec<String>, AvailableTestKind), anyhow::Error> {
|
||||
// extraから--test-kind=のものを取り出し、元の配列から`--test-kind=`のものは除外する
|
||||
let mut extra = extra.to_vec();
|
||||
let index = extra
|
||||
.iter()
|
||||
.position(|arg| arg.starts_with("--test-kind="))
|
||||
.unwrap();
|
||||
.ok_or(anyhow!("test-kind is not found"))?;
|
||||
let test_kind = extra.remove(index);
|
||||
|
||||
let language = test_kind.replace("--test-kind=", "");
|
||||
|
@ -41,13 +43,14 @@ fn handle(commands: AdapterCommands) -> Result<(), LSError> {
|
|||
}
|
||||
AdapterCommands::DetectWorkspace(mut commands) => {
|
||||
let (extra, test_kind) = pick_test_from_extra(&mut commands.extra)?;
|
||||
test_kind.detect_workspaces_root(DetectWorkspaceArgs { extra, ..commands })?;
|
||||
test_kind.detect_workspaces(DetectWorkspaceArgs { extra, ..commands })?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _guard = Log::init().expect("Failed to initialize logger");
|
||||
let args = AdapterCommands::parse();
|
||||
if let Err(error) = handle(args) {
|
||||
io::stderr()
|
||||
|
@ -60,10 +63,8 @@ fn main() {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::runner::cargo_test::CargoTestRunner;
|
||||
use crate::runner::jest::JestRunner;
|
||||
|
||||
#[test]
|
||||
// If `--test-kind=<value>` is not present, then return Err
|
||||
fn error_test_kind_detection() {
|
||||
let mut extra = vec![];
|
||||
pick_test_from_extra(&mut extra).unwrap_err();
|
||||
|
@ -72,22 +73,20 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// If `--test-kind=<value>` is present, then return Ok(value)
|
||||
fn test_kind_detection() {
|
||||
fn single_test_kind_detection() {
|
||||
let mut extra = vec!["--test-kind=cargo-test".to_string()];
|
||||
let (_, language) = pick_test_from_extra(&mut extra).unwrap();
|
||||
assert_eq!(language, AvailableTestKind::CargoTest(CargoTestRunner));
|
||||
}
|
||||
|
||||
#[test]
|
||||
// If multiple `--test-kind=<value>` are present, then return first one
|
||||
fn error_multiple_test_kind_detection() {
|
||||
fn multiple_test_kind_results_first_kind() {
|
||||
let mut extra = vec![
|
||||
"--test-kind=cargo-test".to_string(),
|
||||
"--test-kind=jest".to_string(),
|
||||
"--test-kind=foo".to_string(),
|
||||
];
|
||||
let (_, test_kind) = pick_test_from_extra(&mut extra).unwrap();
|
||||
assert_eq!(test_kind, AvailableTestKind::Jest(JestRunner));
|
||||
assert_eq!(test_kind, AvailableTestKind::CargoTest(CargoTestRunner));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::runner::cargo_test::CargoTestRunner;
|
||||
use crate::runner::go::GoTestRunner;
|
||||
use std::str::FromStr;
|
||||
use testing_language_server::error::LSError;
|
||||
use testing_language_server::spec::DetectWorkspaceArgs;
|
||||
|
@ -11,12 +12,14 @@ use crate::runner::jest::JestRunner;
|
|||
pub enum AvailableTestKind {
|
||||
CargoTest(CargoTestRunner),
|
||||
Jest(JestRunner),
|
||||
GoTest(GoTestRunner),
|
||||
}
|
||||
impl Runner for AvailableTestKind {
|
||||
fn disover(&self, args: DiscoverArgs) -> Result<(), LSError> {
|
||||
match self {
|
||||
AvailableTestKind::CargoTest(runner) => runner.disover(args),
|
||||
AvailableTestKind::Jest(runner) => runner.disover(args),
|
||||
AvailableTestKind::GoTest(runner) => runner.disover(args),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,13 +27,15 @@ impl Runner for AvailableTestKind {
|
|||
match self {
|
||||
AvailableTestKind::CargoTest(runner) => runner.run_file_test(args),
|
||||
AvailableTestKind::Jest(runner) => runner.run_file_test(args),
|
||||
AvailableTestKind::GoTest(runner) => runner.run_file_test(args),
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_workspaces_root(&self, args: DetectWorkspaceArgs) -> Result<(), LSError> {
|
||||
fn detect_workspaces(&self, args: DetectWorkspaceArgs) -> Result<(), LSError> {
|
||||
match self {
|
||||
AvailableTestKind::CargoTest(runner) => runner.detect_workspaces_root(args),
|
||||
AvailableTestKind::Jest(runner) => runner.detect_workspaces_root(args),
|
||||
AvailableTestKind::CargoTest(runner) => runner.detect_workspaces(args),
|
||||
AvailableTestKind::Jest(runner) => runner.detect_workspaces(args),
|
||||
AvailableTestKind::GoTest(runner) => runner.detect_workspaces(args),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +47,7 @@ impl FromStr for AvailableTestKind {
|
|||
match s {
|
||||
"cargo-test" => Ok(AvailableTestKind::CargoTest(CargoTestRunner)),
|
||||
"jest" => Ok(AvailableTestKind::Jest(JestRunner)),
|
||||
"go-test" => Ok(AvailableTestKind::GoTest(GoTestRunner)),
|
||||
_ => Err(anyhow::anyhow!("Unknown test kind: {}", s)),
|
||||
}
|
||||
}
|
||||
|
@ -50,5 +56,5 @@ impl FromStr for AvailableTestKind {
|
|||
pub trait Runner {
|
||||
fn disover(&self, args: DiscoverArgs) -> Result<(), LSError>;
|
||||
fn run_file_test(&self, args: RunFileTestArgs) -> Result<(), LSError>;
|
||||
fn detect_workspaces_root(&self, args: DetectWorkspaceArgs) -> Result<(), LSError>;
|
||||
fn detect_workspaces(&self, args: DetectWorkspaceArgs) -> Result<(), LSError>;
|
||||
}
|
||||
|
|
383
crates/adapter/src/runner/go.rs
Normal file
383
crates/adapter/src/runner/go.rs
Normal file
|
@ -0,0 +1,383 @@
|
|||
use crate::model::Runner;
|
||||
use anyhow::anyhow;
|
||||
use lsp_types::Diagnostic;
|
||||
use lsp_types::Position;
|
||||
use lsp_types::Range;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Output;
|
||||
use std::str::FromStr;
|
||||
use testing_language_server::error::LSError;
|
||||
use testing_language_server::spec::DiscoverResult;
|
||||
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;
|
||||
|
||||
#[derive(Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum Action {
|
||||
Start,
|
||||
Run,
|
||||
Output,
|
||||
Fail,
|
||||
Pass,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct TestResultLine {
|
||||
time: String,
|
||||
action: Action,
|
||||
package: String,
|
||||
test: Option<String>,
|
||||
output: Option<String>,
|
||||
}
|
||||
|
||||
fn get_position_from_output(output: &str) -> Option<(String, u32)> {
|
||||
let pattern = r"^\s{4}(.*_test\.go):(\d+):";
|
||||
let re = Regex::new(pattern).unwrap();
|
||||
if let Some(captures) = re.captures(output) {
|
||||
if let (Some(file_name), Some(lnum)) = (captures.get(1), captures.get(2)) {
|
||||
return Some((
|
||||
file_name.as_str().to_string(),
|
||||
lnum.as_str().parse::<u32>().unwrap() - 1,
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
fn get_log_from_output(output: &str) -> String {
|
||||
output.replace(" ", "")
|
||||
}
|
||||
|
||||
fn parse_diagnostics(
|
||||
contents: &str,
|
||||
workspace_root: PathBuf,
|
||||
file_paths: &[String],
|
||||
) -> Result<RunFileTestResult, LSError> {
|
||||
let contents = contents.replace("\r\n", "\n");
|
||||
let lines = contents.lines();
|
||||
let mut result_map: HashMap<String, Vec<Diagnostic>> = HashMap::new();
|
||||
let mut file_name: Option<String> = None;
|
||||
let mut lnum: Option<u32> = None;
|
||||
let mut message = String::new();
|
||||
let mut last_action: Option<Action> = None;
|
||||
for line in lines {
|
||||
let value: TestResultLine = serde_json::from_str(line).map_err(|e| anyhow!("{:?}", e))?;
|
||||
match value.action {
|
||||
Action::Run => {
|
||||
file_name = None;
|
||||
message = String::new();
|
||||
}
|
||||
Action::Output => {
|
||||
let output = &value.output.unwrap();
|
||||
if let Some((detected_file_name, detected_lnum)) = get_position_from_output(output)
|
||||
{
|
||||
file_name = Some(detected_file_name);
|
||||
lnum = Some(detected_lnum);
|
||||
message = String::new();
|
||||
} else {
|
||||
message += &get_log_from_output(output);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let current_action = value.action;
|
||||
let is_action_changed = last_action.as_ref() != Some(¤t_action);
|
||||
if is_action_changed {
|
||||
last_action = Some(current_action);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let (Some(detected_fn), Some(detected_lnum)) = (&file_name, lnum) {
|
||||
let diagnostic = Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: detected_lnum,
|
||||
character: 1,
|
||||
},
|
||||
end: Position {
|
||||
line: detected_lnum,
|
||||
character: MAX_CHAR_LENGTH,
|
||||
},
|
||||
},
|
||||
message: message.clone(),
|
||||
..Diagnostic::default()
|
||||
};
|
||||
let file_path = workspace_root
|
||||
.join(detected_fn)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
if file_paths.contains(&file_path) {
|
||||
result_map.entry(file_path).or_default().push(diagnostic);
|
||||
}
|
||||
file_name = None;
|
||||
lnum = None;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result_map
|
||||
.into_iter()
|
||||
.map(|(path, diagnostics)| RunFileTestResultItem { path, diagnostics })
|
||||
.collect())
|
||||
}
|
||||
|
||||
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();
|
||||
let query_string = r#"
|
||||
;;query
|
||||
((function_declaration
|
||||
name: (identifier) @test.name)
|
||||
(#match? @test.name "^(Test|Example)"))
|
||||
@test.definition
|
||||
|
||||
(method_declaration
|
||||
name: (field_identifier) @test.name
|
||||
(#match? @test.name "^(Test|Example)")) @test.definition
|
||||
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @test.method)
|
||||
(#match? @test.method "^Run$")
|
||||
arguments: (argument_list . (interpreted_string_literal) @test.name))
|
||||
@test.definition
|
||||
;; query for list table tests
|
||||
(block
|
||||
(short_var_declaration
|
||||
left: (expression_list
|
||||
(identifier) @test.cases)
|
||||
right: (expression_list
|
||||
(composite_literal
|
||||
(literal_value
|
||||
(literal_element
|
||||
(literal_value
|
||||
(keyed_element
|
||||
(literal_element
|
||||
(identifier) @test.field.name)
|
||||
(literal_element
|
||||
(interpreted_string_literal) @test.name)))) @test.definition))))
|
||||
(for_statement
|
||||
(range_clause
|
||||
left: (expression_list
|
||||
(identifier) @test.case)
|
||||
right: (identifier) @test.cases1
|
||||
(#eq? @test.cases @test.cases1))
|
||||
body: (block
|
||||
(expression_statement
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @test.method)
|
||||
(#match? @test.method "^Run$")
|
||||
arguments: (argument_list
|
||||
(selector_expression
|
||||
operand: (identifier) @test.case1
|
||||
(#eq? @test.case @test.case1)
|
||||
field: (field_identifier) @test.field.name1
|
||||
(#eq? @test.field.name @test.field.name1))))))))
|
||||
|
||||
;; query for map table tests
|
||||
(block
|
||||
(short_var_declaration
|
||||
left: (expression_list
|
||||
(identifier) @test.cases)
|
||||
right: (expression_list
|
||||
(composite_literal
|
||||
(literal_value
|
||||
(keyed_element
|
||||
(literal_element
|
||||
(interpreted_string_literal) @test.name)
|
||||
(literal_element
|
||||
(literal_value) @test.definition))))))
|
||||
(for_statement
|
||||
(range_clause
|
||||
left: (expression_list
|
||||
((identifier) @test.key.name)
|
||||
((identifier) @test.case))
|
||||
right: (identifier) @test.cases1
|
||||
(#eq? @test.cases @test.cases1))
|
||||
body: (block
|
||||
(expression_statement
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @test.method)
|
||||
(#match? @test.method "^Run$")
|
||||
arguments: (argument_list
|
||||
((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)
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||
pub struct GoTestRunner;
|
||||
impl Runner for GoTestRunner {
|
||||
fn disover(
|
||||
&self,
|
||||
args: testing_language_server::spec::DiscoverArgs,
|
||||
) -> Result<(), testing_language_server::error::LSError> {
|
||||
let file_paths = args.file_paths;
|
||||
let mut discover_results: DiscoverResult = vec![];
|
||||
|
||||
for file_path in file_paths {
|
||||
let tests = discover(&file_path)?;
|
||||
discover_results.push(DiscoverResultItem {
|
||||
tests,
|
||||
path: file_path,
|
||||
});
|
||||
}
|
||||
serde_json::to_writer(std::io::stdout(), &discover_results)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_file_test(
|
||||
&self,
|
||||
args: testing_language_server::spec::RunFileTestArgs,
|
||||
) -> Result<(), testing_language_server::error::LSError> {
|
||||
let file_paths = args.file_paths;
|
||||
let default_args = ["-v", "-json", "", "-count=1", "-timeout=60s"];
|
||||
let workspace = args.workspace;
|
||||
let test_result = std::process::Command::new("go")
|
||||
.current_dir(&workspace)
|
||||
.arg("test")
|
||||
.args(default_args)
|
||||
.args(args.extra)
|
||||
.output()
|
||||
.unwrap();
|
||||
let Output { stdout, stderr, .. } = test_result;
|
||||
if stdout.is_empty() && !stderr.is_empty() {
|
||||
return Err(LSError::Adapter(String::from_utf8(stderr).unwrap()));
|
||||
}
|
||||
let test_result = String::from_utf8(stdout)?;
|
||||
let diagnostics: RunFileTestResult = parse_diagnostics(
|
||||
&test_result,
|
||||
PathBuf::from_str(&workspace).unwrap(),
|
||||
&file_paths,
|
||||
)?;
|
||||
serde_json::to_writer(std::io::stdout(), &diagnostics)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_workspaces(
|
||||
&self,
|
||||
args: testing_language_server::spec::DetectWorkspaceArgs,
|
||||
) -> Result<(), testing_language_server::error::LSError> {
|
||||
serde_json::to_writer(
|
||||
std::io::stdout(),
|
||||
&detect_workspaces_from_file_paths(&args.file_paths, &["go.mod".to_string()]),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::runner::go::discover;
|
||||
use std::str::FromStr;
|
||||
use std::{fs::read_to_string, path::PathBuf};
|
||||
|
||||
use crate::runner::go::parse_diagnostics;
|
||||
|
||||
#[test]
|
||||
fn test_parse_diagnostics() {
|
||||
let current_dir = std::env::current_dir().unwrap();
|
||||
let test_file_path = current_dir.join("tests/go-test.txt");
|
||||
let contents = read_to_string(test_file_path).unwrap();
|
||||
let workspace = PathBuf::from_str("/home/demo/test/go/src/test").unwrap();
|
||||
let target_file_path = "/home/demo/test/go/src/test/cases_test.go";
|
||||
let result =
|
||||
parse_diagnostics(&contents, workspace, &[target_file_path.to_string()]).unwrap();
|
||||
let result = result.first().unwrap();
|
||||
assert_eq!(result.path, target_file_path);
|
||||
let diagnostic = result.diagnostics.first().unwrap();
|
||||
assert_eq!(diagnostic.range.start.line, 30);
|
||||
assert_eq!(diagnostic.range.start.character, 1);
|
||||
assert_eq!(diagnostic.range.end.line, 30);
|
||||
assert_eq!(diagnostic.message, "\tError Trace:\tcases_test.go:31\n\tError: \tNot equal: \n\t \texpected: 7\n\t \tactual : -1\n\tTest: \tTestSubtract/test_two\n--- FAIL: TestSubtract (0.00s)\n --- FAIL: TestSubtract/test_one (0.00s)\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover() {
|
||||
let file_path = "../../test_proj/go/cases_test.go";
|
||||
let test_items = discover(file_path).unwrap();
|
||||
assert!(!test_items.is_empty());
|
||||
}
|
||||
}
|
|
@ -1,2 +1,4 @@
|
|||
pub mod cargo_test;
|
||||
pub mod go;
|
||||
pub mod jest;
|
||||
pub mod util;
|
||||
|
|
50
crates/adapter/src/runner/util.rs
Normal file
50
crates/adapter/src/runner/util.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// determine if a particular file is the root of workspace based on whether it is in the same directory
|
||||
pub fn detect_workspace_from_file(file_path: PathBuf, file_names: &[String]) -> Option<String> {
|
||||
let parent = file_path.parent();
|
||||
if let Some(parent) = parent {
|
||||
if file_names
|
||||
.iter()
|
||||
.any(|file_name| parent.join(file_name).exists())
|
||||
{
|
||||
return Some(parent.to_string_lossy().to_string());
|
||||
} else {
|
||||
detect_workspace_from_file(parent.to_path_buf(), file_names)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detect_workspaces_from_file_paths(
|
||||
target_file_paths: &[String],
|
||||
file_names: &[String],
|
||||
) -> HashMap<String, Vec<String>> {
|
||||
let mut result_map: HashMap<String, Vec<String>> = HashMap::new();
|
||||
let mut file_paths = target_file_paths.to_vec();
|
||||
file_paths.sort_by_key(|b| std::cmp::Reverse(b.len()));
|
||||
for file_path in file_paths {
|
||||
let existing_workspace = result_map
|
||||
.iter()
|
||||
.find(|(workspace_root, _)| file_path.contains(workspace_root.as_str()));
|
||||
if let Some((workspace_root, _)) = existing_workspace {
|
||||
result_map
|
||||
.entry(workspace_root.to_string())
|
||||
.or_default()
|
||||
.push(file_path.clone());
|
||||
} else {
|
||||
let workspace =
|
||||
detect_workspace_from_file(PathBuf::from_str(&file_path).unwrap(), file_names);
|
||||
if let Some(workspace) = workspace {
|
||||
result_map
|
||||
.entry(workspace)
|
||||
.or_default()
|
||||
.push(file_path.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
result_map
|
||||
}
|
161
crates/adapter/tests/go-test.txt
Normal file
161
crates/adapter/tests/go-test.txt
Normal file
|
@ -0,0 +1,161 @@
|
|||
{"Time":"2024-05-25T17:06:16.98464582+09:00","Action":"start","Package":"neotest_go"}
|
||||
{"Time":"2024-05-25T17:06:16.986822201+09:00","Action":"run","Package":"neotest_go","Test":"TestSubtract"}
|
||||
{"Time":"2024-05-25T17:06:16.986838849+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract","Output":"=== RUN TestSubtract\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986859373+09:00","Action":"run","Package":"neotest_go","Test":"TestSubtract/test_one"}
|
||||
{"Time":"2024-05-25T17:06:16.98686856+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" \tError Trace:\tcases_test.go:31\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986871386+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" \tError: \tNot equal: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.986874139+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" \t \texpected: 3\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986876748+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" \t \tactual : -1\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986879547+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" \tTest: \tTestSubtract/test_one\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986883029+09:00","Action":"run","Package":"neotest_go","Test":"TestSubtract/test_two"}
|
||||
{"Time":"2024-05-25T17:06:16.986885264+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":"=== RUN TestSubtract/test_two\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986888429+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" cases_test.go:31: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.986891613+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" \tError Trace:\tcases_test.go:31\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986894222+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" \tError: \tNot equal: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.986896835+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" \t \texpected: 7\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986899333+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" \t \tactual : -1\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986901904+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" \tTest: \tTestSubtract/test_two\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986906401+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract","Output":"--- FAIL: TestSubtract (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986910144+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_one","Output":" --- FAIL: TestSubtract/test_one (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986913275+09:00","Action":"fail","Package":"neotest_go","Test":"TestSubtract/test_one","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986916945+09:00","Action":"output","Package":"neotest_go","Test":"TestSubtract/test_two","Output":" --- FAIL: TestSubtract/test_two (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986919709+09:00","Action":"fail","Package":"neotest_go","Test":"TestSubtract/test_two","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986922033+09:00","Action":"fail","Package":"neotest_go","Test":"TestSubtract","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986924322+09:00","Action":"run","Package":"neotest_go","Test":"TestAdd"}
|
||||
{"Time":"2024-05-25T17:06:16.986926439+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd","Output":"=== RUN TestAdd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986929637+09:00","Action":"run","Package":"neotest_go","Test":"TestAdd/test_one"}
|
||||
{"Time":"2024-05-25T17:06:16.986931891+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_one","Output":"=== RUN TestAdd/test_one\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98693449+09:00","Action":"run","Package":"neotest_go","Test":"TestAdd/test_two"}
|
||||
{"Time":"2024-05-25T17:06:16.986936644+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":"=== RUN TestAdd/test_two\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986939093+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" cases_test.go:42: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.986941721+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" \tError Trace:\tcases_test.go:42\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986944261+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" \tError: \tNot equal: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.986946773+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" \t \texpected: 5\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986949247+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" \t \tactual : 3\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986951706+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" \tTest: \tTestAdd/test_two\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986954288+09:00","Action":"run","Package":"neotest_go","Test":"TestAdd/string"}
|
||||
{"Time":"2024-05-25T17:06:16.986956496+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/string","Output":"=== RUN TestAdd/string\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986959568+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd","Output":"--- FAIL: TestAdd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986964387+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_one","Output":" --- PASS: TestAdd/test_one (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986967557+09:00","Action":"pass","Package":"neotest_go","Test":"TestAdd/test_one","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986970137+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/test_two","Output":" --- FAIL: TestAdd/test_two (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986973398+09:00","Action":"fail","Package":"neotest_go","Test":"TestAdd/test_two","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986976554+09:00","Action":"output","Package":"neotest_go","Test":"TestAdd/string","Output":" --- PASS: TestAdd/string (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986979769+09:00","Action":"pass","Package":"neotest_go","Test":"TestAdd/string","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.98698262+09:00","Action":"fail","Package":"neotest_go","Test":"TestAdd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.98698541+09:00","Action":"run","Package":"neotest_go","Test":"TestAddOne"}
|
||||
{"Time":"2024-05-25T17:06:16.986987976+09:00","Action":"output","Package":"neotest_go","Test":"TestAddOne","Output":"=== RUN TestAddOne\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986990912+09:00","Action":"output","Package":"neotest_go","Test":"TestAddOne","Output":"--- PASS: TestAddOne (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.986994224+09:00","Action":"pass","Package":"neotest_go","Test":"TestAddOne","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.986996509+09:00","Action":"run","Package":"neotest_go","Test":"TestAddTwo"}
|
||||
{"Time":"2024-05-25T17:06:16.986999108+09:00","Action":"output","Package":"neotest_go","Test":"TestAddTwo","Output":"=== RUN TestAddTwo\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98700243+09:00","Action":"output","Package":"neotest_go","Test":"TestAddTwo","Output":"--- PASS: TestAddTwo (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987005287+09:00","Action":"pass","Package":"neotest_go","Test":"TestAddTwo","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987008349+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest"}
|
||||
{"Time":"2024-05-25T17:06:16.987011032+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest","Output":"=== RUN TestSomeTest\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987014678+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied1"}
|
||||
{"Time":"2024-05-25T17:06:16.987017664+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied1","Output":"=== RUN TestSomeTest/AccessDenied1\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98702332+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied1","Output":"AccessDenied1 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987030097+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied2"}
|
||||
{"Time":"2024-05-25T17:06:16.9870326+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied2","Output":"=== RUN TestSomeTest/AccessDenied2\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987035243+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied2","Output":"AccessDenied2 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98703803+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied3"}
|
||||
{"Time":"2024-05-25T17:06:16.987040299+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied3","Output":"=== RUN TestSomeTest/AccessDenied3\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987042979+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied3","Output":"AccessDenied3 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987045694+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied4"}
|
||||
{"Time":"2024-05-25T17:06:16.987048493+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied4","Output":"=== RUN TestSomeTest/AccessDenied4\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987051059+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied4","Output":"AccessDenied4 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987053703+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied5"}
|
||||
{"Time":"2024-05-25T17:06:16.987055897+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied5","Output":"=== RUN TestSomeTest/AccessDenied5\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987058733+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied5","Output":"AccessDenied5 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987062114+09:00","Action":"run","Package":"neotest_go","Test":"TestSomeTest/AccessDenied6"}
|
||||
{"Time":"2024-05-25T17:06:16.987064491+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied6","Output":"=== RUN TestSomeTest/AccessDenied6\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987067709+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied6","Output":"AccessDenied6 GET /api/nothing lalala 403\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987076359+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest","Output":"--- PASS: TestSomeTest (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987079722+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied1","Output":" --- PASS: TestSomeTest/AccessDenied1 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987082855+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied1","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987085329+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied2","Output":" --- PASS: TestSomeTest/AccessDenied2 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987088221+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied2","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987090756+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied3","Output":" --- PASS: TestSomeTest/AccessDenied3 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987094115+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied3","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987096613+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied4","Output":" --- PASS: TestSomeTest/AccessDenied4 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987099588+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied4","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987104022+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied5","Output":" --- PASS: TestSomeTest/AccessDenied5 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987107814+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied5","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987110865+09:00","Action":"output","Package":"neotest_go","Test":"TestSomeTest/AccessDenied6","Output":" --- PASS: TestSomeTest/AccessDenied6 (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987113695+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest/AccessDenied6","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987116401+09:00","Action":"pass","Package":"neotest_go","Test":"TestSomeTest","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987119142+09:00","Action":"run","Package":"neotest_go","Test":"TestSplit"}
|
||||
{"Time":"2024-05-25T17:06:16.987121813+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit","Output":"=== RUN TestSplit\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987124271+09:00","Action":"run","Package":"neotest_go","Test":"TestSplit/simple"}
|
||||
{"Time":"2024-05-25T17:06:16.987126899+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/simple","Output":"=== RUN TestSplit/simple\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987129965+09:00","Action":"run","Package":"neotest_go","Test":"TestSplit/wrong_sep"}
|
||||
{"Time":"2024-05-25T17:06:16.987132221+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/wrong_sep","Output":"=== RUN TestSplit/wrong_sep\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98713529+09:00","Action":"run","Package":"neotest_go","Test":"TestSplit/no_sep"}
|
||||
{"Time":"2024-05-25T17:06:16.987138035+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/no_sep","Output":"=== RUN TestSplit/no_sep\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987140671+09:00","Action":"run","Package":"neotest_go","Test":"TestSplit/trailing_sep"}
|
||||
{"Time":"2024-05-25T17:06:16.987143812+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/trailing_sep","Output":"=== RUN TestSplit/trailing_sep\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987148473+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/trailing_sep","Output":" map_table_test.go:25: trailing sep: expected: [a b c], got: [a b c ]\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987152641+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit","Output":"--- FAIL: TestSplit (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987156528+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/simple","Output":" --- PASS: TestSplit/simple (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98716009+09:00","Action":"pass","Package":"neotest_go","Test":"TestSplit/simple","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987163018+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/wrong_sep","Output":" --- PASS: TestSplit/wrong_sep (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987166426+09:00","Action":"pass","Package":"neotest_go","Test":"TestSplit/wrong_sep","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987169756+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/no_sep","Output":" --- PASS: TestSplit/no_sep (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987173446+09:00","Action":"pass","Package":"neotest_go","Test":"TestSplit/no_sep","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987176509+09:00","Action":"output","Package":"neotest_go","Test":"TestSplit/trailing_sep","Output":" --- FAIL: TestSplit/trailing_sep (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987179658+09:00","Action":"fail","Package":"neotest_go","Test":"TestSplit/trailing_sep","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.9871823+09:00","Action":"fail","Package":"neotest_go","Test":"TestSplit","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987185013+09:00","Action":"run","Package":"neotest_go","Test":"TestExampleTestSuite"}
|
||||
{"Time":"2024-05-25T17:06:16.987187634+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite","Output":"=== RUN TestExampleTestSuite\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987358969+09:00","Action":"run","Package":"neotest_go","Test":"TestExampleTestSuite/TestExample"}
|
||||
{"Time":"2024-05-25T17:06:16.987372775+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExample","Output":"=== RUN TestExampleTestSuite/TestExample\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987378537+09:00","Action":"run","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure"}
|
||||
{"Time":"2024-05-25T17:06:16.987383079+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":"=== RUN TestExampleTestSuite/TestExampleFailure\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987611537+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" suite_test.go:32: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.987626951+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" \tError Trace:\tsuite_test.go:32\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987631582+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" \tError: \tNot equal: \n"}
|
||||
{"Time":"2024-05-25T17:06:16.987635334+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" \t \texpected: 5\n"}
|
||||
{"Time":"2024-05-25T17:06:16.9876384+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" \t \tactual : 3\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987641353+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" \tTest: \tTestExampleTestSuite/TestExampleFailure\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987649622+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite","Output":"--- FAIL: TestExampleTestSuite (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987655287+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExample","Output":" --- PASS: TestExampleTestSuite/TestExample (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987659094+09:00","Action":"pass","Package":"neotest_go","Test":"TestExampleTestSuite/TestExample","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987663126+09:00","Action":"output","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Output":" --- FAIL: TestExampleTestSuite/TestExampleFailure (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987666501+09:00","Action":"fail","Package":"neotest_go","Test":"TestExampleTestSuite/TestExampleFailure","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.9876691+09:00","Action":"fail","Package":"neotest_go","Test":"TestExampleTestSuite","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987671645+09:00","Action":"run","Package":"neotest_go","Test":"TestOdd"}
|
||||
{"Time":"2024-05-25T17:06:16.987674132+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd","Output":"=== RUN TestOdd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987676921+09:00","Action":"run","Package":"neotest_go","Test":"TestOdd/odd"}
|
||||
{"Time":"2024-05-25T17:06:16.987680637+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd","Output":"=== RUN TestOdd/odd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987683855+09:00","Action":"run","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd"}
|
||||
{"Time":"2024-05-25T17:06:16.98769839+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd","Output":"=== RUN TestOdd/odd/5_is_odd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987711715+09:00","Action":"run","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd/9_is_odd"}
|
||||
{"Time":"2024-05-25T17:06:16.987713743+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd/9_is_odd","Output":"=== RUN TestOdd/odd/5_is_odd/9_is_odd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987715909+09:00","Action":"run","Package":"neotest_go","Test":"TestOdd/odd/7_is_odd"}
|
||||
{"Time":"2024-05-25T17:06:16.987717512+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/7_is_odd","Output":"=== RUN TestOdd/odd/7_is_odd\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987720928+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd","Output":"--- PASS: TestOdd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987723417+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd","Output":" --- PASS: TestOdd/odd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987726445+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd","Output":" --- PASS: TestOdd/odd/5_is_odd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987728552+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd/9_is_odd","Output":" --- PASS: TestOdd/odd/5_is_odd/9_is_odd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.98773067+09:00","Action":"pass","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd/9_is_odd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987733354+09:00","Action":"pass","Package":"neotest_go","Test":"TestOdd/odd/5_is_odd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987734868+09:00","Action":"output","Package":"neotest_go","Test":"TestOdd/odd/7_is_odd","Output":" --- PASS: TestOdd/odd/7_is_odd (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987736884+09:00","Action":"pass","Package":"neotest_go","Test":"TestOdd/odd/7_is_odd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987738363+09:00","Action":"pass","Package":"neotest_go","Test":"TestOdd/odd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987739718+09:00","Action":"pass","Package":"neotest_go","Test":"TestOdd","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.987741167+09:00","Action":"run","Package":"neotest_go","Test":"Example_hello_ok"}
|
||||
{"Time":"2024-05-25T17:06:16.987742665+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ok","Output":"=== RUN Example_hello_ok\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987748658+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ok","Output":"--- PASS: Example_hello_ok (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987750589+09:00","Action":"pass","Package":"neotest_go","Test":"Example_hello_ok","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.98775208+09:00","Action":"run","Package":"neotest_go","Test":"Example_hello_ng"}
|
||||
{"Time":"2024-05-25T17:06:16.987753501+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"=== RUN Example_hello_ng\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987755588+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"--- FAIL: Example_hello_ng (0.00s)\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987757621+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"got:\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987759383+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"hello world\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987761201+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"want:\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987762945+09:00","Action":"output","Package":"neotest_go","Test":"Example_hello_ng","Output":"NG pattern\n"}
|
||||
{"Time":"2024-05-25T17:06:16.987764982+09:00","Action":"fail","Package":"neotest_go","Test":"Example_hello_ng","Elapsed":0}
|
||||
{"Time":"2024-05-25T17:06:16.988651539+09:00","Action":"output","Package":"neotest_go","Output":"FAIL\n"}
|
||||
{"Time":"2024-05-25T17:06:16.988706481+09:00","Action":"output","Package":"neotest_go","Output":"FAIL\tneotest_go\t0.004s\n"}
|
||||
{"Time":"2024-05-25T17:06:16.988710395+09:00","Action":"fail","Package":"neotest_go","Elapsed":0.004}
|
|
@ -3,10 +3,10 @@
|
|||
"testing": {
|
||||
"command": "testing-language-server",
|
||||
"trace.server": "verbose",
|
||||
"filetypes": ["rust", "javascript"],
|
||||
"filetypes": ["rust", "javascript", "go"],
|
||||
"initializationOptions": {
|
||||
"adapterCommand": {
|
||||
".rs": [
|
||||
"rust": [
|
||||
{
|
||||
"path": "testing-ls-adapter",
|
||||
"extra_args": ["--test-kind=cargo-test"],
|
||||
|
@ -14,13 +14,21 @@
|
|||
"exclude_patterns": ["/**/target/**"]
|
||||
}
|
||||
],
|
||||
".js": [
|
||||
"javascript": [
|
||||
{
|
||||
"path": "testing-ls-adapter",
|
||||
"extra_args": ["--test-kind=jest"],
|
||||
"include_patterns": ["/**/*.js"],
|
||||
"exclude_patterns": ["/node_modules/**/*"]
|
||||
}
|
||||
],
|
||||
"go": [
|
||||
{
|
||||
"path": "testing-ls-adapter",
|
||||
"extra_args": ["--test-kind=go-test"],
|
||||
"include_patterns": ["/**/*.go"],
|
||||
"exclude_patterns": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
1
test_proj/go/README.md
Normal file
1
test_proj/go/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
This directory is from https://github.com/nvim-neotest/neotest-go/tree/main/neotest_go.
|
9
test_proj/go/cases.go
Normal file
9
test_proj/go/cases.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package main
|
||||
|
||||
func add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
49
test_proj/go/cases_test.go
Normal file
49
test_proj/go/cases_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSubtract(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
a int
|
||||
b int
|
||||
want int
|
||||
}{
|
||||
{
|
||||
desc: "test one",
|
||||
a: 1,
|
||||
b: 2,
|
||||
want: 3,
|
||||
},
|
||||
{
|
||||
desc: "test two",
|
||||
a: 1,
|
||||
b: 2,
|
||||
want: 7,
|
||||
},
|
||||
}
|
||||
for _, tC := range testCases {
|
||||
t.Run(tC.desc, func(t *testing.T) {
|
||||
assert.Equal(t, tC.want, subtract(tC.a, tC.b))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
t.Run("test one", func(t *testing.T) {
|
||||
assert.Equal(t, 3, add(1, 2))
|
||||
})
|
||||
|
||||
t.Run("test two", func(t *testing.T) {
|
||||
assert.Equal(t, 5, add(1, 2))
|
||||
})
|
||||
|
||||
variable := "string"
|
||||
t.Run(variable, func(t *testing.T) {
|
||||
assert.Equal(t, 3, add(1, 2))
|
||||
})
|
||||
}
|
7
test_proj/go/example.go
Normal file
7
test_proj/go/example.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func hello() {
|
||||
fmt.Println("hello world")
|
||||
}
|
15
test_proj/go/example_test.go
Normal file
15
test_proj/go/example_test.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
func Example_hello_ok() {
|
||||
hello()
|
||||
|
||||
// Output:
|
||||
// hello world
|
||||
}
|
||||
|
||||
func Example_hello_ng() {
|
||||
hello()
|
||||
|
||||
// Output:
|
||||
// NG pattern
|
||||
}
|
11
test_proj/go/go.mod
Normal file
11
test_proj/go/go.mod
Normal file
|
@ -0,0 +1,11 @@
|
|||
module neotest_go
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.4.0 // indirect
|
||||
github.com/stretchr/testify v1.7.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
15
test_proj/go/go.sum
Normal file
15
test_proj/go/go.sum
Normal file
|
@ -0,0 +1,15 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
15
test_proj/go/main.go
Normal file
15
test_proj/go/main.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello world")
|
||||
}
|
||||
|
||||
func addOne(x int) int {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
func addTwo(x int) int {
|
||||
return x + 2
|
||||
}
|
14
test_proj/go/main_tagged_test.go
Normal file
14
test_proj/go/main_tagged_test.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
//go:build files
|
||||
// +build files
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAddOne2(t *testing.T) {
|
||||
assert.Equal(t, 2, addOne(1))
|
||||
}
|
15
test_proj/go/main_test.go
Normal file
15
test_proj/go/main_test.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAddOne(t *testing.T) {
|
||||
assert.Equal(t, 2, addOne(1))
|
||||
}
|
||||
|
||||
func TestAddTwo(t *testing.T) {
|
||||
assert.Equal(t, 3, addTwo(1))
|
||||
}
|
32
test_proj/go/many_table_test.go
Normal file
32
test_proj/go/many_table_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSomeTest(t *testing.T) {
|
||||
tt := []struct {
|
||||
name string
|
||||
method string
|
||||
url string
|
||||
apiKey string
|
||||
status int
|
||||
}{
|
||||
{name: "AccessDenied1", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
{name: "AccessDenied2", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
{name: "AccessDenied3", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
{name: "AccessDenied4", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
{name: "AccessDenied5", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
{name: "AccessDenied6", method: http.MethodGet, url: "/api/nothing", apiKey: "lalala", status: http.StatusForbidden},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(_ *testing.T) {
|
||||
fmt.Println(tc.name, tc.method, tc.url, tc.apiKey, tc.status)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
40
test_proj/go/map_table_test.go
Normal file
40
test_proj/go/map_table_test.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSplit(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
input string
|
||||
sep string
|
||||
want []string
|
||||
}{
|
||||
"simple": {input: "a/b/c", sep: "/", want: []string{"a", "b", "c"}},
|
||||
"wrong sep": {input: "a/b/c", sep: ",", want: []string{"a/b/c"}},
|
||||
"no sep": {input: "abc", sep: "/", want: []string{"abc"}},
|
||||
"trailing sep": {input: "a/b/c/", sep: "/", want: []string{"a", "b", "c"}},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
got := Split(tc.input, tc.sep)
|
||||
if !reflect.DeepEqual(tc.want, got) {
|
||||
t.Fatalf("%s: expected: %v, got: %v", name, tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Split(s, sep string) []string {
|
||||
var result []string
|
||||
i := strings.Index(s, sep)
|
||||
for i > -1 {
|
||||
result = append(result, s[:i])
|
||||
s = s[i+len(sep):]
|
||||
i = strings.Index(s, sep)
|
||||
}
|
||||
return append(result, s)
|
||||
}
|
39
test_proj/go/suite_test.go
Normal file
39
test_proj/go/suite_test.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
// Basic imports
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// Define the suite, and absorb the built-in basic suite
|
||||
// functionality from testify - including a T() method which
|
||||
// returns the current testing context
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
}
|
||||
|
||||
// Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// before each test
|
||||
func (suite *ExampleTestSuite) SetupTest() {
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
}
|
||||
|
||||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
}
|
||||
|
||||
func (suite *ExampleTestSuite) TestExampleFailure() {
|
||||
assert.Equal(suite.T(), 5, 3)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
// a normal test function and pass our suite to suite.Run
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
25
test_proj/go/three_level_nested_test.go
Normal file
25
test_proj/go/three_level_nested_test.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestOdd(t *testing.T) {
|
||||
t.Run("odd", func(t *testing.T) {
|
||||
t.Run("5 is odd", func(t *testing.T) {
|
||||
if 5%2 != 1 {
|
||||
t.Error("5 is actually odd")
|
||||
}
|
||||
t.Run("9 is odd", func(t *testing.T) {
|
||||
if 9%2 != 1 {
|
||||
t.Error("5 is actually odd")
|
||||
}
|
||||
})
|
||||
})
|
||||
t.Run("7 is odd", func(t *testing.T) {
|
||||
if 7%2 != 1 {
|
||||
t.Error("7 is actually odd")
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue