From 0f51a6e7946195d3f40f0ad4130466ae3c103706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Fri, 24 Dec 2021 02:21:07 +1300 Subject: [PATCH] Test filter files --- lib/tests/filter_tagged_filterfiles.rs | 116 +++++++++++++++++++++++++ lib/tests/helpers.rs | 48 +++++++++- lib/tests/ignores/empty.wef | 3 + lib/tests/ignores/folder.wef | 2 + lib/tests/ignores/negate.wef | 2 + lib/tests/ignores/path-patterns.wef | 5 ++ 6 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 lib/tests/filter_tagged_filterfiles.rs create mode 100644 lib/tests/ignores/empty.wef create mode 100644 lib/tests/ignores/folder.wef create mode 100644 lib/tests/ignores/negate.wef create mode 100644 lib/tests/ignores/path-patterns.wef diff --git a/lib/tests/filter_tagged_filterfiles.rs b/lib/tests/filter_tagged_filterfiles.rs new file mode 100644 index 0000000..acd1d69 --- /dev/null +++ b/lib/tests/filter_tagged_filterfiles.rs @@ -0,0 +1,116 @@ +use watchexec::{ + event::{filekind::*, ProcessEnd, Source}, + signal::source::MainSignal, +}; + +mod helpers; +use helpers::tagged_ff::*; + +#[tokio::test] +async fn empty_filter_passes_everything() { + let filterer = filt("", &[], &[file("empty.wef")]).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"); + + filterer.source_does_pass(Source::Keyboard); + filterer.fek_does_pass(FileEventKind::Create(CreateKind::File)); + filterer.pid_does_pass(1234); + filterer.signal_does_pass(MainSignal::User1); + filterer.complete_does_pass(None); + filterer.complete_does_pass(Some(ProcessEnd::Success)); +} + +#[tokio::test] +async fn folder() { + let filterer = filt("", &[], &[file("folder.wef")]).await; + + filterer.file_doesnt_pass("apples"); + filterer.file_doesnt_pass("apples/oranges/bananas"); + filterer.dir_doesnt_pass("apples"); + filterer.dir_doesnt_pass("apples/carrots"); + + filterer.file_doesnt_pass("raw-prunes"); + filterer.dir_doesnt_pass("raw-prunes"); + + filterer.file_doesnt_pass("prunes"); + filterer.file_doesnt_pass("prunes/oranges/bananas"); + + filterer.dir_does_pass("prunes"); + filterer.dir_does_pass("prunes/carrots/cauliflowers/oranges"); +} + +#[tokio::test] +async fn patterns() { + let filterer = filt("", &[], &[file("path-patterns.wef")]).await; + + // Unmatched + filterer.file_does_pass("FINAL-FINAL.docx"); + filterer.dir_does_pass("/a/folder"); + filterer.file_does_pass("rat"); + filterer.file_does_pass("foo/bar/rat"); + filterer.file_does_pass("/foo/bar/rat"); + + // Cargo.toml + filterer.file_doesnt_pass("Cargo.toml"); + filterer.dir_doesnt_pass("Cargo.toml"); + filterer.file_does_pass("Cargo.json"); + + // package.json + filterer.file_doesnt_pass("package.json"); + filterer.dir_doesnt_pass("package.json"); + filterer.file_does_pass("package.toml"); + + // *.gemspec + filterer.file_doesnt_pass("pearl.gemspec"); + filterer.dir_doesnt_pass("sapphire.gemspec"); + filterer.file_doesnt_pass(".gemspec"); + filterer.file_does_pass("diamond.gemspecial"); + + // test-[^u]+ + filterer.file_does_pass("test-unit"); + filterer.dir_doesnt_pass("test-integration"); + filterer.file_does_pass("tester-helper"); + + // [.]sw[a-z]$ + filterer.file_doesnt_pass("source.swa"); + filterer.file_doesnt_pass(".source.swb"); + filterer.file_doesnt_pass("sub/source.swc"); + filterer.file_does_pass("sub/dir.swa/file"); + filterer.file_does_pass("source.sw1"); +} + +#[tokio::test] +async fn negate() { + let filterer = filt("", &[], &[file("negate.wef")]).await; + + filterer.file_doesnt_pass("yeah"); + filterer.file_does_pass("nah"); + filterer.file_does_pass("nah.yeah"); +} + +#[tokio::test] +async fn ignores_and_filters() { + let filterer = filt("", &[file("globs").0], &[file("folder.wef")]).await; + + // ignored + filterer.dir_doesnt_pass("test-helper"); + + // not filtered + filterer.dir_doesnt_pass("tester-helper"); + + // not ignored && filtered + filterer.dir_does_pass("prunes/tester-helper"); +} diff --git a/lib/tests/helpers.rs b/lib/tests/helpers.rs index b80c819..bfcb41b 100644 --- a/lib/tests/helpers.rs +++ b/lib/tests/helpers.rs @@ -12,7 +12,7 @@ use watchexec::{ event::{filekind::FileEventKind, Event, FileType, ProcessEnd, Source, Tag}, filter::{ globset::GlobsetFilterer, - tagged::{Filter, Matcher, Op, Pattern, TaggedFilterer}, + tagged::{files::FilterFile, Filter, Matcher, Op, Pattern, TaggedFilterer}, Filterer, }, ignore_files::IgnoreFile, @@ -21,8 +21,8 @@ use watchexec::{ }; pub mod globset { - pub use super::file; pub use super::globset_filt as filt; + pub use super::ig_file as file; pub use super::Applies; pub use super::PathHarness; } @@ -33,7 +33,7 @@ pub mod globset_ig { } pub mod tagged { - pub use super::file; + pub use super::ig_file as file; pub use super::tagged_filt as filt; pub use super::Applies; pub use super::FilterExt; @@ -47,6 +47,12 @@ pub mod tagged_ig { pub use super::tagged_igfilt as filt; } +pub mod tagged_ff { + pub use super::ff_file as file; + pub use super::tagged::*; + pub use super::tagged_fffilt as filt; +} + pub trait PathHarness { fn check_path( &self, @@ -252,7 +258,27 @@ pub async fn tagged_igfilt(origin: &str, ignore_files: &[IgnoreFile]) -> Arc IgnoreFile { +pub async fn tagged_fffilt( + origin: &str, + ignore_files: &[IgnoreFile], + filter_files: &[FilterFile], +) -> Arc { + let filterer = tagged_igfilt(origin, ignore_files).await; + let mut filters = Vec::new(); + for file in filter_files { + tracing::info!(?file, "loading filter file"); + filters.extend(file.load().await.expect("loading filter file")); + } + + filterer + .add_filters(&filters) + .await + .expect("adding filters"); + + filterer +} + +pub fn ig_file(name: &str) -> IgnoreFile { let path = dunce::canonicalize(".") .unwrap() .join("tests") @@ -265,6 +291,10 @@ pub fn file(name: &str) -> IgnoreFile { } } +pub fn ff_file(name: &str) -> FilterFile { + FilterFile(ig_file(name)) +} + pub trait Applies { fn applies_in(self, origin: &str) -> Self; fn applies_to(self, project_type: ProjectType) -> Self; @@ -283,6 +313,16 @@ impl Applies for IgnoreFile { } } +impl Applies for FilterFile { + fn applies_in(self, origin: &str) -> Self { + Self(self.0.applies_in(origin)) + } + + fn applies_to(self, project_type: ProjectType) -> Self { + Self(self.0.applies_to(project_type)) + } +} + pub fn filter(expr: &str) -> Filter { Filter::from_str(expr).expect("parse filter") } diff --git a/lib/tests/ignores/empty.wef b/lib/tests/ignores/empty.wef new file mode 100644 index 0000000..b39d30b --- /dev/null +++ b/lib/tests/ignores/empty.wef @@ -0,0 +1,3 @@ +# comment + +# blank line diff --git a/lib/tests/ignores/folder.wef b/lib/tests/ignores/folder.wef new file mode 100644 index 0000000..27c7449 --- /dev/null +++ b/lib/tests/ignores/folder.wef @@ -0,0 +1,2 @@ +type==dir +path*=prunes diff --git a/lib/tests/ignores/negate.wef b/lib/tests/ignores/negate.wef new file mode 100644 index 0000000..0f3643d --- /dev/null +++ b/lib/tests/ignores/negate.wef @@ -0,0 +1,2 @@ +path=nah +!path=nah.yeah diff --git a/lib/tests/ignores/path-patterns.wef b/lib/tests/ignores/path-patterns.wef new file mode 100644 index 0000000..06b23f6 --- /dev/null +++ b/lib/tests/ignores/path-patterns.wef @@ -0,0 +1,5 @@ +path*!Cargo.toml +path*!package.json +path*!*.gemspec +path~!test-[^u]+ +path~![.]sw[a-z]$