mirror of
https://github.com/nushell/nushell.git
synced 2025-07-09 19:07:16 +02:00
# Description Instead of converting nested structures into strings and pattern-matching the strings, the `find` command will recursively search the nested structures for matches. - fixes #15618 # User-Facing Changes Text in nested structures will now be highlighted as well. Error values will always passed on instead of testing them against the search term There will be slight changes in match behavior, such as characters that are part of the string representations of data structures no longer matching all nested data structures.
313 lines
11 KiB
Rust
313 lines
11 KiB
Rust
use nu_test_support::nu;
|
|
|
|
#[test]
|
|
fn find_with_list_search_with_string() {
|
|
let actual = nu!("[moe larry curly] | find moe | get 0");
|
|
let actual_no_highlight = nu!("[moe larry curly] | find --no-highlight moe | get 0");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"\u{1b}[37m\u{1b}[0m\u{1b}[41;37mmoe\u{1b}[0m\u{1b}[37m\u{1b}[0m"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "moe");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_list_search_with_char() {
|
|
let actual = nu!("[moe larry curly] | find l | to json -r");
|
|
let actual_no_highlight = nu!("[moe larry curly] | find --no-highlight l | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[\"\\u001b[37m\\u001b[0m\\u001b[41;37ml\\u001b[0m\\u001b[37marry\\u001b[0m\",\"\\u001b[37mcur\\u001b[0m\\u001b[41;37ml\\u001b[0m\\u001b[37my\\u001b[0m\"]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[\"larry\",\"curly\"]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_bytestream_search_with_char() {
|
|
let actual =
|
|
nu!("\"ABC\" | save foo.txt; let res = open foo.txt | find abc; rm foo.txt; $res | get 0");
|
|
let actual_no_highlight = nu!(
|
|
"\"ABC\" | save foo.txt; let res = open foo.txt | find --no-highlight abc; rm foo.txt; $res | get 0"
|
|
);
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"\u{1b}[37m\u{1b}[0m\u{1b}[41;37mABC\u{1b}[0m\u{1b}[37m\u{1b}[0m"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "ABC");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_list_search_with_number() {
|
|
let actual = nu!("[1 2 3 4 5] | find 3 | get 0");
|
|
let actual_no_highlight = nu!("[1 2 3 4 5] | find --no-highlight 3 | get 0");
|
|
|
|
assert_eq!(actual.out, "3");
|
|
assert_eq!(actual_no_highlight.out, "3");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_string() {
|
|
let actual = nu!("echo Cargo.toml | find toml");
|
|
let actual_no_highlight = nu!("echo Cargo.toml | find --no-highlight toml");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"\u{1b}[37mCargo.\u{1b}[0m\u{1b}[41;37mtoml\u{1b}[0m\u{1b}[37m\u{1b}[0m"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "Cargo.toml");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_string_not_found() {
|
|
let actual = nu!("[moe larry curly] | find shemp | is-empty");
|
|
let actual_no_highlight = nu!("[moe larry curly] | find --no-highlight shemp | is-empty");
|
|
|
|
assert_eq!(actual.out, "true");
|
|
assert_eq!(actual_no_highlight.out, "true");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_filepath_search_with_string() {
|
|
let actual =
|
|
nu!(r#"["amigos.txt","arepas.clu","los.txt","tres.txt"] | find arep | to json -r"#);
|
|
let actual_no_highlight = nu!(
|
|
r#"["amigos.txt","arepas.clu","los.txt","tres.txt"] | find --no-highlight arep | to json -r"#
|
|
);
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[\"\\u001b[37m\\u001b[0m\\u001b[41;37marep\\u001b[0m\\u001b[37mas.clu\\u001b[0m\"]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[\"arepas.clu\"]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_filepath_search_with_multiple_patterns() {
|
|
let actual =
|
|
nu!(r#"["amigos.txt","arepas.clu","los.txt","tres.txt"] | find arep ami | to json -r"#);
|
|
let actual_no_highlight = nu!(
|
|
r#"["amigos.txt","arepas.clu","los.txt","tres.txt"] | find --no-highlight arep ami | to json -r"#
|
|
);
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[\"\\u001b[37m\\u001b[0m\\u001b[41;37mami\\u001b[0m\\u001b[37mgos.txt\\u001b[0m\",\"\\u001b[37m\\u001b[0m\\u001b[41;37marep\\u001b[0m\\u001b[37mas.clu\\u001b[0m\"]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[\"amigos.txt\",\"arepas.clu\"]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_takes_into_account_linebreaks_in_string() {
|
|
let actual = nu!(r#""atest\nanothertest\nnohit\n" | find a | length"#);
|
|
let actual_no_highlight =
|
|
nu!(r#""atest\nanothertest\nnohit\n" | find --no-highlight a | length"#);
|
|
|
|
assert_eq!(actual.out, "2");
|
|
assert_eq!(actual_no_highlight.out, "2");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_regex_in_table_keeps_row_if_one_column_matches() {
|
|
let actual = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find --regex ce | get name | to json -r"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find --no-highlight --regex ce | get name | to json -r"
|
|
);
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
r#"["\u001b[37mMauri\u001b[0m\u001b[41;37mce\u001b[0m\u001b[37m\u001b[0m","\u001b[37mLauren\u001b[0m\u001b[41;37mce\u001b[0m\u001b[37m\u001b[0m"]"#
|
|
);
|
|
assert_eq!(actual_no_highlight.out, r#"["Maurice","Laurence"]"#);
|
|
}
|
|
|
|
#[test]
|
|
fn inverted_find_with_regex_in_table_keeps_row_if_none_of_the_columns_matches() {
|
|
let actual = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find --regex moe --invert | get name | to json -r"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find --no-highlight --regex moe --invert | get name | to json -r"
|
|
);
|
|
|
|
assert_eq!(actual.out, r#"["Laurence"]"#);
|
|
assert_eq!(actual_no_highlight.out, r#"["Laurence"]"#);
|
|
}
|
|
|
|
#[test]
|
|
fn find_in_table_only_keep_rows_with_matches_on_selected_columns() {
|
|
let actual = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find r --columns [nickname] | get name | to json -r"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find r --no-highlight --columns [nickname] | get name | to json -r"
|
|
);
|
|
|
|
assert!(actual.out.contains("Laurence"));
|
|
assert!(!actual.out.contains("Maurice"));
|
|
assert!(actual_no_highlight.out.contains("Laurence"));
|
|
assert!(!actual_no_highlight.out.contains("Maurice"));
|
|
}
|
|
|
|
#[test]
|
|
fn inverted_find_in_table_keeps_row_if_none_of_the_selected_columns_matches() {
|
|
let actual = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find r --columns [nickname] --invert | get name | to json -r"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname]; [Maurice moe] [Laurence larry]] | find r --no-highlight --columns [nickname] --invert | get name | to json -r"
|
|
);
|
|
|
|
assert_eq!(actual.out, r#"["Maurice"]"#);
|
|
assert_eq!(actual_no_highlight.out, r#"["Maurice"]"#);
|
|
}
|
|
|
|
#[test]
|
|
fn find_in_table_keeps_row_with_single_matched_and_keeps_other_columns() {
|
|
let actual = nu!(
|
|
"[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18]] | find Maurice"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18]] | find --no-highlight Maurice"
|
|
);
|
|
|
|
println!("{:?}", actual.out);
|
|
assert!(actual.out.contains("moe"));
|
|
assert!(actual.out.contains("Maurice"));
|
|
assert!(actual.out.contains("23"));
|
|
|
|
println!("{:?}", actual_no_highlight.out);
|
|
assert!(actual_no_highlight.out.contains("moe"));
|
|
assert!(actual_no_highlight.out.contains("Maurice"));
|
|
assert!(actual_no_highlight.out.contains("23"));
|
|
}
|
|
|
|
#[test]
|
|
fn find_in_table_keeps_row_with_multiple_matched_and_keeps_other_columns() {
|
|
let actual = nu!(
|
|
"[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18] [William bill 60]] | find moe William"
|
|
);
|
|
let actual_no_highlight = nu!(
|
|
"[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18] [William bill 60]] | find --no-highlight moe William"
|
|
);
|
|
|
|
println!("{:?}", actual.out);
|
|
assert!(actual.out.contains("moe"));
|
|
assert!(actual.out.contains("Maurice"));
|
|
assert!(actual.out.contains("23"));
|
|
assert!(actual.out.contains("William"));
|
|
assert!(actual.out.contains("will"));
|
|
assert!(actual.out.contains("18"));
|
|
assert!(actual.out.contains("bill"));
|
|
assert!(actual.out.contains("60"));
|
|
|
|
println!("{:?}", actual_no_highlight.out);
|
|
assert!(actual_no_highlight.out.contains("moe"));
|
|
assert!(actual_no_highlight.out.contains("Maurice"));
|
|
assert!(actual_no_highlight.out.contains("23"));
|
|
assert!(actual_no_highlight.out.contains("William"));
|
|
assert!(actual_no_highlight.out.contains("will"));
|
|
assert!(actual_no_highlight.out.contains("18"));
|
|
assert!(actual_no_highlight.out.contains("bill"));
|
|
assert!(actual_no_highlight.out.contains("60"));
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_1() {
|
|
let actual = nu!("[[d]; [a?b] [a*b] [a{1}b] ] | find '?' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[[d]; [a?b] [a*b] [a{1}b] ] | find --no-highlight '?' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma\\u001b[0m\\u001b[41;37m?\\u001b[0m\\u001b[37mb\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a?b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_2() {
|
|
let actual = nu!("[[d]; [a?b] [a*b] [a{1}b]] | find '*' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[[d]; [a?b] [a*b] [a{1}b]] | find --no-highlight '*' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma\\u001b[0m\\u001b[41;37m*\\u001b[0m\\u001b[37mb\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a*b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_3() {
|
|
let actual = nu!("[[d]; [a?b] [a*b] [a{1}b] ] | find '{1}' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[[d]; [a?b] [a*b] [a{1}b] ] | find --no-highlight '{1}' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma\\u001b[0m\\u001b[41;37m{1}\\u001b[0m\\u001b[37mb\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a{1}b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_4() {
|
|
let actual = nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find '[' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find --no-highlight '[' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma\\u001b[0m\\u001b[41;37m[\\u001b[0m\\u001b[37m]b\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a[]b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_5() {
|
|
let actual = nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find ']' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find --no-highlight ']' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma[\\u001b[0m\\u001b[41;37m]\\u001b[0m\\u001b[37mb\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a[]b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_with_string_search_with_special_char_6() {
|
|
let actual = nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find '[]' | to json -r");
|
|
let actual_no_highlight =
|
|
nu!("[{d: a?b} {d: a*b} {d: a{1}b} {d: a[]b}] | find --no-highlight '[]' | to json -r");
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
"[{\"d\":\"\\u001b[37ma\\u001b[0m\\u001b[41;37m[]\\u001b[0m\\u001b[37mb\\u001b[0m\"}]"
|
|
);
|
|
assert_eq!(actual_no_highlight.out, "[{\"d\":\"a[]b\"}]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_in_nested_list_dont_match_bracket() {
|
|
let actual = nu!(r#"[ [foo bar] [foo baz] ] | find "[" | to json -r"#);
|
|
|
|
assert_eq!(actual.out, "[]");
|
|
}
|
|
|
|
#[test]
|
|
fn find_and_highlight_in_nested_list() {
|
|
let actual = nu!(r#"[ [foo bar] [foo baz] ] | find "foo" | to json -r"#);
|
|
|
|
assert_eq!(
|
|
actual.out,
|
|
r#"[["\u001b[37m\u001b[0m\u001b[41;37mfoo\u001b[0m\u001b[37m\u001b[0m","bar"],["\u001b[37m\u001b[0m\u001b[41;37mfoo\u001b[0m\u001b[37m\u001b[0m","baz"]]"#
|
|
);
|
|
}
|