mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 22:42:37 +00:00
CAD recipe v2: legible version-mismatch errors, refuse old files cleanly
Port of snaporca 04c3d579a7. Bump SNAPORCA_CAD_RECIPE_VERSION 1 -> 2; deserialize_recipe sets a user-facing error distinguishing too-new / too-old / corrupt instead of a silent bare false. No per-version migration by design. Golden fixture regenerated at v2 (v1 retired), field-value reorder tripwire unchanged. Fork adjustment: Catch2 v3 string matcher ContainsSubstring (not v2's Contains) in the two new version-mismatch tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d04b02cd0e
commit
8edc12c8f1
@@ -1422,7 +1422,7 @@ TEST_CASE("serialize_recipe roundtrip with two bodies", "[CadDocument]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize_recipe rejects future version", "[CadDocument]")
|
||||
TEST_CASE("deserialize_recipe rejects future version with error", "[CadDocument]")
|
||||
{
|
||||
CadDocument doc;
|
||||
std::ostringstream oss;
|
||||
@@ -1432,6 +1432,72 @@ TEST_CASE("deserialize_recipe rejects future version", "[CadDocument]")
|
||||
ar(v);
|
||||
}
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(oss.str()));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
CHECK_THAT(doc.error, Catch::Matchers::ContainsSubstring("newer version"));
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize_recipe rejects older version with error", "[CadDocument]")
|
||||
{
|
||||
CadDocument doc;
|
||||
std::ostringstream oss;
|
||||
{
|
||||
cereal::BinaryOutputArchive ar(oss);
|
||||
uint32_t v = 1;
|
||||
ar(v);
|
||||
}
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(oss.str()));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
CHECK_THAT(doc.error, Catch::Matchers::ContainsSubstring("older version"));
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize_recipe handles truncated blob without throwing", "[CadDocument]")
|
||||
{
|
||||
CadDocument doc;
|
||||
std::string garbage = "this is not a valid cereal blob";
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(garbage));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize_recipe handles empty blob without throwing", "[CadDocument]")
|
||||
{
|
||||
CadDocument doc;
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(""));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize_recipe error is non-empty on every failure path", "[CadDocument]")
|
||||
{
|
||||
CadDocument doc;
|
||||
auto reset = [&]() { doc = CadDocument{}; };
|
||||
|
||||
// too new
|
||||
{
|
||||
std::ostringstream oss;
|
||||
{ cereal::BinaryOutputArchive ar(oss); uint32_t v = 999; ar(v); }
|
||||
reset();
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(oss.str()));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
// too old
|
||||
{
|
||||
std::ostringstream oss;
|
||||
{ cereal::BinaryOutputArchive ar(oss); uint32_t v = 1; ar(v); }
|
||||
reset();
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(oss.str()));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
// truncated / garbage
|
||||
{
|
||||
reset();
|
||||
REQUIRE_FALSE(doc.deserialize_recipe("not a valid blob \x00\x01\x02"));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
// empty
|
||||
{
|
||||
reset();
|
||||
REQUIRE_FALSE(doc.deserialize_recipe(""));
|
||||
REQUIRE_FALSE(doc.error.empty());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("re-edit: editing a mid-timeline feature rebuilds downstream", "[CadDocument]")
|
||||
@@ -1853,7 +1919,7 @@ TEST_CASE("regenerate golden recipe fixture", "[.regen]")
|
||||
auto blob = doc.serialize_recipe();
|
||||
REQUIRE_FALSE(blob.empty());
|
||||
|
||||
std::string path = std::string(TEST_DATA_DIR) + "/cad_recipe_v1.bin";
|
||||
std::string path = std::string(TEST_DATA_DIR) + "/cad_recipe_v2.bin";
|
||||
std::ofstream ofs(path, std::ios::binary);
|
||||
REQUIRE(ofs.is_open());
|
||||
ofs.write(blob.data(), static_cast<std::streamsize>(blob.size()));
|
||||
@@ -1867,7 +1933,7 @@ TEST_CASE("golden recipe v1 still deserialises", "[CadDocument]")
|
||||
using Catch::Matchers::WithinAbs;
|
||||
|
||||
// Read the golden blob from disk
|
||||
std::string path = std::string(TEST_DATA_DIR) + "/cad_recipe_v1.bin";
|
||||
std::string path = std::string(TEST_DATA_DIR) + "/cad_recipe_v2.bin";
|
||||
std::ifstream ifs(path, std::ios::binary);
|
||||
REQUIRE(ifs.is_open());
|
||||
std::string blob((std::istreambuf_iterator<char>(ifs)),
|
||||
|
||||
Reference in New Issue
Block a user