Skip to content

Commit 208b3ec

Browse files
ameynertclaude
andcommitted
test: add unit tests for Variant, ReferenceMapping, Haplotype, and _parse_pop_freqs
Extends test_remap_divref.py with direct tests for the model methods and private helper that were previously only exercised indirectly via reference_mapping(): - Variant.render(): SNP, insertion, deletion - Haplotype.parsed_variants(): single variant, multiple variants, caching (second call returns same list object) - Haplotype.contig(): returns chromosome of first variant - ReferenceMapping.variants_involved_str(): empty, single, multiple - _parse_pop_freqs(): all floats, mixed nulls, single null Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f4afc6d commit 208b3ec

1 file changed

Lines changed: 124 additions & 1 deletion

File tree

divref/tests/tools/test_remap_divref.py

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
"""Tests for Haplotype.reference_mapping coordinate translation in remap_divref."""
1+
"""Tests for remap_divref models and helper functions."""
22

33
from typing import Any
44

55
from divref.tools.remap_divref import Haplotype
66
from divref.tools.remap_divref import ReferenceMapping
7+
from divref.tools.remap_divref import Variant
8+
from divref.tools.remap_divref import _parse_pop_freqs
79

810

911
def create_haplotype(
@@ -156,3 +158,124 @@ def test_large_insertion_with_null_frequencies() -> None:
156158
"nfe": [0.0],
157159
"sas": [0.0],
158160
}
161+
162+
163+
# ---------------------------------------------------------------------------
164+
# Variant.render
165+
# ---------------------------------------------------------------------------
166+
167+
168+
def test_variant_render_snp() -> None:
169+
assert Variant(chromosome="chr1", position=100, reference="A", alternate="T").render() == (
170+
"chr1:100:A:T"
171+
)
172+
173+
174+
def test_variant_render_insertion() -> None:
175+
assert Variant(chromosome="chr2", position=200, reference="A", alternate="ATG").render() == (
176+
"chr2:200:A:ATG"
177+
)
178+
179+
180+
def test_variant_render_deletion() -> None:
181+
assert Variant(chromosome="chrX", position=300, reference="ATG", alternate="A").render() == (
182+
"chrX:300:ATG:A"
183+
)
184+
185+
186+
# ---------------------------------------------------------------------------
187+
# Haplotype.parsed_variants and .contig
188+
# ---------------------------------------------------------------------------
189+
190+
191+
def test_parsed_variants_single() -> None:
192+
hap = create_haplotype(variants="chr1:100:A:T", n_variants=1)
193+
vs = hap.parsed_variants()
194+
assert len(vs) == 1
195+
assert vs[0].chromosome == "chr1"
196+
assert vs[0].position == 100
197+
assert vs[0].reference == "A"
198+
assert vs[0].alternate == "T"
199+
200+
201+
def test_parsed_variants_multiple() -> None:
202+
hap = create_haplotype(variants="chr1:100:A:T,chr1:200:CC:G", n_variants=2)
203+
vs = hap.parsed_variants()
204+
assert len(vs) == 2
205+
assert vs[1].position == 200
206+
assert vs[1].reference == "CC"
207+
208+
209+
def test_parsed_variants_cached() -> None:
210+
# Second call returns the exact same list object (no re-parsing)
211+
hap = create_haplotype(variants="chr1:100:A:T,chr1:200:C:G", n_variants=2)
212+
assert hap.parsed_variants() is hap.parsed_variants()
213+
214+
215+
def test_contig_returns_first_variant_chromosome() -> None:
216+
hap = create_haplotype(variants="chr5:100:A:T,chr5:200:C:G", n_variants=2)
217+
assert hap.contig() == "chr5"
218+
219+
220+
# ---------------------------------------------------------------------------
221+
# ReferenceMapping.variants_involved_str
222+
# ---------------------------------------------------------------------------
223+
224+
225+
def test_variants_involved_str_empty() -> None:
226+
rm = ReferenceMapping(
227+
chromosome="chr1",
228+
start=100,
229+
end=200,
230+
variants_involved=[],
231+
first_variant_index=None,
232+
last_variant_index=None,
233+
population_frequencies={},
234+
)
235+
assert rm.variants_involved_str() == ""
236+
237+
238+
def test_variants_involved_str_single() -> None:
239+
rm = ReferenceMapping(
240+
chromosome="chr1",
241+
start=100,
242+
end=200,
243+
variants_involved=[Variant(chromosome="chr1", position=150, reference="A", alternate="T")],
244+
first_variant_index=0,
245+
last_variant_index=0,
246+
population_frequencies={},
247+
)
248+
assert rm.variants_involved_str() == "chr1:150:A:T"
249+
250+
251+
def test_variants_involved_str_multiple() -> None:
252+
rm = ReferenceMapping(
253+
chromosome="chr1",
254+
start=100,
255+
end=300,
256+
variants_involved=[
257+
Variant(chromosome="chr1", position=150, reference="A", alternate="T"),
258+
Variant(chromosome="chr1", position=200, reference="CC", alternate="C"),
259+
],
260+
first_variant_index=0,
261+
last_variant_index=1,
262+
population_frequencies={},
263+
)
264+
assert rm.variants_involved_str() == "chr1:150:A:T,chr1:200:CC:C"
265+
266+
267+
# ---------------------------------------------------------------------------
268+
# _parse_pop_freqs
269+
# ---------------------------------------------------------------------------
270+
271+
272+
def test_parse_pop_freqs_all_floats() -> None:
273+
assert _parse_pop_freqs("0.1,0.2,0.3") == [0.1, 0.2, 0.3]
274+
275+
276+
def test_parse_pop_freqs_nulls_become_zero() -> None:
277+
assert _parse_pop_freqs("0.1,null,0.3") == [0.1, 0.0, 0.3]
278+
279+
280+
def test_parse_pop_freqs_single_null() -> None:
281+
assert _parse_pop_freqs("null") == [0.0]

0 commit comments

Comments
 (0)