1+ from collections import Counter
2+ from io import StringIO
3+
14import pytest
25
36from easyhla .models import HLAProteinPair
47from easyhla .update_frequency_file_lib import (
8+ FrequencyRowDict ,
59 NewName ,
610 OldName ,
711 OtherLocusException ,
812 parse_nomenclature ,
13+ update_old_frequencies ,
914)
1015from easyhla .utils import HLA_LOCUS
1116
@@ -161,9 +166,6 @@ def test_new_name_to_frequency_format(
161166 assert new_name .to_frequency_format () == expected_result
162167
163168
164- # dict[OldName, NewName], list[str], list[tuple[str, str]], list[tuple[str, str]]
165-
166-
167169@pytest .mark .parametrize (
168170 (
169171 "rows, expected_remapping, expected_deprecated, "
@@ -237,6 +239,7 @@ def test_new_name_to_frequency_format(
237239 ("B*505002" , "B*49:32:11" ),
238240 ("B*570101" , "B*57:01:01" ),
239241 ("Cw*223344" , "C*22:122" ),
242+ ("Cw*223445" , "None" ),
240243 ("DPB1*020102" , "DPB1*02:01:02" ),
241244 ],
242245 {
@@ -246,10 +249,12 @@ def test_new_name_to_frequency_format(
246249 OldName ("B" , "50" , "50" ): NewName ("B" , "49" , "32" ),
247250 OldName ("B" , "57" , "01" ): NewName ("B" , "57" , "01" ),
248251 OldName ("C" , "22" , "33" ): NewName ("C" , "22" , "122" ),
252+ OldName ("C" , "22" , "34" ): NewName (None , "" , "" ),
249253 },
250254 [
251255 "A*020120" ,
252256 "B*505001" ,
257+ "Cw*223445" ,
253258 ],
254259 [("A*020120" , NewName ("A" , "02" , "01" ))],
255260 [("B*505002" , NewName ("B" , "49" , "32" ))],
@@ -279,3 +284,139 @@ def test_parse_nomenclature(
279284 assert result [1 ] == expected_deprecated
280285 assert result [2 ] == expected_deprecated_maps_to_other
281286 assert result [3 ] == expected_mapping_overrides_deprecated
287+
288+
289+ @pytest .mark .parametrize (
290+ (
291+ "old_frequency_lines, remapping, expected_updated_frequencies, "
292+ "expected_unmapped_alleles, expected_deprecated_alleles_seen"
293+ ),
294+ [
295+ pytest .param (
296+ ["1234,5678,5701,5603,2233,4455" ],
297+ {
298+ OldName ("A" , "12" , "34" ): NewName ("A" , "12" , "34" ),
299+ OldName ("A" , "56" , "78" ): NewName ("A" , "56" , "78" ),
300+ OldName ("B" , "57" , "01" ): NewName ("B" , "57" , "01" ),
301+ OldName ("B" , "56" , "03" ): NewName ("B" , "56" , "03" ),
302+ OldName ("C" , "22" , "33" ): NewName ("C" , "22" , "33" ),
303+ OldName ("C" , "44" , "55" ): NewName ("C" , "44" , "55" ),
304+ },
305+ [
306+ {
307+ "a_first" : "12:34" ,
308+ "a_second" : "56:78" ,
309+ "b_first" : "57:01" ,
310+ "b_second" : "56:03" ,
311+ "c_first" : "22:33" ,
312+ "c_second" : "44:55" ,
313+ },
314+ ],
315+ Counter (),
316+ Counter (),
317+ id = "one_row_all_trivial" ,
318+ ),
319+ pytest .param (
320+ ["1234,5678,5701,5603,2233,4455" ],
321+ {
322+ OldName ("A" , "12" , "34" ): NewName ("A" , "12" , "340" ),
323+ OldName ("A" , "56" , "78" ): NewName ("A" , "56" , "110" ),
324+ OldName ("B" , "57" , "01" ): NewName ("B" , "55" , "02" ),
325+ OldName ("B" , "56" , "03" ): NewName ("B" , "53" , "04" ),
326+ OldName ("C" , "22" , "33" ): NewName ("C" , "22" , "115" ),
327+ OldName ("C" , "44" , "55" ): NewName ("C" , "43" , "02" ),
328+ },
329+ [
330+ {
331+ "a_first" : "12:340" ,
332+ "a_second" : "56:110" ,
333+ "b_first" : "55:02" ,
334+ "b_second" : "53:04" ,
335+ "c_first" : "22:115" ,
336+ "c_second" : "43:02" ,
337+ },
338+ ],
339+ Counter (),
340+ Counter (),
341+ id = "one_row_all_nontrivial" ,
342+ ),
343+ pytest .param (
344+ ["1234,5678,5701,5603,2233,4455" ],
345+ {},
346+ [
347+ {
348+ "a_first" : "unmapped" ,
349+ "a_second" : "unmapped" ,
350+ "b_first" : "unmapped" ,
351+ "b_second" : "unmapped" ,
352+ "c_first" : "unmapped" ,
353+ "c_second" : "unmapped" ,
354+ },
355+ ],
356+ Counter (
357+ {
358+ ("A" , "1234" ): 1 ,
359+ ("A" , "5678" ): 1 ,
360+ ("B" , "5701" ): 1 ,
361+ ("B" , "5603" ): 1 ,
362+ ("C" , "2233" ): 1 ,
363+ ("C" , "4455" ): 1 ,
364+ }
365+ ),
366+ Counter (),
367+ id = "one_row_all_unmapped" ,
368+ ),
369+ pytest .param (
370+ ["1234,5678,5701,5603,2233,4455" ],
371+ {
372+ OldName ("A" , "12" , "34" ): NewName (None , "" , "" ),
373+ OldName ("A" , "56" , "78" ): NewName (None , "" , "" ),
374+ OldName ("B" , "57" , "01" ): NewName (None , "" , "" ),
375+ OldName ("B" , "56" , "03" ): NewName (None , "" , "" ),
376+ OldName ("C" , "22" , "33" ): NewName (None , "" , "" ),
377+ OldName ("C" , "44" , "55" ): NewName (None , "" , "" ),
378+ },
379+ [
380+ {
381+ "a_first" : "deprecated" ,
382+ "a_second" : "deprecated" ,
383+ "b_first" : "deprecated" ,
384+ "b_second" : "deprecated" ,
385+ "c_first" : "deprecated" ,
386+ "c_second" : "deprecated" ,
387+ },
388+ ],
389+ Counter (),
390+ Counter (
391+ {
392+ ("A" , "1234" ): 1 ,
393+ ("A" , "5678" ): 1 ,
394+ ("B" , "5701" ): 1 ,
395+ ("B" , "5603" ): 1 ,
396+ ("C" , "2233" ): 1 ,
397+ ("C" , "4455" ): 1 ,
398+ }
399+ ),
400+ id = "one_row_all_deprecated" ,
401+ ),
402+ ],
403+ )
404+ def test_update_old_frequencies (
405+ old_frequency_lines : list [str ],
406+ remapping : dict [OldName , NewName ],
407+ expected_updated_frequencies : list [FrequencyRowDict ],
408+ expected_unmapped_alleles : Counter [tuple [HLA_LOCUS , str ]],
409+ expected_deprecated_alleles_seen : Counter [tuple [HLA_LOCUS , str ]],
410+ ):
411+ fake_old_frequency_file : StringIO = StringIO ("\n " .join (old_frequency_lines ))
412+ updated_frequencies : list [FrequencyRowDict ]
413+ unmapped_alleles : Counter [tuple [HLA_LOCUS , str ]]
414+ deprecated_alleles_seen : Counter [tuple [HLA_LOCUS , str ]]
415+
416+ updated_frequencies , unmapped_alleles , deprecated_alleles_seen = (
417+ update_old_frequencies (fake_old_frequency_file , remapping )
418+ )
419+
420+ assert updated_frequencies == expected_updated_frequencies
421+ assert unmapped_alleles == expected_unmapped_alleles
422+ assert deprecated_alleles_seen == expected_deprecated_alleles_seen
0 commit comments