KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 The 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{
37 {
38 }
39
41};
42
43
47BOOST_FIXTURE_TEST_SUITE( NumericEvaluator, NUM_EVAL_FIXTURE )
48
49
50
54{
55 wxString input;
56 wxString exp_result;
57};
58
59
64{
65 m_eval.Process( "1" );
66 BOOST_CHECK_EQUAL( m_eval.Result(), "1" );
67}
68
73{
74 m_eval.SetVar( "MoL", 42 );
75
76 m_eval.Process( "1 + MoL" );
77 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 42 );
78 BOOST_CHECK_EQUAL( m_eval.Result(), "43" );
79
80 m_eval.SetVar( "MoL", 422 );
81
82 // have to process again to re-evaluate
83 m_eval.Process( "1 + MoL" );
84 BOOST_CHECK_EQUAL( m_eval.Result(), "423" );
85
86 // Can remove one var
87 m_eval.SetVar( "pi", 3.14 );
88 BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 3.14 );
89 m_eval.RemoveVar( "pi" );
90 BOOST_CHECK_EQUAL( m_eval.GetVar( "pi" ), 0.0 );
91
92 // Other is still there
93 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 422 );
94
95 // Add another one back
96 m_eval.SetVar( "piish", 3.1 );
97
98 // String clear doesn't clear vars
99 m_eval.Clear();
100 m_eval.Process( "1 + MoL + piish" );
101 BOOST_CHECK_EQUAL( m_eval.Result(), "426.1" );
102
103 // Clear both
104 m_eval.ClearVar();
105 BOOST_CHECK_EQUAL( m_eval.GetVar( "MoL" ), 0.0 );
106 BOOST_CHECK_EQUAL( m_eval.GetVar( "piish" ), 0.0 );
107}
108
112static const std::vector<EVAL_CASE> eval_cases_valid = {
113 // Empty case
114 { "", "0" },
115 // Trivial eval
116 { "1", "1" },
117 // Decimal separators
118 { "1.5", "1.5" },
119 { "1,5", "1.5" },
120 // Semicolon is valid, but the result is NaN
121 { "1;", "NaN" },
122 // With own unit
123 { "1mm", "1" },
124 // Unit that's not the evaluator's unit
125 { "1in", "25.4" },
126 // Unit with white-space
127 { "1 in", "25.4" },
128 // Unit-less arithmetic
129 { "1+2", "3" },
130 // Multiple units
131 { "1 + 10mm + 1\" + 1.5in + 500mil", "87.2" },
132 // Any White-space is OK
133 { " 1 + 2 ", "3" },
134 // Decimals are OK in expressions
135 { "1.5 + 0.2 + .1", "1.8" },
136 // Negatives are OK
137 { "3 - 10", "-7" },
138 // Lots of operands
139 { "1 + 2 + 10 + 1000.05", "1013.05" },
140 // Operator precedence
141 { "1 + 2 - 4 * 20 / 2", "-37" },
142 // Parens
143 { "(1)", "1" },
144 // Parens affect precedence
145 { "-(1 + (2 - 4)) * 20.8 / 2", "10.4" },
146 // Unary addition is a sign, not a leading operator
147 { "+2 - 1", "1" },
148 // Set var in-string
149 { "x = 1; 1 + x", "2" },
150 // Multiple set vars
151 { "x = 1; y = 2; 10 + x - y", "9" },
152
153 // Unicode units - these currently fail
154// { wxT( "1um" ), "0.001" }, // GREEK SMALL LETTER MU
155// { wxT( "1µm" ), "0.001" }, // GREEK SMALL LETTER MU
156// { wxT( "1 µm" ), "0.001" }, // GREEK SMALL LETTER MU
157// { wxT( "1µm" ), "0.001" }, // MICRO SIGN
158// { wxT( "1 µm" ), "0.001" }, // MICRO SIGN
159};
160
161
166{
167 for( const auto& c : eval_cases_valid )
168 {
169 BOOST_TEST_CONTEXT( c.input + " -> " + c.exp_result )
170 {
171 // Clear for new string input
172 m_eval.Clear();
173
174 m_eval.Process( c.input );
175
176 // These are all valid
177 BOOST_CHECK_EQUAL( m_eval.IsValid(), true );
178 BOOST_CHECK_EQUAL( m_eval.Result(), c.exp_result );
179
180 // Does original text still match?
181 BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
182 }
183 }
184}
185
186
190BOOST_AUTO_TEST_CASE( UnicodeDegree )
191{
192 wxString degreeInput = wxT( "1\u00B0" );
193
194 // Set to degrees and make ready for input
195 m_eval.SetDefaultUnits( EDA_UNITS::DEGREES );
196 m_eval.Clear();
197
198 m_eval.Process( degreeInput );
199
200 // These are all valid
201 BOOST_CHECK_EQUAL( m_eval.IsValid(), true );
202
203// Currently disabled since the parser doesn't parse the unicode correctly
204 //BOOST_CHECK_EQUAL( m_eval.Result(), degreeInput );
205
206 // Does original text still match?
207 BOOST_CHECK_EQUAL( m_eval.OriginalText(), degreeInput );
208}
209
210
212{
213 wxString input;
214};
215
219static const std::vector<EVAL_INVALID_CASE> eval_cases_invalid = {
220 // Trailing operator
221 { "1+" },
222 // Leading operator
223 { "*2 + 1" },
224 // No operator
225 { "1 2" },
226 { "(1)(2)" },
227 // Unknown operator
228 { "1 $ 2" },
229 // Mismatched parens
230 { "(1 + 2" },
231 { "1 + 2)" },
232 // random text
233 { "sdfsdf sdfsd" },
234 // Div by 0
235 { "1 / 0" },
236 // Unknown vars are errors
237 { "1 + unknown" },
238 // Semicolons can't be empty or redundant
239 { ";" },
240 { ";1" },
241 { ";1;" },
242};
243
247BOOST_AUTO_TEST_CASE( ResultsInvalid )
248{
249 for( const auto& c : eval_cases_invalid )
250 {
251 BOOST_TEST_CONTEXT( c.input )
252 {
253 // Clear for new string input
254 m_eval.Clear();
255
256 m_eval.Process( c.input );
257
258 // These are all valid
259 BOOST_CHECK_EQUAL( m_eval.IsValid(), false );
260
261 // Does original text still match?
262 BOOST_CHECK_EQUAL( m_eval.OriginalText(), c.input );
263 }
264 }
265}
266
EDA_UNITS
Definition: eda_units.h:46
Declares the struct as the Boost test fixture.
NUMERIC_EVALUATOR m_eval
BOOST_CHECK_EQUAL(ret, c.m_exp_result)
BOOST_AUTO_TEST_SUITE_END()
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.
BOOST_TEST_CONTEXT("Test Clearance")