#![allow(clippy::unwrap_used, clippy::expect_used)]
use sqlite_forensic::interpret::{BlobContext, BlobInterpreter, LocalStorageInterpreter};
fn utf16le(s: &str) -> Vec<u8> {
s.encode_utf16().flat_map(u16::to_le_bytes).collect()
}
#[test]
fn decodes_item_table_blob_with_high_confidence() {
let interp = LocalStorageInterpreter;
let ctx = BlobContext {
table: Some("ItemTable"),
column: Some("value"),
};
let out = interp
.interpret(&utf16le("https://example.test/path"), &ctx)
.expect("an ItemTable BLOB must be interpreted");
assert_eq!(out.text, "https://example.test/path");
assert!(
out.kind.contains("utf-16"),
"kind names the encoding: {out:?}"
);
assert!(!out.lossy, "clean UTF-16-LE is not lossy");
assert!(
out.confidence >= 0.9,
"the ItemTable schema-name match is a high-confidence prior: {out:?}"
);
}
#[test]
fn does_not_fire_without_the_item_table_context() {
let interp = LocalStorageInterpreter;
let ctx = BlobContext {
table: Some("moz_places"),
column: Some("value"),
};
assert!(
interp.interpret(&utf16le("anything"), &ctx).is_none(),
"no ItemTable context → the localstorage interpreter must not fire"
);
let bare = BlobContext {
table: None,
column: None,
};
assert!(interp.interpret(&utf16le("x"), &bare).is_none());
}
#[test]
fn flags_a_lossy_decode() {
let interp = LocalStorageInterpreter;
let ctx = BlobContext {
table: Some("ItemTable"),
column: None,
};
let mut bytes = utf16le("ok");
bytes.push(0x41); let out = interp.interpret(&bytes, &ctx).expect("still interpreted");
assert!(
out.lossy,
"an odd-length UTF-16-LE blob is a lossy decode: {out:?}"
);
}