diff --git a/src/alterschema/CMakeLists.txt b/src/alterschema/CMakeLists.txt index beba7f179..4d3e0228e 100644 --- a/src/alterschema/CMakeLists.txt +++ b/src/alterschema/CMakeLists.txt @@ -4,7 +4,6 @@ sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME alterschema SOURCES alterschema.cc schema_rule.cc transformer.cc # Canonicalizer canonicalizer/additional_items_implicit.h - canonicalizer/additional_properties_implicit.h canonicalizer/comment_drop.h canonicalizer/const_as_enum.h canonicalizer/dependencies_to_any_of.h @@ -28,7 +27,6 @@ sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME alterschema canonicalizer/exclusive_minimum_integer_to_minimum.h canonicalizer/extends_to_array.h canonicalizer/if_then_else_implicit.h - canonicalizer/implicit_array_keywords.h canonicalizer/implicit_contains_keywords.h canonicalizer/implicit_object_keywords.h canonicalizer/items_implicit.h @@ -39,13 +37,10 @@ sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME alterschema canonicalizer/min_items_given_min_contains.h canonicalizer/min_length_implicit.h canonicalizer/min_properties_covered_by_required.h - canonicalizer/min_properties_implicit.h canonicalizer/minimum_can_equal_integer_fold.h canonicalizer/minimum_can_equal_true_drop.h canonicalizer/multiple_of_implicit.h canonicalizer/optional_property_implicit.h - canonicalizer/properties_implicit.h - canonicalizer/property_names_implicit.h canonicalizer/recursive_anchor_false_drop.h canonicalizer/required_property_implicit.h canonicalizer/type_array_to_any_of.h diff --git a/src/alterschema/alterschema.cc b/src/alterschema/alterschema.cc index c9fbaf116..3ae6f4bc4 100644 --- a/src/alterschema/alterschema.cc +++ b/src/alterschema/alterschema.cc @@ -108,7 +108,6 @@ auto WALK_UP_IN_PLACE_APPLICATORS(const JSON &root, const SchemaFrame &frame, } #include "canonicalizer/additional_items_implicit.h" -#include "canonicalizer/additional_properties_implicit.h" #include "canonicalizer/comment_drop.h" #include "canonicalizer/const_as_enum.h" #include "canonicalizer/dependencies_to_any_of.h" @@ -132,7 +131,6 @@ auto WALK_UP_IN_PLACE_APPLICATORS(const JSON &root, const SchemaFrame &frame, #include "canonicalizer/exclusive_minimum_integer_to_minimum.h" #include "canonicalizer/extends_to_array.h" #include "canonicalizer/if_then_else_implicit.h" -#include "canonicalizer/implicit_array_keywords.h" #include "canonicalizer/implicit_contains_keywords.h" #include "canonicalizer/implicit_object_keywords.h" #include "canonicalizer/items_implicit.h" @@ -143,13 +141,10 @@ auto WALK_UP_IN_PLACE_APPLICATORS(const JSON &root, const SchemaFrame &frame, #include "canonicalizer/min_items_given_min_contains.h" #include "canonicalizer/min_length_implicit.h" #include "canonicalizer/min_properties_covered_by_required.h" -#include "canonicalizer/min_properties_implicit.h" #include "canonicalizer/minimum_can_equal_integer_fold.h" #include "canonicalizer/minimum_can_equal_true_drop.h" #include "canonicalizer/multiple_of_implicit.h" #include "canonicalizer/optional_property_implicit.h" -#include "canonicalizer/properties_implicit.h" -#include "canonicalizer/property_names_implicit.h" #include "canonicalizer/recursive_anchor_false_drop.h" #include "canonicalizer/required_property_implicit.h" #include "canonicalizer/type_array_to_any_of.h" @@ -277,8 +272,6 @@ auto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void { bundle.add(); bundle.add(); bundle.add(); - bundle.add(); - bundle.add(); bundle.add(); bundle.add(); bundle.add(); @@ -355,11 +348,9 @@ auto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void { bundle.add(); bundle.add(); bundle.add(); - bundle.add(); bundle.add(); bundle.add(); bundle.add(); - bundle.add(); bundle.add(); } @@ -427,7 +418,6 @@ auto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void { bundle.add(); bundle.add(); bundle.add(); - bundle.add(); bundle.add(); bundle.add(); bundle.add(); diff --git a/src/alterschema/canonicalizer/additional_properties_implicit.h b/src/alterschema/canonicalizer/additional_properties_implicit.h deleted file mode 100644 index 2b0e56a05..000000000 --- a/src/alterschema/canonicalizer/additional_properties_implicit.h +++ /dev/null @@ -1,45 +0,0 @@ -class AdditionalPropertiesImplicit final : public SchemaTransformRule { -public: - using mutates = std::true_type; - using reframe_after_transform = std::true_type; - AdditionalPropertiesImplicit() - : SchemaTransformRule{"additional_properties_implicit", ""} {}; - - [[nodiscard]] auto - condition(const sourcemeta::core::JSON &schema, - const sourcemeta::core::JSON &, - const sourcemeta::core::Vocabularies &vocabularies, - const sourcemeta::core::SchemaFrame &, - const sourcemeta::core::SchemaFrame::Location &, - const sourcemeta::core::SchemaWalker &, - const sourcemeta::core::SchemaResolver &) const - -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF( - vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, - Vocabularies::Known::JSON_Schema_Draft_1, - Vocabularies::Known::JSON_Schema_Draft_2, - Vocabularies::Known::JSON_Schema_Draft_3, - Vocabularies::Known::JSON_Schema_Draft_4, - Vocabularies::Known::JSON_Schema_Draft_6, - Vocabularies::Known::JSON_Schema_Draft_7}) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "object" && - !schema.defines("additionalProperties")); - this->is_pre_draft4_ = - vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, - Vocabularies::Known::JSON_Schema_Draft_1, - Vocabularies::Known::JSON_Schema_Draft_2, - Vocabularies::Known::JSON_Schema_Draft_3}); - return true; - } - - auto transform(JSON &schema, const Result &) const -> void override { - schema.assign("additionalProperties", - this->is_pre_draft4_ ? sourcemeta::core::JSON::make_object() - : sourcemeta::core::JSON{true}); - } - -private: - mutable bool is_pre_draft4_{false}; -}; diff --git a/src/alterschema/canonicalizer/implicit_array_keywords.h b/src/alterschema/canonicalizer/implicit_array_keywords.h deleted file mode 100644 index b6096742c..000000000 --- a/src/alterschema/canonicalizer/implicit_array_keywords.h +++ /dev/null @@ -1,70 +0,0 @@ -class ImplicitArrayKeywords final : public SchemaTransformRule { -public: - using mutates = std::true_type; - using reframe_after_transform = std::true_type; - ImplicitArrayKeywords() - : SchemaTransformRule{"implicit_array_keywords", ""} {}; - - [[nodiscard]] auto - condition(const sourcemeta::core::JSON &schema, - const sourcemeta::core::JSON &, - const sourcemeta::core::Vocabularies &vocabularies, - const sourcemeta::core::SchemaFrame &, - const sourcemeta::core::SchemaFrame::Location &, - const sourcemeta::core::SchemaWalker &, - const sourcemeta::core::SchemaResolver &) const - -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF( - vocabularies.contains_any( - {Vocabularies::Known::JSON_Schema_Draft_0, - Vocabularies::Known::JSON_Schema_Draft_1, - Vocabularies::Known::JSON_Schema_Draft_2, - Vocabularies::Known::JSON_Schema_Draft_3, - Vocabularies::Known::JSON_Schema_Draft_4, - Vocabularies::Known::JSON_Schema_Draft_6, - Vocabularies::Known::JSON_Schema_Draft_7, - Vocabularies::Known::JSON_Schema_2019_09_Applicator, - Vocabularies::Known::JSON_Schema_2020_12_Applicator}) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "array"); - - const bool is_modern{vocabularies.contains_any( - {Vocabularies::Known::JSON_Schema_2019_09_Applicator, - Vocabularies::Known::JSON_Schema_2020_12_Applicator})}; - this->is_pre_draft4_ = - vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, - Vocabularies::Known::JSON_Schema_Draft_1, - Vocabularies::Known::JSON_Schema_Draft_2, - Vocabularies::Known::JSON_Schema_Draft_3}); - this->has_unique_items_ = - !vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, - Vocabularies::Known::JSON_Schema_Draft_1}); - const bool needs_items{!is_modern && !schema.defines("items")}; - ONLY_CONTINUE_IF( - (this->has_unique_items_ && !schema.defines("uniqueItems")) || - needs_items || !schema.defines("minItems")); - - this->add_items_ = needs_items; - return true; - } - - auto transform(JSON &schema, const Result &) const -> void override { - if (this->has_unique_items_ && !schema.defines("uniqueItems")) { - schema.assign("uniqueItems", sourcemeta::core::JSON{false}); - } - if (this->add_items_ && !schema.defines("items")) { - schema.assign("items", this->is_pre_draft4_ - ? sourcemeta::core::JSON::make_object() - : sourcemeta::core::JSON{true}); - } - if (!schema.defines("minItems")) { - schema.assign("minItems", sourcemeta::core::JSON{0}); - } - } - -private: - mutable bool add_items_{true}; - mutable bool is_pre_draft4_{false}; - mutable bool has_unique_items_{true}; -}; diff --git a/src/alterschema/canonicalizer/implicit_object_keywords.h b/src/alterschema/canonicalizer/implicit_object_keywords.h index 337edf305..d002902cb 100644 --- a/src/alterschema/canonicalizer/implicit_object_keywords.h +++ b/src/alterschema/canonicalizer/implicit_object_keywords.h @@ -14,22 +14,203 @@ class ImplicitObjectKeywords final : public SchemaTransformRule { const sourcemeta::core::SchemaWalker &, const sourcemeta::core::SchemaResolver &) const -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF( + ONLY_CONTINUE_IF(schema.is_object() && schema.defines("type") && + schema.at("type").is_string()); + + const auto &type_value{schema.at("type").to_string()}; + this->reset(); + + if (type_value == "object") { + this->check_object(schema, vocabularies); + } else if (type_value == "array") { + this->check_array(schema, vocabularies); + } + + ONLY_CONTINUE_IF(this->has_work_); + return true; + } + + auto transform(JSON &schema, const Result &) const -> void override { + // Object keywords + if (this->add_pattern_properties_) { + schema.assign("patternProperties", sourcemeta::core::JSON::make_object()); + } + + if (this->add_property_names_) { + schema.assign("propertyNames", sourcemeta::core::JSON{true}); + } + + if (this->add_min_properties_) { + if (schema.defines("required") && schema.at("required").is_array()) { + schema.assign("minProperties", + sourcemeta::core::JSON{schema.at("required").size()}); + } else { + schema.assign("minProperties", sourcemeta::core::JSON{0}); + } + } + + if (this->add_properties_) { + schema.assign("properties", sourcemeta::core::JSON::make_object()); + } + + if (this->add_additional_properties_) { + schema.assign("additionalProperties", + this->additional_properties_as_object_ + ? sourcemeta::core::JSON::make_object() + : sourcemeta::core::JSON{true}); + } + + // Array keywords + if (this->add_unique_items_) { + schema.assign("uniqueItems", sourcemeta::core::JSON{false}); + } + + if (this->add_items_) { + schema.assign("items", this->items_as_object_ + ? sourcemeta::core::JSON::make_object() + : sourcemeta::core::JSON{true}); + } + + if (this->add_min_items_) { + schema.assign("minItems", sourcemeta::core::JSON{0}); + } + } + +private: + auto reset() const -> void { + this->has_work_ = false; + this->add_pattern_properties_ = false; + this->add_property_names_ = false; + this->add_min_properties_ = false; + this->add_properties_ = false; + this->add_additional_properties_ = false; + this->additional_properties_as_object_ = false; + this->add_unique_items_ = false; + this->add_items_ = false; + this->items_as_object_ = false; + this->add_min_items_ = false; + } + + auto check_object(const sourcemeta::core::JSON &schema, + const sourcemeta::core::Vocabularies &vocabularies) const + -> void { + this->add_pattern_properties_ = + !schema.defines("patternProperties") && vocabularies.contains_any( {Vocabularies::Known::JSON_Schema_Draft_3, Vocabularies::Known::JSON_Schema_Draft_4, Vocabularies::Known::JSON_Schema_Draft_6, Vocabularies::Known::JSON_Schema_Draft_7, Vocabularies::Known::JSON_Schema_2019_09_Applicator, - Vocabularies::Known::JSON_Schema_2020_12_Applicator}) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "object" && - !schema.defines("patternProperties")); - return true; + Vocabularies::Known::JSON_Schema_2020_12_Applicator}); + + this->add_property_names_ = + !schema.defines("propertyNames") && + vocabularies.contains_any( + {Vocabularies::Known::JSON_Schema_Draft_6, + Vocabularies::Known::JSON_Schema_Draft_7, + Vocabularies::Known::JSON_Schema_2019_09_Applicator, + Vocabularies::Known::JSON_Schema_2020_12_Applicator}); + + this->add_min_properties_ = + !schema.defines("minProperties") && + vocabularies.contains_any( + {Vocabularies::Known::JSON_Schema_2020_12_Validation, + Vocabularies::Known::JSON_Schema_2019_09_Validation, + Vocabularies::Known::JSON_Schema_Draft_7, + Vocabularies::Known::JSON_Schema_Draft_6, + Vocabularies::Known::JSON_Schema_Draft_4}); + + this->add_properties_ = + !schema.defines("properties") && + ((vocabularies.contains( + Vocabularies::Known::JSON_Schema_2020_12_Validation) && + vocabularies.contains( + Vocabularies::Known::JSON_Schema_2020_12_Applicator)) || + (vocabularies.contains( + Vocabularies::Known::JSON_Schema_2019_09_Validation) && + vocabularies.contains( + Vocabularies::Known::JSON_Schema_2019_09_Applicator)) || + vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_7, + Vocabularies::Known::JSON_Schema_Draft_6, + Vocabularies::Known::JSON_Schema_Draft_4, + Vocabularies::Known::JSON_Schema_Draft_3, + Vocabularies::Known::JSON_Schema_Draft_2, + Vocabularies::Known::JSON_Schema_Draft_1, + Vocabularies::Known::JSON_Schema_Draft_0})); + + const bool is_legacy{ + vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, + Vocabularies::Known::JSON_Schema_Draft_1, + Vocabularies::Known::JSON_Schema_Draft_2, + Vocabularies::Known::JSON_Schema_Draft_3, + Vocabularies::Known::JSON_Schema_Draft_4, + Vocabularies::Known::JSON_Schema_Draft_6, + Vocabularies::Known::JSON_Schema_Draft_7})}; + + this->add_additional_properties_ = + is_legacy && !schema.defines("additionalProperties"); + this->additional_properties_as_object_ = + vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, + Vocabularies::Known::JSON_Schema_Draft_1, + Vocabularies::Known::JSON_Schema_Draft_2, + Vocabularies::Known::JSON_Schema_Draft_3}); + + this->has_work_ = this->add_pattern_properties_ || + this->add_property_names_ || this->add_min_properties_ || + this->add_properties_ || this->add_additional_properties_; } - auto transform(JSON &schema, const Result &) const -> void override { - schema.assign("patternProperties", sourcemeta::core::JSON::make_object()); + auto check_array(const sourcemeta::core::JSON &schema, + const sourcemeta::core::Vocabularies &vocabularies) const + -> void { + if (!vocabularies.contains_any( + {Vocabularies::Known::JSON_Schema_Draft_0, + Vocabularies::Known::JSON_Schema_Draft_1, + Vocabularies::Known::JSON_Schema_Draft_2, + Vocabularies::Known::JSON_Schema_Draft_3, + Vocabularies::Known::JSON_Schema_Draft_4, + Vocabularies::Known::JSON_Schema_Draft_6, + Vocabularies::Known::JSON_Schema_Draft_7, + Vocabularies::Known::JSON_Schema_2019_09_Applicator, + Vocabularies::Known::JSON_Schema_2020_12_Applicator})) { + return; + } + + const bool is_modern{vocabularies.contains_any( + {Vocabularies::Known::JSON_Schema_2019_09_Applicator, + Vocabularies::Known::JSON_Schema_2020_12_Applicator})}; + const bool is_pre_draft4{ + vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, + Vocabularies::Known::JSON_Schema_Draft_1, + Vocabularies::Known::JSON_Schema_Draft_2, + Vocabularies::Known::JSON_Schema_Draft_3})}; + + this->add_unique_items_ = + !schema.defines("uniqueItems") && + !vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0, + Vocabularies::Known::JSON_Schema_Draft_1}); + + this->add_items_ = !is_modern && !schema.defines("items"); + this->items_as_object_ = is_pre_draft4; + + this->add_min_items_ = !schema.defines("minItems"); + + this->has_work_ = + this->add_unique_items_ || this->add_items_ || this->add_min_items_; } + + mutable bool has_work_{false}; + // Object + mutable bool add_pattern_properties_{false}; + mutable bool add_property_names_{false}; + mutable bool add_min_properties_{false}; + mutable bool add_properties_{false}; + mutable bool add_additional_properties_{false}; + mutable bool additional_properties_as_object_{false}; + // Array + mutable bool add_unique_items_{false}; + mutable bool add_items_{false}; + mutable bool items_as_object_{false}; + mutable bool add_min_items_{false}; }; diff --git a/src/alterschema/canonicalizer/min_properties_implicit.h b/src/alterschema/canonicalizer/min_properties_implicit.h deleted file mode 100644 index 4fbdd054f..000000000 --- a/src/alterschema/canonicalizer/min_properties_implicit.h +++ /dev/null @@ -1,41 +0,0 @@ -class MinPropertiesImplicit final : public SchemaTransformRule { -public: - using mutates = std::true_type; - using reframe_after_transform = std::true_type; - MinPropertiesImplicit() - : SchemaTransformRule{ - "min_properties_implicit", - "The `minProperties` keyword has a logical default of 0 or the " - "size of `required`"} {}; - - [[nodiscard]] auto - condition(const sourcemeta::core::JSON &schema, - const sourcemeta::core::JSON &, - const sourcemeta::core::Vocabularies &vocabularies, - const sourcemeta::core::SchemaFrame &, - const sourcemeta::core::SchemaFrame::Location &, - const sourcemeta::core::SchemaWalker &, - const sourcemeta::core::SchemaResolver &) const - -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF(vocabularies.contains_any( - {Vocabularies::Known::JSON_Schema_2020_12_Validation, - Vocabularies::Known::JSON_Schema_2019_09_Validation, - Vocabularies::Known::JSON_Schema_Draft_7, - Vocabularies::Known::JSON_Schema_Draft_6, - Vocabularies::Known::JSON_Schema_Draft_4}) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "object" && - !schema.defines("minProperties")); - return true; - } - - auto transform(JSON &schema, const Result &) const -> void override { - if (schema.defines("required") && schema.at("required").is_array()) { - schema.assign("minProperties", - sourcemeta::core::JSON{schema.at("required").size()}); - } else { - schema.assign("minProperties", sourcemeta::core::JSON{0}); - } - } -}; diff --git a/src/alterschema/canonicalizer/properties_implicit.h b/src/alterschema/canonicalizer/properties_implicit.h deleted file mode 100644 index 9d2f69b93..000000000 --- a/src/alterschema/canonicalizer/properties_implicit.h +++ /dev/null @@ -1,46 +0,0 @@ -class PropertiesImplicit final : public SchemaTransformRule { -public: - using mutates = std::true_type; - using reframe_after_transform = std::true_type; - PropertiesImplicit() - : SchemaTransformRule{"properties_implicit", - "Every object has an implicit `properties` " - "that consists of the empty object"} {}; - - [[nodiscard]] auto - condition(const sourcemeta::core::JSON &schema, - const sourcemeta::core::JSON &, - const sourcemeta::core::Vocabularies &vocabularies, - const sourcemeta::core::SchemaFrame &, - const sourcemeta::core::SchemaFrame::Location &, - const sourcemeta::core::SchemaWalker &, - const sourcemeta::core::SchemaResolver &) const - -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF( - ((vocabularies.contains( - Vocabularies::Known::JSON_Schema_2020_12_Validation) && - vocabularies.contains( - Vocabularies::Known::JSON_Schema_2020_12_Applicator)) || - (vocabularies.contains( - Vocabularies::Known::JSON_Schema_2019_09_Validation) && - vocabularies.contains( - Vocabularies::Known::JSON_Schema_2019_09_Applicator)) || - vocabularies.contains_any( - {Vocabularies::Known::JSON_Schema_Draft_7, - Vocabularies::Known::JSON_Schema_Draft_6, - Vocabularies::Known::JSON_Schema_Draft_4, - Vocabularies::Known::JSON_Schema_Draft_3, - Vocabularies::Known::JSON_Schema_Draft_2, - Vocabularies::Known::JSON_Schema_Draft_1, - Vocabularies::Known::JSON_Schema_Draft_0})) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "object" && - !schema.defines("properties")); - return true; - } - - auto transform(JSON &schema, const Result &) const -> void override { - schema.assign("properties", sourcemeta::core::JSON::make_object()); - } -}; diff --git a/src/alterschema/canonicalizer/property_names_implicit.h b/src/alterschema/canonicalizer/property_names_implicit.h deleted file mode 100644 index b3f83e7ee..000000000 --- a/src/alterschema/canonicalizer/property_names_implicit.h +++ /dev/null @@ -1,33 +0,0 @@ -class PropertyNamesImplicit final : public SchemaTransformRule { -public: - using mutates = std::true_type; - using reframe_after_transform = std::true_type; - PropertyNamesImplicit() - : SchemaTransformRule{"property_names_implicit", ""} {}; - - [[nodiscard]] auto - condition(const sourcemeta::core::JSON &schema, - const sourcemeta::core::JSON &, - const sourcemeta::core::Vocabularies &vocabularies, - const sourcemeta::core::SchemaFrame &, - const sourcemeta::core::SchemaFrame::Location &, - const sourcemeta::core::SchemaWalker &, - const sourcemeta::core::SchemaResolver &) const - -> SchemaTransformRule::Result override { - ONLY_CONTINUE_IF( - vocabularies.contains_any( - {Vocabularies::Known::JSON_Schema_Draft_6, - Vocabularies::Known::JSON_Schema_Draft_7, - Vocabularies::Known::JSON_Schema_2019_09_Applicator, - Vocabularies::Known::JSON_Schema_2020_12_Applicator}) && - schema.is_object() && schema.defines("type") && - schema.at("type").is_string() && - schema.at("type").to_string() == "object" && - !schema.defines("propertyNames")); - return true; - } - - auto transform(JSON &schema, const Result &) const -> void override { - schema.assign("propertyNames", sourcemeta::core::JSON{true}); - } -}; diff --git a/test/alterschema/alterschema_canonicalize_draft4_test.cc b/test/alterschema/alterschema_canonicalize_draft4_test.cc index bed1774fb..8bd64f96a 100644 --- a/test/alterschema/alterschema_canonicalize_draft4_test.cc +++ b/test/alterschema/alterschema_canonicalize_draft4_test.cc @@ -194,17 +194,14 @@ TEST_F(CanonicalizerDraft4Test, min_properties_covered_by_required_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "minProperties": 2, - "required": [ "foo", "bar" ], - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -217,17 +214,14 @@ TEST_F(CanonicalizerDraft4Test, min_properties_implicit_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -241,17 +235,14 @@ TEST_F(CanonicalizerDraft4Test, min_properties_implicit_2) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1251,43 +1242,43 @@ TEST_F(CanonicalizerDraft4Test, dependencies_property_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true - } - }, - { + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { "foo": true, "bar": true }, + "required": [ "foo" ], "patternProperties": {}, + "minProperties": 1, + "properties": {}, "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1300,64 +1291,78 @@ TEST_F(CanonicalizerDraft4Test, dependencies_schema_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { + "type": "object", + "required": [ "foo" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "allOf": [ + { "type": "object", "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, "patternProperties": {}, + "minProperties": 1, + "properties": {}, "additionalProperties": true + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "bar" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] } - }, - { - "allOf": [ - { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "bar" ], - "minProperties": 1, - "properties": { "bar": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + ] + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1642,21 +1647,34 @@ TEST_F(CanonicalizerDraft4Test, anyof_with_nested_allof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "anyOf": [ - { "allOf": [ - { "type": "object", "required": [ "name" ], - "properties": { "name": true }, "patternProperties": {}, - "additionalProperties": true, - "minProperties": 1 }, - { "type": "object", "required": [ "age" ], - "properties": { "age": true }, "patternProperties": {}, - "additionalProperties": true, - "minProperties": 1 } - ] }, - { "type": "string", "minLength": 0 } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "anyOf": [ + { + "allOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "string", + "minLength": 0 + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1688,12 +1706,16 @@ TEST_F(CanonicalizerDraft4Test, not_with_object_schema) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "not": { "type": "object", "required": [ "forbidden" ], - "properties": { "forbidden": true }, "patternProperties": {}, - "additionalProperties": true, - "minProperties": 1 } - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "not": { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1848,37 +1870,37 @@ TEST_F(CanonicalizerDraft4Test, anyof_with_type_sibling) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "a" ], - "properties": { "a": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true - }, - { - "type": "object", - "required": [ "b" ], - "properties": { "b": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1931,42 +1953,42 @@ TEST_F(CanonicalizerDraft4Test, type_with_anyof_and_properties) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "name" ], - "properties": { "name": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true - }, - { - "type": "object", - "required": [ "age" ], - "properties": { "age": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true - } - ] - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 0 - } + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - "minProperties": 0, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 0 + } + }, + "patternProperties": {}, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2216,19 +2238,15 @@ TEST_F(CanonicalizerDraft4Test, object_required_max_less_than_required) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": [ "a", "b", "c" ], - "maxProperties": 2, - "properties": { - "a": true, - "b": true, - "c": true - }, - "patternProperties": {}, - "additionalProperties": true, - "minProperties": 3 - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "required": [ "a", "b", "c" ], + "maxProperties": 2, + "patternProperties": {}, + "minProperties": 3, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2816,43 +2834,55 @@ TEST_F(CanonicalizerDraft4Test, property_named_ref_not_a_reference) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "not": { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "admin" ], - "minProperties": 1, - "properties": { "admin": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { - "type": "array", - "minItems": 0, - "uniqueItems": false, - "items": true - }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "admin" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "type": "object", + "properties": { + "$ref": { + "type": "string", + "minLength": 0 } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "$ref": { "type": "string", "minLength": 0 } - }, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + "patternProperties": {}, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2870,31 +2900,33 @@ TEST_F(CanonicalizerDraft4Test, enum_value_containing_ref_string) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "kind" ], - "minProperties": 1, - "properties": { "kind": true }, - "patternProperties": {}, - "additionalProperties": true - } - ] + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "kind" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "kind": { + "enum": [ "$ref", "inline" ] + } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "kind": { "enum": [ "$ref", "inline" ] } - }, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + "patternProperties": {}, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2959,17 +2991,14 @@ TEST_F(CanonicalizerDraft4Test, dependencies_tautology_stripped) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": [ "bar", "foo" ], - "minProperties": 2, - "properties": { - "bar": true, - "foo": true - }, - "patternProperties": {}, - "additionalProperties": true - })JSON"); + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "required": [ "bar", "foo" ], + "patternProperties": {}, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2988,39 +3017,39 @@ TEST_F(CanonicalizerDraft4Test, type_allof_ref_and_typed_not) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "not": { - "type": "object", - "required": [ "forbidden" ], - "minProperties": 1, - "properties": { "forbidden": true }, - "patternProperties": {}, - "additionalProperties": true - } - }, - { - "$ref": "#/definitions/base" - }, - { + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "base": { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + }, + "allOf": [ + { + "not": { "type": "object", - "minProperties": 0, - "properties": {}, + "required": [ "forbidden" ], "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "base": { - "type": "object", - "minProperties": 0, + "minProperties": 1, "properties": {}, - "patternProperties": {}, "additionalProperties": true } + }, + { + "$ref": "#/definitions/base" + }, + { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3073,81 +3102,109 @@ TEST_F(CanonicalizerDraft4Test, dependencies_with_existing_anyof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + ] + }, + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, + "required": [ "x" ], "patternProperties": {}, - "additionalProperties": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "x" ], - "minProperties": 1, - "properties": { "x": true }, - "patternProperties": {}, - "additionalProperties": true - } - }, - { - "type": "object", - "required": [ "x", "y" ], - "minProperties": 2, - "properties": { "x": true, "y": true }, - "patternProperties": {}, + "properties": {}, "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "x", "y" ], + "patternProperties": {}, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3170,85 +3227,127 @@ TEST_F(CanonicalizerDraft4Test, full_restructure_ref_in_typed_keyword) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-04/schema#", - "allOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "pos": { + "type": "integer", + "minimum": 0, + "multipleOf": 1 + } + }, + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "anyOf": [ + { "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, { "type": "object", - "required": [ "forbidden" ], + "required": [ "a" ], + "patternProperties": {}, "minProperties": 1, - "properties": { "forbidden": true }, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], "patternProperties": {}, + "minProperties": 1, + "properties": {}, "additionalProperties": true }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } ] } + ] + }, + { + "type": "object", + "properties": { + "x": { + "$ref": "#/definitions/pos" + } }, - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], - "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": { - "x": { - "$ref": "#/definitions/pos" - } - }, - "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "pos": { - "type": "integer", - "minimum": 0, - "multipleOf": 1 - } + "patternProperties": {}, + "minProperties": 0, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } diff --git a/test/alterschema/alterschema_canonicalize_draft6_test.cc b/test/alterschema/alterschema_canonicalize_draft6_test.cc index b396cd452..bb09fd6c2 100644 --- a/test/alterschema/alterschema_canonicalize_draft6_test.cc +++ b/test/alterschema/alterschema_canonicalize_draft6_test.cc @@ -195,18 +195,15 @@ TEST_F(CanonicalizerDraft6Test, min_properties_covered_by_required_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "type": "object", - "minProperties": 2, - "required": [ "foo", "bar" ], - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -219,18 +216,15 @@ TEST_F(CanonicalizerDraft6Test, min_properties_implicit_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -244,18 +238,15 @@ TEST_F(CanonicalizerDraft6Test, min_properties_implicit_2) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1260,46 +1251,46 @@ TEST_F(CanonicalizerDraft6Test, dependencies_property_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - }, - { + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { "foo": true, "bar": true }, + "required": [ "foo" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1312,68 +1303,82 @@ TEST_F(CanonicalizerDraft6Test, dependencies_schema_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { + "type": "object", + "required": [ "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "allOf": [ + { "type": "object", "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] } - }, - { - "allOf": [ - { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "bar" ], - "minProperties": 1, - "properties": { "bar": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + ] + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1662,21 +1667,36 @@ TEST_F(CanonicalizerDraft6Test, anyof_with_nested_allof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "anyOf": [ - { "allOf": [ - { "type": "object", "required": [ "name" ], - "properties": { "name": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 }, - { "type": "object", "required": [ "age" ], - "properties": { "age": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 } - ] }, - { "type": "string", "minLength": 0 } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "anyOf": [ + { + "allOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "string", + "minLength": 0 + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1708,12 +1728,17 @@ TEST_F(CanonicalizerDraft6Test, not_with_object_schema) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "not": { "type": "object", "required": [ "forbidden" ], - "properties": { "forbidden": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 } - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "not": { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1869,40 +1894,40 @@ TEST_F(CanonicalizerDraft6Test, anyof_with_type_sibling) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "a" ], - "properties": { "a": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "b" ], - "properties": { "b": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1955,47 +1980,47 @@ TEST_F(CanonicalizerDraft6Test, type_with_anyof_and_properties) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "name" ], - "properties": { "name": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "age" ], - "properties": { "age": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 0 - } + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - "minProperties": 0, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); - - CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 0 + } + }, + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); + + CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } TEST_F(CanonicalizerDraft6Test, double_negation) { @@ -2228,20 +2253,16 @@ TEST_F(CanonicalizerDraft6Test, object_required_max_less_than_required) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "type": "object", - "required": [ "a", "b", "c" ], - "maxProperties": 2, - "properties": { - "a": true, - "b": true, - "c": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true, - "minProperties": 3 - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "required": [ "a", "b", "c" ], + "maxProperties": 2, + "patternProperties": {}, + "propertyNames": true, + "minProperties": 3, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2749,45 +2770,57 @@ TEST_F(CanonicalizerDraft6Test, property_named_ref_not_a_reference) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "not": { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "admin" ], - "minProperties": 1, - "properties": { "admin": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "array", - "minItems": 0, - "uniqueItems": false, - "items": true - }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "admin" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "type": "object", + "properties": { + "$ref": { + "type": "string", + "minLength": 0 } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "$ref": { "type": "string", "minLength": 0 } - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2805,33 +2838,35 @@ TEST_F(CanonicalizerDraft6Test, enum_value_containing_ref_string) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "kind" ], - "minProperties": 1, - "properties": { "kind": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "kind" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "kind": { + "enum": [ "$ref", "inline" ] + } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "kind": { "enum": [ "$ref", "inline" ] } - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2897,18 +2932,15 @@ TEST_F(CanonicalizerDraft6Test, dependencies_tautology_stripped) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "type": "object", - "required": [ "bar", "foo" ], - "minProperties": 2, - "properties": { - "bar": true, - "foo": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "required": [ "bar", "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2927,42 +2959,42 @@ TEST_F(CanonicalizerDraft6Test, type_allof_ref_and_typed_not) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "not": { - "type": "object", - "required": [ "forbidden" ], - "minProperties": 1, - "propertyNames": true, - "properties": { "forbidden": true }, - "patternProperties": {}, - "additionalProperties": true - } - }, - { - "$ref": "#/definitions/base" - }, - { + "$schema": "http://json-schema.org/draft-06/schema#", + "definitions": { + "base": { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + }, + "allOf": [ + { + "not": { "type": "object", - "minProperties": 0, - "propertyNames": true, - "properties": {}, + "required": [ "forbidden" ], "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "base": { - "type": "object", - "minProperties": 0, "propertyNames": true, + "minProperties": 1, "properties": {}, - "patternProperties": {}, "additionalProperties": true } + }, + { + "$ref": "#/definitions/base" + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3013,86 +3045,114 @@ TEST_F(CanonicalizerDraft6Test, dependencies_with_existing_anyof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { + "$schema": "http://json-schema.org/draft-06/schema#", + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + ] + }, + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, + "required": [ "x" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], + "propertyNames": true, "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "x" ], - "minProperties": 1, - "properties": { "x": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - }, - { - "type": "object", - "required": [ "x", "y" ], - "minProperties": 2, - "properties": { "x": true, "y": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "properties": {}, + "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "x", "y" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3115,89 +3175,131 @@ TEST_F(CanonicalizerDraft6Test, full_restructure_ref_in_typed_keyword) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-06/schema#", - "allOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-06/schema#", + "definitions": { + "pos": { + "type": "integer", + "minimum": 0, + "multipleOf": 1 + } + }, + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "anyOf": [ + { "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, { "type": "object", - "required": [ "forbidden" ], + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, "minProperties": 1, - "properties": { "forbidden": true }, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } ] } + ] + }, + { + "type": "object", + "properties": { + "x": { + "$ref": "#/definitions/pos" + } }, - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], - "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "propertyNames": true, - "properties": { - "x": { - "$ref": "#/definitions/pos" - } - }, - "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "pos": { - "type": "integer", - "minimum": 0, - "multipleOf": 1 - } + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } diff --git a/test/alterschema/alterschema_canonicalize_draft7_test.cc b/test/alterschema/alterschema_canonicalize_draft7_test.cc index 70d757e2c..830cc95b1 100644 --- a/test/alterschema/alterschema_canonicalize_draft7_test.cc +++ b/test/alterschema/alterschema_canonicalize_draft7_test.cc @@ -195,18 +195,15 @@ TEST_F(CanonicalizerDraft7Test, min_properties_covered_by_required_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "minProperties": 2, - "required": [ "foo", "bar" ], - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -219,18 +216,15 @@ TEST_F(CanonicalizerDraft7Test, min_properties_implicit_1) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -244,18 +238,15 @@ TEST_F(CanonicalizerDraft7Test, min_properties_implicit_2) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { - "foo": true, - "bar": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "minProperties": 2, + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1260,46 +1251,46 @@ TEST_F(CanonicalizerDraft7Test, dependencies_property_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - }, - { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "foo", "bar" ], - "minProperties": 2, - "properties": { "foo": true, "bar": true }, + "required": [ "foo" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1312,68 +1303,82 @@ TEST_F(CanonicalizerDraft7Test, dependencies_schema_single) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { + "type": "object", + "required": [ "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "allOf": [ + { "type": "object", "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] } - }, - { - "allOf": [ - { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "bar" ], - "minProperties": 1, - "properties": { "bar": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + ] + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1662,21 +1667,36 @@ TEST_F(CanonicalizerDraft7Test, anyof_with_nested_allof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "anyOf": [ - { "allOf": [ - { "type": "object", "required": [ "name" ], - "properties": { "name": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 }, - { "type": "object", "required": [ "age" ], - "properties": { "age": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 } - ] }, - { "type": "string", "minLength": 0 } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "allOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "string", + "minLength": 0 + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1708,12 +1728,17 @@ TEST_F(CanonicalizerDraft7Test, not_with_object_schema) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "not": { "type": "object", "required": [ "forbidden" ], - "properties": { "forbidden": true }, "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 1 } - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "not": { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1869,40 +1894,40 @@ TEST_F(CanonicalizerDraft7Test, anyof_with_type_sibling) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "a" ], - "properties": { "a": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "b" ], - "properties": { "b": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -1955,45 +1980,45 @@ TEST_F(CanonicalizerDraft7Test, type_with_anyof_and_properties) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "name" ], - "properties": { "name": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "age" ], - "properties": { "age": true }, - "minProperties": 1, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 0 - } + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - "minProperties": 0, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + { + "type": "object", + "required": [ "age" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 0 + } + }, + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2228,20 +2253,16 @@ TEST_F(CanonicalizerDraft7Test, object_required_max_less_than_required) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ "a", "b", "c" ], - "maxProperties": 2, - "properties": { - "a": true, - "b": true, - "c": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true, - "minProperties": 3 - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "a", "b", "c" ], + "maxProperties": 2, + "patternProperties": {}, + "propertyNames": true, + "minProperties": 3, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2749,45 +2770,57 @@ TEST_F(CanonicalizerDraft7Test, property_named_ref_not_a_reference) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "not": { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "admin" ], - "minProperties": 1, - "properties": { "admin": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "array", - "minItems": 0, - "uniqueItems": false, - "items": true - }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "admin" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "type": "object", + "properties": { + "$ref": { + "type": "string", + "minLength": 0 } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "$ref": { "type": "string", "minLength": 0 } - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2805,33 +2838,35 @@ TEST_F(CanonicalizerDraft7Test, enum_value_containing_ref_string) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "anyOf": [ - { - "type": "object", - "required": [ "kind" ], - "minProperties": 1, - "properties": { "kind": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "anyOf": [ + { + "type": "object", + "required": [ "kind" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "type": "object", + "properties": { + "kind": { + "enum": [ "$ref", "inline" ] + } }, - { - "type": "object", - "minProperties": 0, - "properties": { - "kind": { "enum": [ "$ref", "inline" ] } - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2897,18 +2932,15 @@ TEST_F(CanonicalizerDraft7Test, dependencies_tautology_stripped) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ "bar", "foo" ], - "minProperties": 2, - "properties": { - "bar": true, - "foo": true - }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - })JSON"); + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "bar", "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -2927,42 +2959,42 @@ TEST_F(CanonicalizerDraft7Test, type_allof_ref_and_typed_not) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "not": { - "type": "object", - "required": [ "forbidden" ], - "minProperties": 1, - "propertyNames": true, - "properties": { "forbidden": true }, - "patternProperties": {}, - "additionalProperties": true - } - }, - { - "$ref": "#/definitions/base" - }, - { + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "base": { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + }, + "allOf": [ + { + "not": { "type": "object", - "minProperties": 0, - "propertyNames": true, - "properties": {}, + "required": [ "forbidden" ], "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "base": { - "type": "object", - "minProperties": 0, "propertyNames": true, + "minProperties": 1, "properties": {}, - "patternProperties": {}, "additionalProperties": true } + }, + { + "$ref": "#/definitions/base" + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3013,86 +3045,114 @@ TEST_F(CanonicalizerDraft7Test, dependencies_with_existing_anyof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + ] + }, + { + "allOf": [ + { + "anyOf": [ + { + "not": { "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, + "required": [ "x" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], + "propertyNames": true, "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "allOf": [ - { - "anyOf": [ - { - "not": { - "type": "object", - "required": [ "x" ], - "minProperties": 1, - "properties": { "x": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - }, - { - "type": "object", - "required": [ "x", "y" ], - "minProperties": 2, - "properties": { "x": true, "y": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "properties": {}, + "additionalProperties": true } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "properties": {}, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - })JSON"); + }, + { + "type": "object", + "required": [ "x", "y" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -3115,89 +3175,131 @@ TEST_F(CanonicalizerDraft7Test, full_restructure_ref_in_typed_keyword) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "pos": { + "type": "integer", + "minimum": 0, + "multipleOf": 1 + } + }, + "allOf": [ + { + "not": { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "forbidden" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + } + }, + { + "anyOf": [ + { "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, { "type": "object", - "required": [ "forbidden" ], + "required": [ "a" ], + "patternProperties": {}, + "propertyNames": true, "minProperties": 1, - "properties": { "forbidden": true }, + "properties": {}, + "additionalProperties": true + }, + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } + ] + }, + { + "anyOf": [ + { + "enum": [ null ] + }, + { + "enum": [ false, true ] + }, + { + "type": "object", + "required": [ "b" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } + { + "type": "array", + "uniqueItems": false, + "items": true, + "minItems": 0 + }, + { + "type": "string", + "minLength": 0 + }, + { + "type": "number" + } ] } + ] + }, + { + "type": "object", + "properties": { + "x": { + "$ref": "#/definitions/pos" + } }, - { - "anyOf": [ - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - }, - { - "anyOf": [ - { "enum": [ null ] }, - { "enum": [ false, true ] }, - { - "type": "object", - "required": [ "b" ], - "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { "type": "array", "minItems": 0, "uniqueItems": false, "items": true }, - { "type": "string", "minLength": 0 }, - { "type": "number" } - ] - } - ] - }, - { - "type": "object", - "minProperties": 0, - "propertyNames": true, - "properties": { - "x": { - "$ref": "#/definitions/pos" - } - }, - "patternProperties": {}, - "additionalProperties": true - } - ], - "definitions": { - "pos": { - "type": "integer", - "minimum": 0, - "multipleOf": 1 - } + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "additionalProperties": true } - })JSON"); + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -4782,39 +4884,39 @@ TEST_F(CanonicalizerDraft7Test, if_then_else_with_type_object) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "if": { - "type": "object", - "required": [ "foo" ], - "minProperties": 1, - "properties": { "foo": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "then": { - "type": "object", - "required": [ "bar" ], - "minProperties": 1, - "properties": { "bar": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "else": true - }, - { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "if": { "type": "object", + "required": [ "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, "properties": {}, + "additionalProperties": true + }, + "then": { + "type": "object", + "required": [ "bar" ], "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 0 - } - ] - })JSON"); + "minProperties": 1, + "properties": {}, + "additionalProperties": true + }, + "else": true + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -5408,38 +5510,38 @@ TEST_F(CanonicalizerDraft7Test, nested_if_then_else_in_then) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", + "if": { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + }, + "then": { "if": { "type": "object", - "properties": {}, + "required": [ "name" ], "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 0 + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, "then": { - "if": { - "type": "object", - "required": [ "name" ], - "minProperties": 1, - "properties": { "name": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "then": { - "type": "object", - "required": [ "name", "age" ], - "minProperties": 2, - "properties": { "name": true, "age": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "else": true + "type": "object", + "required": [ "name", "age" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true }, "else": true - })JSON"); + }, + "else": true +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -5486,49 +5588,67 @@ TEST_F(CanonicalizerDraft7Test, dependencies_with_if_then_else) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { "not": { "type": "object", "required": [ "foo" ], "minProperties": 1, "properties": { "foo": true }, "patternProperties": {}, "additionalProperties": true, "propertyNames": true } }, - { "type": "object", "required": [ "foo", "bar" ], "minProperties": 2, "properties": { "foo": true, "bar": true }, "patternProperties": {}, "additionalProperties": true, "propertyNames": true } - ] - } - ] - }, - { - "if": { - "type": "object", - "required": [ "baz" ], - "minProperties": 1, - "properties": { "baz": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "then": { - "type": "object", - "required": [ "baz", "qux" ], - "minProperties": 2, - "properties": { "baz": true, "qux": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "else": true - }, - { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { + "type": "object", + "required": [ "foo" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "type": "object", + "required": [ "foo", "bar" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 2, + "properties": {}, + "additionalProperties": true + } + ] + } + ] + }, + { + "if": { "type": "object", + "required": [ "baz" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, "properties": {}, + "additionalProperties": true + }, + "then": { + "type": "object", + "required": [ "baz", "qux" ], "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 0 - } - ] - })JSON"); + "minProperties": 2, + "properties": {}, + "additionalProperties": true + }, + "else": true + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -5767,72 +5887,72 @@ TEST_F(CanonicalizerDraft7Test, if_then_else_with_type_not_anyof) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "not": { + "type": "object", + "required": [ "banned" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "anyOf": [ + { "type": "object", - "required": [ "banned" ], - "minProperties": 1, - "properties": { "banned": true }, + "required": [ "a" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - }, - { - "anyOf": [ - { - "type": "object", - "required": [ "a" ], - "minProperties": 1, - "properties": { "a": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "b" ], - "minProperties": 1, - "properties": { "b": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - }, - { - "if": { - "type": "object", - "required": [ "flag" ], + "propertyNames": true, "minProperties": 1, - "properties": { "flag": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "properties": {}, + "additionalProperties": true }, - "then": { + { "type": "object", - "required": [ "flag", "extra" ], - "minProperties": 2, - "properties": { "flag": true, "extra": true }, + "required": [ "b" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "else": true - }, - { + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + ] + }, + { + "if": { "type": "object", + "required": [ "flag" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, "properties": {}, + "additionalProperties": true + }, + "then": { + "type": "object", + "required": [ "flag", "extra" ], "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 0 - } - ] - })JSON"); + "minProperties": 2, + "properties": {}, + "additionalProperties": true + }, + "else": true + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -5850,80 +5970,80 @@ TEST_F(CanonicalizerDraft7Test, if_then_else_with_dependencies_and_type) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "allOf": [ - { - "anyOf": [ - { - "not": { + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "allOf": [ + { + "anyOf": [ + { + "not": { + "type": "object", + "required": [ "credit_card" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true + } + }, + { + "allOf": [ + { "type": "object", "required": [ "credit_card" ], + "patternProperties": {}, + "propertyNames": true, "minProperties": 1, - "properties": { "credit_card": true }, + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "required": [ "billing_address" ], "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true } - }, - { - "allOf": [ - { - "type": "object", - "required": [ "credit_card" ], - "minProperties": 1, - "properties": { "credit_card": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - { - "type": "object", - "required": [ "billing_address" ], - "minProperties": 1, - "properties": { "billing_address": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - } - ] - } - ] - } - ] - }, - { - "if": { - "type": "object", - "required": [ "premium" ], - "minProperties": 1, - "properties": { "premium": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "then": { - "type": "object", - "required": [ "premium", "support_level" ], - "minProperties": 2, - "properties": { "premium": true, "support_level": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "else": true - }, - { + ] + } + ] + } + ] + }, + { + "if": { "type": "object", + "required": [ "premium" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, "properties": {}, + "additionalProperties": true + }, + "then": { + "type": "object", + "required": [ "premium", "support_level" ], "patternProperties": {}, - "additionalProperties": true, "propertyNames": true, - "minProperties": 0 - } - ] - })JSON"); + "minProperties": 2, + "properties": {}, + "additionalProperties": true + }, + "else": true + }, + { + "type": "object", + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0, + "properties": {}, + "additionalProperties": true + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); } @@ -6072,38 +6192,48 @@ TEST_F(CanonicalizerDraft7Test, if_then_else_closed_object) { })JSON"); const auto expected = sourcemeta::core::parse_json(R"JSON({ - "$schema": "http://json-schema.org/draft-07/schema#", - "allOf": [ - { - "if": { - "type": "object", - "required": [ "name" ], - "minProperties": 1, - "properties": { "name": true }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true - }, - "then": { - "type": "object", - "properties": { "name": { "type": "string", "minLength": 1 } }, - "patternProperties": {}, - "additionalProperties": true, - "propertyNames": true, - "minProperties": 0 - }, - "else": true + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "if": { + "type": "object", + "required": [ "name" ], + "patternProperties": {}, + "propertyNames": true, + "minProperties": 1, + "properties": {}, + "additionalProperties": true }, - { + "then": { "type": "object", - "properties": { "name": { "type": "string", "minLength": 0 } }, + "properties": { + "name": { + "type": "string", + "minLength": 1 + } + }, "patternProperties": {}, - "additionalProperties": false, "propertyNames": true, - "minProperties": 0 - } - ] - })JSON"); + "minProperties": 0, + "additionalProperties": true + }, + "else": true + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 0 + } + }, + "additionalProperties": false, + "patternProperties": {}, + "propertyNames": true, + "minProperties": 0 + } + ] +})JSON"); CANONICALIZE_AND_VALIDATE(document, expected, *compiled_meta_); }