rspec-openapi 0.33.1 → 0.34.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb54f98b3234ebee5ea46c0c703f094265d37c17f8fc1c8dcfec5c1f70c88667
4
- data.tar.gz: 30972c7a4dd8387e1db47d954b3b5e380ee9a0d6282981ba73d14007e5fcdce8
3
+ metadata.gz: d493f4696b8bf07c0dcdfe1cbfb4d06736ac7b7efc3c103b8692f6d7aab01db7
4
+ data.tar.gz: 38e4d7f3268a4d84e60ad6f047c3176b1d161ef895f5648422d7231e34ccfff5
5
5
  SHA512:
6
- metadata.gz: 19552292efc3339da373ca62b6e7c20ce23546d5ba81bd7b245ce6796dca729a12fd4138c905b11d90b9892e67f0a3abc18f15eaf7ea8f153f3a4c4b5f76de3c
7
- data.tar.gz: ff754813db11c90118d4169428547b84c7c5a7163384124e94c15eefacff9dd62e701cc6c0c37716cb889dccba061086858ccc32161ed41f4a275d2a0eb8fcff
6
+ metadata.gz: c1dbea1b90c265e2e636a77f406456c2e871fdefa476845538cd44d4486887e09298ce3e55406cb1e2f0c9305a030328a1300638a9804753c56d3b56b40e96cb
7
+ data.tar.gz: 597cf318feef44fa58393dc94c3f4101d990e755028df0df16f76024aa6d79baff86a6d689b5f968c792a8e86e695ddd8f7abfdf89b2c314c9d4c381b83a4309
@@ -10,14 +10,26 @@ class << RSpec::OpenAPI::ComponentsUpdater = Object.new
10
10
  def update!(base, fresh)
11
11
  # Top-level schema: Used as the body of request or response
12
12
  top_level_refs = paths_to_top_level_refs(base)
13
- return if top_level_refs.empty?
14
-
15
13
  fresh_schemas = build_fresh_schemas(top_level_refs, base, fresh)
16
14
 
17
- # Nested schema: References in Top-level schemas. May contain some top-level schema.
18
- generated_schema_names = fresh_schemas.keys
19
- nested_refs = find_non_top_level_nested_refs(base, generated_schema_names)
20
- nested_refs.each do |paths|
15
+ # Nested schema: References in top-level schemas. May contain some top-level schema.
16
+ # A parent to dig fresh data out of only exists once some top-level schema was found.
17
+ apply_component_nested_refs!(fresh_schemas, base) unless top_level_refs.empty?
18
+
19
+ # Nested schema: References inline in a request/response body, not inside a component.
20
+ # Unlike the above, this doesn't depend on any top-level schema being found first.
21
+ apply_inline_nested_refs!(fresh_schemas, base, fresh)
22
+
23
+ return if fresh_schemas.empty?
24
+
25
+ RSpec::OpenAPI::SchemaMerger.merge_normalized!(base, { components: { schemas: fresh_schemas } })
26
+ RSpec::OpenAPI::SchemaCleaner.cleanup_components_schemas!(base, { components: { schemas: fresh_schemas } })
27
+ end
28
+
29
+ private
30
+
31
+ def apply_component_nested_refs!(fresh_schemas, base)
32
+ find_non_top_level_nested_refs(base, fresh_schemas.keys).each do |paths|
21
33
  # Slice between the parent name and the element before "$ref"
22
34
  # ["components", "schema", "Table", "properties", "database", "$ref"]
23
35
  # 0 1 2 ^....................^
@@ -32,16 +44,26 @@ class << RSpec::OpenAPI::ComponentsUpdater = Object.new
32
44
  # Skip if the property using $ref is not found in the parent schema. The property may be removed.
33
45
  next if nested_schema.nil?
34
46
 
35
- schema_name = extract_schema_name(base.dig(*paths)).to_sym
36
- fresh_schemas[schema_name] ||= {}
37
- RSpec::OpenAPI::SchemaMerger.merge_normalized!(fresh_schemas[schema_name], nested_schema)
47
+ merge_fresh_schema!(fresh_schemas, base, paths, nested_schema)
38
48
  end
49
+ end
39
50
 
40
- RSpec::OpenAPI::SchemaMerger.merge_normalized!(base, { components: { schemas: fresh_schemas } })
41
- RSpec::OpenAPI::SchemaCleaner.cleanup_components_schemas!(base, { components: { schemas: fresh_schemas } })
51
+ # No promoted parent schema to dig from here, so pull the fresh data from the same
52
+ # relative path in the raw document instead.
53
+ def apply_inline_nested_refs!(fresh_schemas, base, fresh)
54
+ find_inline_nested_refs(base, fresh_schemas.keys).each do |paths|
55
+ nested_schema = fresh.dig(*paths[0..-2])
56
+ next if nested_schema.nil?
57
+
58
+ merge_fresh_schema!(fresh_schemas, base, paths, nested_schema)
59
+ end
42
60
  end
43
61
 
44
- private
62
+ def merge_fresh_schema!(fresh_schemas, base, paths, nested_schema)
63
+ schema_name = extract_schema_name(base.dig(*paths)).to_sym
64
+ fresh_schemas[schema_name] ||= {}
65
+ RSpec::OpenAPI::SchemaMerger.merge_normalized!(fresh_schemas[schema_name], nested_schema)
66
+ end
45
67
 
46
68
  def build_fresh_schemas(references, base, fresh)
47
69
  references.inject({}) do |acc, paths|
@@ -80,7 +102,26 @@ class << RSpec::OpenAPI::ComponentsUpdater = Object.new
80
102
  *RSpec::OpenAPI::HashHelper.matched_paths_deeply_nested(base, 'components.schemas', 'properties.*.items.$ref'),
81
103
  *RSpec::OpenAPI::HashHelper.matched_paths_deeply_nested(base, 'components.schemas', 'oneOf.*.$ref'),
82
104
  ]
83
- # Reject already-generated schemas to reduce unnecessary loop
105
+ reject_already_generated_refs(nested_refs, base, generated_names)
106
+ end
107
+
108
+ # Like find_non_top_level_nested_refs, but for a $ref inside a schema that's inline
109
+ # rather than itself a component, so it's not reachable by walking components.schemas.
110
+ def find_inline_nested_refs(base, generated_names)
111
+ roots = [
112
+ 'paths.*.*.requestBody.content.application/json.schema',
113
+ 'paths.*.*.responses.*.content.application/json.schema',
114
+ ]
115
+ nested_refs = roots.flat_map do |root|
116
+ [
117
+ *RSpec::OpenAPI::HashHelper.matched_paths_deeply_nested(base, root, 'properties.*.$ref'),
118
+ *RSpec::OpenAPI::HashHelper.matched_paths_deeply_nested(base, root, 'properties.*.items.$ref'),
119
+ ]
120
+ end
121
+ reject_already_generated_refs(nested_refs, base, generated_names)
122
+ end
123
+
124
+ def reject_already_generated_refs(nested_refs, base, generated_names)
84
125
  nested_refs.reject do |paths|
85
126
  ref_link = base.dig(*paths)
86
127
  schema_name = extract_schema_name(ref_link)
@@ -27,6 +27,7 @@ class << RSpec::OpenAPI::NullableConverter = Object.new
27
27
  schema[:type] =
28
28
  case (type = schema[:type])
29
29
  when nil then 'null'
30
+ when Array then type | ['null']
30
31
  else [type, 'null']
31
32
  end
32
33
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenAPI
5
- VERSION = '0.33.1'
5
+ VERSION = '0.34.0'
6
6
  end
7
7
  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.33.1
4
+ version: 0.34.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
@@ -99,7 +99,7 @@ licenses:
99
99
  metadata:
100
100
  homepage_uri: https://github.com/exoego/rspec-openapi
101
101
  source_code_uri: https://github.com/exoego/rspec-openapi
102
- changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.33.1
102
+ changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.34.0
103
103
  rubygems_mfa_required: 'true'
104
104
  rdoc_options: []
105
105
  require_paths: