-
-
Notifications
You must be signed in to change notification settings - Fork 18
lint: add require_schema_declaration rule #885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| class RequireSchemaDeclaration final : public SchemaTransformRule { | ||
| public: | ||
| using mutates = std::false_type; | ||
| using reframe_after_transform = std::false_type; | ||
| RequireSchemaDeclaration() | ||
| : SchemaTransformRule{ | ||
| "require_schema_declaration", | ||
| "A schema should declare its dialect using the `$schema` " | ||
| "keyword"} {}; | ||
| [[nodiscard]] auto | ||
| condition(const sourcemeta::core::JSON &schema, | ||
| const sourcemeta::core::JSON &, | ||
| const sourcemeta::blaze::Vocabularies &vocabularies, | ||
| const sourcemeta::blaze::SchemaFrame &, | ||
| const sourcemeta::blaze::SchemaFrame::Location &location, | ||
| const sourcemeta::blaze::SchemaWalker &, | ||
| const sourcemeta::blaze::SchemaResolver &, const bool) const | ||
| -> SchemaTransformRule::Result override { | ||
| ONLY_CONTINUE_IF(location.pointer.empty()); | ||
| ONLY_CONTINUE_IF(vocabularies.contains_any( | ||
| {Vocabularies::Known::JSON_Schema_2020_12_Core, | ||
| Vocabularies::Known::JSON_Schema_2019_09_Core, | ||
| 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_3_Hyper})); | ||
| ONLY_CONTINUE_IF(schema.is_object()); | ||
| ONLY_CONTINUE_IF(!schema.defines("$schema")); | ||
| return APPLIES_TO_KEYWORDS("$schema"); | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5982,3 +5982,47 @@ TEST(AlterSchema_lint_2019_09, | |
| EXPECT_EQ(sourcemeta::core::to_string(outcome.locations.at(1)), | ||
| "/patternProperties/[[:digit:]]"); | ||
| } | ||
|
|
||
| TEST(AlterSchema_lint_2019_09, require_schema_declaration_1) { | ||
| const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({ | ||
| "$schema": "https://json-schema.org/draft/2019-09/schema", | ||
| "title": "My Schema", | ||
| "description": "A schema", | ||
| "examples": [ "hello" ], | ||
| "type": "string" | ||
| })JSON"); | ||
|
|
||
| LINT_WITHOUT_FIX(document, result, traces); | ||
|
|
||
| EXPECT_TRUE(result.first); | ||
| EXPECT_EQ(traces.size(), 0); | ||
| } | ||
|
|
||
| TEST(AlterSchema_lint_2019_09, require_schema_declaration_2) { | ||
| const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({ | ||
| "title": "My Schema", | ||
| "description": "A schema", | ||
| "examples": [ "hello" ], | ||
| "type": "string" | ||
| })JSON"); | ||
|
|
||
| std::vector<std::tuple<sourcemeta::core::Pointer, std::string, std::string, | ||
| sourcemeta::blaze::SchemaTransformRule::Result, bool>> | ||
| traces; | ||
| sourcemeta::blaze::SchemaTransformer bundle; | ||
| sourcemeta::blaze::add(bundle, sourcemeta::blaze::AlterSchemaMode::Linter); | ||
| const auto result = bundle.check( | ||
| document, sourcemeta::blaze::schema_walker, alterschema_test_resolver, | ||
| [&traces](const auto &pointer, const auto &name, const auto &message, | ||
| const auto &outcome, const auto &fixable) { | ||
| traces.emplace_back(pointer, name, message, outcome, fixable); | ||
| }, | ||
| "https://json-schema.org/draft/2019-09/schema"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, but because the linter will analyse the schema, this ONLY ever works if you pass a default dialect, right? If so, we should be able to transform to fix?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Though on the other side, I know people use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right that the linter can only fire this rule when it already knows the dialect. Making it fixable makes sense then ,the fix would insert $schema with the resolved dialect URI. On the defaultDialect concern, I agree it could be noisy for users who manage a collection of schemas that way, but with auto-fix it becomes a one-shot cleanup. I can update the rule to be fixable if that is the direction you want. |
||
|
|
||
| EXPECT_FALSE(result.first); | ||
| EXPECT_EQ(traces.size(), 1); | ||
| EXPECT_LINT_TRACE(traces, 0, "", "require_schema_declaration", | ||
| "A schema should declare its dialect using the `$schema` " | ||
| "keyword", | ||
| false); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.