Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/znippy-zoomies

lzip-parallel/tests/shared_core_roundtrip.rs

//! Byte-identical decode through the shared `znippy_zip_core` Central Directory path.
//!
//! Self-contained (no network): builds a small in-memory .zip with the `zip`
//! crate, decodes it via lzip-parallel's public API — which parses the CD
//! through the shared `znippy_zip_core::central_dir` parser — and asserts every entry
//! comes back byte-for-byte.  Red if the shared parser mis-resolves an entry
//! offset/size or the ZIP wrapper regresses.

use std::io::{Cursor, Write};
use zip::CompressionMethod;
use zip::write::SimpleFileOptions;

/// Build an in-memory ZIP whose entries mix DEFLATE and STORE.
fn build_zip(entries: &[(&str, &[u8], CompressionMethod)]) -> Vec<u8> {
    let mut buf = Vec::new();
    {
        let mut zw = zip::ZipWriter::new(Cursor::new(&mut buf));
        for (name, data, method) in entries {
            let opts = SimpleFileOptions::default().compression_method(*method);
            zw.start_file(*name, opts).unwrap();
            zw.write_all(data).unwrap();
        }
        zw.finish().unwrap();
    }
    buf
}

#[test]
fn zip_decode_byte_identical_through_shared_core() {
    let payloads: Vec<(&str, Vec<u8>, CompressionMethod)> = vec![
        (
            "dir/notes.txt",
            b"a zip is a jar too\n".to_vec(),
            CompressionMethod::Deflated,
        ),
        (
            "payload/large.bin",
            (0u8..255).cycle().take(9000).collect(),
            CompressionMethod::Deflated,
        ),
        (
            "stored/raw.dat",
            vec![0x5Au8; 4096],
            CompressionMethod::Stored,
        ),
        ("root.txt", b"hello".to_vec(), CompressionMethod::Deflated),
    ];
    let refs: Vec<(&str, &[u8], CompressionMethod)> = payloads
        .iter()
        .map(|(n, d, m)| (*n, d.as_slice(), *m))
        .collect();
    let zip = build_zip(&refs);

    let out = lzip_parallel::decompress_zip(&zip).expect("decode zip");

    // Every non-directory entry must round-trip byte-for-byte.
    for (name, data, _) in &payloads {
        let got = out
            .iter()
            .find(|e| &e.name == name)
            .unwrap_or_else(|| panic!("entry {name} missing from decode"));
        assert_eq!(&got.data, data, "byte mismatch for {name}");
    }
    assert_eq!(out.len(), payloads.len(), "entry count mismatch");
}

#[test]
fn zip_filter_suffixes_uses_shared_cd() {
    let zip = build_zip(&[
        ("pkg/a.py", b"print(1)", CompressionMethod::Deflated),
        ("pkg/a.txt", b"text", CompressionMethod::Deflated),
        ("pkg/b.py", b"print(2)", CompressionMethod::Deflated),
    ]);
    let out = lzip_parallel::decompress_zip_filter_suffixes(&zip, &[".py"]).expect("suffix decode");
    assert_eq!(out.len(), 2);
    assert!(out.iter().all(|e| e.name.ends_with(".py")));
}