From 70a8e56ee5afd30768fb5a3eec8cfa56d477d9c5 Mon Sep 17 00:00:00 2001 From: Kanishk Sachan Date: Thu, 4 Jun 2026 00:29:54 +0100 Subject: [PATCH] test(postings): add unit tests for TermFrequencyRecorder Closes #2285 The TermFrequencyRecorder was completely untested. Add five focused tests: - term_frequency_recorder_has_term_freq: verifies the recorder correctly advertises term-frequency support via has_term_freq() - term_frequency_recorder_zero_docs: term_doc_freq() returns Some(0) before any documents are recorded - term_frequency_recorder_term_doc_freq_single_doc: one document with two occurrences yields term_doc_freq() == Some(1) - term_frequency_recorder_term_doc_freq_multiple_docs: three documents with varying term frequencies yield term_doc_freq() == Some(3), confirming the count tracks documents, not occurrences - term_frequency_recorder_single_occurrence_per_doc: each of three documents has exactly one occurrence - term_frequency_recorder_high_frequency_doc: a single document with 1000 occurrences still yields term_doc_freq() == Some(1) --- src/postings/recorder.rs | 97 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/postings/recorder.rs b/src/postings/recorder.rs index 58610c139..5c766c4e8 100644 --- a/src/postings/recorder.rs +++ b/src/postings/recorder.rs @@ -275,8 +275,9 @@ impl Recorder for TfAndPositionRecorder { mod tests { use common::write_u32_vint; + use stacker::MemoryArena; - use super::{BufferLender, VInt32Reader}; + use super::{BufferLender, Recorder, TermFrequencyRecorder, VInt32Reader}; #[test] fn test_buffer_lender() { @@ -314,4 +315,98 @@ mod tests { let res: Vec = VInt32Reader::new(&buffer[..]).collect(); assert_eq!(&res[..], &vals[..]); } + + // ── TermFrequencyRecorder ───────────────────────────────────────────────── + + #[test] + fn term_frequency_recorder_has_term_freq() { + let rec = TermFrequencyRecorder::default(); + assert!( + rec.has_term_freq(), + "TermFrequencyRecorder must advertise term-frequency support" + ); + } + + #[test] + fn term_frequency_recorder_term_doc_freq_single_doc() { + let mut arena = MemoryArena::default(); + let mut rec = TermFrequencyRecorder::default(); + + // Record one document with two term occurrences. + rec.new_doc(0, &mut arena); + rec.record_position(0, &mut arena); + rec.record_position(1, &mut arena); + rec.close_doc(&mut arena); + + assert_eq!( + rec.term_doc_freq(), + Some(1), + "term_doc_freq should be 1 after recording one document" + ); + } + + #[test] + fn term_frequency_recorder_term_doc_freq_multiple_docs() { + let mut arena = MemoryArena::default(); + let mut rec = TermFrequencyRecorder::default(); + + // Three documents with 1, 3, and 2 occurrences respectively. + for (doc, tf) in [(0u32, 1u32), (5, 3), (10, 2)] { + rec.new_doc(doc, &mut arena); + for pos in 0..tf { + rec.record_position(pos, &mut arena); + } + rec.close_doc(&mut arena); + } + + assert_eq!( + rec.term_doc_freq(), + Some(3), + "term_doc_freq should equal the number of documents recorded" + ); + } + + #[test] + fn term_frequency_recorder_zero_docs() { + let rec = TermFrequencyRecorder::default(); + assert_eq!( + rec.term_doc_freq(), + Some(0), + "term_doc_freq should be 0 before any document is recorded" + ); + } + + #[test] + fn term_frequency_recorder_single_occurrence_per_doc() { + let mut arena = MemoryArena::default(); + let mut rec = TermFrequencyRecorder::default(); + + // Each document has exactly one occurrence — the minimum non-trivial case. + for doc in [1u32, 2, 100] { + rec.new_doc(doc, &mut arena); + rec.record_position(0, &mut arena); + rec.close_doc(&mut arena); + } + + assert_eq!(rec.term_doc_freq(), Some(3)); + } + + #[test] + fn term_frequency_recorder_high_frequency_doc() { + let mut arena = MemoryArena::default(); + let mut rec = TermFrequencyRecorder::default(); + + // A document where the term appears many times. + rec.new_doc(42, &mut arena); + for pos in 0..1000 { + rec.record_position(pos, &mut arena); + } + rec.close_doc(&mut arena); + + assert_eq!( + rec.term_doc_freq(), + Some(1), + "term_doc_freq counts documents, not occurrences" + ); + } }