#include #include namespace mln::particle { namespace { std::string valid() { return R"({"contractSchemaVersion":1,"profileID":"test.wind","profileVersion":1,"allowAdditionalPlanes":false,"sharedValidityRequired":true,"timeRelation":"ANY","requiredPlanes":[{"semanticID":1,"valueClass":"VELOCITY_COMPONENT","unitID":1,"groupID":1,"component":"U_EAST","requiredFlag":true},{"semanticID":2,"valueClass":"VELOCITY_COMPONENT","unitID":1,"groupID":1,"component":"V_NORTH","requiredFlag":true},{"semanticID":3,"valueClass":"VALIDITY","unitID":0,"groupID":0,"component":"NONE","requiredFlag":true}]})"; } TEST(ParticleFieldProfileContractJson, ParsesFrozenSchema) { const auto contract = parseResolvedFieldProfileContractJson(valid()); ASSERT_TRUE(contract); EXPECT_EQ(contract->contractSchemaVersion, 1); EXPECT_EQ(contract->profileID, "test.wind"); EXPECT_EQ(contract->requiredPlanes.size(), 3u); EXPECT_FALSE(contract->allowAdditionalPlanes); } TEST(ParticleFieldProfileContractJson, RejectsMissingFrozenFieldsAndUnknownSchema) { EXPECT_FALSE(parseResolvedFieldProfileContractJson(R"({"contractSchemaVersion":1})")); auto json = valid(); json.replace(json.find("\"contractSchemaVersion\":1"), 25, "\"contractSchemaVersion\":2"); EXPECT_FALSE(parseResolvedFieldProfileContractJson(json)); } TEST(ParticleFieldProfileContractJson, RejectsOutOfRangeDuplicateAndInvalidEnums) { auto overflow = valid(); overflow.replace(overflow.find("\"semanticID\":1"), 14, "\"semanticID\":65536"); EXPECT_FALSE(parseResolvedFieldProfileContractJson(overflow)); auto duplicate = valid(); duplicate.replace(duplicate.find("\"semanticID\":2"), 14, "\"semanticID\":1"); EXPECT_FALSE(parseResolvedFieldProfileContractJson(duplicate)); auto invalidEnum = valid(); invalidEnum.replace(invalidEnum.find("\"timeRelation\":\"ANY\""), 20, "\"timeRelation\":\"LATER\""); EXPECT_FALSE(parseResolvedFieldProfileContractJson(invalidEnum)); } TEST(ParticleFieldProfileContractJson, RejectsPlaneLimitAndInvalidProfileID) { auto invalidID = valid(); invalidID.replace(invalidID.find("test.wind"), 9, ""); EXPECT_FALSE(parseResolvedFieldProfileContractJson(invalidID)); std::string planes; for (int i = 0; i != 65; ++i) { if (!planes.empty()) planes += ','; planes += R"({"semanticID":99,"valueClass":"SCALAR","unitID":0,"groupID":)" + std::to_string(i) + R"(,"component":"NONE","requiredFlag":true})"; } const auto tooMany = std::string(R"({"contractSchemaVersion":1,"profileID":"x","profileVersion":1,"allowAdditionalPlanes":true,"sharedValidityRequired":true,"timeRelation":"ANY","requiredPlanes":[)") + planes + "]}"; EXPECT_FALSE(parseResolvedFieldProfileContractJson(tooMany)); } } // namespace } // namespace mln::particle