File indexing completed on 2024-12-01 12:32:57
0001 /* 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> 0004 */ 0005 0006 #include "keysequencerecordertest.h" 0007 0008 #include "keysequencerecorder.h" 0009 0010 #include <QSignalSpy> 0011 #include <QTest> 0012 #include <QWindow> 0013 0014 QTEST_MAIN(KeySequenceRecorderTest) 0015 0016 void KeySequenceRecorderTest::initTestCase() 0017 { 0018 m_window = new QWindow; 0019 } 0020 0021 void KeySequenceRecorderTest::cleanupTestCase() 0022 { 0023 delete m_window; 0024 } 0025 0026 void KeySequenceRecorderTest::testValidWindow() 0027 { 0028 KeySequenceRecorder recorder(nullptr); 0029 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0030 0031 recorder.startRecording(); 0032 QCOMPARE(recordingSpy.count(), 0); 0033 QVERIFY(!recorder.isRecording()); 0034 0035 recorder.setWindow(m_window); 0036 recorder.startRecording(); 0037 QCOMPARE(recordingSpy.count(), 2); 0038 QVERIFY(recorder.isRecording()); 0039 } 0040 0041 void KeySequenceRecorderTest::testRecording() 0042 { 0043 KeySequenceRecorder recorder(m_window); 0044 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0045 QSignalSpy sequenceSpy(&recorder, &KeySequenceRecorder::currentKeySequenceChanged); 0046 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0047 0048 recorder.startRecording(); 0049 QVERIFY(recorder.isRecording()); 0050 QCOMPARE(recordingSpy.count(), 1); 0051 QCOMPARE(sequenceSpy.count(), 1); 0052 0053 QTest::keyClick(m_window, Qt::Key_A, Qt::ControlModifier); 0054 QVERIFY(recorder.isRecording()); 0055 QCOMPARE(recordingSpy.count(), 1); 0056 QCOMPARE(sequenceSpy.count(), 4); // two key events + modifier release 0057 QCOMPARE(resultSpy.count(), 0); 0058 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0059 0060 QTest::qWait(800); 0061 QCOMPARE(sequenceSpy.count(), 4); 0062 QCOMPARE(recordingSpy.count(), 2); 0063 QVERIFY(!recorder.isRecording()); 0064 QCOMPARE(resultSpy.count(), 1); 0065 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0066 QCOMPARE(resultSpy.takeFirst().at(0).value<QKeySequence>(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0067 } 0068 0069 void KeySequenceRecorderTest::testModifiers() 0070 { 0071 KeySequenceRecorder recorder(m_window); 0072 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0073 QSignalSpy sequenceSpy(&recorder, &KeySequenceRecorder::currentKeySequenceChanged); 0074 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0075 0076 recorder.startRecording(); 0077 QCOMPARE(sequenceSpy.count(), 1); 0078 QCOMPARE(recordingSpy.count(), 1); 0079 QVERIFY(recorder.isRecording()); 0080 0081 QTest::keyPress(m_window, Qt::Key_Control); 0082 QCOMPARE(sequenceSpy.count(), 2); 0083 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::ControlModifier)); 0084 0085 // Releasing a different key because when releasing Key_Meta, QTest sends a KeyRelease event 0086 // with MetaModifier even though modifieres should be empty 0087 QTest::keyRelease(m_window, Qt::Key_A, Qt::NoModifier); 0088 QCOMPARE(sequenceSpy.count(), 3); 0089 QCOMPARE(recorder.currentKeySequence(), QKeySequence()); 0090 QCOMPARE(recordingSpy.count(), 1); 0091 QVERIFY(recorder.isRecording()); 0092 0093 QTest::qWait(800); 0094 QVERIFY(recorder.isRecording()); 0095 0096 QTest::keyPress(m_window, Qt::Key_Control); 0097 QCOMPARE(sequenceSpy.count(), 4); 0098 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::ControlModifier)); 0099 0100 QTest::keyPress(m_window, Qt::Key_Alt, Qt::ControlModifier); 0101 QCOMPARE(sequenceSpy.count(), 6); // QTest sends two key events, one for each modifier 0102 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::AltModifier | Qt::ControlModifier)); 0103 0104 QCOMPARE(resultSpy.count(), 0); // modifierless not allowed 0105 } 0106 0107 void KeySequenceRecorderTest::testModifierless() 0108 { 0109 KeySequenceRecorder recorder(m_window); 0110 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0111 QSignalSpy sequenceSpy(&recorder, &KeySequenceRecorder::currentKeySequenceChanged); 0112 0113 recorder.startRecording(); 0114 QVERIFY(recorder.isRecording()); 0115 QCOMPARE(sequenceSpy.count(), 1); 0116 0117 recorder.setModifierlessAllowed(false); 0118 QTest::keyPress(m_window, Qt::Key_A); 0119 QTest::qWait(800); 0120 QVERIFY(recorder.isRecording()); 0121 QCOMPARE(sequenceSpy.count(), 1); 0122 QCOMPARE(resultSpy.count(), 0); 0123 QCOMPARE(recorder.currentKeySequence(), QKeySequence()); 0124 0125 recorder.setModifierlessAllowed(true); 0126 QTest::keyClick(m_window, Qt::Key_A); 0127 QTest::qWait(800); 0128 QVERIFY(!recorder.isRecording()); 0129 QCOMPARE(sequenceSpy.count(), 2); 0130 QCOMPARE(resultSpy.count(), 1); 0131 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A)); 0132 } 0133 0134 void KeySequenceRecorderTest::testModifierOnly() 0135 { 0136 KeySequenceRecorder recorder(m_window); 0137 recorder.setModifierOnlyAllowed(true); 0138 recorder.setModifierlessAllowed(true); 0139 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0140 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0141 QSignalSpy sequenceSpy(&recorder, &KeySequenceRecorder::currentKeySequenceChanged); 0142 0143 recorder.startRecording(); 0144 QVERIFY(recorder.isRecording()); 0145 QCOMPARE(sequenceSpy.count(), 1); 0146 0147 QTest::keyClick(m_window, Qt::Key_Shift); 0148 recordingSpy.wait(); 0149 QVERIFY(!recorder.isRecording()); 0150 QCOMPARE(sequenceSpy.count(), 3); 0151 QCOMPARE(resultSpy.count(), 1); 0152 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_Shift)); 0153 } 0154 0155 void KeySequenceRecorderTest::testModifierOnlyDisabled() 0156 { 0157 KeySequenceRecorder recorder(m_window); 0158 recorder.setModifierOnlyAllowed(false); 0159 recorder.setModifierlessAllowed(true); 0160 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0161 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0162 QSignalSpy sequenceSpy(&recorder, &KeySequenceRecorder::currentKeySequenceChanged); 0163 0164 recorder.startRecording(); 0165 QVERIFY(recorder.isRecording()); 0166 QCOMPARE(sequenceSpy.count(), 1); 0167 0168 QTest::keyClick(m_window, Qt::Key_Shift); 0169 recordingSpy.wait(); 0170 QVERIFY(recorder.isRecording()); 0171 recorder.cancelRecording(); 0172 QCOMPARE(sequenceSpy.count(), 3); 0173 QCOMPARE(resultSpy.count(), 0); 0174 QCOMPARE(recorder.currentKeySequence(), QKeySequence()); 0175 } 0176 0177 void KeySequenceRecorderTest::testMultiKeyAllowed() 0178 { 0179 KeySequenceRecorder recorder(m_window); 0180 QSignalSpy recordingSpy(&recorder, &KeySequenceRecorder::recordingChanged); 0181 QSignalSpy resultSpy(&recorder, &KeySequenceRecorder::gotKeySequence); 0182 0183 recorder.startRecording(); 0184 0185 recorder.setMultiKeyShortcutsAllowed(true); 0186 int keys[4] = {0}; 0187 for (int i = 0; i < 4; ++i) { 0188 QVERIFY(recorder.isRecording()); 0189 QCOMPARE(recordingSpy.count(), 1); 0190 QCOMPARE(resultSpy.count(), 0); 0191 keys[i] = Qt::Key_A | Qt::ControlModifier; 0192 QKeySequence result(keys[0], keys[1], keys[2], keys[3]); 0193 QTest::keyPress(m_window, Qt::Key_A, Qt::ControlModifier); 0194 QTest::keyRelease(m_window, Qt::Key_A, Qt::ControlModifier); 0195 QCOMPARE(recorder.currentKeySequence(), QKeySequence(keys[0], keys[1], keys[2], keys[3])); 0196 } 0197 QVERIFY(!recorder.isRecording()); 0198 QCOMPARE(recordingSpy.count(), 2); 0199 QCOMPARE(resultSpy.count(), 1); 0200 QCOMPARE(resultSpy.takeFirst().at(0).value<QKeySequence>(), QKeySequence(keys[0], keys[1], keys[2], keys[3])); 0201 0202 recorder.setMultiKeyShortcutsAllowed(false); 0203 recorder.startRecording(); 0204 QVERIFY(recorder.isRecording()); 0205 QCOMPARE(recordingSpy.count(), 3); 0206 QTest::keyPress(m_window, Qt::Key_A, Qt::ControlModifier); 0207 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0208 QVERIFY(!recorder.isRecording()); 0209 QCOMPARE(recordingSpy.count(), 4); 0210 QCOMPARE(resultSpy.count(), 1); 0211 QCOMPARE(resultSpy.takeAt(0).at(0).value<QKeySequence>(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0212 } 0213 0214 #include "moc_keysequencerecordertest.cpp"