diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 3f2938d568..a9c79e708f 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -3,6 +3,7 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp test_3mf.cpp + test_amf.cpp # Round-trip seam metadata and active/dormant volume settings in both formats. test_precise_seam_3mf.cpp test_aabbindirect.cpp diff --git a/tests/libslic3r/test_amf.cpp b/tests/libslic3r/test_amf.cpp new file mode 100644 index 0000000000..10af5fe115 --- /dev/null +++ b/tests/libslic3r/test_amf.cpp @@ -0,0 +1,79 @@ +#include + +#include "libslic3r/Config.hpp" +#include "libslic3r/Format/AMF.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/PrintConfig.hpp" + +#include "test_utils.hpp" + +#include + +#include + +using namespace Slic3r; + +namespace { + +// The smallest AMF the loader accepts: one object holding one volume, a tetrahedron. The metadata +// element of the object is dropped in verbatim, so a test can hand the parser a malformed one. +std::string amf_with_object_metadata(const std::string &object_metadata) +{ + return "\n" + "\n" + " \n" + " " + object_metadata + "\n" + " \n" + " \n" + " 000\n" + " 100\n" + " 010\n" + " 001\n" + " \n" + " \n" + " 021\n" + " 013\n" + " 032\n" + " 123\n" + " \n" + " \n" + " \n" + "\n"; +} + +void write_file(const std::string &path, const std::string &content) +{ + boost::nowide::ofstream f(path, std::ios::binary); + f << content; +} + +bool load(const std::string &path, Model &model) +{ + DynamicPrintConfig config; + ConfigSubstitutionContext substitutions(ForwardCompatibilitySubstitutionRule::Disable); + return load_amf(path.c_str(), &config, &substitutions, &model, nullptr); +} + +} // namespace + +TEST_CASE("An AMF object metadata element with no type attribute is rejected", "[AMF]") +{ + ScopedTemporaryFile tmp(".amf"); + + SECTION("with the attribute the file loads") + { + write_file(tmp.string(), amf_with_object_metadata("tetra")); + + Model model; + REQUIRE(load(tmp.string(), model)); + CHECK(model.objects.size() == 1); + } + + SECTION("without it the load fails instead of reading a null attribute") + { + write_file(tmp.string(), amf_with_object_metadata("tetra")); + + Model model; + CHECK_FALSE(load(tmp.string(), model)); + } +}