rspec-openapi 0.17.0 → 0.18.1
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/release.yaml +24 -0
- data/.github/workflows/test.yml +3 -4
- data/.rubocop_todo.yml +5 -5
- data/Gemfile +1 -1
- data/lib/rspec/openapi/extractors/hanami.rb +8 -12
- data/lib/rspec/openapi/extractors/rack.rb +1 -1
- data/lib/rspec/openapi/extractors/rails.rb +28 -11
- data/lib/rspec/openapi/extractors.rb +7 -0
- data/lib/rspec/openapi/schema_builder.rb +8 -8
- data/lib/rspec/openapi/version.rb +1 -1
- data/lib/rspec/openapi.rb +17 -11
- 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: 20d994264ab34877708e7c467c98b31f1b672ee0d73b953f2791e404895eed58
|
4
|
+
data.tar.gz: 6c319639b445a9178919a435a7816d0dfb5d8156c71d0fe1f929ab76d4733086
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7526eb5af4a66264ad5874c9f3fb3c9dd964196a3d91d7e0739956443fc643646822038c90a707a9b9fb5e26bba9bccd5652973ef227f4c8dd961a440a4682e
|
7
|
+
data.tar.gz: e3d71afaa32041ba31266832c51d4241e248cba2cb4b607adbd157b0164eedab4ef9d5e17ab89c7e196b52a64365aab584aa0dae1f5f0c0701f4dfde49f1f26c
|
@@ -0,0 +1,24 @@
|
|
1
|
+
changelog:
|
2
|
+
exclude:
|
3
|
+
labels:
|
4
|
+
- ignore-for-release
|
5
|
+
authors:
|
6
|
+
- octocat
|
7
|
+
categories:
|
8
|
+
- title: 🛠 Breaking Changes
|
9
|
+
labels:
|
10
|
+
- semver-major
|
11
|
+
- breaking-change
|
12
|
+
- title: 🎉 Exciting New Features
|
13
|
+
labels:
|
14
|
+
- semver-minor
|
15
|
+
- enhancement
|
16
|
+
- title: 🐞 Bugfixes
|
17
|
+
labels:
|
18
|
+
- bug
|
19
|
+
- title: 📄 Documentation
|
20
|
+
labels:
|
21
|
+
- documentation
|
22
|
+
- title: 📦 Other Changes
|
23
|
+
labels:
|
24
|
+
- "*"
|
data/.github/workflows/test.yml
CHANGED
@@ -19,13 +19,12 @@ jobs:
|
|
19
19
|
- ruby: ruby:2.7
|
20
20
|
- ruby: ruby:3.0
|
21
21
|
- ruby: ruby:3.1
|
22
|
-
rails: 6.0.5
|
23
22
|
- ruby: ruby:3.1
|
24
|
-
rails: 6.1.
|
23
|
+
rails: 6.1.7
|
25
24
|
- ruby: ruby:3.1
|
26
|
-
rails: 7.0.
|
25
|
+
rails: 7.0.8
|
27
26
|
- ruby: ruby:3.3
|
28
|
-
rails: 7.1.2
|
27
|
+
rails: 7.1.3.2
|
29
28
|
coverage: coverage
|
30
29
|
env:
|
31
30
|
RAILS_VERSION: ${{ matrix.rails == '' && '6.1.6' || matrix.rails }}
|
data/.rubocop_todo.yml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2024-04-
|
3
|
+
# on 2024-04-20 21:25:22 UTC using RuboCop version 1.62.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 14
|
10
10
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
11
11
|
Metrics/AbcSize:
|
12
|
-
Max:
|
12
|
+
Max: 46
|
13
13
|
|
14
14
|
# Offense count: 1
|
15
15
|
# Configuration parameters: CountComments, CountAsOne.
|
@@ -19,7 +19,7 @@ Metrics/ClassLength:
|
|
19
19
|
# Offense count: 9
|
20
20
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
21
21
|
Metrics/CyclomaticComplexity:
|
22
|
-
Max:
|
22
|
+
Max: 13
|
23
23
|
|
24
24
|
# Offense count: 22
|
25
25
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
@@ -29,7 +29,7 @@ Metrics/MethodLength:
|
|
29
29
|
# Offense count: 5
|
30
30
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
31
31
|
Metrics/PerceivedComplexity:
|
32
|
-
Max:
|
32
|
+
Max: 13
|
33
33
|
|
34
34
|
# Offense count: 1
|
35
35
|
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
data/Gemfile
CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in rspec-openapi.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem 'rails', ENV['RAILS_VERSION'] || '6.0.
|
8
|
+
gem 'rails', ENV['RAILS_VERSION'] || '6.0.6.1'
|
9
9
|
|
10
10
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
|
11
11
|
gem 'hanami', ENV['HANAMI_VERSION'] || '2.1.0'
|
@@ -48,10 +48,14 @@ Hanami::Slice::ClassMethods.prepend(InspectorAnalyzerPrepender)
|
|
48
48
|
|
49
49
|
# Extractor for hanami
|
50
50
|
class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
51
|
-
# @param [
|
51
|
+
# @param [ActionDispatch::Request] request
|
52
52
|
# @param [RSpec::Core::Example] example
|
53
53
|
# @return Array
|
54
54
|
def request_attributes(request, example)
|
55
|
+
route = Hanami.app.router.recognize(request.path, method: request.method)
|
56
|
+
|
57
|
+
return RSpec::OpenAPI::Extractors::Rack.request_attributes(request, example) unless route.routable?
|
58
|
+
|
55
59
|
metadata = example.metadata[:openapi] || {}
|
56
60
|
summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
|
57
61
|
tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
|
@@ -62,9 +66,7 @@ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
|
62
66
|
deprecated = metadata[:deprecated]
|
63
67
|
path = request.path
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
raw_path_params = route.params.filter { |_key, value| number_or_nil(value) }
|
69
|
+
raw_path_params = route.params.filter { |_key, value| RSpec::OpenAPI::Extractors.number_or_nil(value) }
|
68
70
|
|
69
71
|
result = InspectorAnalyzer.call(request.method, add_id(path, route))
|
70
72
|
|
@@ -90,7 +92,7 @@ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
|
90
92
|
return path if route.params.empty?
|
91
93
|
|
92
94
|
route.params.each_pair do |key, value|
|
93
|
-
next unless number_or_nil(value)
|
95
|
+
next unless RSpec::OpenAPI::Extractors.number_or_nil(value)
|
94
96
|
|
95
97
|
path = path.sub("/#{value}", "/:#{key}")
|
96
98
|
end
|
@@ -102,17 +104,11 @@ class << RSpec::OpenAPI::Extractors::Hanami = Object.new
|
|
102
104
|
return path if route.params.empty?
|
103
105
|
|
104
106
|
route.params.each_pair do |key, value|
|
105
|
-
next unless number_or_nil(value)
|
107
|
+
next unless RSpec::OpenAPI::Extractors.number_or_nil(value)
|
106
108
|
|
107
109
|
path = path.sub("/#{value}", "/{#{key}}")
|
108
110
|
end
|
109
111
|
|
110
112
|
path
|
111
113
|
end
|
112
|
-
|
113
|
-
def number_or_nil(string)
|
114
|
-
Integer(string || '')
|
115
|
-
rescue ArgumentError
|
116
|
-
nil
|
117
|
-
end
|
118
114
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Extractor for rack
|
4
4
|
class << RSpec::OpenAPI::Extractors::Rack = Object.new
|
5
|
-
# @param [
|
5
|
+
# @param [ActionDispatch::Request] request
|
6
6
|
# @param [RSpec::Core::Example] example
|
7
7
|
# @return Array
|
8
8
|
def request_attributes(request, example)
|
@@ -2,10 +2,20 @@
|
|
2
2
|
|
3
3
|
# Extractor for rails
|
4
4
|
class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
5
|
-
# @param [
|
5
|
+
# @param [ActionDispatch::Request] request
|
6
6
|
# @param [RSpec::Core::Example] example
|
7
7
|
# @return Array
|
8
8
|
def request_attributes(request, example)
|
9
|
+
# Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
|
10
|
+
fixed_request = request.dup
|
11
|
+
fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
|
12
|
+
|
13
|
+
route, path = find_rails_route(fixed_request)
|
14
|
+
|
15
|
+
raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
|
16
|
+
|
17
|
+
return RSpec::OpenAPI::Extractors::Rack.request_attributes(request, example) unless path
|
18
|
+
|
9
19
|
metadata = example.metadata[:openapi] || {}
|
10
20
|
summary = metadata[:summary] || RSpec::OpenAPI.summary_builder.call(example)
|
11
21
|
tags = metadata[:tags] || RSpec::OpenAPI.tags_builder.call(example)
|
@@ -16,14 +26,6 @@ class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
|
16
26
|
deprecated = metadata[:deprecated]
|
17
27
|
raw_path_params = request.path_parameters
|
18
28
|
|
19
|
-
# Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
|
20
|
-
fixed_request = request.dup
|
21
|
-
fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
|
22
|
-
|
23
|
-
route, path = find_rails_route(fixed_request)
|
24
|
-
raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
|
25
|
-
|
26
|
-
path = path.delete_suffix('(.:format)')
|
27
29
|
summary ||= route.requirements[:action]
|
28
30
|
tags ||= [route.requirements[:controller]&.classify].compact
|
29
31
|
# :controller and :action always exist. :format is added when routes is configured as such.
|
@@ -42,12 +44,17 @@ class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
|
42
44
|
|
43
45
|
# @param [ActionDispatch::Request] request
|
44
46
|
def find_rails_route(request, app: Rails.application, path_prefix: '')
|
45
|
-
app.routes.router.recognize(request) do |route|
|
46
|
-
path = route.path.spec.to_s
|
47
|
+
app.routes.router.recognize(request) do |route, parameters|
|
48
|
+
path = route.path.spec.to_s.delete_suffix('(.:format)')
|
49
|
+
|
47
50
|
if route.app.matches?(request)
|
48
51
|
if route.app.engine?
|
49
52
|
route, path = find_rails_route(request, app: route.app.app, path_prefix: path)
|
50
53
|
next if route.nil?
|
54
|
+
elsif path_prefix + path == add_id(request.path, parameters)
|
55
|
+
return [route, path_prefix + path]
|
56
|
+
else
|
57
|
+
return [route, nil]
|
51
58
|
end
|
52
59
|
return [route, path_prefix + path]
|
53
60
|
end
|
@@ -55,4 +62,14 @@ class << RSpec::OpenAPI::Extractors::Rails = Object.new
|
|
55
62
|
|
56
63
|
nil
|
57
64
|
end
|
65
|
+
|
66
|
+
def add_id(path, parameters)
|
67
|
+
parameters.each_pair do |key, value|
|
68
|
+
next unless RSpec::OpenAPI::Extractors.number_or_nil(value)
|
69
|
+
|
70
|
+
path = path.sub("/#{value}", "/:#{key}")
|
71
|
+
end
|
72
|
+
|
73
|
+
path
|
74
|
+
end
|
58
75
|
end
|
@@ -64,10 +64,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def build_parameters(record)
|
67
|
-
|
68
|
-
|
69
|
-
record.path_params.each do |key, value|
|
70
|
-
parameters << {
|
67
|
+
path_params = record.path_params.map do |key, value|
|
68
|
+
{
|
71
69
|
name: build_parameter_name(key, value),
|
72
70
|
in: 'path',
|
73
71
|
required: true,
|
@@ -76,8 +74,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
76
74
|
}.compact
|
77
75
|
end
|
78
76
|
|
79
|
-
record.query_params.
|
80
|
-
|
77
|
+
query_params = record.query_params.map do |key, value|
|
78
|
+
{
|
81
79
|
name: build_parameter_name(key, value),
|
82
80
|
in: 'query',
|
83
81
|
required: record.required_request_params.include?(key),
|
@@ -86,8 +84,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
86
84
|
}.compact
|
87
85
|
end
|
88
86
|
|
89
|
-
record.request_headers.
|
90
|
-
|
87
|
+
header_params = record.request_headers.map do |key, value|
|
88
|
+
{
|
91
89
|
name: build_parameter_name(key, value),
|
92
90
|
in: 'header',
|
93
91
|
required: true,
|
@@ -96,6 +94,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
|
|
96
94
|
}.compact
|
97
95
|
end
|
98
96
|
|
97
|
+
parameters = path_params + query_params + header_params
|
98
|
+
|
99
99
|
return nil if parameters.empty?
|
100
100
|
|
101
101
|
parameters
|
data/lib/rspec/openapi.rb
CHANGED
@@ -15,18 +15,24 @@ require 'rspec/openapi/shared_hooks'
|
|
15
15
|
require 'rspec/openapi/extractors'
|
16
16
|
require 'rspec/openapi/extractors/rack'
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
if ENV['OPENAPI']
|
19
|
+
DEBUG_ENABLED = ['', '1', 'true'].include?(ENV['DEBUG']&.downcase)
|
20
|
+
|
21
|
+
begin
|
22
|
+
require 'hanami'
|
23
|
+
rescue LoadError
|
24
|
+
warn 'Hanami not detected' if DEBUG_ENABLED
|
25
|
+
else
|
26
|
+
require 'rspec/openapi/extractors/hanami'
|
27
|
+
end
|
24
28
|
|
25
|
-
begin
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
begin
|
30
|
+
require 'rails'
|
31
|
+
rescue LoadError
|
32
|
+
warn 'Rails not detected' if DEBUG_ENABLED
|
33
|
+
else
|
34
|
+
require 'rspec/openapi/extractors/rails'
|
35
|
+
end
|
30
36
|
end
|
31
37
|
|
32
38
|
require 'rspec/openapi/minitest_hooks' if Object.const_defined?('Minitest')
|
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.
|
4
|
+
version: 0.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-04-
|
12
|
+
date: 2024-04-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -62,6 +62,7 @@ extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
64
|
- ".github/dependabot.yml"
|
65
|
+
- ".github/release.yaml"
|
65
66
|
- ".github/workflows/codeql-analysis.yml"
|
66
67
|
- ".github/workflows/rubocop.yml"
|
67
68
|
- ".github/workflows/test.yml"
|
@@ -108,7 +109,7 @@ licenses:
|
|
108
109
|
metadata:
|
109
110
|
homepage_uri: https://github.com/exoego/rspec-openapi
|
110
111
|
source_code_uri: https://github.com/exoego/rspec-openapi
|
111
|
-
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.
|
112
|
+
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.18.1
|
112
113
|
rubygems_mfa_required: 'true'
|
113
114
|
post_install_message:
|
114
115
|
rdoc_options: []
|