From e445532a1fea3b1dda93cee61c534f5b9acc9c16 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Fri, 29 Nov 2024 05:25:49 +0100 Subject: [PATCH] feat(cli): verify assertions for every carat in tests, not just the first one Co-authored-by: Amaan Qureshi --- cli/src/query_testing.rs | 21 ++++++++++++++++++--- cli/src/test_highlight.rs | 9 ++++++--- cli/src/test_tags.rs | 7 +++++-- cli/src/tests/test_highlight_test.rs | 14 +++++++------- cli/src/tests/test_tags_test.rs | 8 ++++---- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cli/src/query_testing.rs b/cli/src/query_testing.rs index 81ea18fb..ef6449c9 100644 --- a/cli/src/query_testing.rs +++ b/cli/src/query_testing.rs @@ -62,6 +62,7 @@ pub struct CaptureInfo { #[derive(Debug, PartialEq, Eq)] pub struct Assertion { pub position: Utf8Point, + pub length: usize, pub negative: bool, pub expected_capture_name: String, } @@ -71,11 +72,13 @@ impl Assertion { pub const fn new( row: usize, col: usize, + length: usize, negative: bool, expected_capture_name: String, ) -> Self { Self { position: Utf8Point::new(row, col), + length, negative, expected_capture_name, } @@ -117,6 +120,7 @@ pub fn parse_position_comments( let mut has_arrow = false; let mut negative = false; let mut arrow_end = 0; + let mut arrow_count = 1; for (i, c) in text.char_indices() { arrow_end = i + 1; if c == '-' && has_left_caret { @@ -126,6 +130,14 @@ pub fn parse_position_comments( if c == '^' { has_arrow = true; position.column += i; + // Continue counting remaining arrows and update their end column + for (_, c) in text[arrow_end..].char_indices() { + if c != '^' { + arrow_end += arrow_count - 1; + break; + } + arrow_count += 1; + } break; } has_left_caret = c == '<'; @@ -152,6 +164,7 @@ pub fn parse_position_comments( assertion_ranges.push((node.start_position(), node.end_position())); result.push(Assertion { position: to_utf8_point(position, source), + length: arrow_count, negative, expected_capture_name: mat.as_str().to_string(), }); @@ -212,7 +225,8 @@ pub fn assert_expected_captures( for assertion in &pairs { if let Some(found) = &infos .iter() - .find(|p| assertion.position >= p.start && assertion.position < p.end) + .find(|p| assertion.position >= p.start && + (assertion.position.row < p.end.row || assertion.position.column + assertion.length - 1 < p.end.column)) { if assertion.expected_capture_name != found.name && found.name != "name" { return Err(anyhow!( @@ -224,9 +238,10 @@ pub fn assert_expected_captures( } } else { return Err(anyhow!( - "Assertion failed: could not match {} at {}", + "Assertion failed: could not match {} at row {}, column {}", assertion.expected_capture_name, - assertion.position + assertion.position.row, + assertion.position.column + assertion.length - 1, )); } } diff --git a/cli/src/test_highlight.rs b/cli/src/test_highlight.rs index 34be438f..75c7fc3f 100644 --- a/cli/src/test_highlight.rs +++ b/cli/src/test_highlight.rs @@ -150,11 +150,13 @@ pub fn iterate_assertions( let mut actual_highlights = Vec::new(); for Assertion { position, + length, negative, expected_capture_name: expected_highlight, } in assertions { let mut passed = false; + let mut end_column = position.column + length - 1; actual_highlights.clear(); // The assertions are ordered by position, so skip past all of the highlights that @@ -165,11 +167,12 @@ pub fn iterate_assertions( continue; } - // Iterate through all of the highlights that start at or before this assertion's, + // Iterate through all of the highlights that start at or before this assertion's // position, looking for one that matches the assertion. let mut j = i; while let (false, Some(highlight)) = (passed, highlights.get(j)) { - if highlight.0 > *position { + end_column = (*position).column + length - 1; + if highlight.0.column > end_column { break 'highlight_loop; } @@ -193,7 +196,7 @@ pub fn iterate_assertions( if !passed { return Err(Failure { row: position.row, - column: position.column, + column: end_column, expected_highlight: expected_highlight.clone(), actual_highlights: actual_highlights.into_iter().cloned().collect(), } diff --git a/cli/src/test_tags.rs b/cli/src/test_tags.rs index 5b290bda..2295ee63 100644 --- a/cli/src/test_tags.rs +++ b/cli/src/test_tags.rs @@ -114,11 +114,13 @@ pub fn test_tag( let mut actual_tags = Vec::<&String>::new(); for Assertion { position, + length, negative, expected_capture_name: expected_tag, } in &assertions { let mut passed = false; + let mut end_column = position.column + length - 1; 'tag_loop: while let Some(tag) = tags.get(i) { if tag.1 <= *position { @@ -130,7 +132,8 @@ pub fn test_tag( // position, looking for one that matches the assertion let mut j = i; while let (false, Some(tag)) = (passed, tags.get(j)) { - if tag.0 > *position { + end_column = (*position).column + length - 1; + if tag.0.column > end_column { break 'tag_loop; } @@ -152,7 +155,7 @@ pub fn test_tag( if !passed { return Err(Failure { row: position.row, - column: position.column, + column: end_column, expected_tag: expected_tag.clone(), actual_tags: actual_tags.into_iter().cloned().collect(), } diff --git a/cli/src/tests/test_highlight_test.rs b/cli/src/tests/test_highlight_test.rs index 054e33f8..e8567d6d 100644 --- a/cli/src/tests/test_highlight_test.rs +++ b/cli/src/tests/test_highlight_test.rs @@ -23,7 +23,7 @@ fn test_highlight_test_with_basic_test() { "// hi", "var abc = function(d) {", " // ^ function", - " // ^ keyword", + " // ^^^ keyword", " return d + e;", " // ^ variable", " // ^ !variable", @@ -39,12 +39,12 @@ fn test_highlight_test_with_basic_test() { assert_eq!( assertions, &[ - Assertion::new(1, 5, false, String::from("function")), - Assertion::new(1, 11, false, String::from("keyword")), - Assertion::new(4, 9, false, String::from("variable")), - Assertion::new(4, 11, true, String::from("variable")), - Assertion::new(8, 5, false, String::from("function")), - Assertion::new(8, 11, false, String::from("keyword")), + Assertion::new(1, 5, 1, false, String::from("function")), + Assertion::new(1, 11, 3, false, String::from("keyword")), + Assertion::new(4, 9, 1, false, String::from("variable")), + Assertion::new(4, 11, 1, true, String::from("variable")), + Assertion::new(8, 5, 1, false, String::from("function")), + Assertion::new(8, 11, 1, false, String::from("keyword")), ] ); diff --git a/cli/src/tests/test_tags_test.rs b/cli/src/tests/test_tags_test.rs index 5f7b88fc..c9019a71 100644 --- a/cli/src/tests/test_tags_test.rs +++ b/cli/src/tests/test_tags_test.rs @@ -30,10 +30,10 @@ fn test_tags_test_with_basic_test() { assert_eq!( assertions, &[ - Assertion::new(1, 4, false, String::from("definition.function")), - Assertion::new(3, 9, false, String::from("reference.call")), - Assertion::new(5, 11, false, String::from("reference.call")), - Assertion::new(5, 13, true, String::from("variable.parameter")), + Assertion::new(1, 4, 1, false, String::from("definition.function")), + Assertion::new(3, 9, 1, false, String::from("reference.call")), + Assertion::new(5, 11, 1, false, String::from("reference.call")), + Assertion::new(5, 13, 1, true, String::from("variable.parameter")), ] );