mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-29 22:02:10 +00:00
add profile validator checks
This commit is contained in:
27
.github/workflows/check_profiles.yml
vendored
27
.github/workflows/check_profiles.yml
vendored
@@ -57,6 +57,20 @@ jobs:
|
|||||||
set +e
|
set +e
|
||||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 -v BBL -f 2>&1 | tee ${{ runner.temp }}/validate_filament_subtypes.log
|
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 -v BBL -f 2>&1 | tee ${{ runner.temp }}/validate_filament_subtypes.log
|
||||||
exit ${PIPESTATUS[0]}
|
exit ${PIPESTATUS[0]}
|
||||||
|
# Flag inherits/compatible_printers/compatible_prints references that point at a deleted or
|
||||||
|
# renamed preset. Opt-in per vendor for now (via -r); enabled for BBL and Qidi until other
|
||||||
|
# vendors' profiles are cleaned up. Runs before the custom-preset injection below.
|
||||||
|
- name: validate preset references for BBL and Qidi profiles
|
||||||
|
id: validate_preset_references
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
set +e
|
||||||
|
rc=0
|
||||||
|
for v in BBL Qidi; do
|
||||||
|
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 -v "$v" -r 2>&1 | tee -a ${{ runner.temp }}/validate_preset_references.log
|
||||||
|
[ ${PIPESTATUS[0]} -ne 0 ] && rc=1
|
||||||
|
done
|
||||||
|
exit $rc
|
||||||
|
|
||||||
- name: validate custom presets
|
- name: validate custom presets
|
||||||
id: validate_custom
|
id: validate_custom
|
||||||
@@ -76,7 +90,7 @@ jobs:
|
|||||||
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
||||||
|
|
||||||
- name: Prepare comment artifact
|
- name: Prepare comment artifact
|
||||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_preset_references.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||||
run: |
|
run: |
|
||||||
{
|
{
|
||||||
# Marker matched by check_profiles_comment.yml to delete prior comments.
|
# Marker matched by check_profiles_comment.yml to delete prior comments.
|
||||||
@@ -111,6 +125,15 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${{ steps.validate_preset_references.outcome }}" = "failure" ]; then
|
||||||
|
echo "### BBL/Qidi Preset Reference Validation Failed"
|
||||||
|
echo ""
|
||||||
|
echo '```'
|
||||||
|
head -c 30000 ${{ runner.temp }}/validate_preset_references.log || echo "No output captured"
|
||||||
|
echo '```'
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${{ steps.validate_custom.outcome }}" = "failure" ]; then
|
if [ "${{ steps.validate_custom.outcome }}" = "failure" ]; then
|
||||||
echo "### Custom Preset Validation Failed"
|
echo "### Custom Preset Validation Failed"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -133,7 +156,7 @@ jobs:
|
|||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
- name: Fail if any check failed
|
- name: Fail if any check failed
|
||||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_preset_references.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||||
run: |
|
run: |
|
||||||
echo "One or more profile checks failed. See above for details."
|
echo "One or more profile checks failed. See above for details."
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ int main(int argc, char* argv[])
|
|||||||
("vendor,v", po::value<std::string>()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified")
|
("vendor,v", po::value<std::string>()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified")
|
||||||
("generate_presets,g", po::value<bool>()->default_value(false), "Generate user presets for mock test")
|
("generate_presets,g", po::value<bool>()->default_value(false), "Generate user presets for mock test")
|
||||||
("check_filament_subtypes,f", po::bool_switch()->default_value(false), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.")
|
("check_filament_subtypes,f", po::bool_switch()->default_value(false), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.")
|
||||||
|
("check_preset_references,r", po::bool_switch()->default_value(false), "Also flag presets whose inherits/compatible_printers/compatible_prints reference a deleted or renamed preset. Off unless this flag is present.")
|
||||||
("log_level,l", po::value<int>()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs.");
|
("log_level,l", po::value<int>()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs.");
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -120,6 +121,7 @@ int main(int argc, char* argv[])
|
|||||||
int log_level = vm["log_level"].as<int>();
|
int log_level = vm["log_level"].as<int>();
|
||||||
bool generate_user_preset = vm["generate_presets"].as<bool>();
|
bool generate_user_preset = vm["generate_presets"].as<bool>();
|
||||||
bool check_filament_subtypes = vm["check_filament_subtypes"].as<bool>();
|
bool check_filament_subtypes = vm["check_filament_subtypes"].as<bool>();
|
||||||
|
bool check_preset_references = vm["check_preset_references"].as<bool>();
|
||||||
|
|
||||||
// check if path is valid, and return error if not
|
// check if path is valid, and return error if not
|
||||||
if (!fs::exists(path) || !fs::is_directory(path)) {
|
if (!fs::exists(path) || !fs::is_directory(path)) {
|
||||||
@@ -166,7 +168,7 @@ int main(int argc, char* argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preset_bundle->has_errors(check_filament_subtypes)) {
|
if (preset_bundle->has_errors(check_filament_subtypes, check_preset_references)) {
|
||||||
std::cout << "Validation failed" << std::endl;
|
std::cout << "Validation failed" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -532,8 +532,16 @@ PresetsConfigSubstitutions PresetBundle::load_presets(AppConfig &config, Forward
|
|||||||
load_user_presets(dir_user_presets, substitution_rule);
|
load_user_presets(dir_user_presets, substitution_rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite renamed compatible_printers / compatible_prints references before selection.
|
// Rewrite renamed compatible_printers / compatible_prints references before selection. Skipped
|
||||||
this->normalize_compatible_presets();
|
// in validation mode so the profile validator (has_errors -> check_preset_references) sees the
|
||||||
|
// raw vendor-JSON references instead of the silently-repaired ones.
|
||||||
|
if (!validation_mode)
|
||||||
|
this->normalize_compatible_presets();
|
||||||
|
// Rewrite renamed compatible_printers / compatible_prints references before selection. Skipped
|
||||||
|
// in validation mode so the profile validator (has_errors -> check_preset_references) sees the
|
||||||
|
// raw vendor-JSON references instead of the silently-repaired ones.
|
||||||
|
if (!validation_mode)
|
||||||
|
this->normalize_compatible_presets();
|
||||||
|
|
||||||
this->update_multi_material_filament_presets();
|
this->update_multi_material_filament_presets();
|
||||||
this->update_compatible(PresetSelectCompatibleType::Never);
|
this->update_compatible(PresetSelectCompatibleType::Never);
|
||||||
@@ -5278,21 +5286,20 @@ static void normalize_compatible_field(Preset &preset, const char *field_key, Pr
|
|||||||
void PresetBundle::normalize_compatible_presets()
|
void PresetBundle::normalize_compatible_presets()
|
||||||
{
|
{
|
||||||
// compatible_printers references a printer preset; compatible_prints (filaments / SLA materials)
|
// compatible_printers references a printer preset; compatible_prints (filaments / SLA materials)
|
||||||
// references a process preset. Skip system presets: they are the targets of renames, not holders
|
// references a process preset. System presets are normalized too: a vendor profile can itself
|
||||||
// of stale references, and their vendor data must not be mutated. (begin()/end() skip defaults.)
|
// reference a sibling preset by a name that was later renamed, and the rewrite is in-memory only
|
||||||
auto normalize = [](PresetCollection &holders, PresetCollection &printers, PresetCollection *processes) {
|
// (system presets are never persisted back to vendor JSON). (begin()/end() skip defaults.)
|
||||||
|
auto normalize = [this](PresetCollection &holders, PresetCollection *processes) {
|
||||||
for (Preset &p : holders) {
|
for (Preset &p : holders) {
|
||||||
if (p.is_system)
|
normalize_compatible_field(p, "compatible_printers", this->printers);
|
||||||
continue;
|
|
||||||
normalize_compatible_field(p, "compatible_printers", printers);
|
|
||||||
if (processes != nullptr)
|
if (processes != nullptr)
|
||||||
normalize_compatible_field(p, "compatible_prints", *processes);
|
normalize_compatible_field(p, "compatible_prints", *processes);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
normalize(this->prints, this->printers, nullptr);
|
normalize(this->prints, nullptr);
|
||||||
normalize(this->filaments, this->printers, &this->prints);
|
normalize(this->filaments, &this->prints);
|
||||||
normalize(this->sla_prints, this->printers, nullptr);
|
normalize(this->sla_prints, nullptr);
|
||||||
normalize(this->sla_materials, this->printers, &this->sla_prints);
|
normalize(this->sla_materials, &this->sla_prints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible)
|
void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible)
|
||||||
@@ -5526,7 +5533,8 @@ void PresetBundle::set_default_suppressed(bool default_suppressed)
|
|||||||
printers.set_default_suppressed(default_suppressed);
|
printers.set_default_suppressed(default_suppressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PresetBundle::has_errors(bool check_duplicate_filament_subtypes) const
|
bool PresetBundle::has_errors(bool check_duplicate_filament_subtypes, bool check_references) const
|
||||||
|
bool PresetBundle::has_errors(bool check_duplicate_filament_subtypes, bool check_references) const
|
||||||
{
|
{
|
||||||
if (m_errors != 0 || printers.m_errors != 0 || filaments.m_errors != 0 || prints.m_errors != 0)
|
if (m_errors != 0 || printers.m_errors != 0 || filaments.m_errors != 0 || prints.m_errors != 0)
|
||||||
return true;
|
return true;
|
||||||
@@ -5549,6 +5557,12 @@ bool PresetBundle::has_errors(bool check_duplicate_filament_subtypes) const
|
|||||||
if (check_duplicate_filament_subtypes && this->check_duplicate_filament_subtypes())
|
if (check_duplicate_filament_subtypes && this->check_duplicate_filament_subtypes())
|
||||||
has_errors = true;
|
has_errors = true;
|
||||||
|
|
||||||
|
if (check_references && this->check_preset_references())
|
||||||
|
has_errors = true;
|
||||||
|
|
||||||
|
if (check_references && this->check_preset_references())
|
||||||
|
has_errors = true;
|
||||||
|
|
||||||
return has_errors;
|
return has_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5579,6 +5593,68 @@ static std::string preset_file_uri(const std::string &file)
|
|||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: validator-only. Flag any system preset whose inherits / compatible_printers /
|
||||||
|
// compatible_prints references a name that no longer resolves. Uses find_preset (exact match, then
|
||||||
|
// the renamed_from map - no fuzzy find_preset2, no alias resolution), so:
|
||||||
|
// nullptr -> the referenced preset was deleted/renamed away (name is dangling),
|
||||||
|
// resolved != name -> the reference uses an old name that renamed_from maps to a current one.
|
||||||
|
// Both should be fixed at the source rather than relying on load-time normalization - which is why
|
||||||
|
// normalize_compatible_presets() is skipped in validation mode (see load_presets), so this sees the
|
||||||
|
// raw vendor-JSON references. Safe under a single-vendor run (-v) too: inherits / compatible_printers
|
||||||
|
// / compatible_prints only name same-vendor or OrcaFilamentLibrary presets (both loaded), so a
|
||||||
|
// reference that does not resolve is genuinely dangling rather than an unloaded cross-vendor preset.
|
||||||
|
bool PresetBundle::check_preset_references() const
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// Resolve one reference (an inherits parent or a compatible_* entry) against its target
|
||||||
|
// collection and log if it is dangling (unknown) or uses a renamed preset's old name.
|
||||||
|
auto report_ref = [&](const Preset &p, const std::string &name, const PresetCollection &target,
|
||||||
|
const char *verb, const char *noun) {
|
||||||
|
const Preset *resolved = target.find_preset(name, false);
|
||||||
|
if (resolved == nullptr) {
|
||||||
|
found = true;
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Preset \"" << p.name << "\" " << verb << " unknown " << noun << " \"" << name << "\":\n"
|
||||||
|
<< preset_file_uri(p.file);
|
||||||
|
} else if (resolved->name != name) {
|
||||||
|
found = true;
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Preset \"" << p.name << "\" " << verb << " renamed " << noun << " \"" << name
|
||||||
|
<< "\" (now \"" << resolved->name << "\"):\n" << preset_file_uri(p.file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto check_list = [&](const Preset &p, const char *key, const PresetCollection &target) {
|
||||||
|
const auto *opt = p.config.option<ConfigOptionStrings>(key);
|
||||||
|
if (opt == nullptr)
|
||||||
|
return;
|
||||||
|
for (const std::string &name : opt->values)
|
||||||
|
if (!name.empty())
|
||||||
|
report_ref(p, name, target, "references", key);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto check_collection = [&](const PresetCollection &holders, const PresetCollection *processes) {
|
||||||
|
for (const Preset &p : holders) {
|
||||||
|
if (!p.is_system)
|
||||||
|
continue;
|
||||||
|
if (const std::string &inh = p.inherits(); !inh.empty())
|
||||||
|
report_ref(p, inh, holders, "inherits", "parent");
|
||||||
|
check_list(p, "compatible_printers", this->printers);
|
||||||
|
if (processes != nullptr)
|
||||||
|
check_list(p, "compatible_prints", *processes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Printers carry no compatible_printers/compatible_prints (those name a printer, so a printer
|
||||||
|
// holding them makes no sense); check_list is a no-op for them, so only their inherits is checked.
|
||||||
|
check_collection(this->printers, nullptr);
|
||||||
|
check_collection(this->prints, nullptr);
|
||||||
|
check_collection(this->filaments, &this->prints);
|
||||||
|
check_collection(this->sla_prints, nullptr);
|
||||||
|
check_collection(this->sla_materials, &this->sla_prints);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
// Orca: a filament is matched from the AMS by (filament_id + printer compatibility).
|
// Orca: a filament is matched from the AMS by (filament_id + printer compatibility).
|
||||||
// For any one printer, at most one instantiated filament preset with a given
|
// For any one printer, at most one instantiated filament preset with a given
|
||||||
// filament_id may be compatible - otherwise the AMS match is ambiguous and the
|
// filament_id may be compatible - otherwise the AMS match is ambiguous and the
|
||||||
|
|||||||
@@ -485,8 +485,13 @@ public:
|
|||||||
return { Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
|
return { Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orca: for validation only. The duplicate filament subtype check is opt-in for now
|
// Orca: for validation only. The duplicate filament subtype and preset-reference checks are
|
||||||
bool has_errors(bool check_duplicate_filament_subtypes = false) const;
|
// opt-in for now (enabled per-vendor by the profile-check CI as vendors are cleaned up).
|
||||||
|
bool has_errors(bool check_duplicate_filament_subtypes = false, bool check_preset_references = false) const;
|
||||||
|
|
||||||
|
// Orca: for validation only. Flag any system preset whose inherits / compatible_printers /
|
||||||
|
// compatible_prints references a deleted (unknown) or renamed (old) preset name.
|
||||||
|
bool check_preset_references() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Orca: validation only - flag any printer with two or more compatible
|
// Orca: validation only - flag any printer with two or more compatible
|
||||||
|
|||||||
@@ -355,6 +355,40 @@ TEST_CASE("Renamed printer/process names are normalized into compatible lists on
|
|||||||
CHECK(compatible_list(bundle.prints, "My Process", "compatible_printers") == std::vector<std::string>{ "New Printer" });
|
CHECK(compatible_list(bundle.prints, "My Process", "compatible_printers") == std::vector<std::string>{ "New Printer" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Renamed names are normalized into a SYSTEM preset's compatible lists", "[Preset][Rename]")
|
||||||
|
{
|
||||||
|
PresetBundle bundle;
|
||||||
|
|
||||||
|
// Current printer + process, each renamed from an older name.
|
||||||
|
add_inmemory_preset(bundle.printers, "New Printer");
|
||||||
|
set_renamed_from(bundle.printers, "New Printer", { "Old Printer" });
|
||||||
|
add_inmemory_preset(bundle.prints, "New Process");
|
||||||
|
set_renamed_from(bundle.prints, "New Process", { "Old Process" });
|
||||||
|
|
||||||
|
// A *system* (vendor) filament whose own compatible lists still reference the OLD names. A vendor
|
||||||
|
// profile can point at a sibling preset that was later renamed, so system presets must be
|
||||||
|
// normalized too (they are skipped by neither collection walk).
|
||||||
|
add_inmemory_preset(bundle.filaments, "System Filament").is_system = true;
|
||||||
|
compatible_list(bundle.filaments, "System Filament", "compatible_printers") = { "Old Printer" };
|
||||||
|
compatible_list(bundle.filaments, "System Filament", "compatible_prints") = { "Old Process" };
|
||||||
|
|
||||||
|
AppConfig app_config;
|
||||||
|
bundle.load_installed_printers(app_config); // build the rename maps
|
||||||
|
bundle.normalize_compatible_presets();
|
||||||
|
|
||||||
|
// The stale references in the system preset are rewritten to the current names.
|
||||||
|
CHECK(compatible_list(bundle.filaments, "System Filament", "compatible_printers") ==
|
||||||
|
std::vector<std::string>{ "New Printer" });
|
||||||
|
CHECK(compatible_list(bundle.filaments, "System Filament", "compatible_prints") ==
|
||||||
|
std::vector<std::string>{ "New Process" });
|
||||||
|
|
||||||
|
// The rewrite does not flag the system preset dirty, and is idempotent.
|
||||||
|
CHECK_FALSE(bundle.filaments.find_preset("System Filament", false, true)->is_dirty);
|
||||||
|
bundle.normalize_compatible_presets();
|
||||||
|
CHECK(compatible_list(bundle.filaments, "System Filament", "compatible_printers") ==
|
||||||
|
std::vector<std::string>{ "New Printer" });
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("compatible_prints on SLA materials resolves against sla_prints, not prints", "[Preset][Rename]")
|
TEST_CASE("compatible_prints on SLA materials resolves against sla_prints, not prints", "[Preset][Rename]")
|
||||||
{
|
{
|
||||||
PresetBundle bundle;
|
PresetBundle bundle;
|
||||||
@@ -377,3 +411,56 @@ TEST_CASE("compatible_prints on SLA materials resolves against sla_prints, not p
|
|||||||
std::vector<std::string>{ "New SLA Process" });
|
std::vector<std::string>{ "New SLA Process" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Profile validator flags dangling and renamed preset references", "[Preset][Validate]")
|
||||||
|
{
|
||||||
|
PresetBundle bundle;
|
||||||
|
|
||||||
|
// Current printers: a real one, and a renamed one (its old name resolves via renamed_from).
|
||||||
|
add_inmemory_preset(bundle.printers, "Real Printer");
|
||||||
|
add_inmemory_preset(bundle.printers, "New Printer");
|
||||||
|
set_renamed_from(bundle.printers, "New Printer", { "Old Printer" });
|
||||||
|
|
||||||
|
// A real process, referenced from a filament's compatible_prints.
|
||||||
|
add_inmemory_preset(bundle.prints, "Real Process").is_system = true;
|
||||||
|
|
||||||
|
// A fully valid system filament: references only current names.
|
||||||
|
add_inmemory_preset(bundle.filaments, "Good Filament").is_system = true;
|
||||||
|
compatible_list(bundle.filaments, "Good Filament", "compatible_printers") = { "Real Printer" };
|
||||||
|
compatible_list(bundle.filaments, "Good Filament", "compatible_prints") = { "Real Process" };
|
||||||
|
|
||||||
|
AppConfig app_config;
|
||||||
|
bundle.load_installed_printers(app_config); // build the rename maps
|
||||||
|
|
||||||
|
// With only valid references, the validator is clean.
|
||||||
|
CHECK_FALSE(bundle.check_preset_references());
|
||||||
|
|
||||||
|
SECTION("deleted compatible_printers is flagged") {
|
||||||
|
add_inmemory_preset(bundle.filaments, "Ghost Ref Filament").is_system = true;
|
||||||
|
compatible_list(bundle.filaments, "Ghost Ref Filament", "compatible_printers") = { "Ghost Printer" };
|
||||||
|
CHECK(bundle.check_preset_references());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("renamed compatible_printers (old name) is flagged") {
|
||||||
|
add_inmemory_preset(bundle.filaments, "Old Ref Filament").is_system = true;
|
||||||
|
compatible_list(bundle.filaments, "Old Ref Filament", "compatible_printers") = { "Old Printer" };
|
||||||
|
CHECK(bundle.check_preset_references());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("deleted compatible_prints is flagged") {
|
||||||
|
add_inmemory_preset(bundle.filaments, "Bad Process Ref").is_system = true;
|
||||||
|
compatible_list(bundle.filaments, "Bad Process Ref", "compatible_prints") = { "Ghost Process" };
|
||||||
|
CHECK(bundle.check_preset_references());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("deleted inherits parent is flagged") {
|
||||||
|
add_inmemory_preset(bundle.filaments, "Orphan Filament", "Ghost Parent").is_system = true;
|
||||||
|
CHECK(bundle.check_preset_references());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("non-system preset with a dangling reference is ignored") {
|
||||||
|
add_inmemory_preset(bundle.filaments, "User Filament"); // is_system stays false
|
||||||
|
compatible_list(bundle.filaments, "User Filament", "compatible_printers") = { "Ghost Printer" };
|
||||||
|
CHECK_FALSE(bundle.check_preset_references());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user