committee 4.3.0 → 4.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c70ee2e436755ddf7b0b59b213ab7c00b60e67ce52520b956b889121b24e4c
4
- data.tar.gz: 06066adc6056231938d36d93a98c5d7318d9c1ff367784265d66c0eb271fb7b6
3
+ metadata.gz: 108842305271b038db8a6a49bd4ec9da83ea573a5061144484f4704a4af278df
4
+ data.tar.gz: 216360635fabf23f082f768594c4799ef4c71f3de4cf7ff7ffc4ac2b7fc5a72c
5
5
  SHA512:
6
- metadata.gz: bfbcc7aa85c676291125ed16b20badadda3eb8d895b6834cdc884602345c6ed3a052ecbdd381615b8bbca49815d884407cf8cc2f8cbbe05702593b5cc171f568
7
- data.tar.gz: cc454350c3d04969ad3f24c1922b887a6e319cea4f0a869b647ef439dbc9f5f83f3922bde82abdeb0994a540e53d5e68345e76d7291b408e42cd2f5a4df9eec1
6
+ metadata.gz: 417368733fb254f0211dd9ff6b273bf722db984325326816e3568ba7352da4079fb27c1405029d7191ae17e232d357041474f89ce6b7209c063911e8f4db26b3
7
+ data.tar.gz: '05682d9aaf2688ef511484bdaca307c1ff63dcefbdf1e4b6dcece592db7a548c5fa7ee0bb3498f4f1b903e20f9944a58790c335fc7c69251bdf0c65e33e3b19c'
data/lib/committee.rb CHANGED
@@ -20,6 +20,7 @@ module Committee
20
20
  end
21
21
  end
22
22
 
23
+ require_relative "committee/utils"
23
24
  require_relative "committee/drivers"
24
25
  require_relative "committee/errors"
25
26
  require_relative "committee/middleware"
@@ -156,7 +156,6 @@ module Committee
156
156
 
157
157
  methods.each do |method, link_data|
158
158
  method = method.upcase
159
-
160
159
  link = Link.new
161
160
  link.enc_type = schema.consumes
162
161
  link.href = href
@@ -7,9 +7,6 @@ module Committee
7
7
  super
8
8
 
9
9
  @strict = options[:strict]
10
-
11
- # deprecated
12
- @allow_extra = options[:allow_extra]
13
10
  end
14
11
 
15
12
  def handle(request)
@@ -7,6 +7,10 @@ module Committee
7
7
 
8
8
  def initialize(app, options = {})
9
9
  super
10
+
11
+ unless options[:strict].nil?
12
+ Committee.warn_deprecated("Committee: Committee::Middleware::ResponseValidation doesn't support strict option now but we'll support this option. This change break backward compatibility so please remove strict option from ResponseValidation")
13
+ end
10
14
  @validate_success_only = @schema.validator_option.validate_success_only
11
15
  end
12
16
 
@@ -2,84 +2,82 @@
2
2
 
3
3
  module Committee
4
4
  class RequestUnpacker
5
- def initialize(request, options={})
6
- @request = request
5
+ class << self
6
+ # Enable string or symbol key access to the nested params hash.
7
+ #
8
+ # (Copied from Sinatra)
9
+ def indifferent_params(object)
10
+ case object
11
+ when Hash
12
+ new_hash = Committee::Utils.indifferent_hash
13
+ object.each { |key, value| new_hash[key] = indifferent_params(value) }
14
+ new_hash
15
+ when Array
16
+ object.map { |item| indifferent_params(item) }
17
+ else
18
+ object
19
+ end
20
+ end
21
+ end
7
22
 
23
+ def initialize(options={})
8
24
  @allow_form_params = options[:allow_form_params]
9
25
  @allow_get_body = options[:allow_get_body]
10
26
  @allow_query_params = options[:allow_query_params]
11
- @coerce_form_params = options[:coerce_form_params]
12
27
  @optimistic_json = options[:optimistic_json]
13
- @schema_validator = options[:schema_validator]
14
28
  end
15
29
 
16
- def call
30
+ # reutrn params and is_form_params
31
+ def unpack_request_params(request)
17
32
  # if Content-Type is empty or JSON, and there was a request body, try to
18
33
  # interpret it as JSON
19
- params = if !@request.media_type || @request.media_type =~ %r{application/(?:.*\+)?json}
20
- parse_json
34
+ params = if !request.media_type || request.media_type =~ %r{application/(?:.*\+)?json}
35
+ parse_json(request)
21
36
  elsif @optimistic_json
22
37
  begin
23
- parse_json
38
+ parse_json(request)
24
39
  rescue JSON::ParserError
25
40
  nil
26
41
  end
27
42
  end
28
43
 
29
- params = if params
30
- params
31
- elsif @allow_form_params && %w[application/x-www-form-urlencoded multipart/form-data].include?(@request.media_type)
44
+ return [params, false] if params
45
+
46
+ if @allow_form_params && %w[application/x-www-form-urlencoded multipart/form-data].include?(request.media_type)
32
47
  # Actually, POST means anything in the request body, could be from
33
48
  # PUT or PATCH too. Silly Rack.
34
- p = @request.POST
35
-
36
- @schema_validator.coerce_form_params(p) if @coerce_form_params
37
-
38
- p
39
- else
40
- {}
49
+ return [request.POST, true] if request.POST
41
50
  end
42
51
 
43
- if @allow_query_params
44
- [indifferent_params(@request.GET).merge(params), headers]
45
- else
46
- [params, headers]
47
- end
52
+ [{}, false]
48
53
  end
49
54
 
50
- private
51
-
52
- # Creates a Hash with indifferent access.
53
- #
54
- # (Copied from Sinatra)
55
- def indifferent_hash
56
- Hash.new { |hash,key| hash[key.to_s] if Symbol === key }
55
+ def unpack_query_params(request)
56
+ @allow_query_params ? self.class.indifferent_params(request.GET) : {}
57
57
  end
58
58
 
59
- # Enable string or symbol key access to the nested params hash.
60
- #
61
- # (Copied from Sinatra)
62
- def indifferent_params(object)
63
- case object
64
- when Hash
65
- new_hash = indifferent_hash
66
- object.each { |key, value| new_hash[key] = indifferent_params(value) }
67
- new_hash
68
- when Array
69
- object.map { |item| indifferent_params(item) }
70
- else
71
- object
59
+ def unpack_headers(request)
60
+ env = request.env
61
+ base = env.keys.grep(/HTTP_/).inject({}) do |headers, key|
62
+ headerized_key = key.gsub(/^HTTP_/, '').gsub(/_/, '-')
63
+ headers[headerized_key] = env[key]
64
+ headers
72
65
  end
66
+
67
+ base['Content-Type'] = env['CONTENT_TYPE'] if env['CONTENT_TYPE']
68
+ base
73
69
  end
74
70
 
75
- def parse_json
76
- return nil if @request.request_method == "GET" && !@allow_get_body
71
+ private
72
+
73
+ def parse_json(request)
74
+ return nil if request.request_method == "GET" && !@allow_get_body
77
75
 
78
- body = @request.body.read
76
+ body = request.body.read
79
77
  # if request body is empty, we just have empty params
80
78
  return nil if body.length == 0
81
79
 
82
- @request.body.rewind
80
+ request.body.rewind
83
81
  hash = JSON.parse(body)
84
82
  # We want a hash specifically. '42', 42, and [42] will all be
85
83
  # decoded properly, but we can't use them here.
@@ -87,19 +85,7 @@ module Committee
87
85
  raise BadRequest,
88
86
  "Invalid JSON input. Require object with parameters as keys."
89
87
  end
90
- indifferent_params(hash)
91
- end
92
-
93
- def headers
94
- env = @request.env
95
- base = env.keys.grep(/HTTP_/).inject({}) do |headers, key|
96
- headerized_key = key.gsub(/^HTTP_/, '').gsub(/_/, '-')
97
- headers[headerized_key] = env[key]
98
- headers
99
- end
100
-
101
- base['Content-Type'] = env['CONTENT_TYPE'] if env['CONTENT_TYPE']
102
- base
88
+ self.class.indifferent_params(hash)
103
89
  end
104
90
  end
105
91
  end
@@ -11,18 +11,8 @@ module Committee
11
11
  end
12
12
 
13
13
  def request_validate(request)
14
- # Attempts to coerce parameters that appear in a link's URL to Ruby
15
- # types that can be validated with a schema.
16
- param_matches_hash = validator_option.coerce_path_params ? coerce_path_params : {}
17
-
18
- # Attempts to coerce parameters that appear in a query string to Ruby
19
- # types that can be validated with a schema.
20
- coerce_query_params(request) if validator_option.coerce_query_params
21
-
22
14
  request_unpack(request)
23
15
 
24
- request.env[validator_option.params_key].merge!(param_matches_hash) if param_matches_hash
25
-
26
16
  request_schema_validation(request)
27
17
  parameter_coerce!(request, link, validator_option.params_key)
28
18
  parameter_coerce!(request, link, "rack.request.query_hash") if link_exist? && !request.GET.nil? && !link.schema.nil?
@@ -50,16 +40,10 @@ module Committee
50
40
  !link.nil?
51
41
  end
52
42
 
53
- def coerce_form_params(parameter)
54
- return unless link_exist?
55
- return unless link.schema
56
- Committee::SchemaValidator::HyperSchema::StringParamsCoercer.new(parameter, link.schema).call!
57
- end
58
-
59
43
  private
60
44
 
61
45
  def coerce_path_params
62
- return unless link_exist?
46
+ return {} unless link_exist?
63
47
 
64
48
  Committee::SchemaValidator::HyperSchema::StringParamsCoercer.new(param_matches, link.schema, coerce_recursive: validator_option.coerce_recursive).call!
65
49
  param_matches
@@ -73,15 +57,38 @@ module Committee
73
57
  end
74
58
 
75
59
  def request_unpack(request)
76
- request.env[validator_option.params_key], request.env[validator_option.headers_key] = Committee::RequestUnpacker.new(
77
- request,
78
- allow_form_params: validator_option.allow_form_params,
79
- allow_get_body: validator_option.allow_get_body,
80
- allow_query_params: validator_option.allow_query_params,
81
- coerce_form_params: validator_option.coerce_form_params,
82
- optimistic_json: validator_option.optimistic_json,
83
- schema_validator: self
84
- ).call
60
+ unpacker = Committee::RequestUnpacker.new(
61
+ allow_form_params: validator_option.allow_form_params,
62
+ allow_get_body: validator_option.allow_get_body,
63
+ allow_query_params: validator_option.allow_query_params,
64
+ optimistic_json: validator_option.optimistic_json,
65
+ )
66
+
67
+ request.env[validator_option.headers_key] = unpacker.unpack_headers(request)
68
+
69
+ # Attempts to coerce parameters that appear in a link's URL to Ruby
70
+ # types that can be validated with a schema.
71
+ param_matches_hash = validator_option.coerce_path_params ? coerce_path_params : {}
72
+
73
+ # Attempts to coerce parameters that appear in a query string to Ruby
74
+ # types that can be validated with a schema.
75
+ coerce_query_params(request) if validator_option.coerce_query_params
76
+
77
+ query_param = unpacker.unpack_query_params(request)
78
+ request_param, is_form_params = unpacker.unpack_request_params(request)
79
+ coerce_form_params(request_param) if validator_option.coerce_form_params && is_form_params
80
+ request.env[validator_option.request_body_hash_key] = request_param
81
+
82
+ request.env[validator_option.params_key] = Committee::Utils.indifferent_hash
83
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(query_param))
84
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request_param))
85
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(param_matches_hash))
86
+ end
87
+
88
+ def coerce_form_params(parameter)
89
+ return unless link_exist?
90
+ return unless link.schema
91
+ Committee::SchemaValidator::HyperSchema::StringParamsCoercer.new(parameter, link.schema).call!
85
92
  end
86
93
 
87
94
  def request_schema_validation(request)
@@ -14,12 +14,7 @@ module Committee
14
14
  def request_validate(request)
15
15
  return unless link_exist?
16
16
 
17
- path_params = validator_option.coerce_path_params ? coerce_path_params : {}
18
-
19
17
  request_unpack(request)
20
-
21
- request.env[validator_option.params_key]&.merge!(path_params) unless path_params.empty?
22
-
23
18
  request_schema_validation(request)
24
19
 
25
20
  copy_coerced_data_to_query_hash(request)
@@ -49,16 +44,13 @@ module Committee
49
44
  !@operation_object.nil?
50
45
  end
51
46
 
52
- def coerce_form_params(_parameter)
53
- # Empty because request_schema_validation checks and coerces
54
- end
55
-
56
47
  private
57
48
 
58
49
  attr_reader :validator_option
59
50
 
60
51
  def coerce_path_params
61
- @operation_object.coerce_path_parameter(@validator_option)
52
+ return Committee::Utils.indifferent_hash unless validator_option.coerce_path_params
53
+ Committee::RequestUnpacker.indifferent_params(@operation_object.coerce_path_parameter(@validator_option))
62
54
  end
63
55
 
64
56
  def request_schema_validation(request)
@@ -73,22 +65,36 @@ module Committee
73
65
  end
74
66
 
75
67
  def request_unpack(request)
76
- request.env[validator_option.params_key], request.env[validator_option.headers_key] = Committee::RequestUnpacker.new(
77
- request,
78
- allow_form_params: validator_option.allow_form_params,
79
- allow_get_body: validator_option.allow_get_body,
80
- allow_query_params: validator_option.allow_query_params,
81
- coerce_form_params: validator_option.coerce_form_params,
82
- optimistic_json: validator_option.optimistic_json,
83
- schema_validator: self
84
- ).call
68
+ unpacker = Committee::RequestUnpacker.new(
69
+ allow_form_params: validator_option.allow_form_params,
70
+ allow_get_body: validator_option.allow_get_body,
71
+ allow_query_params: validator_option.allow_query_params,
72
+ optimistic_json: validator_option.optimistic_json,
73
+ )
74
+
75
+ request.env[validator_option.headers_key] = unpacker.unpack_headers(request)
76
+
77
+ request_param, is_form_params = unpacker.unpack_request_params(request)
78
+ request.env[validator_option.request_body_hash_key] = request_param
79
+ request.env[validator_option.path_hash_key] = coerce_path_params
80
+
81
+ query_param = unpacker.unpack_query_params(request)
82
+
83
+ request.env[validator_option.params_key] = Committee::Utils.indifferent_hash
84
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(query_param))
85
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request.env[validator_option.request_body_hash_key]))
86
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request.env[validator_option.path_hash_key]))
85
87
  end
86
88
 
87
89
  def copy_coerced_data_to_query_hash(request)
88
90
  return if request.env["rack.request.query_hash"].nil? || request.env["rack.request.query_hash"].empty?
89
91
 
92
+ query_hash_key = @validator_option.query_hash_key
93
+ return unless query_hash_key
94
+
95
+ request.env[query_hash_key] = {} unless request.env[query_hash_key]
90
96
  request.env["rack.request.query_hash"].keys.each do |k|
91
- request.env["rack.request.query_hash"][k] = request.env[validator_option.params_key][k]
97
+ request.env[query_hash_key][k] = request.env[validator_option.params_key][k]
92
98
  end
93
99
  end
94
100
  end
@@ -21,12 +21,24 @@ module Committee
21
21
  # Non-boolean options:
22
22
  attr_reader :headers_key,
23
23
  :params_key,
24
+ :query_hash_key,
25
+ :request_body_hash_key,
26
+ :path_hash_key,
24
27
  :prefix
25
28
 
26
29
  def initialize(options, schema, schema_type)
27
30
  # Non-boolean options
28
- @headers_key = options[:headers_key] || "committee.headers"
29
- @params_key = options[:params_key] || "committee.params"
31
+ @headers_key = options[:headers_key] || "committee.headers"
32
+ @params_key = options[:params_key] || "committee.params"
33
+ @query_hash_key = if options[:query_hash_key].nil?
34
+ Committee.warn_deprecated('Committee: please set query_hash_key = rack.request.query_hash because we\'ll change default value in next major version.')
35
+ 'rack.request.query_hash'
36
+ else
37
+ options.fetch(:query_hash_key)
38
+ end
39
+ @path_hash_key = options[:path_hash_key] || "committee.path_hash"
40
+ @request_body_hash_key = options[:request_body_hash_key] || "committee.request_body_hash"
41
+
30
42
  @prefix = options[:prefix]
31
43
 
32
44
  # Boolean options and have a common value by default
@@ -3,9 +3,9 @@
3
3
  module Committee
4
4
  module Test
5
5
  module Methods
6
- def assert_schema_conform
6
+ def assert_schema_conform(expected_status = nil)
7
7
  assert_request_schema_confirm unless old_behavior
8
- assert_response_schema_confirm
8
+ assert_response_schema_confirm(expected_status)
9
9
  end
10
10
 
11
11
  def assert_request_schema_confirm
@@ -17,7 +17,7 @@ module Committee
17
17
  schema_validator.request_validate(request_object)
18
18
  end
19
19
 
20
- def assert_response_schema_confirm
20
+ def assert_response_schema_confirm(expected_status = nil)
21
21
  unless schema_validator.link_exist?
22
22
  response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema (prefix: #{committee_options[:prefix].inspect})."
23
23
  raise Committee::InvalidResponse.new(response)
@@ -25,6 +25,13 @@ module Committee
25
25
 
26
26
  status, headers, body = response_data
27
27
 
28
+ if expected_status.nil?
29
+ Committee.warn_deprecated('Pass expected response status code to check it against the corresponding schema explicitly.')
30
+ elsif expected_status != status
31
+ response = "Expected `#{expected_status}` status code, but it was `#{status}`."
32
+ raise Committee::InvalidResponse.new(response)
33
+ end
34
+
28
35
  if schema_coverage
29
36
  operation_object = router.operation_object(request_object)
30
37
  schema_coverage&.update_response_coverage!(operation_object.original_path, operation_object.http_method, status)
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Committee
4
+ module Utils
5
+ # Creates a Hash with indifferent access.
6
+ #
7
+ # (Copied from Sinatra)
8
+ def self.indifferent_hash
9
+ Hash.new { |hash,key| hash[key.to_s] if Symbol === key }
10
+ end
11
+
12
+ def self.deep_copy(from)
13
+ if from.is_a?(Hash)
14
+ h = Committee::Utils.indifferent_hash
15
+ from.each_pair do |k, v|
16
+ h[k] = deep_copy(v)
17
+ end
18
+ return h
19
+ end
20
+
21
+ if from.is_a?(Array)
22
+ return from.map{ |v| deep_copy(v) }
23
+ end
24
+
25
+ return from
26
+ end
27
+ end
28
+ end
@@ -34,11 +34,27 @@ describe Committee::Middleware::RequestValidation do
34
34
  params = { "datetime_string" => "2016-04-01T16:00:00.000+09:00" }
35
35
 
36
36
  check_parameter = lambda { |env|
37
+ assert_equal DateTime, env['committee.query_hash']["datetime_string"].class
38
+ assert_equal String, env['rack.request.query_hash']["datetime_string"].class
39
+ [200, {}, []]
40
+ }
41
+
42
+ @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true, query_hash_key: "committee.query_hash")
43
+
44
+ get "/string_params_coercer", params
45
+ assert_equal 200, last_response.status
46
+ end
47
+
48
+ it "passes given a datetime and with coerce_date_times enabled on GET endpoint overwrite query_hash" do
49
+ params = { "datetime_string" => "2016-04-01T16:00:00.000+09:00" }
50
+
51
+ check_parameter = lambda { |env|
52
+ assert_equal nil, env['committee.query_hash']
37
53
  assert_equal DateTime, env['rack.request.query_hash']["datetime_string"].class
38
54
  [200, {}, []]
39
55
  }
40
56
 
41
- @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true)
57
+ @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true, query_hash_key: "rack.request.query_hash")
42
58
 
43
59
  get "/string_params_coercer", params
44
60
  assert_equal 200, last_response.status
@@ -154,7 +170,8 @@ describe Committee::Middleware::RequestValidation do
154
170
  }
155
171
 
156
172
  check_parameter = lambda { |env|
157
- hash = env['rack.request.query_hash']
173
+ # hash = env["committee.query_hash"] # 5.0.x-
174
+ hash = env["rack.request.query_hash"]
158
175
  assert_equal DateTime, hash['nested_array'].first['update_time'].class
159
176
  assert_equal 1, hash['nested_array'].first['per_page']
160
177
 
@@ -331,7 +348,7 @@ describe Committee::Middleware::RequestValidation do
331
348
  get "/coerce_path_params/#{not_an_integer}", nil
332
349
  end
333
350
 
334
- assert_match(/expected integer, but received String: abc/i, e.message)
351
+ assert_match(/expected integer, but received String: \"abc\"/i, e.message)
335
352
  end
336
353
 
337
354
  it "optionally raises an error" do
@@ -360,7 +377,8 @@ describe Committee::Middleware::RequestValidation do
360
377
 
361
378
  it "passes through a valid request for OpenAPI3" do
362
379
  check_parameter = lambda { |env|
363
- assert_equal 3, env['rack.request.query_hash']['limit']
380
+ # assert_equal 3, env['committee.query_hash']['limit'] #5.0.x-
381
+ assert_equal 3, env['rack.request.query_hash']['limit'] #5.0.x-
364
382
  [200, {}, []]
365
383
  }
366
384
 
@@ -374,7 +392,7 @@ describe Committee::Middleware::RequestValidation do
374
392
  get "/characters?limit=foo"
375
393
 
376
394
  assert_equal 400, last_response.status
377
- assert_match(/expected integer, but received String: foo/i, last_response.body)
395
+ assert_match(/expected integer, but received String: \\"foo\\"/i, last_response.body)
378
396
  end
379
397
 
380
398
  it "ignores errors when ignore_error: true" do
@@ -394,6 +412,51 @@ describe Committee::Middleware::RequestValidation do
394
412
  get "/coerce_path_params/1"
395
413
  end
396
414
 
415
+ it "corce string and save path hash" do
416
+ @app = new_rack_app_with_lambda(lambda do |env|
417
+ assert_equal env['committee.params']['integer'], 21
418
+ assert_equal env['committee.params'][:integer], 21
419
+ assert_equal env['committee.path_hash']['integer'], 21
420
+ assert_equal env['committee.path_hash'][:integer], 21
421
+ [204, {}, []]
422
+ end, schema: open_api_3_schema)
423
+
424
+ header "Content-Type", "application/json"
425
+ post '/parameter_option_test/21'
426
+ assert_equal 204, last_response.status
427
+ end
428
+
429
+ it "corce string and save request body hash" do
430
+ @app = new_rack_app_with_lambda(lambda do |env|
431
+ assert_equal env['committee.params']['integer'], 21 # use path parameter
432
+ assert_equal env['committee.params'][:integer], 21
433
+ assert_equal env['committee.request_body_hash']['integer'], 42
434
+ assert_equal env['committee.request_body_hash'][:integer], 42
435
+ [204, {}, []]
436
+ end, schema: open_api_3_schema)
437
+
438
+ params = {integer: 42}
439
+
440
+ header "Content-Type", "application/json"
441
+ post '/parameter_option_test/21', JSON.generate(params)
442
+ assert_equal 204, last_response.status
443
+ end
444
+
445
+ it "unpacker test" do
446
+ @app = new_rack_app_with_lambda(lambda do |env|
447
+ assert_equal env['committee.params']['integer'], 42
448
+ assert_equal env['committee.params'][:integer], 42
449
+ # overwrite by request body...
450
+ assert_equal env['rack.request.query_hash']['integer'], 42
451
+ # assert_equal env['rack.request.query_hash'][:integer], 42
452
+ [204, {}, []]
453
+ end, schema: open_api_3_schema, raise: true)
454
+
455
+ header "Content-Type", "application/x-www-form-urlencoded"
456
+ post '/validate?integer=21', "integer=42"
457
+ assert_equal 204, last_response.status
458
+ end
459
+
397
460
  it "OpenAPI3 raise not support method" do
398
461
  @app = new_rack_app(schema: open_api_3_schema)
399
462
 
@@ -408,7 +471,7 @@ describe Committee::Middleware::RequestValidation do
408
471
  [
409
472
  { check_header: true, description: 'valid value', value: 1, expected: { status: 200 } },
410
473
  { check_header: true, description: 'missing value', value: nil, expected: { status: 400, error: 'missing required parameters: integer' } },
411
- { check_header: true, description: 'invalid value', value: 'x', expected: { status: 400, error: 'expected integer, but received String: x' } },
474
+ { check_header: true, description: 'invalid value', value: 'x', expected: { status: 400, error: 'expected integer, but received String: \\"x\\"' } },
412
475
 
413
476
  { check_header: false, description: 'valid value', value: 1, expected: { status: 200 } },
414
477
  { check_header: false, description: 'missing value', value: nil, expected: { status: 200 } },
@@ -435,6 +435,19 @@ describe Committee::Middleware::RequestValidation do
435
435
  assert_equal 200, last_response.status
436
436
  end
437
437
 
438
+ it "corce form params" do
439
+ check_parameter = lambda { |env|
440
+ assert_equal 3, env['committee.params']['age']
441
+ assert_equal 3, env['committee.request_body_hash']['age']
442
+ [200, {}, []]
443
+ }
444
+
445
+ @app = new_rack_app_with_lambda(check_parameter, schema: open_api_2_form_schema, raise: true, allow_form_params: true, coerce_form_params: true)
446
+ header "Content-Type", "application/x-www-form-urlencoded"
447
+ post "/api/pets", "age=3&name=ab"
448
+ assert_equal 200, last_response.status
449
+ end
450
+
438
451
  it "detects an invalid request for OpenAPI" do
439
452
  @app = new_rack_app(schema: open_api_2_schema)
440
453
  get "/api/pets?limit=foo", nil, { "HTTP_AUTH_TOKEN" => "xxx" }
@@ -125,7 +125,7 @@ describe Committee::Middleware::ResponseValidation do
125
125
  [
126
126
  { check_header: true, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
127
127
  { check_header: true, description: 'missing value', header: { 'integer' => nil }, expected: { error: 'headers/integer/schema does not allow null values' } },
128
- { check_header: true, description: 'invalid value', header: { 'integer' => 'x' }, expected: { error: 'headers/integer/schema expected integer, but received String: x' } },
128
+ { check_header: true, description: 'invalid value', header: { 'integer' => 'x' }, expected: { error: 'headers/integer/schema expected integer, but received String: "x"' } },
129
129
 
130
130
  { check_header: false, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
131
131
  { check_header: false, description: 'missing value', header: { 'integer' => nil }, expected: { status: 200 } },
@@ -177,7 +177,7 @@ describe Committee::Middleware::ResponseValidation do
177
177
  get "/characters"
178
178
  end
179
179
 
180
- assert_match(/but received String: 1/i, e.message)
180
+ assert_match(/but received String: \"1\"/i, e.message)
181
181
  end
182
182
 
183
183
  it "detects an invalid response status code with validate_success_only=true" do
@@ -15,6 +15,14 @@ describe Committee::Middleware::ResponseValidation do
15
15
  assert_equal 200, last_response.status
16
16
  end
17
17
 
18
+ # TODO: remove 5.0.0
19
+ it "passes through a valid response" do
20
+ # will show deprecated message
21
+ @app = new_rack_app(JSON.generate([ValidApp]), {}, schema: hyper_schema, strict: true)
22
+ get "/apps"
23
+ assert_equal 200, last_response.status
24
+ end
25
+
18
26
  it "doesn't call error_handler (has a arg) when response is valid" do
19
27
  called = false
20
28
  pr = ->(_e) { called = true }
@@ -9,8 +9,8 @@ describe Committee::RequestUnpacker do
9
9
  "rack.input" => StringIO.new('{"x":"y"}'),
10
10
  }
11
11
  request = Rack::Request.new(env)
12
- params, _ = Committee::RequestUnpacker.new(request).call
13
- assert_equal({ "x" => "y" }, params)
12
+ unpacker = Committee::RequestUnpacker.new
13
+ assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request))
14
14
  end
15
15
 
16
16
  it "unpacks JSON on Content-Type: application/vnd.api+json" do
@@ -19,8 +19,8 @@ describe Committee::RequestUnpacker do
19
19
  "rack.input" => StringIO.new('{"x":"y"}'),
20
20
  }
21
21
  request = Rack::Request.new(env)
22
- params, _ = Committee::RequestUnpacker.new(request).call
23
- assert_equal({ "x" => "y" }, params)
22
+ unpacker = Committee::RequestUnpacker.new
23
+ assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request))
24
24
  end
25
25
 
26
26
  it "unpacks JSON on no Content-Type" do
@@ -28,8 +28,8 @@ describe Committee::RequestUnpacker do
28
28
  "rack.input" => StringIO.new('{"x":"y"}'),
29
29
  }
30
30
  request = Rack::Request.new(env)
31
- params, _ = Committee::RequestUnpacker.new(request).call
32
- assert_equal({ "x" => "y" }, params)
31
+ unpacker = Committee::RequestUnpacker.new
32
+ assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request))
33
33
  end
34
34
 
35
35
  it "doesn't unpack JSON on application/x-ndjson" do
@@ -38,8 +38,8 @@ describe Committee::RequestUnpacker do
38
38
  "rack.input" => StringIO.new('{"x":"y"}\n{"a":"b"}'),
39
39
  }
40
40
  request = Rack::Request.new(env)
41
- params, _ = Committee::RequestUnpacker.new(request).call
42
- assert_equal({}, params)
41
+ unpacker = Committee::RequestUnpacker.new
42
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
43
43
  end
44
44
 
45
45
  it "doesn't unpack JSON under other Content-Types" do
@@ -49,8 +49,8 @@ describe Committee::RequestUnpacker do
49
49
  "rack.input" => StringIO.new('{"x":"y"}'),
50
50
  }
51
51
  request = Rack::Request.new(env)
52
- params, _ = Committee::RequestUnpacker.new(request).call
53
- assert_equal({}, params)
52
+ unpacker = Committee::RequestUnpacker.new
53
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
54
54
  end
55
55
  end
56
56
 
@@ -61,8 +61,8 @@ describe Committee::RequestUnpacker do
61
61
  "rack.input" => StringIO.new('{"x":"y"}'),
62
62
  }
63
63
  request = Rack::Request.new(env)
64
- params, _ = Committee::RequestUnpacker.new(request, optimistic_json: true).call
65
- assert_equal({ "x" => "y" }, params)
64
+ unpacker = Committee::RequestUnpacker.new(optimistic_json: true)
65
+ assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request))
66
66
  end
67
67
  end
68
68
 
@@ -73,8 +73,8 @@ describe Committee::RequestUnpacker do
73
73
  "rack.input" => StringIO.new('x=y&foo=42'),
74
74
  }
75
75
  request = Rack::Request.new(env)
76
- params, _ = Committee::RequestUnpacker.new(request, optimistic_json: true).call
77
- assert_equal({}, params)
76
+ unpacker = Committee::RequestUnpacker.new(optimistic_json: true)
77
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
78
78
  end
79
79
  end
80
80
 
@@ -84,8 +84,8 @@ describe Committee::RequestUnpacker do
84
84
  "rack.input" => StringIO.new(""),
85
85
  }
86
86
  request = Rack::Request.new(env)
87
- params, _ = Committee::RequestUnpacker.new(request).call
88
- assert_equal({}, params)
87
+ unpacker = Committee::RequestUnpacker.new
88
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
89
89
  end
90
90
 
91
91
  it "doesn't unpack form params" do
@@ -95,8 +95,8 @@ describe Committee::RequestUnpacker do
95
95
  "rack.input" => StringIO.new("x=y"),
96
96
  }
97
97
  request = Rack::Request.new(env)
98
- params, _ = Committee::RequestUnpacker.new(request).call
99
- assert_equal({}, params)
98
+ unpacker = Committee::RequestUnpacker.new
99
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
100
100
  end
101
101
  end
102
102
 
@@ -107,96 +107,8 @@ describe Committee::RequestUnpacker do
107
107
  "rack.input" => StringIO.new("x=y"),
108
108
  }
109
109
  request = Rack::Request.new(env)
110
- params, _ = Committee::RequestUnpacker.new(request, allow_form_params: true).call
111
- assert_equal({ "x" => "y" }, params)
112
- end
113
- end
114
-
115
- it "coerces form params with coerce_form_params and a schema" do
116
- %w[application/x-www-form-urlencoded multipart/form-data].each do |content_type|
117
- env = {
118
- "CONTENT_TYPE" => content_type,
119
- "rack.input" => StringIO.new("x=1"),
120
- }
121
- request = Rack::Request.new(env)
122
-
123
- options = {}
124
- # TODO: delete when 5.0.0 released because default value changed
125
- options[:parse_response_by_content_type] = false
126
- router = hyper_schema.build_router(options)
127
- validator = router.build_schema_validator(request)
128
-
129
- schema = JsonSchema::Schema.new
130
- schema.properties = { "x" => JsonSchema::Schema.new }
131
- schema.properties["x"].type = ["integer"]
132
-
133
- link_class = Struct.new(:schema)
134
- link_object = link_class.new(schema)
135
-
136
- validator.instance_variable_set(:@link, link_object)
137
-
138
- params, _ = Committee::RequestUnpacker.new(
139
- request,
140
- allow_form_params: true,
141
- coerce_form_params: true,
142
- schema_validator: validator,
143
- ).call
144
- assert_equal({ "x" => 1 }, params)
145
- end
146
- end
147
-
148
- it "coerces form params with coerce_form_params and an OpenAPI3 schema" do
149
- %w[application/x-www-form-urlencoded multipart/form-data].each do |content_type|
150
- env = {
151
- "CONTENT_TYPE" => content_type,
152
- "rack.input" => StringIO.new("limit=20"),
153
- "PATH_INFO" => "/characters",
154
- "SCRIPT_NAME" => "",
155
- "REQUEST_METHOD" => "GET",
156
- }
157
- request = Rack::Request.new(env)
158
-
159
- options = {}
160
- # TODO: delete when 5.0.0 released because default value changed
161
- options[:parse_response_by_content_type] = false
162
- router = open_api_3_schema.build_router(options)
163
- validator = router.build_schema_validator(request)
164
-
165
- params, _ = Committee::RequestUnpacker.new(
166
- request,
167
- allow_form_params: true,
168
- coerce_form_params: true,
169
- schema_validator: validator,
170
- ).call
171
- # openapi3 not support coerce in request unpacker
172
- assert_equal({ "limit" => '20' }, params)
173
- end
174
- end
175
-
176
- it "coerces error params with coerce_form_params and a OpenAPI3 schema" do
177
- %w[application/x-www-form-urlencoded multipart/form-data].each do |content_type|
178
- env = {
179
- "CONTENT_TYPE" => content_type,
180
- "rack.input" => StringIO.new("limit=twenty"),
181
- "PATH_INFO" => "/characters",
182
- "SCRIPT_NAME" => "",
183
- "REQUEST_METHOD" => "GET",
184
- }
185
- request = Rack::Request.new(env)
186
-
187
- options = {}
188
- # TODO: delete when 5.0.0 released because default value changed
189
- options[:parse_response_by_content_type] = false
190
- router = open_api_3_schema.build_router(options)
191
- validator = router.build_schema_validator(request)
192
-
193
- params, _ = Committee::RequestUnpacker.new(
194
- request,
195
- allow_form_params: true,
196
- coerce_form_params: true,
197
- schema_validator: validator,
198
- ).call
199
- assert_equal({ "limit" => "twenty" }, params)
110
+ unpacker = Committee::RequestUnpacker.new(allow_form_params: true)
111
+ assert_equal([{ "x" => "y" }, true], unpacker.unpack_request_params(request))
200
112
  end
201
113
  end
202
114
 
@@ -208,8 +120,8 @@ describe Committee::RequestUnpacker do
208
120
  "QUERY_STRING" => "a=b"
209
121
  }
210
122
  request = Rack::Request.new(env)
211
- params, _ = Committee::RequestUnpacker.new(request, allow_form_params: true, allow_query_params: true).call
212
- assert_equal({ "x" => "y", "a" => "b" }, params)
123
+ unpacker = Committee::RequestUnpacker.new(allow_form_params: true, allow_query_params: true)
124
+ assert_equal([ { "x" => "y"}, true], unpacker.unpack_request_params(request))
213
125
  end
214
126
  end
215
127
 
@@ -219,8 +131,8 @@ describe Committee::RequestUnpacker do
219
131
  "QUERY_STRING" => "a=b"
220
132
  }
221
133
  request = Rack::Request.new(env)
222
- params, _ = Committee::RequestUnpacker.new(request, allow_query_params: true).call
223
- assert_equal({ "a" => "b" }, params)
134
+ unpacker = Committee::RequestUnpacker.new(allow_query_params: true)
135
+ assert_equal({ "a" => "b" }, unpacker.unpack_query_params(request))
224
136
  end
225
137
 
226
138
  it "errors if JSON is not an object" do
@@ -230,7 +142,7 @@ describe Committee::RequestUnpacker do
230
142
  }
231
143
  request = Rack::Request.new(env)
232
144
  assert_raises(Committee::BadRequest) do
233
- Committee::RequestUnpacker.new(request).call
145
+ Committee::RequestUnpacker.new.unpack_request_params(request)
234
146
  end
235
147
  end
236
148
 
@@ -240,8 +152,8 @@ describe Committee::RequestUnpacker do
240
152
  "rack.input" => StringIO.new('{"x":"y"}'),
241
153
  }
242
154
  request = Rack::Request.new(env)
243
- params, _ = Committee::RequestUnpacker.new(request).call
244
- assert_equal({}, params)
155
+ unpacker = Committee::RequestUnpacker.new
156
+ assert_equal([{}, false], unpacker.unpack_request_params(request))
245
157
  end
246
158
 
247
159
  # this is mostly here for line coverage
@@ -250,8 +162,8 @@ describe Committee::RequestUnpacker do
250
162
  "rack.input" => StringIO.new('{"x":[]}'),
251
163
  }
252
164
  request = Rack::Request.new(env)
253
- params, _ = Committee::RequestUnpacker.new(request).call
254
- assert_equal({ "x" => [] }, params)
165
+ unpacker = Committee::RequestUnpacker.new
166
+ assert_equal([{ "x" => [] }, false], unpacker.unpack_request_params(request))
255
167
  end
256
168
 
257
169
  it "unpacks http header" do
@@ -260,8 +172,8 @@ describe Committee::RequestUnpacker do
260
172
  "rack.input" => StringIO.new(""),
261
173
  }
262
174
  request = Rack::Request.new(env)
263
- _, headers = Committee::RequestUnpacker.new(request, { allow_header_params: true }).call
264
- assert_equal({ "FOO-BAR" => "some header value" }, headers)
175
+ unpacker = Committee::RequestUnpacker.new({ allow_header_params: true })
176
+ assert_equal({ "FOO-BAR" => "some header value" }, unpacker.unpack_headers(request))
265
177
  end
266
178
 
267
179
  it "includes request body when`use_get_body` is true" do
@@ -271,8 +183,8 @@ describe Committee::RequestUnpacker do
271
183
  "QUERY_STRING"=>"data=value&x=aaa",
272
184
  }
273
185
  request = Rack::Request.new(env)
274
- params, _ = Committee::RequestUnpacker.new(request, { allow_query_params: true, allow_get_body: true }).call
275
- assert_equal({ 'data' => 'value', 'x' => 1, 'y' => 2 }, params)
186
+ unpacker = Committee::RequestUnpacker.new({ allow_query_params: true, allow_get_body: true })
187
+ assert_equal([{ 'x' => 1, 'y' => 2 }, false], unpacker.unpack_request_params(request))
276
188
  end
277
189
 
278
190
  it "doesn't include request body when `use_get_body` is false" do
@@ -282,7 +194,7 @@ describe Committee::RequestUnpacker do
282
194
  "QUERY_STRING"=>"data=value&x=aaa",
283
195
  }
284
196
  request = Rack::Request.new(env)
285
- params, _ = Committee::RequestUnpacker.new(request, { allow_query_params: true, use_get_body: false }).call
286
- assert_equal({ 'data' => 'value', 'x' => 'aaa' }, params)
197
+ unpacker = Committee::RequestUnpacker.new({ allow_query_params: true, use_get_body: false })
198
+ assert_equal({ 'data' => 'value', 'x' => 'aaa' }, unpacker.unpack_query_params(request))
287
199
  end
288
200
  end
@@ -81,7 +81,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
81
81
  operation_object.validate_request_params({"integer" => "str"}, HEADER, @validator_option)
82
82
  }
83
83
 
84
- assert_match(/expected integer, but received String: str/i, e.message)
84
+ assert_match(/expected integer, but received String: "str"/i, e.message)
85
85
  assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
86
86
  end
87
87
 
@@ -150,7 +150,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
150
150
  operation_object.validate_request_params({"limit" => "a"}, HEADER, @validator_option)
151
151
  }
152
152
 
153
- assert_match(/expected integer, but received String: a/i, e.message)
153
+ assert_match(/expected integer, but received String: "a"/i, e.message)
154
154
  assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
155
155
  end
156
156
  end
@@ -39,7 +39,7 @@ describe Committee::Test::Methods do
39
39
  it "passes through a valid response" do
40
40
  @app = new_rack_app(JSON.generate([ValidApp]))
41
41
  get "/apps"
42
- assert_schema_conform
42
+ assert_schema_conform(200)
43
43
  end
44
44
 
45
45
  it "passes with prefix" do
@@ -47,18 +47,27 @@ describe Committee::Test::Methods do
47
47
 
48
48
  @app = new_rack_app(JSON.generate([ValidApp]))
49
49
  get "/v1/apps"
50
- assert_schema_conform
50
+ assert_schema_conform(200)
51
51
  end
52
52
 
53
53
  it "detects an invalid response Content-Type" do
54
54
  @app = new_rack_app(JSON.generate([ValidApp]), 200, {})
55
55
  get "/apps"
56
56
  e = assert_raises(Committee::InvalidResponse) do
57
- assert_schema_conform
57
+ assert_schema_conform(200)
58
58
  end
59
59
  assert_match(/response header must be set to/i, e.message)
60
60
  end
61
61
 
62
+ it "it detects unexpected response code" do
63
+ @app = new_rack_app(JSON.generate([ValidApp]), 400)
64
+ get "/apps"
65
+ e = assert_raises(Committee::InvalidResponse) do
66
+ assert_schema_conform(200)
67
+ end
68
+ assert_match(/Expected `200` status code, but it was `400`/i, e.message)
69
+ end
70
+
62
71
  it "detects an invalid response Content-Type but ignore because it's not success status code" do
63
72
  @committee_options.merge!(validate_success_only: true)
64
73
  @app = new_rack_app(JSON.generate([ValidApp]), 400, {})
@@ -70,7 +79,7 @@ describe Committee::Test::Methods do
70
79
  @app = new_rack_app(JSON.generate([ValidApp]), 400, {})
71
80
  get "/apps"
72
81
  e = assert_raises(Committee::InvalidResponse) do
73
- assert_schema_conform
82
+ assert_schema_conform(400)
74
83
  end
75
84
  assert_match(/response header must be set to/i, e.message)
76
85
  end
@@ -46,14 +46,14 @@ describe Committee::Test::Methods do
46
46
  it "passes through a valid response" do
47
47
  @app = new_rack_app(JSON.generate([ValidApp]))
48
48
  get "/apps"
49
- assert_schema_conform
49
+ assert_schema_conform(200)
50
50
  end
51
51
 
52
52
  it "detects an invalid response Content-Type" do
53
53
  @app = new_rack_app(JSON.generate([ValidApp]), {})
54
54
  get "/apps"
55
55
  e = assert_raises(Committee::InvalidResponse) do
56
- assert_schema_conform
56
+ assert_schema_conform(200)
57
57
  end
58
58
  assert_match(/response header must be set to/i, e.message)
59
59
  end
@@ -64,7 +64,8 @@ describe Committee::Test::Methods do
64
64
  _, err = capture_io do
65
65
  assert_schema_conform
66
66
  end
67
- assert_match(/\[DEPRECATION\]/i, err)
67
+ assert_match(/\[DEPRECATION\] Now assert_schema_conform check response schema only/i, err)
68
+ assert_match(/\[DEPRECATION\] Pass expected response status code/i, err)
68
69
  end
69
70
  end
70
71
 
@@ -161,7 +162,8 @@ describe Committee::Test::Methods do
161
162
  _, err = capture_io do
162
163
  assert_schema_conform
163
164
  end
164
- assert_match(/\[DEPRECATION\]/i, err)
165
+ assert_match(/\[DEPRECATION\] Now assert_schema_conform check response schema only/i, err)
166
+ assert_match(/\[DEPRECATION\] Pass expected response status code/i, err)
165
167
  end
166
168
  end
167
169
 
data/test/test_helper.rb CHANGED
@@ -55,6 +55,10 @@ def open_api_2_schema
55
55
  @open_api_2_schema ||= Committee::Drivers.load_from_file(open_api_2_schema_path)
56
56
  end
57
57
 
58
+ def open_api_2_form_schema
59
+ @open_api_2_form_schema ||= Committee::Drivers.load_from_file(open_api_2_form_schema_path)
60
+ end
61
+
58
62
  def open_api_3_schema
59
63
  @open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
60
64
  end
@@ -73,6 +77,10 @@ def open_api_2_data
73
77
  JSON.parse(File.read(open_api_2_schema_path))
74
78
  end
75
79
 
80
+ def open_api_2_form_data
81
+ JSON.parse(File.read(open_api_2_form_schema_path))
82
+ end
83
+
76
84
  def open_api_3_data
77
85
  YAML.load_file(open_api_3_schema_path)
78
86
  end
@@ -85,6 +93,10 @@ def open_api_2_schema_path
85
93
  "./test/data/openapi2/petstore-expanded.json"
86
94
  end
87
95
 
96
+ def open_api_2_form_schema_path
97
+ "./test/data/openapi2/petstore-expanded-form.json"
98
+ end
99
+
88
100
  def open_api_3_schema_path
89
101
  "./test/data/openapi3/normal.yaml"
90
102
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: committee
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandur
8
8
  - geemus (Wesley Beary)
9
9
  - ota42y
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-12-23 00:00:00.000000000 Z
13
+ date: 2021-06-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -53,6 +53,9 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: 0.11.1
56
+ - - "<"
57
+ - !ruby/object:Gem::Version
58
+ version: '1.0'
56
59
  type: :runtime
57
60
  prerelease: false
58
61
  version_requirements: !ruby/object:Gem::Requirement
@@ -60,6 +63,9 @@ dependencies:
60
63
  - - ">="
61
64
  - !ruby/object:Gem::Version
62
65
  version: 0.11.1
66
+ - - "<"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
63
69
  - !ruby/object:Gem::Dependency
64
70
  name: minitest
65
71
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +152,20 @@ dependencies:
146
152
  version: '0'
147
153
  - !ruby/object:Gem::Dependency
148
154
  name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "<"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.13.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "<"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.13.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-performance
149
169
  requirement: !ruby/object:Gem::Requirement
150
170
  requirements:
151
171
  - - ">="
@@ -159,7 +179,21 @@ dependencies:
159
179
  - !ruby/object:Gem::Version
160
180
  version: '0'
161
181
  - !ruby/object:Gem::Dependency
162
- name: rubocop-performance
182
+ name: rubocop-minitest
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: rubocop-rake
163
197
  requirement: !ruby/object:Gem::Requirement
164
198
  requirements:
165
199
  - - ">="
@@ -186,7 +220,7 @@ dependencies:
186
220
  - - ">="
187
221
  - !ruby/object:Gem::Version
188
222
  version: '0'
189
- description:
223
+ description:
190
224
  email:
191
225
  - brandur@mutelight.org
192
226
  - geemus+github@gmail.com
@@ -239,6 +273,7 @@ files:
239
273
  - lib/committee/schema_validator/option.rb
240
274
  - lib/committee/test/methods.rb
241
275
  - lib/committee/test/schema_coverage.rb
276
+ - lib/committee/utils.rb
242
277
  - lib/committee/validation_error.rb
243
278
  - test/bin/committee_stub_test.rb
244
279
  - test/bin_test.rb
@@ -276,7 +311,7 @@ homepage: https://github.com/interagent/committee
276
311
  licenses:
277
312
  - MIT
278
313
  metadata: {}
279
- post_install_message:
314
+ post_install_message:
280
315
  rdoc_options: []
281
316
  require_paths:
282
317
  - lib
@@ -291,8 +326,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
326
  - !ruby/object:Gem::Version
292
327
  version: '0'
293
328
  requirements: []
294
- rubygems_version: 3.1.2
295
- signing_key:
329
+ rubygems_version: 3.2.3
330
+ signing_key:
296
331
  specification_version: 4
297
332
  summary: A collection of Rack middleware to support JSON Schema.
298
333
  test_files: []