File indexing completed on 2024-04-21 04:00:53

0001 // krazy:excludeall=spelling
0002 /**
0003  * SPDX-FileCopyrightText: 2017 David Faure <faure@kde.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-or-later
0006  */
0007 
0008 #include "highlighter.h"
0009 #include "speller.h"
0010 
0011 #include <QObject>
0012 #include <QPlainTextEdit>
0013 #include <QRegularExpression>
0014 #include <QStandardPaths>
0015 #include <QTest>
0016 
0017 using namespace Sonnet;
0018 
0019 class HighlighterTest : public QObject
0020 {
0021     Q_OBJECT
0022 
0023 private Q_SLOTS:
0024     void initTestCase();
0025     void testEnglish();
0026     void testFrench();
0027     void testMultipleLanguages();
0028     void testForceLanguage();
0029 };
0030 
0031 void HighlighterTest::initTestCase()
0032 {
0033     QStandardPaths::setTestModeEnabled(true);
0034 
0035     Speller speller(QStringLiteral("en_US"));
0036     if (!speller.availableBackends().contains(QLatin1String("ASpell"))) {
0037         QSKIP("ASpell not available");
0038     }
0039     // Doing this here affects all the highlighters created later on, due to the weird hidden "Settings" class saving stuff behind the API's back...
0040     speller.setDefaultClient(QStringLiteral("ASpell"));
0041     if (!speller.availableLanguages().contains(QLatin1String("en"))) {
0042         QSKIP("'en' not available");
0043     }
0044 
0045     // How weird to have to do this here and not with the Highlighter API....
0046     speller.setAttribute(Speller::AutoDetectLanguage, true);
0047 }
0048 
0049 static const char s_englishSentence[] = "Hello helo this is the highlighter test enviroment guvernment"; // words from test_suggest.cpp
0050 
0051 void HighlighterTest::testEnglish()
0052 {
0053     // GIVEN
0054     QPlainTextEdit textEdit;
0055     textEdit.setPlainText(QString::fromLatin1(s_englishSentence));
0056     Sonnet::Highlighter highlighter(&textEdit);
0057     highlighter.setCurrentLanguage(QStringLiteral("en"));
0058     if (!highlighter.spellCheckerFound()) {
0059         QSKIP("'en' not available");
0060     }
0061     highlighter.rehighlight();
0062     QTextCursor cursor(textEdit.document());
0063 
0064     // WHEN
0065     cursor.setPosition(6);
0066     const QStringList suggestionsForHelo = highlighter.suggestionsForWord(QStringLiteral("helo"), cursor);
0067     const QStringList unlimitedSuggestions = highlighter.suggestionsForWord(QStringLiteral("helo"), cursor, -1);
0068     cursor.setPosition(40);
0069     const QStringList suggestionsForEnviroment = highlighter.suggestionsForWord(QStringLiteral("enviroment"), cursor);
0070 
0071     // THEN
0072     QCOMPARE(suggestionsForHelo.count(), 10);
0073     QVERIFY2(suggestionsForHelo.contains(QLatin1String("hello")), qPrintable(suggestionsForHelo.join(QLatin1Char(','))));
0074     QVERIFY2(suggestionsForEnviroment.contains(QLatin1String("environment")), qPrintable(suggestionsForEnviroment.join(QLatin1Char(','))));
0075     QVERIFY(unlimitedSuggestions.count() > 10);
0076 }
0077 
0078 static const char s_frenchSentence[] = "Bnjour est un bon mot pour tester le dictionnare.";
0079 
0080 void HighlighterTest::testFrench()
0081 {
0082     // GIVEN
0083     QPlainTextEdit textEdit;
0084     textEdit.setPlainText(QString::fromLatin1(s_frenchSentence));
0085     Sonnet::Highlighter highlighter(&textEdit);
0086     highlighter.setCurrentLanguage(QStringLiteral("fr_FR"));
0087     if (!highlighter.spellCheckerFound()) {
0088         QSKIP("'fr_FR' not available");
0089     }
0090     highlighter.rehighlight();
0091     QTextCursor cursor(textEdit.document());
0092 
0093     // WHEN
0094     cursor.setPosition(0);
0095     const QStringList suggestionsForBnjour = highlighter.suggestionsForWord(QStringLiteral("Bnjour"), cursor);
0096     cursor.setPosition(37);
0097     const QStringList suggestionsForDict = highlighter.suggestionsForWord(QStringLiteral("dictionnare"), cursor);
0098 
0099     // THEN
0100     QVERIFY2(suggestionsForBnjour.contains(QLatin1String("Bonjour")), qPrintable(suggestionsForBnjour.join(QLatin1Char(','))));
0101     QVERIFY2(suggestionsForDict.contains(QLatin1String("dictionnaire")), qPrintable(suggestionsForDict.join(QLatin1Char(','))));
0102 }
0103 
0104 void HighlighterTest::testForceLanguage()
0105 {
0106     // GIVEN
0107     QPlainTextEdit textEdit;
0108     textEdit.setPlainText(QString::fromLatin1(s_frenchSentence));
0109     Sonnet::Highlighter highlighter(&textEdit);
0110     highlighter.setCurrentLanguage(QStringLiteral("en"));
0111     highlighter.setAutoDetectLanguageDisabled(true);
0112     QVERIFY(highlighter.spellCheckerFound());
0113     QVERIFY(highlighter.autoDetectLanguageDisabled());
0114     highlighter.rehighlight();
0115     QCOMPARE(highlighter.currentLanguage(), QStringLiteral("en"));
0116     QTextCursor cursor(textEdit.document());
0117 
0118     // WHEN
0119     cursor.setPosition(0);
0120     const QStringList suggestionsForBnjour = highlighter.suggestionsForWord(QStringLiteral("Bnjour"), cursor);
0121     cursor.setPosition(37);
0122     const QStringList suggestionsForDict = highlighter.suggestionsForWord(QStringLiteral("dictionnare"), cursor);
0123 
0124     // THEN
0125     QVERIFY2(!suggestionsForBnjour.contains(QLatin1String("Bonjour")), qPrintable(suggestionsForBnjour.join(QLatin1Char(','))));
0126     QVERIFY2(!suggestionsForDict.contains(QLatin1String("dictionnaire")), qPrintable(suggestionsForDict.join(QLatin1Char(','))));
0127 }
0128 
0129 void HighlighterTest::testMultipleLanguages()
0130 {
0131     // GIVEN
0132     QPlainTextEdit textEdit;
0133     const QString englishSentence = QString::fromLatin1(s_englishSentence) + QLatin1Char('\n');
0134     textEdit.setPlainText(englishSentence + QString::fromLatin1(s_frenchSentence));
0135     Sonnet::Highlighter highlighter(&textEdit);
0136     highlighter.rehighlight();
0137     QTextCursor cursor(textEdit.document());
0138 
0139     // create Speller to check if we have the language dictionaries available otherwise
0140     // this will just keep failing
0141     Sonnet::Speller speller;
0142     const auto availableLangs = speller.availableLanguages();
0143     bool isFrAvailable = availableLangs.indexOf(QRegularExpression(QStringLiteral("fr"))) != -1;
0144     bool isEnAvailable = availableLangs.indexOf(QRegularExpression(QStringLiteral("en"))) != -1;
0145 
0146     // WHEN
0147     cursor.setPosition(6);
0148     const QStringList suggestionsForHelo = highlighter.suggestionsForWord(QStringLiteral("helo"), cursor);
0149     cursor.setPosition(40);
0150     const QStringList suggestionsForEnviroment = highlighter.suggestionsForWord(QStringLiteral("enviroment"), cursor);
0151     cursor.setPosition(englishSentence.size());
0152     const QStringList suggestionsForBnjour = highlighter.suggestionsForWord(QStringLiteral("Bnjour"), cursor);
0153     cursor.setPosition(englishSentence.size() + 37);
0154     const QStringList suggestionsForDict = highlighter.suggestionsForWord(QStringLiteral("dictionnare"), cursor);
0155 
0156     // THEN
0157     if (isEnAvailable) {
0158         QVERIFY2(suggestionsForHelo.contains(QLatin1String("hello")), qPrintable(suggestionsForHelo.join(QLatin1Char(','))));
0159         QVERIFY2(suggestionsForEnviroment.contains(QLatin1String("environment")), qPrintable(suggestionsForEnviroment.join(QLatin1Char(','))));
0160     }
0161     if (isFrAvailable) {
0162         QVERIFY2(suggestionsForBnjour.contains(QLatin1String("Bonjour")), qPrintable(suggestionsForBnjour.join(QLatin1Char(','))));
0163         QVERIFY2(suggestionsForDict.contains(QLatin1String("dictionnaire")), qPrintable(suggestionsForDict.join(QLatin1Char(','))));
0164     }
0165 }
0166 
0167 QTEST_MAIN(HighlighterTest)
0168 
0169 #include "test_highlighter.moc"