Skip to content

Commit e8697e6

Browse files
committed
Create comprehensive unit tests for cache functionality
- Add tests to `src/cache.rs` - Write tests for cache key creation, equality, and hashing - Test cache hit scenarios (same parameters return cached keys) - Test cache miss scenarios (new parameters generate and cache keys) - Test that cached keys are identical to directly generated keys
1 parent 9d3a433 commit e8697e6

File tree

2 files changed

+218
-1
lines changed

2 files changed

+218
-1
lines changed

.kiro/specs/crc-params-caching/tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
- Verify that the function signature and behavior are identical
3434
- _Requirements: 1.1, 1.2, 5.1, 5.2, 5.3_
3535

36-
- [ ] 6. Create comprehensive unit tests for cache functionality
36+
- [x] 6. Create comprehensive unit tests for cache functionality
3737
- Add tests to `src/cache.rs`
3838
- Write tests for cache key creation, equality, and hashing
3939
- Test cache hit scenarios (same parameters return cached keys)

src/cache.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,204 @@ pub fn clear_cache() {
8686
#[cfg(test)]
8787
mod tests {
8888
use super::*;
89+
use std::collections::HashSet;
90+
91+
#[test]
92+
fn test_cache_key_creation() {
93+
let key1 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
94+
let key2 = CrcParamsCacheKey::new(64, 0x42F0E1EBA9EA3693, false);
95+
96+
assert_eq!(key1.width, 32);
97+
assert_eq!(key1.poly, 0x04C11DB7);
98+
assert_eq!(key1.reflected, true);
99+
100+
assert_eq!(key2.width, 64);
101+
assert_eq!(key2.poly, 0x42F0E1EBA9EA3693);
102+
assert_eq!(key2.reflected, false);
103+
}
104+
105+
#[test]
106+
fn test_cache_key_equality() {
107+
let key1 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
108+
let key2 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
109+
let key3 = CrcParamsCacheKey::new(32, 0x04C11DB7, false); // Different reflected
110+
let key4 = CrcParamsCacheKey::new(64, 0x04C11DB7, true); // Different width
111+
let key5 = CrcParamsCacheKey::new(32, 0x1EDC6F41, true); // Different poly
112+
113+
// Test equality
114+
assert_eq!(key1, key2);
115+
assert_eq!(key1.clone(), key2.clone());
116+
117+
// Test inequality
118+
assert_ne!(key1, key3);
119+
assert_ne!(key1, key4);
120+
assert_ne!(key1, key5);
121+
assert_ne!(key3, key4);
122+
assert_ne!(key3, key5);
123+
assert_ne!(key4, key5);
124+
}
125+
126+
#[test]
127+
fn test_cache_key_hashing() {
128+
let key1 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
129+
let key2 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
130+
let key3 = CrcParamsCacheKey::new(32, 0x04C11DB7, false);
131+
132+
// Create a HashSet to test that keys can be used as hash keys
133+
let mut set = HashSet::new();
134+
set.insert(key1.clone());
135+
set.insert(key2.clone());
136+
set.insert(key3.clone());
137+
138+
// Should only have 2 unique keys (key1 and key2 are equal)
139+
assert_eq!(set.len(), 2);
140+
141+
// Test that equal keys can be found in the set
142+
assert!(set.contains(&key1));
143+
assert!(set.contains(&key2));
144+
assert!(set.contains(&key3));
145+
146+
// Test that a new equivalent key can be found
147+
let key4 = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
148+
assert!(set.contains(&key4));
149+
}
150+
151+
#[test]
152+
fn test_cache_hit_scenarios() {
153+
clear_cache();
154+
155+
// First call should be a cache miss and generate keys
156+
let keys1 = get_or_generate_keys(32, 0x04C11DB7, true);
157+
158+
// Second call with same parameters should be a cache hit
159+
let keys2 = get_or_generate_keys(32, 0x04C11DB7, true);
160+
161+
// Keys should be identical (same array contents)
162+
assert_eq!(keys1, keys2);
163+
164+
// Test multiple cache hits
165+
let keys3 = get_or_generate_keys(32, 0x04C11DB7, true);
166+
let keys4 = get_or_generate_keys(32, 0x04C11DB7, true);
167+
168+
assert_eq!(keys1, keys3);
169+
assert_eq!(keys1, keys4);
170+
assert_eq!(keys2, keys3);
171+
assert_eq!(keys2, keys4);
172+
}
173+
174+
#[test]
175+
fn test_cache_miss_scenarios() {
176+
clear_cache();
177+
178+
// Different width - should be cache miss
179+
let keys_32 = get_or_generate_keys(32, 0x04C11DB7, true);
180+
let keys_64 = get_or_generate_keys(64, 0x04C11DB7, true);
181+
assert_ne!(keys_32, keys_64);
182+
183+
// Different poly - should be cache miss
184+
let keys_poly1 = get_or_generate_keys(32, 0x04C11DB7, true);
185+
let keys_poly2 = get_or_generate_keys(32, 0x1EDC6F41, true);
186+
assert_ne!(keys_poly1, keys_poly2);
187+
188+
// Different reflected - should be cache miss
189+
let keys_refl_true = get_or_generate_keys(32, 0x04C11DB7, true);
190+
let keys_refl_false = get_or_generate_keys(32, 0x04C11DB7, false);
191+
assert_ne!(keys_refl_true, keys_refl_false);
192+
193+
// Verify each parameter set is cached independently
194+
let keys_32_again = get_or_generate_keys(32, 0x04C11DB7, true);
195+
let keys_64_again = get_or_generate_keys(64, 0x04C11DB7, true);
196+
let keys_poly1_again = get_or_generate_keys(32, 0x04C11DB7, true);
197+
let keys_poly2_again = get_or_generate_keys(32, 0x1EDC6F41, true);
198+
let keys_refl_true_again = get_or_generate_keys(32, 0x04C11DB7, true);
199+
let keys_refl_false_again = get_or_generate_keys(32, 0x04C11DB7, false);
200+
201+
assert_eq!(keys_32, keys_32_again);
202+
assert_eq!(keys_64, keys_64_again);
203+
assert_eq!(keys_poly1, keys_poly1_again);
204+
assert_eq!(keys_poly2, keys_poly2_again);
205+
assert_eq!(keys_refl_true, keys_refl_true_again);
206+
assert_eq!(keys_refl_false, keys_refl_false_again);
207+
}
208+
209+
#[test]
210+
fn test_cached_keys_identical_to_generated_keys() {
211+
clear_cache();
212+
213+
// Test CRC32 parameters
214+
let width = 32;
215+
let poly = 0x04C11DB7;
216+
let reflected = true;
217+
218+
// Generate keys directly (bypassing cache)
219+
let direct_keys = generate::keys(width, poly, reflected);
220+
221+
// Get keys through cache (first call will be cache miss, generates and caches)
222+
let cached_keys_first = get_or_generate_keys(width, poly, reflected);
223+
224+
// Get keys through cache again (should be cache hit)
225+
let cached_keys_second = get_or_generate_keys(width, poly, reflected);
226+
227+
// All should be identical
228+
assert_eq!(direct_keys, cached_keys_first);
229+
assert_eq!(direct_keys, cached_keys_second);
230+
assert_eq!(cached_keys_first, cached_keys_second);
231+
232+
// Test CRC64 parameters
233+
let width64 = 64;
234+
let poly64 = 0x42F0E1EBA9EA3693;
235+
let reflected64 = false;
236+
237+
let direct_keys64 = generate::keys(width64, poly64, reflected64);
238+
let cached_keys64_first = get_or_generate_keys(width64, poly64, reflected64);
239+
let cached_keys64_second = get_or_generate_keys(width64, poly64, reflected64);
240+
241+
assert_eq!(direct_keys64, cached_keys64_first);
242+
assert_eq!(direct_keys64, cached_keys64_second);
243+
assert_eq!(cached_keys64_first, cached_keys64_second);
244+
245+
// Verify different parameters produce different keys
246+
assert_ne!(direct_keys, direct_keys64);
247+
assert_ne!(cached_keys_first, cached_keys64_first);
248+
}
249+
250+
#[test]
251+
fn test_multiple_parameter_combinations() {
252+
clear_cache();
253+
254+
// Test various common CRC parameter combinations
255+
let test_cases = [
256+
(32, 0x04C11DB7, true), // CRC32
257+
(32, 0x04C11DB7, false), // CRC32 non-reflected
258+
(32, 0x1EDC6F41, true), // CRC32C
259+
(64, 0x42F0E1EBA9EA3693, true), // CRC64 ISO
260+
(64, 0x42F0E1EBA9EA3693, false), // CRC64 ISO non-reflected
261+
(64, 0xD800000000000000, true), // CRC64 ECMA
262+
];
263+
264+
let mut all_keys = Vec::new();
265+
266+
// Generate keys for all test cases
267+
for &(width, poly, reflected) in &test_cases {
268+
let keys = get_or_generate_keys(width, poly, reflected);
269+
all_keys.push(keys);
270+
}
271+
272+
// Verify all keys are different (no collisions)
273+
for i in 0..all_keys.len() {
274+
for j in (i + 1)..all_keys.len() {
275+
assert_ne!(all_keys[i], all_keys[j],
276+
"Keys should be different for test cases {} and {}", i, j);
277+
}
278+
}
279+
280+
// Verify cache hits return same keys
281+
for (i, &(width, poly, reflected)) in test_cases.iter().enumerate() {
282+
let cached_keys = get_or_generate_keys(width, poly, reflected);
283+
assert_eq!(all_keys[i], cached_keys,
284+
"Cache hit should return same keys for test case {}", i);
285+
}
286+
}
89287

90288
#[test]
91289
fn test_cache_management_utilities() {
@@ -126,4 +324,23 @@ mod tests {
126324
// Keys should be identical (same parameters produce same keys)
127325
assert_eq!(keys, keys2);
128326
}
327+
328+
#[test]
329+
fn test_cache_key_debug_and_clone() {
330+
let key = CrcParamsCacheKey::new(32, 0x04C11DB7, true);
331+
332+
// Test Debug trait
333+
let debug_str = format!("{:?}", key);
334+
assert!(debug_str.contains("CrcParamsCacheKey"));
335+
assert!(debug_str.contains("32"));
336+
assert!(debug_str.contains("0x4c11db7") || debug_str.contains("79764919"));
337+
assert!(debug_str.contains("true"));
338+
339+
// Test Clone trait
340+
let cloned_key = key.clone();
341+
assert_eq!(key, cloned_key);
342+
assert_eq!(key.width, cloned_key.width);
343+
assert_eq!(key.poly, cloned_key.poly);
344+
assert_eq!(key.reflected, cloned_key.reflected);
345+
}
129346
}

0 commit comments

Comments
 (0)