syntheogenesis / tests /test_align.py
Tengo Gzirishvili
Add pairwise sequence alignment (Needleman–Wunsch / Smith–Waterman)
91ed780
Raw
History Blame Contribute Delete
1.82 kB
"""Tests for pairwise alignment (dee/core/align.py)."""
import pytest
from dee.core import align as A
def test_identical_global():
r = A.align("ACGTACGT", "ACGTACGT")
assert r["identity"] == 100.0
assert r["gaps"] == 0
assert r["aligned_a"] == r["aligned_b"] == "ACGTACGT"
assert r["mode"] == "global"
def test_single_mismatch():
r = A.align("ACGTACGT", "ACGTTCGT")
assert r["gaps"] == 0
assert r["length"] == 8
assert r["matches"] == 7
assert 80.0 < r["identity"] < 100.0
assert r["midline"].count(".") == 1 # one mismatch column
def test_insertion_makes_a_gap():
# b has an extra base → a gap appears in the alignment
r = A.align("ACGTACGT", "ACGTAACGT")
assert r["gaps"] >= 1
assert "-" in r["aligned_a"]
# all original bases still match where aligned
assert r["matches"] == 8
def test_local_finds_embedded_region():
a = "GGGGGGACGTACGTGGGGGG"
b = "TTTTACGTACGTTTTT"
r = A.align(a, b, mode="local")
assert r["mode"] == "local"
# the shared ACGTACGT core should align at 100% identity, no gaps
assert "ACGTACGT" in r["aligned_a"].replace("-", "")
assert r["identity"] == 100.0
assert r["gaps"] == 0
def test_whitespace_and_case_normalised():
r = A.align("ac gt\nac gt", "ACGTACGT")
assert r["identity"] == 100.0
def test_empty_raises():
with pytest.raises(ValueError):
A.align("", "ACGT")
with pytest.raises(ValueError):
A.align("ACGT", " ")
def test_oversize_raises():
big = "A" * 2000
with pytest.raises(ValueError):
A.align(big, big) # 4,000,000 cells > MAX_CELLS
def test_midline_lengths_consistent():
r = A.align("ACGTACGTAC", "ACGAACGTTC")
assert len(r["aligned_a"]) == len(r["aligned_b"]) == len(r["midline"]) == r["length"]