QA: Add numeric evaluator tests

Remove obsolete and unbuildable common/libeval/main.cpp
test program.
This commit is contained in:
John Beard 2018-11-28 12:48:45 +00:00 committed by Maciej Suminski
parent 0bceb69fe9
commit 49c723fc83
3 changed files with 233 additions and 52 deletions

View File

@ -1,52 +0,0 @@
/*
This file is part of libeval, a simple math expression evaluator
Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com
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 3 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 <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <assert.h>
#include "numeric_evaluator.h"
int main()
{
NumericEvaluator eval;
eval.process("2.54mm+50mil");
if (eval.isValid()) printf("%s\n", eval.result());
eval.process("x=1; y=5;");
if (eval.isValid()) printf("%s\n", eval.result());
eval.process("x+y");
if (eval.isValid()) printf("%s\n", eval.result());
eval.setVar("posx", -3.14152);
bool retval = eval.process("posx");
assert(retval == eval.isValid());
if (eval.isValid()) printf("%s\n", eval.result());
eval.process("x=1; y=2");
eval.setVar("z", 3);
eval.process("x+y+z");
printf("x+y+z=%s\n", eval.result());
eval.process("1\"");
printf("1\" = %s\n", eval.result());
eval.process("12.7 - 0.1\" - 50mil");
printf("12.7 - 0.1\" - 50mil = %s\n", eval.result());
}

View File

@ -40,6 +40,8 @@ add_executable( qa_common
test_title_block.cpp test_title_block.cpp
test_utf8.cpp test_utf8.cpp
libeval/test_numeric_evaluator.cpp
geometry/test_fillet.cpp geometry/test_fillet.cpp
view/test_zoom_controller.cpp view/test_zoom_controller.cpp

View File

@ -0,0 +1,231 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file test_numeric_evaluator.cpp
* Test suite for #NUMERIC_EVALUATOR
*/
#include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp>
#include <libeval/numeric_evaluator.h>
struct NUM_EVAL_FIXTURE
{
NUM_EVAL_FIXTURE() : m_eval( EDA_UNITS_T::MILLIMETRES, false )
{
}
NUMERIC_EVALUATOR m_eval;
};
/**
* Declares the struct as the Boost test fixture.
*/
BOOST_FIXTURE_TEST_SUITE( NumericEvaluator, NUM_EVAL_FIXTURE )
/**
* Struct representing a test case for #NUMERIC_EVALUATOR
*/
struct EVAL_CASE
{
wxString input;
wxString exp_result;
};
/**
* Basic class ops: set one up, trivial input, tear it down
*/
BOOST_AUTO_TEST_CASE( Basic )
{
m_eval.Process( "1" );
BOOST_CHECK_EQUAL( m_eval.Result(), "1" );
}
/**
* Check that getting/setting vars works
*/
BOOST_AUTO_TEST_CASE( SetVar )
{
m_eval.SetVar( "MoL", 42 );
m_eval.Process( "1 + MoL" );
BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 42 );
BOOST_CHECK_EQUAL( m_eval.Result(), "43" );
m_eval.SetVar( "MoL", 422 );
// have to process again to re-evaluate
m_eval.Process( "1 + MoL" );
BOOST_CHECK_EQUAL( m_eval.Result(), "423" );
// Can remove one var
m_eval.SetVar( "pi", 3.14 );
BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 3.14 );
m_eval.RemoveVar( "pi" );
BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 0.0 );
// Other is still there
BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 422 );
// Add another one back
m_eval.SetVar( "piish", 3.1 );
// String clear doesn't clear vars
m_eval.Clear();
m_eval.Process( "1 + MoL + piish" );
BOOST_CHECK_EQUAL( m_eval.Result(), "426.1" );
// Clear both
m_eval.ClearVar();
BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 0.0 );
BOOST_CHECK_EQUAL( m_eval.GetVar( "piish" ), 0.0 );
}
/**
* A list of valid test strings and the expected results
*/
static const std::vector<EVAL_CASE> eval_cases_valid = {
// Empty case
{ "", "0" },
// Trivial eval
{ "1", "1" },
// Decimal separators
{ "1.5", "1.5" },
{ "1,5", "1.5" },
// Semicolon is valid, but the result is NaN
{ "1;", "nan" },
// With own unit
{ "1mm", "1" },
// Unit that's not the evaluator's unit
{ "1in", "25.4" },
// Unit with white-space
{ "1 in", "25.4" },
// Unit-less arithmetic
{ "1+2", "3" },
// Multiple units
{ "1 + 10mm + 1\" + 1.5in + 500mil", "87.2" },
// Any White-space is OK
{ " 1 + 2 ", "3" },
// Decimals are OK in expressions
{ "1.5 + 0.2 + .1", "1.8" },
// Negatives are OK
{ "3 - 10", "-7" },
// Lots of operands
{ "1 + 2 + 10 + 1000.05", "1013.05" },
// Operator precedence
{ "1 + 2 - 4 * 20 / 2", "-37" },
// Parens
{ "(1)", "1" },
// Parens affect precedence
{ "-(1 + (2 - 4)) * 20.8 / 2", "10.4" },
// Unary addition, not a leading operator
//{ "+2 - 1", "1" } // TODO: This does not come out as valid
// Unknown vars are 0.0
{ "1 + unknown", "1" },
// Set var in-string
{ "x = 1; 1 + x", "2" },
// Multiple set vars
{ "x = 1; y = 2; 10 + x - y", "9" },
};
/**
* Run through a set of test strings, clearing in between
*/
BOOST_AUTO_TEST_CASE( Results )
{
for( const auto& c : eval_cases_valid )
{
// Clear for new string input
m_eval.Clear();
m_eval.Process( c.input );
// These are all valid
BOOST_CHECK_EQUAL( m_eval.IsValid(), true );
BOOST_CHECK_EQUAL( m_eval.Result(), c.exp_result );
// Does original text still match?
BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
}
}
struct EVAL_INVALID_CASE
{
wxString input;
};
/**
* A list of invalid test strings
*/
static const std::vector<EVAL_INVALID_CASE> eval_cases_invalid = {
// Trailing operator
{ "1+" },
// Leading operator
{ "+2 + 1" },
{ "*2 + 1" },
// No operator
{ "1 2" },
{ "(1)(2)" },
// Unknown operator
{ "1 $ 2" },
// Mismatched parens
{ "(1 + 2" },
{ "1 + 2)" },
// random text
{ "sdfsdf sdfsd" },
// Div by 0
{ "1 / 0" },
{ "1 / unknown" },
// Semicolons can't be empty or redundant
{ ";" },
{ ";1" },
{ ";1;" },
};
/**
* Run through a set of invalid test strings, clearing in between
*/
BOOST_AUTO_TEST_CASE( ResultsInvalid )
{
for( const auto& c : eval_cases_invalid )
{
// Clear for new string input
m_eval.Clear();
m_eval.Process( c.input );
// These are all valid
BOOST_CHECK_EQUAL( m_eval.IsValid(), false );
// Does original text still match?
BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
}
}
BOOST_AUTO_TEST_SUITE_END()