From 1e05300ae1ec8ed5f4f225f04c5e7c84b4b8ab60 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 15 Oct 2015 13:41:42 +0300 Subject: [PATCH] Add method for check that formula contain inside only single value. --HG-- branch : develop --- src/libs/qmuparser/qmuformulabase.cpp | 22 +++++++ src/libs/qmuparser/qmuformulabase.h | 2 + src/libs/qmuparser/qmutokenparser.cpp | 46 ++++++++++++++ src/libs/qmuparser/qmutokenparser.h | 3 + src/libs/vpatterndb/calculator.cpp | 22 ------- src/libs/vpatterndb/calculator.h | 3 +- src/test/ValentinaTest/ValentinaTest.pro | 6 +- src/test/ValentinaTest/qttestmainlambda.cpp | 2 + src/test/ValentinaTest/tst_qmutokenparser.cpp | 61 +++++++++++++++++++ src/test/ValentinaTest/tst_qmutokenparser.h | 46 ++++++++++++++ 10 files changed, 187 insertions(+), 26 deletions(-) create mode 100644 src/test/ValentinaTest/tst_qmutokenparser.cpp create mode 100644 src/test/ValentinaTest/tst_qmutokenparser.h diff --git a/src/libs/qmuparser/qmuformulabase.cpp b/src/libs/qmuparser/qmuformulabase.cpp index ced9ed767..a734acbcf 100644 --- a/src/libs/qmuparser/qmuformulabase.cpp +++ b/src/libs/qmuparser/qmuformulabase.cpp @@ -109,4 +109,26 @@ void QmuFormulaBase::SetSepForEval() SetDecSep('.'); } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief RemoveAll remove token from token list. + * + * Standard Qt class QMap doesn't have method RemoveAll. + * Example: remove "-" from tokens list if exist. If don't do that unary minus operation will broken. + * + * @param map map with tokens + * @param val token that need delete + */ +void QmuFormulaBase::RemoveAll(QMap &map, const QString &val) +{ + const QList listKeys = map.keys(val);//Take all keys that contain token. + if (listKeys.size() > 0) + { + for (int i = 0; i < listKeys.size(); ++i) + { + map.remove(listKeys.at(i)); + } + } +} + }// namespace qmu diff --git a/src/libs/qmuparser/qmuformulabase.h b/src/libs/qmuparser/qmuformulabase.h index 9b9b78537..b1785c17e 100644 --- a/src/libs/qmuparser/qmuformulabase.h +++ b/src/libs/qmuparser/qmuformulabase.h @@ -40,6 +40,8 @@ protected: void SetSepForTr(bool osSeparator, bool fromUser); void SetSepForEval(); + static void RemoveAll(QMap &map, const QString &val); + private: Q_DISABLE_COPY(QmuFormulaBase) }; diff --git a/src/libs/qmuparser/qmutokenparser.cpp b/src/libs/qmuparser/qmutokenparser.cpp index 27d080e24..cb513e206 100644 --- a/src/libs/qmuparser/qmutokenparser.cpp +++ b/src/libs/qmuparser/qmutokenparser.cpp @@ -24,6 +24,13 @@ namespace qmu { +//--------------------------------------------------------------------------------------------------------------------- +QmuTokenParser::QmuTokenParser() +{ + InitCharacterSets(); + setAllowSubexpressions(false);//Only one expression per time +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief QmuTokenParser class constructor. Make easy initialization math parser. @@ -59,4 +66,43 @@ QmuTokenParser::~QmuTokenParser() { } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief IsSingle test formula and return true if it contain only one number. + * + * Work only with expressions in internal (C) locale. + * @param formula expression for test + * @return true if fomula has single number + * @throw qmu::QmuParserError if expression is incorrect. Has bad separator. + */ +bool QmuTokenParser::IsSingle(const QString &formula) +{ + QmuTokenParser *cal = new QmuTokenParser(); + + // Parser doesn't know any variable on this stage. So, we just use variable factory that for each unknown + // variable set value to 0. + cal->SetVarFactory(AddVariable, cal); + cal->SetSepForEval();//Reset separators options + + cal->SetExpr(formula); + cal->Eval();// We don't need save result, only parse formula + + QMap tokens = cal->GetTokens();// Tokens (variables, measurements) + const QMap numbers = cal->GetNumbers();// All numbers in expression + + delete cal; + + // Remove "-" from tokens list if exist. If don't do that unary minus operation will broken. + RemoveAll(tokens, QStringLiteral("-")); + + if (tokens.isEmpty() && numbers.size() == 1) + { + return true; + } + else + { + return false; + } +} + }// namespace qmu diff --git a/src/libs/qmuparser/qmutokenparser.h b/src/libs/qmuparser/qmutokenparser.h index e4b8459ab..eddda2eca 100644 --- a/src/libs/qmuparser/qmutokenparser.h +++ b/src/libs/qmuparser/qmutokenparser.h @@ -34,8 +34,11 @@ public: QmuTokenParser(const QString &formula, bool osSeparator, bool fromUser = true); virtual ~QmuTokenParser() Q_DECL_OVERRIDE; + static bool IsSingle(const QString &formula); + private: Q_DISABLE_COPY(QmuTokenParser) + QmuTokenParser(); }; } // namespace qmu diff --git a/src/libs/vpatterndb/calculator.cpp b/src/libs/vpatterndb/calculator.cpp index 382a6bb97..b8eaae764 100644 --- a/src/libs/vpatterndb/calculator.cpp +++ b/src/libs/vpatterndb/calculator.cpp @@ -143,25 +143,3 @@ void Calculator::InitVariables(const QHash &vars, const QMap &map, const QString &val) -{ - const QList listKeys = map.keys(val);//Take all keys that contain token. - if (listKeys.size() > 0) - { - for (int i = 0; i < listKeys.size(); ++i) - { - map.remove(listKeys.at(i)); - } - } -} diff --git a/src/libs/vpatterndb/calculator.h b/src/libs/vpatterndb/calculator.h index c6f2e03c2..c3d89c22d 100644 --- a/src/libs/vpatterndb/calculator.h +++ b/src/libs/vpatterndb/calculator.h @@ -57,13 +57,12 @@ class Calculator:public qmu::QmuFormulaBase { public: Calculator(); - virtual ~Calculator(); + virtual ~Calculator() Q_DECL_OVERRIDE; qreal EvalFormula(const QHash &vars, const QString &formula); private: Q_DISABLE_COPY(Calculator) void InitVariables(const QHash &vars, const QMap &tokens, const QString &formula); - static void RemoveAll(QMap &map, const QString &val); }; #endif // CALCULATOR_H diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index 7c8a9f4ca..0a7b6eec8 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -45,7 +45,8 @@ SOURCES += \ stable.cpp \ tst_measurementregexp.cpp \ tst_tapecommandline.cpp \ - tst_valentinacommandline.cpp + tst_valentinacommandline.cpp \ + tst_qmutokenparser.cpp HEADERS += \ tst_vposter.h \ @@ -58,7 +59,8 @@ HEADERS += \ stable.h \ tst_measurementregexp.h \ tst_tapecommandline.h \ - tst_valentinacommandline.h + tst_valentinacommandline.h \ + tst_qmutokenparser.h # Set using ccache. Function enable_ccache() defined in common.pri. $$enable_ccache() diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index 2ef27d586..4564bb571 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -37,6 +37,7 @@ #include "tst_measurementregexp.h" #include "tst_tapecommandline.h" #include "tst_valentinacommandline.h" +#include "tst_qmutokenparser.h" int main(int argc, char** argv) { @@ -58,6 +59,7 @@ int main(int argc, char** argv) ASSERT_TEST(new TST_MeasurementRegExp()); ASSERT_TEST(new TST_TapeCommandLine()); ASSERT_TEST(new TST_ValentinaCommandLine()); + ASSERT_TEST(new TST_QmuTokenParser()); return status; } diff --git a/src/test/ValentinaTest/tst_qmutokenparser.cpp b/src/test/ValentinaTest/tst_qmutokenparser.cpp new file mode 100644 index 000000000..ed4076296 --- /dev/null +++ b/src/test/ValentinaTest/tst_qmutokenparser.cpp @@ -0,0 +1,61 @@ +/************************************************************************ + ** + ** @file tst_qmutokenparser.cpp + ** @author Roman Telezhynskyi + ** @date 15 10, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina 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 Valentina. If not, see . + ** + *************************************************************************/ + +#include "tst_qmutokenparser.h" +#include "../qmuparser/qmutokenparser.h" + +#include + +//--------------------------------------------------------------------------------------------------------------------- +TST_QmuTokenParser::TST_QmuTokenParser(QObject *parent) + :QObject(parent) +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_QmuTokenParser::IsSingle_data() +{ + QTest::addColumn("formula"); + QTest::addColumn("result"); + + QTest::newRow("Single value") << "15.5" << true; + QTest::newRow("Two digits") << "2+2" << false; + QTest::newRow("Negative single value") << "-2" << true; + QTest::newRow("Digit and variable") << "2+a" << false; + QTest::newRow("One variable twice") << "a+a" << false; + QTest::newRow("Two variables") << "a+b" << false; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_QmuTokenParser::IsSingle() +{ + QFETCH(QString, formula); + QFETCH(bool, result); + + QCOMPARE(qmu::QmuTokenParser::IsSingle(formula), result); +} diff --git a/src/test/ValentinaTest/tst_qmutokenparser.h b/src/test/ValentinaTest/tst_qmutokenparser.h new file mode 100644 index 000000000..1431594d3 --- /dev/null +++ b/src/test/ValentinaTest/tst_qmutokenparser.h @@ -0,0 +1,46 @@ +/************************************************************************ + ** + ** @file tst_qmutokenparser.h + ** @author Roman Telezhynskyi + ** @date 15 10, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina 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 Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef TST_QMUTOKENPARSER_H +#define TST_QMUTOKENPARSER_H + +#include + +class TST_QmuTokenParser : public QObject +{ + Q_OBJECT +public: + Q_DISABLE_COPY(TST_QmuTokenParser) + explicit TST_QmuTokenParser(QObject *parent = 0); + +private slots: + void IsSingle_data(); + void IsSingle(); +}; + +#endif // TST_QMUTOKENPARSER_H