use scrolling_window_pattern_matcher::{ElementSettings, ExtractorAction, Matcher, PatternElement};
#[derive(Debug, Clone)]
struct TestContext {
name: String,
captured_values: Vec<i32>,
}
#[test]
fn test_exact_value_match() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(42));
assert_eq!(matcher.process_item(42).unwrap(), Some(42));
assert_eq!(matcher.process_item(43).unwrap(), None);
}
#[test]
fn test_predicate_match() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::predicate(|x| *x % 2 == 0));
assert_eq!(matcher.process_item(2).unwrap(), Some(2));
assert_eq!(matcher.process_item(4).unwrap(), Some(4));
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), None);
}
#[test]
fn test_range_match() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::range(10, 20));
assert_eq!(matcher.process_item(10).unwrap(), Some(10));
assert_eq!(matcher.process_item(15).unwrap(), Some(15));
assert_eq!(matcher.process_item(20).unwrap(), Some(20));
assert_eq!(matcher.process_item(9).unwrap(), None);
assert_eq!(matcher.process_item(21).unwrap(), None);
}
#[test]
fn test_sequence_pattern() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(1));
matcher.add_pattern(PatternElement::exact(2));
matcher.add_pattern(PatternElement::exact(3));
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(2).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), Some(3));
matcher.reset();
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(2).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), Some(3));
}
#[test]
fn test_pattern_mismatch_reset() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(1));
matcher.add_pattern(PatternElement::exact(2));
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), None);
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(2).unwrap(), Some(2)); }
#[test]
fn test_optional_elements() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(1));
let mut settings = ElementSettings::default();
settings.optional = true;
matcher.add_pattern(PatternElement::exact_with_settings(2, settings));
matcher.add_pattern(PatternElement::exact(3));
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(2).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), Some(3));
matcher.reset();
assert_eq!(matcher.process_item(1).unwrap(), None);
assert_eq!(matcher.process_item(3).unwrap(), Some(3));
}
#[test]
fn test_extractors() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.register_extractor(1, |state| {
Ok(ExtractorAction::Extract(state.current_item * 2))
});
let mut settings = ElementSettings::default();
settings.extractor_id = Some(1);
matcher.add_pattern(PatternElement::exact_with_settings(10, settings));
assert_eq!(matcher.process_item(10).unwrap(), Some(20));
}
#[test]
fn test_context_usage() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
let context = TestContext {
name: "test_context".to_string(),
captured_values: vec![],
};
matcher.set_context(context);
matcher.register_extractor(1, |state| {
Ok(ExtractorAction::Extract(state.current_item + 100))
});
let mut settings = ElementSettings::default();
settings.extractor_id = Some(1);
matcher.add_pattern(PatternElement::exact_with_settings(5, settings));
assert_eq!(matcher.process_item(5).unwrap(), Some(105));
}
#[test]
fn test_process_multiple_items() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(1));
matcher.add_pattern(PatternElement::exact(2));
let items = vec![1, 2, 3, 1, 2, 4, 5];
let results = matcher.process_items(items).unwrap();
assert_eq!(results, vec![2, 2]);
}
#[test]
fn test_string_patterns() {
let mut matcher = Matcher::<String, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact("hello".to_string()));
matcher.add_pattern(PatternElement::exact("world".to_string()));
assert_eq!(matcher.process_item("hello".to_string()).unwrap(), None);
assert_eq!(
matcher.process_item("world".to_string()).unwrap(),
Some("world".to_string())
);
}
#[test]
fn test_complex_mixed_patterns() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.add_pattern(PatternElement::exact(1));
matcher.add_pattern(PatternElement::predicate(|x| *x % 2 == 0));
matcher.add_pattern(PatternElement::range(10, 20));
assert_eq!(matcher.process_item(1).unwrap(), None); assert_eq!(matcher.process_item(8).unwrap(), None); assert_eq!(matcher.process_item(15).unwrap(), Some(15)); }
#[test]
fn test_window_size_constructor() {
let patterns = vec![PatternElement::exact(1), PatternElement::exact(2)];
let matcher = Matcher::<i32, TestContext>::with_patterns(patterns, 20);
assert_eq!(matcher.window_size(), 20);
assert_eq!(matcher.pattern_count(), 2);
}
#[test]
fn test_no_patterns_error() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
let result = matcher.process_item(1);
assert!(result.is_err());
}
#[test]
fn test_extractor_restart_action() {
let mut matcher = Matcher::<i32, TestContext>::new(10);
matcher.register_extractor(1, |state| {
if state.current_item == 5 {
Ok(ExtractorAction::Restart)
} else {
Ok(ExtractorAction::Continue)
}
});
let mut settings = ElementSettings::default();
settings.extractor_id = Some(1);
matcher.add_pattern(PatternElement::exact_with_settings(5, settings));
assert_eq!(matcher.process_item(5).unwrap(), None);
assert_eq!(matcher.current_position(), 0); }