feat(step097): preserve B fixes for unified V15 source

This commit is contained in:
tei
2026-09-27 08:41:27 +09:00
parent b1239ac3b1
commit f3a44c7d5f
18 changed files with 711 additions and 36 deletions

View File

@@ -945,3 +945,54 @@ TEST(RenderSegmentPlan, StrictJSONRejectsUnknownFieldsStrategyAndInvalidFirstBou
RetainedUnderlayRuntimeState state;
EXPECT_FALSE(state.setRenderSegmentPlan(std::move(*parsed)));
}
TEST(RenderSegmentPlan, StrictJSONRejectsNulDuplicateKeysAndUnknownSchema) {
EXPECT_FALSE(parseRenderSegmentPlanJSON(
R"({"schemaVersion":2,"segments":[{"strategy":"RETAINED"}]})"));
EXPECT_FALSE(parseRenderSegmentPlanJSON(
R"({"schemaVersion":1,"schemaVersion":1,"segments":[{"strategy":"RETAINED"}]})"));
EXPECT_FALSE(parseRenderSegmentPlanJSON(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED","strategy":"CONTINUOUS"}]})"));
EXPECT_FALSE(parseRenderSegmentPlanJSON(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED\u0000suffix"}]})"));
EXPECT_FALSE(parseRenderSegmentPlanJSON(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED"},{"strategy":"CONTINUOUS","startLayerId":"water\u0000suffix"}]})"));
std::string rawNul = R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED"}]})";
rawNul.insert(rawNul.end() - 2, '\0');
rawNul.insert(rawNul.end() - 2, 'x');
EXPECT_FALSE(parseRenderSegmentPlanJSON(rawNul));
}
TEST(RenderSegmentPlan, InvalidJSONClearsRendererPlanAndValidPlanRecovers) {
constexpr auto validJSON =
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED"},{"strategy":"CONTINUOUS","startLayerId":"water"}]})";
RetainedUnderlayRuntimeState state;
auto valid = renderSegmentPlanFromJSONOrInvalid(validJSON);
ASSERT_TRUE(state.setRenderSegmentPlan(std::move(valid)));
auto resolved = resolveRenderSegmentPlan(state.renderSegmentPlanConfig(), segmentLayerIds(), true);
ASSERT_TRUE(resolved.valid);
auto invalid = renderSegmentPlanFromJSONOrInvalid(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED","strategy":"CONTINUOUS"}]})");
EXPECT_FALSE(state.setRenderSegmentPlan(std::move(invalid)));
auto cleared = resolveRenderSegmentPlan(state.renderSegmentPlanConfig(), segmentLayerIds(), true);
EXPECT_FALSE(cleared.valid);
EXPECT_EQ(cleared.reason, "unsupported-schema-version");
auto missingBoundary = renderSegmentPlanFromJSONOrInvalid(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED"},{"strategy":"CONTINUOUS"}]})");
EXPECT_FALSE(state.setRenderSegmentPlan(std::move(missingBoundary)));
EXPECT_FALSE(resolveRenderSegmentPlan(state.renderSegmentPlanConfig(), segmentLayerIds(), true).valid);
auto reversedBoundary = renderSegmentPlanFromJSONOrInvalid(
R"({"schemaVersion":1,"segments":[{"strategy":"RETAINED"},{"strategy":"CONTINUOUS","startLayerId":"water"},{"strategy":"RETAINED","startLayerId":"background"}]})");
ASSERT_TRUE(state.setRenderSegmentPlan(std::move(reversedBoundary)));
auto reversed = resolveRenderSegmentPlan(state.renderSegmentPlanConfig(), segmentLayerIds(), true);
EXPECT_FALSE(reversed.valid);
EXPECT_EQ(reversed.reason, "boundary-order-invalid");
auto recovered = renderSegmentPlanFromJSONOrInvalid(validJSON);
ASSERT_TRUE(state.setRenderSegmentPlan(std::move(recovered)));
EXPECT_TRUE(resolveRenderSegmentPlan(state.renderSegmentPlanConfig(), segmentLayerIds(), true).valid);
}