def test_shoot_boulder(control):
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    ba.shooter.up_to_speed = MagicMock(return_value=True)
    setup_tunables(ba, "boulder_automation")

    def _on_step(tm, step):
        if step == 1:
            ba.shoot_boulder()
            assert ba.current_state == "pre_fire"
        elif step == 2:
            # Requires a step for the test for up_to_speed to return true
            assert ba.shooter.shoot.called
        elif step <= 20:
            assert ba.current_state == "firing"
            assert ba.is_executing
            assert ba.intake.intake.called
        if step > 30:  # Should inject ball for around 25 steps - 0.5s
            assert not ba.is_executing
            assert ba.intake.stop.called
            assert ba.shooter.stop.called
        if step == 40:
            return False
        ba.execute()  # Magicbot normally does this for us
        return True

    c = StepController(control, _on_step)
    control.run_test(c)
    assert c.step == 40
def test_shoot_boulder(control):
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    ba.shooter.up_to_speed = MagicMock(return_value=True)
    setup_tunables(ba, "boulder_automation")

    def _on_step(tm, step):
        if step == 1:
            ba.shoot_boulder()
            assert ba.current_state == "pre_fire"
        elif step == 2:
            # Requires a step for the test for up_to_speed to return true
            assert ba.shooter.shoot.called
        elif step <= 20:
            assert ba.current_state == "firing"
            assert ba.is_executing
            assert ba.intake.intake.called
        if step > 30:  # Should inject ball for around 25 steps - 0.5s
            assert not ba.is_executing
            assert ba.intake.stop.called
            assert ba.shooter.stop.called
        if step == 40:
            return False
        ba.execute()  # Magicbot normally does this for us
        return True

    c = StepController(control, _on_step)
    control.run_test(c)
    assert c.step == 40
def test_backdrive_manual():
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    setup_tunables(ba, "boulder_automation")

    ba.engage("backdrive_manual")
    ba.execute()
    assert ba.intake.backdrive_slow.called
    assert ba.shooter.backdrive_recovery.called
    ba.done()
def test_backdrive_manual():
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    setup_tunables(ba, "boulder_automation")

    ba.engage("backdrive_manual")
    ba.execute()
    assert ba.intake.backdrive_slow.called
    assert ba.shooter.backdrive_recovery.called
    ba.done()
def test_intake_boulder(control):
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    ba.intake.up_to_speed = MagicMock(return_value=True)
    ba.intake.ball_detected = MagicMock(return_value=True)
    ba.intake.slowing = MagicMock(return_value=True)
    ba.intake.pinned = MagicMock(return_value=True)
    setup_tunables(ba, "boulder_automation")

    def _on_step(tm, step):
        if step == 1:
            ba.intake_boulder()
            assert ba.current_state == "pre_intake"
        elif step == 2:
            assert ba.intake.intake.called
            assert ba.current_state == "intaking"
        elif step == 3:
            pass
        elif step <= 29:
            assert ba.shooter.backdrive.called
            assert ba.current_state == "intaking_contact"
        elif step == 30:
            assert ba.current_state == "pinning"
        elif step == 31:
            assert ba.shooter.backdrive.called
            assert ba.intake.backdrive_pin.called
            assert ba.current_state == "pinned"
        elif step == 32:
            assert not ba.current_state
        else:
            return False
        ba.execute()  # Magicbot normally does this for us
        return True

    c = StepController(control, _on_step)
    control.run_test(c)
    assert c.step == 33
def test_intake_boulder(control):
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    ba.intake.up_to_speed = MagicMock(return_value=True)
    ba.intake.ball_detected = MagicMock(return_value=True)
    ba.intake.slowing = MagicMock(return_value=True)
    ba.intake.pinned = MagicMock(return_value=True)
    setup_tunables(ba, "boulder_automation")
    def _on_step(tm, step):
        if step == 1:
            ba.intake_boulder()
            assert ba.current_state == "pre_intake"
        elif step == 2:
            assert ba.intake.intake.called
            assert ba.current_state == "intaking"
        elif step == 3:
            pass
        elif step <= 29:
            assert ba.shooter.backdrive.called
            assert ba.current_state == "intaking_contact"
        elif step == 30:
            assert ba.current_state == "pinning"
        elif step == 31:
            assert ba.shooter.backdrive.called
            assert ba.intake.backdrive_pin.called
            assert ba.current_state == "pinned"
        elif step == 32:
            assert not ba.current_state
        else:
            return False
        ba.execute()  # Magicbot normally does this for us
        return True
    c = StepController(control, _on_step)
    control.run_test(c)
    assert c.step == 33
def test_toggle_shoot_boulder():
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    setup_tunables(ba, "boulder_automation")

    assert not ba.current_state
    ba.toggle_shoot_boulder()
    ba.execute()
    assert ba.current_state
    ba.toggle_shoot_boulder()
    ba.execute()
    assert not ba.current_state
def test_toggle_shoot_boulder():
    ba = BoulderAutomation()
    ba.intake = MagicMock()
    ba.shooter = MagicMock()
    setup_tunables(ba, "boulder_automation")

    assert not ba.current_state
    ba.toggle_shoot_boulder()
    ba.execute()
    assert ba.current_state
    ba.toggle_shoot_boulder()
    ba.execute()
    assert not ba.current_state