Commit 08bb4ec7 authored by Alexander Lohnau's avatar Alexander Lohnau 💬 Committed by Harald Sitter

Refactor converter runner

Summary:
The logic from the converter runner has been refactored and moved to seperate files.
Additionally some foreach marcos have been refactored and the numberValue of the query gets only
calculated once, instead of being calculated for each matching unit.

Test Plan: The plugin should work as before and the fractional units in https://phabricator.kde.org/D22869 are still supported.

Reviewers: broulik, ngraham, #plasma, sitter

Reviewed By: broulik, #plasma, sitter

Subscribers: sitter, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D27166
parent 8d5e1a0b
......@@ -34,6 +34,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED
Quick
Qml
Widgets
Test
)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
......
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_runner_converterrunner\")
set(krunner_converter_SRCS
converterrunner.cpp
)
set(krunner_converter_SRCS converterrunner.cpp)
add_library(krunner_converter MODULE ${krunner_converter_SRCS})
target_link_libraries(krunner_converter KF5::UnitConversion KF5::KIOCore KF5::I18n KF5::Runner)
target_link_libraries(krunner_converter KF5::UnitConversion KF5::I18n KF5::Runner Qt5::Widgets)
install(TARGETS krunner_converter DESTINATION ${KDE_INSTALL_PLUGINDIR})
install(FILES plasma-runner-converter.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
add_library(krunner_converter_test STATIC ${krunner_converter_SRCS})
target_link_libraries(krunner_converter_test
KF5::I18n
KF5::Runner
KF5::UnitConversion
Qt5::Widgets
Qt5::Test
)
if(BUILD_TESTING)
add_subdirectory(autotests)
endif()
remove_definitions(-DQT_NO_CAST_FROM_ASCII)
include(ECMAddTests)
ecm_add_test(converterrunnertest.cpp TEST_NAME converterrunnertest LINK_LIBRARIES Qt5::Test krunner_converter_test)
/*
* Copyright (C) 2020 Alexander Lohnau <alexander.lohnau@gmx.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QTest>
#include "../converterrunner.h"
using namespace KUnitConversion;
class ConverterRunnerTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testMostCommonUnits();
void testSpecificTargetUnit();
void testUnitsCaseInsensitive();
void testCaseSensitiveUnits();
void testCurrency();
void testLettersAndCurrency();
void testInvalidCurrency();
void testFractions();
void testInvalidFractions();
void testSymbolsInUnits();
void testNegativeValue();
private:
ConverterRunner *runner = nullptr;
};
void ConverterRunnerTest::initTestCase()
{
setlocale(LC_ALL, "C.utf8");
qputenv("LANG", "en_US");
runner = new ConverterRunner(this, QVariantList());
runner->init();
}
/**
* Test if the most common units are displayed
*/
void ConverterRunnerTest::testMostCommonUnits()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1m"));
runner->match(context);
Converter converter;
const auto lengthCategory = converter.category(KUnitConversion::LengthCategory);
QCOMPARE(context.matches().count(), lengthCategory.mostCommonUnits().count() -1);
}
/*
* Test if specifying a target unit works
*/
void ConverterRunnerTest::testSpecificTargetUnit()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1m > cm"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
QCOMPARE(context.matches().first().text(), QStringLiteral("100 centimeters (cm)"));
}
/**
* Test if the units are case insensitive
*/
void ConverterRunnerTest::testUnitsCaseInsensitive()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1Liter in ML"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
}
/**
* Test if the units that are case sensitive are correctly parsed
*/
void ConverterRunnerTest::testCaseSensitiveUnits()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1Ms as ms"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
QCOMPARE(context.matches().first().text(), QStringLiteral("1.000.000.000 milliseconds (ms)"));
Plasma::RunnerContext context2;
context2.setQuery(QStringLiteral("1.000.000.000milliseconds>Ms"));
runner->match(context2);
QCOMPARE(context2.matches().count(), 1);
QCOMPARE(context2.matches().first().text(), "1 megasecond (Ms)");
}
/**
* Test of a currency gets converted to the most common currencies
*/
void ConverterRunnerTest::testCurrency()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1$"));
runner->match(context);
Converter converter;
const auto currencyCategory = converter.category(KUnitConversion::CurrencyCategory);
QList<Unit> currencyUnits = currencyCategory.mostCommonUnits();
const QString currencyIsoCode = QLocale().currencySymbol(QLocale::CurrencyIsoCode);
const KUnitConversion::Unit localCurrency = currencyCategory.unit(currencyIsoCode);
if (localCurrency.isValid() && !currencyUnits.contains(localCurrency)) {
currencyUnits << localCurrency;
}
QCOMPARE(context.matches().count(), currencyUnits.count() - 1);
}
/**
* Test a combination of currency symbols and letters that is not directly supported by the conversion backend
*/
void ConverterRunnerTest::testLettersAndCurrency()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("4us$>ca$"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
QVERIFY(context.matches().first().text().contains(QLatin1String("Canadian dollars (CAD)")));
}
/**
* Test a query that matches the regex but is not valid
*/
void ConverterRunnerTest::testInvalidCurrency()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("4us$>abc$"));
runner->match(context);
QCOMPARE(context.matches().count(), 0);
}
/**
* Test if the factions are correctly parsed
*/
void ConverterRunnerTest::testFractions()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("6/3m>cm"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
QCOMPARE(context.matches().first().text(), QStringLiteral("200 centimeters (cm)"));
}
/**
* Test if an invalid query with a fraction gets rejected
*/
void ConverterRunnerTest::testInvalidFractions()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("4/4>cm"));
runner->match(context);
QCOMPARE(context.matches().count(), 0);
}
/**
* Test if symbols (other than currencies) are accepted
*/
void ConverterRunnerTest::testSymbolsInUnits()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("1000 µs as year"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
}
/**
* Test if negative values are accepted
*/
void ConverterRunnerTest::testNegativeValue()
{
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("-4m as cm"));
runner->match(context);
QCOMPARE(context.matches().count(), 1);
QCOMPARE(context.matches().first().text(), "-400 centimeters (cm)");
}
QTEST_MAIN(ConverterRunnerTest)
#include "converterrunnertest.moc"
This diff is collapsed.
/*
* Copyright (C) 2007,2008 Petri Damstén <damu@iki.fi>
* Copyright (C) 2020 Alexander Lohnau <alexander.lohnau@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -18,24 +19,47 @@
#ifndef CONVERTERRUNNER_H
#define CONVERTERRUNNER_H
#include <krunner/abstractrunner.h>
#include <KRunner/AbstractRunner>
#include <QRegularExpression>
#include <QLocale>
#include <QAction>
#include <KUnitConversion/Converter>
#include <KUnitConversion/UnitCategory>
/**
* This class converts values to different units.
*/
class ConverterRunner : public Plasma::AbstractRunner
class ConverterRunner: public Plasma::AbstractRunner
{
Q_OBJECT
public:
ConverterRunner(QObject* parent, const QVariantList &args);
ConverterRunner(QObject *parent, const QVariantList &args);
void init() override;
void insertCompatibleUnits();
~ConverterRunner() override;
void match(Plasma::RunnerContext &context) override;
QList<QAction *> actionsForMatch(const Plasma::QueryMatch &match) override;
void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) override;
private:
QStringList m_separators;
KUnitConversion::Converter converter;
const QLocale locale;
QRegularExpression valueRegex;
QRegularExpression unitSeperatorRegex;
/** To convert currency symbols back to ISO string and handle case sensitive units */
QMap<QString, QString> compatibleUnits;
QList<QAction *> actionList;
QLatin1String copyActionId = QLatin1String("copy");
QLatin1String copyUnitActionId = QLatin1String("copy-unit");
QPair<bool, double> stringToDouble(const QStringRef &value);
QPair<bool, double> getValidatedNumberValue(const QString &value);
QList<KUnitConversion::Unit> createResultUnits(QString &outputUnitString,
const KUnitConversion::UnitCategory &category);
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment