//! Run-length and index-rollover boundaries.
//!
//! The `bits` values straddle the magic constants in the match encoder
//! (`BUFFER_MAX`, `WINDOW_BUFFER_MAX`, two-digit distance and length encoding).
//! They are the sharpest correctness boundaries for the offset and length math.

mod common;

use common::{compress_streamed, decompress_streamed};

/// The run lengths to test: around `BUFFER_MAX` and around 60 * 61.
fn bits() -> [usize; 6] {
    let max = 60 * (60 + 1); // 3660
    [59, 60, 61, max - 1, max, max + 1]
}

/// Six ASCII runs of `'a'`.
fn sample_critical_values() -> Vec<String> {
    bits().iter().map(|&b| "a".repeat(b)).collect()
}

/// Eighteen non-ASCII runs: `'aあ'`, `'あ'`, `'あa'` for each bit count.
fn sample_critical_non_ascii() -> Vec<String> {
    let mut out = Vec::new();
    for &b in bits().iter() {
        out.push("a\u{3042}".repeat(b));
        out.push("\u{3042}".repeat(b));
        out.push("\u{3042}a".repeat(b));
    }
    out
}

#[test]
fn sample_lengths_are_valid() {
    assert_eq!(sample_critical_values().len(), 6);
    assert_eq!(sample_critical_non_ascii().len(), 18);
}

#[test]
fn ascii_runs_round_trip() {
    for run in sample_critical_values() {
        assert!(!run.is_empty());
        let compressed = lzbase62::compress(&run);
        assert!(!compressed.is_empty());
        assert_eq!(lzbase62::decompress(&compressed), run);
    }
}

#[test]
fn ascii_runs_round_trip_streaming() {
    for run in sample_critical_values() {
        let compressed = compress_streamed(&run);
        assert!(!compressed.is_empty());
        assert_eq!(decompress_streamed(&compressed), run);
    }
}

#[test]
fn non_ascii_runs_round_trip() {
    for run in sample_critical_non_ascii() {
        assert!(!run.is_empty());
        let compressed = lzbase62::compress(&run);
        assert!(!compressed.is_empty());
        assert_eq!(lzbase62::decompress(&compressed), run);
    }
}

#[test]
fn non_ascii_runs_round_trip_streaming() {
    for run in sample_critical_non_ascii() {
        let compressed = compress_streamed(&run);
        assert!(!compressed.is_empty());
        assert_eq!(decompress_streamed(&compressed), run);
    }
}
