// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include #include #include #include #include SCENARIO("Input Processor tests") { using bsp::KeyCodes; const auto FractionKey = KeyCodes::FnLeft; const auto PlusKey = KeyCodes::JoystickUp; const auto MinusKey = KeyCodes::JoystickDown; const auto MultiplicationKey = KeyCodes::JoystickLeft; const auto DivisionKey = KeyCodes::JoystickRight; GIVEN("An empty input") { utils::setDisplayLanguage("English"); auto inputField = gui::Text{}; auto processor = calc::InputProcessorText{gsl::make_strict_not_null(&inputField)}; inputField.setInputMode(new InputMode({InputMode::digit})); inputField.inputCallback = [&processor](gui::Item &, const gui::InputEvent &event) { return processor.handle(event); }; auto shortPressEvent = [](KeyCodes code) -> gui::InputEvent { return gui::InputEvent{RawKey{RawKey::State::Released, code, 0, 0}, gui::InputEvent::State::keyReleasedShort, static_cast(code)}; }; auto longPressEvent = [](KeyCodes code) -> gui::InputEvent { return gui::InputEvent{RawKey{RawKey::State::Released, code, 0, 0}, gui::InputEvent::State::keyReleasedLong, static_cast(code)}; }; auto passEvent = [&](const gui::InputEvent &event) { inputField.onInput(event); }; auto passShortKeyPress = [&](KeyCodes code) { passEvent(shortPressEvent(code)); }; auto passLongKeyPress = [&](KeyCodes code) { passEvent(longPressEvent(code)); }; auto passShortKeyPresses = [&](const std::vector &codes) { for (const auto &code : codes) { passShortKeyPress(code); } }; auto passLongKeyPresses = [&](const std::vector &codes) { for (const auto &code : codes) { passLongKeyPress(code); } }; THEN("The text is empty") { REQUIRE(inputField.isEmpty()); AND_WHEN("We press enter") { passShortKeyPress(KeyCodes::JoystickEnter); THEN("Nothing happens") { REQUIRE(inputField.isEmpty()); } } } WHEN("We press 1234") { passShortKeyPresses( {KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3, KeyCodes::NumericKey4}); THEN("Text is 1234") { REQUIRE(inputField.getText() == "1234"); } AND_WHEN("We use the clear method") { processor.clear(); THEN("The input is cleared") { REQUIRE(inputField.isEmpty()); } } AND_WHEN("We use the # key") { passShortKeyPresses({3, KeyCodes::NumericKeyPnd}); THEN("The input is deleted") { REQUIRE(inputField.getText() == "1"); } } AND_WHEN("We long press #") { passLongKeyPress(KeyCodes::NumericKeyPnd); THEN("The input is cleared") { REQUIRE(inputField.isEmpty()); } } AND_WHEN("We continue to type") { passShortKeyPresses( {KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3, KeyCodes::NumericKey4}); THEN("The input is limited to predefined limit") { REQUIRE(inputField.getText().length() == calc::limits::MaxInputLength); } AND_WHEN("We try do delete input") { passShortKeyPresses({4, KeyCodes::NumericKeyPnd}); THEN("Input is deleted") { REQUIRE(inputField.getText() == "123"); } } AND_WHEN("We try to compute") { passShortKeyPresses({MinusKey, KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3, KeyCodes::JoystickEnter}); THEN("We are able to") { REQUIRE(inputField.getText() == "1234000"); } } } } WHEN("We enter leading zeros") { passShortKeyPresses({KeyCodes::NumericKey0, KeyCodes::NumericKey0, KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3}); THEN("They are ignored") { REQUIRE(inputField.getText() == "123"); } } WHEN("We start input with the fraction key") { passShortKeyPresses({FractionKey, KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3}); THEN("Is is ignored") { REQUIRE(inputField.getText() == "123"); } } WHEN("We use the fraction key") { passShortKeyPresses({KeyCodes::NumericKey0, FractionKey, KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3}); THEN("A fraction is entered") { REQUIRE(inputField.getText() == "0.123"); } AND_WHEN("We use the fraction key again") { passShortKeyPresses({FractionKey, KeyCodes::NumericKey4, FractionKey, KeyCodes::NumericKey5}); THEN("It is ignored") { REQUIRE(inputField.getText() == "0.12345"); } } AND_WHEN("We try to enter more than 5 decimals") { passShortKeyPresses({KeyCodes::NumericKey4, KeyCodes::NumericKey5, KeyCodes::NumericKey6, KeyCodes::NumericKey7, KeyCodes::NumericKey8, KeyCodes::NumericKey9}); THEN("The input is truncated") { REQUIRE(inputField.getText() == "0.12345"); } AND_WHEN("We try do delete input") { passShortKeyPresses({3, KeyCodes::NumericKeyPnd}); THEN("Input is deleted") { REQUIRE(inputField.getText() == "0.12"); } } AND_WHEN("We try to do operations") { passShortKeyPresses({PlusKey, KeyCodes::NumericKey2, KeyCodes::JoystickEnter}); THEN("It is posible") { REQUIRE(inputField.getText() == "2.12345"); } } } } WHEN("We enter zero") { passShortKeyPress(KeyCodes::NumericKey0); THEN("Zero is shown") { REQUIRE(inputField.getText() == "0"); } AND_WHEN("We enter following zeros") { passShortKeyPresses({5, KeyCodes::NumericKey0}); THEN("They are ignored") { REQUIRE(inputField.getText() == "0"); } } AND_WHEN("We press enter") { passShortKeyPress(KeyCodes::JoystickEnter); THEN("Nothing happens") { REQUIRE(inputField.getText() == "0"); } } } WHEN("We enter a number") { passShortKeyPresses({KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3}); AND_WHEN("We long press joy buttons") { passLongKeyPresses({KeyCodes::JoystickDown, KeyCodes::JoystickUp, KeyCodes::JoystickLeft, KeyCodes::JoystickRight, KeyCodes::JoystickEnter}); THEN("They are ignored") { REQUIRE(inputField.getText() == "123"); } } AND_WHEN("We press plus") { passShortKeyPress(PlusKey); THEN("Input ends with plus sign") { REQUIRE(inputField.getText() == "123+"); } AND_WHEN("We enter a number") { passShortKeyPresses({KeyCodes::NumericKey4, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("Previos input is hidden") { REQUIRE(inputField.getText() == "456"); } AND_WHEN("We press enter") { passShortKeyPress(KeyCodes::JoystickEnter); THEN("The result is computed") { REQUIRE(inputField.getText() == "579"); } } } AND_WHEN("We enter a negative numer") { passShortKeyPresses({MinusKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("Previous input is hidden and typed number is shown") { REQUIRE(inputField.getText() == "56"); } AND_WHEN("We press enter") { passShortKeyPress(KeyCodes::JoystickEnter); THEN("The result is computed") { REQUIRE(inputField.getText() == "67"); } } AND_WHEN("We delete the input") { passShortKeyPresses({2, KeyCodes::NumericKeyPnd}); THEN("Input is deleted") { REQUIRE(inputField.getText().empty()); } AND_WHEN("We press # again") { passShortKeyPress(KeyCodes::NumericKeyPnd); THEN("Previous input is restored") { REQUIRE(inputField.getText() == "123-"); } } } } AND_WHEN("We press the fraction key") { passShortKeyPresses({FractionKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("It replaces plus") { REQUIRE(inputField.getText() == "123.56"); } } AND_WHEN("We press a different operation key") { passShortKeyPress(MultiplicationKey); THEN("It replaces plus") { REQUIRE(inputField.getText() == "123×"); } } AND_WHEN("We enter a proper fraction") { passShortKeyPresses( {KeyCodes::NumericKey4, FractionKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("It is shown") { REQUIRE(inputField.getText() == "4.56"); } AND_WHEN("We press the fraction key again") { passShortKeyPresses( {KeyCodes::NumericKey4, FractionKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("It is ignored") { REQUIRE(inputField.getText() == "4.56456"); } } AND_WHEN("We try to enter more than 5 decimals") { passShortKeyPresses({KeyCodes::NumericKey4, KeyCodes::NumericKey5, KeyCodes::NumericKey6, KeyCodes::NumericKey7, KeyCodes::NumericKey8, KeyCodes::NumericKey9}); THEN("The input is truncated") { REQUIRE(inputField.getText() == "4.56456"); } } } } AND_WHEN("We press minus") { passShortKeyPress(MinusKey); THEN("Input ends with minus sign") { REQUIRE(inputField.getText() == "123-"); } } AND_WHEN("We press multiplication") { passShortKeyPress(MultiplicationKey); THEN("Input ends with multiplication sign") { REQUIRE(inputField.getText() == "123×"); } } AND_WHEN("We press division") { passShortKeyPress(DivisionKey); THEN("Input ends with division sign") { REQUIRE(inputField.getText() == "123÷"); } } } WHEN("We do BIG math") { passShortKeyPresses({5, KeyCodes::NumericKey9}); passShortKeyPress(MultiplicationKey); passShortKeyPresses({5, KeyCodes::NumericKey9}); passShortKeyPress(KeyCodes::JoystickEnter); THEN("Output contains exponent") { REQUIRE(inputField.getText() == "9.9998e9"); } AND_WHEN("We start typing") { passShortKeyPresses({KeyCodes::NumericKey4, MinusKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("Input is cleared before typing") { REQUIRE(inputField.getText() == "56"); } } AND_WHEN("We invoke any operation") { passShortKeyPress(KeyCodes::JoystickUp); THEN("We should see") { REQUIRE(inputField.getText() == "9.9998e9+"); } AND_WHEN("We proceed to type more input") { passShortKeyPresses({KeyCodes::NumericKey1, KeyCodes::NumericKey5, KeyCodes::NumericKey6}); THEN("We should see") { REQUIRE(inputField.getText() == "156"); } } } } WHEN("We enter an equation") { passShortKeyPresses({3, KeyCodes::NumericKey1}); passShortKeyPress(MultiplicationKey); passShortKeyPress(KeyCodes::NumericKey4); AND_WHEN("We press another operation") { passShortKeyPress(PlusKey); THEN("The previous operation is computed first") { REQUIRE(inputField.getText() == "444+"); } AND_WHEN("We continue input") { passShortKeyPress(MinusKey); passShortKeyPresses({3, KeyCodes::NumericKey1}); passShortKeyPress(KeyCodes::JoystickEnter); THEN("The following equation is computed properly") { REQUIRE(inputField.getText() == "333"); } } } } WHEN("We enter the minus key") { passShortKeyPress(MinusKey); AND_WHEN("We press another minus") { passShortKeyPress(MinusKey); THEN("We should see only one minus sign") { REQUIRE(inputField.getText() == "-"); } AND_WHEN("We continue inputting minus sign") { passShortKeyPress(MinusKey); THEN("We still should see only one minus sign") { REQUIRE(inputField.getText() == "-"); } } } AND_WHEN("We input a number") { passShortKeyPress(KeyCodes::NumericKey5); THEN("We should see a '-5' value") { REQUIRE(inputField.getText() == "-5"); } AND_WHEN("We input another minus sign") { passShortKeyPress(MinusKey); THEN("We should see a '-5-' value") { REQUIRE(inputField.getText() == "-5-"); } AND_WHEN("We input another minus sign") { passShortKeyPress(MinusKey); THEN("We should still see a '-5-' value") { REQUIRE(inputField.getText() == "-5-"); } } } } } } }