Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit 144d64c

Browse files
Merge pull request #176 from github/cleanup-test
2 parents 40c6918 + d5b1548 commit 144d64c

File tree

3 files changed

+78
-38
lines changed

3 files changed

+78
-38
lines changed

tree-sitter-stack-graphs/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717

1818
- The `LanguageConfiguration::matches_file` method takes a `ContentProvider` instead of an `Option<&str>` value. This allows lazy file reading *after* the filename is checked, instead of the unconditional loading required before. To give content readers the opportunity to cache read values, a mutable reference is required. The return type has changed to `std::io::Result` to propagate possible errors from content providers. A `FileReader` implementation that caches the last read file is provided as well.
1919

20+
#### Fixed
21+
22+
- Fix a panic condition when assertion refer to source lines beyond the end of the test file.
23+
2024
### CLI
2125

2226
#### Added
2327

2428
- A new `analyze` command that computes stack graphs and partial paths for all given source files and directories. The command does not produce any output at the moment. Analysis per file can be limited using the `--max-file-time` flag.
2529

30+
#### Changed
31+
32+
- The `--show-ignored` flag of the `test` command has been renamed to `--show-skipped`. Only explicitly skipped test files (with a `.skip` extension) will be shown. Other unsupported files are, such as generated HTML files, are never shown.
33+
- The `--hide-passing` flag of the `test` command has been renamed to the more common `--quiet`/`-q`.
34+
- The output of the `test` command has changed to print the test name before the test result, so that it clear which test is currently running.
35+
2636
## v0.6.0 -- 2023-01-13
2737

2838
### Library

tree-sitter-stack-graphs/src/cli/test.rs

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use anyhow::Context as _;
1010
use clap::ArgEnum;
1111
use clap::Args;
1212
use clap::ValueHint;
13-
use colored::Colorize as _;
1413
use stack_graphs::arena::Handle;
1514
use stack_graphs::graph::File;
1615
use stack_graphs::graph::StackGraph;
@@ -29,10 +28,13 @@ use crate::loader::LanguageConfiguration;
2928
use crate::loader::Loader;
3029
use crate::test::Test;
3130
use crate::test::TestResult;
31+
use crate::CancellationFlag;
3232
use crate::LoadError;
3333
use crate::NoCancellation;
3434
use crate::StackGraphLanguage;
3535

36+
use super::util::FileStatusLogger;
37+
3638
/// Flag to control output
3739
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
3840
pub enum OutputMode {
@@ -71,20 +73,26 @@ impl OutputMode {
7173
"#)]
7274
pub struct TestArgs {
7375
/// Test file or directory paths.
74-
#[clap(value_name = "TEST_PATH", required = true, value_hint = ValueHint::AnyPath, parse(from_os_str), validator_os = path_exists)]
76+
#[clap(
77+
value_name = "TEST_PATH",
78+
required = true,
79+
value_hint = ValueHint::AnyPath,
80+
parse(from_os_str),
81+
validator_os = path_exists
82+
)]
7583
pub test_paths: Vec<PathBuf>,
7684

77-
/// Hide passing tests.
78-
#[clap(long)]
79-
pub hide_passing: bool,
85+
/// Hide passing tests in output.
86+
#[clap(long, short = 'q')]
87+
pub quiet: bool,
8088

8189
/// Hide failure error details.
8290
#[clap(long)]
8391
pub hide_failure_errors: bool,
8492

85-
/// Show ignored files in output.
93+
/// Show skipped files in output.
8694
#[clap(long)]
87-
pub show_ignored: bool,
95+
pub show_skipped: bool,
8896

8997
/// Save graph for tests matching output mode.
9098
/// Takes an optional path specification argument for the output file.
@@ -129,17 +137,22 @@ pub struct TestArgs {
129137
pub save_visualization: Option<PathSpec>,
130138

131139
/// Controls when graphs, paths, or visualization are saved.
132-
#[clap(long, arg_enum, default_value_t = OutputMode::OnFailure)]
140+
#[clap(
141+
long,
142+
arg_enum,
143+
default_value_t = OutputMode::OnFailure,
144+
require_equals = true,
145+
)]
133146
pub output_mode: OutputMode,
134147
}
135148

136149
impl TestArgs {
137150
pub fn new(test_paths: Vec<PathBuf>) -> Self {
138151
Self {
139152
test_paths,
140-
hide_passing: false,
153+
quiet: false,
141154
hide_failure_errors: false,
142-
show_ignored: false,
155+
show_skipped: false,
143156
save_graph: None,
144157
save_paths: None,
145158
save_visualization: None,
@@ -194,17 +207,24 @@ impl TestArgs {
194207
test_path: &Path,
195208
loader: &mut Loader,
196209
) -> anyhow::Result<TestResult> {
210+
let mut file_status = FileStatusLogger::new(test_path, !self.quiet);
211+
212+
if self.show_skipped && test_path.extension().map_or(false, |e| e == "skip") {
213+
file_status.warn("skipped")?;
214+
return Ok(TestResult::new());
215+
}
216+
217+
let cancellation_flag = &NoCancellation;
218+
197219
let mut file_reader = FileReader::new();
198-
let lc = match loader.load_for_file(test_path, &mut file_reader, &NoCancellation)? {
220+
let lc = match loader.load_for_file(test_path, &mut file_reader, cancellation_flag)? {
199221
Some(sgl) => sgl,
200-
None => {
201-
if self.show_ignored {
202-
println!("{} {}", "⦵".dimmed(), test_path.display());
203-
}
204-
return Ok(TestResult::new());
205-
}
222+
None => return Ok(TestResult::new()),
206223
};
207224
let source = file_reader.get(test_path)?;
225+
226+
file_status.processing()?;
227+
208228
let default_fragment_path = test_path.strip_prefix(test_root).unwrap();
209229
let mut test = Test::from_source(&test_path, &source, default_fragment_path)?;
210230
self.load_builtins_into(&lc, &mut test.graph)
@@ -224,7 +244,7 @@ impl TestArgs {
224244
&test_fragment.source,
225245
&mut all_paths,
226246
&test_fragment.globals,
227-
&NoCancellation,
247+
cancellation_flag,
228248
)?;
229249
} else if lc.matches_file(
230250
&test_fragment.path,
@@ -239,6 +259,7 @@ impl TestArgs {
239259
&test_fragment.source,
240260
&globals,
241261
&mut test.graph,
262+
cancellation_flag,
242263
)?;
243264
} else {
244265
return Err(anyhow!(
@@ -248,8 +269,8 @@ impl TestArgs {
248269
));
249270
}
250271
}
251-
let result = test.run(&NoCancellation)?;
252-
let success = self.handle_result(test_path, &result)?;
272+
let result = test.run(cancellation_flag)?;
273+
let success = self.handle_result(&result, &mut file_status)?;
253274
if self.output_mode.test(!success) {
254275
let files = test.fragments.iter().map(|f| f.file).collect::<Vec<_>>();
255276
self.save_output(
@@ -283,8 +304,9 @@ impl TestArgs {
283304
source: &str,
284305
globals: &Variables,
285306
graph: &mut StackGraph,
307+
cancellation_flag: &dyn CancellationFlag,
286308
) -> anyhow::Result<()> {
287-
match sgl.build_stack_graph_into(graph, file, source, globals, &NoCancellation) {
309+
match sgl.build_stack_graph_into(graph, file, source, globals, cancellation_flag) {
288310
Err(LoadError::ParseErrors(parse_errors)) => {
289311
Err(map_parse_errors(test_path, &parse_errors, source, " "))
290312
}
@@ -293,20 +315,24 @@ impl TestArgs {
293315
}
294316
}
295317

296-
fn handle_result(&self, test_path: &Path, result: &TestResult) -> anyhow::Result<bool> {
318+
fn handle_result(
319+
&self,
320+
result: &TestResult,
321+
file_status: &mut FileStatusLogger,
322+
) -> anyhow::Result<bool> {
297323
let success = result.failure_count() == 0;
298-
if !success || !self.hide_passing {
299-
println!(
300-
"{} {}: {}/{} assertions",
301-
if success { "✓".green() } else { "✗".red() },
302-
test_path.display(),
303-
result.success_count(),
304-
result.count()
305-
);
324+
if success {
325+
file_status.ok("success")?;
326+
} else {
327+
file_status.error(&format!(
328+
"{}/{} assertions failed",
329+
result.failure_count(),
330+
result.count(),
331+
))?;
306332
}
307333
if !success && !self.hide_failure_errors {
308334
for failure in result.failures_iter() {
309-
println!(" {}", failure);
335+
println!("{}", failure);
310336
}
311337
}
312338
Ok(success)
@@ -327,8 +353,8 @@ impl TestArgs {
327353
.map(|spec| spec.format(test_root, test_path))
328354
{
329355
self.save_graph(&path, &graph, filter)?;
330-
if !success || !self.hide_passing {
331-
println!(" Graph: {}", path.display());
356+
if !success || !self.quiet {
357+
println!("{}: graph at {}", test_path.display(), path.display());
332358
}
333359
}
334360
if let Some(path) = self
@@ -337,8 +363,8 @@ impl TestArgs {
337363
.map(|spec| spec.format(test_root, test_path))
338364
{
339365
self.save_paths(&path, paths, graph, filter)?;
340-
if !success || !self.hide_passing {
341-
println!(" Paths: {}", path.display());
366+
if !success || !self.quiet {
367+
println!("{}: paths at {}", test_path.display(), path.display());
342368
}
343369
}
344370
if let Some(path) = self
@@ -347,8 +373,12 @@ impl TestArgs {
347373
.map(|spec| spec.format(test_root, test_path))
348374
{
349375
self.save_visualization(&path, paths, graph, filter, &test_path)?;
350-
if !success || !self.hide_passing {
351-
println!(" Visualization: {}", path.display());
376+
if !success || !self.quiet {
377+
println!(
378+
"{}: visualization at {}",
379+
test_path.display(),
380+
path.display()
381+
);
352382
}
353383
}
354384
Ok(())

tree-sitter-stack-graphs/src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ impl Test {
220220
}
221221

222222
for fragment in &mut fragments {
223-
fragment.parse_assertions(|line| line_files[line])?;
223+
fragment.parse_assertions(|line| line_files.get(line).cloned().flatten())?;
224224
}
225225

226226
Ok(Self {

0 commit comments

Comments
 (0)