diff options
Diffstat (limited to 'src/gui/test')
| -rw-r--r-- | src/gui/test/HotkeyTests.cpp | 320 | ||||
| -rw-r--r-- | src/gui/test/KeySequenceTests.cpp | 145 | ||||
| -rw-r--r-- | src/gui/test/Utils.h | 38 | ||||
| -rw-r--r-- | src/gui/test/main.cpp | 23 |
4 files changed, 526 insertions, 0 deletions
diff --git a/src/gui/test/HotkeyTests.cpp b/src/gui/test/HotkeyTests.cpp new file mode 100644 index 0000000..7607dfb --- /dev/null +++ b/src/gui/test/HotkeyTests.cpp @@ -0,0 +1,320 @@ +/* barrier -- mouse and keyboard sharing utility + Copyright (C) 2021 Povilas Kanapickas <povilas@radix.lt> + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "../src/Hotkey.h" +#include <gtest/gtest.h> +#include "Utils.h" + +#include <QtCore/QSettings> +#include <QtCore/QTextStream> + +struct TestAction +{ + Action::ActionType type = Action::keyDown; + std::vector<TestKey> keys; + std::vector<std::string> type_screen_names; + std::string screen_name; + Action::SwitchDirection switch_direction; + Action::LockCursorMode lock_cursor_mode; + + static TestAction createKeyAction(Action::ActionType type, const std::vector<TestKey>& keys, + const std::vector<std::string>& type_screen_names = {}) + { + TestAction action; + action.type = Action::keyDown; + action.keys = keys; + action.type_screen_names = type_screen_names; + return action; + } + + static TestAction createKeyDown(const std::vector<TestKey>& keys, + const std::vector<std::string>& type_screen_names = {}) + { + return createKeyAction(Action::keyDown, keys, type_screen_names); + } + + static TestAction createKeyUp(const std::vector<TestKey>& keys, + const std::vector<std::string>& type_screen_names = {}) + { + return createKeyAction(Action::keyUp, keys, type_screen_names); + } + + static TestAction createKeyStroke(const std::vector<TestKey>& keys, + const std::vector<std::string>& type_screen_names = {}) + { + return createKeyAction(Action::keystroke, keys, type_screen_names); + } + + static TestAction createSwitchToScreen(const std::string& screen_name) + { + TestAction action; + action.type = Action::switchToScreen; + action.screen_name = screen_name; + return action; + } + + static TestAction createToggleScreen() + { + TestAction action; + action.type = Action::toggleScreen; + return action; + } + + static TestAction createSwitchInDirection(Action::SwitchDirection switch_direction) + { + TestAction action; + action.type = Action::switchInDirection; + action.switch_direction = switch_direction; + return action; + } + + static TestAction createLockCursorToScreen(Action::LockCursorMode lock_cursor_mode) + { + TestAction action; + action.type = Action::lockCursorToScreen; + action.lock_cursor_mode = lock_cursor_mode; + return action; + } +}; + +struct TestHotKey +{ + std::vector<TestKey> keys; + std::vector<TestAction> actions; +}; + +namespace { + + Action createAction(const TestAction& test_action) + { + Action action; + action.setType(test_action.type); + + switch (test_action.type) { + case Action::keyDown: + case Action::keyUp: + case Action::keystroke: { + KeySequence sequence; + for (auto key : test_action.keys) { + sequence.appendKey(key.key, key.modifier); + } + action.setKeySequence(sequence); + for (const auto& type_screen_name : test_action.type_screen_names) { + action.appendTypeScreenName(QString::fromStdString(type_screen_name)); + } + break; + } + case Action::switchToScreen: + action.setSwitchScreenName(QString::fromStdString(test_action.screen_name)); + break; + case Action::toggleScreen: + break; + case Action::switchInDirection: + action.setSwitchDirection(test_action.switch_direction); + break; + case Action::lockCursorToScreen: + action.setLockCursorMode(test_action.lock_cursor_mode); + break; + } + return action; + } + + Hotkey createHotkey(const TestHotKey& test_hotkey) + { + Hotkey hotkey; + KeySequence sequence; + for (auto key : test_hotkey.keys) { + sequence.appendKey(key.key, key.modifier); + } + hotkey.setKeySequence(sequence); + + for (auto action : test_hotkey.actions) { + hotkey.appendAction(createAction(action)); + } + return hotkey; + } + + std::string hotkeyToStringViaTextStream(const Hotkey& hotkey) + { + QString result; + QTextStream stream{&result}; + stream << hotkey; + return result.toStdString(); + } +} // namespace + +void doHotkeyLoadSaveTest(const TestHotKey& test_hotkey) +{ + auto filename = getTemporaryFilename(); + + Hotkey hotkey_before, hotkey_after; + { + QSettings settings(filename, QSettings::NativeFormat); + + hotkey_before = createHotkey(test_hotkey); + + settings.beginGroup("test"); + hotkey_before.saveSettings(settings); + settings.endGroup(); + } + { + QSettings settings(filename, QSettings::NativeFormat); + + settings.beginGroup("test"); + hotkey_after.loadSettings(settings); + settings.endGroup(); + + ASSERT_EQ(hotkey_before.keySequence().sequence(), hotkey_after.keySequence().sequence()); + ASSERT_EQ(hotkey_before.keySequence().modifiers(), hotkey_after.keySequence().modifiers()); + + const auto& actions_before = hotkey_before.actions(); + const auto& actions_after = hotkey_after.actions(); + + ASSERT_EQ(actions_before.size(), actions_after.size()); + for (int i = 0; i < actions_before.size(); ++i) { + const auto& action_before = actions_before[i]; + const auto& action_after = actions_after[i]; + + ASSERT_EQ(action_before.keySequence().sequence(), action_after.keySequence().sequence()); + ASSERT_EQ(action_before.keySequence().modifiers(), action_after.keySequence().modifiers()); + ASSERT_EQ(action_before.type(), action_after.type()); + ASSERT_EQ(action_before.typeScreenNames(), action_after.typeScreenNames()); + ASSERT_EQ(action_before.switchScreenName(), action_after.switchScreenName()); + ASSERT_EQ(action_before.switchDirection(), action_after.switchDirection()); + ASSERT_EQ(action_before.lockCursorMode(), action_after.lockCursorMode()); + ASSERT_EQ(action_before.activeOnRelease(), action_after.activeOnRelease()); + ASSERT_EQ(action_before.haveScreens(), action_after.haveScreens()); + } + } + + QFile::remove(filename); +} + +TEST(HotkeyLoadSaveTests, Empty) +{ + TestHotKey hotkey; + doHotkeyLoadSaveTest(hotkey); +} + +TEST(HotkeyLoadSaveTests, KeysNoActions) +{ + TestHotKey hotkey = {{{Qt::Key_A, Qt::NoModifier}, {Qt::Key_B, Qt::NoModifier}}, {}}; + doHotkeyLoadSaveTest(hotkey); +} + +TEST(HotkeyLoadSaveTests, CommaKeyNoActions) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_Comma, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, {}}; + doHotkeyLoadSaveTest(hotkey); +} + +TEST(HotkeyLoadSaveTests, KeysSingleAction) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + { + TestAction::createKeyDown({{Qt::Key_Z, Qt::NoModifier}}) + } + }; + doHotkeyLoadSaveTest(hotkey); +} + +TEST(HotkeyLoadSaveTests, KeysMultipleAction) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + { + TestAction::createKeyDown({{Qt::Key_Z, Qt::NoModifier}}), + TestAction::createSwitchToScreen("test_screen") + } + }; + doHotkeyLoadSaveTest(hotkey); +} + +TEST(HotkeyToTexStreamTests, Empty) +{ + TestHotKey hotkey; + ASSERT_EQ(hotkeyToStringViaTextStream(createHotkey(hotkey)), ""); +} + +TEST(HotkeyToTexStreamTests, KeysNoActions) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + {} + }; + ASSERT_EQ(hotkeyToStringViaTextStream(createHotkey(hotkey)), ""); +} + +TEST(HotkeyToTexStreamTests, KeysSingleAction) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + {} + }; + ASSERT_EQ(hotkeyToStringViaTextStream(createHotkey(hotkey)), ""); +} + + +TEST(HotkeyToTexStreamTests, KeysCommaSingleAction) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_Comma, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + { + TestAction::createKeyDown({{Qt::Key_Z, Qt::NoModifier}}) + } + }; + ASSERT_EQ(hotkeyToStringViaTextStream(createHotkey(hotkey)), + "\tkeystroke(a+Comma+b) = keyDown(z,*)\n"); +} + +TEST(HotkeyToTexStreamTests, KeysMultipleAction) +{ + TestHotKey hotkey = { + { + {Qt::Key_A, Qt::NoModifier}, + {Qt::Key_B, Qt::NoModifier} + }, + { + TestAction::createKeyDown({{Qt::Key_Z, Qt::NoModifier}}), + TestAction::createSwitchToScreen("test_screen") + } + }; + ASSERT_EQ(hotkeyToStringViaTextStream(createHotkey(hotkey)), + "\tkeystroke(a+b) = keyDown(z,*), switchToScreen(test_screen)\n"); +} diff --git a/src/gui/test/KeySequenceTests.cpp b/src/gui/test/KeySequenceTests.cpp new file mode 100644 index 0000000..9fa9273 --- /dev/null +++ b/src/gui/test/KeySequenceTests.cpp @@ -0,0 +1,145 @@ +/* barrier -- mouse and keyboard sharing utility + Copyright (C) 2021 Povilas Kanapickas <povilas@radix.lt> + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "../src/KeySequence.h" +#include "Utils.h" +#include <gtest/gtest.h> +#include <cstdio> + +#include <QtCore/QFile> +#include <QtCore/QSettings> +#include <QtCore/QTemporaryFile> + +namespace { + + auto s_key_sequence_test_keys = { + Qt::Key_Space, + Qt::Key_Escape, + Qt::Key_Tab, + Qt::Key_Backtab, + Qt::Key_Backspace, + Qt::Key_Return, + Qt::Key_Insert, + Qt::Key_Delete, + Qt::Key_Pause, + Qt::Key_Print, + Qt::Key_SysReq, + Qt::Key_Home, + Qt::Key_End, + Qt::Key_Left, + Qt::Key_Up, + Qt::Key_Right, + Qt::Key_Down, + Qt::Key_Comma, + Qt::Key_Semicolon, + Qt::Key_PageUp, + Qt::Key_PageDown, + Qt::Key_CapsLock, + Qt::Key_NumLock, + Qt::Key_ScrollLock, + Qt::Key_Help, + Qt::Key_Enter, + Qt::Key_Clear, + Qt::Key_Back, + Qt::Key_Forward, + Qt::Key_Stop, + Qt::Key_Refresh, + Qt::Key_VolumeDown, + Qt::Key_VolumeMute, + Qt::Key_VolumeUp, + Qt::Key_MediaPlay, + Qt::Key_MediaStop, + Qt::Key_MediaPrevious, + Qt::Key_MediaNext, + Qt::Key_HomePage, + Qt::Key_Favorites, + Qt::Key_Search, + Qt::Key_Standby, + Qt::Key_LaunchMail, + Qt::Key_LaunchMedia, + Qt::Key_Launch0, + Qt::Key_Launch1, + Qt::Key_Select, + }; + + std::string keySequenceToString(const std::vector<TestKey>& key_pairs) + { + KeySequence sequence; + for (auto key_pair : key_pairs) { + sequence.appendKey(key_pair.key, key_pair.modifier); + } + return sequence.toString().toStdString(); + } +} // namespace + +class KeySequenceLoadSaveTestFixture : + public ::testing::TestWithParam<Qt::Key> {}; + +TEST_P(KeySequenceLoadSaveTestFixture, SupportsSpecialSymbols) +{ + int key = GetParam(); + + auto filename = getTemporaryFilename(); + + { + QSettings settings(filename, QSettings::NativeFormat); + KeySequence sequence; + + sequence.appendKey(key, 0); + sequence.appendKey(key, 0); + settings.beginGroup("test"); + sequence.saveSettings(settings); + settings.endGroup(); + } + { + QSettings settings(filename, QSettings::NativeFormat); + KeySequence sequence; + + settings.beginGroup("test"); + sequence.loadSettings(settings); + settings.endGroup(); + + const auto& data = sequence.sequence(); + ASSERT_EQ(data.size(), 2); + ASSERT_EQ(data[0], key); + ASSERT_EQ(data[1], key); + } + + QFile::remove(filename); +} + +INSTANTIATE_TEST_CASE_P( + KeySequenceLoadSaveTests, + KeySequenceLoadSaveTestFixture, + ::testing::ValuesIn(s_key_sequence_test_keys)); + +TEST(KeySequenceTests, ToString) +{ + ASSERT_EQ(keySequenceToString({{Qt::Key_Menu, Qt::MetaModifier}}), + "Meta"); + ASSERT_EQ(keySequenceToString({{Qt::Key_A, 0}, {Qt::Key_B, 0}}), + "a+b"); + ASSERT_EQ(keySequenceToString({{Qt::Key_A, 0}, {Qt::Key_Comma, 0}, {Qt::Key_B, 0}}), + "a+Comma+b"); + ASSERT_EQ(keySequenceToString({{Qt::Key_A, 0}, {Qt::Key_Semicolon, 0}, {Qt::Key_B, 0}}), + "a+Semicolon+b"); + ASSERT_EQ(keySequenceToString({{Qt::Key_A, 0}, {Qt::Key_Shift, Qt::ShiftModifier}, + {Qt::Key_0, Qt::ShiftModifier}}), + "a+Shift+0"); + ASSERT_EQ(keySequenceToString({{Qt::Key_A, 0}, {Qt::Key_Control, Qt::ControlModifier}, + {Qt::Key_0, Qt::ControlModifier}}), + "a+Control+0"); +} diff --git a/src/gui/test/Utils.h b/src/gui/test/Utils.h new file mode 100644 index 0000000..da66ce7 --- /dev/null +++ b/src/gui/test/Utils.h @@ -0,0 +1,38 @@ +/* barrier -- mouse and keyboard sharing utility + Copyright (C) 2021 Povilas Kanapickas <povilas@radix.lt> + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef BARRIER_GUI_TEST_UTILS_H +#define BARRIER_GUI_TEST_UTILS_H + +#include <QtCore/QFile> +#include <QtCore/QTemporaryFile> + +struct TestKey +{ + int key = 0; + int modifier = Qt::NoModifier; + + TestKey(int key, int modifier) : key{key}, modifier{modifier} {} +}; + +inline QString getTemporaryFilename() +{ + QTemporaryFile temp_file; + temp_file.open(); + return temp_file.fileName(); +} + +#endif // BARRIER_GUI_TEST_UTILS_H diff --git a/src/gui/test/main.cpp b/src/gui/test/main.cpp new file mode 100644 index 0000000..b57dd76 --- /dev/null +++ b/src/gui/test/main.cpp @@ -0,0 +1,23 @@ +/* barrier -- mouse and keyboard sharing utility + Copyright (C) 2021 Povilas Kanapickas <povilas@radix.lt> + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <gtest/gtest.h> + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return (RUN_ALL_TESTS() == 1) ? 1 : 0; +} |
