//! Round-trip property tests.
//!
//! Round-trip is the natural invariant: decompressing a compressed string yields
//! the input. These cover inputs the fixed vectors miss, including arbitrary BMP
//! strings and highly repetitive runs that stress the match path.

use proptest::prelude::*;

/// Build a `String` from UTF-16 units, mapping lone surrogates to U+FFFD so the
/// `&str` API can carry the value losslessly through the round-trip.
fn units_to_string(units: &[u16]) -> String {
    String::from_utf16_lossy(units)
}

proptest! {
    #[test]
    fn round_trip_arbitrary_str(s in ".*") {
        prop_assert_eq!(lzbase62::decompress(&lzbase62::compress(&s)), s);
    }

    #[test]
    fn round_trip_bmp_units(units in proptest::collection::vec(0u16..=0xFFFF, 0..512)) {
        let input = units_to_string(&units);
        prop_assert_eq!(lzbase62::decompress(&lzbase62::compress(&input)), input);
    }

    #[test]
    fn round_trip_repetitive(
        units in proptest::collection::vec(
            prop_oneof![Just(b'a' as u16), Just(0x3042u16)],
            0..5000,
        )
    ) {
        let input = units_to_string(&units);
        prop_assert_eq!(lzbase62::decompress(&lzbase62::compress(&input)), input);
    }
}
