diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b328c306..61bbe4e74 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -192,6 +192,7 @@ set(UI_TEST_SOURCES set(SLIC3R_TEST_SOURCES ${TESTDIR}/test_harness.cpp ${TESTDIR}/libslic3r/test_trianglemesh.cpp + ${TESTDIR}/libslic3r/test_config.cpp ) add_executable(slic3r slic3r.cpp) #set_target_properties(slic3r PROPERTIES LINK_SEARCH_START_STATIC 1) diff --git a/src/test/libslic3r/test_config.cpp b/src/test/libslic3r/test_config.cpp new file mode 100644 index 000000000..e49fcf9be --- /dev/null +++ b/src/test/libslic3r/test_config.cpp @@ -0,0 +1,100 @@ +#include + +#include "Config.hpp" + +using namespace Slic3r; + +SCENARIO("Generic config validation performs as expected.", "[!mayfail]") { + GIVEN("A config generated from default options") { + auto config {Slic3r::Config::new_from_defaults()}; + WHEN( "perimeter_extrusion_width is set to 250%, a valid value") { + config->set("perimeter_extrusion_width", "250\%"); + THEN( "The config is read as valid.") { + REQUIRE(config->validate() == true); + } + } + WHEN( "perimeter_extrusion_width is set to -10, an invalid value") { + config->set("perimeter_extrusion_width", -10); + THEN( "An exception is thrown.") { + auto except_thrown {false}; + try { + config->validate(); + } catch (const InvalidOptionValue& e) { + except_thrown = true; + } + REQUIRE(except_thrown == true); + } + } + } +} + +SCENARIO("Config accessor functions perform as expected.", "[!mayfail]") { + GIVEN("A config generated from default options") { + auto config {Slic3r::Config::new_from_defaults()}; + WHEN("A numeric option is set through the string interface") { + THEN("The underlying value is set correctly.") { + REQUIRE(false); + } + } + WHEN("An integer-based option is set through the integer interface") { + THEN("The underlying value is set correctly.") { + REQUIRE(false); + } + } + WHEN("An floating-point option is set through the integer interface") { + THEN("The underlying value is set correctly.") { + REQUIRE(false); + } + } + WHEN("A floating-point option is set through the double interface") { + THEN("The underlying value is set correctly.") { + REQUIRE(false); + } + } + WHEN("An integer-based option is set through the double interface") { + THEN("The underlying value is set, rounded to the nearest integer.") { + REQUIRE(false); + } + } + WHEN("A numeric option is set to a non-numeric value.") { + auto except_thrown {false}; + try { + config->set("perimeter_extrusion_width", "zzzz"); + } catch (const InvalidOptionType& e) { + except_thrown = true; + } + THEN("An exception is thown.") { + REQUIRE(except_thrown == true); + } + THEN("The value does not change.") { + REQUIRE(false); + } + } + WHEN("An invalid option is requested during set.") { + auto except_thrown {false}; + try { + config->set("deadbeef_invalid_option", "1"); + } catch (const InvalidOptionType& e) { + except_thrown = true; + } + THEN("An exception is thrown.") { + REQUIRE(except_thrown == true); + } + } + WHEN("An invalid option is requested during get.") { + auto except_thrown {false}; + try { + config->get("deadbeef_invalid_option", false); + } catch (const InvalidOptionType& e) { + except_thrown = true; + } + THEN("An exception is thrown.") { + REQUIRE(except_thrown == true); + } + } + } +} + +SCENARIO("Config ini load/save interface", "[!mayfail]") { + REQUIRE(false); +} diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 655f093f9..ec0b1b576 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -35,6 +35,27 @@ new_from_cli(const int& argc, const char* argv[]) return std::make_shared(); } +bool +Config::validate() +{ + return false; +} + +void +Config::set(const t_config_option_key& opt_key, const std::string& value) +{ +} + +void +Config::set(const t_config_option_key& opt_key, const int value) +{ +} + +void +Config::set(const t_config_option_key& opt_key, const double value) +{ +} + } // namespace Slic3r diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index cdc57125c..43e7f6ca5 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -12,6 +12,16 @@ namespace Slic3r { +/// Exception class for invalid (but correct type) option values. +/// Thrown by validate() +class InvalidOptionValue : public std::runtime_error {}; + +/// Exception class to handle config options that don't exist. +class InvalidConfigOption : public std::runtime_error {}; + +/// Exception class for type mismatches +class InvalidOptionType : public std::runtime_error {}; + class Config; using config_ptr = std::shared_ptr; @@ -31,6 +41,23 @@ public: T& get(const t_config_option_key& opt_key, bool create=false) { return *(dynamic_cast(this->optptr(opt_key, create))); } + + /// Function to parse value from a string to whatever opt_key is. + void set(const t_config_option_key& opt_key, const std::string& value); + + /// Function to parse value from an integer to whatever opt_key is, if + /// opt_key is a numeric type. This will throw an exception and do + /// nothing if called with an incorrect type. + void set(const t_config_option_key& opt_key, const int value); + + /// Function to parse value from an integer to whatever opt_key is, if + /// opt_key is a numeric type. This will throw an exception and do + /// nothing if called with an incorrect type. + void set(const t_config_option_key& opt_key, const double value); + + /// Method to validate the different configuration options. + /// It will throw InvalidConfigOption exceptions on failure. + bool validate(); }; } // namespace Slic3r