Skip to content

Commit 25b983e

Browse files
authored
Merge pull request #56 from civisanalytics/ref_or_properties
Recursively parse non-ref response schemas
2 parents 1f932cb + e03028f commit 25b983e

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
### Fixed
9+
10+
* [#56](https://github.com/civisanalytics/swagger-diff/pull/56)
11+
recursively parse non-ref response schemas (`properties` and `items`)
12+
813
## [1.1.1] - 2017-08-23
914

1015
### Added

lib/swagger/diff/specification.rb

+20-13
Original file line numberDiff line numberDiff line change
@@ -172,19 +172,28 @@ def properties_for_param(prefix, definition)
172172
properties_for_ref(prefix, definition['name'], definition, required)
173173
end
174174

175-
def properties_for_ref(prefix, name, schema, required, list = false)
175+
# rubocop:disable Metrics/ParameterLists
176+
def add_property(ret, prefix, name, schema, required, list)
176177
key = "#{prefix}#{name}"
178+
ret[:required].add(key) if required && required.include?(name)
179+
loc = if schema['in']
180+
schema['in']
181+
else
182+
'body'
183+
end
184+
ret[:all].add("#{key} (in: #{loc}, type: #{schema['type']}#{'[]' if list})")
185+
end
186+
# rubocop:enable Metrics/ParameterLists
187+
188+
def properties_for_ref(prefix, name, schema, required, list = false)
177189
ret = { required: Set.new, all: Set.new }
178-
if schema.key?('$ref')
190+
if schema['$ref']
179191
merge_refs!(ret, nested(schema['$ref'], prefix, name, list))
192+
elsif schema['properties']
193+
prefix = "#{name}#{'[]' if list}/"
194+
merge_refs!(ret, properties(schema['properties'], schema['required'], prefix))
180195
else
181-
ret[:required].add(key) if required && required.include?(name)
182-
loc = if schema['in']
183-
schema['in']
184-
else
185-
'body'
186-
end
187-
ret[:all].add("#{key} (in: #{loc}, type: #{schema['type']}#{'[]' if list})")
196+
add_property(ret, prefix, name, schema, required, list)
188197
end
189198
ret
190199
end
@@ -211,16 +220,15 @@ def hash_property(definition, prefix, name = '')
211220
"#{key} (in: body, type: Hash[string, #{type}])"
212221
end
213222

214-
# rubocop:disable Metrics/CyclomaticComplexity
215223
def properties(properties, required, prefix = '')
216224
ret = { required: Set.new, all: Set.new }
217225
properties.each do |name, schema|
218226
if schema['type'] == 'array'
219227
merge_refs!(ret, properties_for_ref(prefix, name, schema['items'], required, true))
220-
elsif schema['type'] == 'object'
228+
elsif schema['type'] == 'object' || schema['properties']
221229
if schema['allOf']
222230
# TODO: handle nested allOfs.
223-
elsif schema['type'] && schema['type'] == 'object' && schema['properties']
231+
elsif schema['properties']
224232
merge_refs!(ret, properties(schema['properties'], required, "#{prefix}#{name}/"))
225233
else
226234
ret[:all].add(hash_property(schema, prefix, name))
@@ -231,7 +239,6 @@ def properties(properties, required, prefix = '')
231239
end
232240
ret
233241
end
234-
# rubocop:enable Metrics/CyclomaticComplexity
235242

236243
def request_params_inner(params)
237244
ret = { required: Set.new, all: Set.new }

spec/swagger/diff/specification_spec.rb

+31
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,37 @@
420420
end
421421
end
422422

423+
describe 'response properties' do
424+
let(:paths) do
425+
{ '/a/' =>
426+
{ 'get' =>
427+
{ 'responses' =>
428+
{ '200' =>
429+
{ 'description' => 'A generic response',
430+
'schema' =>
431+
{ 'properties' =>
432+
{ 'data' =>
433+
{ 'type' => 'array',
434+
'items' =>
435+
{ 'properties' =>
436+
{ 'obj' =>
437+
{ 'properties' =>
438+
{ 'id' => { 'type' => 'integer' },
439+
'name' => { 'type' => 'string' },
440+
'strings' =>
441+
{ 'type' => 'array',
442+
'items' => { 'type' => 'string' } } } } } } } } } } } } } }
443+
end
444+
445+
it 'parses properties recursively' do
446+
expect(spec.response_attributes)
447+
.to eq('get /a/' =>
448+
{ '200' => Set.new(['data[]/obj/id (in: body, type: integer)',
449+
'data[]/obj/name (in: body, type: string)',
450+
'data[]/obj/strings (in: body, type: string[])']) })
451+
end
452+
end
453+
423454
describe 'response refs' do
424455
let(:paths) do
425456
{ '/a/' =>

0 commit comments

Comments
 (0)