rspec-openapi 0.3.13 → 0.3.18
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/FUNDING.yml +1 -0
- data/CHANGELOG.md +27 -0
- data/lib/rspec/openapi/hooks.rb +16 -1
- data/lib/rspec/openapi/record.rb +1 -0
- data/lib/rspec/openapi/record_builder.rb +4 -2
- data/lib/rspec/openapi/schema_builder.rb +30 -7
- data/lib/rspec/openapi/schema_merger.rb +7 -0
- data/lib/rspec/openapi/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd7d2eb0e69e2e60405a7d71d10acd3b2edf2d4db0358297a900200a0a69012e
|
4
|
+
data.tar.gz: 577545384d404ba11382ab4425e0bd40abeeb3e58db922e82d923f0d6d6ae8e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f60ee2cf93946405e3e151786965b3a0f68e53ad147a6d7613f59f46f834efd9a641d0f878943af934879d2f5e27e8c8d4cd55dac5288d62a85dc2b77009ddb
|
7
|
+
data.tar.gz: 7dc56150dfb4a8a5b526d7ec626b4ebc9c0680878cd1f976213490a489a598dfe2a285f01029e5a17cdbbe0d8b492fe79a2e51148ac24df94d532c404b0231fd
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: k0kubun
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## v0.3.18
|
2
|
+
|
3
|
+
* Support nested query parameters
|
4
|
+
[#29](https://github.com/k0kubun/rspec-openapi/pull/29)
|
5
|
+
|
6
|
+
## v0.3.17
|
7
|
+
|
8
|
+
* Rescue NotImplementedError in the after suite hook as well
|
9
|
+
[#28](https://github.com/k0kubun/rspec-openapi/pull/28)
|
10
|
+
|
11
|
+
## v0.3.16
|
12
|
+
|
13
|
+
* Use `media_type` instead of `content_type` for Rails 6.1
|
14
|
+
[#26](https://github.com/k0kubun/rspec-openapi/pull/26)
|
15
|
+
* Avoid crashing the after suite hook when it fails to build schema
|
16
|
+
[#27](https://github.com/k0kubun/rspec-openapi/pull/27)
|
17
|
+
|
18
|
+
## v0.3.15
|
19
|
+
|
20
|
+
* Fix an error when Content-Disposition header is inline
|
21
|
+
[#24](https://github.com/k0kubun/rspec-openapi/pull/24)
|
22
|
+
|
23
|
+
## v0.3.14
|
24
|
+
|
25
|
+
* Avoid an error when an application calls `request.body.read`
|
26
|
+
[#20](https://github.com/k0kubun/rspec-openapi/pull/20)
|
27
|
+
|
1
28
|
## v0.3.13
|
2
29
|
|
3
30
|
* Avoid crashing when there's no request made in a spec
|
data/lib/rspec/openapi/hooks.rb
CHANGED
@@ -6,6 +6,7 @@ require 'rspec/openapi/schema_file'
|
|
6
6
|
require 'rspec/openapi/schema_merger'
|
7
7
|
|
8
8
|
records = []
|
9
|
+
records_errors = []
|
9
10
|
|
10
11
|
RSpec.configuration.after(:each) do |example|
|
11
12
|
if example.metadata[:type] == :request && example.metadata[:openapi] != false
|
@@ -19,7 +20,21 @@ RSpec.configuration.after(:suite) do
|
|
19
20
|
RSpec::OpenAPI::SchemaFile.new(RSpec::OpenAPI.path).edit do |spec|
|
20
21
|
RSpec::OpenAPI::SchemaMerger.reverse_merge!(spec, RSpec::OpenAPI::DefaultSchema.build(title))
|
21
22
|
records.each do |record|
|
22
|
-
|
23
|
+
begin
|
24
|
+
RSpec::OpenAPI::SchemaMerger.reverse_merge!(spec, RSpec::OpenAPI::SchemaBuilder.build(record))
|
25
|
+
rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
|
26
|
+
# NOTE: Don't fail the build
|
27
|
+
records_errors << [e, record]
|
28
|
+
end
|
23
29
|
end
|
24
30
|
end
|
31
|
+
if records_errors.any?
|
32
|
+
error_message = <<~EOS
|
33
|
+
RSpec::OpenAPI got errors building #{records_errors.size} requests
|
34
|
+
|
35
|
+
#{records_errors.map {|e, record| "#{e.inspect}: #{record.inspect}" }.join("\n")}
|
36
|
+
EOS
|
37
|
+
colorizer = ::RSpec::Core::Formatters::ConsoleCodes
|
38
|
+
RSpec.configuration.reporter.message colorizer.wrap(error_message, :failure)
|
39
|
+
end
|
25
40
|
end
|
data/lib/rspec/openapi/record.rb
CHANGED
@@ -11,5 +11,6 @@ RSpec::OpenAPI::Record = Struct.new(
|
|
11
11
|
:status, # @param [Integer] - 200
|
12
12
|
:response_body, # @param [Object] - {"status" => "ok"}
|
13
13
|
:response_content_type, # @param [String] - "application/json"
|
14
|
+
:response_content_disposition, # @param [String] - "inline"
|
14
15
|
keyword_init: true,
|
15
16
|
)
|
@@ -8,6 +8,7 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
|
|
8
8
|
def build(context, example:)
|
9
9
|
if rack_test?(context)
|
10
10
|
request = ActionDispatch::Request.new(context.last_request.env)
|
11
|
+
request.body.rewind if request.body.respond_to?(:rewind)
|
11
12
|
response = ActionDispatch::TestResponse.new(*context.last_response.to_a)
|
12
13
|
else
|
13
14
|
request = context.request
|
@@ -39,13 +40,14 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
|
|
39
40
|
path_params: raw_path_params(request),
|
40
41
|
query_params: request.query_parameters,
|
41
42
|
request_params: raw_request_params(request),
|
42
|
-
request_content_type: request.
|
43
|
+
request_content_type: request.media_type,
|
43
44
|
summary: summary,
|
44
45
|
tags: tags,
|
45
46
|
description: RSpec::OpenAPI.description_builder.call(example),
|
46
47
|
status: response.status,
|
47
48
|
response_body: response_body,
|
48
|
-
response_content_type: response.
|
49
|
+
response_content_type: response.media_type,
|
50
|
+
response_content_disposition: response.header["Content-Disposition"],
|
49
51
|
).freeze
|
50
52
|
end
|
51
53
|
|
@@ -7,10 +7,11 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
7
7
|
}
|
8
8
|
|
9
9
|
if record.response_body
|
10
|
+
disposition = normalize_content_disposition(record.response_content_disposition)
|
10
11
|
response[:content] = {
|
11
12
|
normalize_content_type(record.response_content_type) => {
|
12
|
-
schema: build_property(record.response_body),
|
13
|
-
example: (record
|
13
|
+
schema: build_property(record.response_body, disposition: disposition),
|
14
|
+
example: response_example(record, disposition: disposition),
|
14
15
|
}.compact,
|
15
16
|
}
|
16
17
|
end
|
@@ -34,6 +35,12 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
38
|
+
def response_example(record, disposition:)
|
39
|
+
return nil if !example_enabled? || disposition
|
40
|
+
|
41
|
+
record.response_body
|
42
|
+
end
|
43
|
+
|
37
44
|
def example_enabled?
|
38
45
|
RSpec::OpenAPI.enable_example
|
39
46
|
end
|
@@ -43,7 +50,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
43
50
|
|
44
51
|
record.path_params.each do |key, value|
|
45
52
|
parameters << {
|
46
|
-
name: key
|
53
|
+
name: build_parameter_name(key, value),
|
47
54
|
in: 'path',
|
48
55
|
required: true,
|
49
56
|
schema: build_property(try_cast(value)),
|
@@ -53,7 +60,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
53
60
|
|
54
61
|
record.query_params.each do |key, value|
|
55
62
|
parameters << {
|
56
|
-
name: key
|
63
|
+
name: build_parameter_name(key, value),
|
57
64
|
in: 'query',
|
58
65
|
schema: build_property(try_cast(value)),
|
59
66
|
example: (try_cast(value) if example_enabled?),
|
@@ -64,6 +71,16 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
64
71
|
parameters
|
65
72
|
end
|
66
73
|
|
74
|
+
def build_parameter_name(key, value)
|
75
|
+
key = key.to_s
|
76
|
+
if value.is_a?(Hash) && (value_keys = value.keys).size == 1
|
77
|
+
value_key = value_keys.first
|
78
|
+
build_parameter_name("#{key}[#{value_key}]", value[value_key])
|
79
|
+
else
|
80
|
+
key
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
67
84
|
def build_request_body(record)
|
68
85
|
return nil if record.request_content_type.nil?
|
69
86
|
return nil if record.request_params.empty?
|
@@ -78,8 +95,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
78
95
|
}
|
79
96
|
end
|
80
97
|
|
81
|
-
def build_property(value)
|
82
|
-
property = build_type(value)
|
98
|
+
def build_property(value, disposition: nil)
|
99
|
+
property = build_type(value, disposition)
|
83
100
|
|
84
101
|
case value
|
85
102
|
when Array
|
@@ -94,7 +111,9 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
94
111
|
property
|
95
112
|
end
|
96
113
|
|
97
|
-
def build_type(value)
|
114
|
+
def build_type(value, disposition)
|
115
|
+
return { type: 'string', format: 'binary' } if disposition
|
116
|
+
|
98
117
|
case value
|
99
118
|
when String
|
100
119
|
{ type: 'string' }
|
@@ -143,4 +162,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
143
162
|
def normalize_content_type(content_type)
|
144
163
|
content_type&.sub(/;.+\z/, '')
|
145
164
|
end
|
165
|
+
|
166
|
+
def normalize_content_disposition(content_disposition)
|
167
|
+
content_disposition&.sub(/;.+\z/, '')
|
168
|
+
end
|
146
169
|
end
|
@@ -30,6 +30,13 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
|
|
30
30
|
deep_reverse_merge!(base[key], value)
|
31
31
|
elsif !base.key?(key)
|
32
32
|
base[key] = value
|
33
|
+
elsif base[key].is_a?(Array) && value.is_a?(Array)
|
34
|
+
if key == "parameters"
|
35
|
+
# merge arrays
|
36
|
+
base[key] |= value
|
37
|
+
end
|
38
|
+
else
|
39
|
+
# no-op
|
33
40
|
end
|
34
41
|
end
|
35
42
|
base
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-openapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -45,6 +45,7 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- ".github/FUNDING.yml"
|
48
49
|
- ".github/workflows/test.yml"
|
49
50
|
- ".gitignore"
|
50
51
|
- ".rspec"
|
@@ -89,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
90
|
- !ruby/object:Gem::Version
|
90
91
|
version: '0'
|
91
92
|
requirements: []
|
92
|
-
rubygems_version: 3.2
|
93
|
+
rubygems_version: 3.1.2
|
93
94
|
signing_key:
|
94
95
|
specification_version: 4
|
95
96
|
summary: Generate OpenAPI schema from RSpec request specs
|