syntheogenesis / tests /test_compare_sequences.py
github-actions[bot]
Deploy a1975e4
15766ed
Raw
History Blame Contribute Delete
3.77 kB
"""#16 from the audit: "how does my clone differ from wild type?"
align.py has done Needleman-Wunsch and Smith-Waterman since the M-series, and
the agent could never call it — the fifth capability found sitting in the repo
with no tool pointing at it. That pattern is the audit's single most common
finding, which is why this file exists at all.
The tool returns DIFFERENCES, not an alignment. A scientist comparing a
sequenced clone to its design wants "one substitution at position 9"; the
aligned strings are the evidence for that, not the answer.
"""
import pytest
from dee.core import agent_tools as t
from dee.core import orchestrator as orch
def cmp_(a, b, **kw):
return t.execute_tool("compare_sequences",
dict(sequence_a=a, sequence_b=b, **kw),
auth_anonymous=True)
def test_a_point_mutation_is_located_exactly():
out = cmp_("ATGGAGGAGCCGCAGTCAGAT", "ATGGAGGAACCGCAGTCAGAT")
assert out["ok"] and out["difference_count"] == 1
assert out["differences"] == [
{"position": 9, "from": "G", "to": "A", "kind": "substitution"}]
def test_identical_sequences_say_so_plainly():
"""The most reassuring answer in the product, and it must not be phrased
as 100% identity with a list of zero differences."""
out = cmp_("ATGCATGCATGC", "ATGCATGCATGC")
assert out["identical"] is True and out["difference_count"] == 0
assert "identical" in orch._summarize("compare_sequences", out)
def test_indels_are_distinguished_from_substitutions():
"""A substitution and a deletion have wildly different consequences —
collapsing both into 'differences' would hide a frameshift."""
out = cmp_("ATGCATGCATGCAAA", "ATGCATGCATGC")
assert out["by_kind"]["deletion"] == 3
assert out["by_kind"]["substitution"] == 0
def test_positions_are_numbered_along_the_reference():
"""Numbering along the ALIGNMENT would give coordinates meaningless
outside this one comparison — useless for going back to the construct."""
out = cmp_("AAATTTGGG", "AAATTTGGGCCC") # b has an insertion at the end
for d in out["differences"]:
assert d["position"] <= 9, d
def test_protein_works_too():
out = cmp_("MSIQHFRVAL", "MSIQHFRVAK")
assert out["difference_count"] == 1
assert out["differences"][0]["to"] == "K"
def test_the_size_ceiling_is_an_answer_not_a_crash():
"""align() refuses oversized input by design; that refusal has to reach
the model as a real result with a next step."""
big = "ACGT" * 200_000
out = cmp_(big, big)
assert out["ok"] is False and out["kind"] == "too_large"
assert "shorter region" in out["next"]
def test_missing_input_is_refused_before_any_work():
assert cmp_("", "ATGC")["ok"] is False
assert cmp_("ATGC", " ")["ok"] is False
def test_an_unknown_mode_is_refused_rather_than_guessed():
out = cmp_("ATGC", "ATGC", mode="fuzzy")
assert out["ok"] is False and "global" in out["error"]
def test_the_summary_leads_with_what_changed_not_just_identity():
"""99% identity is fine for a point mutation and alarming for a
frameshift. The line has to say which."""
line = orch._summarize("compare_sequences",
cmp_("ATGCATGCATGCAAA", "ATGCATGCATGC"))
assert "deletion" in line
def test_it_is_reachable_and_ungated():
"""The whole point of the ticket. Pure local computation on sequences the
caller already holds — nothing transmitted, nothing stored."""
assert "compare_sequences" in t._TOOLS
assert any(s["function"]["name"] == "compare_sequences" for s in orch.TOOL_SPECS)
assert t._TOOLS["compare_sequences"]["requires_signin"] is False
assert orch._requires_confirm("compare_sequences") is False