use super::*;
fn count(a: &[u8], b: &[u8]) -> usize {
let min_len = a.len().min(b.len());
unsafe { count_forward(a.as_ptr(), b.as_ptr(), a.as_ptr().add(min_len)) }
}
#[test]
fn empty_inputs_return_zero() {
let a: [u8; 0] = [];
let b: [u8; 0] = [];
let n = unsafe { count_forward(a.as_ptr(), b.as_ptr(), a.as_ptr()) };
assert_eq!(n, 0);
}
#[test]
fn full_match_inside_8_byte_chunk() {
let a = [1, 2, 3, 4, 5, 6, 7, 8];
let b = [1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(count(&a, &b), 8);
}
#[test]
fn diff_at_byte_3_in_first_chunk() {
let a = [1, 2, 3, 9, 5, 6, 7, 8];
let b = [1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(count(&a, &b), 3);
}
#[test]
fn match_spanning_two_chunks() {
let mut a = [0u8; 16];
let mut b = [0u8; 16];
for i in 0..16 {
a[i] = i as u8;
b[i] = i as u8;
}
a[13] = 99;
assert_eq!(count(&a, &b), 13);
}
#[test]
fn match_terminates_at_iend_within_tail() {
let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
let b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
assert_eq!(count(&a, &b), 11);
}
#[test]
fn diff_in_u32_tail() {
let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 99, 11, 12];
let b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
assert_eq!(count(&a, &b), 9);
}
#[test]
fn diff_in_u16_tail_after_u32_match() {
let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 99, 14];
let b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
assert_eq!(count(&a, &b), 12);
}
#[test]
fn diff_in_single_byte_tail() {
let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 99];
let b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
assert_eq!(count(&a, &b), 12);
}
#[test]
fn long_match_thousand_bytes() {
let a = [0x5Au8; 1024];
let b = [0x5Au8; 1024];
assert_eq!(count(&a, &b), 1024);
}
#[test]
fn no_match_first_byte() {
let a = [0u8, 1, 2, 3, 4, 5, 6, 7];
let b = [9u8, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(count(&a, &b), 0);
}
#[test]
fn dict_2segment_within_dict_only() {
let dict = [10u8, 20, 30, 40];
let inp = [30u8, 40, 99];
assert_eq!(count_forward_dict_2segment(&dict, 2, &inp, 0, 0), 2);
}
#[test]
fn dict_2segment_crosses_boundary_into_input() {
let dict = [1u8, 2, 3];
let inp = [1u8, 2, 3, 1, 2, 3, 9]; assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 3, 0), 3);
}
#[test]
fn dict_2segment_continues_word_at_a_time_past_boundary() {
let dict = [1u8, 2, 3];
let inp = [1u8, 2, 3, 1, 2, 3, 1, 2]; assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 3, 0), 5);
}
#[test]
fn dict_2segment_stops_at_input_end() {
let dict = [7u8, 7];
let inp = [7u8, 7, 7, 7]; assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 2, 0), 2);
}
#[test]
fn dict_2segment_resumes_past_an_established_prefix() {
let dict = [1u8, 2, 3, 4, 5, 6];
let inp = [1u8, 2, 3, 4, 5, 6, 9];
for known in [0usize, 4] {
assert_eq!(
count_forward_dict_2segment(&dict, 0, &inp, 0, known),
6,
"established {known} bytes",
);
}
let dict = [1u8, 2, 3, 4];
let inp = [1u8, 2, 3, 4, 1, 2, 3, 4, 1, 2, 7];
assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 4, 0), 6);
assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 4, 4), 6);
let dict = [5u8, 5, 5, 5];
let inp = [5u8, 5, 5, 5];
assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 0, 4), 4);
let dict = [5u8, 5, 5, 5, 5, 5];
let inp = [5u8, 5, 5, 5];
assert_eq!(count_forward_dict_2segment(&dict, 0, &inp, 0, 4), 4);
}
#[test]
#[should_panic(expected = "cand")]
fn dict_2segment_rejects_a_candidate_outside_the_dict() {
let dict = [1u8, 2, 3];
let inp = [1u8, 2, 3];
let _ = count_forward_dict_2segment(&dict, 3, &inp, 0, 0);
}
#[test]
#[should_panic(expected = "cur")]
fn dict_2segment_rejects_a_cursor_past_the_input() {
let dict = [1u8, 2, 3];
let inp = [1u8, 2, 3];
let _ = count_forward_dict_2segment(&dict, 0, &inp, 4, 0);
}
#[test]
#[should_panic(expected = "count_forward_dict_2segment requires")]
fn dict_2segment_rejects_a_known_prefix_that_would_wrap() {
let dict = [1u8, 2, 3];
let inp = [1u8];
let _ = count_forward_dict_2segment(&dict, 0, &inp, 1, usize::MAX);
}