feat(cli): support NO_COLOR

Co-authored-by: Amaan Qureshi <amaanq12@gmail.com>

This allows users to avoid colored output when NO_COLOR is set to 1.
This commit is contained in:
WillLillis 2024-04-15 14:09:31 -04:00 committed by Amaan Qureshi
parent 5e5026aa73
commit 946acfd70f
5 changed files with 77 additions and 23 deletions

View file

@ -638,6 +638,8 @@ fn run() -> Result<()> {
env::set_var("TREE_SITTER_DEBUG", "1");
}
let color = env::var("NO_COLOR").map_or(true, |v| v != "1");
loader.use_debug_build(test_options.debug_build);
let mut parser = Parser::new();
@ -673,6 +675,7 @@ fn run() -> Result<()> {
update: test_options.update,
open_log: test_options.open_log,
languages: languages.iter().map(|(l, n)| (n.as_str(), l)).collect(),
color,
};
test::run_tests_at_path(&mut parser, &mut opts)?;
@ -691,6 +694,7 @@ fn run() -> Result<()> {
&config.get()?,
&mut highlighter,
&test_highlight_dir,
color,
)?;
parser = highlighter.parser;
}
@ -699,7 +703,13 @@ fn run() -> Result<()> {
if test_tag_dir.is_dir() {
let mut tags_context = TagsContext::new();
tags_context.parser = parser;
test_tags::test_tags(&loader, &config.get()?, &mut tags_context, &test_tag_dir)?;
test_tags::test_tags(
&loader,
&config.get()?,
&mut tags_context,
&test_tag_dir,
color,
)?;
}
}

View file

@ -104,6 +104,7 @@ pub struct TestOptions<'a> {
pub update: bool,
pub open_log: bool,
pub languages: BTreeMap<&'a str, &'a Language>,
pub color: bool,
}
pub fn run_tests_at_path(parser: &mut Parser, opts: &mut TestOptions) -> Result<()> {
@ -164,12 +165,14 @@ pub fn run_tests_at_path(parser: &mut Parser, opts: &mut TestOptions) -> Result<
}
}
print_diff_key();
if opts.color {
print_diff_key();
}
for (i, (name, actual, expected)) in failures.iter().enumerate() {
println!("\n {}. {name}:", i + 1);
let actual = format_sexp(actual, 2);
let expected = format_sexp(expected, 2);
print_diff(&actual, &expected);
print_diff(&actual, &expected, opts.color);
}
if has_parse_errors {
@ -212,24 +215,44 @@ pub fn print_diff_key() {
);
}
pub fn print_diff(actual: &str, expected: &str) {
pub fn print_diff(actual: &str, expected: &str, use_color: bool) {
let changeset = Changeset::new(actual, expected, "\n");
for diff in &changeset.diffs {
match diff {
Difference::Same(part) => {
print!("{part}{}", changeset.split);
if use_color {
print!("{part}{}", changeset.split);
} else {
print!("correct:\n{part}{}", changeset.split);
}
}
Difference::Add(part) => {
print!("{}{}", Colour::Green.paint(part), changeset.split);
if use_color {
print!("{}{}", Colour::Green.paint(part), changeset.split);
} else {
print!("expected:\n{part}{}", changeset.split);
}
}
Difference::Rem(part) => {
print!("{}{}", Colour::Red.paint(part), changeset.split);
if use_color {
print!("{}{}", Colour::Red.paint(part), changeset.split);
} else {
print!("unexpected:\n{part}{}", changeset.split);
}
}
}
}
println!();
}
pub fn opt_color(use_color: bool, color: ansi_term::Colour, text: &str) -> String {
if use_color {
color.paint(text).to_string()
} else {
text.to_string()
}
}
fn run_tests(
parser: &mut Parser,
test_entry: TestEntry,
@ -252,12 +275,12 @@ fn run_tests(
print!("{}", " ".repeat(indent_level as usize));
if attributes.skip {
println!("{}", Colour::Yellow.paint(&name));
println!("{}", opt_color(opts.color, Colour::Yellow, &name));
return Ok(true);
}
if !attributes.platform {
println!("{}", Colour::Purple.paint(&name));
println!("{}", opt_color(opts.color, Colour::Purple, &name));
return Ok(true);
}
@ -273,9 +296,9 @@ fn run_tests(
if attributes.error {
if tree.root_node().has_error() {
println!("{}", Colour::Green.paint(&name));
println!("{}", opt_color(opts.color, Colour::Green, &name));
} else {
println!("{}", Colour::Red.paint(&name));
println!("{}", opt_color(opts.color, Colour::Red, &name));
}
if attributes.fail_fast {
@ -288,7 +311,7 @@ fn run_tests(
}
if actual == output {
println!("{}", Colour::Green.paint(&name));
println!("{}", opt_color(opts.color, Colour::Green, &name));
if opts.update {
let input = String::from_utf8(input.clone()).unwrap();
let output = format_sexp(&output, 0);
@ -330,10 +353,10 @@ fn run_tests(
header_delim_len,
divider_delim_len,
));
println!("{}", Colour::Blue.paint(&name));
println!("{}", opt_color(opts.color, Colour::Blue, &name));
}
} else {
println!("{}", Colour::Red.paint(&name));
println!("{}", opt_color(opts.color, Colour::Red, &name));
}
failures.push((name.clone(), actual, output.clone()));

View file

@ -8,6 +8,7 @@ use tree_sitter_loader::{Config, Loader};
use super::{
query_testing::{parse_position_comments, Assertion},
test::opt_color,
util,
};
@ -47,9 +48,10 @@ pub fn test_highlights(
loader_config: &Config,
highlighter: &mut Highlighter,
directory: &Path,
use_color: bool,
) -> Result<()> {
println!("syntax highlighting:");
test_highlights_indented(loader, loader_config, highlighter, directory, 2)
test_highlights_indented(loader, loader_config, highlighter, directory, use_color, 2)
}
fn test_highlights_indented(
@ -57,6 +59,7 @@ fn test_highlights_indented(
loader_config: &Config,
highlighter: &mut Highlighter,
directory: &Path,
use_color: bool,
indent_level: usize,
) -> Result<()> {
let mut failed = false;
@ -77,6 +80,7 @@ fn test_highlights_indented(
loader_config,
highlighter,
&test_file_path,
use_color,
indent_level + 1,
)
.is_err()
@ -104,13 +108,21 @@ fn test_highlights_indented(
Ok(assertion_count) => {
println!(
"✓ {} ({assertion_count} assertions)",
Colour::Green.paint(test_file_name.to_string_lossy().as_ref()),
opt_color(
use_color,
Colour::Green,
test_file_name.to_string_lossy().as_ref()
),
);
}
Err(e) => {
println!(
"✗ {}",
Colour::Red.paint(test_file_name.to_string_lossy().as_ref())
opt_color(
use_color,
Colour::Red,
test_file_name.to_string_lossy().as_ref()
)
);
println!(
"{indent:indent_level$} {e}",

View file

@ -8,6 +8,7 @@ use tree_sitter_tags::{TagsConfiguration, TagsContext};
use super::{
query_testing::{parse_position_comments, Assertion},
test::opt_color,
util,
};
@ -47,9 +48,9 @@ pub fn test_tags(
loader_config: &Config,
tags_context: &mut TagsContext,
directory: &Path,
use_color: bool,
) -> Result<()> {
let mut failed = false;
println!("tags:");
for tag_test_file in fs::read_dir(directory)? {
let tag_test_file = tag_test_file?;
@ -74,13 +75,21 @@ pub fn test_tags(
Ok(assertion_count) => {
println!(
" ✓ {} ({assertion_count} assertions)",
Colour::Green.paint(test_file_name.to_string_lossy().as_ref()),
opt_color(
use_color,
Colour::Green,
test_file_name.to_string_lossy().as_ref()
),
);
}
Err(e) => {
println!(
" ✗ {}",
Colour::Red.paint(test_file_name.to_string_lossy().as_ref())
opt_color(
use_color,
Colour::Red,
test_file_name.to_string_lossy().as_ref()
)
);
println!(" {e}");
failed = true;

View file

@ -183,7 +183,7 @@ 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);
print_diff(&actual_output, &test.output, true);
println!();
return false;
}
@ -270,7 +270,7 @@ 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);
print_diff(&actual_output, &test.output, true);
println!();
return false;
}
@ -393,7 +393,7 @@ fn test_feature_corpus_files() {
true
} else {
print_diff_key();
print_diff(&actual_output, &test.output);
print_diff(&actual_output, &test.output, true);
println!();
false
}