Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/extension/alterschema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME alterschema
linter/definitions_to_defs.h

# Strict
strict/required_properties_in_properties.h)
strict/required_properties_in_properties.h
linter/then_false.h)

if(SOURCEMETA_CORE_INSTALL)
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME alterschema)
Expand Down
2 changes: 2 additions & 0 deletions src/extension/alterschema/alterschema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ contains_any(const Vocabularies &container,
#include "linter/property_names_type_default.h"
#include "linter/single_type_array.h"
#include "linter/then_empty.h"
#include "linter/then_false.h"
#include "linter/then_without_if.h"
#include "linter/unevaluated_items_default.h"
#include "linter/unevaluated_properties_default.h"
Expand Down Expand Up @@ -108,6 +109,7 @@ auto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void {
bundle.add<NotFalse>();
bundle.add<ThenEmpty>();
bundle.add<ElseEmpty>();
bundle.add<ThenFalse>();
bundle.add<ThenWithoutIf>();
bundle.add<DependenciesPropertyTautology>();
bundle.add<DependentRequiredTautology>();
Expand Down
42 changes: 42 additions & 0 deletions src/extension/alterschema/linter/then_false.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class ThenFalse final : public SchemaTransformRule {
public:
ThenFalse()
: SchemaTransformRule{
"then_false",
"`Setting the `then` keyword to the false schema is a convoluted "
"way of negating the `if` subschema, which you can more cleanly "
"represent using the `not` keyword"} {};

[[nodiscard]] auto
condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,
const SchemaFrame &, const SchemaFrame::Location &,
const SchemaWalker &, const SchemaResolver &) const
-> SchemaTransformRule::Result override {
return contains_any(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make use of the new macros? You can rebase from main and see how I refactored the other rules! More specifically, the new macros will let you highlight if specifically on the Registry

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#"}) &&
schema.is_object() && schema.defines("if") &&
schema.defines("then") && is_schema(schema.at("then")) &&
schema.at("then").is_boolean() && !schema.at("then").to_boolean() &&
is_schema(schema.at("if")) &&
!(schema.at("if").is_boolean() && schema.at("if").to_boolean()) &&
(!schema.defines("else") || (schema.at("else").is_boolean() &&
schema.at("else").to_boolean())) &&
(!schema.at("if").is_object() ||
std::all_of(schema.at("if").as_object().begin(),
schema.at("if").as_object().end(),
[&schema](const auto &entry) {
return !schema.defines(entry.first);
}));
}

auto transform(JSON &schema) const -> void override {
auto if_schema = schema.at("if");
schema.erase("if");
schema.erase("then");
schema.erase("else");
schema.assign("not", std::move(if_schema));
}
};
176 changes: 176 additions & 0 deletions test/alterschema/alterschema_lint_2019_09_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2831,3 +2831,179 @@ TEST(AlterSchema_lint_2019_09, required_properties_in_properties_5) {

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"not": {
"properties": {
"flag": {
"const": true
}
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_2) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"then": false,
"else": true
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"not": {
"properties": {
"flag": {
"const": true
}
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_3) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": true,
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": true,
"then": false
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_4) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": false,
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema"
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_5) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"name": { "type": "string" }
},
"if": {
"properties": {
"name": { "type": "number" }
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"name": { "type": "string" }
},
"if": {
"properties": {
"name": { "type": "number" }
}
},
"then": false
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_6) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"properties": {
"flag": { "const": true }
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"not": {
"properties": {
"flag": { "const": true }
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_7) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"type": "object"
},
"then": false,
"else": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"type": "object"
},
"then": false,
"else": false
})JSON");

EXPECT_EQ(document, expected);
}
Loading
Loading