openapi3_parser 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +1 -1
  5. data/TODO.md +4 -4
  6. data/lib/openapi3_parser/array_sentence.rb +12 -0
  7. data/lib/openapi3_parser/cautious_dig.rb +39 -0
  8. data/lib/openapi3_parser/context.rb +53 -1
  9. data/lib/openapi3_parser/context/location.rb +1 -0
  10. data/lib/openapi3_parser/context/pointer.rb +67 -5
  11. data/lib/openapi3_parser/document.rb +45 -4
  12. data/lib/openapi3_parser/error.rb +9 -0
  13. data/lib/openapi3_parser/node/array.rb +14 -4
  14. data/lib/openapi3_parser/node/map.rb +45 -3
  15. data/lib/openapi3_parser/node/object.rb +25 -5
  16. data/lib/openapi3_parser/node_factory.rb +0 -150
  17. data/lib/openapi3_parser/node_factory/array.rb +198 -0
  18. data/lib/openapi3_parser/node_factory/callback.rb +24 -0
  19. data/lib/openapi3_parser/{node_factories → node_factory}/components.rb +24 -25
  20. data/lib/openapi3_parser/{node_factories → node_factory}/contact.rb +5 -6
  21. data/lib/openapi3_parser/{node_factories → node_factory}/discriminator.rb +6 -7
  22. data/lib/openapi3_parser/{node_factories → node_factory}/encoding.rb +6 -8
  23. data/lib/openapi3_parser/{node_factories → node_factory}/example.rb +4 -5
  24. data/lib/openapi3_parser/{node_factories → node_factory}/external_documentation.rb +4 -5
  25. data/lib/openapi3_parser/node_factory/field.rb +129 -0
  26. data/lib/openapi3_parser/node_factory/fields/reference.rb +54 -18
  27. data/lib/openapi3_parser/{node_factories → node_factory}/header.rb +4 -5
  28. data/lib/openapi3_parser/{node_factories → node_factory}/info.rb +6 -7
  29. data/lib/openapi3_parser/{node_factories → node_factory}/license.rb +4 -5
  30. data/lib/openapi3_parser/{node_factories → node_factory}/link.rb +6 -8
  31. data/lib/openapi3_parser/node_factory/map.rb +206 -21
  32. data/lib/openapi3_parser/{node_factories → node_factory}/media_type.rb +17 -16
  33. data/lib/openapi3_parser/{node_factories → node_factory}/oauth_flow.rb +2 -4
  34. data/lib/openapi3_parser/{node_factories → node_factory}/oauth_flows.rb +4 -6
  35. data/lib/openapi3_parser/node_factory/object.rb +66 -63
  36. data/lib/openapi3_parser/node_factory/object_factory/dsl.rb +50 -0
  37. data/lib/openapi3_parser/node_factory/object_factory/field_config.rb +88 -0
  38. data/lib/openapi3_parser/node_factory/object_factory/node_builder.rb +96 -0
  39. data/lib/openapi3_parser/node_factory/object_factory/validator.rb +172 -0
  40. data/lib/openapi3_parser/node_factory/openapi.rb +65 -0
  41. data/lib/openapi3_parser/node_factory/operation.rb +87 -0
  42. data/lib/openapi3_parser/node_factory/optional_reference.rb +7 -3
  43. data/lib/openapi3_parser/{node_factories → node_factory}/parameter.rb +16 -22
  44. data/lib/openapi3_parser/node_factory/parameter_like.rb +42 -0
  45. data/lib/openapi3_parser/{node_factories → node_factory}/path_item.rb +27 -29
  46. data/lib/openapi3_parser/{node_factories → node_factory}/paths.rb +21 -27
  47. data/lib/openapi3_parser/node_factory/recursive_pointer.rb +17 -0
  48. data/lib/openapi3_parser/node_factory/reference.rb +48 -0
  49. data/lib/openapi3_parser/{node_factories → node_factory}/request_body.rb +15 -19
  50. data/lib/openapi3_parser/{node_factories → node_factory}/response.rb +18 -21
  51. data/lib/openapi3_parser/node_factory/responses.rb +51 -0
  52. data/lib/openapi3_parser/{node_factories → node_factory}/schema.rb +33 -33
  53. data/lib/openapi3_parser/node_factory/security_requirement.rb +21 -0
  54. data/lib/openapi3_parser/{node_factories → node_factory}/security_scheme.rb +4 -6
  55. data/lib/openapi3_parser/{node_factories → node_factory}/server.rb +6 -8
  56. data/lib/openapi3_parser/{node_factories → node_factory}/server_variable.rb +10 -12
  57. data/lib/openapi3_parser/{node_factories → node_factory}/tag.rb +4 -6
  58. data/lib/openapi3_parser/node_factory/type_checker.rb +103 -0
  59. data/lib/openapi3_parser/{node_factories → node_factory}/xml.rb +4 -5
  60. data/lib/openapi3_parser/source/reference_resolver.rb +3 -3
  61. data/lib/openapi3_parser/validation/error.rb +9 -0
  62. data/lib/openapi3_parser/validation/input_validator.rb +18 -0
  63. data/lib/openapi3_parser/validation/validatable.rb +44 -0
  64. data/lib/openapi3_parser/validators/mutually_exclusive_fields.rb +121 -0
  65. data/lib/openapi3_parser/validators/required_fields.rb +37 -0
  66. data/lib/openapi3_parser/validators/unexpected_fields.rb +52 -0
  67. data/lib/openapi3_parser/version.rb +1 -1
  68. metadata +48 -38
  69. data/lib/openapi3_parser/node_factories/array.rb +0 -114
  70. data/lib/openapi3_parser/node_factories/callback.rb +0 -27
  71. data/lib/openapi3_parser/node_factories/map.rb +0 -120
  72. data/lib/openapi3_parser/node_factories/openapi.rb +0 -62
  73. data/lib/openapi3_parser/node_factories/operation.rb +0 -84
  74. data/lib/openapi3_parser/node_factories/parameter/parameter_like.rb +0 -41
  75. data/lib/openapi3_parser/node_factories/reference.rb +0 -35
  76. data/lib/openapi3_parser/node_factories/responses.rb +0 -60
  77. data/lib/openapi3_parser/node_factories/security_requirement.rb +0 -26
  78. data/lib/openapi3_parser/node_factory/field_config.rb +0 -88
  79. data/lib/openapi3_parser/node_factory/object/node_builder.rb +0 -97
  80. data/lib/openapi3_parser/node_factory/object/validator.rb +0 -176
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/array_sentence"
4
+ require "openapi3_parser/error"
5
+
6
+ module Openapi3Parser
7
+ module Validators
8
+ class UnexpectedFields
9
+ using ArraySentence
10
+ private_class_method :new
11
+
12
+ def self.call(*args)
13
+ new.call(*args)
14
+ end
15
+
16
+ def call(validatable,
17
+ allow_extensions: true,
18
+ allowed_fields: nil,
19
+ raise_on_invalid: true)
20
+ fields = unexpected_fields(validatable.input,
21
+ allowed_fields,
22
+ allow_extensions)
23
+ return if fields.empty?
24
+
25
+ if raise_on_invalid
26
+ location_summary = validatable.context.location_summary
27
+ raise Openapi3Parser::Error::UnexpectedFields,
28
+ "Unexpected fields for #{location_summary}: "\
29
+ "#{fields.sentence_join}"
30
+ else
31
+ validatable.add_error(
32
+ "Unexpected fields: #{fields.sentence_join}"
33
+ )
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def unexpected_fields(input, allowed_fields, allow_extensions)
40
+ if allowed_fields
41
+ extra_keys = input.keys - allowed_fields
42
+ return extra_keys unless allow_extensions
43
+ extra_keys.reject { |key| key =~ NodeFactory::EXTENSION_REGEX }
44
+ elsif !allow_extensions
45
+ input.keys.select { |key| key =~ NodeFactory::EXTENSION_REGEX }
46
+ else
47
+ []
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openapi3Parser
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi3_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Dew
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-18 00:00:00.000000000 Z
11
+ date: 2018-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commonmarker
@@ -129,6 +129,8 @@ files:
129
129
  - Rakefile
130
130
  - TODO.md
131
131
  - lib/openapi3_parser.rb
132
+ - lib/openapi3_parser/array_sentence.rb
133
+ - lib/openapi3_parser/cautious_dig.rb
132
134
  - lib/openapi3_parser/context.rb
133
135
  - lib/openapi3_parser/context/location.rb
134
136
  - lib/openapi3_parser/context/pointer.rb
@@ -169,47 +171,50 @@ files:
169
171
  - lib/openapi3_parser/node/server_variable.rb
170
172
  - lib/openapi3_parser/node/tag.rb
171
173
  - lib/openapi3_parser/node/xml.rb
172
- - lib/openapi3_parser/node_factories/array.rb
173
- - lib/openapi3_parser/node_factories/callback.rb
174
- - lib/openapi3_parser/node_factories/components.rb
175
- - lib/openapi3_parser/node_factories/contact.rb
176
- - lib/openapi3_parser/node_factories/discriminator.rb
177
- - lib/openapi3_parser/node_factories/encoding.rb
178
- - lib/openapi3_parser/node_factories/example.rb
179
- - lib/openapi3_parser/node_factories/external_documentation.rb
180
- - lib/openapi3_parser/node_factories/header.rb
181
- - lib/openapi3_parser/node_factories/info.rb
182
- - lib/openapi3_parser/node_factories/license.rb
183
- - lib/openapi3_parser/node_factories/link.rb
184
- - lib/openapi3_parser/node_factories/map.rb
185
- - lib/openapi3_parser/node_factories/media_type.rb
186
- - lib/openapi3_parser/node_factories/oauth_flow.rb
187
- - lib/openapi3_parser/node_factories/oauth_flows.rb
188
- - lib/openapi3_parser/node_factories/openapi.rb
189
- - lib/openapi3_parser/node_factories/operation.rb
190
- - lib/openapi3_parser/node_factories/parameter.rb
191
- - lib/openapi3_parser/node_factories/parameter/parameter_like.rb
192
- - lib/openapi3_parser/node_factories/path_item.rb
193
- - lib/openapi3_parser/node_factories/paths.rb
194
- - lib/openapi3_parser/node_factories/reference.rb
195
- - lib/openapi3_parser/node_factories/request_body.rb
196
- - lib/openapi3_parser/node_factories/response.rb
197
- - lib/openapi3_parser/node_factories/responses.rb
198
- - lib/openapi3_parser/node_factories/schema.rb
199
- - lib/openapi3_parser/node_factories/security_requirement.rb
200
- - lib/openapi3_parser/node_factories/security_scheme.rb
201
- - lib/openapi3_parser/node_factories/server.rb
202
- - lib/openapi3_parser/node_factories/server_variable.rb
203
- - lib/openapi3_parser/node_factories/tag.rb
204
- - lib/openapi3_parser/node_factories/xml.rb
205
174
  - lib/openapi3_parser/node_factory.rb
206
- - lib/openapi3_parser/node_factory/field_config.rb
175
+ - lib/openapi3_parser/node_factory/array.rb
176
+ - lib/openapi3_parser/node_factory/callback.rb
177
+ - lib/openapi3_parser/node_factory/components.rb
178
+ - lib/openapi3_parser/node_factory/contact.rb
179
+ - lib/openapi3_parser/node_factory/discriminator.rb
180
+ - lib/openapi3_parser/node_factory/encoding.rb
181
+ - lib/openapi3_parser/node_factory/example.rb
182
+ - lib/openapi3_parser/node_factory/external_documentation.rb
183
+ - lib/openapi3_parser/node_factory/field.rb
207
184
  - lib/openapi3_parser/node_factory/fields/reference.rb
185
+ - lib/openapi3_parser/node_factory/header.rb
186
+ - lib/openapi3_parser/node_factory/info.rb
187
+ - lib/openapi3_parser/node_factory/license.rb
188
+ - lib/openapi3_parser/node_factory/link.rb
208
189
  - lib/openapi3_parser/node_factory/map.rb
190
+ - lib/openapi3_parser/node_factory/media_type.rb
191
+ - lib/openapi3_parser/node_factory/oauth_flow.rb
192
+ - lib/openapi3_parser/node_factory/oauth_flows.rb
209
193
  - lib/openapi3_parser/node_factory/object.rb
210
- - lib/openapi3_parser/node_factory/object/node_builder.rb
211
- - lib/openapi3_parser/node_factory/object/validator.rb
194
+ - lib/openapi3_parser/node_factory/object_factory/dsl.rb
195
+ - lib/openapi3_parser/node_factory/object_factory/field_config.rb
196
+ - lib/openapi3_parser/node_factory/object_factory/node_builder.rb
197
+ - lib/openapi3_parser/node_factory/object_factory/validator.rb
198
+ - lib/openapi3_parser/node_factory/openapi.rb
199
+ - lib/openapi3_parser/node_factory/operation.rb
212
200
  - lib/openapi3_parser/node_factory/optional_reference.rb
201
+ - lib/openapi3_parser/node_factory/parameter.rb
202
+ - lib/openapi3_parser/node_factory/parameter_like.rb
203
+ - lib/openapi3_parser/node_factory/path_item.rb
204
+ - lib/openapi3_parser/node_factory/paths.rb
205
+ - lib/openapi3_parser/node_factory/recursive_pointer.rb
206
+ - lib/openapi3_parser/node_factory/reference.rb
207
+ - lib/openapi3_parser/node_factory/request_body.rb
208
+ - lib/openapi3_parser/node_factory/response.rb
209
+ - lib/openapi3_parser/node_factory/responses.rb
210
+ - lib/openapi3_parser/node_factory/schema.rb
211
+ - lib/openapi3_parser/node_factory/security_requirement.rb
212
+ - lib/openapi3_parser/node_factory/security_scheme.rb
213
+ - lib/openapi3_parser/node_factory/server.rb
214
+ - lib/openapi3_parser/node_factory/server_variable.rb
215
+ - lib/openapi3_parser/node_factory/tag.rb
216
+ - lib/openapi3_parser/node_factory/type_checker.rb
217
+ - lib/openapi3_parser/node_factory/xml.rb
213
218
  - lib/openapi3_parser/source.rb
214
219
  - lib/openapi3_parser/source/reference.rb
215
220
  - lib/openapi3_parser/source/reference_resolver.rb
@@ -221,12 +226,17 @@ files:
221
226
  - lib/openapi3_parser/source_input/url.rb
222
227
  - lib/openapi3_parser/validation/error.rb
223
228
  - lib/openapi3_parser/validation/error_collection.rb
229
+ - lib/openapi3_parser/validation/input_validator.rb
230
+ - lib/openapi3_parser/validation/validatable.rb
224
231
  - lib/openapi3_parser/validators/absolute_uri.rb
225
232
  - lib/openapi3_parser/validators/component_keys.rb
226
233
  - lib/openapi3_parser/validators/duplicate_parameters.rb
227
234
  - lib/openapi3_parser/validators/email.rb
228
235
  - lib/openapi3_parser/validators/media_type.rb
236
+ - lib/openapi3_parser/validators/mutually_exclusive_fields.rb
229
237
  - lib/openapi3_parser/validators/reference.rb
238
+ - lib/openapi3_parser/validators/required_fields.rb
239
+ - lib/openapi3_parser/validators/unexpected_fields.rb
230
240
  - lib/openapi3_parser/validators/url.rb
231
241
  - lib/openapi3_parser/version.rb
232
242
  - openapi3_parser.gemspec
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "openapi3_parser/context"
4
- require "openapi3_parser/error"
5
- require "openapi3_parser/node_factory"
6
- require "openapi3_parser/node/array"
7
- require "openapi3_parser/validation/error"
8
- require "openapi3_parser/validation/error_collection"
9
-
10
- module Openapi3Parser
11
- module NodeFactories
12
- class Array
13
- include NodeFactory
14
- input_type ::Array
15
-
16
- def initialize(
17
- context,
18
- default: [],
19
- value_input_type: nil,
20
- value_factory: nil,
21
- validate: nil
22
- )
23
- @default = default
24
- @given_value_input_type = value_input_type
25
- @given_value_factory = value_factory
26
- @given_validate = validate
27
- super(context)
28
- end
29
-
30
- private
31
-
32
- attr_reader :default, :given_value_input_type,
33
- :given_value_factory, :given_validate
34
-
35
- def process_input(input)
36
- input.each_with_index.map do |value, i|
37
- if value_factory?
38
- initialize_value_factory(Context.next_field(context, i))
39
- else
40
- value
41
- end
42
- end
43
- end
44
-
45
- def validate(input, _context)
46
- given_validate&.call(input, self)
47
- end
48
-
49
- def validate_input
50
- value_errors = processed_input.flat_map do |value|
51
- value.respond_to?(:errors) ? value.errors.to_a : []
52
- end
53
- errors = value_errors + validate_value_input_type(processed_input,
54
- context)
55
- Validation::ErrorCollection.combine(super, errors)
56
- end
57
-
58
- def build_node(input)
59
- check_value_input_type(input)
60
- data = input.map do |value|
61
- value.respond_to?(:node) ? value.node : value
62
- end
63
- build_array(data, context)
64
- end
65
-
66
- def build_array(data, context)
67
- Node::Array.new(data, context)
68
- end
69
-
70
- def build_resolved_input
71
- processed_input.map do |value|
72
- value.respond_to?(:resolved_input) ? value.resolved_input : value
73
- end
74
- end
75
-
76
- def value_factory?
77
- !given_value_factory.nil?
78
- end
79
-
80
- def initialize_value_factory(context)
81
- factory = given_value_factory
82
- return factory.new(context) if factory.is_a?(Class)
83
- factory.call(context)
84
- end
85
-
86
- def validate_value_input_type(input, context)
87
- input.each_with_index.each_with_object([]) do |(value, i), memo|
88
- error = error_for_value_input_type(value)
89
- next unless error
90
- memo << Validation::Error.new(
91
- error, Context.next_field(context, i), self.class
92
- )
93
- end
94
- end
95
-
96
- def check_value_input_type(input)
97
- input.each_with_index do |value, i|
98
- error = error_for_value_input_type(value)
99
- next unless error
100
- next_context = Context.next_field(context, i)
101
- raise Openapi3Parser::Error::InvalidType,
102
- "Invalid type for #{next_context.location_summary}. "\
103
- "#{error}"
104
- end
105
- end
106
-
107
- def error_for_value_input_type(value)
108
- type = given_value_input_type
109
- return unless type
110
- "Expected #{type}" unless value.is_a?(type)
111
- end
112
- end
113
- end
114
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "openapi3_parser/node_factory/map"
4
- require "openapi3_parser/node_factories/path_item"
5
- require "openapi3_parser/node/callback"
6
-
7
- module Openapi3Parser
8
- module NodeFactories
9
- class Callback
10
- include NodeFactory::Map
11
-
12
- private
13
-
14
- def process_input(input)
15
- input.each_with_object({}) do |(key, value), memo|
16
- memo[key] = value if extension?(key)
17
- next_context = Context.next_field(context, key)
18
- memo[key] = NodeFactories::PathItem.new(next_context)
19
- end
20
- end
21
-
22
- def build_map(data, context)
23
- Node::Callback.new(data, context)
24
- end
25
- end
26
- end
27
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "openapi3_parser/context"
4
- require "openapi3_parser/error"
5
- require "openapi3_parser/node_factory/map"
6
- require "openapi3_parser/node/map"
7
- require "openapi3_parser/validation/error"
8
- require "openapi3_parser/validation/error_collection"
9
-
10
- module Openapi3Parser
11
- module NodeFactories
12
- class Map
13
- include NodeFactory::Map
14
-
15
- # rubocop:disable Metrics/ParameterLists
16
- def initialize(
17
- context,
18
- key_input_type: String,
19
- value_input_type: nil,
20
- value_factory: nil,
21
- validate: nil,
22
- default: {}
23
- )
24
- @given_key_input_type = key_input_type
25
- @given_value_input_type = value_input_type
26
- @given_value_factory = value_factory
27
- @given_validate = validate
28
- @given_default = default
29
- super(context)
30
- end
31
- # rubocop:enable Metrics/ParameterLists
32
-
33
- private
34
-
35
- attr_reader :given_key_input_type, :given_value_input_type,
36
- :given_value_factory, :given_validate, :given_default
37
-
38
- def process_input(input)
39
- input.each_with_object({}) do |(key, value), memo|
40
- memo[key] = if value_factory?
41
- next_context = Context.next_field(context, key)
42
- initialize_value_factory(next_context)
43
- else
44
- value
45
- end
46
- end
47
- end
48
-
49
- def validate_type
50
- error = super
51
- return error if error
52
- return unless given_key_input_type
53
- invalid_keys = context.input.keys.reject do |key|
54
- key.is_a?(given_key_input_type)
55
- end
56
- error = "Expected keys to be of type #{given_key_input_type}"
57
- return error if invalid_keys.any?
58
- end
59
-
60
- def validate(input, context)
61
- given_validate&.call(input, context)
62
- end
63
-
64
- def validate_input
65
- errors = validate_value_input_type(processed_input, context)
66
- Validation::ErrorCollection.combine(super, errors)
67
- end
68
-
69
- def build_node(input)
70
- check_value_input_type(input)
71
- super(input)
72
- end
73
-
74
- def build_map(data, context)
75
- Node::Map.new(data, context)
76
- end
77
-
78
- def value_factory?
79
- !given_value_factory.nil?
80
- end
81
-
82
- def initialize_value_factory(context)
83
- factory = given_value_factory
84
- return factory.new(context) if factory.is_a?(Class)
85
- factory.call(context)
86
- end
87
-
88
- def validate_value_input_type(input, context)
89
- input.each_with_object([]) do |(key, value), memo|
90
- error = error_for_value_input_type(value)
91
- next unless error
92
- memo << Validation::Error.new(
93
- error, Context.next_field(context, key), self.class
94
- )
95
- end
96
- end
97
-
98
- def check_value_input_type(input)
99
- input.each do |key, value|
100
- error = error_for_value_input_type(value)
101
- next unless error
102
- next_context = Context.next_field(context, key)
103
- raise Openapi3Parser::Error::InvalidType,
104
- "Invalid type for #{next_context.location_summary}. "\
105
- "#{error}"
106
- end
107
- end
108
-
109
- def error_for_value_input_type(value)
110
- type = given_value_input_type
111
- return unless type
112
- "Expected #{type}" unless value.is_a?(type)
113
- end
114
-
115
- def default
116
- given_default
117
- end
118
- end
119
- end
120
- end