mod helpers; use helpers::globset::*; use std::io::Write; #[tokio::test] async fn empty_filter_passes_everything() { let filterer = filt(&[], &[], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/test/Cargo.toml"); filterer.dir_does_pass("/a/folder"); filterer.file_does_pass("apples/carrots/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples/carrots/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.dir_does_pass("apples/oranges/bananas"); } #[tokio::test] async fn exact_filename() { let filterer = filt(&["Cargo.toml"], &[], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("/test/foo/bar/Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("/test/Cargo.toml"); } #[tokio::test] async fn exact_filename_in_folder() { let filterer = filt(&["sub/Cargo.toml"], &[], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_does_pass("sub/Cargo.toml"); filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("/test/sub/Cargo.toml"); } #[tokio::test] async fn exact_filename_in_hidden_folder() { let filterer = filt(&[".sub/Cargo.toml"], &[], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_does_pass(".sub/Cargo.toml"); filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("/test/.sub/Cargo.toml"); } #[tokio::test] async fn exact_filenames_multiple() { let filterer = filt(&["Cargo.toml", "package.json"], &[], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("/test/foo/bar/Cargo.toml"); filterer.file_does_pass("package.json"); filterer.file_does_pass("/test/foo/bar/package.json"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_doesnt_pass("package.toml"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("/test/Cargo.toml"); filterer.dir_does_pass("/test/package.json"); } #[tokio::test] async fn glob_single_final_ext_star() { let filterer = filt(&["Cargo.*"], &[], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("Cargo.toml"); } #[tokio::test] async fn glob_star_trailing_slash() { let filterer = filt(&["Cargo.*/"], &[], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_doesnt_pass("Gemfile.toml"); filterer.file_doesnt_pass("FINAL-FINAL.docx"); filterer.dir_doesnt_pass("/a/folder"); filterer.dir_does_pass("Cargo.toml"); filterer.unk_doesnt_pass("Cargo.toml"); } #[tokio::test] async fn glob_star_leading_slash() { let filterer = filt(&["/Cargo.*"], &[], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.dir_does_pass("Cargo.toml"); filterer.unk_does_pass("Cargo.toml"); filterer.file_doesnt_pass("foo/Cargo.toml"); filterer.dir_doesnt_pass("foo/Cargo.toml"); } #[tokio::test] async fn glob_leading_double_star() { let filterer = filt(&["**/possum"], &[], &[], &[], &[]).await; filterer.file_does_pass("possum"); filterer.file_does_pass("foo/bar/possum"); filterer.file_does_pass("/foo/bar/possum"); filterer.dir_does_pass("possum"); filterer.dir_does_pass("foo/bar/possum"); filterer.dir_does_pass("/foo/bar/possum"); filterer.file_doesnt_pass("rat"); filterer.file_doesnt_pass("foo/bar/rat"); filterer.file_doesnt_pass("/foo/bar/rat"); } #[tokio::test] async fn glob_trailing_double_star() { let filterer = filt(&["possum/**"], &[], &[], &[], &[]).await; // these do work by expectation and in v1 filterer.file_does_pass("/test/possum/foo/bar"); filterer.dir_doesnt_pass("possum"); filterer.dir_doesnt_pass("foo/bar/possum"); filterer.dir_does_pass("possum/foo/bar"); filterer.file_doesnt_pass("rat"); filterer.file_doesnt_pass("foo/bar/rat"); filterer.file_doesnt_pass("/foo/bar/rat"); } #[tokio::test] async fn glob_middle_double_star() { let filterer = filt(&["apples/**/oranges"], &[], &[], &[], &[]).await; filterer.dir_doesnt_pass("/a/folder"); filterer.file_does_pass("apples/carrots/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples/carrots/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.dir_doesnt_pass("apples/oranges/bananas"); } #[tokio::test] async fn glob_double_star_trailing_slash() { let filterer = filt(&["apples/**/oranges/"], &[], &[], &[], &[]).await; filterer.dir_doesnt_pass("/a/folder"); filterer.file_doesnt_pass("apples/carrots/oranges"); filterer.file_doesnt_pass("apples/carrots/cauliflowers/oranges"); filterer.file_doesnt_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples/carrots/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.dir_doesnt_pass("apples/oranges/bananas"); filterer.unk_doesnt_pass("apples/carrots/oranges"); filterer.unk_doesnt_pass("apples/carrots/cauliflowers/oranges"); filterer.unk_doesnt_pass("apples/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn ignore_exact_filename() { let filterer = filt(&[], &["Cargo.toml"], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("/test/Cargo.toml"); } #[tokio::test] async fn ignore_exact_filename_in_folder() { let filterer = filt(&[], &["sub/Cargo.toml"], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_doesnt_pass("sub/Cargo.toml"); filterer.file_does_pass("/test/foo/bar/Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("/test/sub/Cargo.toml"); } #[tokio::test] async fn ignore_exact_filename_in_hidden_folder() { let filterer = filt(&[], &[".sub/Cargo.toml"], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_doesnt_pass(".sub/Cargo.toml"); filterer.file_does_pass("/test/foo/bar/Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("/test/.sub/Cargo.toml"); } #[tokio::test] async fn ignore_exact_filenames_multiple() { let filterer = filt(&[], &["Cargo.toml", "package.json"], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml"); filterer.file_doesnt_pass("package.json"); filterer.file_doesnt_pass("/test/foo/bar/package.json"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("package.toml"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("/test/Cargo.toml"); filterer.dir_doesnt_pass("/test/package.json"); } #[tokio::test] async fn ignore_glob_single_final_ext_star() { let filterer = filt(&[], &["Cargo.*"], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("Cargo.toml"); } #[tokio::test] async fn ignore_glob_star_trailing_slash() { let filterer = filt(&[], &["Cargo.*/"], &[], &[], &[]).await; filterer.file_does_pass("Cargo.toml"); filterer.file_does_pass("Cargo.json"); filterer.file_does_pass("Gemfile.toml"); filterer.file_does_pass("FINAL-FINAL.docx"); filterer.dir_does_pass("/a/folder"); filterer.dir_doesnt_pass("Cargo.toml"); filterer.unk_does_pass("Cargo.toml"); } #[tokio::test] async fn ignore_glob_star_leading_slash() { let filterer = filt(&[], &["/Cargo.*"], &[], &[], &[]).await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("Cargo.json"); filterer.dir_doesnt_pass("Cargo.toml"); filterer.unk_doesnt_pass("Cargo.toml"); filterer.file_does_pass("foo/Cargo.toml"); filterer.dir_does_pass("foo/Cargo.toml"); } #[tokio::test] async fn ignore_glob_leading_double_star() { let filterer = filt(&[], &["**/possum"], &[], &[], &[]).await; filterer.file_doesnt_pass("possum"); filterer.file_doesnt_pass("foo/bar/possum"); filterer.file_doesnt_pass("/foo/bar/possum"); filterer.dir_doesnt_pass("possum"); filterer.dir_doesnt_pass("foo/bar/possum"); filterer.dir_doesnt_pass("/foo/bar/possum"); filterer.file_does_pass("rat"); filterer.file_does_pass("foo/bar/rat"); filterer.file_does_pass("/foo/bar/rat"); } #[tokio::test] async fn ignore_glob_trailing_double_star() { let filterer = filt(&[], &["possum/**"], &[], &[], &[]).await; filterer.file_does_pass("possum"); filterer.file_doesnt_pass("possum/foo/bar"); filterer.file_does_pass("/possum/foo/bar"); filterer.file_doesnt_pass("/test/possum/foo/bar"); filterer.dir_does_pass("possum"); filterer.dir_does_pass("foo/bar/possum"); filterer.dir_does_pass("/foo/bar/possum"); filterer.dir_doesnt_pass("possum/foo/bar"); filterer.dir_does_pass("/possum/foo/bar"); filterer.dir_doesnt_pass("/test/possum/foo/bar"); filterer.file_does_pass("rat"); filterer.file_does_pass("foo/bar/rat"); filterer.file_does_pass("/foo/bar/rat"); } #[tokio::test] async fn ignore_glob_middle_double_star() { let filterer = filt(&[], &["apples/**/oranges"], &[], &[], &[]).await; filterer.dir_does_pass("/a/folder"); filterer.file_doesnt_pass("apples/carrots/oranges"); filterer.file_doesnt_pass("apples/carrots/cauliflowers/oranges"); filterer.file_doesnt_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_doesnt_pass("apples/carrots/oranges"); filterer.dir_doesnt_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_doesnt_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.dir_does_pass("apples/oranges/bananas"); } #[tokio::test] async fn ignore_glob_double_star_trailing_slash() { let filterer = filt(&[], &["apples/**/oranges/"], &[], &[], &[]).await; filterer.dir_does_pass("/a/folder"); filterer.file_does_pass("apples/carrots/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_doesnt_pass("apples/carrots/oranges"); filterer.dir_doesnt_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_doesnt_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.dir_does_pass("apples/oranges/bananas"); filterer.unk_does_pass("apples/carrots/oranges"); filterer.unk_does_pass("apples/carrots/cauliflowers/oranges"); filterer.unk_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn ignores_take_precedence() { let filterer = filt( &["*.docx", "*.toml", "*.json"], &["*.toml", "*.json"], &[], &[], &[], ) .await; filterer.file_doesnt_pass("Cargo.toml"); filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml"); filterer.file_doesnt_pass("package.json"); filterer.file_doesnt_pass("/test/foo/bar/package.json"); filterer.dir_doesnt_pass("/test/Cargo.toml"); filterer.dir_doesnt_pass("/test/package.json"); filterer.file_does_pass("FINAL-FINAL.docx"); } #[tokio::test] async fn extensions_fail_dirs() { let filterer = filt(&[], &[], &[], &["py"], &[]).await; filterer.file_does_pass("Cargo.py"); filterer.file_doesnt_pass("Cargo.toml"); filterer.dir_doesnt_pass("Cargo"); filterer.dir_doesnt_pass("Cargo.toml"); filterer.dir_doesnt_pass("Cargo.py"); } #[tokio::test] async fn extensions_fail_extensionless() { let filterer = filt(&[], &[], &[], &["py"], &[]).await; filterer.file_does_pass("Cargo.py"); filterer.file_doesnt_pass("Cargo"); } #[tokio::test] async fn multipath_allow_on_any_one_pass() { use watchexec::filter::Filterer; use watchexec_events::{Event, FileType, Tag}; let filterer = filt(&[], &[], &[], &["py"], &[]).await; let origin = tokio::fs::canonicalize(".").await.unwrap(); let event = Event { tags: vec![ Tag::Path { path: origin.join("Cargo.py"), file_type: Some(FileType::File), }, Tag::Path { path: origin.join("Cargo.toml"), file_type: Some(FileType::File), }, Tag::Path { path: origin.join("Cargo.py"), file_type: Some(FileType::Dir), }, ], metadata: Default::default(), }; assert!(filterer.check_event(&event, Priority::Normal).unwrap()); } #[tokio::test] async fn extensions_and_filters_glob() { let filterer = filt(&["*/justfile"], &[], &[], &["md", "css"], &[]).await; filterer.file_does_pass("foo/justfile"); filterer.file_does_pass("bar.md"); filterer.file_does_pass("qux.css"); filterer.file_doesnt_pass("nope.py"); // Watchexec 1.x buggy behaviour, should not pass #[cfg(unix)] filterer.file_does_pass("justfile"); } #[tokio::test] async fn extensions_and_filters_slash() { let filterer = filt(&["/justfile"], &[], &[], &["md", "css"], &[]).await; filterer.file_does_pass("justfile"); filterer.file_does_pass("bar.md"); filterer.file_does_pass("qux.css"); filterer.file_doesnt_pass("nope.py"); } #[tokio::test] async fn leading_single_glob_file() { let filterer = filt(&["*/justfile"], &[], &[], &[], &[]).await; filterer.file_does_pass("foo/justfile"); filterer.file_doesnt_pass("notfile"); filterer.file_doesnt_pass("not/thisfile"); // Watchexec 1.x buggy behaviour, should not pass #[cfg(unix)] filterer.file_does_pass("justfile"); } #[tokio::test] async fn nonpath_event_passes() { use watchexec::filter::Filterer; use watchexec_events::{Event, Source, Tag}; let filterer = filt(&[], &[], &[], &["py"], &[]).await; assert!(filterer .check_event( &Event { tags: vec![Tag::Source(Source::Internal)], metadata: Default::default(), }, Priority::Normal ) .unwrap()); assert!(filterer .check_event( &Event { tags: vec![Tag::Source(Source::Keyboard)], metadata: Default::default(), }, Priority::Normal ) .unwrap()); } // The following tests replicate the "buggy"/"confusing" watchexec v1 behaviour. #[tokio::test] async fn ignore_folder_incorrectly_with_bare_match() { let filterer = filt(&[], &["prunes"], &[], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes/oranges/bananas"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes"); filterer.dir_doesnt_pass("prunes"); // buggy behaviour (should be doesnt): filterer.file_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("prunes/oranges/bananas"); filterer.dir_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn ignore_folder_incorrectly_with_bare_and_leading_slash() { let filterer = filt(&[], &["/prunes"], &[], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes/oranges/bananas"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes"); filterer.dir_doesnt_pass("prunes"); // buggy behaviour (should be doesnt): filterer.file_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("prunes/oranges/bananas"); filterer.dir_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn ignore_folder_incorrectly_with_bare_and_trailing_slash() { let filterer = filt(&[], &["prunes/"], &[], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes/oranges/bananas"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.dir_doesnt_pass("prunes"); // buggy behaviour (should be doesnt): filterer.file_does_pass("prunes"); filterer.file_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("prunes/oranges/bananas"); filterer.dir_does_pass("prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("prunes/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn ignore_folder_incorrectly_with_only_double_double_glob() { let filterer = filt(&[], &["**/prunes/**"], &[], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes/oranges/bananas"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes/carrots/cauliflowers/oranges"); filterer.file_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes/oranges/bananas"); filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/oranges"); filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges"); // buggy behaviour (should be doesnt): filterer.file_does_pass("prunes"); filterer.dir_does_pass("prunes"); } #[tokio::test] async fn ignore_folder_correctly_with_double_and_double_double_globs() { let filterer = filt(&[], &["**/prunes", "**/prunes/**"], &[], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("apples/carrots/cauliflowers/oranges"); filterer.file_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("apples/oranges/bananas"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("apples/carrots/cauliflowers/oranges"); filterer.dir_does_pass("apples/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.file_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_does_pass("raw-prunes/oranges/bananas"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/oranges"); filterer.dir_does_pass("raw-prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes"); filterer.file_doesnt_pass("prunes/carrots/cauliflowers/oranges"); filterer.file_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges"); filterer.file_doesnt_pass("prunes/oranges/bananas"); filterer.dir_doesnt_pass("prunes"); filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/oranges"); filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges"); } #[tokio::test] async fn whitelist_overrides_ignore() { let filterer = filt(&[], &["**/prunes"], &["/prunes"], &[], &[]).await; filterer.file_does_pass("apples"); filterer.file_does_pass("/prunes"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("/prunes"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_doesnt_pass("apples/prunes"); filterer.file_doesnt_pass("raw/prunes"); filterer.dir_doesnt_pass("apples/prunes"); filterer.dir_doesnt_pass("raw/prunes"); } #[tokio::test] async fn whitelist_overrides_ignore_files() { let mut ignore_file = tempfile::NamedTempFile::new().unwrap(); let _ = ignore_file.write(b"prunes"); let origin = std::fs::canonicalize(".").unwrap(); let whitelist = origin.join("prunes").display().to_string(); let filterer = filt( &[], &[], &[&whitelist], &[], &[ignore_file.path().to_path_buf()], ) .await; filterer.file_does_pass("apples"); filterer.file_does_pass("prunes"); filterer.dir_does_pass("apples"); filterer.dir_does_pass("prunes"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_doesnt_pass("apples/prunes"); filterer.file_doesnt_pass("raw/prunes"); filterer.dir_doesnt_pass("apples/prunes"); filterer.dir_doesnt_pass("raw/prunes"); } #[tokio::test] async fn whitelist_overrides_ignore_files_nested() { let mut ignore_file = tempfile::NamedTempFile::new().unwrap(); let _ = ignore_file.write(b"prunes\n"); let origin = std::fs::canonicalize(".").unwrap(); let whitelist = origin.join("prunes").join("target").display().to_string(); let filterer = filt( &[], &[], &[&whitelist], &[], &[ignore_file.path().to_path_buf()], ) .await; filterer.file_does_pass("apples"); filterer.file_doesnt_pass("prunes"); filterer.dir_does_pass("apples"); filterer.dir_doesnt_pass("prunes"); filterer.file_does_pass("raw-prunes"); filterer.dir_does_pass("raw-prunes"); filterer.file_doesnt_pass("prunes/apples"); filterer.file_doesnt_pass("prunes/raw"); filterer.dir_doesnt_pass("prunes/apples"); filterer.dir_doesnt_pass("prunes/raw"); filterer.file_doesnt_pass("apples/prunes"); filterer.file_doesnt_pass("raw/prunes"); filterer.dir_doesnt_pass("apples/prunes"); filterer.dir_doesnt_pass("raw/prunes"); filterer.file_does_pass("prunes/target"); filterer.dir_does_pass("prunes/target"); filterer.file_doesnt_pass("prunes/nested/target"); filterer.dir_doesnt_pass("prunes/nested/target"); }