Test filter files
This commit is contained in:
parent
26254f7022
commit
0f51a6e794
|
@ -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");
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ use watchexec::{
|
||||||
event::{filekind::FileEventKind, Event, FileType, ProcessEnd, Source, Tag},
|
event::{filekind::FileEventKind, Event, FileType, ProcessEnd, Source, Tag},
|
||||||
filter::{
|
filter::{
|
||||||
globset::GlobsetFilterer,
|
globset::GlobsetFilterer,
|
||||||
tagged::{Filter, Matcher, Op, Pattern, TaggedFilterer},
|
tagged::{files::FilterFile, Filter, Matcher, Op, Pattern, TaggedFilterer},
|
||||||
Filterer,
|
Filterer,
|
||||||
},
|
},
|
||||||
ignore_files::IgnoreFile,
|
ignore_files::IgnoreFile,
|
||||||
|
@ -21,8 +21,8 @@ use watchexec::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod globset {
|
pub mod globset {
|
||||||
pub use super::file;
|
|
||||||
pub use super::globset_filt as filt;
|
pub use super::globset_filt as filt;
|
||||||
|
pub use super::ig_file as file;
|
||||||
pub use super::Applies;
|
pub use super::Applies;
|
||||||
pub use super::PathHarness;
|
pub use super::PathHarness;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ pub mod globset_ig {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod tagged {
|
pub mod tagged {
|
||||||
pub use super::file;
|
pub use super::ig_file as file;
|
||||||
pub use super::tagged_filt as filt;
|
pub use super::tagged_filt as filt;
|
||||||
pub use super::Applies;
|
pub use super::Applies;
|
||||||
pub use super::FilterExt;
|
pub use super::FilterExt;
|
||||||
|
@ -47,6 +47,12 @@ pub mod tagged_ig {
|
||||||
pub use super::tagged_igfilt as filt;
|
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 {
|
pub trait PathHarness {
|
||||||
fn check_path(
|
fn check_path(
|
||||||
&self,
|
&self,
|
||||||
|
@ -252,7 +258,27 @@ pub async fn tagged_igfilt(origin: &str, ignore_files: &[IgnoreFile]) -> Arc<Tag
|
||||||
filterer
|
filterer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file(name: &str) -> IgnoreFile {
|
pub async fn tagged_fffilt(
|
||||||
|
origin: &str,
|
||||||
|
ignore_files: &[IgnoreFile],
|
||||||
|
filter_files: &[FilterFile],
|
||||||
|
) -> Arc<TaggedFilterer> {
|
||||||
|
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(".")
|
let path = dunce::canonicalize(".")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.join("tests")
|
.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 {
|
pub trait Applies {
|
||||||
fn applies_in(self, origin: &str) -> Self;
|
fn applies_in(self, origin: &str) -> Self;
|
||||||
fn applies_to(self, project_type: ProjectType) -> 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 {
|
pub fn filter(expr: &str) -> Filter {
|
||||||
Filter::from_str(expr).expect("parse filter")
|
Filter::from_str(expr).expect("parse filter")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# comment
|
||||||
|
|
||||||
|
# blank line
|
|
@ -0,0 +1,2 @@
|
||||||
|
type==dir
|
||||||
|
path*=prunes
|
|
@ -0,0 +1,2 @@
|
||||||
|
path=nah
|
||||||
|
!path=nah.yeah
|
|
@ -0,0 +1,5 @@
|
||||||
|
path*!Cargo.toml
|
||||||
|
path*!package.json
|
||||||
|
path*!*.gemspec
|
||||||
|
path~!test-[^u]+
|
||||||
|
path~![.]sw[a-z]$
|
Loading…
Reference in New Issue