rspec-openapi 0.16.1 → 0.17.0

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: c69f9d896be2ad115cb158175dbcf2c1cba9b6d08a7214d23a107a67ec5fc529
4
- data.tar.gz: a5af92611c4b47790f165ce6d861bfdedd1214f5dcd9c5641e618f272fe5a7ca
3
+ metadata.gz: '04058c6bcfd8f9ec499d5c7eb82da1e1123bfd9a666056384cda5a39aa70e4b7'
4
+ data.tar.gz: a4df891dbf2ba621f1cf3a78dbfcaab22da75583a40ea974935ad6e9aad1dfa0
5
5
  SHA512:
6
- metadata.gz: 8e345e850fc539eb4e9fb018cdc48e7acadb47c774b47b438fcd1a95ebc680708999ae6d5440ee45f793bab47d27effd4e054fa3a08e25bf4e6956085effe9ea
7
- data.tar.gz: b1f47ba0a95186141f38465ac4e6a89636185606c48b8a0a67b7f163934c18181ea59e4c7fe94e54291aa821f662ee726437f350f69f872399063b024f7cbfde
6
+ metadata.gz: 9764345746f2c8133a18580eb1dffcf97709dd6e077b86e326f62604daffc856fd0c67e2735c7e8dbc16ae56828d9d3d9222cbc75f2f4a2e63789308df6ea4fd
7
+ data.tar.gz: e54bf06b9d2bd91952b56e91cc2cfcbae1cfb0998ab00a7019c4176b114a3652ef3e3323bf922530c2cf8e207742df6ff6fb6764be680ba8db7a8910bf260cdc
data/.rubocop_todo.yml CHANGED
@@ -1,35 +1,35 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-04-01 14:13:50 UTC using RuboCop version 1.62.1.
3
+ # on 2024-04-12 14:06:44 UTC using RuboCop version 1.62.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 11
9
+ # Offense count: 13
10
10
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
11
11
  Metrics/AbcSize:
12
- Max: 49
12
+ Max: 47
13
13
 
14
- # Offense count: 2
14
+ # Offense count: 1
15
15
  # Configuration parameters: CountComments, CountAsOne.
16
16
  Metrics/ClassLength:
17
17
  Max: 195
18
18
 
19
- # Offense count: 8
19
+ # Offense count: 9
20
20
  # Configuration parameters: AllowedMethods, AllowedPatterns.
21
21
  Metrics/CyclomaticComplexity:
22
- Max: 13
22
+ Max: 12
23
23
 
24
- # Offense count: 19
24
+ # Offense count: 22
25
25
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
26
26
  Metrics/MethodLength:
27
27
  Max: 36
28
28
 
29
- # Offense count: 4
29
+ # Offense count: 5
30
30
  # Configuration parameters: AllowedMethods, AllowedPatterns.
31
31
  Metrics/PerceivedComplexity:
32
- Max: 13
32
+ Max: 12
33
33
 
34
34
  # Offense count: 1
35
35
  # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
@@ -39,7 +39,7 @@ Naming/VariableNumber:
39
39
  Exclude:
40
40
  - 'spec/integration_tests/roda_test.rb'
41
41
 
42
- # Offense count: 6
42
+ # Offense count: 7
43
43
  # Configuration parameters: AllowedConstants.
44
44
  Style/Documentation:
45
45
  Exclude:
@@ -49,3 +49,4 @@ Style/Documentation:
49
49
  - 'lib/rspec/openapi/minitest_hooks.rb'
50
50
  - 'lib/rspec/openapi/result_recorder.rb'
51
51
  - 'lib/rspec/openapi/schema_file.rb'
52
+ - 'lib/rspec/openapi/shared_hooks.rb'
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rspec-openapi [![Gem Version](https://badge.fury.io/rb/rspec-openapi.svg)](https://badge.fury.io/rb/rspec-openapi) [![test](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml/badge.svg)](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/exoego/rspec-openapi/branch/master/graph/badge.svg?token=egYm6AlxkD)](https://codecov.io/gh/exoego/rspec-openapi)
1
+ # rspec-openapi [![Gem Version](https://badge.fury.io/rb/rspec-openapi.svg)](https://rubygems.org/gems/rspec-openapi) [![test](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml/badge.svg)](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/exoego/rspec-openapi/branch/master/graph/badge.svg?token=egYm6AlxkD)](https://codecov.io/gh/exoego/rspec-openapi) [![Ruby-toolbox](https://img.shields.io/badge/ruby-toolbox-a61414?cacheSeconds=31536000)](https://www.ruby-toolbox.com/projects/rspec-openapi)
2
2
 
3
3
  Generate OpenAPI schema from RSpec request specs.
4
4
 
@@ -97,7 +97,7 @@ paths:
97
97
 
98
98
  and the schema file can be used as an input of [Swagger UI](https://github.com/swagger-api/swagger-ui) or [Redoc](https://github.com/Redocly/redoc).
99
99
 
100
- ![Redoc example](./spec/rails/doc/screenshot.png)
100
+ ![Redoc example](./spec/apps/rails/doc/screenshot.png)
101
101
 
102
102
 
103
103
  ### Configuration
@@ -190,6 +190,13 @@ RSpec::OpenAPI.ignored_path_params = %i[controller action format]
190
190
  # In that case, you can specify the paths to ignore.
191
191
  # String or Regexp is acceptable.
192
192
  RSpec::OpenAPI.ignored_paths = ["/admin/full/path/", Regexp.new("^/_internal/")]
193
+
194
+ # Your custom post-processing hook (like unrandomizing IDs)
195
+ RSpec::OpenAPI.post_process_hook = -> (path, records, spec) do
196
+ RSpec::OpenAPI::HashHelper.matched_paths(spec, 'paths.*.*.responses.*.content.*.*.*.id').each do |paths|
197
+ spec.dig(*paths[0..-2]).merge!(id: '123')
198
+ end
199
+ end
193
200
  ```
194
201
 
195
202
  ### Can I use rspec-openapi with `$ref` to minimize duplication of schema?
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/inflector'
4
+ require 'hanami'
5
+
6
+ # https://github.com/hanami/router/blob/97f75b8529574bd4ff23165460e82a6587bc323c/lib/hanami/router/inspector.rb#L13
7
+ class Inspector
8
+ attr_accessor :routes, :inflector
9
+
10
+ def initialize(routes: [])
11
+ @routes = routes
12
+ @inflector = Dry::Inflector.new
13
+ end
14
+
15
+ def add_route(route)
16
+ routes.push(route)
17
+ end
18
+
19
+ def call(verb, path)
20
+ route = routes.find { |r| r.http_method == verb && r.path == path }
21
+
22
+ if route.to.is_a?(Proc)
23
+ {
24
+ tags: [],
25
+ summary: "#{verb} #{path}",
26
+ }
27
+ else
28
+ data = route.to.split('.')
29
+
30
+ {
31
+ tags: [inflector.classify(data[0])],
32
+ summary: data[1],
33
+ }
34
+ end
35
+ end
36
+ end
37
+
38
+ InspectorAnalyzer = Inspector.new
39
+
40
+ # Add default parameter to load inspector before test cases run
41
+ module InspectorAnalyzerPrepender
42
+ def router(inspector: InspectorAnalyzer)
43
+ super
44
+ end
45
+ end
46
+
47
+ Hanami::Slice::ClassMethods.prepend(InspectorAnalyzerPrepender)
48
+
49
+ # Extractor for hanami
50
+ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
51
+ # @param [RSpec::ExampleGroups::*] context
52
+ # @param [RSpec::Core::Example] example
53
+ # @return Array
54
+ def request_attributes(request, example)
55
+ metadata = example.metadata[:openapi] || {}
56
+ summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
57
+ tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
58
+ operation_id = metadata[:operation_id]
59
+ required_request_params = metadata[:required_request_params] || []
60
+ security = metadata[:security]
61
+ description = metadata[:description] || RSpec::OpenAPI.description_builder.call(example)
62
+ deprecated = metadata[:deprecated]
63
+ path = request.path
64
+
65
+ route = Hanami.app.router.recognize(request.path, method: request.method)
66
+
67
+ raw_path_params = route.params.filter { |_key, value| number_or_nil(value) }
68
+
69
+ result = InspectorAnalyzer.call(request.method, add_id(path, route))
70
+
71
+ summary ||= result[:summary]
72
+ tags ||= result[:tags]
73
+ path = add_openapi_id(path, route)
74
+
75
+ raw_path_params = raw_path_params.slice(*(raw_path_params.keys - RSpec::OpenAPI.ignored_path_params))
76
+
77
+ [path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated]
78
+ end
79
+
80
+ # @param [RSpec::ExampleGroups::*] context
81
+ def request_response(context)
82
+ request = ActionDispatch::Request.new(context.last_request.env)
83
+ request.body.rewind if request.body.respond_to?(:rewind)
84
+ response = ActionDispatch::TestResponse.new(*context.last_response.to_a)
85
+
86
+ [request, response]
87
+ end
88
+
89
+ def add_id(path, route)
90
+ return path if route.params.empty?
91
+
92
+ route.params.each_pair do |key, value|
93
+ next unless number_or_nil(value)
94
+
95
+ path = path.sub("/#{value}", "/:#{key}")
96
+ end
97
+
98
+ path
99
+ end
100
+
101
+ def add_openapi_id(path, route)
102
+ return path if route.params.empty?
103
+
104
+ route.params.each_pair do |key, value|
105
+ next unless number_or_nil(value)
106
+
107
+ path = path.sub("/#{value}", "/{#{key}}")
108
+ end
109
+
110
+ path
111
+ end
112
+
113
+ def number_or_nil(string)
114
+ Integer(string || '')
115
+ rescue ArgumentError
116
+ nil
117
+ end
118
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extractor for rack
4
+ class << RSpec::OpenAPI::Extractors::Rack = Object.new
5
+ # @param [RSpec::ExampleGroups::*] context
6
+ # @param [RSpec::Core::Example] example
7
+ # @return Array
8
+ def request_attributes(request, example)
9
+ metadata = example.metadata[:openapi] || {}
10
+ summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
11
+ tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
12
+ operation_id = metadata[:operation_id]
13
+ required_request_params = metadata[:required_request_params] || []
14
+ security = metadata[:security]
15
+ description = metadata[:description] || RSpec::OpenAPI.description_builder.call(example)
16
+ deprecated = metadata[:deprecated]
17
+ raw_path_params = request.path_parameters
18
+ path = request.path
19
+ summary ||= "#{request.method} #{path}"
20
+ [path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated]
21
+ end
22
+
23
+ # @param [RSpec::ExampleGroups::*] context
24
+ def request_response(context)
25
+ request = ActionDispatch::Request.new(context.last_request.env)
26
+ request.body.rewind if request.body.respond_to?(:rewind)
27
+ response = ActionDispatch::TestResponse.new(*context.last_response.to_a)
28
+
29
+ [request, response]
30
+ end
31
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extractor for rails
4
+ class << RSpec::OpenAPI::Extractors::Rails = Object.new
5
+ # @param [RSpec::ExampleGroups::*] context
6
+ # @param [RSpec::Core::Example] example
7
+ # @return Array
8
+ def request_attributes(request, example)
9
+ metadata = example.metadata[:openapi] || {}
10
+ summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
11
+ tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
12
+ operation_id = metadata[:operation_id]
13
+ required_request_params = metadata[:required_request_params] || []
14
+ security = metadata[:security]
15
+ description = metadata[:description] || RSpec::OpenAPI.description_builder.call(example)
16
+ deprecated = metadata[:deprecated]
17
+ raw_path_params = request.path_parameters
18
+
19
+ # Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
20
+ fixed_request = request.dup
21
+ fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
22
+
23
+ route, path = find_rails_route(fixed_request)
24
+ raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
25
+
26
+ path = path.delete_suffix('(.:format)')
27
+ summary ||= route.requirements[:action]
28
+ tags ||= [route.requirements[:controller]&.classify].compact
29
+ # :controller and :action always exist. :format is added when routes is configured as such.
30
+ # TODO: Use .except(:controller, :action, :format) when we drop support for Ruby 2.x
31
+ raw_path_params = raw_path_params.slice(*(raw_path_params.keys - RSpec::OpenAPI.ignored_path_params))
32
+
33
+ summary ||= "#{request.method} #{path}"
34
+
35
+ [path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated]
36
+ end
37
+
38
+ # @param [RSpec::ExampleGroups::*] context
39
+ def request_response(context)
40
+ [context.request, context.response]
41
+ end
42
+
43
+ # @param [ActionDispatch::Request] request
44
+ def find_rails_route(request, app: Rails.application, path_prefix: '')
45
+ app.routes.router.recognize(request) do |route|
46
+ path = route.path.spec.to_s
47
+ if route.app.matches?(request)
48
+ if route.app.engine?
49
+ route, path = find_rails_route(request, app: route.app.app, path_prefix: path)
50
+ next if route.nil?
51
+ end
52
+ return [route, path_prefix + path]
53
+ end
54
+ end
55
+
56
+ nil
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create namespace
4
+ module RSpec::OpenAPI::Extractors
5
+ end
@@ -13,7 +13,7 @@ module RSpec::OpenAPI::Minitest
13
13
  human_name = name.sub(/^test_/, '').gsub('_', ' ')
14
14
  example = Example.new(self, human_name, {}, file_path)
15
15
  path = RSpec::OpenAPI.path.then { |p| p.is_a?(Proc) ? p.call(example) : p }
16
- record = RSpec::OpenAPI::RecordBuilder.build(self, example: example)
16
+ record = RSpec::OpenAPI::RecordBuilder.build(self, example: example, extractor: SharedHooks.find_extractor)
17
17
  RSpec::OpenAPI.path_records[path] << record if record
18
18
  end
19
19
  result
@@ -7,12 +7,12 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
7
7
  # @param [RSpec::ExampleGroups::*] context
8
8
  # @param [RSpec::Core::Example] example
9
9
  # @return [RSpec::OpenAPI::Record,nil]
10
- def build(context, example:)
11
- request, response = extract_request_response(context)
10
+ def build(context, example:, extractor:)
11
+ request, response = extractor.request_response(context)
12
12
  return if request.nil?
13
13
 
14
14
  path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated =
15
- extract_request_attributes(request, example)
15
+ extractor.request_attributes(request, example)
16
16
 
17
17
  return if RSpec::OpenAPI.ignored_paths.any? { |ignored_path| path.match?(ignored_path) }
18
18
 
@@ -69,71 +69,6 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
69
69
  [request_headers, response_headers]
70
70
  end
71
71
 
72
- def extract_request_attributes(request, example)
73
- metadata = example.metadata[:openapi] || {}
74
- summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
75
- tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
76
- operation_id = metadata[:operation_id]
77
- required_request_params = metadata[:required_request_params] || []
78
- security = metadata[:security]
79
- description = metadata[:description] || RSpec::OpenAPI.description_builder.call(example)
80
- deprecated = metadata[:deprecated]
81
- raw_path_params = request.path_parameters
82
- path = request.path
83
- if rails?
84
- # Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
85
- fixed_request = request.dup
86
- fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
87
-
88
- route, path = find_rails_route(fixed_request)
89
- raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
90
-
91
- path = path.delete_suffix('(.:format)')
92
- summary ||= route.requirements[:action]
93
- tags ||= [route.requirements[:controller]&.classify].compact
94
- # :controller and :action always exist. :format is added when routes is configured as such.
95
- # TODO: Use .except(:controller, :action, :format) when we drop support for Ruby 2.x
96
- raw_path_params = raw_path_params.slice(*(raw_path_params.keys - RSpec::OpenAPI.ignored_path_params))
97
- end
98
- summary ||= "#{request.method} #{path}"
99
- [path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated]
100
- end
101
-
102
- def extract_request_response(context)
103
- if rack_test?(context)
104
- request = ActionDispatch::Request.new(context.last_request.env)
105
- request.body.rewind if request.body.respond_to?(:rewind)
106
- response = ActionDispatch::TestResponse.new(*context.last_response.to_a)
107
- else
108
- request = context.request
109
- response = context.response
110
- end
111
- [request, response]
112
- end
113
-
114
- def rails?
115
- defined?(Rails) && Rails.respond_to?(:application) && Rails.application
116
- end
117
-
118
- def rack_test?(context)
119
- defined?(Rack::Test::Methods) && context.class < Rack::Test::Methods
120
- end
121
-
122
- # @param [ActionDispatch::Request] request
123
- def find_rails_route(request, app: Rails.application, path_prefix: '')
124
- app.routes.router.recognize(request) do |route|
125
- path = route.path.spec.to_s
126
- if route.app.matches?(request)
127
- if route.app.engine?
128
- route, path = find_rails_route(request, app: route.app.app, path_prefix: path)
129
- next if route.nil?
130
- end
131
- return [route, path_prefix + path]
132
- end
133
- end
134
- nil
135
- end
136
-
137
72
  # workaround to get real request parameters
138
73
  # because ActionController::ParamsWrapper overwrites request_parameters
139
74
  def raw_request_params(request)
@@ -29,11 +29,8 @@ class RSpec::OpenAPI::ResultRecorder
29
29
  rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
30
30
  @error_records[e] = record # Avoid failing the build
31
31
  end
32
- RSpec::OpenAPI::SchemaCleaner.cleanup_conflicting_security_parameters!(spec)
33
- RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
34
- RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
35
- RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
36
- RSpec::OpenAPI::SchemaSorter.deep_sort!(spec)
32
+ cleanup_schema!(new_from_zero, spec)
33
+ execute_post_process_hook(path, records, spec)
37
34
  end
38
35
  end
39
36
  end
@@ -49,4 +46,18 @@ class RSpec::OpenAPI::ResultRecorder
49
46
  #{@error_records.map { |e, record| "#{e.inspect}: #{record.inspect}" }.join("\n")}
50
47
  ERR_MSG
51
48
  end
49
+
50
+ private
51
+
52
+ def execute_post_process_hook(path, records, spec)
53
+ RSpec::OpenAPI.post_process_hook.call(path, records, spec) if RSpec::OpenAPI.post_process_hook.is_a?(Proc)
54
+ end
55
+
56
+ def cleanup_schema!(new_from_zero, spec)
57
+ RSpec::OpenAPI::SchemaCleaner.cleanup_conflicting_security_parameters!(spec)
58
+ RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
59
+ RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
60
+ RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
61
+ RSpec::OpenAPI::SchemaSorter.deep_sort!(spec)
62
+ end
52
63
  end
@@ -5,7 +5,7 @@ require 'rspec/core'
5
5
  RSpec.configuration.after(:each) do |example|
6
6
  if RSpec::OpenAPI.example_types.include?(example.metadata[:type]) && example.metadata[:openapi] != false
7
7
  path = RSpec::OpenAPI.path.then { |p| p.is_a?(Proc) ? p.call(example) : p }
8
- record = RSpec::OpenAPI::RecordBuilder.build(self, example: example)
8
+ record = RSpec::OpenAPI::RecordBuilder.build(self, example: example, extractor: SharedHooks.find_extractor)
9
9
  RSpec::OpenAPI.path_records[path] << record if record
10
10
  end
11
11
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SharedHooks
4
+ def self.find_extractor
5
+ if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
6
+ RSpec::OpenAPI::Extractors::Rails
7
+ elsif defined?(Hanami) && Hanami.respond_to?(:app) && Hanami.app?
8
+ RSpec::OpenAPI::Extractors::Hanami
9
+ # elsif defined?(Roda)
10
+ # some Roda extractor
11
+ else
12
+ RSpec::OpenAPI::Extractors::Rack
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenAPI
5
- VERSION = '0.16.1'
5
+ VERSION = '0.17.0'
6
6
  end
7
7
  end
data/lib/rspec/openapi.rb CHANGED
@@ -11,6 +11,23 @@ require 'rspec/openapi/schema_merger'
11
11
  require 'rspec/openapi/schema_cleaner'
12
12
  require 'rspec/openapi/schema_sorter'
13
13
  require 'rspec/openapi/key_transformer'
14
+ require 'rspec/openapi/shared_hooks'
15
+ require 'rspec/openapi/extractors'
16
+ require 'rspec/openapi/extractors/rack'
17
+
18
+ begin
19
+ require 'hanami'
20
+ require 'rspec/openapi/extractors/hanami'
21
+ rescue LoadError
22
+ puts 'Hanami not detected'
23
+ end
24
+
25
+ begin
26
+ require 'rails'
27
+ require 'rspec/openapi/extractors/rails'
28
+ rescue LoadError
29
+ puts 'Rails not detected'
30
+ end
14
31
 
15
32
  require 'rspec/openapi/minitest_hooks' if Object.const_defined?('Minitest')
16
33
  require 'rspec/openapi/rspec_hooks' if ENV['OPENAPI'] && Object.const_defined?('RSpec')
@@ -33,6 +50,7 @@ module RSpec::OpenAPI
33
50
  @path_records = Hash.new { |h, k| h[k] = [] }
34
51
  @ignored_path_params = %i[controller action format]
35
52
  @ignored_paths = []
53
+ @post_process_hook = nil
36
54
 
37
55
  # This is the configuraion override file name we look for within each path.
38
56
  @config_filename = 'rspec_openapi.rb'
@@ -54,7 +72,8 @@ module RSpec::OpenAPI
54
72
  :response_headers,
55
73
  :path_records,
56
74
  :ignored_paths,
57
- :ignored_path_params
75
+ :ignored_path_params,
76
+ :post_process_hook
58
77
 
59
78
  attr_reader :config_filename
60
79
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-openapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-04-01 00:00:00.000000000 Z
12
+ date: 2024-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -80,6 +80,10 @@ files:
80
80
  - lib/rspec/openapi.rb
81
81
  - lib/rspec/openapi/components_updater.rb
82
82
  - lib/rspec/openapi/default_schema.rb
83
+ - lib/rspec/openapi/extractors.rb
84
+ - lib/rspec/openapi/extractors/hanami.rb
85
+ - lib/rspec/openapi/extractors/rack.rb
86
+ - lib/rspec/openapi/extractors/rails.rb
83
87
  - lib/rspec/openapi/hash_helper.rb
84
88
  - lib/rspec/openapi/key_transformer.rb
85
89
  - lib/rspec/openapi/minitest_hooks.rb
@@ -92,6 +96,7 @@ files:
92
96
  - lib/rspec/openapi/schema_file.rb
93
97
  - lib/rspec/openapi/schema_merger.rb
94
98
  - lib/rspec/openapi/schema_sorter.rb
99
+ - lib/rspec/openapi/shared_hooks.rb
95
100
  - lib/rspec/openapi/version.rb
96
101
  - rspec-openapi.gemspec
97
102
  - scripts/rspec
@@ -103,7 +108,7 @@ licenses:
103
108
  metadata:
104
109
  homepage_uri: https://github.com/exoego/rspec-openapi
105
110
  source_code_uri: https://github.com/exoego/rspec-openapi
106
- changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.16.1
111
+ changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.17.0
107
112
  rubygems_mfa_required: 'true'
108
113
  post_install_message:
109
114
  rdoc_options: []