Add method for check that formula contain inside only single value.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2015-10-15 13:41:42 +03:00
parent 5cd9a88761
commit 1e05300ae1
10 changed files with 187 additions and 26 deletions

View file

@ -109,4 +109,26 @@ void QmuFormulaBase::SetSepForEval()
SetDecSep('.'); 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<int, QString> &map, const QString &val)
{
const QList<int> 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 }// namespace qmu

View file

@ -40,6 +40,8 @@ protected:
void SetSepForTr(bool osSeparator, bool fromUser); void SetSepForTr(bool osSeparator, bool fromUser);
void SetSepForEval(); void SetSepForEval();
static void RemoveAll(QMap<int, QString> &map, const QString &val);
private: private:
Q_DISABLE_COPY(QmuFormulaBase) Q_DISABLE_COPY(QmuFormulaBase)
}; };

View file

@ -24,6 +24,13 @@
namespace qmu namespace qmu
{ {
//---------------------------------------------------------------------------------------------------------------------
QmuTokenParser::QmuTokenParser()
{
InitCharacterSets();
setAllowSubexpressions(false);//Only one expression per time
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief QmuTokenParser class constructor. Make easy initialization math parser. * @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<int, QString> tokens = cal->GetTokens();// Tokens (variables, measurements)
const QMap<int, QString> 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 }// namespace qmu

View file

@ -34,8 +34,11 @@ public:
QmuTokenParser(const QString &formula, bool osSeparator, bool fromUser = true); QmuTokenParser(const QString &formula, bool osSeparator, bool fromUser = true);
virtual ~QmuTokenParser() Q_DECL_OVERRIDE; virtual ~QmuTokenParser() Q_DECL_OVERRIDE;
static bool IsSingle(const QString &formula);
private: private:
Q_DISABLE_COPY(QmuTokenParser) Q_DISABLE_COPY(QmuTokenParser)
QmuTokenParser();
}; };
} // namespace qmu } // namespace qmu

View file

@ -143,25 +143,3 @@ void Calculator::InitVariables(const QHash<QString, qreal *> &vars, const QMap<i
++i; ++i;
} }
} }
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Calculator::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 Calculator::RemoveAll(QMap<int, QString> &map, const QString &val)
{
const QList<int> 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));
}
}
}

View file

@ -57,13 +57,12 @@ class Calculator:public qmu::QmuFormulaBase
{ {
public: public:
Calculator(); Calculator();
virtual ~Calculator(); virtual ~Calculator() Q_DECL_OVERRIDE;
qreal EvalFormula(const QHash<QString, qreal *> &vars, const QString &formula); qreal EvalFormula(const QHash<QString, qreal *> &vars, const QString &formula);
private: private:
Q_DISABLE_COPY(Calculator) Q_DISABLE_COPY(Calculator)
void InitVariables(const QHash<QString, qreal *> &vars, const QMap<int, QString> &tokens, void InitVariables(const QHash<QString, qreal *> &vars, const QMap<int, QString> &tokens,
const QString &formula); const QString &formula);
static void RemoveAll(QMap<int, QString> &map, const QString &val);
}; };
#endif // CALCULATOR_H #endif // CALCULATOR_H

View file

@ -45,7 +45,8 @@ SOURCES += \
stable.cpp \ stable.cpp \
tst_measurementregexp.cpp \ tst_measurementregexp.cpp \
tst_tapecommandline.cpp \ tst_tapecommandline.cpp \
tst_valentinacommandline.cpp tst_valentinacommandline.cpp \
tst_qmutokenparser.cpp
HEADERS += \ HEADERS += \
tst_vposter.h \ tst_vposter.h \
@ -58,7 +59,8 @@ HEADERS += \
stable.h \ stable.h \
tst_measurementregexp.h \ tst_measurementregexp.h \
tst_tapecommandline.h \ tst_tapecommandline.h \
tst_valentinacommandline.h tst_valentinacommandline.h \
tst_qmutokenparser.h
# Set using ccache. Function enable_ccache() defined in common.pri. # Set using ccache. Function enable_ccache() defined in common.pri.
$$enable_ccache() $$enable_ccache()

View file

@ -37,6 +37,7 @@
#include "tst_measurementregexp.h" #include "tst_measurementregexp.h"
#include "tst_tapecommandline.h" #include "tst_tapecommandline.h"
#include "tst_valentinacommandline.h" #include "tst_valentinacommandline.h"
#include "tst_qmutokenparser.h"
int main(int argc, char** argv) 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_MeasurementRegExp());
ASSERT_TEST(new TST_TapeCommandLine()); ASSERT_TEST(new TST_TapeCommandLine());
ASSERT_TEST(new TST_ValentinaCommandLine()); ASSERT_TEST(new TST_ValentinaCommandLine());
ASSERT_TEST(new TST_QmuTokenParser());
return status; return status;
} }

View file

@ -0,0 +1,61 @@
/************************************************************************
**
** @file tst_qmutokenparser.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "tst_qmutokenparser.h"
#include "../qmuparser/qmutokenparser.h"
#include <QtTest>
//---------------------------------------------------------------------------------------------------------------------
TST_QmuTokenParser::TST_QmuTokenParser(QObject *parent)
:QObject(parent)
{
}
//---------------------------------------------------------------------------------------------------------------------
void TST_QmuTokenParser::IsSingle_data()
{
QTest::addColumn<QString>("formula");
QTest::addColumn<bool>("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);
}

View file

@ -0,0 +1,46 @@
/************************************************************************
**
** @file tst_qmutokenparser.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef TST_QMUTOKENPARSER_H
#define TST_QMUTOKENPARSER_H
#include <QObject>
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