rspec-openapi 0.18.3 → 0.19.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 +4 -4
- data/.github/workflows/test.yml +3 -1
- data/Gemfile +4 -0
- data/README.md +17 -2
- data/lib/rspec/openapi/extractors/hanami.rb +13 -1
- data/lib/rspec/openapi/extractors/rack.rb +13 -1
- data/lib/rspec/openapi/extractors/rails.rb +16 -3
- data/lib/rspec/openapi/record.rb +2 -0
- data/lib/rspec/openapi/record_builder.rb +4 -1
- data/lib/rspec/openapi/result_recorder.rb +1 -1
- data/lib/rspec/openapi/schema_builder.rb +25 -13
- data/lib/rspec/openapi/schema_cleaner.rb +2 -2
- data/lib/rspec/openapi/version.rb +1 -1
- data/lib/rspec/openapi.rb +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0fd8968099cf455a6ee1eabe6039c60955020493d97e584fb57b1ba79aca8d3
|
4
|
+
data.tar.gz: 15ae08318ba0843a65cbd4bf418b82f2ce9d7c173600f0ea2d776763f4790819
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c15dc4a7d63f610cd654ea2718ffccbd15c59ec66bcc45f219352bdccbe7a6e49baa4810a866fefd483b34ec94992a7f48ce799d8cace7ced59f2dd5fb9db81
|
7
|
+
data.tar.gz: 9306ae8e95e9d4dcb0aa40d20b716217c2712ad081448c7f61cb832dd210864883c6f93999257715347fd85b5eb9f1d5ccb0615db3102de112fdfddebeb78318
|
data/.github/workflows/test.yml
CHANGED
@@ -25,6 +25,8 @@ jobs:
|
|
25
25
|
rails: 7.0.8
|
26
26
|
- ruby: ruby:3.3
|
27
27
|
rails: 7.1.3.2
|
28
|
+
- ruby: ruby:3.4
|
29
|
+
rails: 8.0.2
|
28
30
|
coverage: coverage
|
29
31
|
env:
|
30
32
|
RAILS_VERSION: ${{ matrix.rails == '' && '6.1.6' || matrix.rails }}
|
@@ -38,7 +40,7 @@ jobs:
|
|
38
40
|
- run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
39
41
|
name: codecov-action@v4 workaround
|
40
42
|
- name: Upload coverage reports
|
41
|
-
uses: codecov/codecov-action@
|
43
|
+
uses: codecov/codecov-action@v5
|
42
44
|
if: matrix.coverage == 'coverage'
|
43
45
|
with:
|
44
46
|
fail_ci_if_error: true
|
data/Gemfile
CHANGED
@@ -11,8 +11,12 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
|
|
11
11
|
gem 'hanami', ENV['HANAMI_VERSION'] || '2.1.0'
|
12
12
|
gem 'hanami-controller', ENV['HANAMI_VERSION'] || '2.1.0'
|
13
13
|
gem 'hanami-router', ENV['HANAMI_VERSION'] || '2.1.0'
|
14
|
+
|
15
|
+
gem 'dry-logger', '1.0.3'
|
14
16
|
end
|
15
17
|
|
18
|
+
gem 'concurrent-ruby', '1.3.4'
|
19
|
+
|
16
20
|
gem 'roda'
|
17
21
|
|
18
22
|
gem 'rails-dom-testing', '~> 2.2'
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# rspec-openapi [](https://rubygems.org/gems/rspec-openapi) [](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml) [](https://codecov.io/gh/exoego/rspec-openapi) [](https://www.ruby-toolbox.com/projects/rspec-openapi)
|
1
|
+
# rspec-openapi [](https://rubygems.org/gems/rspec-openapi) [](https://github.com/exoego/rspec-openapi/actions/workflows/test.yml) [](https://codecov.io/gh/exoego/rspec-openapi) [](https://www.ruby-toolbox.com/projects/rspec-openapi) [](https://deepwiki.com/exoego/rspec-openapi)
|
2
|
+
|
2
3
|
|
3
4
|
Generate OpenAPI schema from RSpec request specs.
|
4
5
|
|
@@ -52,7 +53,7 @@ end
|
|
52
53
|
If you run the spec with `OPENAPI=1`,
|
53
54
|
|
54
55
|
```
|
55
|
-
OPENAPI=1 rspec spec/requests/tables_spec.rb
|
56
|
+
OPENAPI=1 bundle exec rspec spec/requests/tables_spec.rb
|
56
57
|
```
|
57
58
|
|
58
59
|
It will generate [`doc/openapi.yaml` file](./spec/rails/doc/openapi.yaml) like:
|
@@ -122,8 +123,18 @@ RSpec::OpenAPI.path = -> (example) {
|
|
122
123
|
end
|
123
124
|
}
|
124
125
|
|
126
|
+
# Change the default title of the generated schema
|
125
127
|
RSpec::OpenAPI.title = 'OpenAPI Documentation'
|
126
128
|
|
129
|
+
# Or generate individual titles for your partial schema files, given an RSpec example
|
130
|
+
RSpec::OpenAPI.title = -> (example) {
|
131
|
+
case example.file_path
|
132
|
+
when %r[spec/requests/api/v1/] then 'API v1 Documentation'
|
133
|
+
when %r[spec/requests/api/v2/] then 'API v2 Documentation'
|
134
|
+
else 'OpenAPI Documentation'
|
135
|
+
end
|
136
|
+
}
|
137
|
+
|
127
138
|
# Disable generating `example`
|
128
139
|
RSpec::OpenAPI.enable_example = false
|
129
140
|
|
@@ -177,6 +188,10 @@ RSpec::OpenAPI.summary_builder = ->(example) { example.metadata.dig(:example_gro
|
|
177
188
|
# This example uses the tags from the parent_example_group
|
178
189
|
RSpec::OpenAPI.tags_builder = -> (example) { example.metadata.dig(:example_group, :parent_example_group, :openapi, :tags) }
|
179
190
|
|
191
|
+
# Configure custom format for specific properties
|
192
|
+
# This example assigns 'date-time' format to properties with names ending in '_at'
|
193
|
+
RSpec::OpenAPI.formats_builder = ->(_example, key) { key.end_with?('_at') ? 'date-time' : nil }
|
194
|
+
|
180
195
|
# Change the example type(s) that will generate schema
|
181
196
|
RSpec::OpenAPI.example_types = %i[request]
|
182
197
|
|
@@ -59,6 +59,7 @@ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
|
59
59
|
metadata = example.metadata[:openapi] || {}
|
60
60
|
summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
|
61
61
|
tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
|
62
|
+
formats = metadata[:formats] || RSpec::OpenAPI.formats_builder.curry.call(example)
|
62
63
|
operation_id = metadata[:operation_id]
|
63
64
|
required_request_params = metadata[:required_request_params] || []
|
64
65
|
security = metadata[:security]
|
@@ -76,7 +77,18 @@ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
|
76
77
|
|
77
78
|
raw_path_params = raw_path_params.slice(*(raw_path_params.keys - RSpec::OpenAPI.ignored_path_params))
|
78
79
|
|
79
|
-
[
|
80
|
+
[
|
81
|
+
path,
|
82
|
+
summary,
|
83
|
+
tags,
|
84
|
+
operation_id,
|
85
|
+
required_request_params,
|
86
|
+
raw_path_params,
|
87
|
+
description,
|
88
|
+
security,
|
89
|
+
deprecated,
|
90
|
+
formats,
|
91
|
+
]
|
80
92
|
end
|
81
93
|
|
82
94
|
# @param [RSpec::ExampleGroups::*] context
|
@@ -9,6 +9,7 @@ class << RSpec::OpenAPI::Extractors::Rack = Object.new
|
|
9
9
|
metadata = example.metadata[:openapi] || {}
|
10
10
|
summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
|
11
11
|
tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
|
12
|
+
formats = metadata[:formats] || RSpec::OpenAPI.formats_builder.curry.call(example)
|
12
13
|
operation_id = metadata[:operation_id]
|
13
14
|
required_request_params = metadata[:required_request_params] || []
|
14
15
|
security = metadata[:security]
|
@@ -17,7 +18,18 @@ class << RSpec::OpenAPI::Extractors::Rack = Object.new
|
|
17
18
|
raw_path_params = request.path_parameters
|
18
19
|
path = request.path
|
19
20
|
summary ||= "#{request.method} #{path}"
|
20
|
-
[
|
21
|
+
[
|
22
|
+
path,
|
23
|
+
summary,
|
24
|
+
tags,
|
25
|
+
operation_id,
|
26
|
+
required_request_params,
|
27
|
+
raw_path_params,
|
28
|
+
description,
|
29
|
+
security,
|
30
|
+
deprecated,
|
31
|
+
formats,
|
32
|
+
]
|
21
33
|
end
|
22
34
|
|
23
35
|
# @param [RSpec::ExampleGroups::*] context
|
@@ -12,13 +12,15 @@ class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
|
12
12
|
|
13
13
|
route, path = find_rails_route(fixed_request)
|
14
14
|
|
15
|
-
raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
|
16
|
-
|
17
15
|
return RSpec::OpenAPI::Extractors::Rack.request_attributes(request, example) unless path
|
18
16
|
|
17
|
+
raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
|
18
|
+
|
19
19
|
metadata = example.metadata[:openapi] || {}
|
20
20
|
summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
|
21
21
|
tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
|
22
|
+
formats = metadata[:formats] || RSpec::OpenAPI.formats_builder.curry.call(example)
|
23
|
+
|
22
24
|
operation_id = metadata[:operation_id]
|
23
25
|
required_request_params = metadata[:required_request_params] || []
|
24
26
|
security = metadata[:security]
|
@@ -34,7 +36,18 @@ class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
|
34
36
|
|
35
37
|
summary ||= "#{request.method} #{path}"
|
36
38
|
|
37
|
-
[
|
39
|
+
[
|
40
|
+
path,
|
41
|
+
summary,
|
42
|
+
tags,
|
43
|
+
operation_id,
|
44
|
+
required_request_params,
|
45
|
+
raw_path_params,
|
46
|
+
description,
|
47
|
+
security,
|
48
|
+
deprecated,
|
49
|
+
formats,
|
50
|
+
]
|
38
51
|
end
|
39
52
|
|
40
53
|
# @param [RSpec::ExampleGroups::*] context
|
data/lib/rspec/openapi/record.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec::OpenAPI::Record = Struct.new(
|
4
|
+
:title, # @param [String] - "API Documentation - Statuses"
|
4
5
|
:http_method, # @param [String] - "GET"
|
5
6
|
:path, # @param [String] - "/v1/status/:id"
|
6
7
|
:path_params, # @param [Hash] - {:controller=>"v1/statuses", :action=>"create", :id=>"1"}
|
@@ -11,6 +12,7 @@ RSpec::OpenAPI::Record = Struct.new(
|
|
11
12
|
:request_headers, # @param [Array] - [["header_key1", "header_value1"], ["header_key2", "header_value2"]]
|
12
13
|
:summary, # @param [String] - "v1/statuses #show"
|
13
14
|
:tags, # @param [Array] - ["Status"]
|
15
|
+
:formats, # @param [Proc] - ->(key) { key.end_with?('_at') ? 'date-time' : nil }
|
14
16
|
:operation_id, # @param [String] - "request-1234"
|
15
17
|
:description, # @param [String] - "returns a status"
|
16
18
|
:security, # @param [Array] - [{securityScheme1: []}]
|
@@ -11,7 +11,8 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
|
|
11
11
|
request, response = extractor.request_response(context)
|
12
12
|
return if request.nil?
|
13
13
|
|
14
|
-
|
14
|
+
title = RSpec::OpenAPI.title.then { |t| t.is_a?(Proc) ? t.call(example) : t }
|
15
|
+
path, summary, tags, operation_id, required_request_params, raw_path_params, description, security, deprecated, formats =
|
15
16
|
extractor.request_attributes(request, example)
|
16
17
|
|
17
18
|
return if RSpec::OpenAPI.ignored_paths.any? { |ignored_path| path.match?(ignored_path) }
|
@@ -19,6 +20,7 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
|
|
19
20
|
request_headers, response_headers = extract_headers(request, response)
|
20
21
|
|
21
22
|
RSpec::OpenAPI::Record.new(
|
23
|
+
title: title,
|
22
24
|
http_method: request.method,
|
23
25
|
path: path,
|
24
26
|
path_params: raw_path_params,
|
@@ -29,6 +31,7 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
|
|
29
31
|
request_headers: request_headers,
|
30
32
|
summary: summary,
|
31
33
|
tags: tags,
|
34
|
+
formats: formats,
|
32
35
|
operation_id: operation_id,
|
33
36
|
description: description,
|
34
37
|
security: security,
|
@@ -16,7 +16,7 @@ class RSpec::OpenAPI::ResultRecorder
|
|
16
16
|
puts "WARNING: Unable to load #{config_file}: #{e}"
|
17
17
|
end
|
18
18
|
|
19
|
-
title =
|
19
|
+
title = records.first.title
|
20
20
|
RSpec::OpenAPI::SchemaFile.new(path).edit do |spec|
|
21
21
|
schema = RSpec::OpenAPI::DefaultSchema.build(title)
|
22
22
|
schema[:info].merge!(RSpec::OpenAPI.info)
|
@@ -18,7 +18,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
18
18
|
if has_content
|
19
19
|
response[:content] = {
|
20
20
|
normalize_content_type(record.response_content_type) => {
|
21
|
-
schema: build_property(record.response_body, disposition: disposition),
|
21
|
+
schema: build_property(record.response_body, disposition: disposition, record: record),
|
22
22
|
example: response_example(record, disposition: disposition),
|
23
23
|
}.compact,
|
24
24
|
}
|
@@ -36,7 +36,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
36
36
|
security: record.security,
|
37
37
|
deprecated: record.deprecated ? true : nil,
|
38
38
|
parameters: build_parameters(record),
|
39
|
-
requestBody: http_method
|
39
|
+
requestBody: include_nil_request_body?(http_method) ? nil : build_request_body(record),
|
40
40
|
responses: {
|
41
41
|
record.status.to_s => response,
|
42
42
|
},
|
@@ -48,6 +48,10 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
|
+
def include_nil_request_body?(http_method)
|
52
|
+
%w[delete get].include?(http_method)
|
53
|
+
end
|
54
|
+
|
51
55
|
def enrich_with_required_keys(obj)
|
52
56
|
obj[:required] = obj[:properties]&.keys || []
|
53
57
|
obj
|
@@ -69,7 +73,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
69
73
|
name: build_parameter_name(key, value),
|
70
74
|
in: 'path',
|
71
75
|
required: true,
|
72
|
-
schema: build_property(try_cast(value)),
|
76
|
+
schema: build_property(try_cast(value), key: key, record: record),
|
73
77
|
example: (try_cast(value) if example_enabled?),
|
74
78
|
}.compact
|
75
79
|
end
|
@@ -79,7 +83,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
79
83
|
name: build_parameter_name(key, value),
|
80
84
|
in: 'query',
|
81
85
|
required: record.required_request_params.include?(key),
|
82
|
-
schema: build_property(try_cast(value)),
|
86
|
+
schema: build_property(try_cast(value), key: key, record: record),
|
83
87
|
example: (try_cast(value) if example_enabled?),
|
84
88
|
}.compact
|
85
89
|
end
|
@@ -89,7 +93,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
89
93
|
name: build_parameter_name(key, value),
|
90
94
|
in: 'header',
|
91
95
|
required: true,
|
92
|
-
schema: build_property(try_cast(value)),
|
96
|
+
schema: build_property(try_cast(value), key: key, record: record),
|
93
97
|
example: (try_cast(value) if example_enabled?),
|
94
98
|
}.compact
|
95
99
|
end
|
@@ -106,7 +110,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
106
110
|
|
107
111
|
record.response_headers.each do |key, value|
|
108
112
|
headers[key] = {
|
109
|
-
schema: build_property(try_cast(value)),
|
113
|
+
schema: build_property(try_cast(value), key: key, record: record),
|
110
114
|
}.compact
|
111
115
|
end
|
112
116
|
|
@@ -130,27 +134,29 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
130
134
|
{
|
131
135
|
content: {
|
132
136
|
normalize_content_type(record.request_content_type) => {
|
133
|
-
schema: build_property(record.request_params),
|
137
|
+
schema: build_property(record.request_params, record: record),
|
134
138
|
example: (build_example(record.request_params) if example_enabled?),
|
135
139
|
}.compact,
|
136
140
|
},
|
137
141
|
}
|
138
142
|
end
|
139
143
|
|
140
|
-
def build_property(value, disposition: nil)
|
141
|
-
|
144
|
+
def build_property(value, disposition: nil, key: nil, record: nil)
|
145
|
+
format = disposition ? 'binary' : infer_format(key, record)
|
146
|
+
|
147
|
+
property = build_type(value, format: format)
|
142
148
|
|
143
149
|
case value
|
144
150
|
when Array
|
145
151
|
property[:items] = if value.empty?
|
146
152
|
{} # unknown
|
147
153
|
else
|
148
|
-
build_property(value.first)
|
154
|
+
build_property(value.first, record: record)
|
149
155
|
end
|
150
156
|
when Hash
|
151
157
|
property[:properties] = {}.tap do |properties|
|
152
158
|
value.each do |key, v|
|
153
|
-
properties[key] = build_property(v)
|
159
|
+
properties[key] = build_property(v, record: record, key: key)
|
154
160
|
end
|
155
161
|
end
|
156
162
|
property = enrich_with_required_keys(property)
|
@@ -158,8 +164,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
158
164
|
property
|
159
165
|
end
|
160
166
|
|
161
|
-
def build_type(value,
|
162
|
-
return { type: 'string', format:
|
167
|
+
def build_type(value, format: nil)
|
168
|
+
return { type: 'string', format: format } if format
|
163
169
|
|
164
170
|
case value
|
165
171
|
when String
|
@@ -183,6 +189,12 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
183
189
|
end
|
184
190
|
end
|
185
191
|
|
192
|
+
def infer_format(key, record)
|
193
|
+
return nil if !key || !record || !record.formats
|
194
|
+
|
195
|
+
record.formats[key]
|
196
|
+
end
|
197
|
+
|
186
198
|
# Convert an always-String param to an appropriate type
|
187
199
|
def try_cast(value)
|
188
200
|
Integer(value)
|
@@ -50,7 +50,7 @@ class << RSpec::OpenAPI::SchemaCleaner = Object.new
|
|
50
50
|
parent_path_definition = base.dig(*path.take(path.length - 1))
|
51
51
|
|
52
52
|
security_schemes.each do |security_scheme_name, security_scheme|
|
53
|
-
|
53
|
+
remove_parameters_conflicting_with_security_scheme!(
|
54
54
|
parent_path_definition, security_scheme, security_scheme_name,
|
55
55
|
)
|
56
56
|
end
|
@@ -71,7 +71,7 @@ class << RSpec::OpenAPI::SchemaCleaner = Object.new
|
|
71
71
|
|
72
72
|
private
|
73
73
|
|
74
|
-
def
|
74
|
+
def remove_parameters_conflicting_with_security_scheme!(path_definition, security_scheme, security_scheme_name)
|
75
75
|
return unless path_definition[:security]
|
76
76
|
return unless path_definition[:parameters]
|
77
77
|
return unless path_definition.dig(:security, 0).keys.include?(security_scheme_name)
|
data/lib/rspec/openapi.rb
CHANGED
@@ -33,6 +33,7 @@ module RSpec::OpenAPI
|
|
33
33
|
@description_builder = ->(example) { example.description }
|
34
34
|
@summary_builder = ->(example) { example.metadata[:summary] }
|
35
35
|
@tags_builder = ->(example) { example.metadata[:tags] }
|
36
|
+
@formats_builder = ->(example) { example.metadata[:formats] }
|
36
37
|
@info = {}
|
37
38
|
@application_version = '1.0.0'
|
38
39
|
@request_headers = []
|
@@ -56,6 +57,7 @@ module RSpec::OpenAPI
|
|
56
57
|
:description_builder,
|
57
58
|
:summary_builder,
|
58
59
|
:tags_builder,
|
60
|
+
:formats_builder,
|
59
61
|
:info,
|
60
62
|
:application_version,
|
61
63
|
:request_headers,
|
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.
|
4
|
+
version: 0.19.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:
|
12
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -109,7 +109,7 @@ licenses:
|
|
109
109
|
metadata:
|
110
110
|
homepage_uri: https://github.com/exoego/rspec-openapi
|
111
111
|
source_code_uri: https://github.com/exoego/rspec-openapi
|
112
|
-
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.
|
112
|
+
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.19.0
|
113
113
|
rubygems_mfa_required: 'true'
|
114
114
|
post_install_message:
|
115
115
|
rdoc_options: []
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '0'
|
128
128
|
requirements: []
|
129
|
-
rubygems_version: 3.4.
|
129
|
+
rubygems_version: 3.4.19
|
130
130
|
signing_key:
|
131
131
|
specification_version: 4
|
132
132
|
summary: Generate OpenAPI schema from RSpec request specs
|