filter: add unit tests
This commit is contained in:
391
src/filter.rs
391
src/filter.rs
@@ -14,16 +14,27 @@ pub enum CaseSensitivity {
|
||||
CommandDependent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ComparisonOperator {
|
||||
Equal,
|
||||
NotEqual,
|
||||
GreaterThan,
|
||||
GreaterThanOrEqual,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Filter {
|
||||
Not(Box<Filter>),
|
||||
And(Box<Filter>, Box<Filter>),
|
||||
|
||||
EqTag(Tag, String, CaseSensitivity),
|
||||
Contains(Tag, String, CaseSensitivity),
|
||||
StartsWith(Tag, String, CaseSensitivity),
|
||||
PerlRegex(Tag, String),
|
||||
NegPerlRegex(Tag, String),
|
||||
// The bool indicates whether the comparison is negated (true for !=, false for ==)
|
||||
EqTag(Tag, CaseSensitivity, bool),
|
||||
Contains(Tag, CaseSensitivity, bool),
|
||||
StartsWith(Tag, CaseSensitivity, bool),
|
||||
PerlRegex(Tag),
|
||||
NegPerlRegex(Tag),
|
||||
EqUri(String),
|
||||
Base(String),
|
||||
ModifiedSince(u64),
|
||||
@@ -37,9 +48,375 @@ pub enum Filter {
|
||||
bits: Option<u8>,
|
||||
channels: Option<u8>,
|
||||
},
|
||||
PrioCmp(Priority),
|
||||
PrioCmp(ComparisonOperator, Priority),
|
||||
}
|
||||
|
||||
pub fn parse_filter(parts: &mut SplitWhitespace<'_>) -> Result<Filter, RequestParserError> {
|
||||
todo!()
|
||||
// TODO: count parentheses and extract the full filter string
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn parse_filter_str(string: &str) -> Result<Filter, RequestParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_eq_tag() {
|
||||
let mut parts = "(artist == 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
)
|
||||
);
|
||||
|
||||
let mut parts = "(artist != 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_contains() {
|
||||
let mut parts = "(album contains 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(album !contains 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_starts_with() {
|
||||
let mut parts = "(title starts_with 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(title !starts_with 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_perl_regex_positive() {
|
||||
let mut parts = "(composer =~ 'Beethoven.*')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::PerlRegex(Tag::Composer("Beethoven.*".to_string())),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_perl_regex_negative() {
|
||||
let mut parts = "(genre !~ 'Pop.*')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::NegPerlRegex(Tag::Genre("Pop.*".to_string())),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_base() {
|
||||
let mut parts = "(base 'Rock/Classics')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(filter, Filter::Base("Rock/Classics".to_string()),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_modified_since() {
|
||||
let mut parts = "(modified-since '1622505600')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(filter, Filter::ModifiedSince(1622505600),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_audio_added_since() {
|
||||
let mut parts = "(added-since '1622505600')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(filter, Filter::ModifiedSince(1622505600),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_audio_format_eq() {
|
||||
let mut parts = "(AudioFormat == '44100:16:2')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::AudioFormatEq {
|
||||
sample_rate: 44100,
|
||||
bits: 16,
|
||||
channels: 2,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_audio_format_eq_mask() {
|
||||
let mut parts = "(AudioFormat =~ '44100:*:2')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::AudioFormatEqMask {
|
||||
sample_rate: Some(44100),
|
||||
bits: None,
|
||||
channels: Some(2),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_prio_cmp() {
|
||||
let mut parts = "(prio >= 42)".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::PrioCmp(ComparisonOperator::GreaterThanOrEqual, 42),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_not() {
|
||||
let mut parts = "(!(artist == 'The Beatles'))".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Not(Box::new(Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
))),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_and() {
|
||||
let mut parts =
|
||||
"((artist == 'The Beatles') AND (album == 'Abbey Road'))".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::And(
|
||||
Box::new(Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
)),
|
||||
Box::new(Filter::EqTag(
|
||||
Tag::Album("Abbey Road".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_explicitly_case_sensitive() {
|
||||
let mut parts = "(artist eq_cs 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(artist !eq_cs 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(album contains_cs 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(album !contains_cs 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(title starts_with_cs 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(title !starts_with_cs 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CaseSensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_explicitly_case_insensitive() {
|
||||
let mut parts = "(artist eq_ci 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(artist !eq_ci 'The Beatles')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(album contains_ci 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(album !contains_ci 'Greatest Hits')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::Contains(
|
||||
Tag::Album("Greatest Hits".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(title starts_with_ci 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut parts = "(title !starts_with_ci 'Symphony No. ')".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::StartsWith(
|
||||
Tag::Title("Symphony No. ".to_string()),
|
||||
CaseSensitivity::CaseInsensitive,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_string_escapes() {
|
||||
let mut parts = "(Artist == \"foo\\'bar\\\"\")".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("foo'bar\"".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter_excessive_whitespace() {
|
||||
let mut parts = "(\tartist\n == 'The Beatles' ) ".split_whitespace();
|
||||
let filter = parse_filter(&mut parts).unwrap();
|
||||
assert_eq!(
|
||||
filter,
|
||||
Filter::EqTag(
|
||||
Tag::Artist("The Beatles".to_string()),
|
||||
CaseSensitivity::CommandDependent,
|
||||
false,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user