#[macro_export]
macro_rules! assert_contains_in_order {
($actual: expr, $expected: expr) => {
let actual = $actual.clone().into_iter();
let expected = $expected.clone().into_iter();
assert!(
actual.len() >= expected.len(),
"Expected to find each of {:?} in order in {:?}",
expected.as_slice(),
actual.as_slice()
);
let mut cur_pos = 0;
for e in expected.clone() {
if let Some(found) = actual.as_slice()[cur_pos..].iter().position(|it| it == &e) {
cur_pos = found.clone();
} else {
panic!(
"Expected to find each of {:?} in order in {:?} - Missing {:?}",
expected.as_slice(), actual.as_slice(), e
)
}
}
};
}
#[cfg(test)]
mod tests {
#[test]
fn should_succeed_if_both_sides_empty() {
assert_contains_in_order!(Vec::<bool>::new(), Vec::<bool>::new());
}
#[test]
fn should_succeed_if_same_elements_in_same_order() {
assert_contains_in_order!(vec![1, 2, 3], vec![1, 2, 3]);
}
#[test]
fn should_succeed_if_same_duplicate_elements_in_same_order() {
assert_contains_in_order!(vec![2, 1, 2], vec![2, 1, 2]);
}
#[test]
fn should_succeed_if_actual_has_more_elememts_but_in_same_order() {
assert_contains_in_order!(vec![1, 2, 3], vec![1, 3]);
}
#[test]
fn should_succeed_if_actual_has_duplicate_elememts_but_in_same_order() {
assert_contains_in_order!(vec![1, 3, 3], vec![1, 3]);
}
#[test]
#[should_panic(expected = r"Expected to find each of [1, 2, 3] in order in [1, 2]")]
fn should_fail_if_actual_has_fewer_elememts_even_in_same_order() {
assert_contains_in_order!(vec![1, 2], vec![1, 2, 3]);
}
#[test]
#[should_panic(expected = r"Expected to find each of [2] in order in [1] - Missing 2")]
fn should_fail_if_elements_are_not_the_same() {
assert_contains_in_order!(vec![1], vec![2]);
}
#[test]
#[should_panic(expected = r"Expected to find each of [2, 1] in order in [1, 2] - Missing 1")]
fn should_fail_if_same_elements_but_different_order() {
assert_contains_in_order!(vec![1, 2], vec![2, 1]);
}
}