committee 4.3.0 → 4.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c70ee2e436755ddf7b0b59b213ab7c00b60e67ce52520b956b889121b24e4c
4
- data.tar.gz: 06066adc6056231938d36d93a98c5d7318d9c1ff367784265d66c0eb271fb7b6
3
+ metadata.gz: 3a1c74892e2e3abf70f99999312c39aa6e85d0fe8323b73d534ff231c3d7f443
4
+ data.tar.gz: 0be5e25f5dc94b28aa1d0055f7403e2ca8e59199567d128a7ea2d459a833d4cd
5
5
  SHA512:
6
- metadata.gz: bfbcc7aa85c676291125ed16b20badadda3eb8d895b6834cdc884602345c6ed3a052ecbdd381615b8bbca49815d884407cf8cc2f8cbbe05702593b5cc171f568
7
- data.tar.gz: cc454350c3d04969ad3f24c1922b887a6e319cea4f0a869b647ef439dbc9f5f83f3922bde82abdeb0994a540e53d5e68345e76d7291b408e42cd2f5a4df9eec1
6
+ metadata.gz: 1c8f4286e8be5cd6331e8ca323963bed83c2e0e2960037a78fa0aa78e23f3d684ee931336a4f5e4ce55f4b7dd83f7cf9873ea704979ed53e5cbc47599f3ebc98
7
+ data.tar.gz: bc840cb4285ecc917613162d6b9837c419e88464a96724b06bf90f07236bf725cc5d099e17c8ecc5cc64f948ff5b35a513a9387ed948c56bcad664d71487313d
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.rc1
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-05-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -146,6 +146,20 @@ dependencies:
146
146
  version: '0'
147
147
  - !ruby/object:Gem::Dependency
148
148
  name: rubocop
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "<"
152
+ - !ruby/object:Gem::Version
153
+ version: 1.13.0
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "<"
159
+ - !ruby/object:Gem::Version
160
+ version: 1.13.0
161
+ - !ruby/object:Gem::Dependency
162
+ name: rubocop-performance
149
163
  requirement: !ruby/object:Gem::Requirement
150
164
  requirements:
151
165
  - - ">="
@@ -159,7 +173,21 @@ dependencies:
159
173
  - !ruby/object:Gem::Version
160
174
  version: '0'
161
175
  - !ruby/object:Gem::Dependency
162
- name: rubocop-performance
176
+ name: rubocop-minitest
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ - !ruby/object:Gem::Dependency
190
+ name: rubocop-rake
163
191
  requirement: !ruby/object:Gem::Requirement
164
192
  requirements:
165
193
  - - ">="
@@ -186,7 +214,7 @@ dependencies:
186
214
  - - ">="
187
215
  - !ruby/object:Gem::Version
188
216
  version: '0'
189
- description:
217
+ description:
190
218
  email:
191
219
  - brandur@mutelight.org
192
220
  - geemus+github@gmail.com
@@ -239,6 +267,7 @@ files:
239
267
  - lib/committee/schema_validator/option.rb
240
268
  - lib/committee/test/methods.rb
241
269
  - lib/committee/test/schema_coverage.rb
270
+ - lib/committee/utils.rb
242
271
  - lib/committee/validation_error.rb
243
272
  - test/bin/committee_stub_test.rb
244
273
  - test/bin_test.rb
@@ -276,7 +305,7 @@ homepage: https://github.com/interagent/committee
276
305
  licenses:
277
306
  - MIT
278
307
  metadata: {}
279
- post_install_message:
308
+ post_install_message:
280
309
  rdoc_options: []
281
310
  require_paths:
282
311
  - lib
@@ -287,12 +316,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
287
316
  version: 2.4.0
288
317
  required_rubygems_version: !ruby/object:Gem::Requirement
289
318
  requirements:
290
- - - ">="
319
+ - - ">"
291
320
  - !ruby/object:Gem::Version
292
- version: '0'
321
+ version: 1.3.1
293
322
  requirements: []
294
- rubygems_version: 3.1.2
295
- signing_key:
323
+ rubygems_version: 3.2.3
324
+ signing_key:
296
325
  specification_version: 4
297
326
  summary: A collection of Rack middleware to support JSON Schema.
298
327
  test_files: []