无语了

This commit is contained in:
2026-08-11 17:06:17 +08:00
parent de88da9a8a
commit 542637ede4
7 changed files with 843 additions and 529 deletions
+36 -28
View File
@@ -298,9 +298,9 @@ TEST(RenderiveWebGallery, BackendControlSchemaValidatesEveryPatch) {
"spectrum", current,
R"({"category":"event","type":"gallery_patch","patch":{"current_pen":"#ff8844","frequency_point_size":1024,"line_interpolation":"Cubic_Value","max_render_fps":1000}})");
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_EQ(std::get<std::string>(accepted.candidate->values.at("current_pen")), "#ff8844");
EXPECT_DOUBLE_EQ(std::get<double>(accepted.candidate->values.at("frequency_point_size")), 1024);
EXPECT_DOUBLE_EQ(std::get<double>(accepted.candidate->values.at("max_render_fps")), 1000);
EXPECT_EQ(std::get<std::string>(gallery_property_value(*accepted.candidate, "current_pen")), "#ff8844");
EXPECT_DOUBLE_EQ(std::get<double>(gallery_property_value(*accepted.candidate, "frequency_point_size")), 1024);
EXPECT_DOUBLE_EQ(std::get<double>(gallery_property_value(*accepted.candidate, "max_render_fps")), 1000);
const auto excessive_fps = Gallery_Protocol::apply_patch(
"spectrum", current,
@@ -342,18 +342,22 @@ TEST(RenderiveWebGallery, EveryPublishedControlValidatesItsCompleteInputContract
const auto defaults = Gallery_Protocol::default_state(case_id, mode.value);
const auto contract = parse_json(Gallery_Protocol::case_json(
case_id, defaults, "{}", {}, mode.value));
const auto& controls = contract.at("controls").at("data");
EXPECT_EQ(controls.size(), defaults.values.size()) << case_id << '/' << mode.id;
const auto& resource = contract.at("controls");
const auto& controls = resource.at("descriptor").at("fields");
const auto& data = resource.at("data");
EXPECT_EQ(controls.size(), gallery_property_count(defaults)) << case_id << '/' << mode.id;
std::set<std::string> ids;
for (const auto& control : controls) {
++validated_control_instances;
const std::string id = control.at("id");
const std::string id = control.at("name");
const auto& presentation = control.at("presentation");
SCOPED_TRACE(std::string(case_id) + "/" + std::string(mode.id) + "/" + id);
EXPECT_TRUE(ids.insert(id).second);
EXPECT_FALSE(control.at("api").get<std::string>().empty());
EXPECT_FALSE(control.at("group").get<std::string>().empty());
EXPECT_TRUE(control.at("editable").get<bool>());
EXPECT_FALSE(presentation.at("description").get<std::string>().empty());
const std::string input = control.at("input");
const std::string input = presentation.at("control");
const auto& current_value = data.at(id);
const auto apply = [&](const nlohmann::json& value) {
nlohmann::json request{{"category", "event"}, {"type", "gallery_patch"},
{"patch", {{id, value}}}};
@@ -367,65 +371,69 @@ TEST(RenderiveWebGallery, EveryPublishedControlValidatesItsCompleteInputContract
};
if (input == "boolean") {
const bool alternative = !control.at("value").get<bool>();
const bool alternative = !current_value.get<bool>();
const auto accepted = apply(alternative);
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_EQ(std::get<bool>(accepted.candidate->values.at(id)), alternative);
EXPECT_EQ(std::get<bool>(gallery_property_value(*accepted.candidate, id)), alternative);
expect_rejected(1);
} else if (input == "number") {
const double minimum = control.at("minimum");
const double maximum = control.at("maximum");
const double current = control.at("value");
const double step = std::max(control.at("step").get<double>(), 1e-9);
const double current = current_value;
const double step = std::max(control.at("multiple_of").get<double>(), 1e-9);
double alternative = current + step;
if (alternative > maximum)
alternative = current - step;
if (alternative < minimum || alternative == current)
alternative = current == minimum ? maximum : minimum;
if (control.at("integer").get<bool>())
const bool integer = control.at("value_type") == "integer";
if (integer)
alternative = std::round(alternative);
const auto accepted = apply(alternative);
const nlohmann::json alternative_value = integer ?
nlohmann::json(static_cast<std::int64_t>(std::llround(alternative))) :
nlohmann::json(alternative);
const auto accepted = apply(alternative_value);
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_DOUBLE_EQ(std::get<double>(accepted.candidate->values.at(id)),
EXPECT_DOUBLE_EQ(std::get<double>(gallery_property_value(*accepted.candidate, id)),
alternative);
EXPECT_TRUE(apply(minimum).candidate.has_value());
EXPECT_TRUE(apply(maximum).candidate.has_value());
EXPECT_TRUE(apply(integer ? nlohmann::json(static_cast<std::int64_t>(minimum)) : nlohmann::json(minimum)).candidate.has_value());
EXPECT_TRUE(apply(integer ? nlohmann::json(static_cast<std::int64_t>(maximum)) : nlohmann::json(maximum)).candidate.has_value());
expect_rejected(minimum - std::max(1.0, std::abs(minimum) * 0.1 + 1.0));
expect_rejected(maximum + std::max(1.0, std::abs(maximum) * 0.1 + 1.0));
expect_rejected("not-a-number");
if (control.at("integer").get<bool>() && maximum - minimum >= 1.0)
if (integer && maximum - minimum >= 1.0)
expect_rejected(std::clamp(std::floor(current) + 0.5,
minimum + 0.5, maximum - 0.5));
} else if (input == "select") {
const auto& options = control.at("options");
const auto& options = presentation.at("options");
ASSERT_FALSE(options.empty());
const std::string current = control.at("value");
const std::string current = current_value;
const auto alternative = std::find_if(
options.begin(), options.end(), [&current](const auto& option) {
return option.template get<std::string>() != current;
return option.at("value").template get<std::string>() != current;
});
ASSERT_NE(alternative, options.end());
const std::string value = alternative->get<std::string>();
const std::string value = alternative->at("value").get<std::string>();
const auto accepted = apply(value);
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_EQ(std::get<std::string>(accepted.candidate->values.at(id)), value);
EXPECT_EQ(std::get<std::string>(gallery_property_value(*accepted.candidate, id)), value);
expect_rejected("__invalid_gallery_option__");
expect_rejected(7);
} else if (input == "color") {
const std::string value = control.at("value") == "#123456" ?
const std::string value = current_value == "#123456" ?
"#654321" : "#123456";
const auto accepted = apply(value);
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_EQ(std::get<std::string>(accepted.candidate->values.at(id)), value);
EXPECT_EQ(std::get<std::string>(gallery_property_value(*accepted.candidate, id)), value);
expect_rejected("red");
expect_rejected(7);
} else {
ASSERT_EQ(input, "text");
std::string value = control.at("value").get<std::string>() + "_qa";
std::string value = current_value.get<std::string>() + "_qa";
const auto accepted = apply(value);
ASSERT_TRUE(accepted.candidate.has_value());
EXPECT_EQ(std::get<std::string>(accepted.candidate->values.at(id)), value);
EXPECT_EQ(std::get<std::string>(gallery_property_value(*accepted.candidate, id)), value);
expect_rejected(std::string(161, 'x'));
expect_rejected(7);
}