const EXPECTED_HEADER: [u8; 8] = [b'K', b'H', b'H', b'S', 0x02, 0x00, 0x00, 0x00];
#[test]
fn magic_constant_is_exact_bytes() {
assert_eq!(keyhog_core::HYPERSCAN_CACHE_MAGIC, b"KHHS");
assert_eq!(
keyhog_core::HYPERSCAN_CACHE_MAGIC,
&[0x4B, 0x48, 0x48, 0x53]
);
}
#[test]
fn version_constant_is_two() {
assert_eq!(keyhog_core::HYPERSCAN_CACHE_VERSION, 2_u32);
}
#[test]
fn header_len_constant_is_eight() {
assert_eq!(keyhog_core::HYPERSCAN_CACHE_HEADER_LEN, 8_usize);
assert_eq!(
keyhog_core::HYPERSCAN_CACHE_HEADER_LEN,
keyhog_core::HYPERSCAN_CACHE_MAGIC.len() + core::mem::size_of::<u32>()
);
}
#[test]
fn file_bytes_cap_is_128_mib() {
assert_eq!(keyhog_core::HYPERSCAN_CACHE_FILE_BYTES, 134_217_728_u64);
assert_eq!(keyhog_core::HYPERSCAN_CACHE_FILE_BYTES, 128 * 1024 * 1024);
}
#[test]
fn write_header_emits_exact_eight_bytes() {
let mut out = Vec::new();
keyhog_core::write_hyperscan_cache_header(&mut out);
assert_eq!(out.len(), 8);
assert_eq!(out.as_slice(), &EXPECTED_HEADER);
assert_eq!(&out[..4], b"KHHS");
assert_eq!(&out[4..8], &[0x02, 0x00, 0x00, 0x00]);
assert_eq!(
u32::from_le_bytes([out[4], out[5], out[6], out[7]]),
keyhog_core::HYPERSCAN_CACHE_VERSION
);
}
#[test]
fn write_then_validate_round_trips_true() {
let mut out = Vec::new();
keyhog_core::write_hyperscan_cache_header(&mut out);
assert!(keyhog_core::hyperscan_cache_header_is_valid(&out));
}
#[test]
fn write_appends_and_preserves_existing_prefix() {
let mut out = vec![0xAA, 0xBB, 0xCC];
keyhog_core::write_hyperscan_cache_header(&mut out);
assert_eq!(out.len(), 11);
assert_eq!(&out[..3], &[0xAA, 0xBB, 0xCC]);
assert_eq!(&out[3..], &EXPECTED_HEADER);
assert!(keyhog_core::hyperscan_cache_header_is_valid(&out[3..]));
}
#[test]
fn exact_valid_header_validates_true() {
assert!(keyhog_core::hyperscan_cache_header_is_valid(
&EXPECTED_HEADER
));
}
#[test]
fn corrupted_magic_validates_false() {
let mut header = EXPECTED_HEADER;
header[0] = b'X';
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&header));
let mut header2 = EXPECTED_HEADER;
header2[3] = b's';
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&header2));
}
#[test]
fn wrong_version_validates_false() {
let mut v1 = EXPECTED_HEADER;
v1[4] = 0x01;
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&v1));
let mut v3 = EXPECTED_HEADER;
v3[4] = 0x03;
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&v3));
let mut v0 = EXPECTED_HEADER;
v0[4] = 0x00;
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&v0));
}
#[test]
fn high_byte_version_flip_validates_false() {
let mut header = EXPECTED_HEADER;
header[7] = 0x02; assert!(!keyhog_core::hyperscan_cache_header_is_valid(&header));
assert_ne!(
u32::from_le_bytes([header[4], header[5], header[6], header[7]]),
keyhog_core::HYPERSCAN_CACHE_VERSION
);
}
#[test]
fn short_header_validates_false() {
assert!(!keyhog_core::hyperscan_cache_header_is_valid(
&EXPECTED_HEADER[..7]
));
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&[]));
assert!(!keyhog_core::hyperscan_cache_header_is_valid(b"KHHS"));
}
#[test]
fn overlong_header_validates_false() {
let mut nine = EXPECTED_HEADER.to_vec();
nine.push(0x00);
assert_eq!(nine.len(), 9);
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&nine));
}
#[test]
fn empty_body_write_and_validate_by_header_len_slice() {
let mut data = Vec::new();
keyhog_core::write_hyperscan_cache_header(&mut data);
data.extend_from_slice(&[0x11, 0x22, 0x33, 0x44]); assert_eq!(data.len(), 12);
let header_len = keyhog_core::HYPERSCAN_CACHE_HEADER_LEN;
assert!(data.len() > header_len);
assert!(keyhog_core::hyperscan_cache_header_is_valid(
&data[..header_len]
));
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&data));
}
#[test]
fn all_zero_header_validates_false() {
let zeros = [0_u8; 8];
assert!(!keyhog_core::hyperscan_cache_header_is_valid(&zeros));
}