use pattern_core::{Combinable, Pattern};
#[test]
fn test_combine_atomic_patterns() {
let p1 = Pattern::point("hello".to_string());
let p2 = Pattern::point(" world".to_string());
let result = p1.combine(p2);
assert_eq!(result.value(), "hello world");
assert_eq!(result.length(), 0); assert!(result.is_atomic());
}
#[test]
fn test_combine_atomic_patterns_empty_strings() {
let p1 = Pattern::point("".to_string());
let p2 = Pattern::point("test".to_string());
let result = p1.combine(p2);
assert_eq!(result.value(), "test");
assert!(result.is_atomic());
}
#[test]
fn test_combine_patterns_with_elements() {
let p1 = Pattern::pattern(
"a".to_string(),
vec![
Pattern::point("b".to_string()),
Pattern::point("c".to_string()),
],
);
let p2 = Pattern::pattern("d".to_string(), vec![Pattern::point("e".to_string())]);
let result = p1.combine(p2);
assert_eq!(result.value(), "ad");
assert_eq!(result.length(), 3);
let values: Vec<_> = result.elements().iter().map(|p| p.value()).collect();
assert_eq!(values, vec!["b", "c", "e"]);
}
#[test]
fn test_combine_patterns_multiple_elements() {
let p1 = Pattern::pattern(
"x".to_string(),
vec![
Pattern::point("1".to_string()),
Pattern::point("2".to_string()),
Pattern::point("3".to_string()),
],
);
let p2 = Pattern::pattern(
"y".to_string(),
vec![
Pattern::point("4".to_string()),
Pattern::point("5".to_string()),
],
);
let result = p1.combine(p2);
assert_eq!(result.value(), "xy");
assert_eq!(result.length(), 5); }
#[test]
fn test_combine_atomic_with_pattern() {
let p1 = Pattern::point("atomic".to_string());
let p2 = Pattern::pattern(
"parent".to_string(),
vec![Pattern::point("child".to_string())],
);
let result = p1.combine(p2);
assert_eq!(result.value(), "atomicparent");
assert_eq!(result.length(), 1); }
#[test]
fn test_combine_pattern_with_atomic() {
let p1 = Pattern::pattern(
"parent".to_string(),
vec![Pattern::point("child".to_string())],
);
let p2 = Pattern::point("atomic".to_string());
let result = p1.combine(p2);
assert_eq!(result.value(), "parentatomic");
assert_eq!(result.length(), 1); }
#[test]
fn test_combine_pattern_with_itself() {
let p = Pattern::pattern(
"self".to_string(),
vec![
Pattern::point("a".to_string()),
Pattern::point("b".to_string()),
],
);
let result = p.clone().combine(p.clone());
assert_eq!(result.value(), "selfself");
assert_eq!(result.length(), 4);
assert!(result.elements().len() == 4);
}
#[test]
fn test_combine_deep_nesting() {
fn create_deep_pattern(depth: usize, prefix: &str) -> Pattern<String> {
if depth == 0 {
Pattern::point(format!("{}leaf", prefix))
} else {
Pattern::pattern(
format!("{}level{}", prefix, depth),
vec![create_deep_pattern(depth - 1, prefix)],
)
}
}
let p1 = create_deep_pattern(100, "a");
let p2 = create_deep_pattern(100, "b");
let result = p1.combine(p2);
assert_eq!(result.length(), 2); assert_eq!(result.depth(), 100);
assert!(result.value().starts_with("alevel100"));
assert!(result.value().ends_with("blevel100"));
}
#[test]
fn test_combine_wide_patterns() {
let elements1: Vec<_> = (0..1000)
.map(|i| Pattern::point(format!("a{}", i)))
.collect();
let elements2: Vec<_> = (0..1000)
.map(|i| Pattern::point(format!("b{}", i)))
.collect();
let p1 = Pattern::pattern("left".to_string(), elements1);
let p2 = Pattern::pattern("right".to_string(), elements2);
let result = p1.combine(p2);
assert_eq!(result.value(), "leftright");
assert_eq!(result.length(), 2000);
assert_eq!(result.elements()[0].value(), "a0");
assert_eq!(result.elements()[999].value(), "a999");
assert_eq!(result.elements()[1000].value(), "b0");
assert_eq!(result.elements()[1999].value(), "b999");
}
#[test]
fn test_combine_very_wide_patterns() {
let elements1: Vec<_> = (0..5000).map(|i| Pattern::point(i.to_string())).collect();
let elements2: Vec<_> = (5000..10000)
.map(|i| Pattern::point(i.to_string()))
.collect();
let p1 = Pattern::pattern("x".to_string(), elements1);
let p2 = Pattern::pattern("y".to_string(), elements2);
let result = p1.combine(p2);
assert_eq!(result.value(), "xy");
assert_eq!(result.length(), 10000);
}
#[test]
fn test_combine_empty_elements() {
let p1 = Pattern::pattern("a".to_string(), vec![]);
let p2 = Pattern::pattern("b".to_string(), vec![]);
let result = p1.combine(p2);
assert_eq!(result.value(), "ab");
assert_eq!(result.length(), 0);
}
#[test]
fn test_combine_nested_structures() {
let p1 = Pattern::pattern(
"root1".to_string(),
vec![Pattern::pattern(
"child1".to_string(),
vec![Pattern::point("leaf1".to_string())],
)],
);
let p2 = Pattern::pattern(
"root2".to_string(),
vec![Pattern::pattern(
"child2".to_string(),
vec![Pattern::point("leaf2".to_string())],
)],
);
let result = p1.combine(p2);
assert_eq!(result.value(), "root1root2");
assert_eq!(result.length(), 2);
assert_eq!(result.elements()[0].value(), "child1");
assert_eq!(result.elements()[1].value(), "child2");
}