use super::{Permuter, TreePermutation};
#[test]
fn test_empty_permuter() {
let p: Permuter<15> = Permuter::empty();
assert_eq!(p.size(), 0);
assert_eq!(p.back(), 0);
assert_eq!(p.value(), 0x0123_4567_89AB_CDE0);
}
#[test]
fn test_default_is_empty() {
let p: Permuter<15> = Permuter::default();
assert_eq!(p.size(), 0);
assert_eq!(p.value(), Permuter::<15>::empty().value());
}
#[test]
fn test_make_sorted_full() {
let p: Permuter<15> = Permuter::make_sorted(15);
assert_eq!(p.size(), 15);
for i in 0..15 {
assert_eq!(p.get(i), i, "position {i} should map to slot {i}");
}
assert_eq!(p.value(), 0xEDCB_A987_6543_210F);
}
#[test]
fn test_make_sorted_partial() {
let p: Permuter<15> = Permuter::make_sorted(3);
assert_eq!(p.size(), 3);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
assert_eq!(p.get(2), 2);
assert_eq!(p.back(), 3);
}
#[test]
fn test_make_sorted_zero() {
let p: Permuter<15> = Permuter::make_sorted(0);
assert_eq!(p.size(), 0);
assert_eq!(p.back(), 0);
}
#[test]
fn test_make_sorted_one() {
let p: Permuter<15> = Permuter::make_sorted(1);
assert_eq!(p.size(), 1);
assert_eq!(p.get(0), 0);
assert_eq!(p.back(), 1);
}
#[test]
fn test_insert_from_back() {
let mut p: Permuter<15> = Permuter::empty();
assert_eq!(p.size(), 0);
let slot0: usize = p.insert_from_back(0);
assert_eq!(slot0, 0); assert_eq!(p.size(), 1);
assert_eq!(p.get(0), 0);
let slot1: usize = p.insert_from_back(0);
assert_eq!(slot1, 1); assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 1); assert_eq!(p.get(1), 0);
let slot2: usize = p.insert_from_back(1);
assert_eq!(slot2, 2);
assert_eq!(p.size(), 3);
assert_eq!(p.get(0), 1);
assert_eq!(p.get(1), 2); assert_eq!(p.get(2), 0); }
#[test]
fn test_insert_from_back_at_end() {
let mut p: Permuter<15> = Permuter::empty();
let slot0: usize = p.insert_from_back(0);
let slot1: usize = p.insert_from_back(1); let slot2: usize = p.insert_from_back(2);
assert_eq!(p.size(), 3);
assert_eq!(p.get(0), slot0);
assert_eq!(p.get(1), slot1);
assert_eq!(p.get(2), slot2);
}
#[test]
fn test_insert_fill_to_capacity() {
let mut p: Permuter<15> = Permuter::empty();
for i in 0..15 {
let slot = p.insert_from_back(i);
assert_eq!(slot, i);
}
assert_eq!(p.size(), 15);
for i in 0..15 {
assert_eq!(p.get(i), i);
}
}
#[test]
fn test_remove_to_back() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
assert_eq!(p.size(), 5);
p.remove_to_back(2);
assert_eq!(p.size(), 4);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
assert_eq!(p.get(2), 3);
assert_eq!(p.get(3), 4);
assert_eq!(p.back(), 2);
}
#[test]
fn test_remove_to_back_first() {
let mut p: Permuter<15> = Permuter::make_sorted(3);
p.remove_to_back(0);
assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 1);
assert_eq!(p.get(1), 2);
assert_eq!(p.back(), 0);
}
#[test]
fn test_remove_to_back_last() {
let mut p: Permuter<15> = Permuter::make_sorted(3);
p.remove_to_back(2);
assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
assert_eq!(p.back(), 2);
}
#[test]
fn test_remove_middle() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
p.remove(2);
assert_eq!(p.size(), 4);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
assert_eq!(p.get(2), 3);
assert_eq!(p.get(3), 4);
assert_eq!(p.get(4), 2);
}
#[test]
fn test_remove_first() {
let mut p: Permuter<15> = Permuter::make_sorted(3);
p.remove(0);
assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 1);
assert_eq!(p.get(1), 2);
assert_eq!(p.get(2), 0); }
#[test]
fn test_remove_last() {
let mut p: Permuter<15> = Permuter::make_sorted(3);
p.remove(2);
assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
assert_eq!(p.get(2), 2);
}
#[test]
fn test_exchange_basic() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
p.exchange(1, 3);
assert_eq!(p.size(), 5); assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 3); assert_eq!(p.get(2), 2);
assert_eq!(p.get(3), 1); assert_eq!(p.get(4), 4);
}
#[test]
fn test_exchange_same() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
let original: u64 = p.value();
p.exchange(2, 2);
assert_eq!(p.value(), original);
}
#[test]
fn test_exchange_adjacent() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
p.exchange(2, 3);
assert_eq!(p.get(2), 3);
assert_eq!(p.get(3), 2);
}
#[test]
fn test_exchange_first_last() {
let mut p: Permuter<15> = Permuter::make_sorted(15);
p.exchange(0, 14);
assert_eq!(p.get(0), 14);
assert_eq!(p.get(14), 0);
}
#[test]
fn test_rotate_basic() {
let mut p: Permuter<7> = Permuter::make_sorted(7);
p.rotate(2, 4);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
}
#[test]
fn test_rotate_no_op() {
let mut p: Permuter<15> = Permuter::make_sorted(5);
let original: u64 = p.value();
p.rotate(2, 2);
assert_eq!(p.value(), original);
p.rotate(15, 15);
assert_eq!(p.value(), original);
}
#[test]
fn test_insert_remove_roundtrip() {
let mut p: Permuter<15> = Permuter::empty();
for i in 0..5 {
let _ = p.insert_from_back(i);
}
assert_eq!(p.size(), 5);
for _ in 0..5 {
p.remove_to_back(0);
}
assert_eq!(p.size(), 0);
p.debug_assert_valid();
}
#[test]
fn test_insert_remove_roundtrip_alt() {
let mut p: Permuter<15> = Permuter::empty();
for i in 0..5 {
let _ = p.insert_from_back(i);
}
for _ in 0..5 {
p.remove(0);
}
assert_eq!(p.size(), 0);
p.debug_assert_valid();
}
#[test]
fn test_compact_permuter() {
let mut p: Permuter<7> = Permuter::empty();
assert_eq!(p.size(), 0);
assert_eq!(p.back(), 0);
let slot: usize = p.insert_from_back(0);
assert_eq!(slot, 0);
assert_eq!(p.size(), 1);
let sorted: Permuter<7> = Permuter::make_sorted(7);
assert_eq!(sorted.size(), 7);
for i in 0..7 {
assert_eq!(sorted.get(i), i);
}
}
#[test]
fn test_width_3_permuter() {
let mut p: Permuter<3> = Permuter::empty();
assert_eq!(p.size(), 0);
let _ = p.insert_from_back(0);
let _ = p.insert_from_back(0);
let _ = p.insert_from_back(0);
assert_eq!(p.size(), 3);
p.debug_assert_valid();
}
#[test]
fn test_set_size() {
let mut p: Permuter<15> = Permuter::make_sorted(10);
assert_eq!(p.size(), 10);
p.set_size(5);
assert_eq!(p.size(), 5);
p.set_size(0);
assert_eq!(p.size(), 0);
}
#[test]
fn test_value_accessor() {
let p: Permuter<15> = Permuter::empty();
let v: u64 = p.value();
let p2: Permuter<15> = Permuter::empty();
assert_eq!(p.value(), p2.value());
assert_eq!(v, 0x0123_4567_89AB_CDE0);
}
#[test]
fn test_clone_and_eq() {
let p1: Permuter<15> = Permuter::make_sorted(5);
let p2: Permuter = p1;
assert_eq!(p1, p2);
assert_eq!(p1.value(), p2.value());
}
#[test]
fn test_insert_from_back_immutable_basic() {
let p: Permuter<15> = Permuter::empty();
assert_eq!(p.size(), 0);
let (new_p, slot) = p.insert_from_back_immutable(0);
assert_eq!(p.size(), 0);
assert_eq!(new_p.size(), 1);
assert_eq!(slot, 0);
assert_eq!(new_p.get(0), 0);
}
#[test]
fn test_insert_from_back_immutable_matches_mutable() {
let original: Permuter<15> = Permuter::make_sorted(5);
let mut mutable = original;
let mutable_slot = mutable.insert_from_back(2);
let (immutable, immutable_slot) = original.insert_from_back_immutable(2);
assert_eq!(mutable_slot, immutable_slot);
assert_eq!(mutable.value(), immutable.value());
assert_eq!(mutable.size(), immutable.size());
for i in 0..mutable.size() {
assert_eq!(mutable.get(i), immutable.get(i));
}
}
#[test]
fn test_insert_from_back_immutable_chain() {
let p0: Permuter<15> = Permuter::empty();
let (p1, slot0) = p0.insert_from_back_immutable(0);
let (p2, slot1) = p1.insert_from_back_immutable(0);
let (p3, slot2) = p2.insert_from_back_immutable(1);
assert_eq!(p0.size(), 0);
assert_eq!(p1.size(), 1);
assert_eq!(p2.size(), 2);
assert_eq!(p3.size(), 3);
assert_eq!(slot0, 0);
assert_eq!(slot1, 1);
assert_eq!(slot2, 2);
assert_eq!(p3.get(0), 1); assert_eq!(p3.get(1), 2); assert_eq!(p3.get(2), 0); }
#[test]
fn test_insert_from_back_immutable_for_cas() {
let current: Permuter<15> = Permuter::make_sorted(3);
let current_value = current.value();
let (new_perm, slot) = current.insert_from_back_immutable(1);
assert_eq!(current.value(), current_value);
assert_ne!(new_perm.value(), current_value);
assert_eq!(slot, 3); assert_eq!(new_perm.size(), 4);
}
#[test]
fn test_make_sorted_via_trait() {
fn check_trait<P: TreePermutation>() {
let p = P::make_sorted(2);
assert_eq!(p.size(), 2);
assert_eq!(p.get(0), 0);
assert_eq!(p.get(1), 1);
}
check_trait::<Permuter<15>>();
}