diff --git a/src/Gui/InputHint.h b/src/Gui/InputHint.h index bcd38dcc3a..0fd39676cb 100644 --- a/src/Gui/InputHint.h +++ b/src/Gui/InputHint.h @@ -253,6 +253,16 @@ struct InputHint InputSequence(const std::initializer_list keys) : keys(keys) {} + + friend bool operator==(const InputSequence& lhs, const InputSequence& rhs) + { + return lhs.keys == rhs.keys; + } + + friend bool operator!=(const InputSequence& lhs, const InputSequence& rhs) + { + return !(lhs == rhs); + } }; /** @@ -270,8 +280,41 @@ struct InputHint * @brief List of sequences to be substituted. */ std::list sequences; + + friend bool operator==(const InputHint& lhs, const InputHint& rhs) + { + return lhs.message == rhs.message && lhs.sequences == rhs.sequences; + } + + friend bool operator!=(const InputHint& lhs, const InputHint& rhs) + { + return !(lhs == rhs); + } }; +template +struct StateHints +{ + T state; + std::list hints; +}; + +template +using HintTable = std::vector>; + +template +static std::list lookupHints(T state, HintTable table, const std::list& fallback = {}) { + const auto stateMatches = [&state](const StateHints& entry) { + return entry.state == state; + }; + + if (auto it = std::ranges::find_if(table, stateMatches); it != table.end()) { + return it->hints; + } + + return fallback; +} + } // namespace Gui #endif // GUI_INPUTHINT_H diff --git a/tests/src/Gui/CMakeLists.txt b/tests/src/Gui/CMakeLists.txt index bf6b87d0fd..7b18d4662d 100644 --- a/tests/src/Gui/CMakeLists.txt +++ b/tests/src/Gui/CMakeLists.txt @@ -5,12 +5,12 @@ add_executable(Gui_tests_run StyleParameters/StyleParametersApplicationTest.cpp StyleParameters/ParserTest.cpp StyleParameters/ParameterManagerTest.cpp + InputHintTest.cpp ) # Qt tests setup_qt_test(QuantitySpinBox) - target_link_libraries(Gui_tests_run PRIVATE GTest::gtest_main GTest::gmock_main diff --git a/tests/src/Gui/InputHintTest.cpp b/tests/src/Gui/InputHintTest.cpp new file mode 100644 index 0000000000..fa1f511f9b --- /dev/null +++ b/tests/src/Gui/InputHintTest.cpp @@ -0,0 +1,85 @@ +#include + +#include "Gui/InputHint.h" + +using namespace Gui; +using enum InputHint::UserInput; + +class InputHintTest: public ::testing::Test +{ +protected: + enum class State : std::uint8_t + { + SeekFirst, + SeekSecond + }; + + enum class Method : std::uint8_t + { + FirstMethod, + SecondMethod + }; + + using StateMethod = std::pair; + + // Constants for hints + static const InputHint firstHint; + static const InputHint secondHint; + static const InputHint firstMethodHint; + static const InputHint secondMethodHint; + static const InputHint thirdMethodHint; + static const InputHint fourthMethodHint; +}; + +// Define the constants +const InputHint InputHintTest::firstHint = {QString("First hint"), {{KeySpace}}}; +const InputHint InputHintTest::secondHint = {QString("Second hint"), {{KeyEnter}}}; +const InputHint InputHintTest::firstMethodHint = {QString("First method hint"), {{KeyA}}}; +const InputHint InputHintTest::secondMethodHint = {QString("Second method hint"), {{KeyB}}}; +const InputHint InputHintTest::thirdMethodHint = {QString("Third method hint"), {{KeyC}}}; +const InputHint InputHintTest::fourthMethodHint = {QString("Fourth method hint"), {{KeyD}}}; + +TEST_F(InputHintTest, LookupHintsSimpleState) +{ + // Arrange + std::list hintsSeekFirst = {firstHint}; + std::list hintsSeekSecond = {secondHint}; + + HintTable table = {{.state = State::SeekFirst, .hints = hintsSeekFirst}, + {.state = State::SeekSecond, .hints = hintsSeekSecond}}; + + // Act + auto resultFirst = lookupHints(State::SeekFirst, table); + auto resultSecond = lookupHints(State::SeekSecond, table); + + // Assert + EXPECT_EQ(resultFirst, hintsSeekFirst); + EXPECT_EQ(resultSecond, hintsSeekSecond); +} + +TEST_F(InputHintTest, LookupHintsPairState) +{ + // Arrange + std::list firstFirstHints = {firstMethodHint}; + std::list firstSecondHints = {secondMethodHint}; + std::list secondFirstHints = {thirdMethodHint}; + std::list secondSecondHints = {fourthMethodHint}; + + HintTable table = { + {.state = {State::SeekFirst, Method::FirstMethod}, .hints = firstFirstHints}, + {.state = {State::SeekFirst, Method::SecondMethod}, .hints = firstSecondHints}, + {.state = {State::SeekSecond, Method::FirstMethod}, .hints = secondFirstHints}, + {.state = {State::SeekSecond, Method::SecondMethod}, .hints = secondSecondHints}}; + + // Act + auto resultFirstFirst = lookupHints({State::SeekFirst, Method::FirstMethod}, table); + auto resultFirstSecond = lookupHints({State::SeekFirst, Method::SecondMethod}, table); + auto resultSecondFirst = lookupHints({State::SeekSecond, Method::FirstMethod}, table); + auto resultSecondSecond = lookupHints({State::SeekSecond, Method::SecondMethod}, table); + + // Assert + EXPECT_EQ(resultFirstFirst, firstFirstHints); + EXPECT_EQ(resultFirstSecond, firstSecondHints); + EXPECT_EQ(resultSecondFirst, secondFirstHints); + EXPECT_EQ(resultSecondSecond, secondSecondHints); +}