use pattern_core::Pattern;
#[test]
fn values_atomic_pattern() {
let pattern = Pattern::point("test");
let values = pattern.values();
assert_eq!(values.len(), 1);
assert_eq!(values, vec![&"test"]);
}
#[test]
fn values_atomic_pattern_integer() {
let pattern = Pattern::point(42);
let values = pattern.values();
assert_eq!(values.len(), 1);
assert_eq!(values, vec![&42]);
}
#[test]
fn values_flat_pattern_preserves_order() {
let pattern = Pattern::pattern(
"first",
vec![Pattern::point("second"), Pattern::point("third")],
);
let values = pattern.values();
assert_eq!(values.len(), 3);
assert_eq!(values, vec![&"first", &"second", &"third"]);
}
#[test]
fn values_flat_pattern_multiple_elements() {
let pattern = Pattern::pattern(
1,
vec![
Pattern::point(2),
Pattern::point(3),
Pattern::point(4),
Pattern::point(5),
],
);
let values = pattern.values();
assert_eq!(values.len(), 5);
assert_eq!(values, vec![&1, &2, &3, &4, &5]);
}
#[test]
fn values_flat_pattern_root_first() {
let pattern = Pattern::pattern("root", vec![Pattern::point("a"), Pattern::point("b")]);
let values = pattern.values();
assert_eq!(values[0], &"root");
assert_eq!(values[1], &"a");
assert_eq!(values[2], &"b");
}
#[test]
fn values_nested_pattern_depth_first_order() {
let pattern = Pattern::pattern(
"A",
vec![
Pattern::point("B"),
Pattern::pattern("C", vec![Pattern::point("D")]),
],
);
let values = pattern.values();
assert_eq!(values.len(), 4);
assert_eq!(values, vec![&"A", &"B", &"C", &"D"]);
}
#[test]
fn values_deeply_nested_pattern() {
let level3 = Pattern::point(4);
let level2 = Pattern::pattern(3, vec![level3]);
let level1 = Pattern::pattern(2, vec![level2]);
let pattern = Pattern::pattern(1, vec![level1]);
let values = pattern.values();
assert_eq!(values.len(), 4);
assert_eq!(values, vec![&1, &2, &3, &4]);
}
#[test]
fn values_nested_pattern_multiple_branches() {
let branch1 = Pattern::pattern(2, vec![Pattern::point(3)]);
let branch2 = Pattern::pattern(4, vec![Pattern::point(5)]);
let pattern = Pattern::pattern(1, vec![branch1, branch2]);
let values = pattern.values();
assert_eq!(values.len(), 5);
assert_eq!(values, vec![&1, &2, &3, &4, &5]);
}
#[test]
fn values_length_equals_size_atomic() {
let pattern = Pattern::point(42);
let values = pattern.values();
assert_eq!(values.len(), pattern.size());
}
#[test]
fn values_length_equals_size_flat() {
let pattern = Pattern::pattern(
"root",
vec![
Pattern::point("a"),
Pattern::point("b"),
Pattern::point("c"),
],
);
let values = pattern.values();
assert_eq!(values.len(), pattern.size());
assert_eq!(values.len(), 4);
}
#[test]
fn values_length_equals_size_nested() {
let inner = Pattern::pattern(2, vec![Pattern::point(3)]);
let pattern = Pattern::pattern(1, vec![inner, Pattern::point(4)]);
let values = pattern.values();
assert_eq!(values.len(), pattern.size());
assert_eq!(values.len(), 4);
}
#[test]
fn values_length_equals_size_complex() {
let level4 = Pattern::point(5);
let level3 = Pattern::pattern(4, vec![level4]);
let level2 = Pattern::pattern(3, vec![level3]);
let level1 = Pattern::pattern(2, vec![level2]);
let pattern = Pattern::pattern(1, vec![level1, Pattern::point(6)]);
let values = pattern.values();
assert_eq!(values.len(), pattern.size());
assert_eq!(values.len(), 6);
}
#[test]
fn values_integrates_with_iterator_sum() {
let pattern = Pattern::pattern(
1,
vec![Pattern::point(2), Pattern::point(3), Pattern::point(4)],
);
let sum: i32 = pattern.values().iter().map(|&&v| v).sum();
assert_eq!(sum, 10); }
#[test]
fn values_integrates_with_iterator_filter() {
let pattern = Pattern::pattern(
1,
vec![
Pattern::point(2),
Pattern::point(3),
Pattern::point(4),
Pattern::point(5),
],
);
let evens: Vec<i32> = pattern
.values()
.iter()
.filter(|&&v| v % 2 == 0)
.map(|&&v| v)
.collect();
assert_eq!(evens, vec![2, 4]);
}
#[test]
fn values_integrates_with_iterator_all() {
let pattern = Pattern::pattern(
1,
vec![Pattern::point(2), Pattern::point(3), Pattern::point(4)],
);
let all_positive = pattern.values().iter().all(|&&v| v > 0);
assert!(all_positive);
let all_large = pattern.values().iter().all(|&&v| v > 10);
assert!(!all_large);
}
#[test]
fn values_integrates_with_iterator_any() {
let pattern = Pattern::pattern(
1,
vec![Pattern::point(2), Pattern::point(3), Pattern::point(4)],
);
let any_large = pattern.values().iter().any(|&&v| v > 3);
assert!(any_large);
let any_negative = pattern.values().iter().any(|&&v| v < 0);
assert!(!any_negative);
}
#[test]
fn values_integrates_with_iterator_find() {
let pattern = Pattern::pattern(
1,
vec![Pattern::point(2), Pattern::point(3), Pattern::point(4)],
);
let values = pattern.values();
let found = values.iter().find(|&&v| *v == 3);
assert_eq!(found, Some(&&3));
let values2 = pattern.values();
let not_found = values2.iter().find(|&&v| *v == 10);
assert_eq!(not_found, None);
}
#[test]
fn values_integrates_with_iterator_map() {
let pattern = Pattern::pattern("hello", vec![Pattern::point("world"), Pattern::point("!")]);
let lengths: Vec<usize> = pattern.values().iter().map(|s| s.len()).collect();
assert_eq!(lengths, vec![5, 5, 1]);
}
#[test]
fn values_integrates_with_iterator_fold() {
let pattern = Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]);
let product = pattern.values().iter().fold(1, |acc, &&v| acc * v);
assert_eq!(product, 24); }
#[test]
fn values_can_be_called_multiple_times() {
let pattern = Pattern::pattern(1, vec![Pattern::point(2), Pattern::point(3)]);
let values1 = pattern.values();
let values2 = pattern.values();
assert_eq!(values1, values2);
}
#[test]
fn values_returns_references_not_clones() {
let pattern = Pattern::pattern("test", vec![Pattern::point("data")]);
let values = pattern.values();
assert_eq!(*values[0], "test");
assert_eq!(*values[1], "data");
}
#[test]
fn values_works_with_custom_types() {
#[derive(Clone, PartialEq, Debug)]
struct Item {
id: u32,
name: String,
}
let item1 = Item {
id: 1,
name: "first".to_string(),
};
let item2 = Item {
id: 2,
name: "second".to_string(),
};
let pattern = Pattern::pattern(item1.clone(), vec![Pattern::point(item2.clone())]);
let values = pattern.values();
assert_eq!(values.len(), 2);
assert_eq!(values[0].id, 1);
assert_eq!(values[1].id, 2);
}