rspec-openapi 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86927b142ea56ae6b4c2c4f70c1cf8d21159b85f614369d4af15c91489e56647
4
- data.tar.gz: 3711fffd6052537911f4bfaafdb2d22fba78a1649f71c97f16325d79ccc3d427
3
+ metadata.gz: 9749f7a6121a78737336bd436f5fda8b20381a82f4cb507f42667bf3d38a2a4b
4
+ data.tar.gz: ff0bc4a559323f1285d282ab786b5666c950b8ad0b9585fa749cf1f2b0f3613e
5
5
  SHA512:
6
- metadata.gz: 7a54a6a78f142fc39b7a4ad5a5afd92e2486ba320e414e0782f0eb2c386535588e6126c851d868b265807a29844706547a6757fb1d45a2eb1cda820923fa7c15
7
- data.tar.gz: b53892f024ecb7733fb99e83ab1c299d3ae0b36465a2ca806d1234896a90fd45bf47df335bc14977004aa8c113c272daadf029b4c0c7ad46773be1ad5e2dec0e
6
+ metadata.gz: 4e412c58158ffaa1518640e3082ef04c41d50ec43de94ef032c866ebbec2468775d4ea3b2c976294f14ce6b8570b3e86df7248f17877c491efa9fc31e5a8819a
7
+ data.tar.gz: 65d7308f7d552d9ac299a6d3330933283c237345b477de260a2e2af24210268f2e41350619cec83f145f028a7374b197281cbd9752d1cb2aa3baa696f8240739
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "monthly"
7
+ labels:
8
+ - "chore"
@@ -25,7 +25,7 @@ jobs:
25
25
 
26
26
  steps:
27
27
  - name: Checkout repository
28
- uses: actions/checkout@v3
28
+ uses: actions/checkout@v4
29
29
 
30
30
  - name: Initialize CodeQL
31
31
  uses: github/codeql-action/init@v2
@@ -14,7 +14,7 @@ jobs:
14
14
 
15
15
  steps:
16
16
  - name: Checkout repository
17
- uses: actions/checkout@v3
17
+ uses: actions/checkout@v4
18
18
 
19
19
  - name: Set up Ruby
20
20
  uses: ruby/setup-ruby@v1
@@ -26,11 +26,24 @@ jobs:
26
26
  rails: 6.1.6
27
27
  - ruby: ruby:3.1
28
28
  rails: 7.0.3
29
+ coverage: coverage
29
30
  env:
30
31
  RAILS_VERSION: ${{ matrix.rails == '' && '6.1.6' || matrix.rails }}
32
+ COVERAGE: ${{ matrix.coverage || '' }}
31
33
  steps:
32
- - uses: actions/checkout@v2
34
+ - uses: actions/checkout@v4
33
35
  - name: bundle install
34
36
  run: bundle install -j$(nproc) --retry 3
37
+ - name: install simplecov-fork only for minitest with coverage
38
+ run: |
39
+ gem install specific_install
40
+ gem specific_install https://github.com/exoego/simplecov.git branch-fix
41
+ if: matrix.coverage == 'coverage'
35
42
  - run: bundle exec rspec
36
43
  timeout-minutes: 1
44
+ - name: Upload coverage reports
45
+ uses: codecov/codecov-action@v3
46
+ if: matrix.coverage == 'coverage'
47
+ with:
48
+ fail_ci_if_error: true
49
+ files: ./coverage/coverage.xml
data/.rubocop.yml CHANGED
@@ -17,6 +17,8 @@ Style/ClassAndModuleChildren:
17
17
  EnforcedStyle: compact
18
18
  Exclude:
19
19
  - 'lib/rspec/openapi/version.rb'
20
+ Layout/FirstArrayElementIndentation:
21
+ EnforcedStyle: consistent
20
22
  Metrics/BlockLength:
21
23
  Exclude:
22
24
  - 'spec/**/*'
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless ENV['COVERAGE'] && ENV['COVERAGE'].empty?
4
+ require 'simplecov'
5
+ require 'simplecov-cobertura'
6
+
7
+ SimpleCov.at_fork.call(Process.pid)
8
+ SimpleCov.formatter SimpleCov::Formatter::MultiFormatter.new([
9
+ SimpleCov::Formatter::CoberturaFormatter,
10
+ ])
11
+ SimpleCov.start do
12
+ enable_coverage :branch
13
+ add_filter '/spec/'
14
+ add_filter '/scripts/'
15
+ end
16
+ end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## v0.10.0
2
+ - bugfix: Merge parameter data to preserve description in manually edited Openapi spec
3
+ [#149](https://github.com/exoego/rspec-openapi/pull/149)
4
+ - feat: Add ability to configure which path params to ignore
5
+ [#150](https://github.com/exoego/rspec-openapi/pull/150)
6
+ - feat: Add custom title
7
+ [#147](https://github.com/exoego/rspec-openapi/pull/147)
8
+ - feat: Add ability to define custom summary and tags builders
9
+ [#148](https://github.com/exoego/rspec-openapi/pull/148)
10
+ - enhancement: Sort paths lexicographically so the order of paths is more stable and predictable
11
+ [#155](https://github.com/exoego/rspec-openapi/pull/155)
12
+ - enhancement: requestBody should not merge requestBody from error examples
13
+ [#154](https://github.com/exoego/rspec-openapi/pull/154)
14
+
15
+ ## v0.9.0
16
+ - bugfix: Fix engine path resolution
17
+ [#113](https://github.com/exoego/rspec-openapi/pull/113)
18
+ - bugfix: fix multiple uploaded files
19
+ [#117](https://github.com/exoego/rspec-openapi/pull/117), [#126](https://github.com/exoego/rspec-openapi/pull/126)
20
+ - feat: Add required_request_params to metadata
21
+ [#114](https://github.com/exoego/rspec-openapi/pull/114)
22
+ - bugfix(minitest):
23
+ [#128](https://github.com/exoego/rspec-openapi/pull/128)
24
+ - doc(minitest): Add instructions for minitest triggered yaml generation
25
+ [#116](https://github.com/exoego/rspec-openapi/pull/116)
26
+ - chore: Don't dump records into temporary file
27
+ [#127](https://github.com/exoego/rspec-openapi/pull/127)
28
+
1
29
  ## v0.8.1
2
30
  - bugfix: Empty `required` array should not be present.
3
31
  [#111](https://github.com/exoego/rspec-openapi/pull/111)
data/Gemfile CHANGED
@@ -10,6 +10,8 @@ gem 'roda'
10
10
  gem 'rspec-rails'
11
11
 
12
12
  group :test do
13
+ gem 'simplecov', git: 'https://github.com/exoego/simplecov.git', branch: 'branch-fix'
14
+ gem 'simplecov-cobertura'
13
15
  gem 'super_diff'
14
16
  end
15
17
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rspec-openapi ![test](https://github.com/k0kubun/rspec-openapi/workflows/test/badge.svg)
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)
2
2
 
3
3
  Generate OpenAPI schema from RSpec request specs.
4
4
 
@@ -122,6 +122,8 @@ RSpec::OpenAPI.path = -> (example) {
122
122
  end
123
123
  }
124
124
 
125
+ RSpec::OpenAPI.title = 'OpenAPI Documentation'
126
+
125
127
  # Disable generating `example`
126
128
  RSpec::OpenAPI.enable_example = false
127
129
 
@@ -167,8 +169,21 @@ EOS
167
169
  # Generate a custom description, given an RSpec example
168
170
  RSpec::OpenAPI.description_builder = -> (example) { example.description }
169
171
 
172
+ # Generate a custom summary, given an RSpec example
173
+ # This example uses the summary from the example_group.
174
+ RSpec::OpenAPI.summary_builder = ->(example) { example.metadata.dig(:example_group, :openapi, :summary) }
175
+
176
+ # Generate a custom tags, given an RSpec example
177
+ # This example uses the tags from the parent_example_group
178
+ RSpec::OpenAPI.tags_builder = -> (example) { example.metadata.dig(:example_group, :parent_example_group, :openapi, :tags) }
179
+
170
180
  # Change the example type(s) that will generate schema
171
181
  RSpec::OpenAPI.example_types = %i[request]
182
+
183
+ # Configure which path params to ignore
184
+ # :controller and :action always exist. :format is added when routes is configured as such.
185
+ RSpec::OpenAPI.ignored_path_params = %i[controller action format]
186
+
172
187
  ```
173
188
 
174
189
  ### Can I use rspec-openapi with `$ref` to minimize duplication of schema?
@@ -199,7 +214,7 @@ paths:
199
214
  application/json:
200
215
  schema:
201
216
  $ref: "#/components/schemas/User"
202
- # Note) #/components/schamas is not needed to be defined.
217
+ # Note) #/components/schemas is not needed to be defined.
203
218
  ```
204
219
 
205
220
  3. Then, re-run rspec-openapi. It will generate `#/components/schemas` with the referenced schema (`User` for example) newly-generated or updated.
@@ -278,7 +293,7 @@ If you find a room for improvement, open an issue.
278
293
 
279
294
  ### How can I add information which can't be generated from RSpec?
280
295
 
281
- rspec-openapi tries to keep manual modifications as much as possible when generating specs.
296
+ rspec-openapi tries to preserve manual modifications as much as possible when generating specs.
282
297
  You can directly edit `doc/openapi.yaml` as you like without spoiling the automatic generation capability.
283
298
 
284
299
  ### Can I exclude specific specs from OpenAPI generation?
@@ -308,6 +323,7 @@ Some examples' attributes can be overwritten via RSpec metadata options. Example
308
323
  summary: 'list all posts',
309
324
  description: 'list all posts ordered by pub_date',
310
325
  tags: %w[v1 posts],
326
+ required_request_params: %w[limit],
311
327
  security: [{"MyToken" => []}],
312
328
  } do
313
329
  # ...
@@ -344,6 +360,12 @@ It should work with both classes inheriting from `ActionDispatch::IntegrationTes
344
360
 
345
361
  Please note that not all features present in the rspec integration work with minitest (yet). For example, custom per test case metadata is not supported. A custom `description_builder` will not work either.
346
362
 
363
+ Run minitest with OPENAPI=1 to generate `doc/openapi.yaml` for your request specs.
364
+
365
+ ```bash
366
+ $ OPENAPI=1 bundle exec rails t
367
+ ```
368
+
347
369
  ## Links
348
370
 
349
371
  Existing RSpec plugins which have OpenAPI integration:
@@ -5,11 +5,7 @@ require 'minitest'
5
5
  module RSpec::OpenAPI::Minitest
6
6
  Example = Struct.new(:context, :description, :metadata, :file_path)
7
7
 
8
- module TestPatch
9
- def self.prepended(base)
10
- base.extend(ClassMethods)
11
- end
12
-
8
+ module RunPatch
13
9
  def run(*args)
14
10
  result = super
15
11
  if ENV['OPENAPI'] && self.class.openapi?
@@ -22,6 +18,12 @@ module RSpec::OpenAPI::Minitest
22
18
  end
23
19
  result
24
20
  end
21
+ end
22
+
23
+ module ActivateOpenApiClassMethods
24
+ def self.prepended(base)
25
+ base.extend(ClassMethods)
26
+ end
25
27
 
26
28
  module ClassMethods
27
29
  def openapi?
@@ -35,10 +37,12 @@ module RSpec::OpenAPI::Minitest
35
37
  end
36
38
  end
37
39
 
38
- Minitest::Test.prepend RSpec::OpenAPI::Minitest::TestPatch
40
+ Minitest::Test.prepend RSpec::OpenAPI::Minitest::ActivateOpenApiClassMethods
41
+
42
+ if ENV['OPENAPI']
43
+ Minitest::Test.prepend RSpec::OpenAPI::Minitest::RunPatch
39
44
 
40
- Minitest.after_run do
41
- if ENV['OPENAPI']
45
+ Minitest.after_run do
42
46
  result_recorder = RSpec::OpenAPI::ResultRecorder.new(RSpec::OpenAPI.path_records)
43
47
  result_recorder.record_results!
44
48
  puts result_record.error_message if result_recorder.errors?
@@ -6,10 +6,12 @@ RSpec::OpenAPI::Record = Struct.new(
6
6
  :path_params, # @param [Hash] - {:controller=>"v1/statuses", :action=>"create", :id=>"1"}
7
7
  :query_params, # @param [Hash] - {:query=>"string"}
8
8
  :request_params, # @param [Hash] - {:request=>"body"}
9
+ :required_request_params, # @param [Array] - ["param1", "param2"]
9
10
  :request_content_type, # @param [String] - "application/json"
10
11
  :request_headers, # @param [Array] - [["header_key1", "header_value1"], ["header_key2", "header_value2"]]
11
12
  :summary, # @param [String] - "v1/statuses #show"
12
13
  :tags, # @param [Array] - ["Status"]
14
+ :operation_id, # @param [String] - "request-1234"
13
15
  :description, # @param [String] - "returns a status"
14
16
  :security, # @param [Array] - [{securityScheme1: []}]
15
17
  :status, # @param [Integer] - 200
@@ -11,7 +11,8 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
11
11
  request, response = extract_request_response(context)
12
12
  return if request.nil?
13
13
 
14
- path, summary, tags, raw_path_params, description, security = extract_request_attributes(request, example)
14
+ path, summary, tags, operation_id, required_request_params, raw_path_params, description, security =
15
+ extract_request_attributes(request, example)
15
16
 
16
17
  request_headers, response_headers = extract_headers(request, response)
17
18
 
@@ -21,10 +22,12 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
21
22
  path_params: raw_path_params,
22
23
  query_params: request.query_parameters,
23
24
  request_params: raw_request_params(request),
25
+ required_request_params: required_request_params,
24
26
  request_content_type: request.media_type,
25
27
  request_headers: request_headers,
26
28
  summary: summary,
27
29
  tags: tags,
30
+ operation_id: operation_id,
28
31
  description: description,
29
32
  security: security,
30
33
  status: response.status,
@@ -59,23 +62,31 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
59
62
 
60
63
  def extract_request_attributes(request, example)
61
64
  metadata = example.metadata[:openapi] || {}
62
- summary = metadata[:summary]
63
- tags = metadata[:tags]
65
+ summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
66
+ tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
67
+ operation_id = metadata[:operation_id]
68
+ required_request_params = metadata[:required_request_params] || []
64
69
  security = metadata[:security]
65
70
  description = metadata[:description] || RSpec::OpenAPI.description_builder.call(example)
66
71
  raw_path_params = request.path_parameters
67
72
  path = request.path
68
73
  if rails?
69
- route = find_rails_route(request)
70
- path = route.path.spec.to_s.delete_suffix('(.:format)')
74
+ # 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
75
+ fixed_request = request.dup
76
+ fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
77
+
78
+ route, path = find_rails_route(fixed_request)
79
+ raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
80
+
81
+ path = path.delete_suffix('(.:format)')
71
82
  summary ||= route.requirements[:action]
72
83
  tags ||= [route.requirements[:controller]&.classify].compact
73
84
  # :controller and :action always exist. :format is added when routes is configured as such.
74
85
  # TODO: Use .except(:controller, :action, :format) when we drop support for Ruby 2.x
75
- raw_path_params = raw_path_params.slice(*(raw_path_params.keys - %i[controller action format]))
86
+ raw_path_params = raw_path_params.slice(*(raw_path_params.keys - RSpec::OpenAPI.ignored_path_params))
76
87
  end
77
88
  summary ||= "#{request.method} #{path}"
78
- [path, summary, tags, raw_path_params, description, security]
89
+ [path, summary, tags, operation_id, required_request_params, raw_path_params, description, security]
79
90
  end
80
91
 
81
92
  def extract_request_response(context)
@@ -99,21 +110,18 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
99
110
  end
100
111
 
101
112
  # @param [ActionDispatch::Request] request
102
- def find_rails_route(request, app: Rails.application, fix_path: true)
103
- # 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
104
- if fix_path && !request.script_name.empty?
105
- request = request.dup
106
- request.path_info = File.join(request.script_name, request.path_info)
107
- end
108
-
113
+ def find_rails_route(request, app: Rails.application, path_prefix: '')
109
114
  app.routes.router.recognize(request) do |route|
115
+ path = route.path.spec.to_s
110
116
  if route.app.matches?(request)
111
- return find_rails_route(request, app: route.app.app, fix_path: false) if route.app.engine?
112
-
113
- return route
117
+ if route.app.engine?
118
+ route, path = find_rails_route(request, app: route.app.app, path_prefix: path)
119
+ next if route.nil?
120
+ end
121
+ return [route, path_prefix + path]
114
122
  end
115
123
  end
116
- raise "No route matched for #{request.request_method} #{request.path_info}"
124
+ nil
117
125
  end
118
126
 
119
127
  # workaround to get real request parameters
@@ -7,7 +7,7 @@ class RSpec::OpenAPI::ResultRecorder
7
7
  end
8
8
 
9
9
  def record_results!
10
- title = File.basename(Dir.pwd)
10
+ title = RSpec::OpenAPI.title
11
11
  @path_records.each do |path, records|
12
12
  RSpec::OpenAPI::SchemaFile.new(path).edit do |spec|
13
13
  schema = RSpec::OpenAPI::DefaultSchema.build(title)
@@ -15,7 +15,6 @@ class RSpec::OpenAPI::ResultRecorder
15
15
  RSpec::OpenAPI::SchemaMerger.merge!(spec, schema)
16
16
  new_from_zero = {}
17
17
  records.each do |record|
18
- File.open('/tmp/records', 'a') { |f| f.puts record.to_yaml }
19
18
  begin
20
19
  record_schema = RSpec::OpenAPI::SchemaBuilder.build(record)
21
20
  RSpec::OpenAPI::SchemaMerger.merge!(spec, record_schema)
@@ -27,6 +26,7 @@ class RSpec::OpenAPI::ResultRecorder
27
26
  RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
28
27
  RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
29
28
  RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
29
+ RSpec::OpenAPI::SchemaCleaner.sort_paths!(spec)
30
30
  end
31
31
  end
32
32
  end
@@ -27,6 +27,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
27
27
  record.http_method.downcase => {
28
28
  summary: record.summary,
29
29
  tags: record.tags,
30
+ operationId: record.operation_id,
30
31
  security: record.security,
31
32
  parameters: build_parameters(record),
32
33
  requestBody: build_request_body(record),
@@ -73,6 +74,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
73
74
  parameters << {
74
75
  name: build_parameter_name(key, value),
75
76
  in: 'query',
77
+ required: record.required_request_params.include?(key),
76
78
  schema: build_property(try_cast(value)),
77
79
  example: (try_cast(value) if example_enabled?),
78
80
  }.compact
@@ -118,6 +120,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
118
120
  def build_request_body(record)
119
121
  return nil if record.request_content_type.nil?
120
122
  return nil if record.request_params.empty?
123
+ return nil if record.status >= 400
121
124
 
122
125
  {
123
126
  content: {
@@ -191,10 +194,23 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
191
194
 
192
195
  def adjust_params(value)
193
196
  value.each do |key, v|
194
- if v.is_a?(ActionDispatch::Http::UploadedFile)
197
+ case v
198
+ when ActionDispatch::Http::UploadedFile
195
199
  value[key] = v.original_filename
196
- elsif v.is_a?(Hash)
200
+ when Hash
197
201
  adjust_params(v)
202
+ when Array
203
+ result = v.map do |item|
204
+ case item
205
+ when ActionDispatch::Http::UploadedFile
206
+ item.original_filename
207
+ when Hash
208
+ adjust_params(item)
209
+ else
210
+ item
211
+ end
212
+ end
213
+ value[key] = result
198
214
  end
199
215
  end
200
216
  end
@@ -47,10 +47,17 @@ class << RSpec::OpenAPI::SchemaCleaner = Object.new
47
47
  paths_to_objects.each do |path|
48
48
  parent = base.dig(*path.take(path.length - 1))
49
49
  # "required" array must not be present if empty
50
- parent.delete('required') if parent['required'].empty?
50
+ parent.delete('required') if parent['required'] && parent['required'].empty?
51
51
  end
52
52
  end
53
53
 
54
+ # Sort "paths" lexicographically to make the order more predictable
55
+ #
56
+ # @param [Hash] #
57
+ def sort_paths!(spec)
58
+ spec['paths'] = spec['paths']&.entries&.sort_by! { |path, _| path }.to_h
59
+ end
60
+
54
61
  private
55
62
 
56
63
  def cleanup_array!(base, spec, selector, fields_for_identity = [])
@@ -43,16 +43,28 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
43
43
  end
44
44
 
45
45
  def merge_arrays(base, key, value)
46
- case key
47
- when 'parameters'
48
- base[key] = value | base[key]
49
- base[key].uniq! { |param| param.slice('name', 'in') }
50
- when 'required'
51
- # Preserve properties that appears in all test cases
52
- base[key] = value & base[key]
53
- else
54
- # last one wins
55
- base[key] = value
46
+ base[key] = case key
47
+ when 'parameters'
48
+ merge_parameters(base, key, value)
49
+ when 'required'
50
+ # Preserve properties that appears in all test cases
51
+ value & base[key]
52
+ else
53
+ # last one wins
54
+ value
55
+ end
56
+ end
57
+
58
+ def merge_parameters(base, key, value)
59
+ all_parameters = value | base[key]
60
+
61
+ unique_base_parameters = base[key].index_by { |parameter| [parameter['name'], parameter['in']] }
62
+ all_parameters = all_parameters.map do |parameter|
63
+ base_parameter = unique_base_parameters[[parameter['name'], parameter['in']]] || {}
64
+ base_parameter ? base_parameter.merge(parameter) : parameter
56
65
  end
66
+
67
+ all_parameters.uniq! { |param| param.slice('name', 'in') }
68
+ base[key] = all_parameters
57
69
  end
58
70
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenAPI
5
- VERSION = '0.8.1'
5
+ VERSION = '0.10.0'
6
6
  end
7
7
  end
data/lib/rspec/openapi.rb CHANGED
@@ -10,16 +10,17 @@ require 'rspec/openapi/schema_file'
10
10
  require 'rspec/openapi/schema_merger'
11
11
  require 'rspec/openapi/schema_cleaner'
12
12
 
13
- if ENV['OPENAPI']
14
- require 'rspec/openapi/minitest_hooks'
15
- require 'rspec/openapi/rspec_hooks'
16
- end
13
+ require 'rspec/openapi/minitest_hooks' if Object.const_defined?('Minitest')
14
+ require 'rspec/openapi/rspec_hooks' if ENV['OPENAPI'] && Object.const_defined?('RSpec')
17
15
 
18
16
  module RSpec::OpenAPI
19
17
  @path = 'doc/openapi.yaml'
18
+ @title = File.basename(Dir.pwd)
20
19
  @comment = nil
21
20
  @enable_example = true
22
21
  @description_builder = ->(example) { example.description }
22
+ @summary_builder = ->(example) { example.metadata[:summary] }
23
+ @tags_builder = ->(example) { example.metadata[:tags] }
23
24
  @info = {}
24
25
  @application_version = '1.0.0'
25
26
  @request_headers = []
@@ -28,12 +29,16 @@ module RSpec::OpenAPI
28
29
  @example_types = %i[request]
29
30
  @response_headers = []
30
31
  @path_records = Hash.new { |h, k| h[k] = [] }
32
+ @ignored_path_params = %i[controller action format]
31
33
 
32
34
  class << self
33
35
  attr_accessor :path,
36
+ :title,
34
37
  :comment,
35
38
  :enable_example,
36
39
  :description_builder,
40
+ :summary_builder,
41
+ :tags_builder,
37
42
  :info,
38
43
  :application_version,
39
44
  :request_headers,
@@ -41,6 +46,7 @@ module RSpec::OpenAPI
41
46
  :security_schemes,
42
47
  :example_types,
43
48
  :response_headers,
44
- :path_records
49
+ :path_records,
50
+ :ignored_path_params
45
51
  end
46
52
  end
data/scripts/rspec ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # (The MIT License)
5
+ # Copyright (c) 2012 Chad Humphries, David Chelimsky, Myron Marston
6
+ # Copyright (c) 2009 Chad Humphries, David Chelimsky
7
+ # Copyright (c) 2006 David Chelimsky, The RSpec Development Team
8
+ # Copyright (c) 2005 Steven Baker
9
+
10
+ require 'rspec/core'
11
+ RSpec::Core::Runner.invoke
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # (The MIT License)
5
+ # Copyright (c) 2012 Chad Humphries, David Chelimsky, Myron Marston
6
+ # Copyright (c) 2009 Chad Humphries, David Chelimsky
7
+ # Copyright (c) 2006 David Chelimsky, The RSpec Development Team
8
+ # Copyright (c) 2005 Steven Baker
9
+
10
+ # Turn on verbose to make sure we not generating any ruby warning
11
+ $VERBOSE = true
12
+
13
+ # So our "did they run the rspec command?" detection logic thinks
14
+ # that we run `rspec`.
15
+ $0 = 'rspec'
16
+
17
+ # This is necessary for when `--standalone` is being used.
18
+ $LOAD_PATH.unshift File.expand_path '../bundle', __dir__
19
+
20
+ # For the travis build we put the bundle directory up a directory
21
+ # so it can be shared among the repos for faster bundle installs.
22
+ $LOAD_PATH.unshift File.expand_path '../../bundle', __dir__
23
+
24
+ require 'bundler/setup'
25
+
26
+ # To use simplecov while running rspec-core's test suite, we must
27
+ # load simplecov _before_ loading any of rspec-core's files.
28
+ # So, this executable exists purely as a wrapper script that
29
+ # first loads simplecov, and then loads rspec.
30
+ begin
31
+ # Simplecov emits some ruby warnings when loaded, so silence them.
32
+ old_verbose = $VERBOSE
33
+ $VERBOSE = false
34
+
35
+ unless (ENV.fetch('COVERAGE', nil) && ENV['COVERAGE'].empty?) || RUBY_VERSION < '1.9.3'
36
+ require 'simplecov'
37
+
38
+ SimpleCov.start do
39
+ enable_coverage :branch
40
+ end
41
+ end
42
+ rescue LoadError
43
+ # simplecov is not available
44
+ ensure
45
+ $VERBOSE = old_verbose
46
+ end
47
+
48
+ load File.expand_path('rspec', __dir__)
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.8.1
4
+ version: 0.10.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: 2023-04-29 00:00:00.000000000 Z
12
+ date: 2023-12-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -47,6 +47,7 @@ executables: []
47
47
  extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
+ - ".github/dependabot.yml"
50
51
  - ".github/workflows/codeql-analysis.yml"
51
52
  - ".github/workflows/rubocop.yml"
52
53
  - ".github/workflows/test.yml"
@@ -54,6 +55,7 @@ files:
54
55
  - ".rspec"
55
56
  - ".rubocop.yml"
56
57
  - ".rubocop_todo.yml"
58
+ - ".simplecov_spawn.rb"
57
59
  - CHANGELOG.md
58
60
  - Gemfile
59
61
  - LICENSE.txt
@@ -76,6 +78,8 @@ files:
76
78
  - lib/rspec/openapi/schema_merger.rb
77
79
  - lib/rspec/openapi/version.rb
78
80
  - rspec-openapi.gemspec
81
+ - scripts/rspec
82
+ - scripts/rspec_with_simplecov
79
83
  - test.png
80
84
  homepage: https://github.com/exoego/rspec-openapi
81
85
  licenses: