mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-01 14:27:00 +00:00
QidiPrinterAgent composes QD_<series>_<vendor>_<typeidx> setting ids from device enums and previously degraded any slot whose id matched no visible preset to generic-by-type. Plan v4.2 retires every QD_* preset id to the succession ledger, so insert the ledger walk between the direct match and the generic fallback: a composed QD_* id now forwards to its family's minted OF* successor exactly like every other retired id. Behavior-neutral until the ids are actually retired (the ledger holds no QD_* keys yet, and live QD_* presets still match directly). Also documents the code<->ledger lockstep on the hardcoded non-numeric- series fallback table (QD_1_0_1/_11/_41/_50) and adds a C++ test pinning that the succession walk is key-format agnostic. Gates: libslic3r_tests [filament_id] 14 assertions green; libslic3r_gui compiles.
70 lines
3.0 KiB
C++
70 lines
3.0 KiB
C++
#include <catch2/catch_all.hpp>
|
|
|
|
#include "libslic3r/Preset.hpp"
|
|
|
|
using namespace Slic3r;
|
|
|
|
// Pure-function coverage of the succession chain walk (follow_filament_id_succession).
|
|
// The ledger-file loader (filament_id_succession_map) is deliberately untested here so
|
|
// the test carries no resources-dir dependency.
|
|
TEST_CASE("filament_id succession follows forwarding chains", "[Preset][filament_id]") {
|
|
SECTION("empty map returns empty") {
|
|
const std::map<std::string, std::string> empty;
|
|
CHECK(follow_filament_id_succession("OFabc123", empty).empty());
|
|
CHECK(follow_filament_id_succession("", empty).empty());
|
|
}
|
|
|
|
const std::map<std::string, std::string> forwards = {
|
|
{"OFold001", "OFnew001"},
|
|
{"OFchainA", "OFchainB"},
|
|
{"OFchainB", "OFchainC"},
|
|
{"OFchainC", "OFlive00"},
|
|
};
|
|
|
|
SECTION("absent id returns empty") {
|
|
CHECK(follow_filament_id_succession("GFL99", forwards).empty());
|
|
}
|
|
|
|
SECTION("single hop resolves to the successor") {
|
|
CHECK(follow_filament_id_succession("OFold001", forwards) == "OFnew001");
|
|
}
|
|
|
|
SECTION("multi-hop chain resolves to the live end") {
|
|
CHECK(follow_filament_id_succession("OFchainA", forwards) == "OFlive00");
|
|
CHECK(follow_filament_id_succession("OFchainB", forwards) == "OFlive00");
|
|
CHECK(follow_filament_id_succession("OFchainC", forwards) == "OFlive00");
|
|
}
|
|
|
|
// QidiPrinterAgent resolves device-composed QD_* protocol ids through this same walk;
|
|
// the map key format carries no OF assumption.
|
|
SECTION("device-protocol QD_* keys forward like any other id") {
|
|
const std::map<std::string, std::string> qd = {{"QD_2_1_11", "OFnew001"}};
|
|
CHECK(follow_filament_id_succession("QD_2_1_11", qd) == "OFnew001");
|
|
CHECK(follow_filament_id_succession("QD_2_1_12", qd).empty());
|
|
}
|
|
}
|
|
|
|
// Cycles are a ledger-validation error (script check 9) and never ship, but the client
|
|
// walk must still terminate on corrupt data: it stops at the last id reached before any
|
|
// id would repeat.
|
|
TEST_CASE("filament_id succession terminates on malformed cycles", "[Preset][filament_id]") {
|
|
SECTION("two-node cycle returns the last id before revisiting") {
|
|
const std::map<std::string, std::string> cycle = {{"A", "B"}, {"B", "A"}};
|
|
CHECK(follow_filament_id_succession("A", cycle) == "B");
|
|
CHECK(follow_filament_id_succession("B", cycle) == "A");
|
|
}
|
|
|
|
SECTION("cycle entered through a tail stops before re-entering it") {
|
|
// T -> A -> B -> C -> A: stops at C, the last id reached before repeating A.
|
|
const std::map<std::string, std::string> cycle = {
|
|
{"T", "A"}, {"A", "B"}, {"B", "C"}, {"C", "A"}};
|
|
CHECK(follow_filament_id_succession("T", cycle) == "C");
|
|
CHECK(follow_filament_id_succession("A", cycle) == "C");
|
|
}
|
|
|
|
SECTION("self-loop returns the id itself") {
|
|
const std::map<std::string, std::string> loop = {{"A", "A"}};
|
|
CHECK(follow_filament_id_succession("A", loop) == "A");
|
|
}
|
|
}
|