Skip to content

Commit

Permalink
Port antipattern/exclusive_(max|min)imum_number_and_(max|min)imum f…
Browse files Browse the repository at this point in the history
…rom JSON BinPack

Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Sep 9, 2024
1 parent ff818e2 commit 0e4bb8e
Show file tree
Hide file tree
Showing 9 changed files with 528 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/linter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ noa_library(NAMESPACE sourcemeta PROJECT alterschema NAME linter
antipattern/const_with_type.h
antipattern/duplicate_enum_values.h
antipattern/duplicate_required_values.h
antipattern/exclusive_maximum_number_and_maximum.h
antipattern/exclusive_minimum_number_and_minimum.h
antipattern/enum_with_type.h

# Simplify
Expand Down
4 changes: 2 additions & 2 deletions src/linter/antipattern/duplicate_required_values.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
class DuplicateRequiredValues final : public Rule {
public:
DuplicateRequiredValues()
: Rule("duplicate_required_values",
: Rule{"duplicate_required_values",
"Setting duplicate values in `required` is considered an "
"anti-pattern") {};
"anti-pattern"} {};

[[nodiscard]] auto
condition(const sourcemeta::jsontoolkit::JSON &schema, const std::string &,
Expand Down
32 changes: 32 additions & 0 deletions src/linter/antipattern/exclusive_maximum_number_and_maximum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class ExclusiveMaximumNumberAndMaximum final : public Rule {
public:
ExclusiveMaximumNumberAndMaximum()
: Rule{"exclusive_maximum_number_and_maximum",
"Setting both `exclusiveMaximum` and `maximum` at the same time "
"is considered an anti-pattern. You should choose one"} {};

[[nodiscard]] auto
condition(const sourcemeta::jsontoolkit::JSON &schema, const std::string &,
const std::set<std::string> &vocabularies,
const sourcemeta::jsontoolkit::Pointer &) const -> bool override {
return contains_any(
vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/validation",
"https://json-schema.org/draft/2019-09/vocab/validation",
"http://json-schema.org/draft-07/schema#",
"http://json-schema.org/draft-06/schema#"}) &&
schema.is_object() && schema.defines("maximum") &&
schema.defines("exclusiveMaximum") &&
schema.at("maximum").is_number() &&
schema.at("exclusiveMaximum").is_number();
}

auto transform(Transformer &transformer) const -> void override {
if (transformer.schema().at("maximum") <
transformer.schema().at("exclusiveMaximum")) {
transformer.erase("exclusiveMaximum");
} else {
transformer.erase("maximum");
}
}
};
32 changes: 32 additions & 0 deletions src/linter/antipattern/exclusive_minimum_number_and_minimum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class ExclusiveMinimumNumberAndMinimum final : public Rule {
public:
ExclusiveMinimumNumberAndMinimum()
: Rule{"exclusive_minimum_number_and_minimum",
"Setting both `exclusiveMinimum` and `minimum` at the same time "
"is considered an anti-pattern. You should choose one"} {};

[[nodiscard]] auto
condition(const sourcemeta::jsontoolkit::JSON &schema, const std::string &,
const std::set<std::string> &vocabularies,
const sourcemeta::jsontoolkit::Pointer &) const -> bool override {
return contains_any(
vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/validation",
"https://json-schema.org/draft/2019-09/vocab/validation",
"http://json-schema.org/draft-07/schema#",
"http://json-schema.org/draft-06/schema#"}) &&
schema.is_object() && schema.defines("minimum") &&
schema.defines("exclusiveMinimum") &&
schema.at("minimum").is_number() &&
schema.at("exclusiveMinimum").is_number();
}

auto transform(Transformer &transformer) const -> void override {
if (transformer.schema().at("exclusiveMinimum") <
transformer.schema().at("minimum")) {
transformer.erase("exclusiveMinimum");
} else {
transformer.erase("minimum");
}
}
};
4 changes: 4 additions & 0 deletions src/linter/linter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ auto contains_any(const T &container, const T &values) -> bool {
#include "antipattern/duplicate_enum_values.h"
#include "antipattern/duplicate_required_values.h"
#include "antipattern/enum_with_type.h"
#include "antipattern/exclusive_maximum_number_and_maximum.h"
#include "antipattern/exclusive_minimum_number_and_minimum.h"
// Simplify
#include "simplify/single_type_array.h"
// Redundant
Expand Down Expand Up @@ -49,6 +51,8 @@ auto add(Bundle &bundle, const LinterCategory category) -> void {
bundle.add<DuplicateEnumValues>();
bundle.add<DuplicateRequiredValues>();
bundle.add<ConstWithType>();
bundle.add<ExclusiveMaximumNumberAndMaximum>();
bundle.add<ExclusiveMinimumNumberAndMinimum>();
break;
case LinterCategory::Simplify:
bundle.add<SingleTypeArray>();
Expand Down
114 changes: 114 additions & 0 deletions test/linter/2019_09_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -586,3 +586,117 @@ TEST(Lint_2019_09, duplicate_required_values_1) {

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_maximum_number_and_maximum_1) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMaximum": 3,
"maximum": 3
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMaximum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_maximum_number_and_maximum_2) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMaximum": 3,
"maximum": 2
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"maximum": 2
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_maximum_number_and_maximum_3) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMaximum": 3,
"maximum": 1
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"maximum": 1
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_minimum_number_and_minimum_1) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMinimum": 3,
"minimum": 3
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMinimum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_minimum_number_and_minimum_2) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMinimum": 3,
"minimum": 2
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMinimum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2019_09, exclusive_minimum_number_and_minimum_3) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"exclusiveMinimum": 3,
"minimum": 4
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"minimum": 4
})JSON");

EXPECT_EQ(document, expected);
}
114 changes: 114 additions & 0 deletions test/linter/2020_12_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -569,3 +569,117 @@ TEST(Lint_2020_12, duplicate_required_values_1) {

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_maximum_number_and_maximum_1) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMaximum": 3,
"maximum": 3
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMaximum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_maximum_number_and_maximum_2) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMaximum": 3,
"maximum": 2
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"maximum": 2
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_maximum_number_and_maximum_3) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMaximum": 3,
"maximum": 1
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"maximum": 1
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_minimum_number_and_minimum_1) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMinimum": 3,
"minimum": 3
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMinimum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_minimum_number_and_minimum_2) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMinimum": 3,
"minimum": 2
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMinimum": 3
})JSON");

EXPECT_EQ(document, expected);
}

TEST(Lint_2020_12, exclusive_minimum_number_and_minimum_3) {
sourcemeta::jsontoolkit::JSON document =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"exclusiveMinimum": 3,
"minimum": 4
})JSON");

LINT_AND_FIX(document);

const sourcemeta::jsontoolkit::JSON expected =
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"minimum": 4
})JSON");

EXPECT_EQ(document, expected);
}
Loading

0 comments on commit 0e4bb8e

Please sign in to comment.