hatchimera / tests /test_fusion.py
arkai2025's picture
feat(share): Quick Draw!-style lineage GIF share flow + voxel build animation
8ca9c78
Raw
History Blame Contribute Delete
2.51 kB
import sys; sys.path.insert(0, "src")
from buddy_fusion.fusion import Lineage, Creature
from buddy_fusion.fallback import fallback_genome
def test_add_ancestor_has_no_parents_and_gen_0():
lin = Lineage()
c = lin.add(fallback_genome(1))
assert c.generation == 0 and c.parent_ids == ()
def test_fuse_creates_gen_1_child_with_two_parents():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
child = lin.fuse(a.id, b.id, seed=9) # uses deterministic fallback when no runtime
assert child.generation == 1
assert set(child.parent_ids) == {a.id, b.id}
assert lin.get(child.id) is child
def test_generation_increments_from_max_parent():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
c1 = lin.fuse(a.id, b.id, seed=1)
c2 = lin.fuse(c1.id, a.id, seed=2)
assert c2.generation == 2
def test_serialize_roundtrip():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
lin.fuse(a.id, b.id, seed=3)
restored = Lineage.from_dict(lin.to_dict())
assert len(restored.creatures) == 3
def test_bloodline_of_fresh_hatch_is_parents_then_child():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
child = lin.fuse(a.id, b.id, seed=3)
chain = lin.bloodline(child.id)
assert [c.id for c in chain] == [a.id, b.id, child.id] # oldest-first, both parents
assert chain[-1] is child
def test_bloodline_includes_descendants_when_present():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
c1 = lin.fuse(a.id, b.id, seed=1) # gen 1
grandchild = lin.fuse(c1.id, a.id, seed=2) # gen 2, child of c1
chain = lin.bloodline(c1.id)
ids = [c.id for c in chain]
assert c1.id in ids and grandchild.id in ids # spine pulls in the descendant
assert ids == sorted(ids, key=lambda x: chain[ids.index(x)].generation) # generation-ordered
def test_bloodline_unknown_id_is_empty():
lin = Lineage()
assert lin.bloodline("nope") == []
def test_bloodline_is_bounded_on_deep_tree():
lin = Lineage()
a = lin.add(fallback_genome(1)); b = lin.add(fallback_genome(2))
focus = lin.fuse(a.id, b.id, seed=0)
for i in range(8): # long descendant chain
focus = lin.fuse(focus.id, a.id, seed=i + 10)
# focus is the deepest node; ancestry up is capped, so the chain never explodes
assert len(lin.bloodline(a.id)) <= 8