KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_numeric_evaluator.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
30
32
34{
36 {
37 }
38
40};
41
42
46BOOST_FIXTURE_TEST_SUITE( NumericEvaluator, NUM_EVAL_FIXTURE )
47
48
49
53{
54 wxString input;
55 wxString exp_result;
56};
57
58
63{
64 m_eval.Process( "1" );
65 BOOST_CHECK_EQUAL( m_eval.Result(), "1" );
66}
67
72{
73 m_eval.SetVar( "MoL", 42 );
74
75 m_eval.Process( "1 + MoL" );
76 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 42 );
77 BOOST_CHECK_EQUAL( m_eval.Result(), "43" );
78
79 m_eval.SetVar( "MoL", 422 );
80
81 // have to process again to re-evaluate
82 m_eval.Process( "1 + MoL" );
83 BOOST_CHECK_EQUAL( m_eval.Result(), "423" );
84
85 // Can remove one var
86 m_eval.SetVar( "pi", 3.14 );
87 BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 3.14 );
88 m_eval.RemoveVar( "pi" );
89 BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 0.0 );
90
91 // Other is still there
92 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 422 );
93
94 // Add another one back
95 m_eval.SetVar( "piish", 3.1 );
96
97 // String clear doesn't clear vars
98 m_eval.Clear();
99 m_eval.Process( "1 + MoL + piish" );
100 BOOST_CHECK_EQUAL( m_eval.Result(), "426.1" );
101
102 // Clear both
103 m_eval.ClearVar();
104 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 0.0 );
105 BOOST_CHECK_EQUAL( m_eval.GetVar( "piish" ), 0.0 );
106}
107
111static const std::vector<EVAL_CASE> eval_cases_valid = {
112 // Empty case
113 { "", "0" },
114 // Trivial eval
115 { "1", "1" },
116 // Decimal separators
117 { "1.5", "1.5" },
118 { "1,5", "1.5" },
119 // Semicolon is valid, but the result is NaN
120 { "1;", "NaN" },
121 // With own unit
122 { "1mm", "1" },
123 // Unit that's not the evaluator's unit
124 { "1in", "25.4" },
125 // Unit with white-space
126 { "1 in", "25.4" },
127 // Unit-less arithmetic
128 { "1+2", "3" },
129 // Multiple units
130 { "1 + 10mm + 1\" + 1.5in + 500mil", "87.2" },
131 // Any White-space is OK
132 { " 1 + 2 ", "3" },
133 // Decimals are OK in expressions
134 { "1.5 + 0.2 + .1", "1.8" },
135 // Negatives are OK
136 { "3 - 10", "-7" },
137 // Lots of operands
138 { "1 + 2 + 10 + 1000.05", "1013.05" },
139 // Operator precedence
140 { "1 + 2 - 4 * 20 / 2", "-37" },
141 // Parens
142 { "(1)", "1" },
143 // Parens affect precedence
144 { "-(1 + (2 - 4)) * 20.8 / 2", "10.4" },
145 // Unary addition is a sign, not a leading operator
146 { "+2 - 1", "1" },
147 // Set var in-string
148 { "x = 1; 1 + x", "2" },
149 // Multiple set vars
150 { "x = 1; y = 2; 10 + x - y", "9" },
151
152 // Unicode units - these currently fail
153// { wxT( "1um" ), "0.001" }, // GREEK SMALL LETTER MU
154// { wxT( "1µm" ), "0.001" }, // GREEK SMALL LETTER MU
155// { wxT( "1 µm" ), "0.001" }, // GREEK SMALL LETTER MU
156// { wxT( "1µm" ), "0.001" }, // MICRO SIGN
157// { wxT( "1 µm" ), "0.001" }, // MICRO SIGN
158};
159
160
165{
166 for( const auto& c : eval_cases_valid )
167 {
168 BOOST_TEST_CONTEXT( c.input + " -> " + c.exp_result )
169 {
170 // Clear for new string input
171 m_eval.Clear();
172
173 m_eval.Process( c.input );
174
175 // These are all valid
176 BOOST_CHECK_EQUAL( m_eval.IsValid(), true );
177 BOOST_CHECK_EQUAL( m_eval.Result(), c.exp_result );
178
179 // Does original text still match?
180 BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
181 }
182 }
183}
184
185
189BOOST_AUTO_TEST_CASE( UnicodeDegree )
190{
191 wxString degreeInput = wxT( "1\u00B0" );
192
193 // Set to degrees and make ready for input
194 m_eval.SetDefaultUnits( EDA_UNITS::DEGREES );
195 m_eval.Clear();
196
197 m_eval.Process( degreeInput );
198
199 // These are all valid
200 BOOST_CHECK_EQUAL( m_eval.IsValid(), true );
201
202// Currently disabled since the parser doesn't parse the unicode correctly
203 //BOOST_CHECK_EQUAL( m_eval.Result(), degreeInput );
204
205 // Does original text still match?
206 BOOST_CHECK_EQUAL( m_eval.OriginalText(), degreeInput );
207}
208
209
211{
212 wxString input;
213};
214
218static const std::vector<EVAL_INVALID_CASE> eval_cases_invalid = {
219 // Trailing operator
220 { "1+" },
221 // Leading operator
222 { "*2 + 1" },
223 // No operator
224 { "1 2" },
225 { "(1)(2)" },
226 // Unknown operator
227 { "1 $ 2" },
228 // Mismatched parens
229 { "(1 + 2" },
230 { "1 + 2)" },
231 // random text
232 { "sdfsdf sdfsd" },
233 // Div by 0
234 { "1 / 0" },
235 // Unknown vars are errors
236 { "1 + unknown" },
237 // Semicolons can't be empty or redundant
238 { ";" },
239 { ";1" },
240 { ";1;" },
241};
242
246BOOST_AUTO_TEST_CASE( ResultsInvalid )
247{
248 for( const auto& c : eval_cases_invalid )
249 {
250 BOOST_TEST_CONTEXT( c.input )
251 {
252 // Clear for new string input
253 m_eval.Clear();
254
255 m_eval.Process( c.input );
256
257 // These are all valid
258 BOOST_CHECK_EQUAL( m_eval.IsValid(), false );
259
260 // Does original text still match?
261 BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
262 }
263 }
264}
265
266BOOST_AUTO_TEST_SUITE_END()
EDA_UNITS
Definition: eda_units.h:46
Declares the struct as the Boost test fixture.
NUMERIC_EVALUATOR m_eval
static const std::vector< EVAL_INVALID_CASE > eval_cases_invalid
A list of invalid test strings.
BOOST_AUTO_TEST_CASE(Basic)
Basic class ops: set one up, trivial input, tear it down.
static const std::vector< EVAL_CASE > eval_cases_valid
A list of valid test strings and the expected results.
#define BOOST_TEST_CONTEXT(A)