Repository navigation
fix(compare): use semantic integer comparison for BAM tag values - #214
Conversation
bd29843 to
0895c36
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #214 +/- ##
==========================================
+ Coverage 88.05% 88.07% +0.02%
==========================================
Files 113 113
Lines 52762 52863 +101
==========================================
+ Hits 46460 46560 +100
- Misses 6302 6303 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
📝 WalkthroughWalkthroughAdded two internal helpers, 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/commands/compare/raw_compare.rs (1)
547-619: Consider adding signed integer edge case tests.Good coverage of the core scenarios. Missing tests for signed values:
- Negative values across types (e.g., -100 as i8 vs -100 as i16 → should match)
- Same byte, different sign interpretation (e.g., i8(-1) vs u8(255) → should NOT match)
The second case validates that the
b as i8cast indecode_int_tagworks correctly.🧪 Suggested additional tests
+ #[test] + fn test_order_independent_negative_value_across_types() { + // -100 as i8 (c) vs -100 as i16 (s) => should match + let r1 = base_record(&vec![b'X', b'N', b'c', (-100i8) as u8]); + let r2 = base_record(&make_s_tag(*b"XN", -100)); + assert!(raw_tags_equal_order_independent(&r1, &r2)); + } + + #[test] + fn test_order_independent_same_bytes_different_sign_interpretation() { + // i8(-1) = 0xFF vs u8(255) = 0xFF => semantically different, should NOT match + let r1 = base_record(&vec![b'X', b'V', b'c', 0xFF]); // -1 as i8 + let r2 = base_record(&make_c_tag(*b"XV", 255)); // 255 as u8 + assert!(!raw_tags_equal_order_independent(&r1, &r2)); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/commands/compare/raw_compare.rs` around lines 547 - 619, Add two unit tests to cover signed-integer edge cases: one that asserts semantic equality for negative values across signed types (e.g., create records with make_i8/make_s_tag or equivalent i8 vs i16 -100 and assert raw_tags_equal_order_independent returns true and raw_compare_structured shows tag_order_match true but tags_match false), and one that asserts non-equality for same bytes with different sign interpretation (e.g., i8(-1) vs u8(255) using make_i_tag/make_c_tag or the existing make_* helpers) and assert raw_tags_equal_order_independent returns false; reference decode_int_tag in the test names/comments so it’s clear these verify the b as i8 cast behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/commands/compare/raw_compare.rs`:
- Around line 547-619: Add two unit tests to cover signed-integer edge cases:
one that asserts semantic equality for negative values across signed types
(e.g., create records with make_i8/make_s_tag or equivalent i8 vs i16 -100 and
assert raw_tags_equal_order_independent returns true and raw_compare_structured
shows tag_order_match true but tags_match false), and one that asserts
non-equality for same bytes with different sign interpretation (e.g., i8(-1) vs
u8(255) using make_i_tag/make_c_tag or the existing make_* helpers) and assert
raw_tags_equal_order_independent returns false; reference decode_int_tag in the
test names/comments so it’s clear these verify the b as i8 cast behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1c5c7891-4503-4b2c-9dd1-d2739e8333e6
📒 Files selected for processing (1)
src/commands/compare/raw_compare.rs
0895c36 to
0bab68e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/commands/compare/raw_compare.rs`:
- Around line 204-216: Add coverage for the u32 tag by implementing a helper
like make_I_tag(tag: [u8;2], value: u32) that builds aux bytes with b'I' and
value.to_le_bytes(), then update the integer-type test matrix to include the I/i
pair and convert the integer comparison tests to rstest parameterized cases
(c/C/s/S/i/I) and use proptest for value ranges; change references to existing
helpers (make_s_tag, make_upper_s_tag) to add and use the new make_I_tag helper
in the parameterized tests so decode_int_tag(b'I') is exercised with u32 inputs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 51aa50fb-92ee-4f30-b896-048de713e05a
📒 Files selected for processing (1)
src/commands/compare/raw_compare.rs
When two BAMs encode the same integer value with different BAM types (e.g., C/u8 for 158 vs s/i16 for 158), raw byte comparison incorrectly flags them as different. The order-independent tag comparison now detects when both tags have integer types (c/C/s/S/i/I) with different encodings and decodes both to i64 for semantic comparison, falling back to byte comparison for non-integer types.
0bab68e to
33dfbca
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/commands/compare/raw_compare.rs (1)
644-650: Consider adding amake_lower_c_taghelper for i8 tags.Test manually constructs
[b'X', b'N', b'c', (-100i8) as u8]. A helper like the others would improve consistency:✨ Suggested helper
+ /// Helper to build aux bytes for a c-type (i8) integer tag. + fn make_lower_c_tag(tag: [u8; 2], value: i8) -> Vec<u8> { + vec![tag[0], tag[1], b'c', value as u8] + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/commands/compare/raw_compare.rs` around lines 644 - 650, The test test_order_independent_negative_value_across_types manually builds an i8 tag byte sequence ([b'X', b'N', b'c', (-100i8) as u8]) which is inconsistent with other tests that use helpers like make_s_tag; add a make_lower_c_tag function (mirroring naming/behavior of existing tag helpers) that accepts an i8 and returns the proper byte vector, then update the test to use make_lower_c_tag instead of constructing the bytes inline; locate usages around base_record, make_s_tag, and raw_tags_equal_order_independent to ensure the new helper integrates consistently with other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/commands/compare/raw_compare.rs`:
- Around line 644-650: The test
test_order_independent_negative_value_across_types manually builds an i8 tag
byte sequence ([b'X', b'N', b'c', (-100i8) as u8]) which is inconsistent with
other tests that use helpers like make_s_tag; add a make_lower_c_tag function
(mirroring naming/behavior of existing tag helpers) that accepts an i8 and
returns the proper byte vector, then update the test to use make_lower_c_tag
instead of constructing the bytes inline; locate usages around base_record,
make_s_tag, and raw_tags_equal_order_independent to ensure the new helper
integrates consistently with other tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b37dee06-8ce9-4226-9c0e-e55ac8a12787
📒 Files selected for processing (1)
src/commands/compare/raw_compare.rs
Summary
raw_tags_equal_order_independentnow decodes integer tag values semantically when type bytes differc/C/s/S/i/I), values are decoded toi64for comparisonContext
After #197 rewrote
compare bamsto use raw byte comparison, it lost semantic integer normalization. BAMs from different tools (fgumi vs fgbio) may encode the same integer value with different BAM types (e.g.,C/u8 vss/i16 for value 158), causing falsetag_diffreports.Observed on schmitt-abl1: 14,164 records reported as
tag_diffwith 0 actual value differences — all diffs werecD/cMtags with identical values but different integer encodings.Test plan
test_order_independent_same_value_different_int_types_u8_vs_i16— u8 158 == i16 158test_order_independent_same_value_different_int_types_u8_vs_i32— u8 200 == i32 200test_order_independent_same_value_different_int_types_i16_vs_i32— i16 1000 == i32 1000test_order_independent_different_values_different_int_types— different values still detectedcargo test --all --lib --tests)cargo ci-fmtandcargo ci-lintpassFixes #212