rspec-openapi 0.21.0 → 0.21.2
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/codeql-analysis.yml +1 -1
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/test.yml +1 -1
- data/.gitignore +1 -0
- data/lib/rspec/openapi/schema_builder.rb +73 -43
- data/lib/rspec/openapi/schema_merger.rb +2 -0
- data/lib/rspec/openapi/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3d8b74f9e75f015e91e3ebc37ab353459d0a8d887fb096ad7e9fcf829898290e
|
|
4
|
+
data.tar.gz: 1fdbc903fdb61f685ca02d63a88a82eb9a3184e00a0766f1e31e82001ed068b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb64851800a090a4cf4d9f78921f1203456ddf8b9d4e820af73d9449a259c7d6e5dd9997e01058136b0dc7b551bc5406e2e176f2818c27b6d7e5a6a00a136fb3
|
|
7
|
+
data.tar.gz: 82600b4917083f3b4a27f7bf4ee8b8b4314dc76a4c9c03f5143e5e182d652edea3cb6cef97f7b2f3598a2c27f143fdcb714058143d47fb44d2ccb6181fafe4fd
|
data/.github/workflows/test.yml
CHANGED
|
@@ -32,7 +32,7 @@ jobs:
|
|
|
32
32
|
RAILS_VERSION: ${{ matrix.rails == '' && '6.1.6' || matrix.rails }}
|
|
33
33
|
COVERAGE: ${{ matrix.coverage || '' }}
|
|
34
34
|
steps:
|
|
35
|
-
- uses: actions/checkout@
|
|
35
|
+
- uses: actions/checkout@v6
|
|
36
36
|
- name: bundle install
|
|
37
37
|
run: bundle install -j$(nproc) --retry 3
|
|
38
38
|
- run: bundle exec rspec
|
data/.gitignore
CHANGED
|
@@ -246,69 +246,99 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
|
246
246
|
|
|
247
247
|
def build_array_items_schema(array, record: nil)
|
|
248
248
|
return {} if array.empty?
|
|
249
|
+
return build_property(array.first, record: record) if array.size == 1
|
|
250
|
+
return build_property(array.first, record: record) unless array.all? { |item| item.is_a?(Hash) }
|
|
249
251
|
|
|
250
|
-
|
|
252
|
+
all_schemas = array.map { |item| build_property(item, record: record) }
|
|
253
|
+
merged_schema = all_schemas.first.dup
|
|
254
|
+
merged_schema[:properties] = {}
|
|
251
255
|
|
|
252
|
-
|
|
253
|
-
if array.size > 1 && array.all? { |item| item.is_a?(Hash) }
|
|
254
|
-
array[1..].each do |item|
|
|
255
|
-
item_schema = build_property(item, record: record)
|
|
256
|
-
merged_schema = merge_object_schemas(merged_schema, item_schema)
|
|
257
|
-
end
|
|
258
|
-
end
|
|
256
|
+
all_keys = all_schemas.flat_map { |s| s[:properties]&.keys || [] }.uniq
|
|
259
257
|
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
all_keys.each do |key|
|
|
259
|
+
all_property_schemas = all_schemas.map { |s| s[:properties]&.[](key) }
|
|
260
|
+
|
|
261
|
+
nullable_only_schemas = all_property_schemas.select { |p| p && p.keys == [:nullable] }
|
|
262
|
+
property_variations = all_property_schemas.select { |p| p && p.keys != [:nullable] }
|
|
262
263
|
|
|
263
|
-
|
|
264
|
-
return schema1 unless schema2.is_a?(Hash) && schema1.is_a?(Hash)
|
|
265
|
-
return schema1 unless schema1[:type] == 'object' && schema2[:type] == 'object'
|
|
264
|
+
has_nullable = all_property_schemas.any?(&:nil?) || nullable_only_schemas.any?
|
|
266
265
|
|
|
267
|
-
|
|
266
|
+
next if property_variations.empty? && !has_nullable
|
|
268
267
|
|
|
269
|
-
|
|
270
|
-
|
|
268
|
+
if property_variations.empty? && has_nullable
|
|
269
|
+
merged_schema[:properties][key] = { nullable: true }
|
|
270
|
+
elsif property_variations.size == 1
|
|
271
|
+
merged_schema[:properties][key] = property_variations.first.dup
|
|
272
|
+
else
|
|
273
|
+
unique_types = property_variations.map { |p| p[:type] }.compact.uniq
|
|
271
274
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
275
|
+
case unique_types.first
|
|
276
|
+
when 'array'
|
|
277
|
+
merged_schema[:properties][key] = { type: 'array' }
|
|
278
|
+
items_variations = property_variations.map { |p| p[:items] }.compact
|
|
279
|
+
merged_schema[:properties][key][:items] = build_merged_schema_from_variations(items_variations)
|
|
280
|
+
when 'object'
|
|
281
|
+
merged_schema[:properties][key] = build_merged_schema_from_variations(property_variations)
|
|
276
282
|
else
|
|
277
|
-
|
|
283
|
+
merged_schema[:properties][key] = property_variations.first.dup
|
|
278
284
|
end
|
|
279
285
|
end
|
|
280
286
|
|
|
281
|
-
|
|
282
|
-
merged[:properties][key] = make_property_nullable(prop1) unless schema2[:properties][key]
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
required1 = Set.new(schema1[:required] || [])
|
|
286
|
-
required2 = Set.new(schema2[:required] || [])
|
|
287
|
-
merged[:required] = (required1 & required2).to_a
|
|
287
|
+
merged_schema[:properties][key][:nullable] = true if has_nullable && merged_schema[:properties][key].is_a?(Hash)
|
|
288
288
|
end
|
|
289
289
|
|
|
290
|
-
|
|
290
|
+
all_required_sets = all_schemas.map { |s| s[:required] || [] }
|
|
291
|
+
merged_schema[:required] = all_required_sets.reduce(:&) || []
|
|
292
|
+
|
|
293
|
+
merged_schema
|
|
291
294
|
end
|
|
292
295
|
|
|
293
|
-
def
|
|
294
|
-
return
|
|
296
|
+
def build_merged_schema_from_variations(variations)
|
|
297
|
+
return {} if variations.empty?
|
|
298
|
+
return variations.first if variations.size == 1
|
|
295
299
|
|
|
296
|
-
|
|
300
|
+
types = variations.map { |v| v[:type] }.compact.uniq
|
|
297
301
|
|
|
298
|
-
|
|
299
|
-
|
|
302
|
+
if types.size == 1 && types.first == 'object'
|
|
303
|
+
merged = { type: 'object', properties: {} }
|
|
304
|
+
all_keys = variations.flat_map { |v| v[:properties]&.keys || [] }.uniq
|
|
300
305
|
|
|
301
|
-
|
|
302
|
-
|
|
306
|
+
all_keys.each do |key|
|
|
307
|
+
all_prop_variations = variations.map { |v| v[:properties]&.[](key) }
|
|
303
308
|
|
|
304
|
-
|
|
305
|
-
|
|
309
|
+
nullable_only = all_prop_variations.select { |p| p && p.keys == [:nullable] }
|
|
310
|
+
prop_variations = all_prop_variations.select { |p| p && p.keys != [:nullable] }.compact
|
|
306
311
|
|
|
307
|
-
|
|
308
|
-
return property unless property.is_a?(Hash)
|
|
312
|
+
has_nullable = all_prop_variations.any?(&:nil?) || nullable_only.any?
|
|
309
313
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
if prop_variations.size == 1
|
|
315
|
+
merged[:properties][key] = prop_variations.first.dup
|
|
316
|
+
merged[:properties][key][:nullable] = true if has_nullable
|
|
317
|
+
elsif prop_variations.size > 1
|
|
318
|
+
prop_types = prop_variations.map { |p| p[:type] }.compact.uniq
|
|
319
|
+
|
|
320
|
+
if prop_types.size == 1
|
|
321
|
+
# Only recursively merge if it's an object type
|
|
322
|
+
merged[:properties][key] = if prop_types.first == 'object'
|
|
323
|
+
build_merged_schema_from_variations(prop_variations)
|
|
324
|
+
else
|
|
325
|
+
prop_variations.first.dup
|
|
326
|
+
end
|
|
327
|
+
else
|
|
328
|
+
unique_props = prop_variations.map { |p| p.reject { |k, _| k == :nullable } }.uniq
|
|
329
|
+
merged[:properties][key] = { oneOf: unique_props }
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
merged[:properties][key][:nullable] = true if has_nullable || prop_variations.size < variations.size
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
all_required = variations.map { |v| v[:required] || [] }
|
|
337
|
+
merged[:required] = all_required.reduce(:&) || []
|
|
338
|
+
|
|
339
|
+
merged
|
|
340
|
+
else
|
|
341
|
+
variations.first
|
|
342
|
+
end
|
|
313
343
|
end
|
|
314
344
|
end
|
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.21.
|
|
4
|
+
version: 0.21.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Takashi Kokubun
|
|
@@ -108,7 +108,7 @@ licenses:
|
|
|
108
108
|
metadata:
|
|
109
109
|
homepage_uri: https://github.com/exoego/rspec-openapi
|
|
110
110
|
source_code_uri: https://github.com/exoego/rspec-openapi
|
|
111
|
-
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.21.
|
|
111
|
+
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.21.2
|
|
112
112
|
rubygems_mfa_required: 'true'
|
|
113
113
|
rdoc_options: []
|
|
114
114
|
require_paths:
|