search.rs

  1use project::search::SearchQuery;
  2use text::Rope;
  3use util::{
  4    paths::{PathMatcher, PathStyle},
  5    rel_path::RelPath,
  6};
  7
  8#[test]
  9fn path_matcher_creation_for_valid_paths() {
 10    for valid_path in [
 11        "file",
 12        "Cargo.toml",
 13        ".DS_Store",
 14        "~/dir/another_dir/",
 15        "./dir/file",
 16        "dir/[a-z].txt",
 17    ] {
 18        let path_matcher = PathMatcher::new(&[valid_path.to_owned()], PathStyle::local())
 19            .unwrap_or_else(|e| panic!("Valid path {valid_path} should be accepted, but got: {e}"));
 20        assert!(
 21            path_matcher.is_match(&RelPath::new(valid_path.as_ref(), PathStyle::local()).unwrap()),
 22            "Path matcher for valid path {valid_path} should match itself"
 23        )
 24    }
 25}
 26
 27#[test]
 28fn path_matcher_creation_for_globs() {
 29    for invalid_glob in ["dir/[].txt", "dir/[a-z.txt", "dir/{file"] {
 30        match PathMatcher::new(&[invalid_glob.to_owned()], PathStyle::local()) {
 31            Ok(_) => panic!("Invalid glob {invalid_glob} should not be accepted"),
 32            Err(_expected) => {}
 33        }
 34    }
 35
 36    for valid_glob in [
 37        "dir/?ile",
 38        "dir/*.txt",
 39        "dir/**/file",
 40        "dir/[a-z].txt",
 41        "{dir,file}",
 42    ] {
 43        match PathMatcher::new(&[valid_glob.to_owned()], PathStyle::local()) {
 44            Ok(_expected) => {}
 45            Err(e) => panic!("Valid glob should be accepted, but got: {e}"),
 46        }
 47    }
 48}
 49
 50#[test]
 51fn test_case_sensitive_pattern_items() {
 52    let case_sensitive = false;
 53    let search_query = SearchQuery::regex(
 54        "test\\C",
 55        false,
 56        case_sensitive,
 57        false,
 58        false,
 59        Default::default(),
 60        Default::default(),
 61        false,
 62        None,
 63    )
 64    .expect("Should be able to create a regex SearchQuery");
 65
 66    assert_eq!(
 67        search_query.case_sensitive(),
 68        true,
 69        "Case sensitivity should be enabled when \\C pattern item is present in the query."
 70    );
 71
 72    let case_sensitive = true;
 73    let search_query = SearchQuery::regex(
 74        "test\\c",
 75        true,
 76        case_sensitive,
 77        false,
 78        false,
 79        Default::default(),
 80        Default::default(),
 81        false,
 82        None,
 83    )
 84    .expect("Should be able to create a regex SearchQuery");
 85
 86    assert_eq!(
 87        search_query.case_sensitive(),
 88        false,
 89        "Case sensitivity should be disabled when \\c pattern item is present, even if initially set to true."
 90    );
 91
 92    let case_sensitive = false;
 93    let search_query = SearchQuery::regex(
 94        "test\\c\\C",
 95        false,
 96        case_sensitive,
 97        false,
 98        false,
 99        Default::default(),
100        Default::default(),
101        false,
102        None,
103    )
104    .expect("Should be able to create a regex SearchQuery");
105
106    assert_eq!(
107        search_query.case_sensitive(),
108        true,
109        "Case sensitivity should be enabled when \\C is the last pattern item, even after a \\c."
110    );
111
112    let case_sensitive = false;
113    let search_query = SearchQuery::regex(
114        "tests\\\\C",
115        false,
116        case_sensitive,
117        false,
118        false,
119        Default::default(),
120        Default::default(),
121        false,
122        None,
123    )
124    .expect("Should be able to create a regex SearchQuery");
125
126    assert_eq!(
127        search_query.case_sensitive(),
128        false,
129        "Case sensitivity should not be enabled when \\C pattern item is preceded by a backslash."
130    );
131}
132
133#[gpui::test]
134async fn test_multiline_regex(cx: &mut gpui::TestAppContext) {
135    let search_query = SearchQuery::regex(
136        "^hello$\n",
137        false,
138        false,
139        false,
140        false,
141        Default::default(),
142        Default::default(),
143        false,
144        None,
145    )
146    .expect("Should be able to create a regex SearchQuery");
147
148    use language::Buffer;
149    let text = Rope::from("hello\nworld\nhello\nworld");
150    let snapshot = cx
151        .update(|app| Buffer::build_snapshot(text, None, None, app))
152        .await;
153
154    let results = search_query.search(&snapshot, None).await;
155    assert_eq!(results, vec![0..6, 12..18]);
156}