35 return aStream << unitStr.ToStdString();
115 {
"@{}",
"@{}",
true },
118 {
"@{1}",
"1",
false },
121 {
"@{1.5}",
"1.5",
false },
125 {
"@{1+2}",
"3",
false },
126 {
"@{1 + 2}",
"3",
false },
127 {
"@{1.5 + 0.2 + 0.1}",
"1.8",
false },
128 {
"@{3 - 10}",
"-7",
false },
129 {
"@{1 + 2 + 10 + 1000.05}",
"1013.05",
false },
132 {
"@{1 + 2 - 4 * 20 / 2}",
"-37",
false },
135 {
"@{(1)}",
"1",
false },
136 {
"@{-(1 + (2 - 4)) * 20.8 / 2}",
"10.4",
false },
139 {
"@{+2 - 1}",
"1",
false },
147 {
"@{1+}",
"",
true },
150 {
"@{*2 + 1}",
"",
true },
153 {
"@{1 / 0}",
"",
true },
156 {
"@{1 + ${unknown}}",
"@{1 + ${unknown}}",
true },
159 {
"@{(1 + 2}",
"",
true },
160 {
"@{1 + 2)}",
"",
true },
163 {
"@{1 $ 2}",
"",
true },
179 if( testCase.shouldError )
209 if( testCase.input.Contains(
"${unknown}" ) )
234 const std::vector<VarTestCase> varCases = {
235 {
"@{${x}}",
"10",
false },
236 {
"@{${y}}",
"5",
false },
237 {
"@{${x} + ${y}}",
"15",
false },
238 {
"@{${x} * ${y}}",
"50",
false },
239 {
"@{${x} - ${y}}",
"5",
false },
240 {
"@{${x} / ${y}}",
"2",
false },
241 {
"@{(${x} + ${y}) * 2}",
"30",
false },
244 {
"@{${undefined}}",
"@{${undefined}}",
true },
247 {
"@{${x} + ${undefined}}",
"@{${x} + ${undefined}}",
true },
250 for(
const auto& testCase : varCases )
256 if( testCase.shouldError )
277 struct MathTestCase {
283 const std::vector<MathTestCase> mathCases = {
285 {
"@{abs(-5)}",
"5",
false },
286 {
"@{min(3, 7)}",
"3",
false },
287 {
"@{max(3, 7)}",
"7",
false },
288 {
"@{sqrt(16)}",
"4",
false },
289 {
"@{ceil(3.2)}",
"4",
false },
290 {
"@{floor(3.8)}",
"3",
false },
291 {
"@{round(3.6)}",
"4",
false },
292 {
"@{pow(2, 3)}",
"8",
false },
295 {
"@{sum(1, 2, 3)}",
"6",
false },
296 {
"@{avg(2, 4, 6)}",
"4",
false },
299 for(
const auto& testCase : mathCases )
305 if( testCase.shouldError )
340 BOOST_CHECK( !evaluator_mm.
HasErrors() );
344 if (varName ==
"width") {
356 BOOST_CHECK( !evaluator_callback.
HasErrors() );
411 persistent_eval.
Evaluate(
"@{1 + 1}" );
417 persistent_eval.
Evaluate(
"@{${test} + 8}" );
443 double numeric_result = wxAtof(
result );
444 BOOST_CHECK_CLOSE( numeric_result, 38.1, 0.01 );
450 result = evaluator_mm.
Evaluate(
"@{${inch_in_mm} + ${mil_in_mm}}" );
462 result = evaluator_mm.
Evaluate(
"@{${one_inch} + ${thousand_mils}}" );
518 std::cout <<
"DEBUG: @{1in} returned '" <<
result.ToStdString() <<
"'" << std::endl;
520 std::cout <<
"DEBUG: @{1in} Errors: " << evaluator_mm.
GetErrorSummary().ToStdString() << std::endl;
564 double result_val = wxAtof(
result);
565 BOOST_CHECK(
std::abs(result_val - 1.0) < 0.001 );
586 double result_val2 = wxAtof(
result);
587 BOOST_CHECK(
std::abs(result_val2 - 76.2) < 0.001 );
598 wxString
result = evaluator_mm.Evaluate(
"@{1xyz}" );
603 result = evaluator_mm.Evaluate(
"@{25.4}" );
607 result = evaluator_mm.Evaluate(
"@{0mm}" );
610 result = evaluator_mm.Evaluate(
"@{0in}" );
614 result = evaluator_mm.Evaluate(
"@{2.54cm}" );
617 result = evaluator_mm.Evaluate(
"@{0.5in}" );
621 result = evaluator_mm.Evaluate(
"@{1um}" );
633 BOOST_CHECK( eval.
Process(
"1 + 2" ) );
642 BOOST_CHECK( eval.
Process(
"x + y" ) );
647 BOOST_CHECK_CLOSE( eval.
GetVar(
"x" ), 5.0, 0.001 );
648 BOOST_CHECK_CLOSE( eval.
GetVar(
"y" ), 3.0, 0.001 );
649 BOOST_CHECK_CLOSE( eval.
GetVar(
"undefined" ), 0.0, 0.001 );
652 BOOST_CHECK( eval.
Process(
"1in + 1mm" ) );
657 BOOST_CHECK( eval.
Process(
"sqrt(16)" ) );
662 BOOST_CHECK( !eval.
Process(
"1 + * 2" ) );
663 BOOST_CHECK( !eval.
IsValid() );
667 BOOST_CHECK_CLOSE( eval.
GetVar(
"x" ), 5.0, 0.001 );
669 BOOST_CHECK( eval.
Process(
"x * 2" ) );
675 BOOST_CHECK_CLOSE( eval.
GetVar(
"x" ), 0.0, 0.001 );
676 BOOST_CHECK_CLOSE( eval.
GetVar(
"y" ), 3.0, 0.001 );
680 BOOST_CHECK_CLOSE( eval.
GetVar(
"y" ), 0.0, 0.001 );
683 BOOST_CHECK( eval.
Process(
"42" ) );
689 BOOST_CHECK( eval.
Process(
"3.14" ) );
707 BOOST_CHECK_CLOSE( wxAtof(
result ), 1.016, 0.01 );
711 BOOST_CHECK_CLOSE( wxAtof(
result ), 10.0, 0.01 );
716 BOOST_CHECK_CLOSE( wxAtof(
result ), 1.0, 0.01 );
721 BOOST_CHECK_CLOSE( wxAtof(
result ), 2.016, 0.01 );
726 BOOST_CHECK_CLOSE( wxAtof(
result ), 1000.0, 0.01 );
731 BOOST_CHECK_CLOSE( wxAtof(
result ), 0.04, 0.01 );
736 BOOST_CHECK_CLOSE( wxAtof(
result ), 2.54, 0.01 );
High-level wrapper for evaluating mathematical and string expressions in wxString format.
EDA_UNITS GetDefaultUnits() const
Get the current default units.
bool HasVariableCallback() const
Check if a custom variable callback is set.
wxString Evaluate(const wxString &aInput)
Main evaluation function - processes input string and evaluates all} expressions.
bool RemoveVariable(const wxString &aName)
Remove a variable from the evaluator.
bool HasErrors() const
Check if the last evaluation had errors.
wxString GetErrorSummary() const
Get detailed error information from the last evaluation.
void SetDefaultUnits(EDA_UNITS aUnits)
Set the default units for expressions.
void ClearVariables()
Clear all stored variables.
bool HasVariable(const wxString &aName) const
Check if a variable exists in stored variables.
void SetVariable(const wxString &aName, double aValue)
Set a numeric variable for use in expressions.
NUMERIC_EVALUATOR compatible wrapper around EXPRESSION_EVALUATOR.
void LocaleChanged()
Handle locale changes (for decimal separator)
bool Process(const wxString &aString)
Process and evaluate an expression.
wxString Result() const
Get the result of the last evaluation.
void RemoveVar(const wxString &aString)
Remove a single variable.
void SetVar(const wxString &aString, double aValue)
Set a variable value.
void ClearVar()
Remove all variables.
double GetVar(const wxString &aString)
Get a variable value.
void Clear()
Clear parser state but retain variables.
bool IsValid() const
Check if the last evaluation was successful.
wxString OriginalText() const
Get the original input text.
KICOMMON_API wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
auto MakeValue(T aVal) -> Result< T >
auto MakeError(std::string aMsg) -> Result< T >
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
static const std::vector< EVAL_INVALID_CASE > eval_cases_invalid
A list of invalid test strings.
static const std::vector< EVAL_CASE > eval_cases_valid
A list of valid test strings and the expected results.
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_AUTO_TEST_CASE(Basic)
Basic functionality test.
std::ostream & operator<<(std::ostream &aStream, EDA_UNITS aUnits)
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")