From bc7589f180df3d6d50e1380f857dd878e34471c3 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Mon, 9 Sep 2024 16:22:53 -0400 Subject: [PATCH] Port `redundant/pattern_properties_default` from JSON BinPack (#208) Signed-off-by: Juan Cruz Viotti --- src/linter/CMakeLists.txt | 1 + src/linter/linter.cc | 2 ++ .../redundant/pattern_properties_default.h | 28 +++++++++++++++++++ test/linter/2019_09_test.cc | 17 +++++++++++ test/linter/2020_12_test.cc | 17 +++++++++++ test/linter/draft3_test.cc | 17 +++++++++++ test/linter/draft4_test.cc | 17 +++++++++++ test/linter/draft6_test.cc | 17 +++++++++++ test/linter/draft7_test.cc | 17 +++++++++++ 9 files changed, 133 insertions(+) create mode 100644 src/linter/redundant/pattern_properties_default.h diff --git a/src/linter/CMakeLists.txt b/src/linter/CMakeLists.txt index 97834b3..49b36ee 100644 --- a/src/linter/CMakeLists.txt +++ b/src/linter/CMakeLists.txt @@ -33,6 +33,7 @@ noa_library(NAMESPACE sourcemeta PROJECT alterschema NAME linter redundant/items_schema_default.h redundant/max_contains_without_contains.h redundant/min_contains_without_contains.h + redundant/pattern_properties_default.h redundant/properties_default.h redundant/then_without_if.h redundant/unevaluated_items_default.h diff --git a/src/linter/linter.cc b/src/linter/linter.cc index 169b1ab..7ce22f9 100644 --- a/src/linter/linter.cc +++ b/src/linter/linter.cc @@ -43,6 +43,7 @@ auto contains_any(const T &container, const T &values) -> bool { #include "redundant/items_schema_default.h" #include "redundant/max_contains_without_contains.h" #include "redundant/min_contains_without_contains.h" +#include "redundant/pattern_properties_default.h" #include "redundant/properties_default.h" #include "redundant/then_without_if.h" #include "redundant/unevaluated_items_default.h" @@ -85,6 +86,7 @@ auto add(Bundle &bundle, const LinterCategory category) -> void { bundle.add(); bundle.add(); bundle.add(); + bundle.add(); bundle.add(); bundle.add(); bundle.add(); diff --git a/src/linter/redundant/pattern_properties_default.h b/src/linter/redundant/pattern_properties_default.h new file mode 100644 index 0000000..71ae322 --- /dev/null +++ b/src/linter/redundant/pattern_properties_default.h @@ -0,0 +1,28 @@ +class PatternPropertiesDefault final : public Rule { +public: + PatternPropertiesDefault() + : Rule{"pattern_properties_default", + "Setting the `patternProperties` keyword to the empty object " + "does not add any further constraint"} {}; + + [[nodiscard]] auto + condition(const sourcemeta::jsontoolkit::JSON &schema, const std::string &, + const std::set &vocabularies, + const sourcemeta::jsontoolkit::Pointer &) const -> bool override { + return contains_any( + vocabularies, + {"https://json-schema.org/draft/2020-12/vocab/applicator", + "https://json-schema.org/draft/2019-09/vocab/applicator", + "http://json-schema.org/draft-07/schema#", + "http://json-schema.org/draft-06/schema#", + "http://json-schema.org/draft-04/schema#", + "http://json-schema.org/draft-03/schema#"}) && + schema.is_object() && schema.defines("patternProperties") && + schema.at("patternProperties").is_object() && + schema.at("patternProperties").empty(); + } + + auto transform(Transformer &transformer) const -> void override { + transformer.erase("patternProperties"); + } +}; diff --git a/test/linter/2019_09_test.cc b/test/linter/2019_09_test.cc index b1d7c63..939b004 100644 --- a/test/linter/2019_09_test.cc +++ b/test/linter/2019_09_test.cc @@ -840,3 +840,20 @@ TEST(Lint_2019_09, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_2019_09, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "https://json-schema.org/draft/2019-09/schema" + })JSON"); + + EXPECT_EQ(document, expected); +} diff --git a/test/linter/2020_12_test.cc b/test/linter/2020_12_test.cc index c11d925..e19707d 100644 --- a/test/linter/2020_12_test.cc +++ b/test/linter/2020_12_test.cc @@ -823,3 +823,20 @@ TEST(Lint_2020_12, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_2020_12, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema" + })JSON"); + + EXPECT_EQ(document, expected); +} diff --git a/test/linter/draft3_test.cc b/test/linter/draft3_test.cc index aa38271..3f85ab7 100644 --- a/test/linter/draft3_test.cc +++ b/test/linter/draft3_test.cc @@ -285,3 +285,20 @@ TEST(Lint_draft3, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_draft3, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-03/schema#", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-03/schema#" + })JSON"); + + EXPECT_EQ(document, expected); +} diff --git a/test/linter/draft4_test.cc b/test/linter/draft4_test.cc index dbbf975..6eebdd8 100644 --- a/test/linter/draft4_test.cc +++ b/test/linter/draft4_test.cc @@ -339,3 +339,20 @@ TEST(Lint_draft4, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_draft4, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-04/schema#", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-04/schema#" + })JSON"); + + EXPECT_EQ(document, expected); +} diff --git a/test/linter/draft6_test.cc b/test/linter/draft6_test.cc index 15bc929..4456855 100644 --- a/test/linter/draft6_test.cc +++ b/test/linter/draft6_test.cc @@ -490,3 +490,20 @@ TEST(Lint_draft6, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_draft6, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-06/schema#", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-06/schema#" + })JSON"); + + EXPECT_EQ(document, expected); +} diff --git a/test/linter/draft7_test.cc b/test/linter/draft7_test.cc index a0f8b42..88d766f 100644 --- a/test/linter/draft7_test.cc +++ b/test/linter/draft7_test.cc @@ -581,3 +581,20 @@ TEST(Lint_draft7, properties_default) { EXPECT_EQ(document, expected); } + +TEST(Lint_draft7, pattern_properties_default) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-07/schema#", + "patternProperties": {} + })JSON"); + + LINT_AND_FIX(document); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$schema": "http://json-schema.org/draft-07/schema#" + })JSON"); + + EXPECT_EQ(document, expected); +}