✅ Purifying flame fusion applies familiar stats
| Category | Ability |
| Status | Passing |
| Test | tests/test_abilities_familiars.py::test_purifying_flame_fusion_applies_familiar_stats |
When Duban fuses with Purifying Flame, the fusion uses Purifying Flame's
Preconditions
-
Lane 0: P1's Duban (#001) — base HP=6, READIED.
-
Lane 0: P1's Purifying Flame (#102_1) — familiar, fhp=9.
-
Duban is not yet fused.
Action
- fuse_demons(state, duban, purifying_flame)
from engine.fusion import fuse_demons
state = make_game_state()
duban = make_demon("001", lane=0, owner=Side.PLAYER_1)
state = place_demon(state, duban)
duban = state.demons[-1]
flame = make_familiar_demon("102_1", lane=0, owner=Side.PLAYER_1)
state = place_demon(state, flame)
flame = state.demons[-1]
new_state = fuse_demons(state, duban, flame)
# Fused demon in state
fused = next((d for d in new_state.demons if d.unit_id == "001"), None)
Expected Postconditions
-
Resulting demon has current_hp = 6 (Duban base HP) + 9 (Purifying Flame fhp) = 15.
-
fused_bottom = "102_1".
-
is_fused = True.
-
Purifying Flame removed from field.
Assertions
assert fused is not None, "Fused Duban should still be on field as top card."
assert fused.is_fused is True, "Demon should be marked as fused."
assert fused.fused_bottom == "102_1", f"fused_bottom should be '102_1', got {fused.fused_bottom!r}"
# HP: Duban base=6, Purifying Flame fhp=9 → 15
duban_data = UNITS["001"]
flame_data = FAMILIARS["102_1"]
expected_hp = duban_data.hp + (flame_data.fhp or 0)
assert fused.current_hp == expected_hp, (
f"Fused HP should be {expected_hp} (Duban base {duban_data.hp} + Flame fhp {flame_data.fhp}). "
f"Got {fused.current_hp}."
)
# Purifying Flame removed from field
flame_on_field = [d for d in new_state.demons if d.unit_id == "102_1"]
assert len(flame_on_field) == 0, "Purifying Flame (bottom card) should be removed after fusion."