import json
import tempfile
from pathlib import Path
import pytest
import ferro_hgvs
LONG_RUN = "GCTAGCTAGC" + "A" * 300 + "GCTAGCTAGCTA"
DUP_CONTIG = "GCTAGC" + "ACGTACGT" + "TCGATC"
def _normalizer(sequence: str) -> ferro_hgvs.Normalizer:
payload = {
"transcripts": [],
"proteins": {},
"genomic_sequences": {"NC_TEST.1": sequence},
}
path = Path(tempfile.mkdtemp()) / "reference.json"
path.write_text(json.dumps(payload))
return ferro_hgvs.Normalizer(reference_json=str(path))
def test_three_spellings_of_one_deletion_converge():
normalizer = _normalizer(LONG_RUN)
results = {
normalizer.rederive(spelling)
for spelling in ("NC_TEST.1:g.11del", "NC_TEST.1:g.160del", "NC_TEST.1:g.310del")
}
assert results == {"NC_TEST.1:g.310del"}
def test_a_duplication_and_its_insertion_spelling_converge():
normalizer = _normalizer(DUP_CONTIG)
assert normalizer.rederive("NC_TEST.1:g.7_14dup") == "NC_TEST.1:g.7_14dup"
assert normalizer.rederive("NC_TEST.1:g.14_15insACGTACGT") == "NC_TEST.1:g.7_14dup"
def test_a_run_reaching_the_contig_end_settles_by_the_sequence():
normalizer = _normalizer("GCTAGCTAGC" + "A" * 40)
assert normalizer.rederive("NC_TEST.1:g.15del") == "NC_TEST.1:g.50del"
def test_max_grid_cells_and_recommended_form_are_keyword_only():
normalizer = _normalizer(LONG_RUN)
with pytest.raises(TypeError):
normalizer.rederive("NC_TEST.1:g.11del", 4096) with pytest.raises(TypeError):
normalizer.rederive("NC_TEST.1:g.11del", normalize_flag=True)
def test_recommended_form_true_reaches_the_normalizer():
core = "GCTAGC" + "A" + "TCGATC" normalizer = _normalizer(core)
assert normalizer.rederive("NC_TEST.1:g.7_8insAAA") == "NC_TEST.1:g.7_8insAAA"
assert (
normalizer.rederive("NC_TEST.1:g.7_8insAAA", recommended_form=True) == "NC_TEST.1:g.7A[4]"
)
def test_an_unparseable_description_raises_parse_error():
normalizer = _normalizer(LONG_RUN)
with pytest.raises(ferro_hgvs.ParseError):
normalizer.rederive("not an hgvs description")
def test_a_zero_grid_budget_raises_value_error():
normalizer = _normalizer(LONG_RUN)
with pytest.raises(ValueError):
normalizer.rederive("NC_TEST.1:g.11del", max_grid_cells=0)
def test_an_unknown_accession_raises_normalization_error():
normalizer = _normalizer(LONG_RUN)
with pytest.raises(ferro_hgvs.NormalizationError):
normalizer.rederive("NC_ABSENT.1:g.11del")
def test_the_per_side_flags_are_wired_to_their_own_fields():
derived = ferro_hgvs.from_sequences_detailed("NC_TEST.1", 5, "ACGT", "ACGA")
assert derived.bounded_at_end is True
assert derived.bounded_at_start is False
assert derived.placement_bounded_by_window is True
derived = ferro_hgvs.from_sequences_detailed("NC_TEST.1", 5, "ACGT", "TCGT")
assert derived.bounded_at_start is True
assert derived.bounded_at_end is False
assert derived.placement_bounded_by_window is True
def test_an_interior_change_flags_neither_side():
derived = ferro_hgvs.from_sequences_detailed("NC_TEST.1", 5, "TAAAAG", "TAAAG")
assert derived.bounded_at_start is False
assert derived.bounded_at_end is False
assert derived.placement_bounded_by_window is False
def test_the_repr_names_all_three_flags():
derived = ferro_hgvs.from_sequences_detailed("NC_TEST.1", 5, "ACGT", "ACGA")
text = repr(derived)
assert "placement_bounded_by_window=True" in text
assert "bounded_at_start=False" in text
assert "bounded_at_end=True" in text