def test_stuck_door():
    # Door is closed
    driver = StuckDoorDriver(0.4, 0.15)
    door_model = Door("Test door", driver, 0.5, 0.1, 0.2)

    # The door is closed and idle
    assert door_model.state.__class__.__name__ == 'ClosedState'
    assert door_model.intent.__class__.__name__ == 'IdleIntent'
    # Set "open" intent
    door_model.set_intent('Open');
    assert door_model.intent.__class__.__name__ == 'OpenIntent'
    assert driver.door_signal == True
    time.sleep(0.175)
    # After 0.15 seconds, the door stucks in lower position
    assert driver.door_signal == False
    assert door_model.state.__class__.__name__ == 'ClosedState'
    assert door_model.intent.__class__.__name__ == 'OpenIntent'
    assert driver.lower_limit_switch == True
    assert driver.upper_limit_switch == False
    time.sleep(0.05)
    # After 0.2 seconds, the door should be triggered once more
    assert driver.door_signal == True
    time.sleep(0.2)
    # After 0.4 seconds, the door should be in transit to upper position
    assert driver.door_signal == False
    assert door_model.state.__class__.__name__ == 'OpeningState'
    assert door_model.intent.__class__.__name__ == 'OpenIntent'
    assert driver.lower_limit_switch == False
    assert driver.upper_limit_switch == False
def test_opening_timeout():
    # Door is closed
    mock_driver = MockDriver()
    door_model = Door("Test door", mock_driver, 0.2, 0.1, 0.2)
    door_model.set_new_state('Opening')

    # The upper switch will not close before timeout is reached
    time.sleep(0.3)

    assert door_model.state.__class__.__name__ == "IntermediateState"
def test_intermediate_to_open():
    # Door is closed
    mock_driver = MockDriver()
    door_model = Door("Test door", mock_driver, 0.2, 0.1, 0.2)
    door_model.set_new_state('Intermediate')

    # The upper switch closed
    mock_driver.upper_limit_switch = True
    signal(SIGNAL_UPPER_SWITCH_CHANGED).send(mock_driver)

    assert door_model.state.__class__.__name__ == "OpenState"
def test_closing():
    # Door is closed
    mock_driver = MockDriver()
    door_model = Door("Test door", mock_driver, 0.2, 0.1, 0.2)
    door_model.set_new_state('Closing')

    # The lower switch closed
    mock_driver.lower_limit_switch = True
    signal(SIGNAL_LOWER_SWITCH_CHANGED).send(mock_driver)

    assert door_model.state.__class__.__name__ == "ClosedState"
    time.sleep(0.3)
    assert door_model.state.__class__.__name__ == "ClosedState"
def test_start_opening():
    # Door is closed
    mock_driver = MockDriver()
    mock_driver.lower_limit_switch = True
    door_model = Door("Test door", mock_driver, 1, 0.1, 0.2)

    # trigger move
    door_model.start_door_signal()

    assert mock_driver.door_signal == True

    # The lower switch opened
    mock_driver.lower_limit_switch = False
    signal(SIGNAL_LOWER_SWITCH_CHANGED).send(mock_driver)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "OpeningState"
def test_start_closing_timeout():
    # Door is open
    mock_driver = MockDriver()
    mock_driver.upper_limit_switch = True
    door_model = Door("Test door", mock_driver, 1, 0.1, 0.2)

    # trigger move
    door_model.start_door_signal()

    assert mock_driver.door_signal == True

    # The upper switch will not open for 200 ms
    # This should expire the trigger timer (100 ms)
    time.sleep(0.2)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "OpenState"
def test_start_opening_timeout():
    # Door is closed
    mock_driver = MockDriver()
    mock_driver.lower_limit_switch = True
    door_model = Door("Test door", mock_driver, 1, 0.1, 0.2)

    # trigger move
    door_model.start_door_signal()

    assert mock_driver.door_signal == True

    # The lower switch will not open for two seconds
    # This should expire the trigger timer
    time.sleep(0.2)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "ClosedState"
def test_perfect_door():
    # Door is closed
    driver = PerfectDoorDriver(0.4, 0.15)
    door_model = Door("Test door", driver, 0.5, 0.1, 0.2)

    # The door is closed and idle
    assert door_model.state.__class__.__name__ == 'ClosedState'
    assert door_model.intent.__class__.__name__ == 'IdleIntent'
    # Set "open" intent
    door_model.set_intent('Open');
    assert door_model.intent.__class__.__name__ == 'OpenIntent'
    assert driver.door_signal == True
    time.sleep(0.2)
    # After 0.15 seconds, the door should be in transit to upper position
    assert driver.door_signal == False
    assert door_model.state.__class__.__name__ == 'OpeningState'
    assert door_model.intent.__class__.__name__ == 'OpenIntent'
    assert driver.lower_limit_switch == False
    assert driver.upper_limit_switch == False
    time.sleep(0.25)
    # After 0.4 seconds, the door should be in upper position
    assert door_model.state.__class__.__name__ == 'OpenState'
    assert door_model.intent.__class__.__name__ == 'IdleIntent'
    assert driver.upper_limit_switch == True

    # The door is open and idle
    # Set "close" intent
    door_model.set_intent('Close');
    assert door_model.intent.__class__.__name__ == 'CloseIntent'
    assert driver.door_signal == True
    time.sleep(0.2)
    # After 0.15 seconds, the door should be in transit to lower position
    assert driver.door_signal == False
    assert door_model.state.__class__.__name__ == 'ClosingState'
    assert door_model.intent.__class__.__name__ == 'CloseIntent'
    assert driver.lower_limit_switch == False
    assert driver.upper_limit_switch == False
    time.sleep(0.25)
    # After 0.4 seconds, the door should be in lower position
    assert door_model.state.__class__.__name__ == 'ClosedState'
    assert door_model.intent.__class__.__name__ == 'IdleIntent'
    assert driver.lower_limit_switch == True
def test_state_closed_error():
    # Door is closed
    mock_driver = MockDriver()
    mock_driver.lower_limit_switch = True
    door_model = Door("Test door", mock_driver, 1, 0.1, 0.3)

    # start intent
    door_model.set_intent("Open");

    assert mock_driver.door_signal == True

    logger.debug("The lower switch didn't open, the door stuck")
    time.sleep(0.2)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "ClosedState"
    mock_driver.door_signal_toggled = False

    logger.debug("The intent have to restart the door after timeout")
    time.sleep(0.2)
    assert mock_driver.door_signal_toggled == True

    logger.debug("The intent have restart the door after timeout")

    logger.debug("Now the lower switch opened")
    mock_driver.lower_limit_switch = False
    signal(SIGNAL_LOWER_SWITCH_CHANGED).send(mock_driver)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "OpeningState"

    logger.debug("The upper switch closed")
    mock_driver.upper_limit_switch = True
    signal(SIGNAL_UPPER_SWITCH_CHANGED).send(mock_driver)

    assert door_model.state.__class__.__name__ == "OpenState"
    assert door_model.intent.__class__.__name__ == "IdleIntent"
def test_state_closed():
    # Door is closed
    mock_driver = MockDriver()
    mock_driver.lower_limit_switch = True
    door_model = Door("Test door", mock_driver, 1, 0.1, 0.2)

    # start intent
    door_model.set_intent("Open");

    assert mock_driver.door_signal == True

    logger.debug("The lower switch opened")
    mock_driver.lower_limit_switch = False
    signal(SIGNAL_LOWER_SWITCH_CHANGED).send(mock_driver)

    assert mock_driver.door_signal == False
    assert door_model.state.__class__.__name__ == "OpeningState"

    logger.debug("The upper switch closed")
    mock_driver.upper_limit_switch = True
    signal(SIGNAL_UPPER_SWITCH_CHANGED).send(mock_driver)

    assert door_model.state.__class__.__name__ == "OpenState"
    assert door_model.intent.__class__.__name__ == "IdleIntent"