1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 04:48:52 -05:00

chore(test): add [WILDCHARS(x)] and [WILDLINE] (#22803)

This commit is contained in:
David Sherret 2024-03-08 17:16:07 -05:00 committed by GitHub
parent 66d1b155dd
commit 071b3da020
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 132 additions and 9 deletions

View file

@ -54,8 +54,7 @@ macro_rules! assert_not_contains {
#[track_caller] #[track_caller]
pub fn assert_wildcard_match(actual: &str, expected: &str) { pub fn assert_wildcard_match(actual: &str, expected: &str) {
if !expected.contains("[WILDCARD]") && !expected.contains("[UNORDERED_START]") if !expected.contains("[WILD") && !expected.contains("[UNORDERED_START]") {
{
pretty_assertions::assert_eq!(actual, expected); pretty_assertions::assert_eq!(actual, expected);
} else { } else {
match crate::wildcard_match_detailed(expected, actual) { match crate::wildcard_match_detailed(expected, actual) {

View file

@ -674,21 +674,43 @@ pub fn wildcard_match_detailed(
let parts = parse_wildcard_pattern_text(&pattern).unwrap(); let parts = parse_wildcard_pattern_text(&pattern).unwrap();
let mut was_last_wildcard = false; let mut was_last_wildcard = false;
let mut was_last_wildline = false;
for (i, part) in parts.iter().enumerate() { for (i, part) in parts.iter().enumerate() {
match part { match part {
WildcardPatternPart::Wildcard => { WildcardPatternPart::Wildcard => {
output_lines.push("<WILDCARD />".to_string()); output_lines.push("<WILDCARD />".to_string());
} }
WildcardPatternPart::Wildline => {
output_lines.push("<WILDLINE />".to_string());
}
WildcardPatternPart::Wildnum(times) => {
if current_text.len() < *times {
output_lines
.push(format!("==== HAD MISSING WILDCHARS({}) ====", times));
output_lines.push(colors::red(annotate_whitespace(current_text)));
return WildcardMatchResult::Fail(output_lines.join("\n"));
}
output_lines.push(format!("<WILDCHARS({}) />", times));
current_text = &current_text[*times..];
}
WildcardPatternPart::Text(search_text) => { WildcardPatternPart::Text(search_text) => {
let is_last = i + 1 == parts.len(); let is_last = i + 1 == parts.len();
let search_index = if is_last && was_last_wildcard { let search_index = if is_last && was_last_wildcard {
// search from the end of the file // search from the end of the file
current_text.rfind(search_text) current_text.rfind(search_text)
} else if was_last_wildline {
if is_last {
find_last_text_on_line(search_text, current_text)
} else {
find_first_text_on_line(search_text, current_text)
}
} else { } else {
current_text.find(search_text) current_text.find(search_text)
}; };
match search_index { match search_index {
Some(found_index) if was_last_wildcard || found_index == 0 => { Some(found_index)
if was_last_wildcard || was_last_wildline || found_index == 0 =>
{
output_lines.push(format!( output_lines.push(format!(
"<FOUND>{}</FOUND>", "<FOUND>{}</FOUND>",
colors::gray(annotate_whitespace(search_text)) colors::gray(annotate_whitespace(search_text))
@ -707,11 +729,12 @@ pub fn wildcard_match_detailed(
return WildcardMatchResult::Fail(output_lines.join("\n")); return WildcardMatchResult::Fail(output_lines.join("\n"));
} }
None => { None => {
let was_wildcard_or_line = was_last_wildcard || was_last_wildline;
let mut max_found_index = 0; let mut max_found_index = 0;
for (index, _) in search_text.char_indices() { for (index, _) in search_text.char_indices() {
let sub_string = &search_text[..index]; let sub_string = &search_text[..index];
if let Some(found_index) = current_text.find(sub_string) { if let Some(found_index) = current_text.find(sub_string) {
if was_last_wildcard || found_index == 0 { if was_wildcard_or_line || found_index == 0 {
max_found_index = index; max_found_index = index;
} else { } else {
break; break;
@ -720,7 +743,7 @@ pub fn wildcard_match_detailed(
break; break;
} }
} }
if !was_last_wildcard && max_found_index > 0 { if !was_wildcard_or_line && max_found_index > 0 {
output_lines.push(format!( output_lines.push(format!(
"<FOUND>{}</FOUND>", "<FOUND>{}</FOUND>",
colors::gray(annotate_whitespace( colors::gray(annotate_whitespace(
@ -731,13 +754,13 @@ pub fn wildcard_match_detailed(
output_lines output_lines
.push("==== COULD NOT FIND SEARCH TEXT ====".to_string()); .push("==== COULD NOT FIND SEARCH TEXT ====".to_string());
output_lines.push(colors::green(annotate_whitespace( output_lines.push(colors::green(annotate_whitespace(
if was_last_wildcard { if was_wildcard_or_line {
search_text search_text
} else { } else {
&search_text[max_found_index..] &search_text[max_found_index..]
}, },
))); )));
if was_last_wildcard && max_found_index > 0 { if was_wildcard_or_line && max_found_index > 0 {
output_lines.push(format!( output_lines.push(format!(
"==== MAX FOUND ====\n{}", "==== MAX FOUND ====\n{}",
colors::red(annotate_whitespace( colors::red(annotate_whitespace(
@ -766,6 +789,7 @@ pub fn wildcard_match_detailed(
} }
WildcardPatternPart::UnorderedLines(expected_lines) => { WildcardPatternPart::UnorderedLines(expected_lines) => {
assert!(!was_last_wildcard, "unsupported"); assert!(!was_last_wildcard, "unsupported");
assert!(!was_last_wildline, "unsupported");
let mut actual_lines = Vec::with_capacity(expected_lines.len()); let mut actual_lines = Vec::with_capacity(expected_lines.len());
for _ in 0..expected_lines.len() { for _ in 0..expected_lines.len() {
match current_text.find('\n') { match current_text.find('\n') {
@ -823,9 +847,10 @@ pub fn wildcard_match_detailed(
} }
} }
was_last_wildcard = matches!(part, WildcardPatternPart::Wildcard); was_last_wildcard = matches!(part, WildcardPatternPart::Wildcard);
was_last_wildline = matches!(part, WildcardPatternPart::Wildline);
} }
if was_last_wildcard || current_text.is_empty() { if was_last_wildcard || was_last_wildline || current_text.is_empty() {
WildcardMatchResult::Success WildcardMatchResult::Success
} else { } else {
output_lines.push("==== HAD TEXT AT END OF FILE ====".to_string()); output_lines.push("==== HAD TEXT AT END OF FILE ====".to_string());
@ -837,6 +862,8 @@ pub fn wildcard_match_detailed(
#[derive(Debug)] #[derive(Debug)]
enum WildcardPatternPart<'a> { enum WildcardPatternPart<'a> {
Wildcard, Wildcard,
Wildline,
Wildnum(usize),
Text(&'a str), Text(&'a str),
UnorderedLines(Vec<&'a str>), UnorderedLines(Vec<&'a str>),
} }
@ -860,6 +887,8 @@ fn parse_wildcard_pattern_text(
enum InnerPart<'a> { enum InnerPart<'a> {
Wildcard, Wildcard,
Wildline,
Wildnum(usize),
UnorderedLines(Vec<&'a str>), UnorderedLines(Vec<&'a str>),
Char, Char,
} }
@ -872,9 +901,29 @@ fn parse_wildcard_pattern_text(
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
fn parse(mut self) -> ParseResult<'a, Vec<WildcardPatternPart<'a>>> { fn parse(mut self) -> ParseResult<'a, Vec<WildcardPatternPart<'a>>> {
fn parse_num(input: &str) -> ParseResult<usize> {
let num_char_count =
input.chars().take_while(|c| c.is_ascii_digit()).count();
if num_char_count == 0 {
return ParseError::backtrace();
}
let (char_text, input) = input.split_at(num_char_count);
let value = str::parse::<usize>(char_text).unwrap();
Ok((input, value))
}
fn parse_wild_num(input: &str) -> ParseResult<usize> {
let (input, _) = tag("[WILDCHARS(")(input)?;
let (input, times) = parse_num(input)?;
let (input, _) = tag(")]")(input)?;
ParseResult::Ok((input, times))
}
while !self.current_input.is_empty() { while !self.current_input.is_empty() {
let (next_input, inner_part) = or3( let (next_input, inner_part) = or5(
map(tag("[WILDCARD]"), |_| InnerPart::Wildcard), map(tag("[WILDCARD]"), |_| InnerPart::Wildcard),
map(tag("[WILDLINE]"), |_| InnerPart::Wildline),
map(parse_wild_num, InnerPart::Wildnum),
map(parse_unordered_lines, |lines| { map(parse_unordered_lines, |lines| {
InnerPart::UnorderedLines(lines) InnerPart::UnorderedLines(lines)
}), }),
@ -885,6 +934,14 @@ fn parse_wildcard_pattern_text(
self.queue_previous_text(next_input); self.queue_previous_text(next_input);
self.parts.push(WildcardPatternPart::Wildcard); self.parts.push(WildcardPatternPart::Wildcard);
} }
InnerPart::Wildline => {
self.queue_previous_text(next_input);
self.parts.push(WildcardPatternPart::Wildline);
}
InnerPart::Wildnum(times) => {
self.queue_previous_text(next_input);
self.parts.push(WildcardPatternPart::Wildnum(times));
}
InnerPart::UnorderedLines(expected_lines) => { InnerPart::UnorderedLines(expected_lines) => {
self.queue_previous_text(next_input); self.queue_previous_text(next_input);
self self
@ -923,6 +980,38 @@ fn parse_wildcard_pattern_text(
})(text) })(text)
} }
fn find_first_text_on_line(
search_text: &str,
current_text: &str,
) -> Option<usize> {
let end_search_pos = current_text.find('\n').unwrap_or(current_text.len());
let found_pos = current_text.find(search_text)?;
if found_pos <= end_search_pos {
Some(found_pos)
} else {
None
}
}
fn find_last_text_on_line(
search_text: &str,
current_text: &str,
) -> Option<usize> {
let end_search_pos = current_text.find('\n').unwrap_or(current_text.len());
let mut best_match = None;
let mut search_pos = 0;
while let Some(new_pos) = current_text[search_pos..].find(search_text) {
search_pos += new_pos;
if search_pos <= end_search_pos {
best_match = Some(search_pos);
} else {
break;
}
search_pos += 1;
}
best_match
}
pub fn with_pty(deno_args: &[&str], action: impl FnMut(Pty)) { pub fn with_pty(deno_args: &[&str], action: impl FnMut(Pty)) {
let context = TestContextBuilder::default().use_temp_cwd().build(); let context = TestContextBuilder::default().use_temp_cwd().build();
context.new_command().args_vec(deno_args).with_pty(action); context.new_command().args_vec(deno_args).with_pty(action);
@ -1318,6 +1407,19 @@ grault",
multiline_pattern, multiline_pattern,
&multi_line_builder("garply", None), &multi_line_builder("garply", None),
)); ));
// wildline
assert!(wildcard_match("foo[WILDLINE]baz", "foobarbaz"));
assert!(wildcard_match("foo[WILDLINE]bar", "foobarbar"));
assert!(!wildcard_match("foo[WILDLINE]baz", "fooba\nrbaz"));
assert!(wildcard_match("foo[WILDLINE]", "foobar"));
// wildnum
assert!(wildcard_match("foo[WILDCHARS(3)]baz", "foobarbaz"));
assert!(!wildcard_match("foo[WILDCHARS(4)]baz", "foobarbaz"));
assert!(!wildcard_match("foo[WILDCHARS(2)]baz", "foobarbaz"));
assert!(!wildcard_match("foo[WILDCHARS(1)]baz", "foobarbaz"));
assert!(!wildcard_match("foo[WILDCHARS(20)]baz", "foobarbaz"));
} }
#[test] #[test]
@ -1352,4 +1454,26 @@ grault",
assert_eq!(size, Some(120380 * 1024)); assert_eq!(size, Some(120380 * 1024));
} }
#[test]
fn test_find_first_text_on_line() {
let text = "foo\nbar\nbaz";
assert_eq!(find_first_text_on_line("foo", text), Some(0));
assert_eq!(find_first_text_on_line("oo", text), Some(1));
assert_eq!(find_first_text_on_line("o", text), Some(1));
assert_eq!(find_first_text_on_line("o\nbar", text), Some(2));
assert_eq!(find_first_text_on_line("f", text), Some(0));
assert_eq!(find_first_text_on_line("bar", text), None);
}
#[test]
fn test_find_last_text_on_line() {
let text = "foo\nbar\nbaz";
assert_eq!(find_last_text_on_line("foo", text), Some(0));
assert_eq!(find_last_text_on_line("oo", text), Some(1));
assert_eq!(find_last_text_on_line("o", text), Some(2));
assert_eq!(find_last_text_on_line("o\nbar", text), Some(2));
assert_eq!(find_last_text_on_line("f", text), Some(0));
assert_eq!(find_last_text_on_line("bar", text), None);
}
} }