kdelibs/kdeui/tests/kglobalshortcuttest.cpp
Ivailo Monev 383d2cd332 generic: misc cleanups
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2016-04-12 11:07:40 +00:00

375 lines
13 KiB
C++

/*
This file is part of the KDE libraries
Copyright (c) 2007 Andreas Hartmetz <ahartmetz@gmail.com>
Copyright (c) 2008 Michael Jansen <kde@michael-jansen.biz>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kglobalshortcuttest.h"
#include <qdbusinterface.h>
#include <qtest_kde.h>
#include <kaction.h>
#include <kaction_p.h>
#include <kactioncollection.h>
#include <kglobal.h>
#include <kglobalaccel.h>
#include <kdebug.h>
#include <kservice.h>
#include <unistd.h>
#include <QtDBus/QDBusConnectionInterface>
const QKeySequence sequenceA = QKeySequence(Qt::SHIFT + Qt::META + Qt::CTRL + Qt::ALT + Qt::Key_F28 );
const QKeySequence sequenceB = QKeySequence(Qt::Key_F29);
const QKeySequence sequenceC = QKeySequence(Qt::SHIFT + Qt::META + Qt::CTRL + Qt::Key_F28 );
const QKeySequence sequenceD = QKeySequence(Qt::META + Qt::ALT + Qt::Key_F30);
const QKeySequence sequenceE = QKeySequence(Qt::META + Qt::Key_F29);
const QKeySequence sequenceF = QKeySequence(Qt::META + Qt::Key_F27);
/* These tests could be better. They don't include actually triggering actions,
and we just choose very improbable shortcuts to avoid conflicts with real
applications' shortcuts. */
//we need a KComponentData and a GUI so that the implementation can grab keys
QTEST_KDEMAIN( KGlobalShortcutTest, GUI )
void KGlobalShortcutTest::initTestCase()
{
m_daemonInstalled = !KService::serviceByDesktopName("kglobalaccel").isNull();
}
void KGlobalShortcutTest::setupTest(QString id)
{
if (m_actionA) {
m_actionA->forgetGlobalShortcut();
delete m_actionA;
}
if (m_actionB) {
m_actionB->forgetGlobalShortcut();
delete m_actionB;
}
// Ensure that the previous test did cleanup correctly
KGlobalAccel *kga = KGlobalAccel::self();
Q_UNUSED(kga);
m_actionA = new KAction("Text For Action A", this);
m_actionA->setObjectName("Action A:" + id);
m_actionA->setGlobalShortcut(
KShortcut(sequenceA, sequenceB),
KAction::ActiveShortcut|KAction::DefaultShortcut,
KAction::NoAutoloading);
m_actionB = new KAction("Text For Action B", this);
m_actionB->setObjectName("Action B:" + id);
m_actionB->setGlobalShortcut(
KShortcut(),
KAction::ActiveShortcut|KAction::DefaultShortcut,
KAction::NoAutoloading);
}
void KGlobalShortcutTest::testSetShortcut()
{
setupTest("testSetShortcut");
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
// Just ensure that the desired values are set for both actions
KShortcut cutA(sequenceA, sequenceB);
QCOMPARE(m_actionA->globalShortcut(), cutA);
QCOMPARE(m_actionA->globalShortcut(KAction::DefaultShortcut), cutA);
QVERIFY(m_actionB->globalShortcut().isEmpty());
QVERIFY(m_actionB->globalShortcut(KAction::DefaultShortcut).isEmpty());
}
// Current state
// m_actionA: (sequenceA, sequenceB)
// m_actionB: (,)
void KGlobalShortcutTest::testFindActionByKey()
{
// Skip this. The above testcase hasn't changed the actions
setupTest("testFindActionByKey");
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
QList<KGlobalShortcutInfo> actionId = KGlobalAccel::self()->getGlobalShortcutsByKey(sequenceB);
QCOMPARE(actionId.size(), 1);
QString actionIdAComponentUniqueName("qttest");
QString actionIdAUniqueName("Action A:testFindActionByKey");
QString actionIdAComponentFriendlyName("KDE Test Program");
QString actionIdAFriendlyName("Text For Action A");
QCOMPARE(actionId.first().componentUniqueName(), actionIdAComponentUniqueName);
QCOMPARE(actionId.first().uniqueName(), actionIdAUniqueName);
QCOMPARE(actionId.first().componentFriendlyName(), actionIdAComponentFriendlyName);
QCOMPARE(actionId.first().friendlyName(), actionIdAFriendlyName);
actionId = KGlobalAccel::self()->getGlobalShortcutsByKey(sequenceA);
QCOMPARE(actionId.size(), 1);
QCOMPARE(actionId.first().componentUniqueName(), actionIdAComponentUniqueName);
QCOMPARE(actionId.first().uniqueName(), actionIdAUniqueName);
QCOMPARE(actionId.first().componentFriendlyName(), actionIdAComponentFriendlyName);
QCOMPARE(actionId.first().friendlyName(), actionIdAFriendlyName);
}
void KGlobalShortcutTest::testChangeShortcut()
{
// Skip this. The above testcase hasn't changed the actions
setupTest("testChangeShortcut");
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
// Change the shortcut
KShortcut newCutA(sequenceC);
m_actionA->setGlobalShortcut(newCutA, KAction::ActiveShortcut, KAction::NoAutoloading);
// Ensure that the change is active
QCOMPARE(m_actionA->globalShortcut(), newCutA);
// We haven't changed the default shortcut, ensure it is unchanged
KShortcut cutA(sequenceA, sequenceB);
QCOMPARE(m_actionA->globalShortcut(KAction::DefaultShortcut), cutA);
// Try to set a already take shortcut
KShortcut cutB(m_actionA->globalShortcut().primary(), QKeySequence(sequenceE));
m_actionB->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
// Ensure that no change was made to the primary active shortcut
QVERIFY(m_actionB->globalShortcut().primary().isEmpty());
// Ensure that the change to the secondary active shortcut was made
QCOMPARE(m_actionB->globalShortcut().alternate(), QKeySequence(sequenceE));
// Ensure that the default shortcut is still empty
QVERIFY(m_actionB->globalShortcut(KAction::DefaultShortcut).isEmpty()); // unchanged
// Only change the active shortcut
cutB.setPrimary(sequenceD);
m_actionB->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
// Check that the change went through
QCOMPARE(m_actionB->globalShortcut(), cutB);
// Check that the default shortcut is not active
QVERIFY(m_actionB->globalShortcut(KAction::DefaultShortcut).isEmpty()); // unchanged
}
void KGlobalShortcutTest::testStealShortcut()
{
setupTest("testStealShortcut");
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
// Steal a shortcut from an action. First ensure the initial state is
// correct
KShortcut cutA(sequenceA, sequenceB);
QCOMPARE(m_actionA->globalShortcut(), cutA);
QCOMPARE(m_actionA->globalShortcut(KAction::DefaultShortcut), cutA);
KGlobalAccel::stealShortcutSystemwide(sequenceA);
//let DBus do its thing in case it happens asynchronously
QTest::qWait(200);
QVERIFY(m_actionB->globalShortcut(KAction::ActiveShortcut).primary().isEmpty());
}
void KGlobalShortcutTest::testSaveRestore()
{
setupTest("testSaveRestore");
//It /would be nice/ to test persistent storage. That is not so easy...
KShortcut cutA = m_actionA->globalShortcut();
// Delete the action
delete m_actionA;
// Recreate it
m_actionA = new KAction("Text For Action A", this);
m_actionA->setObjectName("Action A:testSaveRestore");
// Now it's empty
QVERIFY(m_actionA->globalShortcut().isEmpty());
m_actionA->setGlobalShortcut(KShortcut());
// Now it's restored
QCOMPARE(m_actionA->globalShortcut(), cutA);
// And again
delete m_actionA;
m_actionA = new KAction("Text For Action A", this);
m_actionA->setObjectName("Action A:testSaveRestore");
m_actionA->setGlobalShortcut(KShortcut(QKeySequence(), cutA.primary()));
QCOMPARE(m_actionA->globalShortcut(), cutA);
}
// Duplicated again!
enum actionIdFields
{
ComponentUnique = 0,
ActionUnique = 1,
ComponentFriendly = 2,
ActionFriendly = 3
};
void KGlobalShortcutTest::testListActions()
{
setupTest("testListActions");
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
// As in kdebase/workspace/kcontrol/keys/globalshortcuts.cpp
KGlobalAccel *kga = KGlobalAccel::self();
Q_UNUSED(kga);
}
void KGlobalShortcutTest::testComponentAssignment()
{
// We don't use them here
// setupTest();
KComponentData otherComponent("test_component1");
KActionCollection coll((QObject*)NULL);
coll.setComponentData(otherComponent);
KShortcut cutB;
/************************************************************
* Ensure that the actions get a correct component assigned *
************************************************************/
// Action without action collection get the global component
{
KAction action("Text For Action A", NULL);
action.setObjectName("Action C");
QVERIFY(action.d->componentData == KGlobal::mainComponent());
action.setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
QVERIFY(action.d->componentData == KGlobal::mainComponent());
// cleanup
action.forgetGlobalShortcut();
}
// Action with action collection get the component of the collection
{
KAction *action = coll.addAction("Action C");
QVERIFY(action->d->componentData == otherComponent);
action->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
QVERIFY(action->d->componentData == otherComponent);
// cleanup
action->forgetGlobalShortcut();
delete action;
}
}
void KGlobalShortcutTest::testConfigurationActions()
{
setupTest("testConfigurationActions");
// Create a configuration action
KAction cfg_action("Text For Action A", NULL);
cfg_action.setObjectName("Action A:testConfigurationActions");
cfg_action.setProperty("isConfigurationAction", true);
cfg_action.setGlobalShortcut(KShortcut());
// Check that the configuration action has the correct shortcuts
QCOMPARE(m_actionA->globalShortcut(), cfg_action.globalShortcut());
// TODO:
// - change shortcut from configuration action and test for
// yourShortcutGotChanged
// - Ensure that the config action doesn't trigger(how?)
// - Ensure that the original action is still working when the
// configuration action is deleted
}
void KGlobalShortcutTest::testOverrideMainComponentData()
{
setupTest("testOverrideMainComponentData");
KComponentData otherComponent("test_component1");
KActionCollection coll((QObject*)NULL);
coll.setComponentData(otherComponent);
KShortcut cutB;
// Action without action collection
KAction *action = new KAction("Text For Action A", this);
QVERIFY(action->d->componentData == KGlobal::mainComponent());
action->setObjectName("Action A");
action->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
QVERIFY(action->d->componentData == KGlobal::mainComponent());
// Action with action collection
action->forgetGlobalShortcut();
delete action;
action = coll.addAction("Action A");
QVERIFY(action->d->componentData == otherComponent);
action->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
QVERIFY(action->d->componentData == otherComponent);
// cleanup
action->forgetGlobalShortcut();
delete coll.takeAction(action);
}
void KGlobalShortcutTest::testNotification()
{
setupTest("testNotification");
// Action without action collection
KAction *action = new KAction("Text For Action A", this);
QVERIFY(action->d->componentData == KGlobal::mainComponent());
action->setObjectName("Action A");
KShortcut cutB;
action->setGlobalShortcut(cutB, KAction::ActiveShortcut, KAction::NoAutoloading);
QVERIFY(action->d->componentData == KGlobal::mainComponent());
// kglobalacceld collects registrations and shows the together. Give it
// time to kick in.
sleep(2);
action->forgetGlobalShortcut();
}
void KGlobalShortcutTest::testForgetGlobalShortcut()
{
setupTest("testForgetGlobalShortcut");
// Ensure that forgetGlobalShortcut can be called on any action.
KAction a("Test", NULL);
a.forgetGlobalShortcut();
if (!m_daemonInstalled)
QSKIP("kglobalaccel not installed", SkipAll);
// We forget these two shortcuts and check that the component is gone
// after that. If not it can mean the forgetGlobalShortcut() call is
// broken OR someone messed up these tests to leave an additional global
// shortcut behind.
m_actionB->forgetGlobalShortcut();
m_actionA->forgetGlobalShortcut();
// kglobalaccel writes asynchronous.
sleep(1);
KGlobalAccel *kga = KGlobalAccel::self();
Q_UNUSED(kga);
}
#include "moc_kglobalshortcuttest.cpp"