#[allow(unused_imports)]
use crate::imp::chunker::{chunk_slice, chunk_stream, Chunk};
use proptest::prelude::*;
fn small_cfg() -> crate::imp::core::ChunkerConfig {
crate::imp::core::ChunkerConfig {
min_size: 64,
target_size: 256,
max_size: 1024,
mask: 0xFF,
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(256))]
#[test]
fn determinism_same_input_same_chunks(data in proptest::collection::vec(any::<u8>(), 0..50_000)) {
let cfg = small_cfg();
let a = chunk_slice(&data, &cfg);
let b = chunk_slice(&data, &cfg);
prop_assert_eq!(a, b);
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(256))]
#[test]
fn reconstruct_offsets_and_bounds(data in proptest::collection::vec(any::<u8>(), 0..50_000)) {
let cfg = small_cfg();
let chunks = chunk_slice(&data, &cfg);
let mut rebuilt = Vec::with_capacity(data.len());
for c in &chunks {
rebuilt.extend_from_slice(&c.data);
}
prop_assert_eq!(&rebuilt, &data);
let mut off = 0usize;
for c in &chunks {
prop_assert_eq!(c.offset, off);
off += c.data.len();
}
if chunks.len() > 1 {
for c in &chunks[..chunks.len() - 1] {
prop_assert!(c.len() >= cfg.min_size);
prop_assert!(c.len() <= cfg.max_size);
}
}
if let Some(last) = chunks.last() {
prop_assert!(!last.is_empty());
prop_assert!(last.len() <= cfg.max_size);
}
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(64))]
#[test]
fn front_insert_locality_is_consistent(
prefix in proptest::collection::vec(any::<u8>(), 1..2000),
body in proptest::collection::vec(any::<u8>(), 5_000..40_000),
) {
let cfg = small_cfg();
let mut modified = prefix.clone();
modified.extend_from_slice(&body);
let oc = chunk_slice(&body, &cfg);
let mc = chunk_slice(&modified, &cfg);
let oj: Vec<u8> = oc.iter().flat_map(|c| c.data.clone()).collect();
prop_assert_eq!(&oj, &body);
let mj: Vec<u8> = mc.iter().flat_map(|c| c.data.clone()).collect();
prop_assert_eq!(&mj, &modified);
let mut shared = 0usize;
while shared < oc.len()
&& shared < mc.len()
&& oc[oc.len() - 1 - shared].hash == mc[mc.len() - 1 - shared].hash
{
shared += 1;
}
prop_assert!(shared <= oc.len().min(mc.len()));
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(128))]
#[test]
fn stream_equals_slice_property(data in proptest::collection::vec(any::<u8>(), 0..30_000)) {
let cfg = small_cfg();
let want = chunk_slice(&data, &cfg);
let got = chunk_stream(std::io::Cursor::new(&data), &cfg).unwrap();
prop_assert_eq!(got, want);
}
}