Ported PlaceholderParser unit tests to C++.

This commit is contained in:
bubnikv 2020-01-21 12:10:02 +01:00
parent 6eaf48ebd8
commit 05ea01bdcc
5 changed files with 79 additions and 70 deletions

View File

@ -1152,7 +1152,8 @@ namespace client
[ px::bind(&expr<Iterator>::min, _val, _2) ] [ px::bind(&expr<Iterator>::min, _val, _2) ]
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')') | (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
[ px::bind(&expr<Iterator>::max, _val, _2) ] [ px::bind(&expr<Iterator>::max, _val, _2) ]
| (kw["int"] > '(' > unary_expression(_r1) ) [ px::bind(&FactorActions::to_int, _1, _val) ] //FIXME this is likley not correct
| (kw["int"] > '(' > unary_expression(_r1) /* > ')' */ ) [ px::bind(&FactorActions::to_int, _1, _val) ]
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ] | (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ] | (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
| (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ] | (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]

View File

@ -41,7 +41,7 @@ public:
// Fill in the template using a macro processing language. // Fill in the template using a macro processing language.
// Throws std::runtime_error on syntax or runtime error. // Throws std::runtime_error on syntax or runtime error.
std::string process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override = nullptr) const; std::string process(const std::string &templ, unsigned int current_extruder_id = 0, const DynamicConfig *config_override = nullptr) const;
// Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax. // Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax.
// Throws std::runtime_error on syntax or runtime error. // Throws std::runtime_error on syntax or runtime error.

View File

@ -1,4 +1,4 @@
use Test::More tests => 81; use Test::More tests => 41;
use strict; use strict;
use warnings; use warnings;
@ -45,73 +45,6 @@ use Slic3r::Test;
#========================================================== #==========================================================
{
my $parser = Slic3r::GCode::PlaceholderParser->new;
my $config = Slic3r::Config::new_from_defaults;
$config->set('printer_notes', ' PRINTER_VENDOR_PRUSA3D PRINTER_MODEL_MK2 ');
$config->set('nozzle_diameter', [0.6,0.6,0.6,0.6]);
$parser->apply_config($config);
$parser->set('foo' => 0);
$parser->set('bar' => 2);
$parser->set('num_extruders' => 4);
is $parser->process('[temperature_[foo]]'),
$config->temperature->[0],
"nested config options (legacy syntax)";
is $parser->process('{temperature[foo]}'),
$config->temperature->[0],
"array reference";
is $parser->process("test [ temperature_ [foo] ] \n hu"),
"test " . $config->temperature->[0] . " \n hu",
"whitespaces and newlines are maintained";
is $parser->process('{2*3}'), '6', 'math: 2*3';
is $parser->process('{2*3/6}'), '1', 'math: 2*3/6';
is $parser->process('{2*3/12}'), '0', 'math: 2*3/12';
ok abs($parser->process('{2.*3/12}') - 0.5) < 1e-7, 'math: 2.*3/12';
is $parser->process('{10%2.5}') '0', 'math: 10 % 2.5';
is $parser->process('{11/2.5-1}') '1', 'math: 11 % 2.5';
is $parser->process('{2*(3-12)}'), '-18', 'math: 2*(3-12)';
is $parser->process('{2*foo*(3-12)}'), '0', 'math: 2*foo*(3-12)';
is $parser->process('{2*bar*(3-12)}'), '-36', 'math: 2*bar*(3-12)';
ok abs($parser->process('{2.5*bar*(3-12)}') - -45) < 1e-7, 'math: 2.5*bar*(3-12)';
is $parser->process('{min(12, 14)}'), '12', 'math: min(12, 14)';
is $parser->process('{max(12, 14)}'), '14', 'math: max(12, 14)';
is $parser->process('{min(13.4, -1238.1)}'), '-1238.1', 'math: min(13.4, -1238.1)';
is $parser->process('{max(13.4, -1238.1)}'), '13.4', 'math: max(13.4, -1238.1)';
is $parser->process('{int(13.4)}'), '13', 'math: int(13.4)';
# Test the boolean expression parser.
is $parser->evaluate_boolean_expression('12 == 12'), 1, 'boolean expression parser: 12 == 12';
is $parser->evaluate_boolean_expression('12 != 12'), 0, 'boolean expression parser: 12 != 12';
is $parser->evaluate_boolean_expression('"has some PATTERN embedded" =~ /.*PATTERN.*/'), 1, 'boolean expression parser: regex matches';
is $parser->evaluate_boolean_expression('"has some PATTERN embedded" =~ /.*PTRN.*/'), 0, 'boolean expression parser: regex does not match';
is $parser->evaluate_boolean_expression('foo + 2 == bar'), 1, 'boolean expression parser: accessing variables, equal';
is $parser->evaluate_boolean_expression('foo + 3 == bar'), 0, 'boolean expression parser: accessing variables, not equal';
is $parser->evaluate_boolean_expression('(12 == 12) and (13 != 14)'), 1, 'boolean expression parser: (12 == 12) and (13 != 14)';
is $parser->evaluate_boolean_expression('(12 == 12) && (13 != 14)'), 1, 'boolean expression parser: (12 == 12) && (13 != 14)';
is $parser->evaluate_boolean_expression('(12 == 12) or (13 == 14)'), 1, 'boolean expression parser: (12 == 12) or (13 == 14)';
is $parser->evaluate_boolean_expression('(12 == 12) || (13 == 14)'), 1, 'boolean expression parser: (12 == 12) || (13 == 14)';
is $parser->evaluate_boolean_expression('(12 == 12) and not (13 == 14)'), 1, 'boolean expression parser: (12 == 12) and not (13 == 14)';
is $parser->evaluate_boolean_expression('(12 == 12) ? (1 - 1 == 0) : (2 * 2 == 3)'), 1, 'boolean expression parser: ternary true';
is $parser->evaluate_boolean_expression('(12 == 21/2) ? (1 - 1 == 0) : (2 * 2 == 3)'), 0, 'boolean expression parser: ternary false';
is $parser->evaluate_boolean_expression('(12 == 13) ? (1 - 1 == 3) : (2 * 2 == 4)'), 1, 'boolean expression parser: ternary false';
is $parser->evaluate_boolean_expression('(12 == 2 * 6) ? (1 - 1 == 3) : (2 * 2 == 4)'), 0, 'boolean expression parser: ternary true';
is $parser->evaluate_boolean_expression('12 < 3'), 0, 'boolean expression parser: lower than - false';
is $parser->evaluate_boolean_expression('12 < 22'), 1, 'boolean expression parser: lower than - true';
is $parser->evaluate_boolean_expression('12 > 3'), 1, 'boolean expression parser: greater than - true';
is $parser->evaluate_boolean_expression('12 > 22'), 0, 'boolean expression parser: greater than - false';
is $parser->evaluate_boolean_expression('12 <= 3'), 0, 'boolean expression parser: lower than or equal- false';
is $parser->evaluate_boolean_expression('12 <= 22'), 1, 'boolean expression parser: lower than or equal - true';
is $parser->evaluate_boolean_expression('12 >= 3'), 1, 'boolean expression parser: greater than or equal - true';
is $parser->evaluate_boolean_expression('12 >= 22'), 0, 'boolean expression parser: greater than or equal - false';
is $parser->evaluate_boolean_expression('12 <= 12'), 1, 'boolean expression parser: lower than or equal (same values) - true';
is $parser->evaluate_boolean_expression('12 >= 12'), 1, 'boolean expression parser: greater than or equal (same values) - true';
is $parser->evaluate_boolean_expression('printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1'), 1, 'complex expression';
is $parser->evaluate_boolean_expression('printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.6 and num_extruders>1)'), 1, 'complex expression2';
is $parser->evaluate_boolean_expression('printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.3 and num_extruders>1)'), 0, 'complex expression3';
}
{ {
my $config = Slic3r::Config::new_from_defaults; my $config = Slic3r::Config::new_from_defaults;
$config->set('output_filename_format', 'ts_[travel_speed]_lh_[layer_height].gcode'); $config->set('output_filename_format', 'ts_[travel_speed]_lh_[layer_height].gcode');

View File

@ -7,6 +7,7 @@ add_executable(${_TEST_NAME}_tests
test_config.cpp test_config.cpp
test_elephant_foot_compensation.cpp test_elephant_foot_compensation.cpp
test_geometry.cpp test_geometry.cpp
test_placeholder_parser.cpp
test_polygon.cpp test_polygon.cpp
test_stl.cpp test_stl.cpp
) )

View File

@ -0,0 +1,74 @@
#include <catch2/catch.hpp>
#include "libslic3r/PlaceholderParser.hpp"
#include "libslic3r/PrintConfig.hpp"
using namespace Slic3r;
SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
PlaceholderParser parser;
auto config = DynamicPrintConfig::full_print_config();
config.set_deserialize( {
{ "printer_notes", " PRINTER_VENDOR_PRUSA3D PRINTER_MODEL_MK2 " },
{ "nozzle_diameter", "0.6;0.6;0.6;0.6" },
{ "temperature", "357;359;363;378" }
});
parser.apply_config(config);
parser.set("foo", 0);
parser.set("bar", 2);
parser.set("num_extruders", 4);
SECTION("nested config options (legacy syntax)") { REQUIRE(parser.process("[temperature_[foo]]") == "357"); }
SECTION("array reference") { REQUIRE(parser.process("{temperature[foo]}") == "357"); }
SECTION("whitespaces and newlines are maintained") { REQUIRE(parser.process("test [ temperature_ [foo] ] \n hu") == "test 357 \n hu"); }
// Test the math expressions.
SECTION("math: 2*3") { REQUIRE(parser.process("{2*3}") == "6"); }
SECTION("math: 2*3/6") { REQUIRE(parser.process("{2*3/6}") == "1"); }
SECTION("math: 2*3/12") { REQUIRE(parser.process("{2*3/12}") == "0"); }
SECTION("math: 2.*3/12") { REQUIRE(std::stod(parser.process("{2.*3/12}")) == Approx(0.5)); }
// SECTION("math: 10 % 2.5") { REQUIRE(parser.process("{10%2.5}") == "0"); }
// SECTION("math: 11 / 2.5") { REQUIRE(parser.process("{11/2.5-1}") == "1"); }
SECTION("math: 2*(3-12)") { REQUIRE(parser.process("{2*(3-12)}") == "-18"); }
SECTION("math: 2*foo*(3-12)") { REQUIRE(parser.process("{2*foo*(3-12)}") == "0"); }
SECTION("math: 2*bar*(3-12)") { REQUIRE(parser.process("{2*bar*(3-12)}") == "-36"); }
SECTION("math: 2.5*bar*(3-12)") { REQUIRE(std::stod(parser.process("{2.5*bar*(3-12)}")) == Approx(-45)); }
SECTION("math: min(12, 14)") { REQUIRE(parser.process("{min(12, 14)}") == "12"); }
SECTION("math: max(12, 14)") { REQUIRE(parser.process("{max(12, 14)}") == "14"); }
SECTION("math: min(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{min(13.4, -1238.1)}")) == Approx(-1238.1)); }
SECTION("math: max(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{max(13.4, -1238.1)}")) == Approx(13.4)); }
// SECTION("math: int(13.4)") { REQUIRE(parser.process("{int(13.4)}") == "13"); }
// Test the boolean expression parser.
auto boolean_expression = [&parser](const std::string& templ) { return parser.evaluate_boolean_expression(templ, parser.config()); };
SECTION("boolean expression parser: 12 == 12") { REQUIRE(boolean_expression("12 == 12")); }
SECTION("boolean expression parser: 12 != 12") { REQUIRE(! boolean_expression("12 != 12")); }
SECTION("boolean expression parser: regex matches") { REQUIRE(boolean_expression("\"has some PATTERN embedded\" =~ /.*PATTERN.*/")); }
SECTION("boolean expression parser: regex does not match") { REQUIRE(! boolean_expression("\"has some PATTERN embedded\" =~ /.*PTRN.*/")); }
SECTION("boolean expression parser: accessing variables, equal") { REQUIRE(boolean_expression("foo + 2 == bar")); }
SECTION("boolean expression parser: accessing variables, not equal") { REQUIRE(! boolean_expression("foo + 3 == bar")); }
SECTION("boolean expression parser: (12 == 12) and (13 != 14)") { REQUIRE(boolean_expression("(12 == 12) and (13 != 14)")); }
SECTION("boolean expression parser: (12 == 12) && (13 != 14)") { REQUIRE(boolean_expression("(12 == 12) && (13 != 14)")); }
SECTION("boolean expression parser: (12 == 12) or (13 == 14)") { REQUIRE(boolean_expression("(12 == 12) or (13 == 14)")); }
SECTION("boolean expression parser: (12 == 12) || (13 == 14)") { REQUIRE(boolean_expression("(12 == 12) || (13 == 14)")); }
SECTION("boolean expression parser: (12 == 12) and not (13 == 14)") { REQUIRE(boolean_expression("(12 == 12) and not (13 == 14)")); }
SECTION("boolean expression parser: ternary true") { REQUIRE(boolean_expression("(12 == 12) ? (1 - 1 == 0) : (2 * 2 == 3)")); }
SECTION("boolean expression parser: ternary false") { REQUIRE(! boolean_expression("(12 == 21/2) ? (1 - 1 == 0) : (2 * 2 == 3)")); }
SECTION("boolean expression parser: ternary false 2") { REQUIRE(boolean_expression("(12 == 13) ? (1 - 1 == 3) : (2 * 2 == 4)")); }
SECTION("boolean expression parser: ternary true 2") { REQUIRE(! boolean_expression("(12 == 2 * 6) ? (1 - 1 == 3) : (2 * 2 == 4)")); }
SECTION("boolean expression parser: lower than - false") { REQUIRE(! boolean_expression("12 < 3")); }
SECTION("boolean expression parser: lower than - true") { REQUIRE(boolean_expression("12 < 22")); }
SECTION("boolean expression parser: greater than - true") { REQUIRE(boolean_expression("12 > 3")); }
SECTION("boolean expression parser: greater than - false") { REQUIRE(! boolean_expression("12 > 22")); }
SECTION("boolean expression parser: lower than or equal- false") { REQUIRE(! boolean_expression("12 <= 3")); }
SECTION("boolean expression parser: lower than or equal - true") { REQUIRE(boolean_expression("12 <= 22")); }
SECTION("boolean expression parser: greater than or equal - true") { REQUIRE(boolean_expression("12 >= 3")); }
SECTION("boolean expression parser: greater than or equal - false") { REQUIRE(! boolean_expression("12 >= 22")); }
SECTION("boolean expression parser: lower than or equal (same values) - true") { REQUIRE(boolean_expression("12 <= 12")); }
SECTION("boolean expression parser: greater than or equal (same values) - true") { REQUIRE(boolean_expression("12 >= 12")); }
SECTION("complex expression") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1")); }
SECTION("complex expression2") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.6 and num_extruders>1)")); }
SECTION("complex expression3") { REQUIRE(! boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.3 and num_extruders>1)")); }
}