|
|
@@ -1,5 +1,3 @@
|
|
|
-#include <string_view>
|
|
|
-
|
|
|
#include <gmock/gmock.h>
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
@@ -75,6 +73,24 @@ TEST(Annotation, NotSchemaFlipsAnnotationRule) {
|
|
|
EXPECT_THAT(result, ErrorAt(""_jptr, "/not"_jptr, "minimum", "6 >= 5"));
|
|
|
}
|
|
|
|
|
|
+TEST(Annotation, NotSchemaPropogatesDeeply) {
|
|
|
+ auto const schema = R"({
|
|
|
+ "not": {
|
|
|
+ "properties": {
|
|
|
+ "A": {
|
|
|
+ "enum": [ 1, 3, 4 ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ auto const instance = R"({"A": 3})"_json;
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
+
|
|
|
+ EXPECT_THAT(result, ErrorAt("/A"_jptr, "/not/properties/A"_jptr, "enum", "1"));
|
|
|
+}
|
|
|
+
|
|
|
TEST(Annotation, PathFollowsSchemaNotConstraintModel) {
|
|
|
auto const schema = R"({
|
|
|
"$comment": "disallow is implemented in the form of NotConstraint[TypeConstraint]",
|
|
|
@@ -88,36 +104,142 @@ TEST(Annotation, PathFollowsSchemaNotConstraintModel) {
|
|
|
EXPECT_THAT(result, ErrorAt("disallow", "string is in types [string]"));
|
|
|
}
|
|
|
|
|
|
-TEST(Annotation, SomeConstraintsAnnotateBothValidAndInvalid) {
|
|
|
+TEST(Annotation, AttachesAlwaysFalseSensibly) {
|
|
|
auto const schema = R"({
|
|
|
- "$comment": "accepts any number <= 0 or >= 10",
|
|
|
- "oneOf": [
|
|
|
- { "minimum": 10 },
|
|
|
- { "maximum": 0 }
|
|
|
- ]
|
|
|
+ "properties": {
|
|
|
+ "A": false
|
|
|
+ }
|
|
|
})"_json;
|
|
|
|
|
|
- auto const instance = R"(-1)"_json;
|
|
|
+ auto const instance = R"({
|
|
|
+ "A": null
|
|
|
+ })"_json;
|
|
|
jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
|
|
|
- EXPECT_THAT(result, Not(HasAnnotationAt(""_jptr, "/oneOf"_jptr)));
|
|
|
- EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/0"_jptr, "minimum", "-1 < 10"));
|
|
|
- EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/1"_jptr, "maximum", "-1 <= 0"));
|
|
|
+ EXPECT_THAT(result, ErrorAt("/A"_jptr, "/properties/A"_jptr, "", "always false"));
|
|
|
}
|
|
|
|
|
|
-TEST(Annotation, AttachesAlwaysFalseSensibly) {
|
|
|
+TEST(Annotation, IfThenCanGiveABecauseReason) {
|
|
|
auto const schema = R"({
|
|
|
- "properties": {
|
|
|
- "A": false
|
|
|
+ "if": {
|
|
|
+ "properties": {
|
|
|
+ "A": { "const": true }
|
|
|
+ },
|
|
|
+ "required": [ "A" ]
|
|
|
+ },
|
|
|
+ "then": {
|
|
|
+ "properties": {
|
|
|
+ "B": { "multipleOf": 3 }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "else": {
|
|
|
+ "properties": {
|
|
|
+ "B": { "multipleOf": 5 }
|
|
|
+ }
|
|
|
}
|
|
|
})"_json;
|
|
|
|
|
|
auto const instance = R"({
|
|
|
- "A": null
|
|
|
+ "A": true,
|
|
|
+ "B": 4
|
|
|
})"_json;
|
|
|
+
|
|
|
jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
|
|
|
- EXPECT_THAT(result, ErrorAt("/A"_jptr, "/properties/A"_jptr, "", "always false"));
|
|
|
+ EXPECT_THAT(result,
|
|
|
+ ErrorAt(""_jptr, "/if"_jptr, "required", "contains all required properties A"));
|
|
|
+ EXPECT_THAT(result, ErrorAt("/A"_jptr, "/if/properties/A"_jptr, "const", "matches value"));
|
|
|
+ EXPECT_THAT(result, ErrorAt("/B"_jptr, "/then/properties/B"_jptr, "multipleOf",
|
|
|
+ "4 is not a multiple of 3"));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Annotation, IfElseCanGiveABecauseReason) {
|
|
|
+ auto const schema = R"({
|
|
|
+ "if": {
|
|
|
+ "properties": {
|
|
|
+ "A": { "const": true }
|
|
|
+ },
|
|
|
+ "required": [ "A" ]
|
|
|
+ },
|
|
|
+ "then": {
|
|
|
+ "properties": {
|
|
|
+ "B": { "multipleOf": 3 }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "else": {
|
|
|
+ "properties": {
|
|
|
+ "B": { "multipleOf": 5 }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ auto const instance = R"({
|
|
|
+ "A": false,
|
|
|
+ "B": 4
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
+
|
|
|
+ EXPECT_THAT(result,
|
|
|
+ ErrorAt(""_jptr, "/if"_jptr, "required", "contains all required properties A"));
|
|
|
+ EXPECT_THAT(result, ErrorAt("/A"_jptr, "/if/properties/A"_jptr, "const", "true was expected"));
|
|
|
+ EXPECT_THAT(result, ErrorAt("/B"_jptr, "/else/properties/B"_jptr, "multipleOf",
|
|
|
+ "4 is not a multiple of 5"));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Annotation, OneOfGivesAllReasonsOnTooMany) {
|
|
|
+ auto const schema = R"({
|
|
|
+ "oneOf": [
|
|
|
+ { "minimum": 5 },
|
|
|
+ { "multipleOf": 3 },
|
|
|
+ { "maximum": 2 }
|
|
|
+ ]
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ auto const instance = R"(6)"_json;
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
+
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, ""_jptr, "oneOf", "validates multiple subschemas [ 0, 1 ]"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/0"_jptr, "minimum", "6 >= 5"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/1"_jptr, "multipleOf", "6 is a multiple of 3"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/2"_jptr, "maximum", "6 > 2"));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Annotation, OneOfGivesAllReasonsOnNoMatches) {
|
|
|
+ auto const schema = R"({
|
|
|
+ "oneOf": [
|
|
|
+ { "minimum": 5 },
|
|
|
+ { "multipleOf": 3 },
|
|
|
+ { "maximum": 2 }
|
|
|
+ ]
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ auto const instance = R"(4)"_json;
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
+
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, ""_jptr, "oneOf", "validates no subschemas"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/0"_jptr, "minimum", "4 < 5"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/1"_jptr, "multipleOf", "4 is not a multiple of 3"));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/2"_jptr, "maximum", "4 > 2"));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Annotation, OneOfGivesAllReasonsOnMatch) {
|
|
|
+ auto const schema = R"({
|
|
|
+ "oneOf": [
|
|
|
+ { "minimum": 5 },
|
|
|
+ { "multipleOf": 3 },
|
|
|
+ { "maximum": 2 }
|
|
|
+ ]
|
|
|
+ })"_json;
|
|
|
+
|
|
|
+ auto const instance = R"(3)"_json;
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result = validate(schema, instance);
|
|
|
+
|
|
|
+ EXPECT_THAT(result, Not(HasAnnotationAt(""_jptr, ""_jptr)));
|
|
|
+ EXPECT_THAT(result, ErrorAt(""_jptr, "/oneOf/1"_jptr, "multipleOf", "3 is a multiple of 3"));
|
|
|
}
|
|
|
|
|
|
int main(int argc, char ** argv) {
|