/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech 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 QElectroTech. If not, see .
*/
#include "commandsearchpopup.h"
#include "shortcutmanager.h"
#include
#include
#include
#include
#include
/**
CommandSearchPopup: accent- and case-blind matching, ranking, and that
Enter runs the highlighted command of the owning window only.
*/
class tst_commandsearch : public QObject
{
Q_OBJECT
private:
QAction *add(QWidget *owner, const QString &id, const QString &text)
{
auto *action = new QAction(text, owner);
ShortcutManager::instance().registerAction(action, id, QStringLiteral("test"), QKeySequence());
return action;
}
QStringList shown(CommandSearchPopup &popup)
{
QStringList texts;
auto *list = popup.findChild();
for (int i = 0 ; i < list->count() ; ++i) {
texts << list->item(i)->text();
}
return texts;
}
private slots:
void fold_data()
{
QTest::addColumn("input");
QTest::addColumn("expected");
QTest::newRow("accents") << QStringLiteral("Éditer l'élément") << QStringLiteral("editer l'element");
QTest::newRow("mnemonic") << QStringLiteral("&Fichier") << QStringLiteral("fichier");
QTest::newRow("cedilla") << QStringLiteral("Façade") << QStringLiteral("facade");
QTest::newRow("plain") << QStringLiteral("zoom") << QStringLiteral("zoom");
}
void fold()
{
QFETCH(QString, input);
QFETCH(QString, expected);
QCOMPARE(CommandSearchPopup::fold(input), expected);
}
void ranksAndRunsTheBestMatch()
{
QWidget owner;
QWidget other;
QAction *rotate = add(&owner, QStringLiteral("t.rotate"), QStringLiteral("Pivoter"));
add(&owner, QStringLiteral("t.rotate_texts"), QStringLiteral("Orienter les textes"));
QAction *edit = add(&owner, QStringLiteral("t.edit"), QStringLiteral("Éditer l'item sélectionné"));
add(&owner, QStringLiteral("t.text"), QStringLiteral("Ajouter un champ de texte"));
//Same id family, another window: must not be listed
add(&other, QStringLiteral("t.other"), QStringLiteral("Texte d'une autre fenêtre"));
CommandSearchPopup popup(&owner);
popup.popUpAt(QPoint(0, 0));
auto *search = popup.findChild();
search->setText(QStringLiteral("texte"));
//word start ("…textes") before a contained match; other window absent
QCOMPARE(shown(popup), (QStringList{QStringLiteral("Ajouter un champ de texte"),
QStringLiteral("Orienter les textes")}));
search->setText(QStringLiteral("editer"));
QCOMPARE(shown(popup).value(0), QStringLiteral("Éditer l'item sélectionné"));
QSignalSpy edited(edit, &QAction::triggered);
QSignalSpy rotated(rotate, &QAction::triggered);
QTest::keyClick(&popup, Qt::Key_Return);
QCOMPARE(edited.count(), 1);
QCOMPARE(rotated.count(), 0);
QVERIFY(!popup.isVisible());
}
void disabledCommandsCannotRun()
{
QWidget owner;
QAction *paste = add(&owner, QStringLiteral("u.paste"), QStringLiteral("Coller"));
paste->setEnabled(false);
CommandSearchPopup popup(&owner);
popup.popUpAt(QPoint(0, 0));
popup.findChild()->setText(QStringLiteral("coller"));
QCOMPARE(shown(popup), QStringList{QStringLiteral("Coller")});
QSignalSpy pasted(paste, &QAction::triggered);
QTest::keyClick(&popup, Qt::Key_Return);
QCOMPARE(pasted.count(), 0);
}
};
QTEST_MAIN(tst_commandsearch)
#include "tst_commandsearch.moc"