rswag-specs 2.5.1 → 2.7.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: df4a6de7cd0c39993e11e3cee2e4f21a1bf7175d53d467530a2d5d2fb0de62ad
4
- data.tar.gz: 5845e6e3cc9368ff18a777155bb039aae5f8ad526444b9bf00ef5c3635ad732a
3
+ metadata.gz: 989468cbcebd005e6bf95724400366cfa1b80e7d395bb6d1255bc12c283a98b2
4
+ data.tar.gz: 949a822da86b5d6f3ead28cdd1262a093bcd8399875b1962f101c41634cc4c51
5
5
  SHA512:
6
- metadata.gz: '088948aa3b15b493d95d678e6d30d211bc3d942d27db9f6c340acdee76b43783352b830045d118b1d91f65be068248c4a829d5f0a06fe58cd4478b903b069a25'
7
- data.tar.gz: 60175ad736c79c12cfc14e1a9e810b57e0676a52ddc5b35fdb084fc6b0b8f0b1097080d6a367535287b982a71241b6675f6484252fce4a2b351972dead2664d5
6
+ metadata.gz: b4cb982b39359a8f69dd5ebf18287a2b4941349a202751d10f936b81014fce8ec99a24886e5de63c4fb1d4aba653893cf4ebff9f425f547be99b1ac3910e53ad
7
+ data.tar.gz: 1064a439e5b8652c40a77eddd6d0837ea908780750187879bb8bdb11af67656ea6882a8a251bb8627001c7857ebad94c378d68432c1101e2e19647b5c7c29ae5
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support'
4
+
3
5
  module Rswag
4
6
  module Specs
5
7
  module ExampleGroupHelpers
8
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: Support for Ruby 2.6 will be dropped in v3.0') if RUBY_VERSION.start_with? '2.6'
9
+
6
10
  def path(template, metadata = {}, &block)
7
11
  metadata[:path_item] = { template: template }
8
12
  describe(template, metadata, &block)
@@ -69,23 +73,44 @@ module Rswag
69
73
  # NOTE: Similar to 'description', 'examples' need to handle the case when
70
74
  # being invoked with no params to avoid overriding 'examples' method of
71
75
  # rspec-core ExampleGroup
72
- def examples(example = nil)
73
- return super() if example.nil?
76
+ def examples(examples = nil)
77
+ return super() if examples.nil?
78
+ # should we add a deprecation warning?
79
+ examples.each_with_index do |(mime, example_object), index|
80
+ example(mime, "example_#{index}", example_object)
81
+ end
82
+ end
74
83
 
75
- metadata[:response][:content] =
76
- example.each_with_object({}) do |(mime, example_object), memo|
77
- memo[mime] = { example: example_object }
78
- end
84
+ def example(mime, name, value, summary=nil, description=nil)
85
+ # Todo - move initialization of metadata somewhere else.
86
+ if metadata[:response][:content].blank?
87
+ metadata[:response][:content] = {}
88
+ end
89
+
90
+ if metadata[:response][:content][mime].blank?
91
+ metadata[:response][:content][mime] = {}
92
+ metadata[:response][:content][mime][:examples] = {}
93
+ end
94
+
95
+ example_object = {
96
+ value: value,
97
+ summary: summary,
98
+ description: description
99
+ }.select { |_, v| v.present? }
100
+ # TODO, issue a warning if example is being overridden with the same key
101
+ metadata[:response][:content][mime][:examples].merge!(
102
+ { name.to_sym => example_object }
103
+ )
79
104
  end
80
105
 
81
106
  def run_test!(&block)
82
- # NOTE: rspec 2.x support
83
107
  if RSPEC_VERSION < 3
108
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: Support for RSpec 2.X will be dropped in v3.0')
84
109
  before do
85
110
  submit_request(example.metadata)
86
111
  end
87
112
 
88
- it "returns a #{metadata[:response][:code]} response" do
113
+ it "returns a #{metadata[:response][:code]} response", rswag: true do
89
114
  assert_response_matches_metadata(metadata)
90
115
  block.call(response) if block_given?
91
116
  end
@@ -94,7 +119,7 @@ module Rswag
94
119
  submit_request(example.metadata)
95
120
  end
96
121
 
97
- it "returns a #{metadata[:response][:code]} response" do |example|
122
+ it "returns a #{metadata[:response][:code]} response", rswag: true do |example|
98
123
  assert_response_matches_metadata(example.metadata, &block)
99
124
  example.instance_exec(response, &block) if block_given?
100
125
  end
@@ -7,14 +7,11 @@ module Rswag
7
7
  class ExtendedSchema < JSON::Schema::Draft4
8
8
  def initialize
9
9
  super
10
- @attributes['type'] = ExtendedTypeAttribute
11
10
  @uri = URI.parse('http://tempuri.org/rswag/specs/extended_schema')
12
11
  @names = ['http://tempuri.org/rswag/specs/extended_schema']
13
12
  end
14
- end
15
13
 
16
- class ExtendedTypeAttribute < JSON::Schema::TypeV4Attribute
17
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
14
+ def validate(current_schema, data, *)
18
15
  return if data.nil? && (current_schema.schema['nullable'] == true || current_schema.schema['x-nullable'] == true)
19
16
 
20
17
  super
@@ -101,23 +101,82 @@ module Rswag
101
101
  request[:verb] = metadata[:operation][:verb]
102
102
  end
103
103
 
104
+ def base_path_from_servers(swagger_doc, use_server = :default)
105
+ return '' if swagger_doc[:servers].nil? || swagger_doc[:servers].empty?
106
+ server = swagger_doc[:servers].first
107
+ variables = {}
108
+ server.fetch(:variables, {}).each_pair { |k,v| variables[k] = v[use_server] }
109
+ base_path = server[:url].gsub(/\{(.*?)\}/) { |name| variables[name.to_sym] }
110
+ URI(base_path).path
111
+ end
112
+
104
113
  def add_path(request, metadata, swagger_doc, parameters, example)
105
- template = (swagger_doc[:basePath] || '') + metadata[:path_item][:template]
114
+ open_api_3_doc = doc_version(swagger_doc).start_with?('3')
115
+ uses_base_path = swagger_doc[:basePath].present?
116
+
117
+ if open_api_3_doc && uses_base_path
118
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: basePath is replaced in OpenAPI3! Update your swagger_helper.rb')
119
+ end
120
+
121
+ if uses_base_path
122
+ template = (swagger_doc[:basePath] || '') + metadata[:path_item][:template]
123
+ else # OpenAPI 3
124
+ template = base_path_from_servers(swagger_doc) + metadata[:path_item][:template]
125
+ end
106
126
 
107
127
  request[:path] = template.tap do |path_template|
108
128
  parameters.select { |p| p[:in] == :path }.each do |p|
129
+ unless example.respond_to?(p[:name])
130
+ raise ArgumentError.new("`#{p[:name].to_s}` parameter key present, but not defined within example group"\
131
+ "(i. e `it` or `let` block)")
132
+ end
109
133
  path_template.gsub!("{#{p[:name]}}", example.send(p[:name]).to_s)
110
134
  end
111
135
 
112
136
  parameters.select { |p| p[:in] == :query }.each_with_index do |p, i|
113
137
  path_template.concat(i.zero? ? '?' : '&')
114
- path_template.concat(build_query_string_part(p, example.send(p[:name])))
138
+ path_template.concat(build_query_string_part(p, example.send(p[:name]), swagger_doc))
115
139
  end
116
140
  end
117
141
  end
118
142
 
119
- def build_query_string_part(param, value)
143
+ def build_query_string_part(param, value, swagger_doc)
120
144
  name = param[:name]
145
+
146
+ # OAS 3: https://swagger.io/docs/specification/serialization/
147
+ if swagger_doc && doc_version(swagger_doc).start_with?('3') && param[:schema]
148
+ style = param[:style]&.to_sym || :form
149
+ explode = param[:explode].nil? ? true : param[:explode]
150
+
151
+ case param[:schema][:type].to_sym
152
+ when :object
153
+ case style
154
+ when :deepObject
155
+ return { name => value }.to_query
156
+ when :form
157
+ if explode
158
+ return value.to_query
159
+ else
160
+ return "#{CGI.escape(name.to_s)}=" + value.to_a.flatten.map{|v| CGI.escape(v.to_s) }.join(',')
161
+ end
162
+ end
163
+ when :array
164
+ case explode
165
+ when true
166
+ return value.to_a.flatten.map{|v| "#{CGI.escape(name.to_s)}=#{CGI.escape(v.to_s)}"}.join('&')
167
+ else
168
+ separator = case style
169
+ when :form then ','
170
+ when :spaceDelimited then '%20'
171
+ when :pipeDelimited then '|'
172
+ end
173
+ return "#{CGI.escape(name.to_s)}=" + value.to_a.flatten.map{|v| CGI.escape(v.to_s) }.join(separator)
174
+ end
175
+ else
176
+ return "#{name}=#{value}"
177
+ end
178
+ end
179
+
121
180
  type = param[:type] || param.dig(:schema, :type)
122
181
  return "#{name}=#{value}" unless type&.to_sym == :array
123
182
 
@@ -154,8 +213,8 @@ module Rswag
154
213
  tuples << ['Content-Type', content_type]
155
214
  end
156
215
 
157
- # Rails test infrastructure requires rackified headers
158
- rackified_tuples = tuples.map do |pair|
216
+ # Rails test infrastructure requires rack-formatted headers
217
+ rack_formatted_tuples = tuples.map do |pair|
159
218
  [
160
219
  case pair[0]
161
220
  when 'Accept' then 'HTTP_ACCEPT'
@@ -167,7 +226,7 @@ module Rswag
167
226
  ]
168
227
  end
169
228
 
170
- request[:headers] = Hash[rackified_tuples]
229
+ request[:headers] = Hash[rack_formatted_tuples]
171
230
  end
172
231
 
173
232
  def add_payload(request, parameters, example)
@@ -53,7 +53,7 @@ module Rswag
53
53
  return unless errors.any?
54
54
 
55
55
  raise UnexpectedResponse,
56
- "Expected response body to match schema: #{errors[0]}\n" \
56
+ "Expected response body to match schema: #{errors.join("\n")}\n" \
57
57
  "Response body: #{JSON.pretty_generate(JSON.parse(body))}"
58
58
  end
59
59
 
@@ -7,10 +7,12 @@ require 'swagger_helper'
7
7
  module Rswag
8
8
  module Specs
9
9
  class SwaggerFormatter < ::RSpec::Core::Formatters::BaseTextFormatter
10
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: Support for Ruby 2.6 will be dropped in v3.0') if RUBY_VERSION.start_with? '2.6'
10
11
 
11
- # NOTE: rspec 2.x support
12
12
  if RSPEC_VERSION > 2
13
13
  ::RSpec::Core::Formatters.register self, :example_group_finished, :stop
14
+ else
15
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: Support for RSpec 2.X will be dropped in v3.0')
14
16
  end
15
17
 
16
18
  def initialize(output, config = Rswag::Specs.config)
@@ -21,7 +23,6 @@ module Rswag
21
23
  end
22
24
 
23
25
  def example_group_finished(notification)
24
- # NOTE: rspec 2.x support
25
26
  metadata = if RSPEC_VERSION > 2
26
27
  notification.group.metadata
27
28
  else
@@ -54,12 +55,13 @@ module Rswag
54
55
  doc[:paths]&.each_pair do |_k, v|
55
56
  v.each_pair do |_verb, value|
56
57
  is_hash = value.is_a?(Hash)
57
- if is_hash && value.dig(:parameters)
58
- schema_param = value.dig(:parameters)&.find { |p| (p[:in] == :body || p[:in] == :formData) && p[:schema] }
59
- mime_list = value.dig(:consumes) || doc[:consumes]
58
+ if is_hash && value[:parameters]
59
+ schema_param = value[:parameters]&.find { |p| (p[:in] == :body || p[:in] == :formData) && p[:schema] }
60
+ mime_list = value[:consumes] || doc[:consumes]
60
61
  if value && schema_param && mime_list
61
62
  value[:requestBody] = { content: {} } unless value.dig(:requestBody, :content)
62
63
  value[:requestBody][:required] = true if schema_param[:required]
64
+ value[:requestBody][:description] = schema_param[:description] if schema_param[:description]
63
65
  mime_list.each do |mime|
64
66
  value[:requestBody][:content][mime] = { schema: schema_param[:schema] }
65
67
  end
@@ -196,8 +198,8 @@ module Rswag
196
198
 
197
199
  def remove_invalid_operation_keys!(value)
198
200
  is_hash = value.is_a?(Hash)
199
- value.delete(:consumes) if is_hash && value.dig(:consumes)
200
- value.delete(:produces) if is_hash && value.dig(:produces)
201
+ value.delete(:consumes) if is_hash && value[:consumes]
202
+ value.delete(:produces) if is_hash && value[:produces]
201
203
  end
202
204
  end
203
205
  end
@@ -11,10 +11,15 @@ namespace :rswag do
11
11
  'spec/requests/**/*_spec.rb, spec/api/**/*_spec.rb, spec/integration/**/*_spec.rb'
12
12
  )
13
13
 
14
- # NOTE: rspec 2.x support
14
+ additional_rspec_opts = ENV.fetch(
15
+ 'ADDITIONAL_RSPEC_OPTS',
16
+ ''
17
+ )
18
+
15
19
  if Rswag::Specs::RSPEC_VERSION > 2 && Rswag::Specs.config.swagger_dry_run
16
- t.rspec_opts = ['--format Rswag::Specs::SwaggerFormatter', '--dry-run', '--order defined']
20
+ t.rspec_opts = ['--format Rswag::Specs::SwaggerFormatter', '--dry-run', '--order defined'] << additional_rspec_opts
17
21
  else
22
+ ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: Support for RSpec 2.X will be dropped in v3.0')
18
23
  t.rspec_opts = ['--format Rswag::Specs::SwaggerFormatter', '--order defined']
19
24
  end
20
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rswag-specs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richie Morris
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-02-10 00:00:00.000000000 Z
13
+ date: 2022-10-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -56,19 +56,53 @@ dependencies:
56
56
  name: json-schema
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '2.2'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '4.0'
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
- - - "~>"
69
+ - - ">="
67
70
  - !ruby/object:Gem::Version
68
71
  version: '2.2'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '4.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-core
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '2.14'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '2.14'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '='
94
+ - !ruby/object:Gem::Version
95
+ version: 0.21.2
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '='
101
+ - !ruby/object:Gem::Version
102
+ version: 0.21.2
69
103
  description: 'Simplify API integration testing with a succinct rspec DSL and generate
70
- OpenAPI specification files directly from your rspecs. More about the OpenAPI initiative
71
- here: http://spec.openapis.org/'
104
+ OpenAPI specification files directly from your rspec tests. More about the OpenAPI
105
+ initiative here: http://spec.openapis.org/'
72
106
  email:
73
107
  - domaindrivendev@gmail.com
74
108
  executables: []