ajhahn.de
← the-way-out
Python 82 lines
"""PressurePlate charge/trip behaviour and Lever single-shot toggle.
Both use lazy-built surfaces, so they need a video context — provided
by conftest's dummy SDL setup."""
import pygame

from interactables import Lever, PressurePlate
from settings import PLATE_TRIGGER_DELAY


def _plate():
    return PressurePlate((0, 0), [pygame.sprite.Group()], gate_group=("ord", 0))


def _lever():
    return Lever((0, 0), [pygame.sprite.Group()], gate_group=("ord", 0))


# --- PressurePlate -------------------------------------------------------

def test_plate_starts_idle():
    p = _plate()
    assert p.activated is False
    assert p.charge == 0.0


def test_plate_charge_accumulates_below_threshold():
    p = _plate()
    half = PLATE_TRIGGER_DELAY / 2
    tripped = p.step_on(half)
    assert tripped is False
    assert p.activated is False
    assert p.charge == half


def test_plate_trips_at_threshold_exactly_once():
    p = _plate()
    # Two equal halves exactly hit PLATE_TRIGGER_DELAY — that's the
    # tripping frame, and step_on returns True only on it.
    half = PLATE_TRIGGER_DELAY / 2
    assert p.step_on(half) is False
    assert p.step_on(half) is True
    assert p.activated is True
    # Subsequent ticks must not re-fire — the level opens the gate
    # exactly once.
    assert p.step_on(0.1) is False


def test_plate_stays_tripped_after_step_off():
    p = _plate()
    p.step_on(PLATE_TRIGGER_DELAY)        # trip it
    p.step_off()
    assert p.activated is True            # still down


def test_step_off_resets_charge_only_while_untripped():
    p = _plate()
    p.step_on(PLATE_TRIGGER_DELAY / 3)
    p.step_off()
    assert p.charge == 0.0
    # After tripping, charge is frozen (the plate stays down forever),
    # so step_off must be a no-op on the charge.
    p.step_on(PLATE_TRIGGER_DELAY)        # trip
    charge_after_trip = p.charge
    p.step_off()
    assert p.charge == charge_after_trip


# --- Lever ---------------------------------------------------------------

def test_lever_starts_inactive():
    lev = _lever()
    assert lev.activated is False


def test_lever_use_toggles_once_and_returns_true_only_first_time():
    lev = _lever()
    assert lev.use() is True
    assert lev.activated is True
    # Second pull is a no-op: returns False, stays activated.
    assert lev.use() is False
    assert lev.activated is True