mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 09:02:06 +00:00
Add diff compare method for DynamicConfig
Help the unit test report errors better.
This commit is contained in:
@@ -1703,6 +1703,81 @@ t_config_option_keys DynamicConfig::keys() const
|
||||
return keys;
|
||||
}
|
||||
|
||||
DynamicConfig::DynamicConfigDifference DynamicConfig::diff_report(const DynamicConfig& rhs) const {
|
||||
DynamicConfig::DynamicConfigDifference result;
|
||||
|
||||
std::set<t_config_option_key> all_keys;
|
||||
|
||||
for (const auto& kvp : this->options) {
|
||||
all_keys.insert(kvp.first);
|
||||
}
|
||||
for (const auto& kvp : rhs.options) {
|
||||
all_keys.insert(kvp.first);
|
||||
}
|
||||
|
||||
for (const auto& key : all_keys) {
|
||||
auto left_it = this->options.find(key);
|
||||
auto right_it = rhs.options.find(key);
|
||||
|
||||
bool left_has = (left_it != this->options.end());
|
||||
bool right_has = (right_it != rhs.options.end());
|
||||
|
||||
if (left_has && right_has) {
|
||||
if (*left_it->second != *right_it->second) {
|
||||
result.differences[key] = {
|
||||
left_it->second->serialize(),
|
||||
right_it->second->serialize()
|
||||
};
|
||||
}
|
||||
} else if (left_has) {
|
||||
result.differences[key] = {
|
||||
left_it->second->serialize(),
|
||||
std::nullopt
|
||||
};
|
||||
} else if (right_has) {
|
||||
result.differences[key] = {
|
||||
std::nullopt,
|
||||
right_it->second->serialize()
|
||||
};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DynamicConfig::DynamicConfigDifference& diff) {
|
||||
if (!diff.is_different()) {
|
||||
os << "Configurations are identical.\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
int missing_right=0, missing_left=0, differ=0;
|
||||
os << "DynamicConfig Differences Found (" << diff.differences.size() << " keys):\n";
|
||||
for (const auto& kvp : diff.differences) {
|
||||
const auto& key = kvp.first;
|
||||
const auto& detail = kvp.second;
|
||||
|
||||
os << " Key: **" << key << "**\n";
|
||||
|
||||
if (detail.is_missing_key()) {
|
||||
// Determine which side is missing the key
|
||||
if (detail.left_value.has_value()) {
|
||||
os << " - **Missing in Right**: Key exists in left config. Value: " << detail.left_value.value() << "\n";
|
||||
missing_right++;
|
||||
} else {
|
||||
os << " - **Missing in Left**: Key exists in right config. Value: " << detail.right_value.value() << "\n";
|
||||
missing_left++;
|
||||
}
|
||||
} else if (detail.is_different_value()) {
|
||||
differ++;
|
||||
os << " - **Value Differs**:\n";
|
||||
os << " -> Left Value: " << detail.left_value.value() << "\n";
|
||||
os << " -> Right Value: " << detail.right_value.value() << "\n";
|
||||
}
|
||||
}
|
||||
os << "Summary: " << missing_right << " missing on right, " << missing_left << " missing on left, and " << differ << " have differing values\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
void StaticConfig::set_defaults()
|
||||
{
|
||||
// use defaults from definition
|
||||
|
||||
@@ -2783,6 +2783,40 @@ public:
|
||||
std::map<t_config_option_key, std::unique_ptr<ConfigOption>>::const_iterator cend() const { return options.cend(); }
|
||||
size_t size() const { return options.size(); }
|
||||
|
||||
/**
|
||||
* @brief Detailed information about the difference found for a single key.
|
||||
*/
|
||||
struct KeyDifference {
|
||||
std::optional<std::string> left_value;
|
||||
std::optional<std::string> right_value;
|
||||
|
||||
bool is_missing_key() const {
|
||||
return !left_value.has_value() || !right_value.has_value();
|
||||
}
|
||||
bool is_different_value() const {
|
||||
return left_value.has_value() && right_value.has_value() && (left_value.value() != right_value.value());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The full report object containing all detected differences.
|
||||
*/
|
||||
struct DynamicConfigDifference {
|
||||
std::map<t_config_option_key, KeyDifference> differences;
|
||||
|
||||
bool is_different() const {
|
||||
return !differences.empty();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Computes the symmetric difference between this DynamicConfig (left)
|
||||
* and another DynamicConfig (rhs).
|
||||
* @param rhs The right-hand side config to compare against.
|
||||
* @return DynamicConfigDifference report.
|
||||
*/
|
||||
DynamicConfigDifference diff_report(const DynamicConfig& rhs) const;
|
||||
|
||||
private:
|
||||
std::map<t_config_option_key, std::unique_ptr<ConfigOption>> options;
|
||||
|
||||
@@ -2790,6 +2824,8 @@ private:
|
||||
template<class Archive> void serialize(Archive &ar) { ar(options); }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DynamicConfig::DynamicConfigDifference& diff);
|
||||
|
||||
// Configuration store with a static definition of configuration values.
|
||||
// In Slic3r, the static configuration stores are during the slicing / g-code generation for efficiency reasons,
|
||||
// because the configuration values could be accessed directly.
|
||||
|
||||
Reference in New Issue
Block a user