From 0b60b38c7acf025c08d2ba0346b3b9bcb8e19b21 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Sun, 16 Aug 2026 19:48:08 -0700 Subject: [PATCH] test(codec): assert the bases the codec_template consensus tests are named for #768 (the fix for fulcrumgenomics/fgumi#763) now stores the reverse CODEC read in reference orientation, so codec_template families consense to the reference sequence over the region the two strands share rather than the mostly-N output the create_fr_pair orientation bug used to produce. Two #767 tests still asserted only the consensus length, under a codec_template doc comment that still claimed the bases were unusable and pointed at #763. test_dovetailed_starts_without_an_indel_call_a_consensus and test_terminal_indel_outside_the_shared_region_calls_a_consensus now assert the emitted consensus bases, each verified byte-for-byte against REF_BASES over the shared span (the lone N's are single-strand soft-clip read-through edges), and the stale doc comment is corrected. The two sibling tests are threshold and rejection tests and keep their existing assertions. Test-only; no production change. Closes #807. --- crates/fgumi-consensus/src/codec_caller.rs | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/crates/fgumi-consensus/src/codec_caller.rs b/crates/fgumi-consensus/src/codec_caller.rs index eac88ba90..450131638 100644 --- a/crates/fgumi-consensus/src/codec_caller.rs +++ b/crates/fgumi-consensus/src/codec_caller.rs @@ -4050,12 +4050,11 @@ mod tests { /// Both reads are cut from the same shared reference bases, so the alignment geometry is /// the only variable between them. /// - /// The tests below assert consensus *lengths* rather than consensus *bases*, because - /// [`create_fr_pair`] stores the reverse read's `SEQ` in read orientation where a BAM - /// stores it in reference orientation — so its two strands point opposite ways and the - /// consensus comes out mostly `N` for every family the fixture builds, not just these. - /// Tracked as fulcrumgenomics/fgumi#763; the length is what this fix is about, and it is - /// unaffected. + /// With the reverse read stored in reference orientation (fulcrumgenomics/fgumi#763, fixed + /// by #768), a family with no strand disagreement consenses to the reference sequence over + /// the region the two strands share — so the tests below assert the consensus *bases*, not + /// merely its length. Positions only one strand covers — the soft-clip read-through edges — + /// resolve to `N`. fn codec_template( pos_start: usize, pos_cigar: &[(Kind, usize)], @@ -4140,6 +4139,14 @@ mod tests { 128, "the reverse read gives up two bases to the overlap clip, leaving both strands 128" ); + // The consensus is the reference sequence the two strands share: `REF_BASES[200..326]` + // for the 126 positions both align, bracketed by the soft-clip read-through edge. A + // mis-placed clip would shift these bases while leaving the length intact. + assert_eq!( + &consensus[0].bases[..], + b"ANTAACTTTTTGATAGTAGCGGGAGTAGGAGTAAATCTTGTACTAATTAGTGAATATTCTGTTGATGGTGGCTGAAAATTTATAGCTACACAACCAAAAAAATAAAAAACGTTAGTCAATAGCATTTA", + "the consensus must be the reference sequence the two strands share", + ); } /// The duplex overlap is measured over the region both strands align, so a threshold @@ -4208,6 +4215,14 @@ mod tests { 127, "both strands keep 127 bases after the overlap clip, so the consensus is 127 long" ); + // The consensus is the reference sequence the two strands share, with the terminal + // deletion skipped; the lone `N` is the single-strand edge past the reverse read's + // close. A mis-placed clip would shift these bases while leaving the length intact. + assert_eq!( + &consensus[0].bases[..], + b"ANTAACTTTTTGATAGTAGCGGGAGTAGGAGTAAATCTTGTACTAATTAGTGAATATTCTGTTGATGGTGGCTGAAAATTTATAGCTACACAACCAAAAAAATAAAAAACGTTAGTCAATAGCATNA", + "the consensus must be the reference sequence the two strands share", + ); } /// The control the fix must not weaken: a deletion *inside* the shared region still