diff --git a/src/core/autotests/emojimanagertest.cpp b/src/core/autotests/emojimanagertest.cpp index e40df3b2..f9fa994b 100644 --- a/src/core/autotests/emojimanagertest.cpp +++ b/src/core/autotests/emojimanagertest.cpp @@ -1,127 +1,129 @@ /* Copyright (c) 2018-2020 Laurent Montel 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 ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "emojimanagertest.h" #include "emoticons/emojimanager.h" #include "emoticons/emoji.h" #include #include #include QTEST_GUILESS_MAIN(EmojiManagerTest) EmojiManagerTest::EmojiManagerTest(QObject *parent) : QObject(parent) { } void EmojiManagerTest::shouldHaveDefaultValue() { EmojiManager manager(nullptr, false); QVERIFY(manager.serverUrl().isEmpty()); QCOMPARE(manager.count(), 0); } void EmojiManagerTest::shouldParseEmoji_data() { QTest::addColumn("name"); QTest::addColumn("number"); QTest::addRow("emojiparent") << QStringLiteral("emojiparent") << 7; } void EmojiManagerTest::shouldParseEmoji() { QFETCH(QString, name); QFETCH(int, number); const QString originalJsonFile = QLatin1String(RUQOLA_DATA_DIR) + QLatin1String("/json/restapi/") + name + QLatin1String(".json"); QFile f(originalJsonFile); QVERIFY(f.open(QIODevice::ReadOnly)); const QByteArray content = f.readAll(); f.close(); const QJsonDocument doc = QJsonDocument::fromJson(content); const QJsonObject obj = doc.object(); EmojiManager manager(nullptr, false); manager.loadCustomEmoji(obj); QCOMPARE(manager.count(), number); } void EmojiManagerTest::shouldSupportUnicodeEmojis() { EmojiManager manager; QString grinning; grinning += QChar(0xd800+61); grinning += QChar(0xDC00+512); // A basic emoji that was already there in the initial emoji.json from fairchat QCOMPARE(manager.unicodeEmoticonForEmoji(QStringLiteral(":grinning:")).unicode(), grinning); // The one that made me use https://raw.githubusercontent.com/joypixels/emoji-toolkit/master/emoji.json instead QVERIFY(manager.unicodeEmoticonForEmoji(QStringLiteral(":zany_face:")).isValid()); // A "shortname alternate" - QVERIFY(manager.unicodeEmoticonForEmoji(QStringLiteral(":water_polo_tone5:")).isValid()); + QCOMPARE(manager.unicodeEmoticonForEmoji(QStringLiteral(":water_polo_tone5:")).key(), QStringLiteral("1f93d-1f3ff")); + // One that is not (yet?) in NotoColorEmoji + QCOMPARE(manager.unicodeEmoticonForEmoji(QStringLiteral(":woman_climbing_tone4:")).key(), QStringLiteral("1f9d7-1f3fe-2640")); } void EmojiManagerTest::shouldGenerateHtml() { const QString originalJsonFile = QLatin1String(RUQOLA_DATA_DIR) + QLatin1String("/json/restapi/emojiparent.json"); QFile f(originalJsonFile); QVERIFY(f.open(QIODevice::ReadOnly)); const QByteArray content = f.readAll(); f.close(); const QJsonDocument doc = QJsonDocument::fromJson(content); const QJsonObject obj = doc.object(); EmojiManager manager(nullptr, false); manager.loadCustomEmoji(obj); //No serverUrl set. QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":foo:")), QStringLiteral(":foo:")); const QString serverUrl = QStringLiteral("www.kde.org"); manager.setServerUrl(serverUrl); // :foo: doesn't exist QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":foo:")), QStringLiteral(":foo:")); QCOMPARE(manager.customEmojiFileName(QStringLiteral(":foo:")), QString()); // Existing emoji QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":vader:")), QStringLiteral("")); QCOMPARE(manager.customEmojiFileName(QStringLiteral(":vader:")), QStringLiteral("/emoji-custom/vader.png")); // Alias QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":darth:")), QStringLiteral("")); QCOMPARE(manager.customEmojiFileName(QStringLiteral(":darth:")), QStringLiteral("/emoji-custom/vader.png")); } void EmojiManagerTest::shouldChangeServerUrl() { const QString originalJsonFile = QLatin1String(RUQOLA_DATA_DIR) + QLatin1String("/json/restapi/emojiparent.json"); QFile f(originalJsonFile); QVERIFY(f.open(QIODevice::ReadOnly)); const QByteArray content = f.readAll(); f.close(); const QJsonDocument doc = QJsonDocument::fromJson(content); const QJsonObject obj = doc.object(); EmojiManager manager(nullptr, false); manager.loadCustomEmoji(obj); QString serverUrl = QStringLiteral("www.kde.org"); manager.setServerUrl(serverUrl); //It exists QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":vader:")), QStringLiteral("").arg(serverUrl)); //Change server url => clear cache serverUrl = QStringLiteral("www.bla.org"); manager.setServerUrl(serverUrl); QCOMPARE(manager.replaceEmojiIdentifier(QStringLiteral(":vader:")), QStringLiteral("").arg(serverUrl)); } diff --git a/src/core/emoticons/unicodeemoticon.cpp b/src/core/emoticons/unicodeemoticon.cpp index a7e5c35a..d4589b1b 100644 --- a/src/core/emoticons/unicodeemoticon.cpp +++ b/src/core/emoticons/unicodeemoticon.cpp @@ -1,161 +1,138 @@ /* Copyright (c) 2018-2020 Laurent Montel 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 ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "emoticons/unicodeemoticon.h" #include #include UnicodeEmoticon::UnicodeEmoticon() { } bool UnicodeEmoticon::isValid() const { return !mIdentifier.isEmpty() && !mUnicode.isEmpty(); } QString UnicodeEmoticon::identifier() const { return mIdentifier; } void UnicodeEmoticon::setIdentifier(const QString &name) { mIdentifier = name; } QString UnicodeEmoticon::unicode() const { return mUnicode; } QString UnicodeEmoticon::unicodeDisplay() const { if (!mUnicode.isEmpty()) { if (mCachedHtml.isEmpty()) { mCachedHtml = QStringLiteral("%1").arg(mUnicode); } } return mCachedHtml; } -//Code from fairchat -//Reimplement it ? QString UnicodeEmoticon::escapeUnicodeEmoji(const QString &pString) { QString retString; - if (pString.contains(QLatin1Char('-'))) { - const QStringList parts = pString.split(QLatin1Char('-')); - - for (const auto &item : parts) { - int part; - std::stringstream ss; - ss << std::hex << item.toStdString(); - ss >> part; - - if (part >= 0x10000 && part <= 0x10FFFF) { - const int hi = ((part - 0x10000) / 0x400) + 0xD800; - const int lo = ((part - 0x10000) % 0x400) + 0xDC00; - retString += QChar(hi); - retString += QChar(lo); - } else { - retString = QChar(part); - } - } - } else { - int part; - std::stringstream ss; - ss << std::hex << pString.toStdString(); - ss >> part; - - if (part >= 0x10000 && part <= 0x10FFFF) { - const int hi = ((part - 0x10000) / 0x400) + 0xD800; - const int lo = ((part - 0x10000) % 0x400) + 0xDC00; - retString += QChar(hi); - retString += QChar(lo); + const QStringList parts = pString.split(QLatin1Char('-')); + for (const auto &item : parts) { + bool ok; + const int part = item.toInt(&ok, 16); + Q_ASSERT(ok); + if (QChar::requiresSurrogates(part)) { + retString += QChar::highSurrogate(part); + retString += QChar::lowSurrogate(part); } else { retString = QChar(part); } } return retString; } QString UnicodeEmoticon::key() const { return mKey; } void UnicodeEmoticon::setKey(const QString &key) { mKey = key; } int UnicodeEmoticon::order() const { return mOrder; } void UnicodeEmoticon::setOrder(int order) { mOrder = order; } void UnicodeEmoticon::setUnicode(const QString &unicode) { mUnicode = escapeUnicodeEmoji(unicode); } QString UnicodeEmoticon::category() const { return mCategory; } void UnicodeEmoticon::setCategory(const QString &category) { mCategory = category; } QStringList UnicodeEmoticon::aliases() const { return mAliases; } void UnicodeEmoticon::setAliases(const QStringList &aliases) { mAliases = aliases; } bool UnicodeEmoticon::hasEmoji(const QString &identifier) const { return (mIdentifier == identifier) || mAliases.contains(identifier); } QDebug operator <<(QDebug d, const UnicodeEmoticon &t) { d << "Identifier : " << t.identifier(); d << "Unicode: " << t.unicode(); d << "Category: " << t.category(); d << "Aliases: " << t.aliases(); d << "Order: " << t.order(); d << "Key:" << t.key(); return d; }