diff --git a/kmymoney/widgets/CMakeLists.txt b/kmymoney/widgets/CMakeLists.txt index 09a80f5d9..99a78776b 100644 --- a/kmymoney/widgets/CMakeLists.txt +++ b/kmymoney/widgets/CMakeLists.txt @@ -1,260 +1,266 @@ ########### create links ############### set(kmymoney_STAT_HEADERS kaccounttemplateselector.h kguiutils.h kmymoneyaccountcombo.h kmymoneyaccountcompletion.h kmymoneyaccountselector.h kmymoneycategory.h kmymoneycombo.h kmymoneymvccombo.h kmymoneycompletion.h kmymoneycurrencyselector.h kmymoneydateinput.h kmymoneylineedit.h kmymoneyselector.h kmymoneytitlelabel.h register.h registeritem.h groupmarker.h fancydategroupmarker.h scheduledtransaction.h selectedtransaction.h selectedtransactions.h stdtransactiondownloaded.h stdtransactionmatched.h transactioneditorcontainer.h transactionform.h transaction.h investtransaction.h stdtransaction.h transactionsortoption.h kmymoneyvalidationfeedback.h onlinejobmessagesview.h kmymoneydateedit.h amountedit.h amountvalidator.h creditdebithelper.h ) ########### Shared widget library ########### set(kmm_widgets_sources kmymoneydateinput.cpp kmymoneyvalidationfeedback.cpp styleditemdelegateforwarder.cpp kmymoneylineedit.cpp kmymoneytextedit.cpp kmymoneytextedithighlighter.cpp kmymoneymvccombo.cpp kmymoneygeneralcombo.cpp kmymoneyactivitycombo.cpp kmymoneycashflowcombo.cpp kmymoneyfrequencycombo.cpp kmymoneyoccurrencecombo.cpp kmymoneyoccurrenceperiodcombo.cpp kmymoneypayeecombo.cpp kmymoneyperiodcombo.cpp kmymoneyreconcilecombo.cpp kmymoneytagcombo.cpp kmymoneyaccountselector.cpp ktagcontainer.cpp ktaglabel.cpp kmymoneyselector.cpp kmymoneycalculator.cpp ktreewidgetfilterlinewidget.cpp kguiutils.cpp onlinejobmessagesview.cpp kmymoneydateedit.cpp kmymoneymoneyvalidator.cpp amountedit.cpp amountvalidator.cpp creditdebithelper.cpp daterangedlg.cpp ktransactionfilter.cpp kmymoneyaccounttreeview.cpp accountsviewproxymodel.cpp budgetviewproxymodel.cpp kmymoneyviewbase.cpp kmymoneyaccountsviewbase.cpp ) set(nationalAccountWidget_SOURCES ./payeeidentifier/nationalaccount/nationalaccountedit.cpp ./payeeidentifier/nationalaccount/nationalaccountdelegate.cpp ) set(nationalAccountWidget_HEADERS ./payeeidentifier/nationalaccount/nationalaccountdelegate.h ./payeeidentifier/nationalaccount/nationalaccountedit.h ) set(IBANBICWidget_SOURCES ./payeeidentifier/ibanbic/kibanlineedit.cpp ./payeeidentifier/ibanbic/kbicedit.cpp ./payeeidentifier/ibanbic/ibanvalidator.cpp ./payeeidentifier/ibanbic/bicvalidator.cpp ./payeeidentifier/ibanbic/ibanbicitemdelegate.cpp ./payeeidentifier/ibanbic/ibanbicitemedit.cpp ) set(IBANBICWidget_HEADERS ./payeeidentifier/ibanbic/kibanlineedit.h ./payeeidentifier/ibanbic/kbicedit.h ./payeeidentifier/ibanbic/ibanvalidator.h ./payeeidentifier/ibanbic/bicvalidator.h ./payeeidentifier/ibanbic/ibanbicitemdelegate.h ) list(APPEND kmm_widgets_sources ${nationalAccountWidget_SOURCES}) list(APPEND kmymoney_STAT_HEADERS ${nationalAccountWidget_HEADERS}) list(APPEND kmm_widgets_sources ${IBANBICWidget_SOURCES}) list(APPEND kmymoney_STAT_HEADERS ${IBANBICWidget_HEADERS}) ki18n_wrap_ui(kmm_widgets_sources kmymoneyvalidationfeedback.ui onlinejobmessagesview.ui daterangedlg.ui ktransactionfilter.ui ./payeeidentifier/nationalaccount/nationalaccountedit.ui ./payeeidentifier/ibanbic/ibanbicitemedit.ui ) add_library(kmm_widgets SHARED ${kmm_widgets_sources}) target_link_libraries(kmm_widgets PUBLIC kmm_settings KF5::TextWidgets KF5::KIOWidgets KF5::Completion KF5::Notifications KF5::ItemViews KF5::I18n Qt5::Gui Qt5::Core Alkimia::alkimia kmm_mymoney kmm_models kmm_plugin ) set_target_properties(kmm_widgets PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} COMPILE_FLAGS "-DKMM_BUILD_WIDGETS_LIB" ) generate_export_header(kmm_widgets) install(TARGETS kmm_widgets ${INSTALL_TARGETS_DEFAULT_ARGS} ) ########### Basic Widget Library (kmymoney_base) STATIC ################# # Common sources for libkmymoney.so and libwidgets.a that do not # contain the KMM_DESIGNER flag set(_uncritial_common_sources kmymoneyaccountcombo.cpp kmymoneycombo.cpp kmymoneycompletion.cpp kmymoneytitlelabel.cpp kmymoneydateedit.cpp kpricetreeitem.cpp registeritem.cpp registerfilter.cpp scheduledtransaction.cpp selectedtransaction.cpp selectedtransactions.cpp stdtransactiondownloaded.cpp stdtransactionmatched.cpp transactionform.cpp tabbar.cpp transactionformitemdelegate.cpp transactionsortoption.cpp ) # sources that contain the KMM_DESIGNER flag set (_critial_common_sources kaccounttemplateselector.cpp kmymoneycurrencyselector.cpp kmymoneyaccountcompletion.cpp kmymoneycategory.cpp groupmarker.cpp groupmarkers.cpp fancydategroupmarker.cpp fancydategroupmarkers.cpp register.cpp itemptrvector.cpp qwidgetcontainer.cpp registeritemdelegate.cpp transaction.cpp stdtransaction.cpp investtransaction.cpp transactioneditorcontainer.cpp ) set (kmymoney_base_UI transactionsortoption.ui kaccounttemplateselector.ui ) ki18n_wrap_ui(kmymoney_base_ui_srcs ${kmymoney_base_UI}) set(_uncritial_common_sources ${_uncritial_common_sources} ${kmymoney_base_ui_srcs}) # in order to use add_dependencies, we need to add this custom target # for all generated header files. # (see http://www.vtk.org/Wiki/CMake_FAQ#How_can_I_add_a_dependency_to_a_source_file_which_is_generated_in_a_subdirectory.3F ) add_custom_target(generate_base_ui_srcs DEPENDS ${kmymoney_base_ui_srcs}) # We can compile the uncritical sources without KMM_DESIGNER flags add_library(kmymoney_base STATIC ${_uncritial_common_sources}) # TODO: fix dependencies target_link_libraries(kmymoney_base KF5::XmlGui KF5::TextWidgets KF5::IconThemes KF5::I18n KF5::ConfigWidgets KF5::ConfigCore KF5::Completion KF5::Service Qt5::Gui Qt5::Widgets Qt5::Xml kmm_settings Alkimia::alkimia) add_dependencies(kmymoney_base kmm_settings) ########### QtDesigner Widget Library (kmymoneywidgets) ################# # we never link against this library, # but it is needed for uic and QtDesigner if( USE_QT_DESIGNER ) set(kmymoneywidgets_PART_SRCS ${CMAKE_CURRENT_BINARY_DIR}/kmymoneywidgets.cpp) kde4_add_widget_files(kmymoneywidgets_PART_SRCS kmymoney.widgets) set(kmymoneywidgets_PART_SRCS ${_critial_common_sources} ${kmymoneywidgets_PART_SRCS}) add_library(kmymoneywidgets MODULE ${kmymoneywidgets_PART_SRCS}) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # The option -DKMM_DESIGNER will leave away any code that breaks uic. set_target_properties(kmymoneywidgets PROPERTIES COMPILE_FLAGS "-DKMM_DESIGNER") # The qt-designer widget library shouldn't need to link against the # dialogs and converter libraries. If a widget references something # from one of these libraries it is most likely due to code that needs # to be excluded with a KMM_DESIGNER ifndef. target_link_libraries(kmymoneywidgets kmymoney_base kmm_mymoney kmymoney_common kmm_settings models) install(TARGETS kmymoneywidgets DESTINATION ${QT_PLUGINS_DIR}/designer ) endif( USE_QT_DESIGNER ) ########### Widget Library (widgets) STATIC ################# set(libwidgets_a_SOURCES ${_critial_common_sources} kmymoneybriefschedule.cpp registersearchline.cpp transactioneditorcontainer.cpp ) set(libwidgets_a_UI kmymoneybriefschedule.ui ) # using uic on the above UI files DEPENDS on libkmymoney.so. If uic # does not find libkmymoney.so, gcc will fail compiling # kmymoneyreportconfigtab2decl.cpp and throw errors like "invalid use # of undefined type `struct KMyMoneyGeneralCombo'" ki18n_wrap_ui(widgets_ui_srcs ${libwidgets_a_UI}) add_custom_target(generate_widgets_ui_srcs DEPENDS ${widgets_ui_srcs}) add_library(widgets STATIC ${libwidgets_a_SOURCES} ${widgets_ui_srcs} ) target_link_libraries(widgets KF5::XmlGui kmymoney_base) add_dependencies(widgets kmm_settings) ########### install files ############### install(FILES ${kmymoney_STAT_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/kmm_widgets_export.h DESTINATION ${INCLUDE_INSTALL_DIR}/kmymoney COMPONENT Devel) + +############## tests #################### + +if(BUILD_TESTING) + add_subdirectory(tests) +endif() diff --git a/kmymoney/widgets/amountvalidator.h b/kmymoney/widgets/amountvalidator.h index 20925df8f..8a32ade5b 100644 --- a/kmymoney/widgets/amountvalidator.h +++ b/kmymoney/widgets/amountvalidator.h @@ -1,71 +1,69 @@ /* * Copyright 2016 Thomas Baumgart * Copyright 2017-2018 Łukasz Wojniłowicz * * This program 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. * * This program 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 this program. If not, see . */ #ifndef AMOUNTVALIDATOR_H #define AMOUNTVALIDATOR_H #include "kmm_widgets_export.h" // ---------------------------------------------------------------------------- // QT Includes #include // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneymoney.h" - /** * This class is derived from KDoubleValidator and uses * the monetary symbols instead of the numeric symbols. * Also, it always accepts localized input. * * @author Thomas Baumgart */ class AmountValidator : public QDoubleValidator { Q_OBJECT public: /** * Constuct a locale-aware KDoubleValidator with default range * (whatever QDoubleValidator uses for that) and parent @p * parent */ explicit AmountValidator(QObject * parent); /** * Constuct a locale-aware KDoubleValidator for range [@p bottom,@p * top] and a precision of @p digits after the decimal * point. */ explicit AmountValidator(double bottom, double top, int decimals, QObject * parent); /** * Destructs the validator. */ ~AmountValidator(); /** Overloaded for internal reasons. The API is not affected. */ QValidator::State validate(QString & input, int & pos) const override; }; #endif diff --git a/kmymoney/widgets/tests/CMakeLists.txt b/kmymoney/widgets/tests/CMakeLists.txt new file mode 100644 index 000000000..a56d13000 --- /dev/null +++ b/kmymoney/widgets/tests/CMakeLists.txt @@ -0,0 +1,21 @@ +include(ECMAddTests) + +set(testwidgets_SOURCES + ../amountvalidator.cpp + ) + +add_library(testwidgets STATIC ${testwidgets_SOURCES}) +target_link_libraries(testwidgets PUBLIC + Qt5::Gui + Qt5::Core +) + +file(GLOB tests_sources "*-test.cpp") +ecm_add_tests(${tests_sources} + LINK_LIBRARIES + Qt5::Gui + Qt5::Core + Qt5::Test + Qt5::Xml + testwidgets +) diff --git a/kmymoney/widgets/tests/amountvalidator-test.cpp b/kmymoney/widgets/tests/amountvalidator-test.cpp new file mode 100644 index 000000000..9bcba3c7d --- /dev/null +++ b/kmymoney/widgets/tests/amountvalidator-test.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2019 Thomas Baumgart + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +#include "amountvalidator-test.h" + +#include +#include + +#include +#include "amountvalidator.h" + +QTEST_GUILESS_MAIN(AmountValidatorTest) + +void AmountValidatorTest::init() +{ + defaultLocale = QLocale(); +} + +void AmountValidatorTest::cleanup() +{ + QLocale::setDefault(defaultLocale); +} + + +void AmountValidatorTest::setLocale(const QString& name) +{ + currentLocale = name; +} + +void AmountValidatorTest::addAcceptableNumber(const QString& testCaseName, const QString& number) +{ + const int result = static_cast(QValidator::Acceptable); + QString fixedNumber(number); + // replace a blank in the test string with a non-breakable-space + fixedNumber.replace(" ", "\u00A0"); + QTest::newRow((QString("%1:%2").arg(currentLocale, testCaseName)).toUtf8()) << currentLocale << fixedNumber << result; +} + +void AmountValidatorTest::addInvalidNumber(const QString& testCaseName, const QString& number) +{ + const int result = static_cast(QValidator::Invalid); + QString fixedNumber(number); + // replace a blank in the test string with a non-breakable-space + fixedNumber.replace(" ", "\u00A0"); + QTest::newRow((QString("%1:%2").arg(currentLocale, testCaseName)).toUtf8()) << currentLocale << fixedNumber << result; +} + +void AmountValidatorTest::testValidator_data() +{ + QTest::addColumn("locale"); + QTest::addColumn("inputValue"); + QTest::addColumn("result"); + + setLocale("en_US"); + addAcceptableNumber("amount w/ thousand and decimal", "1,123.00"); + addAcceptableNumber("amount no thousand but decimal", "1123.00"); + addAcceptableNumber("neg. amount no thousand but decimal", "-1123.00"); + addAcceptableNumber("amount no thousand no decimal", "1123"); + addAcceptableNumber("amount only fraction", ".00"); + + addInvalidNumber("amount w/ thousand and decimal reversed", "1.123,00"); + addInvalidNumber("neg. amount w/ thousand and decimal reversed", "1.123,00-"); + addInvalidNumber("amount only fraction reversed", ",00"); + + setLocale("sv_FI"); + addAcceptableNumber("amount w/ thousand and decimal", "1 123,00"); + addAcceptableNumber("neg. amount w/ thousand and decimal", "-1 123,00"); + addAcceptableNumber("amount no thousand but decimal", "1123,00"); + addAcceptableNumber("amount no thousand no decimal", "1123"); + addAcceptableNumber("amount only fraction", ",00"); + + setLocale("de_DE"); + addAcceptableNumber("amount w/ thousand and decimal", "1.123,00"); + addAcceptableNumber("amount no thousand but decimal", "1123,00"); + addAcceptableNumber("amount no thousand no decimal", "1123"); + addAcceptableNumber("amount only fraction", ",00"); + + addInvalidNumber("amount w/ thousand and decimal reversed", "1,123.00"); + addInvalidNumber("amount only fraction reversed", ".00"); + + setLocale("es_PE"); + addAcceptableNumber("amount w/ thousand and decimal", "1,123.00"); + addAcceptableNumber("amount no thousand but decimal", "1123.00"); + addAcceptableNumber("amount no thousand no decimal", "1123"); + addAcceptableNumber("amount only fraction", ".00"); + + addInvalidNumber("amount w/ thousand and decimal reversed", "1.123,00"); + addInvalidNumber("amount only fraction reversed", ",00"); +} + +void AmountValidatorTest::testValidator() +{ + QFETCH(QString, locale); + QFETCH(QString, inputValue); + QFETCH(int, result); + + QLocale::setDefault(locale); + AmountValidator m(nullptr); + int pos = inputValue.length(); + // QCOMPARE(m->validate(inputValue, pos), static_cast(result)); + QCOMPARE((int)m.validate(inputValue, pos), result); +} diff --git a/kmymoney/widgets/tests/amountvalidator-test.h b/kmymoney/widgets/tests/amountvalidator-test.h new file mode 100644 index 000000000..de958ca30 --- /dev/null +++ b/kmymoney/widgets/tests/amountvalidator-test.h @@ -0,0 +1,47 @@ +/* + * Copyright 2019 Thomas Baumgart + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +#ifndef AMOUNTVALIDATORTEST_H +#define AMOUNTVALIDATORTEST_H + +#include +#include +#include + +class AmountValidator; + +class AmountValidatorTest : public QObject +{ + Q_OBJECT + +protected: + QLocale defaultLocale; + QString currentLocale; + +private Q_SLOTS: + void init(); + void cleanup(); + void testValidator_data(); + void testValidator(); + +private: + void setLocale(const QString& name); + void addAcceptableNumber(const QString& testCaseName, const QString& number); + void addInvalidNumber(const QString& testCaseName, const QString& number); +}; + +#endif