use detect::parser::test_utils::RawTestExpr;
use detect::parser::*;
#[test]
fn test_unterminated_double_quote() {
let result = RawParser::parse_raw_expr(r#"contents ~= "a"#);
assert!(result.is_err(), "Unterminated double quote should fail");
let result = RawParser::parse_raw_expr(r#"name == "test"#);
assert!(result.is_err(), "Unterminated double quote should fail");
let result = RawParser::parse_raw_expr(r#"ext == "some long string"#);
assert!(result.is_err(), "Unterminated double quote should fail");
}
#[test]
fn test_unterminated_single_quote() {
let result = RawParser::parse_raw_expr("contents ~= 'a");
assert!(result.is_err(), "Unterminated single quote should fail");
let result = RawParser::parse_raw_expr("name == 'test");
assert!(result.is_err(), "Unterminated single quote should fail");
let result = RawParser::parse_raw_expr("ext == 'foo bar baz");
assert!(result.is_err(), "Unterminated single quote should fail");
}
#[test]
fn test_stray_double_quote_after_value() {
let result = RawParser::parse_raw_expr(r#"contents ~= a""#);
assert!(result.is_err(), "Stray double quote should fail");
let result = RawParser::parse_raw_expr(r#"name == foo""#);
assert!(result.is_err(), "Stray double quote should fail");
let result = RawParser::parse_raw_expr(r#"ext == test.rs""#);
assert!(result.is_err(), "Stray double quote should fail");
}
#[test]
fn test_stray_single_quote_after_value() {
let result = RawParser::parse_raw_expr("contents ~= a'");
assert!(result.is_err(), "Stray single quote should fail");
let result = RawParser::parse_raw_expr("name == foo'");
assert!(result.is_err(), "Stray single quote should fail");
let result = RawParser::parse_raw_expr("ext == test.rs'");
assert!(result.is_err(), "Stray single quote should fail");
}
#[test]
fn test_quote_errors_in_complex_expressions() {
let result = RawParser::parse_raw_expr(r#"ext == rs AND name == "unterminated"#);
assert!(
result.is_err(),
"Unterminated quote in AND expression should fail"
);
let result = RawParser::parse_raw_expr(r#"ext == rs OR name == 'foo"#);
assert!(
result.is_err(),
"Unterminated quote in OR expression should fail"
);
let result = RawParser::parse_raw_expr(r#"ext == rs AND name == foo""#);
assert!(result.is_err(), "Stray quote in AND expression should fail");
let result = RawParser::parse_raw_expr(r#"ext == rs OR name == bar'"#);
assert!(result.is_err(), "Stray quote in OR expression should fail");
}
#[test]
fn test_lone_quote_as_value() {
let result = RawParser::parse_raw_expr(r#"contents ~= ""#);
assert!(result.is_err(), "Lone double quote should fail");
let result = RawParser::parse_raw_expr("contents ~= '");
assert!(result.is_err(), "Lone single quote should fail");
}
#[test]
fn test_properly_quoted_strings_still_work() {
let result = RawParser::parse_raw_expr(r#"name == "properly quoted""#);
assert!(result.is_ok(), "Properly quoted double quotes should work");
let expected = RawTestExpr::quoted_predicate("name", "==", "properly quoted");
assert_eq!(result.unwrap().to_test_expr(), expected);
let result = RawParser::parse_raw_expr("name == 'properly quoted'");
assert!(result.is_ok(), "Properly quoted single quotes should work");
let expected = RawTestExpr::quoted_predicate("name", "==", "properly quoted");
assert_eq!(result.unwrap().to_test_expr(), expected);
let result = RawParser::parse_raw_expr(r#"content ~= "test string with spaces""#);
assert!(result.is_ok(), "Quoted string with spaces should work");
let expected = RawTestExpr::quoted_predicate("content", "~=", "test string with spaces");
assert_eq!(result.unwrap().to_test_expr(), expected);
}
#[test]
fn test_edge_case_empty_inputs() {
let result = RawParser::parse_raw_expr("");
assert!(result.is_err(), "Empty string should fail");
let result = RawParser::parse_raw_expr(" ");
assert!(result.is_err(), "Whitespace only should fail");
let result = RawParser::parse_raw_expr("==");
assert!(result.is_err(), "Operator only should fail");
}
#[test]
fn test_malformed_sets() {
let result = RawParser::parse_raw_expr("name in [foo, bar");
assert!(result.is_err(), "Unclosed set should fail");
let result = RawParser::parse_raw_expr("name in foo, bar]");
assert!(result.is_err(), "Malformed syntax should fail");
let result = RawParser::parse_raw_expr("name in [foo, [bar]]");
assert!(
result.is_ok(),
"Simplified grammar allows nested brackets (typecheck will handle validity)"
);
let result = RawParser::parse_raw_expr("name in [foo, bar,]");
assert!(result.is_ok(), "Trailing comma is now allowed");
let result = RawParser::parse_raw_expr("name in [,,,]");
assert!(result.is_ok(), "Only commas parses as empty set");
}
#[test]
fn test_malformed_quotes() {
let result = RawParser::parse_raw_expr(r#"name == "foo'"#);
assert!(result.is_err(), "Mismatched quotes should fail");
let result = RawParser::parse_raw_expr(r#"name == 'foo""#);
assert!(result.is_err(), "Mismatched quotes should fail");
let result = RawParser::parse_raw_expr(r#"name == "foo\""#);
assert!(result.is_err(), "Escaped quote at end should fail");
let result = RawParser::parse_raw_expr(r#"name == ""foo""#);
assert!(result.is_err(), "Double quotes should fail");
let result = RawParser::parse_raw_expr(r#"name == fo"o"#);
assert!(result.is_err(), "Quote in middle should fail");
}
#[test]
fn test_boolean_logic_edge_cases() {
let result = RawParser::parse_raw_expr("name == foo AND");
assert!(result.is_err(), "Incomplete AND should fail");
let result = RawParser::parse_raw_expr("OR name == foo");
assert!(result.is_err(), "Leading OR should fail");
let result = RawParser::parse_raw_expr("NOT");
assert!(result.is_err(), "Standalone NOT should fail");
let result = RawParser::parse_raw_expr("name == foo AND OR bar == baz");
assert!(result.is_err(), "AND OR should fail");
let result = RawParser::parse_raw_expr("name == foo NOT AND bar == baz");
assert!(result.is_err(), "NOT AND should fail");
let result = RawParser::parse_raw_expr("NOT NOT name == foo");
let expected = RawTestExpr::not(RawTestExpr::not(RawTestExpr::string_predicate(
"name", "==", "foo",
)));
assert_eq!(result.unwrap().to_test_expr(), expected);
let result = RawParser::parse_raw_expr("NOT filename == NOT");
let expected = RawTestExpr::not(RawTestExpr::string_predicate("filename", "==", "NOT"));
assert_eq!(result.unwrap().to_test_expr(), expected);
}
#[test]
fn test_parentheses_edge_cases() {
let result = RawParser::parse_raw_expr("((name == foo)");
assert!(result.is_err(), "Unmatched opening parens should fail");
let result = RawParser::parse_raw_expr("(name == foo))");
assert!(result.is_err(), "Unmatched closing parens should fail");
let result = RawParser::parse_raw_expr("()");
assert!(result.is_err(), "Empty parentheses should fail");
let result = RawParser::parse_raw_expr("name (==) foo");
assert!(result.is_err(), "Parentheses around operators should fail");
let result = RawParser::parse_raw_expr("((name == foo))");
let expected = RawTestExpr::string_predicate("name", "==", "foo");
assert_eq!(result.unwrap().to_test_expr(), expected);
}