From 2194037d1650460826805c7fc27a3a077a8ff7ea Mon Sep 17 00:00:00 2001 From: Kris Austin Date: Wed, 8 Jul 2026 20:57:06 -0500 Subject: [PATCH] test: cover floor/ceil and the built-in function boundary in the placeholder parser (#14667) round() already had unit coverage; floor() and ceil() had none. Add the missing positive cases for both signs, plus round()'s half-away-from-zero tie-break, and one negative case asserting that a name outside the grammar's built-in function set is treated as an undefined variable and throws, rather than being passed through to a math library. --- tests/libslic3r/test_placeholder_parser.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/libslic3r/test_placeholder_parser.cpp b/tests/libslic3r/test_placeholder_parser.cpp index ec72b72769..14716b0b5e 100644 --- a/tests/libslic3r/test_placeholder_parser.cpp +++ b/tests/libslic3r/test_placeholder_parser.cpp @@ -52,6 +52,11 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { SECTION("math: round(-13.4)") { REQUIRE(parser.process("{round(-13.4)}") == "-13"); } SECTION("math: round(13.6)") { REQUIRE(parser.process("{round(13.6)}") == "14"); } SECTION("math: round(-13.6)") { REQUIRE(parser.process("{round(-13.6)}") == "-14"); } + SECTION("math: round(13.5)") { REQUIRE(parser.process("{round(13.5)}") == "14"); } + SECTION("math: floor(13.9)") { REQUIRE(parser.process("{floor(13.9)}") == "13"); } + SECTION("math: floor(-13.1)") { REQUIRE(parser.process("{floor(-13.1)}") == "-14"); } + SECTION("math: ceil(13.1)") { REQUIRE(parser.process("{ceil(13.1)}") == "14"); } + SECTION("math: ceil(-13.9)") { REQUIRE(parser.process("{ceil(-13.9)}") == "-13"); } SECTION("math: digits(5, 15)") { REQUIRE(parser.process("{digits(5, 15)}") == " 5"); } SECTION("math: digits(5., 15)") { REQUIRE(parser.process("{digits(5., 15)}") == " 5"); } SECTION("math: zdigits(5, 15)") { REQUIRE(parser.process("{zdigits(5, 15)}") == "000000000000005"); } @@ -65,6 +70,8 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { SECTION("math: interpolate_table(13.84375892476, (0, 0), (20, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13.84375892476, (0, 0), (20, 20))}")) == Catch::Approx(13.84375892476)); } SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(13.)); } SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(20.)); } + // Only the grammar's built-in functions are callable; any other name is an undefined variable and throws. + SECTION("math: a non-built-in function name throws") { REQUIRE_THROWS(parser.process("{sqrt(16)}")); } // regex_replace(subject, /pattern/, replacement): the string-transform primitive. SECTION("regex_replace: strips a file extension") { REQUIRE(parser.process("{regex_replace(\"part.stl\", /\\.[^.]*$/, \"\")}") == "part"); }