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"