aboutsummaryrefslogtreecommitdiff
path: root/crates/rsli/src/lib.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-02-10 02:11:11 +0300
committerValentin Popov <valentin@popov.link>2026-02-10 02:11:11 +0300
commit371a060eb685a2b76651689689dfa07461f69c7e (patch)
tree944c9a6c46f35ced0333884242ccbd0544fbd878 /crates/rsli/src/lib.rs
parente08b5f3853784e2fb8dc016d4a149c1a2282f127 (diff)
downloadfparkan-371a060eb685a2b76651689689dfa07461f69c7e.tar.xz
fparkan-371a060eb685a2b76651689689dfa07461f69c7e.zip
Refactor tests and move them to a dedicated module
- Moved the test suite from `lib.rs` to a new `tests.rs` file for better organization. - Added a `SyntheticRsliEntry` struct to facilitate synthetic test cases. - Introduced `RsliBuildOptions` struct to manage options for building RsLi byte arrays. - Implemented various utility functions for file handling, data compression, and bit manipulation. - Enhanced the `rsli_read_unpack_and_repack_all_files` test to validate all RsLi archives. - Added new tests for synthetic entries covering all packing methods, overlay handling, and validation error cases.
Diffstat (limited to 'crates/rsli/src/lib.rs')
-rw-r--r--crates/rsli/src/lib.rs186
1 files changed, 2 insertions, 184 deletions
diff --git a/crates/rsli/src/lib.rs b/crates/rsli/src/lib.rs
index 0c55b25..ae800dc 100644
--- a/crates/rsli/src/lib.rs
+++ b/crates/rsli/src/lib.rs
@@ -27,6 +27,7 @@ impl Default for OpenOptions {
}
}
+#[derive(Debug)]
pub struct Library {
bytes: Arc<[u8]>,
entries: Vec<EntryRecord>,
@@ -979,187 +980,4 @@ fn needs_xor_key(method: PackMethod) -> bool {
}
#[cfg(test)]
-mod tests {
- use super::*;
- use std::any::Any;
- use std::panic::{catch_unwind, AssertUnwindSafe};
- use std::path::PathBuf;
-
- fn collect_files_recursive(root: &Path, out: &mut Vec<PathBuf>) {
- let Ok(entries) = fs::read_dir(root) else {
- return;
- };
- for entry in entries.flatten() {
- let path = entry.path();
- if path.is_dir() {
- collect_files_recursive(&path, out);
- } else if path.is_file() {
- out.push(path);
- }
- }
- }
-
- fn rsli_test_files() -> Vec<PathBuf> {
- let root = Path::new(env!("CARGO_MANIFEST_DIR"))
- .join("..")
- .join("..")
- .join("testdata")
- .join("rsli");
- let mut files = Vec::new();
- collect_files_recursive(&root, &mut files);
- files.sort();
- files
- .into_iter()
- .filter(|path| {
- fs::read(path)
- .map(|data| data.get(0..4) == Some(b"NL\0\x01"))
- .unwrap_or(false)
- })
- .collect()
- }
-
- fn panic_message(payload: Box<dyn Any + Send>) -> String {
- let any = payload.as_ref();
- if let Some(message) = any.downcast_ref::<String>() {
- return message.clone();
- }
- if let Some(message) = any.downcast_ref::<&str>() {
- return (*message).to_string();
- }
- String::from("panic without message")
- }
-
- #[test]
- fn rsli_read_unpack_and_repack_all_files() {
- let files = rsli_test_files();
- assert!(!files.is_empty(), "testdata/rsli contains no RsLi archives");
-
- let checked = files.len();
- let mut success = 0usize;
- let mut failures = Vec::new();
-
- for path in files {
- let display_path = path.display().to_string();
- let result = catch_unwind(AssertUnwindSafe(|| {
- let original = fs::read(&path).expect("failed to read archive");
- let library = Library::open_path(&path)
- .unwrap_or_else(|err| panic!("failed to open {}: {err}", path.display()));
-
- let count = library.entry_count();
- assert_eq!(
- count,
- library.entries().count(),
- "entry count mismatch: {}",
- path.display()
- );
-
- for idx in 0..count {
- let id = EntryId(idx as u32);
- let meta_ref = library
- .get(id)
- .unwrap_or_else(|| panic!("missing entry #{idx} in {}", path.display()));
-
- let loaded = library.load(id).unwrap_or_else(|err| {
- panic!("load failed for {} entry #{idx}: {err}", path.display())
- });
-
- let packed = library.load_packed(id).unwrap_or_else(|err| {
- panic!(
- "load_packed failed for {} entry #{idx}: {err}",
- path.display()
- )
- });
- let unpacked = library.unpack(&packed).unwrap_or_else(|err| {
- panic!("unpack failed for {} entry #{idx}: {err}", path.display())
- });
- assert_eq!(
- loaded,
- unpacked,
- "load != unpack in {} entry #{idx}",
- path.display()
- );
-
- let mut out = Vec::new();
- let written = library.load_into(id, &mut out).unwrap_or_else(|err| {
- panic!(
- "load_into failed for {} entry #{idx}: {err}",
- path.display()
- )
- });
- assert_eq!(
- written,
- loaded.len(),
- "load_into size mismatch in {} entry #{idx}",
- path.display()
- );
- assert_eq!(
- out,
- loaded,
- "load_into payload mismatch in {} entry #{idx}",
- path.display()
- );
-
- let fast = library.load_fast(id).unwrap_or_else(|err| {
- panic!(
- "load_fast failed for {} entry #{idx}: {err}",
- path.display()
- )
- });
- assert_eq!(
- fast.as_slice(),
- loaded.as_slice(),
- "load_fast mismatch in {} entry #{idx}",
- path.display()
- );
-
- let found = library.find(&meta_ref.meta.name).unwrap_or_else(|| {
- panic!(
- "find failed for '{}' in {}",
- meta_ref.meta.name,
- path.display()
- )
- });
- let found_meta = library.get(found).expect("find returned invalid entry id");
- assert_eq!(
- found_meta.meta.name,
- meta_ref.meta.name,
- "find returned a different entry in {}",
- path.display()
- );
- }
-
- let rebuilt = library
- .rebuild_from_parsed_metadata()
- .unwrap_or_else(|err| panic!("rebuild failed for {}: {err}", path.display()));
- assert_eq!(
- rebuilt,
- original,
- "byte-to-byte roundtrip mismatch for {}",
- path.display()
- );
- }));
-
- match result {
- Ok(()) => success += 1,
- Err(payload) => {
- failures.push(format!("{}: {}", display_path, panic_message(payload)));
- }
- }
- }
-
- let failed = failures.len();
- eprintln!(
- "RsLi summary: checked={}, success={}, failed={}",
- checked, success, failed
- );
- if !failures.is_empty() {
- panic!(
- "RsLi validation failed.\nsummary: checked={}, success={}, failed={}\n{}",
- checked,
- success,
- failed,
- failures.join("\n")
- );
- }
- }
-}
+mod tests;