rubocop-iotventure 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/Gemfile.lock +1 -1
- data/README.md +36 -5
- data/lib/rubocop/cop/iotventure/additional_properties.rb +106 -0
- data/lib/rubocop/cop/iotventure/schema_definition_per_response.rb +40 -0
- data/lib/rubocop/cop/iotventure_cops.rb +1 -0
- data/lib/rubocop/iotventure/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: beea57247dc2b420f2cdff17108b0b0b4a7f542e242b4a01d3515ae3f16d5337
|
4
|
+
data.tar.gz: 4ce49ecad2def1b3879ea73cfa6c147af01c606e0a5ffc237812e3dcc3bb394c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d55967ddcd84b5c83e12c2e27efbc80d628c4de15cb187f9aebd954a042eff85f5260fe7967db59e4a077156395fd6ea5f6b82a81bf5167691a9225ea15257c
|
7
|
+
data.tar.gz: 543147561c54fc3bdbe7d6009773df9a65a8c951271125b6d907b7ad0a2753c0380fed021331c24d440780bf6652b89cfa653db1c018403a3d19e756650e6ae6
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -12,14 +12,45 @@ gem 'rubocop-iotventure', require: false
|
|
12
12
|
|
13
13
|
And then execute:
|
14
14
|
|
15
|
-
|
15
|
+
```shell
|
16
|
+
bundle install
|
17
|
+
```
|
16
18
|
|
17
|
-
Or install it yourself
|
19
|
+
Or install it yourself using:
|
18
20
|
|
19
|
-
|
21
|
+
```shell
|
22
|
+
gem install rubocop-iotventure
|
23
|
+
```
|
20
24
|
|
21
25
|
## Usage
|
22
26
|
|
27
|
+
### IotVenture/AdditionalProperties
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# bad
|
31
|
+
{
|
32
|
+
type: :object,
|
33
|
+
properties: {
|
34
|
+
prop1: { type: :string },
|
35
|
+
prop2: { type: :string }
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
# good
|
40
|
+
{
|
41
|
+
type: :object,
|
42
|
+
properties: {
|
43
|
+
prop1: { type: :string },
|
44
|
+
prop2: { type: :string }
|
45
|
+
},
|
46
|
+
additionalProperties: false
|
47
|
+
}
|
48
|
+
```
|
49
|
+
|
50
|
+
This cop checks that all object schemas have the `additionalProperties` property set to `false` or a useful matcher (not `true`). This is to prevent unexpected properties from being added to the object.
|
51
|
+
|
52
|
+
Note: This only works for schemas defined as Ruby hashes.
|
53
|
+
|
23
54
|
### Iotventure/DuplicateResponseCode
|
24
55
|
|
25
56
|
```ruby
|
@@ -69,7 +100,7 @@ response 200, 'response description' do
|
|
69
100
|
end
|
70
101
|
```
|
71
102
|
|
72
|
-
This cop checks that there is exactly one top-level schema definition per response block
|
103
|
+
This cop checks that there is exactly one top-level schema definition per response block (except 204 No Content blocks, those should not have any schema definitions). Multiple or misplaced schema definitions might overwrite each other.
|
73
104
|
|
74
105
|
## Development
|
75
106
|
|
@@ -79,7 +110,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
79
110
|
|
80
111
|
## Contributing
|
81
112
|
|
82
|
-
Bug reports and pull requests are welcome on Bitbucket at https://bitbucket.org/iotventure/rubocop-iotventure
|
113
|
+
Bug reports and pull requests are welcome on Bitbucket at <https://bitbucket.org/iotventure/rubocop-iotventure>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://bitbucket.org/iotventure/rubocop-iotventure/src/master/CODE_OF_CONDUCT.md).
|
83
114
|
|
84
115
|
## License
|
85
116
|
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Iotventure
|
6
|
+
# This cop checks that every array and object schema has additionalProperties (defined or set to false).
|
7
|
+
# Note: This only works for schemas defined as Ruby hashes.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
#
|
13
|
+
# {
|
14
|
+
# type: :object,
|
15
|
+
# properties: {
|
16
|
+
# foo: { type: :string },
|
17
|
+
# bar: { type: :boolean }
|
18
|
+
# }
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
#
|
25
|
+
# {
|
26
|
+
# type: :object,
|
27
|
+
# properties: {
|
28
|
+
# foo: { type: :string },
|
29
|
+
# bar: { type: :boolean }
|
30
|
+
# },
|
31
|
+
# additionalProperties: true
|
32
|
+
# }
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
#
|
39
|
+
# {
|
40
|
+
# type: :object,
|
41
|
+
# properties: {
|
42
|
+
# foo: { type: :string },
|
43
|
+
# bar: { type: :boolean }
|
44
|
+
# },
|
45
|
+
# additionalProperties: false
|
46
|
+
# }
|
47
|
+
#
|
48
|
+
#
|
49
|
+
#
|
50
|
+
class AdditionalProperties < Base
|
51
|
+
MISSING_MSG = 'Schema is missing additionalProperties. ' \
|
52
|
+
'Please add it to the schema at %<current>s'
|
53
|
+
ALWAYS_TRUE_MSG = 'Schema has additionalProperties set to true. ' \
|
54
|
+
'Please set it to false or define a rule at %<current>s'
|
55
|
+
|
56
|
+
# @!method schema_definition_with_properties?(node)
|
57
|
+
def_node_matcher :schema_object_definition_with_properties?, <<~PATTERN
|
58
|
+
(hash<
|
59
|
+
(pair
|
60
|
+
(sym :type)
|
61
|
+
{(sym :object) (str "object")}
|
62
|
+
)
|
63
|
+
(pair
|
64
|
+
<{(sym :properties) (sym :patternProperties)}>
|
65
|
+
...
|
66
|
+
)
|
67
|
+
...
|
68
|
+
>)
|
69
|
+
PATTERN
|
70
|
+
|
71
|
+
# @!method always_true_schema?(node)
|
72
|
+
def_node_matcher :always_true_schema?, <<~PATTERN
|
73
|
+
{
|
74
|
+
(true)
|
75
|
+
(hash) # Empty hash is also always true in JSON Schema
|
76
|
+
}
|
77
|
+
PATTERN
|
78
|
+
|
79
|
+
def on_hash(node)
|
80
|
+
return unless schema_object_definition_with_properties?(node)
|
81
|
+
|
82
|
+
additional_properties = node.pairs.find { |pair| pair.key.value == :additionalProperties }
|
83
|
+
return add_missing_offense(node) unless additional_properties
|
84
|
+
|
85
|
+
add_always_true_offense(node) if always_true_schema?(additional_properties.value)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def add_missing_offense(node)
|
91
|
+
add_offense(node, message: format(MISSING_MSG, current: source_location(node)))
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_always_true_offense(node)
|
95
|
+
add_offense(node, message: format(ALWAYS_TRUE_MSG, current: source_location(node)))
|
96
|
+
end
|
97
|
+
|
98
|
+
def source_location(node)
|
99
|
+
range = node.location.expression
|
100
|
+
path = smart_path(range.source_buffer.name)
|
101
|
+
"#{path}:#{range.line}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -43,6 +43,15 @@ module RuboCop
|
|
43
43
|
#
|
44
44
|
# @example
|
45
45
|
#
|
46
|
+
# # bad
|
47
|
+
#
|
48
|
+
# response 204, 'response description' do
|
49
|
+
# schema '$ref' => '#/components/schemas/object'
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
#
|
46
55
|
# # good
|
47
56
|
#
|
48
57
|
# response 200, 'response description' do
|
@@ -50,6 +59,14 @@ module RuboCop
|
|
50
59
|
# end
|
51
60
|
#
|
52
61
|
#
|
62
|
+
# @example
|
63
|
+
#
|
64
|
+
# # good
|
65
|
+
#
|
66
|
+
# response 204, 'response description' do
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
#
|
53
70
|
class SchemaDefinitionPerResponse < Base
|
54
71
|
MISSING_MSG = 'Schema definition is missing for response declaration at %<current>s.'
|
55
72
|
DUPLICATED_MSG = 'Schema definition is defined both at %<first>s and %<second>s '\
|
@@ -58,6 +75,8 @@ module RuboCop
|
|
58
75
|
'but should be defined immediately after response declaration at %<other>s.'
|
59
76
|
MISPLACED_WITHOUT_RESPONSE_DEFINITION_MSG = 'Schema definition for %<schema_name>s is '\
|
60
77
|
'outside of response declaration.'
|
78
|
+
NO_CONTENT_SCHEMA_MSG = 'Schema definition for %<schema_name>s is defined at %<current>s, '\
|
79
|
+
'but 204 response should not have schema.'
|
61
80
|
|
62
81
|
# @!method response_block?(node)
|
63
82
|
def_node_matcher :response_block, <<~PATTERN
|
@@ -69,6 +88,18 @@ module RuboCop
|
|
69
88
|
)
|
70
89
|
PATTERN
|
71
90
|
|
91
|
+
# @!method no_content_response(node)
|
92
|
+
def_node_matcher :no_content_response, <<~PATTERN
|
93
|
+
(block
|
94
|
+
(send nil? :response
|
95
|
+
(:int 204)
|
96
|
+
(:str _)
|
97
|
+
...
|
98
|
+
)
|
99
|
+
...
|
100
|
+
)
|
101
|
+
PATTERN
|
102
|
+
|
72
103
|
# @!method schema_definition?(node)
|
73
104
|
def_node_matcher :schema_definition, <<~PATTERN
|
74
105
|
(send nil? :schema
|
@@ -119,6 +150,7 @@ module RuboCop
|
|
119
150
|
# that will be picked up by check_for_misplaced_schema
|
120
151
|
def check_schema_definition_count(node)
|
121
152
|
schema_definitions = schema_definitions(node)
|
153
|
+
return check_no_schemas(schema_definitions) if no_content_response(node)
|
122
154
|
|
123
155
|
return if schema_definitions.count == 1
|
124
156
|
|
@@ -127,6 +159,14 @@ module RuboCop
|
|
127
159
|
add_duplicated_offense(node, schema_definitions)
|
128
160
|
end
|
129
161
|
|
162
|
+
def check_no_schemas(schema_definitions)
|
163
|
+
schema_definitions.each do |schema_definition|
|
164
|
+
message = format(NO_CONTENT_SCHEMA_MSG, schema_name: find_schema_name(schema_definition),
|
165
|
+
current: source_location(schema_definition))
|
166
|
+
add_offense(schema_definition.loc.expression, message: message)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
130
170
|
def add_missing_offense(node)
|
131
171
|
message = format(MISSING_MSG, current: source_location(node))
|
132
172
|
add_offense(node.loc.expression, message: message)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-iotventure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fynn Starke
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- bin/setup
|
129
129
|
- config/default.yml
|
130
130
|
- lib/rubocop-iotventure.rb
|
131
|
+
- lib/rubocop/cop/iotventure/additional_properties.rb
|
131
132
|
- lib/rubocop/cop/iotventure/duplicate_response_code.rb
|
132
133
|
- lib/rubocop/cop/iotventure/save_request_example.rb
|
133
134
|
- lib/rubocop/cop/iotventure/schema_definition_per_response.rb
|
@@ -159,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
160
|
- !ruby/object:Gem::Version
|
160
161
|
version: '0'
|
161
162
|
requirements: []
|
162
|
-
rubygems_version: 3.3
|
163
|
+
rubygems_version: 3.2.3
|
163
164
|
signing_key:
|
164
165
|
specification_version: 4
|
165
166
|
summary: Rswag cops.
|