committee 4.4.0 → 5.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/committee/drivers/open_api_2/driver.rb +1 -1
  3. data/lib/committee/drivers/open_api_2/parameter_schema_builder.rb +1 -1
  4. data/lib/committee/drivers.rb +21 -9
  5. data/lib/committee/middleware/base.rb +5 -4
  6. data/lib/committee/middleware/request_validation.rb +1 -8
  7. data/lib/committee/middleware/response_validation.rb +13 -14
  8. data/lib/committee/request_unpacker.rb +1 -1
  9. data/lib/committee/schema_validator/hyper_schema/response_validator.rb +1 -1
  10. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +32 -33
  11. data/lib/committee/schema_validator/open_api_3/request_validator.rb +2 -2
  12. data/lib/committee/schema_validator/open_api_3.rb +28 -15
  13. data/lib/committee/schema_validator/option.rb +5 -13
  14. data/lib/committee/test/methods.rb +2 -7
  15. data/lib/committee/version.rb +5 -0
  16. data/lib/committee.rb +9 -2
  17. data/test/committee_test.rb +28 -2
  18. data/test/drivers/open_api_3/driver_test.rb +1 -1
  19. data/test/drivers_test.rb +20 -7
  20. data/test/middleware/base_test.rb +6 -13
  21. data/test/middleware/request_validation_open_api_3_test.rb +117 -41
  22. data/test/middleware/request_validation_test.rb +1 -28
  23. data/test/middleware/response_validation_open_api_3_test.rb +46 -3
  24. data/test/middleware/response_validation_test.rb +6 -25
  25. data/test/schema_validator/hyper_schema/response_validator_test.rb +10 -0
  26. data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +1 -1
  27. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +55 -11
  28. data/test/schema_validator/open_api_3/request_validator_test.rb +10 -0
  29. data/test/schema_validator/open_api_3/response_validator_test.rb +14 -0
  30. data/test/test/methods_new_version_test.rb +1 -1
  31. data/test/test/methods_test.rb +11 -31
  32. data/test/test_helper.rb +11 -3
  33. metadata +14 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 108842305271b038db8a6a49bd4ec9da83ea573a5061144484f4704a4af278df
4
- data.tar.gz: 216360635fabf23f082f768594c4799ef4c71f3de4cf7ff7ffc4ac2b7fc5a72c
3
+ metadata.gz: 4257522fd7e79dceca7f4ee846f35d8eea30f70a4a2a9ab1f9e99a946eb992f6
4
+ data.tar.gz: c71c15566465b608e72380c47ad3beceb9195d47949c234c1fbb0f99b0ebc22a
5
5
  SHA512:
6
- metadata.gz: 417368733fb254f0211dd9ff6b273bf722db984325326816e3568ba7352da4079fb27c1405029d7191ae17e232d357041474f89ce6b7209c063911e8f4db26b3
7
- data.tar.gz: '05682d9aaf2688ef511484bdaca307c1ff63dcefbdf1e4b6dcece592db7a548c5fa7ee0bb3498f4f1b903e20f9944a58790c335fc7c69251bdf0c65e33e3b19c'
6
+ metadata.gz: ca98156c131a991a05fc12f4bb149e2d740c6083befb91b96874ac27b2fdc923109e452f64d35f3e8bb0e92bd3c19575171013f8529ef95437bbd3b51335d1a4
7
+ data.tar.gz: a623459fca01819e67403a3ba73b4e7cf3997d01c48b6c21f71f87ca51b9f6eddf3e3e413be25678d684042cb94b991a75c5432ea85cec07af7f07696accaa94
@@ -59,7 +59,7 @@ module Committee
59
59
  schema.base_path = data['basePath'] || ''
60
60
 
61
61
  # Arbitrarily choose the first media type found in these arrays. This
62
- # appraoch could probably stand to be improved, but at least users will
62
+ # approach could probably stand to be improved, but at least users will
63
63
  # for now have the option of turning media type validation off if they so
64
64
  # choose.
65
65
  schema.consumes = data['consumes'].first
@@ -62,7 +62,7 @@ module Committee
62
62
  # And same idea: despite parameters not being schemas, the items
63
63
  # key (if preset) is actually a schema that defines each item of an
64
64
  # array type, so we can just reflect that directly onto our
65
- # artifical schema.
65
+ # artificial schema.
66
66
  if param_data["type"] == "array" && param_data["items"]
67
67
  param_schema.items = param_data["items"]
68
68
  end
@@ -20,26 +20,27 @@ module Committee
20
20
  # load and build drive from JSON file
21
21
  # @param [String] schema_path
22
22
  # @return [Committee::Driver]
23
- def self.load_from_json(schema_path)
24
- load_from_data(JSON.parse(File.read(schema_path)), schema_path)
23
+ def self.load_from_json(schema_path, parser_options: {})
24
+ load_from_data(JSON.parse(File.read(schema_path)), schema_path, parser_options: parser_options)
25
25
  end
26
26
 
27
27
  # load and build drive from YAML file
28
28
  # @param [String] schema_path
29
29
  # @return [Committee::Driver]
30
- def self.load_from_yaml(schema_path)
31
- load_from_data(YAML.load_file(schema_path), schema_path)
30
+ def self.load_from_yaml(schema_path, parser_options: {})
31
+ data = YAML.respond_to?(:unsafe_load_file) ? YAML.unsafe_load_file(schema_path) : YAML.load_file(schema_path)
32
+ load_from_data(data, schema_path, parser_options: parser_options)
32
33
  end
33
34
 
34
35
  # load and build drive from file
35
36
  # @param [String] schema_path
36
37
  # @return [Committee::Driver]
37
- def self.load_from_file(schema_path)
38
+ def self.load_from_file(schema_path, parser_options: {})
38
39
  case File.extname(schema_path)
39
40
  when '.json'
40
- load_from_json(schema_path)
41
+ load_from_json(schema_path, parser_options: parser_options)
41
42
  when '.yaml', '.yml'
42
- load_from_yaml(schema_path)
43
+ load_from_yaml(schema_path, parser_options: parser_options)
43
44
  else
44
45
  raise "Committee only supports the following file extensions: '.json', '.yaml', '.yml'"
45
46
  end
@@ -48,9 +49,19 @@ module Committee
48
49
  # load and build drive from Hash object
49
50
  # @param [Hash] hash
50
51
  # @return [Committee::Driver]
51
- def self.load_from_data(hash, schema_path = nil)
52
+ def self.load_from_data(hash, schema_path = nil, parser_options: {})
52
53
  if hash['openapi']&.start_with?('3.0.')
53
- openapi = OpenAPIParser.parse_with_filepath(hash, schema_path)
54
+ # From the next major version, we want to ensure `{ strict_reference_validation: true }`
55
+ # as a parser option here, but since it may break existing implementations, just warn
56
+ # if it is not explicitly set. See: https://github.com/interagent/committee/issues/343#issuecomment-997400329
57
+ opts = parser_options.dup
58
+
59
+ Committee.warn_deprecated_until_6(!opts.key?(:strict_reference_validation), 'openapi_parser will default to strict reference validation ' +
60
+ 'from next version. Pass config `strict_reference_validation: true` (or false, if you must) ' +
61
+ 'to quiet this warning.')
62
+ opts[:strict_reference_validation] ||= false
63
+
64
+ openapi = OpenAPIParser.parse_with_filepath(hash, schema_path, opts)
54
65
  return Committee::Drivers::OpenAPI3::Driver.new.parse(openapi)
55
66
  end
56
67
 
@@ -60,6 +71,7 @@ module Committee
60
71
  Committee::Drivers::HyperSchema::Driver.new
61
72
  end
62
73
 
74
+ # TODO: in the future, pass `opts` here and allow optionality in other drivers?
63
75
  driver.parse(hash)
64
76
  end
65
77
  end
@@ -30,11 +30,12 @@ module Committee
30
30
  class << self
31
31
  def get_schema(options)
32
32
  schema = options[:schema]
33
- unless schema
34
- schema = Committee::Drivers::load_from_file(options[:schema_path]) if options[:schema_path]
35
-
36
- raise(ArgumentError, "Committee: need option `schema` or `schema_path`") unless schema
33
+ if !schema && options[:schema_path]
34
+ # In the future, we could have `parser_options` as an exposed config?
35
+ parser_options = options.key?(:strict_reference_validation) ? { strict_reference_validation: options[:strict_reference_validation] } : {}
36
+ schema = Committee::Drivers::load_from_file(options[:schema_path], parser_options: parser_options)
37
37
  end
38
+ raise(ArgumentError, "Committee: need option `schema` or `schema_path`") unless schema
38
39
 
39
40
  # Expect the type we want by now. If we don't have it, the user passed
40
41
  # something else non-standard in.
@@ -34,14 +34,7 @@ module Committee
34
34
  private
35
35
 
36
36
  def handle_exception(e, env)
37
- return unless @error_handler
38
-
39
- if @error_handler.arity > 1
40
- @error_handler.call(e, env)
41
- else
42
- Committee.warn_deprecated('Using `error_handler.call(exception)` is deprecated and will be change to `error_handler.call(exception, request.env)` in next major version.')
43
- @error_handler.call(e)
44
- end
37
+ @error_handler.call(e, env) if @error_handler
45
38
  end
46
39
  end
47
40
  end
@@ -7,10 +7,7 @@ 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
+ @strict = options[:strict]
14
11
  @validate_success_only = @schema.validator_option.validate_success_only
15
12
  end
16
13
 
@@ -19,7 +16,7 @@ module Committee
19
16
 
20
17
  begin
21
18
  v = build_schema_validator(request)
22
- v.response_validate(status, headers, response) if v.link_exist? && self.class.validate?(status, validate_success_only)
19
+ v.response_validate(status, headers, response, @strict) if v.link_exist? && self.class.validate?(status, validate_success_only)
23
20
 
24
21
  rescue Committee::InvalidResponse
25
22
  handle_exception($!, request.env)
@@ -38,21 +35,23 @@ module Committee
38
35
 
39
36
  class << self
40
37
  def validate?(status, validate_success_only)
41
- status != 204 && (!validate_success_only || (200...300).include?(status))
38
+ case status
39
+ when 204
40
+ false
41
+ when 200..299
42
+ true
43
+ when 304
44
+ false
45
+ else
46
+ !validate_success_only
47
+ end
42
48
  end
43
49
  end
44
50
 
45
51
  private
46
52
 
47
53
  def handle_exception(e, env)
48
- return unless @error_handler
49
-
50
- if @error_handler.arity > 1
51
- @error_handler.call(e, env)
52
- else
53
- Committee.warn_deprecated('Using `error_handler.call(exception)` is deprecated and will be change to `error_handler.call(exception, request.env)` in next major version.')
54
- @error_handler.call(e)
55
- end
54
+ @error_handler.call(e, env) if @error_handler
56
55
  end
57
56
  end
58
57
  end
@@ -27,7 +27,7 @@ module Committee
27
27
  @optimistic_json = options[:optimistic_json]
28
28
  end
29
29
 
30
- # reutrn params and is_form_params
30
+ # return params and is_form_params
31
31
  def unpack_request_params(request)
32
32
  # if Content-Type is empty or JSON, and there was a request body, try to
33
33
  # interpret it as JSON
@@ -14,7 +14,7 @@ module Committee
14
14
  end
15
15
 
16
16
  def call(status, headers, data)
17
- unless status == 204 # 204 No Content
17
+ unless [204, 304].include?(status) # 204 No Content or 304 Not Modified
18
18
  response = Rack::Response.new(data, status, headers)
19
19
  check_content_type!(response)
20
20
  end
@@ -39,18 +39,12 @@ module Committee
39
39
  raise Committee::InvalidResponse.new(e.message, original_error: e)
40
40
  end
41
41
 
42
- def validate_request_params(params, headers, validator_option)
42
+ def validate_request_params(path_params, query_params, body_params, headers, validator_option)
43
43
  ret, err = case request_operation.http_method
44
- when 'get'
45
- validate_get_request_params(params, headers, validator_option)
46
- when 'post'
47
- validate_post_request_params(params, headers, validator_option)
48
- when 'put'
49
- validate_post_request_params(params, headers, validator_option)
50
- when 'patch'
51
- validate_post_request_params(params, headers, validator_option)
52
- when 'delete'
53
- validate_get_request_params(params, headers, validator_option)
44
+ when 'get', 'delete', 'head'
45
+ validate_get_request_params(path_params, query_params, headers, validator_option)
46
+ when 'post', 'put', 'patch', 'options'
47
+ validate_post_request_params(path_params, query_params, body_params, headers, validator_option)
54
48
  else
55
49
  raise "Committee OpenAPI3 not support #{request_operation.http_method} method"
56
50
  end
@@ -80,28 +74,17 @@ module Committee
80
74
  # @return [OpenAPIParser::RequestOperation]
81
75
 
82
76
  # @return [OpenAPIParser::SchemaValidator::Options]
83
- def build_openapi_parser_path_option(validator_option)
84
- coerce_value = validator_option.coerce_path_params
85
- datetime_coerce_class = validator_option.coerce_date_times ? DateTime : nil
86
- validate_header = validator_option.check_header
87
- OpenAPIParser::SchemaValidator::Options.new(coerce_value: coerce_value,
88
- datetime_coerce_class: datetime_coerce_class,
89
- validate_header: validate_header)
77
+ def build_openapi_parser_body_option(validator_option)
78
+ build_openapi_parser_option(validator_option, validator_option.coerce_form_params)
90
79
  end
91
80
 
92
81
  # @return [OpenAPIParser::SchemaValidator::Options]
93
- def build_openapi_parser_post_option(validator_option)
94
- coerce_value = validator_option.coerce_form_params
95
- datetime_coerce_class = validator_option.coerce_date_times ? DateTime : nil
96
- validate_header = validator_option.check_header
97
- OpenAPIParser::SchemaValidator::Options.new(coerce_value: coerce_value,
98
- datetime_coerce_class: datetime_coerce_class,
99
- validate_header: validate_header)
82
+ def build_openapi_parser_path_option(validator_option)
83
+ build_openapi_parser_option(validator_option, validator_option.coerce_query_params)
100
84
  end
101
85
 
102
86
  # @return [OpenAPIParser::SchemaValidator::Options]
103
- def build_openapi_parser_get_option(validator_option)
104
- coerce_value = validator_option.coerce_query_params
87
+ def build_openapi_parser_option(validator_option, coerce_value)
105
88
  datetime_coerce_class = validator_option.coerce_date_times ? DateTime : nil
106
89
  validate_header = validator_option.check_header
107
90
  OpenAPIParser::SchemaValidator::Options.new(coerce_value: coerce_value,
@@ -109,24 +92,40 @@ module Committee
109
92
  validate_header: validate_header)
110
93
  end
111
94
 
112
- def validate_get_request_params(params, headers, validator_option)
95
+ def validate_get_request_params(path_params, query_params, headers, validator_option)
113
96
  # bad performance because when we coerce value, same check
114
- request_operation.validate_request_parameter(params, headers, build_openapi_parser_get_option(validator_option))
97
+ validate_path_and_query_params(path_params, query_params, headers, validator_option)
115
98
  rescue OpenAPIParser::OpenAPIError => e
116
99
  raise Committee::InvalidRequest.new(e.message, original_error: e)
117
100
  end
118
101
 
119
- def validate_post_request_params(params, headers, validator_option)
102
+ def validate_post_request_params(path_params, query_params, body_params, headers, validator_option)
120
103
  content_type = headers['Content-Type'].to_s.split(";").first.to_s
121
104
 
122
105
  # bad performance because when we coerce value, same check
123
- schema_validator_options = build_openapi_parser_post_option(validator_option)
124
- request_operation.validate_request_parameter(params, headers, schema_validator_options)
125
- request_operation.validate_request_body(content_type, params, schema_validator_options)
106
+ validate_path_and_query_params(path_params, query_params, headers, validator_option)
107
+ request_operation.validate_request_body(content_type, body_params, build_openapi_parser_body_option(validator_option))
126
108
  rescue => e
127
109
  raise Committee::InvalidRequest.new(e.message, original_error: e)
128
110
  end
129
111
 
112
+ def validate_path_and_query_params(path_params, query_params, headers, validator_option)
113
+ # it's currently impossible to validate path params and query params separately
114
+ # so we have to resort to this workaround
115
+
116
+ path_keys = path_params.keys.to_set
117
+ query_keys = query_params.keys.to_set
118
+
119
+ merged_params = query_params.merge(path_params)
120
+
121
+ request_operation.validate_request_parameter(merged_params, headers, build_openapi_parser_path_option(validator_option))
122
+
123
+ merged_params.each do |k, v|
124
+ path_params[k] = v if path_keys.include?(k)
125
+ query_params[k] = v if query_keys.include?(k)
126
+ end
127
+ end
128
+
130
129
  def response_validate_options(strict, check_header)
131
130
  ::OpenAPIParser::SchemaValidator::ResponseValidateOptions.new(strict: strict, validate_header: check_header)
132
131
  end
@@ -11,11 +11,11 @@ module Committee
11
11
  @validator_option = validator_option
12
12
  end
13
13
 
14
- def call(request, params, headers)
14
+ def call(request, path_params, query_params, body_params, headers)
15
15
  content_type = ::Committee::SchemaValidator.request_media_type(request)
16
16
  check_content_type(request, content_type) if @validator_option.check_content_type
17
17
 
18
- @operation_object.validate_request_params(params, headers, @validator_option)
18
+ @operation_object.validate_request_params(path_params, query_params, body_params, headers, @validator_option)
19
19
  end
20
20
 
21
21
  private
@@ -17,7 +17,7 @@ module Committee
17
17
  request_unpack(request)
18
18
  request_schema_validation(request)
19
19
 
20
- copy_coerced_data_to_query_hash(request)
20
+ copy_coerced_data_to_params(request)
21
21
  end
22
22
 
23
23
  def response_validate(status, headers, response, test_method = false)
@@ -34,6 +34,7 @@ module Committee
34
34
  full_body
35
35
  end
36
36
 
37
+ # TODO: refactoring name
37
38
  strict = test_method
38
39
  Committee::SchemaValidator::OpenAPI3::ResponseValidator.
39
40
  new(@operation_object, validator_option).
@@ -57,7 +58,19 @@ module Committee
57
58
  return unless @operation_object
58
59
 
59
60
  validator = Committee::SchemaValidator::OpenAPI3::RequestValidator.new(@operation_object, validator_option: validator_option)
60
- validator.call(request, request.env[validator_option.params_key], header(request))
61
+ validator.call(request, path_params(request), query_params(request), body_params(request), header(request))
62
+ end
63
+
64
+ def path_params(request)
65
+ request.env[validator_option.path_hash_key]
66
+ end
67
+
68
+ def query_params(request)
69
+ request.env[validator_option.query_hash_key]
70
+ end
71
+
72
+ def body_params(request)
73
+ request.env[validator_option.request_body_hash_key]
61
74
  end
62
75
 
63
76
  def header(request)
@@ -79,22 +92,22 @@ module Committee
79
92
  request.env[validator_option.path_hash_key] = coerce_path_params
80
93
 
81
94
  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]))
95
+ query_param.merge!(request_param) if request.get? && validator_option.allow_get_body
96
+ request.env[validator_option.query_hash_key] = query_param
87
97
  end
88
98
 
89
- def copy_coerced_data_to_query_hash(request)
90
- return if request.env["rack.request.query_hash"].nil? || request.env["rack.request.query_hash"].empty?
91
-
92
- query_hash_key = @validator_option.query_hash_key
93
- return unless query_hash_key
99
+ def copy_coerced_data_to_params(request)
100
+ order = if validator_option.parameter_overwite_by_rails_rule
101
+ # (high priority) path_hash_key -> query_param -> request_body_hash
102
+ [validator_option.request_body_hash_key, validator_option.query_hash_key, validator_option.path_hash_key]
103
+ else
104
+ # (high priority) path_hash_key -> request_body_hash -> query_param
105
+ [validator_option.query_hash_key, validator_option.request_body_hash_key, validator_option.path_hash_key]
106
+ end
94
107
 
95
- request.env[query_hash_key] = {} unless request.env[query_hash_key]
96
- request.env["rack.request.query_hash"].keys.each do |k|
97
- request.env[query_hash_key][k] = request.env[validator_option.params_key][k]
108
+ request.env[validator_option.params_key] = Committee::Utils.indifferent_hash
109
+ order.each do |key|
110
+ request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request.env[key]))
98
111
  end
99
112
  end
100
113
  end
@@ -16,7 +16,8 @@ module Committee
16
16
  :coerce_recursive,
17
17
  :optimistic_json,
18
18
  :validate_success_only,
19
- :parse_response_by_content_type
19
+ :parse_response_by_content_type,
20
+ :parameter_overwite_by_rails_rule
20
21
 
21
22
  # Non-boolean options:
22
23
  attr_reader :headers_key,
@@ -30,12 +31,7 @@ module Committee
30
31
  # Non-boolean options
31
32
  @headers_key = options[:headers_key] || "committee.headers"
32
33
  @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
34
+ @query_hash_key = options[:query_hash_key] || "committee.query_hash"
39
35
  @path_hash_key = options[:path_hash_key] || "committee.path_hash"
40
36
  @request_body_hash_key = options[:request_body_hash_key] || "committee.request_body_hash"
41
37
 
@@ -48,12 +44,8 @@ module Committee
48
44
  @check_header = options.fetch(:check_header, true)
49
45
  @coerce_recursive = options.fetch(:coerce_recursive, true)
50
46
  @optimistic_json = options.fetch(:optimistic_json, false)
51
- @parse_response_by_content_type = if options[:parse_response_by_content_type].nil?
52
- Committee.warn_deprecated('Committee: please set parse_response_by_content_type = false because we\'ll change default value in next major version.')
53
- false
54
- else
55
- options.fetch(:parse_response_by_content_type)
56
- end
47
+ @parse_response_by_content_type = options.fetch(:parse_response_by_content_type, true)
48
+ @parameter_overwite_by_rails_rule = options.fetch(:parameter_overwite_by_rails_rule, true)
57
49
 
58
50
  # Boolean options and have a different value by default
59
51
  @allow_get_body = options.fetch(:allow_get_body, schema.driver.default_allow_get_body)
@@ -26,7 +26,7 @@ module Committee
26
26
  status, headers, body = response_data
27
27
 
28
28
  if expected_status.nil?
29
- Committee.warn_deprecated('Pass expected response status code to check it against the corresponding schema explicitly.')
29
+ Committee.need_good_option('Pass expected response status code to check it against the corresponding schema explicitly.')
30
30
  elsif expected_status != status
31
31
  response = "Expected `#{expected_status}` status code, but it was `#{status}`."
32
32
  raise Committee::InvalidResponse.new(response)
@@ -77,12 +77,7 @@ module Committee
77
77
  end
78
78
 
79
79
  def old_behavior
80
- old_assert_behavior = committee_options.fetch(:old_assert_behavior, nil)
81
- if old_assert_behavior.nil?
82
- Committee.warn_deprecated('Now assert_schema_conform check response schema only. but we will change check request and response in future major version. so if you want to conform response only, please use assert_response_schema_confirm, or you can suppress this message and keep old behavior by setting old_assert_behavior=true.')
83
- old_assert_behavior = true
84
- end
85
- old_assert_behavior
80
+ committee_options.fetch(:old_assert_behavior, false)
86
81
  end
87
82
  end
88
83
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Committee
4
+ VERSION = '5.0.0.beta1'.freeze
5
+ end
data/lib/committee.rb CHANGED
@@ -6,6 +6,8 @@ require "json_schema"
6
6
  require "rack"
7
7
  require 'openapi_parser'
8
8
 
9
+ require_relative "committee/version"
10
+
9
11
  module Committee
10
12
  def self.debug?
11
13
  ENV["COMMITTEE_DEBUG"]
@@ -15,8 +17,13 @@ module Committee
15
17
  $stderr.puts(message) if debug?
16
18
  end
17
19
 
18
- def self.warn_deprecated(message)
19
- warn("[DEPRECATION] #{message}")
20
+ def self.need_good_option(message)
21
+ warn(message)
22
+ end
23
+
24
+ def self.warn_deprecated_until_6(cond, message)
25
+ raise "remove deprecated!" unless Committee::VERSION.start_with?("5")
26
+ warn("[DEPRECATION] #{message}") if cond
20
27
  end
21
28
  end
22
29
 
@@ -31,21 +31,47 @@ describe Committee do
31
31
  end
32
32
  end
33
33
 
34
+ it "warns need_good_option" do
35
+ old_stderr = $stderr
36
+ $stderr = StringIO.new
37
+ begin
38
+ Committee.need_good_option "show"
39
+ assert_equal "show\n", $stderr.string
40
+ ensure
41
+ $stderr = old_stderr
42
+ end
43
+ end
44
+
34
45
  it "warns on deprecated unless $VERBOSE is nil" do
35
46
  old_stderr = $stderr
36
47
  old_verbose = $VERBOSE
37
48
  $stderr = StringIO.new
38
49
  begin
39
50
  $VERBOSE = nil
40
- Committee.warn_deprecated "blah"
51
+ Committee.warn_deprecated_until_6 true, "blah"
41
52
  assert_equal "", $stderr.string
42
53
 
43
54
  $VERBOSE = true
44
- Committee.warn_deprecated "blah"
55
+ Committee.warn_deprecated_until_6 true, "blah"
45
56
  assert_equal "[DEPRECATION] blah\n", $stderr.string
46
57
  ensure
47
58
  $stderr = old_stderr
48
59
  $VERBOSE = old_verbose
49
60
  end
50
61
  end
62
+
63
+
64
+ it "doesn't warns on deprecated if cond is false" do
65
+ old_stderr = $stderr
66
+ old_verbose = $VERBOSE
67
+ $stderr = StringIO.new
68
+ begin
69
+ $VERBOSE = true
70
+ Committee.warn_deprecated_until_6 false, "blah"
71
+ assert_equal "", $stderr.string
72
+ ensure
73
+ $stderr = old_stderr
74
+ $VERBOSE = old_verbose
75
+ end
76
+ end
51
77
  end
@@ -16,7 +16,7 @@ describe Committee::Drivers::OpenAPI3::Driver do
16
16
  end
17
17
 
18
18
  it "override methods" do
19
- parser = OpenAPIParser.parse(open_api_3_data)
19
+ parser = OpenAPIParser.parse(open_api_3_data, strict_reference_validation: false)
20
20
  schema = @driver.parse(parser)
21
21
 
22
22
  assert_kind_of Committee::Drivers::OpenAPI3::Schema, schema
data/test/drivers_test.rb CHANGED
@@ -37,20 +37,33 @@ describe Committee::Drivers do
37
37
  end
38
38
 
39
39
  it 'loads OpenAPI 3' do
40
- s = Committee::Drivers.load_from_file(open_api_3_schema_path)
40
+ s = Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true})
41
41
  assert_kind_of Committee::Drivers::Schema, s
42
42
  assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
43
43
  end
44
44
 
45
45
  it 'load OpenAPI 3 (patch version 3.0.1)' do
46
- s = Committee::Drivers.load_from_file(open_api_3_0_1_schema_path)
46
+ s = Committee::Drivers.load_from_file(open_api_3_0_1_schema_path, parser_options:{strict_reference_validation: true})
47
47
  assert_kind_of Committee::Drivers::Schema, s
48
48
  assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
49
49
  end
50
50
 
51
+ it 'fails to load OpenAPI 3 with invalid reference' do
52
+ parser_options = { strict_reference_validation: true }
53
+ assert_raises(OpenAPIParser::MissingReferenceError) do
54
+ Committee::Drivers.load_from_file(open_api_3_invalid_reference_path, parser_options: parser_options)
55
+ end
56
+ end
57
+
58
+ # This test can be removed when the test above (raising on invalid reference) becomes default behavior?
59
+ it 'allows loading OpenAPI 3 with invalid reference as existing behavior' do
60
+ s = Committee::Drivers.load_from_file(open_api_3_invalid_reference_path, parser_options:{strict_reference_validation: false})
61
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
62
+ end
63
+
51
64
  it 'errors on an unsupported file extension' do
52
65
  e = assert_raises(StandardError) do
53
- Committee::Drivers.load_from_file('test.xml')
66
+ Committee::Drivers.load_from_file('test.xml', parser_options:{strict_reference_validation: true})
54
67
  end
55
68
  assert_equal "Committee only supports the following file extensions: '.json', '.yaml', '.yml'", e.message
56
69
  end
@@ -58,13 +71,13 @@ describe Committee::Drivers do
58
71
 
59
72
  describe 'load_from_json(schema_path)' do
60
73
  it 'loads OpenAPI2' do
61
- s = Committee::Drivers.load_from_json(open_api_2_schema_path)
74
+ s = Committee::Drivers.load_from_json(open_api_2_schema_path, parser_options:{strict_reference_validation: true})
62
75
  assert_kind_of Committee::Drivers::Schema, s
63
76
  assert_kind_of Committee::Drivers::OpenAPI2::Schema, s
64
77
  end
65
78
 
66
79
  it 'loads Hyper-Schema' do
67
- s = Committee::Drivers.load_from_json(hyper_schema_schema_path)
80
+ s = Committee::Drivers.load_from_json(hyper_schema_schema_path, parser_options:{strict_reference_validation: true})
68
81
  assert_kind_of Committee::Drivers::Schema, s
69
82
  assert_kind_of Committee::Drivers::HyperSchema::Schema, s
70
83
  end
@@ -72,7 +85,7 @@ describe Committee::Drivers do
72
85
 
73
86
  describe 'load_from_yaml(schema_path)' do
74
87
  it 'loads OpenAPI3' do
75
- s = Committee::Drivers.load_from_yaml(open_api_3_schema_path)
88
+ s = Committee::Drivers.load_from_yaml(open_api_3_schema_path, parser_options:{strict_reference_validation: true})
76
89
  assert_kind_of Committee::Drivers::Schema, s
77
90
  assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
78
91
  end
@@ -80,7 +93,7 @@ describe Committee::Drivers do
80
93
 
81
94
  describe 'load_from_data(schema_path)' do
82
95
  it 'loads OpenAPI3' do
83
- s = Committee::Drivers.load_from_data(open_api_3_data)
96
+ s = Committee::Drivers.load_from_data(open_api_3_data, parser_options:{strict_reference_validation: false})
84
97
  assert_kind_of Committee::Drivers::Schema, s
85
98
  assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
86
99
  end