use super::Expr;
use std::collections::{HashMap, HashSet};
fn create_term(keyword: &str) -> Expr {
Expr::Term {
keywords: vec![keyword.to_string()],
field: None,
required: false,
excluded: false,
exact: false,
}
}
fn create_required_term(keyword: &str) -> Expr {
Expr::Term {
keywords: vec![keyword.to_string()],
field: None,
required: true,
excluded: false,
exact: false,
}
}
fn create_excluded_term(keyword: &str) -> Expr {
Expr::Term {
keywords: vec![keyword.to_string()],
field: None,
required: false,
excluded: true,
exact: false,
}
}
fn create_exact_term(keyword: &str) -> Expr {
Expr::Term {
keywords: vec![keyword.to_string()],
field: None,
required: false,
excluded: false,
exact: true,
}
}
fn create_term_indices(terms: &[&str]) -> HashMap<String, usize> {
let mut map = HashMap::new();
for (i, &term) in terms.iter().enumerate() {
map.insert(term.to_string(), i);
}
map
}
fn create_matched_terms(indices: &[usize]) -> HashSet<usize> {
indices.iter().copied().collect()
}
#[test]
fn test_evaluate_simple_terms() {
let term_indices = create_term_indices(&["foo", "bar", "baz"]);
let expr = create_term("foo");
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let expr = create_required_term("foo");
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let expr = create_excluded_term("foo");
let matched_terms = create_matched_terms(&[1, 2]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_and_expressions() {
let term_indices = create_term_indices(&["foo", "bar", "baz"]);
let expr = Expr::And(
Box::new(create_term("foo")),
Box::new(create_term("bar"))
);
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_or_expressions() {
let term_indices = create_term_indices(&["foo", "bar", "baz"]);
let expr = Expr::Or(
Box::new(create_term("foo")),
Box::new(create_term("bar"))
);
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_complex_expressions() {
let term_indices = create_term_indices(&["foo", "bar", "baz", "qux", "zod"]);
let expr = Expr::Or(
Box::new(Expr::And(
Box::new(create_term("foo")),
Box::new(create_term("bar"))
)),
Box::new(create_term("baz"))
);
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[2]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1, 2]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[3, 4]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_required_excluded_terms() {
let term_indices = create_term_indices(&["foo", "bar", "baz", "qux"]);
let expr = Expr::And(
Box::new(create_required_term("foo")),
Box::new(create_excluded_term("bar"))
);
let matched_terms = create_matched_terms(&[0, 2, 3]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[2, 3]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_elastic_style_queries() {
let term_indices = create_term_indices(&["keyword1", "keyword2", "keyword3", "keyword4"]);
let expr = Expr::And(
Box::new(Expr::Or(
Box::new(create_required_term("keyword1")),
Box::new(create_required_term("keyword2"))
)),
Box::new(create_excluded_term("keyword3"))
);
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[3]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_nested_expressions() {
let term_indices = create_term_indices(&["a", "b", "c", "d", "e"]);
let expr = Expr::And(
Box::new(create_term("a")),
Box::new(Expr::Or(
Box::new(create_term("b")),
Box::new(Expr::And(
Box::new(create_term("c")),
Box::new(Expr::Or(
Box::new(create_term("d")),
Box::new(create_term("e"))
))
))
))
);
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 2, 3]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 2, 4]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1, 2, 3, 4]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1, 2, 3, 4]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 2]); assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_with_missing_terms() {
let term_indices = create_term_indices(&["foo", "bar"]);
let expr = Expr::And(
Box::new(create_term("foo")),
Box::new(create_term("baz")) );
let matched_terms = create_matched_terms(&[0]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let expr = Expr::And(
Box::new(create_term("foo")),
Box::new(create_excluded_term("baz")) );
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_optional_terms() {
let term_indices = create_term_indices(&["required", "optional", "excluded"]);
let expr = Expr::And(
Box::new(Expr::Or(
Box::new(create_required_term("required")),
Box::new(create_term("optional"))
)),
Box::new(create_excluded_term("excluded"))
);
let matched_terms = create_matched_terms(&[0]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]);
assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 2]);
assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}
#[test]
fn test_evaluate_exact_terms() {
let term_indices = create_term_indices(&["running", "run", "whitelist", "white", "list"]);
let expr = create_exact_term("running");
let matched_terms = create_matched_terms(&[0]); assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[1]); assert!(!expr.evaluate(&matched_terms, &term_indices, false));
let expr = Expr::Term {
keywords: vec!["run".to_string()],
field: None,
required: false,
excluded: false,
exact: false,
};
let mut term_indices_updated = HashMap::new();
term_indices_updated.insert("run".to_string(), 1); term_indices_updated.insert("running".to_string(), 0); term_indices_updated.insert("whitelist".to_string(), 2);
term_indices_updated.insert("white".to_string(), 3);
term_indices_updated.insert("list".to_string(), 4);
let matched_terms = create_matched_terms(&[0, 1]); assert!(expr.evaluate(&matched_terms, &term_indices_updated, false));
let matched_terms = create_matched_terms(&[1]); assert!(expr.evaluate(&matched_terms, &term_indices, false));
let expr = Expr::And(
Box::new(Expr::Term {
keywords: vec!["run".to_string()], field: None,
required: false,
excluded: false,
exact: false,
}),
Box::new(create_exact_term("whitelist"))
);
let matched_terms = create_matched_terms(&[1, 2]); assert!(expr.evaluate(&matched_terms, &term_indices, false));
let matched_terms = create_matched_terms(&[0, 3, 4]); assert!(!expr.evaluate(&matched_terms, &term_indices, false));
}