diff --git a/libs/RobotKit/CMakeLists.txt b/libs/RobotKit/CMakeLists.txt index bfc5f892df..2d03e705f8 100644 --- a/libs/RobotKit/CMakeLists.txt +++ b/libs/RobotKit/CMakeLists.txt @@ -42,8 +42,14 @@ if(${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") leka_unit_tests_sources( tests/RobotController_test_initializeComponents.cpp tests/RobotController_test_registerEvents.cpp - tests/RobotController_test_stateConnected.cpp - tests/RobotController_test_stateDisconnected.cpp + + tests/RobotController_test_raise.cpp + tests/RobotController_test_hardware.cpp + tests/RobotController_test_timeouts.cpp + tests/RobotController_test_behaviors.cpp + tests/RobotController_test_fileExchange.cpp + tests/RobotController_test_update.cpp + tests/RobotController_test_magicCard.cpp ) endif() endif() diff --git a/libs/RobotKit/tests/RobotController_test.h b/libs/RobotKit/tests/RobotController_test.h index f57b95a72b..840c2f6eaa 100644 --- a/libs/RobotKit/tests/RobotController_test.h +++ b/libs/RobotKit/tests/RobotController_test.h @@ -144,12 +144,6 @@ class RobotControllerTest : public testing::Test bool spy_isCharging_return_value = false; - void expectedCallsStopMotors() - { - EXPECT_CALL(mock_motor_left, stop()); - EXPECT_CALL(mock_motor_right, stop()); - } - void expectedCallsStopActuators() { EXPECT_CALL(mock_ledkit, stop).Times(AtLeast(1)); @@ -162,135 +156,50 @@ class RobotControllerTest : public testing::Test void expectedCallsInitializeComponents() { - { - InSequence seq; - - EXPECT_CALL(mbed_mock_gatt, addService).Times(8); - EXPECT_CALL(mbed_mock_gap, setEventHandler).Times(1); - EXPECT_CALL(mbed_mock_gatt, setEventHandler).Times(1); - - EXPECT_CALL(mock_mcu, getID).Times(1); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1); - - EXPECT_CALL(firmware_update, getCurrentVersion).Times(1); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1); - - Sequence set_serial_number_as_ble_device_name; - EXPECT_CALL(mock_mcu, getID).InSequence(set_serial_number_as_ble_device_name); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1).InSequence(set_serial_number_as_ble_device_name); - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).InSequence(set_serial_number_as_ble_device_name); - - expectedCallsStopMotors(); - - EXPECT_CALL(mock_ledkit, init); - - EXPECT_CALL(mock_videokit, initializeScreen).Times(1); - EXPECT_CALL(mock_lcd, turnOff).Times(1); - EXPECT_CALL(mock_videokit, stopVideo).Times(1); - - EXPECT_CALL(mock_ledkit, stop).Times(AtLeast(1)); - } + EXPECT_CALL(mock_mcu, getID).Times(AnyNumber()); + EXPECT_CALL(firmware_update, getCurrentVersion).Times(AnyNumber()); + + EXPECT_CALL(mbed_mock_gap, setEventHandler).Times(AnyNumber()); + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).Times(AnyNumber()); + EXPECT_CALL(mbed_mock_gatt, addService).Times(AnyNumber()); + EXPECT_CALL(mbed_mock_gatt, setEventHandler).Times(AnyNumber()); + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + EXPECT_CALL(mock_ledkit, init).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, initializeScreen).Times(AnyNumber()); + EXPECT_CALL(mock_lcd, turnOff).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); rc.initializeComponents(); } void expectedCallsRegisterEvents() { - { - InSequence seq; - - Sequence on_low_battery_sequence; - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - EXPECT_CALL(battery, isCharging) - .InSequence(on_low_battery_sequence) - .WillOnce(Return(spy_isCharging_return_value)); - if (spy_isCharging_return_value == false) { - EXPECT_CALL( - mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-empty-must_be_charged.jpg"})) - .Times(1); - expectedCallsStopMotors(); - } - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - - Sequence on_data_updated_sequence; - EXPECT_CALL(battery, level).InSequence(on_data_updated_sequence); - EXPECT_CALL(battery, isCharging).InSequence(on_data_updated_sequence); - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).InSequence(on_data_updated_sequence); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2).InSequence(on_data_updated_sequence); - - EXPECT_CALL(battery, onChargeDidStart).WillOnce(SaveArg<0>(&on_charge_did_start)); - - EXPECT_CALL(battery, onChargeDidStop).WillOnce(SaveArg<0>(&on_charge_did_stop)); - - { - InSequence event_setup_complete; - - if (spy_isCharging_return_value == true) { - expectedCallsTransitionSetupToCharging(); - } else { - expectedCallsTransitionSetupToIdle(); - } - } - } - - rc.registerEvents(); - } - - void expectedCallsTransitionSetupToIdle() - { - Sequence is_charging_sequence; - - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(spy_isCharging_return_value)); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); - - expectedCallsRunLaunchingBehavior(); - - Sequence on_idle_entry_sequence; - EXPECT_CALL(timeout_state_transition, onTimeout) - .InSequence(on_idle_entry_sequence) - .WillOnce(GetCallback(&on_sleep_timeout)); - EXPECT_CALL(timeout_state_transition, start).InSequence(on_idle_entry_sequence); - - EXPECT_CALL(mock_videokit, playVideoOnRepeat).InSequence(on_idle_entry_sequence); - EXPECT_CALL(mock_lcd, turnOn).Times(AtLeast(1)).InSequence(on_idle_entry_sequence); - } - - void expectedCallsTransitionSetupToCharging() - { - Sequence is_charging_sequence; - - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(spy_isCharging_return_value)); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); - - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(spy_isCharging_return_value)); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); + EXPECT_CALL(battery, isCharging).Times(AnyNumber()); + EXPECT_CALL(battery, level).Times(AnyNumber()); - expectedCallsRunLaunchingBehavior(); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, displayImage).Times(AnyNumber()); - Sequence start_deep_sleep_timeout_sequence; - EXPECT_CALL(timeout_state_transition, onTimeout).InSequence(start_deep_sleep_timeout_sequence); - EXPECT_CALL(timeout_state_transition, start).InSequence(start_deep_sleep_timeout_sequence); + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).Times(AnyNumber()); + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); - Sequence start_charging_behavior_sequence; - EXPECT_CALL(battery, level).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_videokit, displayImage).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_ledkit, start).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_lcd, turnOn).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(timeout_state_internal, onTimeout) - .InSequence(start_charging_behavior_sequence) - .WillOnce(GetCallback(&on_charging_start_timeout)); - EXPECT_CALL(timeout_state_internal, start).InSequence(start_charging_behavior_sequence); - } + { + EXPECT_CALL(timeout_state_transition, onTimeout).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, start).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, playVideoOnRepeat).Times(AnyNumber()); + EXPECT_CALL(mock_lcd, turnOn).Times(AnyNumber()); + } // ? On Idle entry - void expectedCallsRunLaunchingBehavior() - { - InSequence run_launching_behavior_sequence; + // Saved callback + EXPECT_CALL(battery, onChargeDidStart).WillOnce(SaveArg<0>(&on_charge_did_start)); + EXPECT_CALL(battery, onChargeDidStop).WillOnce(SaveArg<0>(&on_charge_did_stop)); - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-misc-splash_screen-large-400.jpg"})) - .Times(1); - EXPECT_CALL(mock_lcd, turnOn); + rc.registerEvents(); } void expectedCallsResetAutonomousActivitiesTimeout() diff --git a/libs/RobotKit/tests/RobotController_test_behaviors.cpp b/libs/RobotKit/tests/RobotController_test_behaviors.cpp new file mode 100644 index 0000000000..640e1b06d7 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_behaviors.cpp @@ -0,0 +1,232 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, runLaunchingBehavior) +{ + { + EXPECT_CALL(mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-misc-splash_screen-large-400.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, launching); + EXPECT_CALL(mock_lcd, turnOn); + + rc.runLaunchingBehavior(); +} + +TEST_F(RobotControllerTest, startWaitingBehavior) +{ + { + EXPECT_CALL( + mock_videokit, + playVideoOnRepeat( + std::filesystem::path {"/fs/home/vid/system/robot-system-idle-looking_top_right_left-no_eyebrows.avi"}, + _)); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, waiting); + EXPECT_CALL(mock_lcd, turnOn); + + rc.startWaitingBehavior(); +} + +TEST_F(RobotControllerTest, stopWaitingBehavior) +{ + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, stopVideo); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, stop); + + rc.stopWaitingBehavior(); +} + +TEST_F(RobotControllerTest, startWorkingBehavior) +{ + { + EXPECT_CALL(mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-face-smiling-slightly.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, working); + EXPECT_CALL(mock_lcd, turnOn); + + rc.startWorkingBehavior(); +} + +TEST_F(RobotControllerTest, startSleepingBehavior) +{ + { + EXPECT_CALL( + mock_videokit, + playVideoOnce( + std::filesystem::path {"/fs/home/vid/system/robot-system-sleep-yawn_then_sleep-no_eyebrows.avi"}, _)); + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::sleeping))); + + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, sleeping); + EXPECT_CALL(mock_lcd, turnOn); + + Sequence seq; + EXPECT_CALL(timeout_state_internal, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_sleeping_start_timeout)); + EXPECT_CALL(timeout_state_internal, start).InSequence(seq); + + rc.startSleepingBehavior(); + + EXPECT_CALL(mock_lcd, turnOff); + EXPECT_CALL(mock_ledkit, stop); + + on_sleeping_start_timeout(); +} + +TEST_F(RobotControllerTest, stopSleepingBehavior) +{ + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, stopVideo); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, stop); + + EXPECT_CALL(timeout_state_internal, stop); + + rc.stopSleepingBehavior(); +} + +TEST_F(RobotControllerTest, onChargingBehavior) +{ + auto level = uint8_t {}; + + level = 10; + { + EXPECT_CALL(mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-empty_red.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingEmpty); + rc.onChargingBehavior(level); + + level = 33; + { + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_1-red.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingLow); + rc.onChargingBehavior(level); + + level = 66; + { + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_2-orange.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingMedium); + rc.onChargingBehavior(level); + + level = 80; + { + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_3-green.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingHigh); + rc.onChargingBehavior(level); + + level = 100; + { + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_4-green.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingFull); + rc.onChargingBehavior(level); +} + +TEST_F(RobotControllerTest, startChargingBehavior) +{ + EXPECT_CALL(battery, level).WillRepeatedly(Return(0)); + { + EXPECT_CALL(mock_videokit, displayImage); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingEmpty); + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, blinkOnCharge); + EXPECT_CALL(mock_lcd, turnOn); + + Sequence seq; + EXPECT_CALL(timeout_state_internal, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_charging_start_timeout)); + EXPECT_CALL(timeout_state_internal, start).InSequence(seq); + + rc.startChargingBehavior(); + + EXPECT_CALL(mock_lcd, turnOff); + + on_charging_start_timeout(); +} + +TEST_F(RobotControllerTest, stopChargingBehavior) +{ + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, stopVideo); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, stop); + + EXPECT_CALL(timeout_state_internal, stop); + + rc.stopChargingBehavior(); +} + +TEST_F(RobotControllerTest, startConnectionBehaviorIsCharging) +{ + expectedCallsStopActuators(); + + Sequence seq; + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::ble_connection))).InSequence(seq); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, bleConnectionWithoutVideo); + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))).InSequence(seq); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, blinkOnCharge); + + EXPECT_CALL(mock_videokit, playVideoOnce).Times(0); + EXPECT_CALL(mock_lcd, turnOn).Times(0); + + rc.startConnectionBehavior(); +} + +TEST_F(RobotControllerTest, startConnectionBehaviorIsNotCharging) +{ + expectedCallsStopActuators(); + + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::ble_connection))); + EXPECT_CALL(mock_videokit, playVideoOnce); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, bleConnectionWithVideo); + + EXPECT_CALL(mock_lcd, turnOn); + + rc.startConnectionBehavior(); +} + +TEST_F(RobotControllerTest, startDisconnectionBehaviorCharging) +{ + expectedCallsStopActuators(); + + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))).Times(1); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, blinkOnCharge); + + rc.startDisconnectionBehavior(); +} + +TEST_F(RobotControllerTest, startDisconnectionBehaviorNotCharging) +{ + expectedCallsStopActuators(); + + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + + EXPECT_CALL(mock_ledkit, start).Times(0); + + rc.startDisconnectionBehavior(); +} diff --git a/libs/RobotKit/tests/RobotController_test_fileExchange.cpp b/libs/RobotKit/tests/RobotController_test_fileExchange.cpp new file mode 100644 index 0000000000..5896616e17 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_fileExchange.cpp @@ -0,0 +1,75 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, startFileExchangeIsCharging) +{ + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + + { + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, blinkOnCharge); + { + EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path {"/fs/home/img/system/robot-file_exchange.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, fileExchange); + EXPECT_CALL(mock_lcd, turnOn); + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + rc.startFileExchange(); +} + +TEST_F(RobotControllerTest, startFileExchangeIsNotCharging) +{ + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + + { + EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path {"/fs/home/img/system/robot-file_exchange.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, fileExchange); + EXPECT_CALL(mock_lcd, turnOn); + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + rc.startFileExchange(); +} + +TEST_F(RobotControllerTest, stopFileExchange) +{ + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + rc.stopFileExchange(); +} + +TEST_F(RobotControllerTest, isReadyToFileExchange) +{ + auto actual_is_ready = bool {}; + auto minimal_battery = uint8_t {25}; + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToFileExchange(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToFileExchange(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToFileExchange(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToFileExchange(); + EXPECT_TRUE(actual_is_ready); +} diff --git a/libs/RobotKit/tests/RobotController_test_hardware.cpp b/libs/RobotKit/tests/RobotController_test_hardware.cpp new file mode 100644 index 0000000000..69b1ab7819 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_hardware.cpp @@ -0,0 +1,76 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, stopActuators) +{ + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + rc.stopActuators(); +} + +TEST_F(RobotControllerTest, stopActuatorsAndLcd) +{ + EXPECT_CALL(mock_lcd, turnOff); + + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + rc.stopActuatorsAndLcd(); +} + +TEST_F(RobotControllerTest, suspendHardwareForDeepSleep) +{ + rc.suspendHardwareForDeepSleep(); +} + +TEST_F(RobotControllerTest, onChargeDidStart) +{ + { + EXPECT_CALL(battery, isCharging).WillOnce(Return(false)); + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)); + } // TODO: Expect raise call + + on_charge_did_start(); +} + +TEST_F(RobotControllerTest, onChargeDidStop) +{ + on_charge_did_stop(); + + // TODO: Expect raise call +} + +TEST_F(RobotControllerTest, isCharging) +{ + auto actual_is_charging = bool {}; + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_charging = rc.isCharging(); + EXPECT_TRUE(actual_is_charging); + + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_charging = rc.isCharging(); + EXPECT_FALSE(actual_is_charging); +} + +TEST_F(RobotControllerTest, isBleConnected) +{ + rc.isBleConnected(); + + // ? Cannot be tested +} diff --git a/libs/RobotKit/tests/RobotController_test_initializeComponents.cpp b/libs/RobotKit/tests/RobotController_test_initializeComponents.cpp index f3f0ff3b89..555b7f8d61 100644 --- a/libs/RobotKit/tests/RobotController_test_initializeComponents.cpp +++ b/libs/RobotKit/tests/RobotController_test_initializeComponents.cpp @@ -11,33 +11,26 @@ TEST_F(RobotControllerTest, initialization) TEST_F(RobotControllerTest, initializeComponents) { - { - InSequence seq; + EXPECT_CALL(mock_mcu, getID).Times(AtLeast(1)); - EXPECT_CALL(mbed_mock_gatt, addService).Times(8); - EXPECT_CALL(mbed_mock_gap, setEventHandler).Times(1); - EXPECT_CALL(mbed_mock_gatt, setEventHandler).Times(1); + EXPECT_CALL(firmware_update, getCurrentVersion); - EXPECT_CALL(mock_mcu, getID).Times(1); - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1); + EXPECT_CALL(mbed_mock_gap, setEventHandler); + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); - EXPECT_CALL(firmware_update, getCurrentVersion).Times(1); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1); + EXPECT_CALL(mbed_mock_gatt, addService).Times(8); + EXPECT_CALL(mbed_mock_gatt, setEventHandler); + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); - Sequence set_serial_number_as_ble_device_name; - EXPECT_CALL(mock_mcu, getID).InSequence(set_serial_number_as_ble_device_name); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(1).InSequence(set_serial_number_as_ble_device_name); - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).InSequence(set_serial_number_as_ble_device_name); + EXPECT_CALL(mock_ledkit, init); - expectedCallsStopMotors(); + EXPECT_CALL(mock_videokit, initializeScreen); + EXPECT_CALL(mock_lcd, turnOff); + EXPECT_CALL(mock_videokit, stopVideo); - EXPECT_CALL(mock_ledkit, init).Times(1); - - EXPECT_CALL(mock_videokit, initializeScreen).Times(1); - EXPECT_CALL(mock_lcd, turnOff).Times(1); - EXPECT_CALL(mock_videokit, stopVideo).Times(1); - } + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); rc.initializeComponents(); } diff --git a/libs/RobotKit/tests/RobotController_test_magicCard.cpp b/libs/RobotKit/tests/RobotController_test_magicCard.cpp new file mode 100644 index 0000000000..102d9332c3 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_magicCard.cpp @@ -0,0 +1,352 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +// ! TODO: Refactor with composite SM & CoreTimer mock + +TEST_F(RobotControllerTest, onMagicCardAvailableEmergencyStopDelayNotOver) +{ + expectedCallsResetAutonomousActivitiesTimeout(); + + rc.onMagicCardAvailable(MagicCard::emergency_stop); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableEmergencyStopDelayOver) +{ + auto delay_over = 11s; + + expectedCallsResetAutonomousActivitiesTimeout(); + + { + EXPECT_CALL(mock_lcd, turnOff); + + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + } // TODO: Expect raise call + + spy_kernel_addElapsedTimeToTickCount(delay_over); + + rc.onMagicCardAvailable(MagicCard::emergency_stop); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollNotInAutonomousActivityDelayNotOver) +{ + expectedCallsResetAutonomousActivitiesTimeout(); + + auto delay_not_over = 1000ms; + spy_kernel_addElapsedTimeToTickCount(delay_not_over); + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollNotInAutonomousActivityDelayOver) +{ + expectedCallsResetAutonomousActivitiesTimeout(); + + auto delay_over = 1001ms; + spy_kernel_addElapsedTimeToTickCount(delay_over); + + { + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + + EXPECT_CALL(mock_videokit, displayImage).Times(AnyNumber()); + } // TODO: Expect raise call + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollInAutonomousActivityIsNotPlayingDelayNotOver) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + expectedCallsResetAutonomousActivitiesTimeout(); + + auto delay_not_over = 2000ms; + spy_kernel_addElapsedTimeToTickCount(delay_not_over); + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollInAutonomousActivityIsNotPlayingDelayOver) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + // expectedCallsResetAutonomousActivitiesTimeout(); + + auto delay_over = 2001ms; + spy_kernel_addElapsedTimeToTickCount(delay_over); + + { + EXPECT_CALL(timeout_autonomous_activities, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, onTimeout).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, start).Times(AnyNumber()); + + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + + EXPECT_CALL(mock_videokit, displayImage).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_transition, onTimeout).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, start).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, playVideoOnRepeat); + EXPECT_CALL(mock_lcd, turnOn); + } // TODO: Expect raise call + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollInAutonomousActivityIsPlayingDelayNotOver) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + expectedCallsResetAutonomousActivitiesTimeout(); + + auto set_activitykit_is_playing = [this] { + const std::unordered_map activities {{MagicCard::number_10, &display_tag}}; + activitykit.registerActivities(activities); + EXPECT_CALL(mock_videokit, displayImage); + activitykit.start(MagicCard::number_10); + }; + set_activitykit_is_playing(); + + auto delay_not_over = 1000ms; + spy_kernel_addElapsedTimeToTickCount(delay_not_over); + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableDiceRollInAutonomousActivityIsPlayingDelayOver) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + // expectedCallsResetAutonomousActivitiesTimeout(); + + auto set_activitykit_is_playing = [this] { + const std::unordered_map activities {{MagicCard::number_10, &display_tag}}; + activitykit.registerActivities(activities); + EXPECT_CALL(mock_videokit, displayImage); + activitykit.start(MagicCard::number_10); + }; + set_activitykit_is_playing(); + + auto delay_over = 1001ms; + spy_kernel_addElapsedTimeToTickCount(delay_over); + + { + EXPECT_CALL(timeout_autonomous_activities, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, onTimeout).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, start).Times(AnyNumber()); + + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + + EXPECT_CALL(mock_videokit, displayImage).Times(AnyNumber()); + } // TODO: Expect raise call + + rc.onMagicCardAvailable(MagicCard::dice_roll); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableOtherNotInAutonomousActivityIsNotPlaying) +{ + expectedCallsResetAutonomousActivitiesTimeout(); + + rc.onMagicCardAvailable(MagicCard::number_10); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableOtherNotInAutonomousActivityIsPlaying) +{ + expectedCallsResetAutonomousActivitiesTimeout(); + + auto set_activitykit_is_playing = [this] { + const std::unordered_map activities {{MagicCard::number_10, &display_tag}}; + activitykit.registerActivities(activities); + EXPECT_CALL(mock_videokit, displayImage); + activitykit.start(MagicCard::number_10); + }; + set_activitykit_is_playing(); + + rc.onMagicCardAvailable(MagicCard::number_10); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableOtherInAutonomousActivityIsPlaying) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + expectedCallsResetAutonomousActivitiesTimeout(); + + auto set_activitykit_is_playing = [this] { + const std::unordered_map activities {{MagicCard::number_10, &display_tag}}; + activitykit.registerActivities(activities); + EXPECT_CALL(mock_videokit, displayImage); + activitykit.start(MagicCard::number_10); + }; + set_activitykit_is_playing(); + + rc.onMagicCardAvailable(MagicCard::number_10); +} + +TEST_F(RobotControllerTest, onMagicCardAvailableOtherInAutonomousActivityIsNotPlaying) +{ + rc.state_machine.set_current_states(lksm::state::autonomous_activities); + + expectedCallsResetAutonomousActivitiesTimeout(); + + rc.onMagicCardAvailable(MagicCard::number_10); +} + +TEST_F(RobotControllerTest, raiseEmergencyStop) +{ + { + EXPECT_CALL(mock_lcd, turnOff); + + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, stop).Times(AnyNumber()); + } // TODO: Expect raise call + + rc.raiseEmergencyStop(); +} + +TEST_F(RobotControllerTest, raiseEmergencyStopReboot) +{ + rc.state_machine.set_current_states(lksm::state::emergency_stopped); + + auto min_calls_to_reboot = 7; + for (int i = 0; i < min_calls_to_reboot; i++) { + rc.raiseEmergencyStop(); + } + + // ? Should expect "system_reset()" call +} + +TEST_F(RobotControllerTest, resetEmergencyStopCounter) +{ + rc.resetEmergencyStopCounter(); + + // nothing expected +} + +TEST_F(RobotControllerTest, startAutonomousActivityMode) +{ + EXPECT_CALL(mock_videokit, displayImage).Times(1); + EXPECT_CALL(mock_lcd, turnOn); + + rc.startAutonomousActivityMode(); +} + +TEST_F(RobotControllerTest, stopAutonomousActivityMode) +{ + EXPECT_CALL(timeout_autonomous_activities, stop); + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, stopVideo); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, stop); + + rc.stopAutonomousActivityMode(); +} + +TEST_F(RobotControllerTest, raiseAutonomousActivityModeRequested) +{ + { + EXPECT_CALL(mock_ears, hide).Times(AnyNumber()); + EXPECT_CALL(mock_belt, hide).Times(AnyNumber()); + EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); + EXPECT_CALL(mock_videokit, stopVideo).Times(AnyNumber()); + EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); + EXPECT_CALL(mock_motor_right, stop).Times(AnyNumber()); + + EXPECT_CALL(timeout_state_internal, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_state_transition, stop).Times(AnyNumber()); + EXPECT_CALL(timeout_autonomous_activities, stop).Times(AnyNumber()); + + EXPECT_CALL(mock_videokit, displayImage).Times(AnyNumber()); + } // TODO: Expect raise call + + rc.raiseAutonomousActivityModeRequested(); +} + +TEST_F(RobotControllerTest, raiseAutonomousActivityModeExited) +{ + rc.raiseAutonomousActivityModeExited(); + + // TODO: Expect raise call +} + +TEST_F(RobotControllerTest, resetAutonomousActivitiesTimeout) +{ + auto expected_duration = 600s; + + Sequence seq; + EXPECT_CALL(timeout_autonomous_activities, stop).InSequence(seq); + EXPECT_CALL(timeout_autonomous_activities, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_autonomous_activities_timeout)); + EXPECT_CALL(timeout_autonomous_activities, start(std::chrono::microseconds {expected_duration})).InSequence(seq); + + rc.resetAutonomousActivitiesTimeout(); +} + +TEST_F(RobotControllerTest, onAutonomousActivitiesTimeout) +{ + EXPECT_CALL(timeout_autonomous_activities, stop); + EXPECT_CALL(timeout_autonomous_activities, onTimeout) + .WillOnce(GetCallback(&on_autonomous_activities_timeout)); + EXPECT_CALL(timeout_autonomous_activities, start); + rc.resetAutonomousActivitiesTimeout(); + + on_autonomous_activities_timeout(); + + // TODO: Expect raise call +} + +TEST_F(RobotControllerTest, onTagActivated) +{ + auto onTagActivated = rfidkit.getCallback(); + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); + + expectedCallsResetAutonomousActivitiesTimeout(); + + onTagActivated(MagicCard::none); +} diff --git a/libs/RobotKit/tests/RobotController_test_raise.cpp b/libs/RobotKit/tests/RobotController_test_raise.cpp new file mode 100644 index 0000000000..98fe83e7c5 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_raise.cpp @@ -0,0 +1,12 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, raise) +{ + rc.raise(system::robot::sm::event::setup_complete {}); + + // nothing expected +} diff --git a/libs/RobotKit/tests/RobotController_test_registerEvents.cpp b/libs/RobotKit/tests/RobotController_test_registerEvents.cpp index ecf7320b8c..6fa9ed018c 100644 --- a/libs/RobotKit/tests/RobotController_test_registerEvents.cpp +++ b/libs/RobotKit/tests/RobotController_test_registerEvents.cpp @@ -4,192 +4,69 @@ #include "./RobotController_test.h" -TEST_F(RobotControllerTest, registerEventsBatteryIsNotCharging) +TEST_F(RobotControllerTest, registerEventsIsNotCharging) { - rc.state_machine.set_current_states(lksm::state::setup); + // TODO: Add EXPECT_CALL(mock_batterykit, onDataUpdated); + // TODO: Add EXPECT_CALL(mock_batterykit, onLowBattery); { - InSequence seq; - - Sequence on_low_battery_sequence; - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - EXPECT_CALL(battery, isCharging).InSequence(on_low_battery_sequence).WillOnce(Return(false)); - EXPECT_CALL( - mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-empty-must_be_charged.jpg"})); - expectedCallsStopMotors(); - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - - Sequence on_data_updated_sequence; - EXPECT_CALL(battery, level).InSequence(on_data_updated_sequence); - EXPECT_CALL(battery, isCharging).InSequence(on_data_updated_sequence).WillOnce(Return(false)); - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).InSequence(on_data_updated_sequence); - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2).InSequence(on_data_updated_sequence); - - EXPECT_CALL(battery, onChargeDidStart); - - EXPECT_CALL(battery, onChargeDidStop); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + EXPECT_CALL(battery, level).WillRepeatedly(Return(0)); { - InSequence event_setup_complete; + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path { + "/fs/home/img/system/robot-battery-empty-must_be_charged.jpg"})); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, lowBattery); + } // ? : on_data_updated callback call - Sequence is_charging_sequence; - - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(false)); + { + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); - - Sequence run_launching_behavior_sequence; - EXPECT_CALL( - mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-misc-splash_screen-large-400.jpg"})) - .InSequence(run_launching_behavior_sequence); - EXPECT_CALL(mock_lcd, turnOn).InSequence(run_launching_behavior_sequence); + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); + } // ? : on_low_battery callback call - EXPECT_CALL(timeout_state_transition, onTimeout); - EXPECT_CALL(timeout_state_transition, start); + } // TODO: Replace with EXPECT_CALL(mock_batterykit, startEventHandler); - EXPECT_CALL(mock_videokit, playVideoOnRepeat); - EXPECT_CALL(mock_lcd, turnOn); - } - } + EXPECT_CALL(battery, onChargeDidStart); + EXPECT_CALL(battery, onChargeDidStop); rc.registerEvents(); + + // TODO: Expect raise call } -TEST_F(RobotControllerTest, registerEventsBatteryIsCharging) +TEST_F(RobotControllerTest, registerEventsIsCharging) { - rc.state_machine.set_current_states(lksm::state::setup); + // TODO: Add EXPECT_CALL(mock_batterykit, onDataUpdated); + // TODO: Add EXPECT_CALL(mock_batterykit, onLowBattery); { - InSequence seq; - - Sequence on_low_battery_sequence; - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - EXPECT_CALL(battery, isCharging).InSequence(on_low_battery_sequence).WillOnce(Return(true)); - EXPECT_CALL(battery, level).InSequence(on_low_battery_sequence); - - Sequence on_data_updated_sequence; - EXPECT_CALL(battery, level).InSequence(on_data_updated_sequence); - EXPECT_CALL(battery, isCharging).InSequence(on_data_updated_sequence).WillOnce(Return(true)); - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).InSequence(on_data_updated_sequence); - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2).InSequence(on_data_updated_sequence); - EXPECT_CALL(mock_videokit, displayImage).InSequence(on_data_updated_sequence); - - EXPECT_CALL(battery, onChargeDidStart); - - EXPECT_CALL(battery, onChargeDidStop); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + EXPECT_CALL(battery, level).WillRepeatedly(Return(100)); { - InSequence event_setup_complete; - - Sequence is_charging_sequence; + { + EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path { + "/fs/home/img/system/robot-battery-charging-quarter_4-green.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingFull); + } // ? : on_data_updated callback call - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(true)); - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); - - EXPECT_CALL(battery, isCharging).InSequence(is_charging_sequence).WillOnce(Return(true)); + { + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).InSequence(is_charging_sequence); - - Sequence run_launching_behavior_sequence; - EXPECT_CALL( - mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-misc-splash_screen-large-400.jpg"})) - .InSequence(run_launching_behavior_sequence); - EXPECT_CALL(mock_lcd, turnOn).InSequence(run_launching_behavior_sequence); - - Sequence start_deep_sleep_timeout_sequence; - EXPECT_CALL(timeout_state_transition, onTimeout).InSequence(start_deep_sleep_timeout_sequence); - EXPECT_CALL(timeout_state_transition, start).InSequence(start_deep_sleep_timeout_sequence); - - Sequence start_charging_behavior_sequence; - EXPECT_CALL(battery, level).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_videokit, displayImage).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_ledkit, start).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(mock_lcd, turnOn).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(timeout_state_internal, onTimeout).InSequence(start_charging_behavior_sequence); - EXPECT_CALL(timeout_state_internal, start).InSequence(start_charging_behavior_sequence); - } - } + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); + } // ? : on_low_battery callback call - rc.registerEvents(); -} - -TEST_F(RobotControllerTest, registerOnFactoryResetNotificationCallback) -{ - MockFunction callback {}; + } // TODO: Replace with EXPECT_CALL(mock_batterykit, startEventHandler); - rc.registerOnFactoryResetNotificationCallback(callback.AsStdFunction()); + EXPECT_CALL(battery, onChargeDidStart); + EXPECT_CALL(battery, onChargeDidStop); - // nothing can be expected -} - -TEST_F(RobotControllerTest, onChargingBehaviorLevelBelow25) -{ - auto battery_level = 0; - - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-empty_red.jpg"})) - .Times(1); - - rc.onChargingBehavior(battery_level); -} - -TEST_F(RobotControllerTest, onChargingBehaviorLevelAbove25Below50) -{ - auto battery_level = 32; - - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_1-red.jpg"})) - .Times(1); - - rc.onChargingBehavior(battery_level); -} - -TEST_F(RobotControllerTest, onChargingBehaviorLevelAbove50Below75) -{ - auto battery_level = 62; - - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_2-orange.jpg"})) - .Times(1); - - rc.onChargingBehavior(battery_level); -} - -TEST_F(RobotControllerTest, onChargingBehaviorLevelAbove75Below90) -{ - auto battery_level = 88; - - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_3-green.jpg"})) - .Times(1); - - rc.onChargingBehavior(battery_level); -} - -TEST_F(RobotControllerTest, onChargingBehaviorLevelAbove90) -{ - auto battery_level = 94; - - EXPECT_CALL(mock_videokit, - displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-quarter_4-green.jpg"})) - .Times(1); - - rc.onChargingBehavior(battery_level); -} - -TEST_F(RobotControllerTest, onTagActivated) -{ - auto onTagActivated = rfidkit.getCallback(); - - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); - - expectedCallsResetAutonomousActivitiesTimeout(); + rc.registerEvents(); - onTagActivated(MagicCard::none); + // TODO: Expect raise call } diff --git a/libs/RobotKit/tests/RobotController_test_stateConnected.cpp b/libs/RobotKit/tests/RobotController_test_stateConnected.cpp deleted file mode 100644 index d1ef7e2e50..0000000000 --- a/libs/RobotKit/tests/RobotController_test_stateConnected.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Leka - LekaOS -// Copyright 2022 APF France handicap -// SPDX-License-Identifier: Apache-2.0 - -#include "./RobotController_test.h" - -TEST_F(RobotControllerTest, startConnectionBehaviorIsCharging) -{ - EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); - - expectedCallsStopActuators(); - Sequence on_ble_connection_sequence; - EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::ble_connection))) - .Times(1) - .InSequence(on_ble_connection_sequence); - EXPECT_CALL(mock_videokit, playVideoOnce).Times(0).InSequence(on_ble_connection_sequence); - EXPECT_CALL(mock_lcd, turnOn).Times(0).InSequence(on_ble_connection_sequence); - EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))) - .Times(1) - .InSequence(on_ble_connection_sequence); - - rc.startConnectionBehavior(); -} - -TEST_F(RobotControllerTest, startConnectionBehaviorIsNotCharging) -{ - EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); - - expectedCallsStopActuators(); - Sequence on_ble_connection_sequence; - EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::ble_connection))) - .Times(1) - .InSequence(on_ble_connection_sequence); - EXPECT_CALL(mock_videokit, playVideoOnce).Times(1).InSequence(on_ble_connection_sequence); - EXPECT_CALL(mock_lcd, turnOn).Times(1).InSequence(on_ble_connection_sequence); - - rc.startConnectionBehavior(); -} diff --git a/libs/RobotKit/tests/RobotController_test_stateDisconnected.cpp b/libs/RobotKit/tests/RobotController_test_stateDisconnected.cpp deleted file mode 100644 index fa7728576d..0000000000 --- a/libs/RobotKit/tests/RobotController_test_stateDisconnected.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Leka - LekaOS -// Copyright 2022 APF France handicap -// SPDX-License-Identifier: Apache-2.0 - -#include "./RobotController_test.h" - -TEST_F(RobotControllerTest, startDisconnectionBehaviorCharging) -{ - expectedCallsStopActuators(); - - EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); - EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))).Times(1); - - rc.startDisconnectionBehavior(); -} - -TEST_F(RobotControllerTest, startDisconnectionBehaviorNotCharging) -{ - expectedCallsStopActuators(); - - EXPECT_CALL(battery, isCharging).WillOnce(Return(false)); - EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::blink_on_charge))).Times(0); - - rc.startDisconnectionBehavior(); -} diff --git a/libs/RobotKit/tests/RobotController_test_timeouts.cpp b/libs/RobotKit/tests/RobotController_test_timeouts.cpp new file mode 100644 index 0000000000..b9462b7c21 --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_timeouts.cpp @@ -0,0 +1,123 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, startIdleTimeout) +{ + auto expected_duration = 600s; + + Sequence seq; + EXPECT_CALL(timeout_state_transition, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_idle_timeout)); + EXPECT_CALL(timeout_state_transition, start(std::chrono::microseconds {expected_duration})).InSequence(seq); + + rc.startIdleTimeout(); +} + +TEST_F(RobotControllerTest, onIdleTimeout) +{ + EXPECT_CALL(timeout_state_transition, onTimeout) + .WillOnce(GetCallback(&on_idle_timeout)); + EXPECT_CALL(timeout_state_transition, start); + rc.startIdleTimeout(); + + on_idle_timeout(); + + // TODO: Expect raise call +} + +TEST_F(RobotControllerTest, stopIdleTimeout) +{ + EXPECT_CALL(timeout_state_transition, stop); + + rc.stopIdleTimeout(); +} + +TEST_F(RobotControllerTest, startSleepTimeout) +{ + auto expected_duration = 60s; + + Sequence seq; + EXPECT_CALL(timeout_state_transition, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_sleep_timeout)); + EXPECT_CALL(timeout_state_transition, start(std::chrono::microseconds {expected_duration})).InSequence(seq); + + rc.startSleepTimeout(); +} + +TEST_F(RobotControllerTest, onSleepTimeout) +{ + EXPECT_CALL(timeout_state_transition, onTimeout) + .WillOnce(GetCallback(&on_sleep_timeout)); + EXPECT_CALL(timeout_state_transition, start); + rc.startSleepTimeout(); + + { + EXPECT_CALL(timeout_state_transition, stop); + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL(mock_videokit, stopVideo); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, stop); + + EXPECT_CALL(timeout_state_transition, onTimeout); + EXPECT_CALL(timeout_state_transition, start); + { + { + EXPECT_CALL(mock_videokit, playVideoOnce); + EXPECT_CALL(mock_ledkit, start(isSameAnimation(&led::animation::sleeping))); + + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, sleeping); + EXPECT_CALL(mock_lcd, turnOn); + + EXPECT_CALL(timeout_state_internal, onTimeout); + EXPECT_CALL(timeout_state_internal, start); + } + } // TODO: Expect raise call + + on_sleep_timeout(); +} + +TEST_F(RobotControllerTest, stopSleepTimeout) +{ + EXPECT_CALL(timeout_state_transition, stop); + + rc.stopSleepTimeout(); +} + +TEST_F(RobotControllerTest, startDeepSleepTimeout) +{ + auto expected_duration = 600s; + + Sequence seq; + EXPECT_CALL(timeout_state_transition, onTimeout) + .InSequence(seq) + .WillOnce(GetCallback(&on_deep_sleep_timeout)); + EXPECT_CALL(timeout_state_transition, start(std::chrono::microseconds {expected_duration})).InSequence(seq); + + rc.startDeepSleepTimeout(); +} + +TEST_F(RobotControllerTest, onDeepSleepTimeout) +{ + EXPECT_CALL(timeout_state_transition, onTimeout) + .WillOnce(GetCallback(&on_deep_sleep_timeout)); + EXPECT_CALL(timeout_state_transition, start); + rc.startDeepSleepTimeout(); + + on_deep_sleep_timeout(); + + // TODO: Expect raise call +} + +TEST_F(RobotControllerTest, stopDeepSleepTimeout) +{ + EXPECT_CALL(timeout_state_transition, stop); + + rc.stopDeepSleepTimeout(); +} diff --git a/libs/RobotKit/tests/RobotController_test_update.cpp b/libs/RobotKit/tests/RobotController_test_update.cpp new file mode 100644 index 0000000000..ad97c98b1e --- /dev/null +++ b/libs/RobotKit/tests/RobotController_test_update.cpp @@ -0,0 +1,99 @@ +// Leka - LekaOS +// Copyright 2023 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "./RobotController_test.h" + +TEST_F(RobotControllerTest, isReadyToUpdateVersionIsNotAvailable) +{ + auto actual_is_ready = bool {}; + auto minimal_battery = uint8_t {25}; + + EXPECT_CALL(firmware_update, isVersionAvailable).WillRepeatedly(Return(false)); + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); +} + +TEST_F(RobotControllerTest, isReadyToUpdateVersionIsAvailable) +{ + auto actual_is_ready = bool {}; + auto minimal_battery = uint8_t {25}; + + EXPECT_CALL(firmware_update, isVersionAvailable).WillRepeatedly(Return(true)); + + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(AnyNumber()); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_FALSE(actual_is_ready); + + EXPECT_CALL(battery, level).WillRepeatedly(Return(minimal_battery + 1)); + EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); + actual_is_ready = rc.isReadyToUpdate(); + EXPECT_TRUE(actual_is_ready); +} + +TEST_F(RobotControllerTest, applyUpdateCallbackNotRegistered) +{ + EXPECT_CALL(firmware_update, loadFirmware).WillOnce(Return(false)); + rc.applyUpdate(); + + EXPECT_CALL(firmware_update, loadFirmware).WillOnce(Return(true)); + rc.applyUpdate(); +} + +TEST_F(RobotControllerTest, applyUpdateCallbackRegistered) +{ + MockFunction callback; + rc.registerOnUpdateLoadedCallback(callback.AsStdFunction()); + + EXPECT_CALL(firmware_update, loadFirmware).WillOnce(Return(false)); + EXPECT_CALL(callback, Call).Times(0); + rc.applyUpdate(); + + EXPECT_CALL(firmware_update, loadFirmware).WillOnce(Return(true)); + EXPECT_CALL(callback, Call).Times(1); + rc.applyUpdate(); +} + +TEST_F(RobotControllerTest, registerOnFactoryResetNotificationCallback) +{ + MockFunction callback {}; + + rc.registerOnFactoryResetNotificationCallback(callback.AsStdFunction()); + + // nothing expected +}