File indexing completed on 2024-11-24 05:00:37

0001 /*
0002     SPDX-FileCopyrightText: 2011 Andriy Rysin <rysin@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QTest>
0008 
0009 #include "../xkb_rules.h"
0010 
0011 #include <qdom.h>
0012 
0013 static const Rules::ExtrasFlag readExtras = Rules::NO_EXTRAS;
0014 
0015 class RulesTest : public QObject
0016 {
0017     Q_OBJECT
0018 
0019     Rules *rules;
0020 
0021 private Q_SLOTS:
0022     void initTestCase()
0023     {
0024         rules = Rules::readRules(readExtras);
0025     }
0026 
0027     void cleanupTestCase()
0028     {
0029         delete rules;
0030     }
0031 
0032     void testRules()
0033     {
0034         QVERIFY(rules != nullptr);
0035         QVERIFY(rules->modelInfos.size() > 0);
0036         QVERIFY(rules->layoutInfos.size() > 0);
0037         QVERIFY(rules->optionGroupInfos.size() > 0);
0038     }
0039 
0040     void testModel()
0041     {
0042         for (const ModelInfo *modelInfo : std::as_const(rules->modelInfos)) {
0043             QVERIFY(modelInfo != nullptr);
0044             QVERIFY(modelInfo->name.length() > 0);
0045             QVERIFY(modelInfo->description.length() > 0);
0046             //          QVERIFY( ! modelInfo->vendor.isEmpty() );
0047         }
0048     }
0049 
0050     void testLayouts()
0051     {
0052         for (const LayoutInfo *layoutInfo : std::as_const(rules->layoutInfos)) {
0053             QVERIFY(layoutInfo != nullptr);
0054             QVERIFY(!layoutInfo->name.isEmpty());
0055             //          const char* desc = layoutInfo->name.toUtf8() ;
0056             //          qDebug() << layoutInfo->name;
0057             QVERIFY(!layoutInfo->description.isEmpty());
0058 
0059             for (const VariantInfo *variantInfo : layoutInfo->variantInfos) {
0060                 QVERIFY(variantInfo != nullptr);
0061                 QVERIFY(!variantInfo->name.isEmpty());
0062                 QVERIFY(!variantInfo->description.isEmpty());
0063             }
0064             for (const QString &language : layoutInfo->languages) {
0065                 QVERIFY(!language.isEmpty());
0066             }
0067         }
0068     }
0069 
0070     void testOptionGroups()
0071     {
0072         for (const OptionGroupInfo *optionGroupInfo : std::as_const(rules->optionGroupInfos)) {
0073             QVERIFY(optionGroupInfo != nullptr);
0074             QVERIFY(!optionGroupInfo->name.isEmpty());
0075             QVERIFY(!optionGroupInfo->description.isEmpty());
0076             // optionGroupInfo->exclusive
0077 
0078             for (const OptionInfo *optionInfo : optionGroupInfo->optionInfos) {
0079                 QVERIFY(optionInfo != nullptr);
0080                 QVERIFY(!optionInfo->name.isEmpty());
0081                 QVERIFY(!optionInfo->description.isEmpty());
0082             }
0083         }
0084     }
0085 
0086     void testExtras()
0087     {
0088         const Rules *rulesWithExtras = Rules::readRules(Rules::READ_EXTRAS);
0089         QVERIFY2(rulesWithExtras->layoutInfos.size() > rules->layoutInfos.size(), "Rules with extras should have more layouts");
0090 
0091         for (const LayoutInfo *layoutInfo : std::as_const(rules->layoutInfos)) {
0092             QVERIFY(!layoutInfo->fromExtras);
0093         }
0094 
0095         bool foundFromExtras = false, foundNonExtras = false;
0096         for (const LayoutInfo *layoutInfo : rulesWithExtras->layoutInfos) {
0097             if (layoutInfo->fromExtras)
0098                 foundFromExtras = true;
0099             if (!layoutInfo->fromExtras)
0100                 foundNonExtras = true;
0101             layoutInfo->languages.size(); // make sure we can access all merged objects
0102             layoutInfo->variantInfos.size(); // make sure we can access all merged objects
0103         }
0104         QVERIFY(foundNonExtras);
0105         QVERIFY(foundFromExtras);
0106     }
0107 
0108     void testWriteNewXml()
0109     {
0110         QDomDocument doc(QStringLiteral("xkbConfigRegistry"));
0111         QDomElement root = doc.createElement(QStringLiteral("xkbConfigRegistry"));
0112         root.setAttribute(QStringLiteral("version"), QStringLiteral("2.0"));
0113         doc.appendChild(root);
0114 
0115         QDomElement modelList = doc.createElement(QStringLiteral("modelList"));
0116         root.appendChild(modelList);
0117         for (const ModelInfo *modelInfo : std::as_const(rules->modelInfos)) {
0118             QDomElement model = doc.createElement(QStringLiteral("model"));
0119             model.setAttribute(QStringLiteral("name"), modelInfo->name);
0120             model.setAttribute(QStringLiteral("description"), modelInfo->description);
0121             model.setAttribute(QStringLiteral("vendor"), modelInfo->vendor);
0122             modelList.appendChild(model);
0123         }
0124 
0125         QDomElement layoutList = doc.createElement(QStringLiteral("layoutList"));
0126         for (const LayoutInfo *layoutInfo : std::as_const(rules->layoutInfos)) {
0127             QDomElement layout = doc.createElement(QStringLiteral("layout"));
0128             layout.setAttribute(QStringLiteral("name"), layoutInfo->name);
0129             layout.setAttribute(QStringLiteral("description"), layoutInfo->description);
0130 
0131             QDomElement langList = doc.createElement(QStringLiteral("languageList"));
0132             for (const QString &lang : layoutInfo->languages) {
0133                 QDomElement langNode = doc.createElement(QStringLiteral("lang"));
0134                 langNode.setAttribute(QStringLiteral("iso639Id"), lang);
0135                 langList.appendChild(langNode);
0136             }
0137             if (langList.hasChildNodes()) {
0138                 layout.appendChild(langList);
0139             }
0140 
0141             QDomElement variantList = doc.createElement(QStringLiteral("variantList"));
0142             for (const VariantInfo *variantInfo : layoutInfo->variantInfos) {
0143                 QDomElement variant = doc.createElement(QStringLiteral("variant"));
0144                 variant.setAttribute(QStringLiteral("name"), variantInfo->name);
0145                 variant.setAttribute(QStringLiteral("description"), variantInfo->description);
0146 
0147                 QDomElement langList = doc.createElement(QStringLiteral("languageList"));
0148                 for (const QString &lang : variantInfo->languages) {
0149                     QDomElement langNode = doc.createElement(QStringLiteral("lang"));
0150                     langNode.setAttribute(QStringLiteral("iso639Id"), lang);
0151                     langList.appendChild(langNode);
0152                 }
0153                 if (langList.hasChildNodes()) {
0154                     variant.appendChild(langList);
0155                 }
0156 
0157                 variantList.appendChild(variant);
0158             }
0159             if (variantList.hasChildNodes()) {
0160                 layout.appendChild(variantList);
0161             }
0162 
0163             layoutList.appendChild(layout);
0164         }
0165         root.appendChild(layoutList);
0166 
0167         QDomElement optionGroupList = doc.createElement(QStringLiteral("optionList"));
0168         for (const OptionGroupInfo *optionGroupInfo : std::as_const(rules->optionGroupInfos)) {
0169             QDomElement optionGroup = doc.createElement(QStringLiteral("optionGroup"));
0170             optionGroup.setAttribute(QStringLiteral("name"), optionGroupInfo->name);
0171             optionGroup.setAttribute(QStringLiteral("description"), optionGroupInfo->description);
0172             optionGroup.setAttribute(QStringLiteral("exclusive"), optionGroupInfo->exclusive);
0173 
0174             for (const OptionInfo *optionInfo : optionGroupInfo->optionInfos) {
0175                 QDomElement option = doc.createElement(QStringLiteral("option"));
0176                 option.setAttribute(QStringLiteral("name"), optionInfo->name);
0177                 option.setAttribute(QStringLiteral("description"), optionInfo->description);
0178                 optionGroup.appendChild(option);
0179             }
0180 
0181             optionGroupList.appendChild(optionGroup);
0182         }
0183         root.appendChild(optionGroupList);
0184 
0185         QFile file(QStringLiteral("base2.xml"));
0186         if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
0187             qWarning() << "Failed to open layout memory xml file for writing" << file.fileName();
0188             QFAIL("failed");
0189         }
0190 
0191         QTextStream out(&file);
0192         out << doc.toString();
0193     }
0194 
0195     void testRulesVersion()
0196     {
0197         QVERIFY(!rules->version.isEmpty());
0198 
0199         Rules *rules10 = new Rules();
0200         Rules::readRules(rules10, QStringLiteral("config/base.xml"), false);
0201         QCOMPARE(rules10->version, QString("1.0"));
0202         delete rules10;
0203 
0204         Rules *rules11 = new Rules();
0205         Rules::readRules(rules11, QStringLiteral("config/base.1.1.xml"), false);
0206         QCOMPARE(rules11->version, QString("1.1"));
0207 
0208         for (const LayoutInfo *layoutInfo : std::as_const(rules11->layoutInfos)) {
0209             QVERIFY(layoutInfo != nullptr);
0210             QVERIFY(!layoutInfo->name.isEmpty());
0211             QVERIFY(!layoutInfo->description.isEmpty());
0212 
0213             for (const VariantInfo *variantInfo : layoutInfo->variantInfos) {
0214                 QVERIFY(variantInfo != nullptr);
0215                 QVERIFY(!variantInfo->name.isEmpty());
0216                 QVERIFY(!variantInfo->description.isEmpty());
0217             }
0218         }
0219 
0220         delete rules11;
0221     }
0222 
0223     void loadRulesBenchmark()
0224     {
0225         QBENCHMARK {
0226             Rules *rules = Rules::readRules(readExtras);
0227             delete rules;
0228         }
0229     }
0230 };
0231 
0232 // need kde libs for config-workspace.h used in xkb_rules.cpp
0233 QTEST_MAIN(RulesTest)
0234 
0235 #include "xkb_rules_test.moc"