From 6a8676f335c986d93d2236162b466529256fb672 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 28 Sep 2025 22:25:30 -0400 Subject: [PATCH] refactor(test): generalize printing of test diff keys and diffs --- crates/cli/src/fuzz.rs | 10 +-- crates/cli/src/test.rs | 99 +++++++++++++++++++---------- crates/cli/src/tests/corpus_test.rs | 14 ++-- 3 files changed, 76 insertions(+), 47 deletions(-) diff --git a/crates/cli/src/fuzz.rs b/crates/cli/src/fuzz.rs index 24806fca..f1524825 100644 --- a/crates/cli/src/fuzz.rs +++ b/crates/cli/src/fuzz.rs @@ -25,7 +25,7 @@ use crate::{ random::Rand, }, parse::perform_edit, - test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields, TestEntry}, + test::{parse_tests, strip_sexp_fields, DiffKey, TestDiff, TestEntry}, }; pub static LOG_ENABLED: LazyLock = LazyLock::new(|| env::var("TREE_SITTER_LOG").is_ok()); @@ -183,8 +183,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -276,8 +276,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output && !test.error { println!("Incorrect parse for {test_name} - seed {seed}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index f5cc5de4..b19d7afd 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -317,49 +317,78 @@ pub fn check_queries_at_path(language: &Language, path: &Path) -> Result<()> { Ok(()) } -pub fn print_diff_key() { - println!( - "\ncorrect / {} / {}", - paint(Some(AnsiColor::Green), "expected"), - paint(Some(AnsiColor::Red), "unexpected") - ); +pub struct DiffKey; + +impl std::fmt::Display for DiffKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "\ncorrect / {} / {}", + paint(Some(AnsiColor::Green), "expected"), + paint(Some(AnsiColor::Red), "unexpected") + )?; + Ok(()) + } } -pub fn print_diff(actual: &str, expected: &str, use_color: bool) { - let diff = TextDiff::from_lines(actual, expected); - for diff in diff.iter_all_changes() { - match diff.tag() { - ChangeTag::Equal => { - if use_color { - print!("{diff}"); - } else { - print!(" {diff}"); +pub struct TestDiff<'a> { + pub actual: &'a str, + pub expected: &'a str, + pub use_color: bool, +} + +impl<'a> TestDiff<'a> { + #[must_use] + pub const fn new(actual: &'a str, expected: &'a str, use_color: bool) -> Self { + Self { + actual, + expected, + use_color, + } + } +} + +impl std::fmt::Display for TestDiff<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let diff = TextDiff::from_lines(self.actual, self.expected); + for diff in diff.iter_all_changes() { + match diff.tag() { + ChangeTag::Equal => { + if self.use_color { + write!(f, "{diff}")?; + } else { + write!(f, " {diff}")?; + } } - } - ChangeTag::Insert => { - if use_color { - print!("{}", paint(Some(AnsiColor::Green), diff.as_str().unwrap())); - } else { - print!("+{diff}"); + ChangeTag::Insert => { + if self.use_color { + write!( + f, + "{}", + paint(Some(AnsiColor::Green), diff.as_str().unwrap()) + )?; + } else { + write!(f, "+{diff}")?; + } + if diff.missing_newline() { + writeln!(f)?; + } } - if diff.missing_newline() { - println!(); - } - } - ChangeTag::Delete => { - if use_color { - print!("{}", paint(Some(AnsiColor::Red), diff.as_str().unwrap())); - } else { - print!("-{diff}"); - } - if diff.missing_newline() { - println!(); + ChangeTag::Delete => { + if self.use_color { + write!(f, "{}", paint(Some(AnsiColor::Red), diff.as_str().unwrap()))?; + } else { + write!(f, "-{diff}")?; + } + if diff.missing_newline() { + writeln!(f)?; + } } } } - } - println!(); + Ok(()) + } } struct TestFailure { diff --git a/crates/cli/src/tests/corpus_test.rs b/crates/cli/src/tests/corpus_test.rs index fe2e2943..de797401 100644 --- a/crates/cli/src/tests/corpus_test.rs +++ b/crates/cli/src/tests/corpus_test.rs @@ -16,7 +16,7 @@ use crate::{ LOG_GRAPH_ENABLED, START_SEED, }, parse::perform_edit, - test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields}, + test::{parse_tests, strip_sexp_fields, DiffKey, TestDiff}, tests::{ allocations, helpers::fixtures::{fixtures_dir, get_language, get_test_language, SCRATCH_BASE_DIR}, @@ -209,8 +209,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -297,8 +297,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect parse for {test_name} - seed {seed}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -428,8 +428,8 @@ fn test_feature_corpus_files() { if actual_output == test.output { true } else { - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + print!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); false }