diff --git a/src/documentation/documentation.cc b/src/documentation/documentation.cc index b5d57adc1..70b9ee841 100644 --- a/src/documentation/documentation.cc +++ b/src/documentation/documentation.cc @@ -647,7 +647,12 @@ auto emit_row(const sourcemeta::core::JSON &schema, sourcemeta::core::JSON path, } } - if (expand_applicators && is_complex_schema(schema)) { + if (expand_applicators && is_complex_schema(schema) && + visited.find(&schema) == visited.end()) { + visited.emplace(&schema, + VisitedEntry{.identifier = static_cast( + row.at("identifier").to_integer()), + .path = row.at("path")}); auto row_children{sourcemeta::core::JSON::make_array()}; walk_branches("anyOf", "Any of", schema, row_children, frame, root, visited, next_identifier); @@ -657,22 +662,10 @@ auto emit_row(const sourcemeta::core::JSON &schema, sourcemeta::core::JSON path, next_identifier); walk_if_then_else(schema, row_children, frame, root, visited, next_identifier); - if (schema.is_object() && schema.defines("not")) { - const auto ¬_schema{schema.at("not")}; - const auto has_inline{ - not_schema.is_object() && - !(not_schema.defines("anyOf") || not_schema.defines("oneOf") || - not_schema.defines("allOf") || not_schema.defines("not")) && - !constraints_of(not_schema).empty()}; - if (!has_inline) { - walk_branching_subschema("Must NOT match", "value", not_schema, - row_children, frame, root, visited, - next_identifier, false); - } - } if (!row_children.empty()) { row.assign("children", std::move(row_children)); } + visited.erase(&schema); } rows.push_back(std::move(row)); @@ -745,7 +738,10 @@ auto walk_properties(const sourcemeta::core::JSON &schema, const auto row_identifier{ static_cast(row.at("identifier").to_integer())}; - if (is_complex_schema(resolved)) { + if (is_complex_schema(resolved) && + visited.find(&resolved) == visited.end()) { + visited.emplace(&resolved, + VisitedEntry{.identifier = row_identifier, .path = path}); auto prop_children{sourcemeta::core::JSON::make_array()}; walk_branches("anyOf", "Any of", resolved, prop_children, frame, root, visited, next_identifier); @@ -771,6 +767,7 @@ auto walk_properties(const sourcemeta::core::JSON &schema, if (!prop_children.empty()) { row.assign("children", std::move(prop_children)); } + visited.erase(&resolved); } rows.push_back(std::move(row)); diff --git a/test/documentation/documentation_2020_12_test.cc b/test/documentation/documentation_2020_12_test.cc index 1da554b75..9c539cee6 100644 --- a/test/documentation/documentation_2020_12_test.cc +++ b/test/documentation/documentation_2020_12_test.cc @@ -1955,6 +1955,149 @@ TEST_F(Documentation202012Test, property_with_anyof) { expected); } +TEST_F(Documentation202012Test, recursive_ref_in_property_anyof) { + const auto schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "child": { + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "properties": { + "child": { "$ref": "#/properties/child" } + } + } + ] + } + } + })JSON")}; + + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "object" + } + }, + { + "identifier": 2, + "path": [ + { + "type": "literal", + "value": "child" + } + ], + "type": { + "kind": "any" + }, + "required": false, + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 3, + "rows": [ + { + "identifier": 4, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + } + } + ] + }, + { + "identifier": 5, + "rows": [ + { + "identifier": 6, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "object" + } + }, + { + "identifier": 7, + "path": [ + { + "type": "literal", + "value": "child" + } + ], + "type": { + "kind": "recursiveRef", + "identifier": 2, + "path": [ + { + "type": "literal", + "value": "child" + } + ] + }, + "required": false + }, + { + "identifier": 8, + "path": [ + { + "type": "wildcard", + "value": "*" + } + ], + "type": { + "kind": "any" + } + } + ] + } + ] + } + ] + }, + { + "identifier": 9, + "path": [ + { + "type": "wildcard", + "value": "*" + } + ], + "type": { + "kind": "any" + } + } + ] + } + )JSON")}; + + EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, + sourcemeta::core::schema_resolver, *compiled_schema_, + expected); +} + TEST_F(Documentation202012Test, additional_properties_object_deep) { const auto schema{sourcemeta::core::parse_json(R"JSON({ "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -3746,7 +3889,9 @@ TEST_F(Documentation202012Test, external_ref_root) { "rows": [ { "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], + "path": [ + { "type": "synthetic", "value": "root" } + ], "type": { "kind": "externalRef", "url": "https://example.com/user.json" @@ -3884,8 +4029,13 @@ TEST_F(Documentation202012Test, dynamic_ref_standalone) { "rows": [ { "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "dynamicRef", "anchor": "target" } + "path": [ + { "type": "synthetic", "value": "root" } + ], + "type": { + "kind": "dynamicRef", + "anchor": "target" + } } ] })JSON")}; @@ -4851,139 +5001,6 @@ TEST_F(Documentation202012Test, if_then_else) { "else": { "type": "integer" } })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "If", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { - "kind": "enum", - "values": [ true ] - } - } - ] - } - ] - }, - { - "label": "Then", - "children": [ - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" } - } - ] - } - ] - }, - { - "label": "Else", - "children": [ - { - "identifier": 6, - "rows": [ - { - "identifier": 7, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "integer" } - } - ] - } - ] - } - ] - })JSON")}; - - EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, - sourcemeta::core::schema_resolver, *compiled_schema_, - expected); -} - -TEST_F(Documentation202012Test, allof_simple) { - const auto schema{sourcemeta::core::parse_json(R"JSON({ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "allOf": [ - { "enum": [ "a", "b" ] }, - { "enum": [ "b", "c" ] } - ] - })JSON")}; - - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "All of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { - "kind": "enum", - "values": [ "a", "b" ] - } - } - ] - }, - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { - "kind": "enum", - "values": [ "b", "c" ] - } - } - ] - } - ] - } - ] - })JSON")}; - - EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, - sourcemeta::core::schema_resolver, *compiled_schema_, - expected); -} - -TEST_F(Documentation202012Test, dependent_schemas) { - const auto schema{sourcemeta::core::parse_json(R"JSON({ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "dependentSchemas": { - "a": { "required": [ "b" ] } - } - })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON( { "identifier": 0, @@ -5003,7 +5020,7 @@ TEST_F(Documentation202012Test, dependent_schemas) { ], "children": [ { - "label": "All of", + "label": "If", "children": [ { "identifier": 2, @@ -5017,13 +5034,201 @@ TEST_F(Documentation202012Test, dependent_schemas) { } ], "type": { - "kind": "any" + "kind": "enum", + "values": [ true ] } } - ], - "children": [ + ] + } + ] + }, + { + "label": "Then", + "children": [ + { + "identifier": 4, + "rows": [ { - "label": "Any of", + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + } + } + ] + } + ] + }, + { + "label": "Else", + "children": [ + { + "identifier": 6, + "rows": [ + { + "identifier": 7, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "integer" + } + } + ] + } + ] + } + ] + } + )JSON")}; + + EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, + sourcemeta::core::schema_resolver, *compiled_schema_, + expected); +} + +TEST_F(Documentation202012Test, allof_simple) { + const auto schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { "enum": [ "a", "b" ] }, + { "enum": [ "b", "c" ] } + ] + })JSON")}; + + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "All of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "a", + "b" + ] + } + } + ] + }, + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "b", + "c" + ] + } + } + ] + } + ] + } + ] + } + )JSON")}; + + EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, + sourcemeta::core::schema_resolver, *compiled_schema_, + expected); +} + +TEST_F(Documentation202012Test, dependent_schemas) { + const auto schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "dependentSchemas": { + "a": { "required": [ "b" ] } + } + })JSON")}; + + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "All of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "Any of", "children": [ { "identifier": 4, @@ -5420,161 +5625,220 @@ TEST_F(Documentation202012Test, contains_branching) { } })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "array" }, - "constraints": [ ">= 1 matching items" ] - } - ], - "children": [ - { - "label": "Contains", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ - { "type": "synthetic", "value": "matching item" } - ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Any of", - "children": [ - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "enum", - "values": [ 1 ] - } - } - ] - }, - { - "identifier": 6, - "rows": [ - { - "identifier": 7, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "enum", - "values": [ 2 ] - } - } - ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "array" + }, + "constraints": [ + ">= 1 matching items" + ] + } + ], + "children": [ + { + "label": "Contains", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "matching item" + } + ], + "type": { + "kind": "any" } - ] - } - ] - } - ] - } - ] - })JSON")}; - - EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, - sourcemeta::core::schema_resolver, *compiled_schema_, - expected); -} - -TEST_F(Documentation202012Test, content_schema_branching) { - const auto schema{sourcemeta::core::parse_json(R"JSON({ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "string", - "contentEncoding": "base64", - "contentMediaType": "application/json", - "contentSchema": { - "anyOf": [ - { "enum": [ "v1" ] }, + } + ], + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + 1 + ] + } + } + ] + }, + { + "identifier": 6, + "rows": [ + { + "identifier": 7, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + 2 + ] + } + } + ] + } + ] + } + ] + } + ] + } + ] + } + )JSON")}; + + EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, + sourcemeta::core::schema_resolver, *compiled_schema_, + expected); +} + +TEST_F(Documentation202012Test, content_schema_branching) { + const auto schema{sourcemeta::core::parse_json(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "contentEncoding": "base64", + "contentMediaType": "application/json", + "contentSchema": { + "anyOf": [ + { "enum": [ "v1" ] }, { "enum": [ "v2" ] } ] } })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" }, - "badges": [ - { "kind": "encoding", "value": "base64" }, - { "kind": "mime", "value": "application/json" } - ] - } - ], - "children": [ - { - "label": "Decoded content", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "decoded" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Any of", - "children": [ - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "enum", - "values": [ "v1" ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + }, + "badges": [ + { + "kind": "encoding", + "value": "base64" + }, + { + "kind": "mime", + "value": "application/json" + } + ] + } + ], + "children": [ + { + "label": "Decoded content", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "decoded" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "v1" + ] + } } - } - ] - }, - { - "identifier": 6, - "rows": [ - { - "identifier": 7, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "enum", - "values": [ "v2" ] + ] + }, + { + "identifier": 6, + "rows": [ + { + "identifier": 7, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "v2" + ] + } } - } - ] - } - ] - } - ] - } - ] - } - ] - })JSON")}; + ] + } + ] + } + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_, @@ -5590,49 +5854,72 @@ TEST_F(Documentation202012Test, oneOf_simple) { ] })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "One of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { - "kind": "enum", - "values": [ "x" ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "One of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "x" + ] + } } - } - ] - }, - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { - "kind": "enum", - "values": [ "y" ] + ] + }, + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "enum", + "values": [ + "y" + ] + } } - } - ] - } - ] - } - ] - })JSON")}; + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_, @@ -5719,9 +6006,7 @@ TEST_F(Documentation202012Test, property_names_branching) { "kind": "primitive", "name": "string" }, - "constraints": [ - "pattern: ^x" - ] + "constraints": [ "pattern: ^x" ] } ] }, @@ -5740,9 +6025,7 @@ TEST_F(Documentation202012Test, property_names_branching) { "kind": "primitive", "name": "string" }, - "constraints": [ - "pattern: ^y" - ] + "constraints": [ "pattern: ^y" ] } ] } @@ -5807,44 +6090,70 @@ TEST_F(Documentation202012Test, not_flat) { "not": { "type": "string", "pattern": "^x" } })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "All of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" }, - "constraints": [ "must NOT match pattern: ^x" ] - } - ] - }, - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" } - } - ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" } - ] - } - ] - })JSON")}; + } + ], + "children": [ + { + "label": "All of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + }, + "constraints": [ + "must NOT match pattern: ^x" + ] + } + ] + }, + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + } + } + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_, @@ -5863,101 +6172,140 @@ TEST_F(Documentation202012Test, not_branching) { } })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "All of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Must NOT match", - "children": [ - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ - { "type": "synthetic", "value": "value" } - ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Any of", - "children": [ - { - "identifier": 6, - "rows": [ - { - "identifier": 7, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "primitive", - "name": "string" - }, - "constraints": [ "pattern: ^x" ] - } - ] - }, - { - "identifier": 8, - "rows": [ - { - "identifier": 9, - "path": [ - { "type": "synthetic", "value": "root" } - ], - "type": { - "kind": "primitive", - "name": "string" - }, - "constraints": [ "pattern: ^y" ] - } - ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "All of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" + } + } + ], + "children": [ + { + "label": "Must NOT match", + "children": [ + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "value" + } + ], + "type": { + "kind": "any" } - ] - } - ] + } + ], + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 6, + "rows": [ + { + "identifier": 7, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + }, + "constraints": [ + "pattern: ^x" + ] + } + ] + }, + { + "identifier": 8, + "rows": [ + { + "identifier": 9, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + }, + "constraints": [ + "pattern: ^y" + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "identifier": 10, + "rows": [ + { + "identifier": 11, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" } - ] - } - ] - }, - { - "identifier": 10, - "rows": [ - { - "identifier": 11, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" } - } - ] - } - ] - } - ] - })JSON")}; + } + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_, @@ -6159,43 +6507,68 @@ TEST_F(Documentation202012Test, no_type_keyword_produces_any) { ] })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Any of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" } - } - ] - }, - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "integer" } - } - ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" } - ] - } - ] - })JSON")}; + } + ], + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + } + } + ] + }, + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "integer" + } + } + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_, diff --git a/test/documentation/documentation_draft4_test.cc b/test/documentation/documentation_draft4_test.cc index bed831f6e..6949b408a 100644 --- a/test/documentation/documentation_draft4_test.cc +++ b/test/documentation/documentation_draft4_test.cc @@ -1278,43 +1278,68 @@ TEST_F(DocumentationDraft4Test, anyof) { ] })JSON")}; - const auto expected{sourcemeta::core::parse_json(R"JSON({ - "identifier": 0, - "rows": [ - { - "identifier": 1, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "any" } - } - ], - "children": [ - { - "label": "Any of", - "children": [ - { - "identifier": 2, - "rows": [ - { - "identifier": 3, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "string" } - } - ] - }, - { - "identifier": 4, - "rows": [ - { - "identifier": 5, - "path": [ { "type": "synthetic", "value": "root" } ], - "type": { "kind": "primitive", "name": "integer" } - } - ] + const auto expected{sourcemeta::core::parse_json(R"JSON( + { + "identifier": 0, + "rows": [ + { + "identifier": 1, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "any" } - ] - } - ] - })JSON")}; + } + ], + "children": [ + { + "label": "Any of", + "children": [ + { + "identifier": 2, + "rows": [ + { + "identifier": 3, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "string" + } + } + ] + }, + { + "identifier": 4, + "rows": [ + { + "identifier": 5, + "path": [ + { + "type": "synthetic", + "value": "root" + } + ], + "type": { + "kind": "primitive", + "name": "integer" + } + } + ] + } + ] + } + ] + } + )JSON")}; EXPECT_DOCUMENTATION(schema, sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, *compiled_schema_,