File indexing completed on 2024-12-01 03:39:53
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 "kkeysequencerecordertest.h" 0007 0008 #include "kkeysequencerecorder.h" 0009 0010 #include <QSignalSpy> 0011 #include <QTest> 0012 #include <QWindow> 0013 0014 QTEST_MAIN(KKeySequenceRecorderTest) 0015 0016 void KKeySequenceRecorderTest::initTestCase() 0017 { 0018 m_window = new QWindow; 0019 } 0020 0021 void KKeySequenceRecorderTest::cleanupTestCase() 0022 { 0023 delete m_window; 0024 } 0025 0026 void KKeySequenceRecorderTest::testValidWindow() 0027 { 0028 KKeySequenceRecorder recorder(nullptr); 0029 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::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 KKeySequenceRecorderTest::testRecording() 0042 { 0043 KKeySequenceRecorder recorder(m_window); 0044 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); 0045 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0046 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::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 KKeySequenceRecorderTest::testModifiers() 0070 { 0071 KKeySequenceRecorder recorder(m_window); 0072 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); 0073 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0074 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::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 QTRY_VERIFY_WITH_TIMEOUT(recorder.isRecording(), 800); 0094 0095 QTest::keyPress(m_window, Qt::Key_Control); 0096 QCOMPARE(sequenceSpy.count(), 4); 0097 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::ControlModifier)); 0098 0099 QTest::keyPress(m_window, Qt::Key_Alt, Qt::ControlModifier); 0100 QCOMPARE(sequenceSpy.count(), 6); // QTest sends two key events, one for each modifier 0101 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::AltModifier | Qt::ControlModifier)); 0102 0103 QCOMPARE(resultSpy.count(), 0); // modifierless not allowed 0104 } 0105 0106 void KKeySequenceRecorderTest::testModifierless() 0107 { 0108 KKeySequenceRecorder recorder(m_window); 0109 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); 0110 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0111 0112 recorder.startRecording(); 0113 QVERIFY(recorder.isRecording()); 0114 QCOMPARE(sequenceSpy.count(), 1); 0115 0116 recorder.setModifierlessAllowed(false); 0117 QTest::keyPress(m_window, Qt::Key_A); 0118 QTRY_VERIFY_WITH_TIMEOUT(recorder.isRecording(), 800); 0119 QCOMPARE(sequenceSpy.count(), 1); 0120 QCOMPARE(resultSpy.count(), 0); 0121 QCOMPARE(recorder.currentKeySequence(), QKeySequence()); 0122 0123 recorder.setModifierlessAllowed(true); 0124 QTest::keyClick(m_window, Qt::Key_A); 0125 QTRY_VERIFY_WITH_TIMEOUT(!recorder.isRecording(), 800); 0126 QCOMPARE(sequenceSpy.count(), 2); 0127 QCOMPARE(resultSpy.count(), 1); 0128 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A)); 0129 } 0130 0131 void KKeySequenceRecorderTest::testModifierOnly() 0132 { 0133 KKeySequenceRecorder recorder(m_window); 0134 recorder.setModifierOnlyAllowed(true); 0135 recorder.setModifierlessAllowed(true); 0136 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); 0137 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); 0138 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0139 0140 recorder.startRecording(); 0141 QVERIFY(recorder.isRecording()); 0142 QCOMPARE(sequenceSpy.count(), 1); 0143 0144 QTest::keyClick(m_window, Qt::Key_Shift); 0145 recordingSpy.wait(); 0146 QVERIFY(!recorder.isRecording()); 0147 QCOMPARE(sequenceSpy.count(), 3); 0148 QCOMPARE(resultSpy.count(), 1); 0149 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_Shift)); 0150 } 0151 0152 void KKeySequenceRecorderTest::testModifierOnlyDisabled() 0153 { 0154 KKeySequenceRecorder recorder(m_window); 0155 recorder.setModifierOnlyAllowed(false); 0156 recorder.setModifierlessAllowed(true); 0157 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); 0158 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); 0159 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0160 0161 recorder.startRecording(); 0162 QVERIFY(recorder.isRecording()); 0163 QCOMPARE(sequenceSpy.count(), 1); 0164 0165 QTest::keyClick(m_window, Qt::Key_Shift); 0166 recordingSpy.wait(); 0167 QVERIFY(recorder.isRecording()); 0168 recorder.cancelRecording(); 0169 QCOMPARE(sequenceSpy.count(), 3); 0170 QCOMPARE(resultSpy.count(), 0); 0171 QCOMPARE(recorder.currentKeySequence(), QKeySequence()); 0172 } 0173 0174 void KKeySequenceRecorderTest::testMultiKeyAllowed() 0175 { 0176 KKeySequenceRecorder recorder(m_window); 0177 QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); 0178 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); 0179 0180 recorder.startRecording(); 0181 0182 recorder.setMultiKeyShortcutsAllowed(true); 0183 int keys[4] = {0}; 0184 for (int i = 0; i < 4; ++i) { 0185 QVERIFY(recorder.isRecording()); 0186 QCOMPARE(recordingSpy.count(), 1); 0187 QCOMPARE(resultSpy.count(), 0); 0188 keys[i] = (Qt::Key_A | Qt::ControlModifier).toCombined(); 0189 QKeySequence result(keys[0], keys[1], keys[2], keys[3]); 0190 QTest::keyPress(m_window, Qt::Key_A, Qt::ControlModifier); 0191 QTest::keyRelease(m_window, Qt::Key_A, Qt::ControlModifier); 0192 QCOMPARE(recorder.currentKeySequence(), QKeySequence(keys[0], keys[1], keys[2], keys[3])); 0193 } 0194 QVERIFY(!recorder.isRecording()); 0195 QCOMPARE(recordingSpy.count(), 2); 0196 QCOMPARE(resultSpy.count(), 1); 0197 QCOMPARE(resultSpy.takeFirst().at(0).value<QKeySequence>(), QKeySequence(keys[0], keys[1], keys[2], keys[3])); 0198 0199 recorder.setMultiKeyShortcutsAllowed(false); 0200 recorder.startRecording(); 0201 QVERIFY(recorder.isRecording()); 0202 QCOMPARE(recordingSpy.count(), 3); 0203 QTest::keyPress(m_window, Qt::Key_A, Qt::ControlModifier); 0204 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0205 QVERIFY(!recorder.isRecording()); 0206 QCOMPARE(recordingSpy.count(), 4); 0207 QCOMPARE(resultSpy.count(), 1); 0208 QCOMPARE(resultSpy.takeAt(0).at(0).value<QKeySequence>(), QKeySequence(Qt::Key_A | Qt::ControlModifier)); 0209 } 0210 0211 void KKeySequenceRecorderTest::testKeyNonLetterNoModifier() 0212 { 0213 KKeySequenceRecorder recorder(m_window); 0214 QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); 0215 QSignalSpy sequenceSpy(&recorder, &KKeySequenceRecorder::currentKeySequenceChanged); 0216 0217 recorder.startRecording(); 0218 QVERIFY(recorder.isRecording()); 0219 QCOMPARE(sequenceSpy.count(), 1); 0220 0221 recorder.setModifierlessAllowed(false); 0222 QTest::keyPress(m_window, Qt::Key_Insert); 0223 QTRY_VERIFY_WITH_TIMEOUT(recorder.isRecording(), 800); 0224 QCOMPARE(sequenceSpy.count(), 2); 0225 QCOMPARE(resultSpy.count(), 0); 0226 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_Insert)); 0227 0228 recorder.setModifierlessAllowed(true); 0229 QTest::keyClick(m_window, Qt::Key_Insert); 0230 QTRY_VERIFY_WITH_TIMEOUT(!recorder.isRecording(), 800); 0231 QCOMPARE(sequenceSpy.count(), 3); 0232 QCOMPARE(resultSpy.count(), 1); 0233 QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_Insert, Qt::Key_Insert)); 0234 } 0235 0236 #include "moc_kkeysequencerecordertest.cpp"