rswag-specs 2.16.0 → 3.0.0.pre

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.
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rswag-specs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.0
4
+ version: 3.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richie Morris
8
8
  - Greg Myers
9
9
  - Jay Danielian
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-11-13 00:00:00.000000000 Z
13
+ date: 2025-08-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '2.14'
81
+ version: '3.12'
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '2.14'
88
+ version: '3.12'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: simplecov
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -100,9 +100,10 @@ dependencies:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
102
  version: 0.21.2
103
- description: 'Simplify API integration testing with a succinct rspec DSL and generate
104
- OpenAPI specification files directly from your rspec tests. More about the OpenAPI
105
- initiative here: http://spec.openapis.org/'
103
+ description: |
104
+ Simplify API integration testing with a succinct rspec DSL and generate OpenAPI
105
+ specification files directly from your rspec tests. More about the OpenAPI initiative
106
+ here: http://spec.openapis.org/
106
107
  email:
107
108
  - domaindrivendev@gmail.com
108
109
  executables: []
@@ -113,27 +114,27 @@ files:
113
114
  - MIT-LICENSE
114
115
  - Rakefile
115
116
  - lib/generators/rspec/USAGE
116
- - lib/generators/rspec/swagger_generator.rb
117
+ - lib/generators/rspec/openapi_generator.rb
117
118
  - lib/generators/rspec/templates/spec.rb
118
119
  - lib/generators/rswag/specs/install/USAGE
119
120
  - lib/generators/rswag/specs/install/install_generator.rb
120
- - lib/generators/rswag/specs/install/templates/swagger_helper.rb
121
+ - lib/generators/rswag/specs/install/templates/openapi_helper.rb
121
122
  - lib/rswag/route_parser.rb
122
123
  - lib/rswag/specs.rb
123
124
  - lib/rswag/specs/configuration.rb
124
125
  - lib/rswag/specs/example_group_helpers.rb
125
126
  - lib/rswag/specs/example_helpers.rb
126
127
  - lib/rswag/specs/extended_schema.rb
128
+ - lib/rswag/specs/openapi_formatter.rb
127
129
  - lib/rswag/specs/railtie.rb
128
130
  - lib/rswag/specs/request_factory.rb
129
131
  - lib/rswag/specs/response_validator.rb
130
- - lib/rswag/specs/swagger_formatter.rb
131
132
  - lib/tasks/rswag-specs_tasks.rake
132
133
  homepage: https://github.com/rswag/rswag
133
134
  licenses:
134
135
  - MIT
135
136
  metadata: {}
136
- post_install_message:
137
+ post_install_message:
137
138
  rdoc_options: []
138
139
  require_paths:
139
140
  - lib
@@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
150
  version: '0'
150
151
  requirements: []
151
152
  rubygems_version: 3.5.11
152
- signing_key:
153
+ signing_key:
153
154
  specification_version: 4
154
155
  summary: An OpenAPI-based (formerly called Swagger) DSL for rspec-rails & accompanying
155
156
  rake task for generating OpenAPI specification files
@@ -1,229 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/hash/deep_merge'
4
- require 'rspec/core/formatters/base_text_formatter'
5
- require 'swagger_helper'
6
-
7
- module Rswag
8
- module Specs
9
- class SwaggerFormatter < ::RSpec::Core::Formatters::BaseTextFormatter
10
- if RSPEC_VERSION > 2
11
- ::RSpec::Core::Formatters.register self, :example_group_finished, :stop
12
- end
13
-
14
- def initialize(output, config = Rswag::Specs.config)
15
- super(output)
16
- @config = config
17
-
18
- @output.puts 'Generating Swagger docs ...'
19
- end
20
-
21
- def example_group_finished(notification)
22
- metadata = if RSPEC_VERSION > 2
23
- notification.group.metadata
24
- else
25
- notification.metadata
26
- end
27
-
28
- # !metadata[:document] won't work, since nil means we should generate
29
- # docs.
30
- return if metadata[:document] == false
31
- return unless metadata.key?(:response)
32
-
33
- swagger_doc = @config.get_openapi_spec(metadata[:openapi_spec] || metadata[:swagger_doc])
34
-
35
- unless doc_version(swagger_doc).start_with?('2')
36
- # This is called multiple times per file!
37
- # metadata[:operation] is also re-used between examples within file
38
- # therefore be careful NOT to modify its content here.
39
- upgrade_request_type!(metadata)
40
- upgrade_servers!(swagger_doc)
41
- upgrade_oauth!(swagger_doc)
42
- upgrade_response_produces!(swagger_doc, metadata)
43
- end
44
-
45
- swagger_doc.deep_merge!(metadata_to_swagger(metadata))
46
- end
47
-
48
- def stop(_notification = nil)
49
- @config.openapi_specs.each do |url_path, doc|
50
- unless doc_version(doc).start_with?('2')
51
- doc[:paths]&.each_pair do |_k, v|
52
- v.each_pair do |_verb, value|
53
- is_hash = value.is_a?(Hash)
54
- if is_hash && value[:parameters]
55
- schema_param = value[:parameters]&.find { |p| (p[:in] == :body || p[:in] == :formData) && p[:schema] }
56
- mime_list = value[:consumes] || doc[:consumes]
57
-
58
- if value && schema_param && mime_list
59
- value[:requestBody] = { content: {} } unless value.dig(:requestBody, :content)
60
- value[:requestBody][:required] = true if schema_param[:required]
61
- value[:requestBody][:description] = schema_param[:description] if schema_param[:description]
62
- examples = value.dig(:request_examples)
63
- mime_list.each do |mime|
64
- value[:requestBody][:content][mime] = { schema: schema_param[:schema] }
65
- if examples
66
- value[:requestBody][:content][mime][:examples] ||= {}
67
- examples.map do |example|
68
- value[:requestBody][:content][mime][:examples][example[:name]] = {
69
- summary: example[:summary] || value[:summary],
70
- value: example[:value]
71
- }
72
- end
73
- end
74
- end
75
- end
76
-
77
- enum_param = value.dig(:parameters).find{|p| p[:enum]}
78
- if enum_param && enum_param.is_a?(Hash)
79
- enum_param[:description] = generate_enum_description(enum_param)
80
- end
81
-
82
- value[:parameters].reject! { |p| p[:in] == :body || p[:in] == :formData }
83
- end
84
- remove_invalid_operation_keys!(value)
85
- end
86
- end
87
- end
88
-
89
- file_path = File.join(@config.openapi_root, url_path)
90
- dirname = File.dirname(file_path)
91
- FileUtils.mkdir_p dirname unless File.exist?(dirname)
92
-
93
- File.open(file_path, 'w') do |file|
94
- file.write(pretty_generate(doc))
95
- end
96
-
97
- @output.puts "Swagger doc generated at #{file_path}"
98
- end
99
- end
100
-
101
- private
102
-
103
- def pretty_generate(doc)
104
- if @config.openapi_format == :yaml
105
- clean_doc = yaml_prepare(doc)
106
- YAML.dump(clean_doc)
107
- else # config errors are thrown in 'def openapi_format', no throw needed here
108
- JSON.pretty_generate(doc)
109
- end
110
- end
111
-
112
- def yaml_prepare(doc)
113
- json_doc = JSON.pretty_generate(doc)
114
- JSON.parse(json_doc)
115
- end
116
-
117
- def metadata_to_swagger(metadata)
118
- response_code = metadata[:response][:code]
119
- response = metadata[:response].reject { |k, _v| k == :code }
120
-
121
- verb = metadata[:operation][:verb]
122
- operation = metadata[:operation]
123
- .reject { |k, _v| k == :verb }
124
- .merge(responses: { response_code => response })
125
-
126
- path_template = metadata[:path_item][:template]
127
- path_item = metadata[:path_item]
128
- .reject { |k, _v| k == :template }
129
- .merge(verb => operation)
130
-
131
- { paths: { path_template => path_item } }
132
- end
133
-
134
- def doc_version(doc)
135
- doc[:openapi] || doc[:swagger] || '3'
136
- end
137
-
138
- def upgrade_response_produces!(swagger_doc, metadata)
139
- # Accept header
140
- mime_list = Array(metadata[:operation][:produces] || swagger_doc[:produces])
141
- target_node = metadata[:response]
142
- upgrade_content!(mime_list, target_node)
143
- metadata[:response].delete(:schema)
144
- end
145
-
146
- def upgrade_content!(mime_list, target_node)
147
- schema = target_node[:schema]
148
- return if mime_list.empty? || schema.nil?
149
-
150
- target_node[:content] ||= {}
151
- mime_list.each do |mime_type|
152
- # TODO: upgrade to have content-type specific schema
153
- (target_node[:content][mime_type] ||= {}).merge!(schema: schema)
154
- end
155
- end
156
-
157
- def upgrade_request_type!(metadata)
158
- # No deprecation here as it seems valid to allow type as a shorthand
159
- operation_nodes = metadata[:operation][:parameters] || []
160
- path_nodes = metadata[:path_item][:parameters] || []
161
- header_node = metadata[:response][:headers] || {}
162
-
163
- (operation_nodes + path_nodes + [header_node]).each do |node|
164
- if node && node[:type] && node[:schema].nil?
165
- node[:schema] = { type: node[:type] }
166
- node.delete(:type)
167
- end
168
- end
169
- end
170
-
171
- def upgrade_servers!(swagger_doc)
172
- return unless swagger_doc[:servers].nil? && swagger_doc.key?(:schemes)
173
-
174
- Rswag::Specs.deprecator.warn('Rswag::Specs: WARNING: schemes, host, and basePath are replaced in OpenAPI3! Rename to array of servers[{url}] (in swagger_helper.rb)')
175
-
176
- swagger_doc[:servers] = { urls: [] }
177
- swagger_doc[:schemes].each do |scheme|
178
- swagger_doc[:servers][:urls] << scheme + '://' + swagger_doc[:host] + swagger_doc[:basePath]
179
- end
180
-
181
- swagger_doc.delete(:schemes)
182
- swagger_doc.delete(:host)
183
- swagger_doc.delete(:basePath)
184
- end
185
-
186
- def upgrade_oauth!(swagger_doc)
187
- # find flow in securitySchemes (securityDefinitions will have been re-written)
188
- schemes = swagger_doc.dig(:components, :securitySchemes)
189
- return unless schemes&.any? { |_k, v| v.key?(:flow) }
190
-
191
- schemes.each do |name, v|
192
- next unless v.key?(:flow)
193
-
194
- Rswag::Specs.deprecator.warn("Rswag::Specs: WARNING: securityDefinitions flow is replaced in OpenAPI3! Rename to components/securitySchemes/#{name}/flows[] (in swagger_helper.rb)")
195
- flow = swagger_doc[:components][:securitySchemes][name].delete(:flow).to_s
196
- if flow == 'accessCode'
197
- Rswag::Specs.deprecator.warn("Rswag::Specs: WARNING: securityDefinitions accessCode is replaced in OpenAPI3! Rename to clientCredentials (in swagger_helper.rb)")
198
- flow = 'authorizationCode'
199
- end
200
- if flow == 'application'
201
- Rswag::Specs.deprecator.warn("Rswag::Specs: WARNING: securityDefinitions application is replaced in OpenAPI3! Rename to authorizationCode (in swagger_helper.rb)")
202
- flow = 'clientCredentials'
203
- end
204
- flow_elements = swagger_doc[:components][:securitySchemes][name].except(:type).each_with_object({}) do |(k, _v), a|
205
- a[k] = swagger_doc[:components][:securitySchemes][name].delete(k)
206
- end
207
- swagger_doc[:components][:securitySchemes][name].merge!(flows: { flow => flow_elements })
208
- end
209
- end
210
-
211
- def remove_invalid_operation_keys!(value)
212
- return unless value.is_a?(Hash)
213
-
214
- value.delete(:consumes) if value[:consumes]
215
- value.delete(:produces) if value[:produces]
216
- value.delete(:request_examples) if value[:request_examples]
217
- value[:parameters].each { |p| p.delete(:getter) } if value[:parameters]
218
- end
219
-
220
- def generate_enum_description(param)
221
- enum_description = "#{param[:description]}:\n "
222
- param[:enum].each do |k,v|
223
- enum_description += "* `#{k}` #{v}\n "
224
- end
225
- enum_description
226
- end
227
- end
228
- end
229
- end