use crate::utils::hash::{hash_key, murmur3_32, MurmurHasher};
use std::hash::Hasher;
#[test]
fn test_murmur3_consistency() {
let test_cases = vec![
(&b""[..], 0u32, 0u32),
(&b"a"[..], 0, 0x3c2569b2),
(&b"ab"[..], 0, 0x9bbfd75f),
(&b"abc"[..], 0, 0xb3dd93fa),
(&b"abcd"[..], 0, 0x43ed676a),
(&b"hello"[..], 0, 0x248bfa47),
(&b"hello world"[..], 0, 0x5e928f0f),
];
for (input, seed, expected) in test_cases {
let result = murmur3_32(input, seed);
assert_eq!(result, expected, "Failed for input: {:?}", input);
}
}
#[test]
fn test_hash_key_function() {
let key1 = b"test_key";
let key2 = b"test_key";
let key3 = b"different_key";
assert_eq!(hash_key(key1), hash_key(key2));
assert_ne!(hash_key(key1), hash_key(key3));
}
#[test]
fn test_murmur_hasher() {
let mut hasher1 = MurmurHasher::new();
hasher1.write(b"test");
let hash1 = hasher1.finish();
let mut hasher2 = MurmurHasher::new();
hasher2.write(b"test");
let hash2 = hasher2.finish();
assert_eq!(hash1, hash2);
let mut hasher3 = MurmurHasher::new();
hasher3.write(b"different");
let hash3 = hasher3.finish();
assert_ne!(hash1, hash3);
}
#[test]
fn test_murmur_hasher_with_seed() {
let mut hasher1 = MurmurHasher::with_seed(12345);
hasher1.write(b"test");
let hash1 = hasher1.finish();
let mut hasher2 = MurmurHasher::with_seed(12345);
hasher2.write(b"test");
let hash2 = hasher2.finish();
assert_eq!(hash1, hash2);
let mut hasher3 = MurmurHasher::with_seed(54321);
hasher3.write(b"test");
let hash3 = hasher3.finish();
assert_ne!(hash1, hash3);
}
#[test]
fn test_murmur3_different_seeds() {
let data = b"test data";
let hash1 = murmur3_32(data, 0);
let hash2 = murmur3_32(data, 1);
let hash3 = murmur3_32(data, 12345);
assert_ne!(hash1, hash2);
assert_ne!(hash1, hash3);
assert_ne!(hash2, hash3);
}
#[test]
fn test_murmur3_various_lengths() {
let test_cases = vec![
vec![], vec![1], vec![1, 2, 3], vec![1, 2, 3, 4], vec![1, 2, 3, 4, 5], vec![1; 100], ];
for data in test_cases {
let hash = murmur3_32(&data, 0);
assert!(hash != 0 || data.is_empty());
}
}
#[test]
fn test_hash_distribution() {
use std::collections::HashSet;
let mut hashes = HashSet::new();
for i in 0..1000 {
let key = format!("key_{}", i);
let hash = hash_key(key.as_bytes());
hashes.insert(hash);
}
assert!(
hashes.len() > 990,
"Too many hash collisions: {}/1000",
hashes.len()
);
}
#[test]
fn test_murmur_hasher_default() {
let mut hasher1 = MurmurHasher::default();
let mut hasher2 = MurmurHasher::new();
hasher1.write(b"test");
hasher2.write(b"test");
assert_eq!(hasher1.finish(), hasher2.finish());
}
#[test]
fn test_hash_consistency_across_calls() {
let key = b"consistent_key";
let mut hashes = Vec::new();
for _ in 0..10 {
hashes.push(hash_key(key));
}
for hash in &hashes[1..] {
assert_eq!(hashes[0], *hash);
}
}
#[test]
fn test_murmur3_known_values() {
assert_eq!(murmur3_32(b"", 0), 0);
assert_eq!(murmur3_32(b"", 1), 0x514e28b7);
assert_eq!(murmur3_32(b"", 0xffffffff), 0x81f16f39);
assert_eq!(murmur3_32(b"\0\0\0\0", 0), 0x2362f9de);
assert_eq!(murmur3_32(b"aaaa", 0x9747b28c), 0x5a97808a);
assert_eq!(murmur3_32(b"Hello, world!", 0x9747b28c), 0x24884cba);
}
#[test]
fn test_hasher_trait_implementation() {
let mut our_hasher = MurmurHasher::new();
our_hasher.write(b"test");
our_hasher.write(b"data");
let our_hash = our_hasher.finish();
let mut our_hasher2 = MurmurHasher::new();
our_hasher2.write(b"test");
our_hasher2.write(b"data");
let our_hash2 = our_hasher2.finish();
assert_eq!(our_hash, our_hash2);
}