ryquest 1.0.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 +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.rubocop.yml +20 -0
- data/Dockerfile +9 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +79 -0
- data/LICENSE.txt +21 -0
- data/Makefile +45 -0
- data/README.md +135 -0
- data/lib/ryquest/version.rb +7 -0
- data/lib/ryquest.rb +68 -0
- data/ryquest.gemspec +33 -0
- metadata +57 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b32ac1fdb4ae871b7e52a0df4179d982cc3a9a8bd8bc6bac8e7ea17b2858a81c
|
4
|
+
data.tar.gz: 80cf2f367cf8b5f321891be62fe74386f74c53b48af98309442c422e9f7c0b23
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '0415958de921a0769182be9f4fa46b13937203818b88b688d8099ad744f2ad5b0da24cd00f9db2349503badb65b33daf7c50aa3f05ebc97ce80e59d872f829ec'
|
7
|
+
data.tar.gz: b2a4c736dc8c802ed6d482a6ace36dc7cd2f2a01b2c374a9b6d93f94265e4fedd938f926d975a0750bf087a7116d395719c46ff8ea5a441847eb277cf3aae2a8
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
Exclude:
|
4
|
+
- /bin/**
|
5
|
+
|
6
|
+
Style/SingleLineMethods:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Style/MethodDefParentheses:
|
10
|
+
Enabled: false
|
11
|
+
|
12
|
+
Lint/AmbiguousRegexpLiteral:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Metrics/BlockLength:
|
16
|
+
Exclude:
|
17
|
+
- /app/spec/**/**/**/**/**/**/*.rb
|
18
|
+
|
19
|
+
Gemspec/RequiredRubyVersion:
|
20
|
+
Enabled: false
|
data/Dockerfile
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
## CORE
|
6
|
+
# Include dependencies
|
7
|
+
gemspec
|
8
|
+
|
9
|
+
## TEST
|
10
|
+
# Get some tools (included by rails) in order to run test
|
11
|
+
gem 'activesupport', '~> 6.1.4'
|
12
|
+
# Framework
|
13
|
+
gem 'rspec', '~> 3.10.0'
|
14
|
+
# Coverage
|
15
|
+
gem 'simplecov', '~> 0.19.1'
|
16
|
+
|
17
|
+
## DEV TOOLS
|
18
|
+
# Breakpoint
|
19
|
+
gem 'byebug', '~> 11.1.3'
|
20
|
+
# Linter
|
21
|
+
gem 'rubocop', '~> 1.21.0'
|
22
|
+
# Documentation
|
23
|
+
gem 'yard', '~> 0.9.26'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ryquest (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
activesupport (6.1.4.1)
|
10
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
|
+
i18n (>= 1.6, < 2)
|
12
|
+
minitest (>= 5.1)
|
13
|
+
tzinfo (~> 2.0)
|
14
|
+
zeitwerk (~> 2.3)
|
15
|
+
ast (2.4.2)
|
16
|
+
byebug (11.1.3)
|
17
|
+
concurrent-ruby (1.1.9)
|
18
|
+
diff-lcs (1.4.4)
|
19
|
+
docile (1.4.0)
|
20
|
+
i18n (1.8.11)
|
21
|
+
concurrent-ruby (~> 1.0)
|
22
|
+
minitest (5.14.4)
|
23
|
+
parallel (1.21.0)
|
24
|
+
parser (3.0.2.0)
|
25
|
+
ast (~> 2.4.1)
|
26
|
+
rainbow (3.0.0)
|
27
|
+
regexp_parser (2.1.1)
|
28
|
+
rexml (3.2.5)
|
29
|
+
rspec (3.10.0)
|
30
|
+
rspec-core (~> 3.10.0)
|
31
|
+
rspec-expectations (~> 3.10.0)
|
32
|
+
rspec-mocks (~> 3.10.0)
|
33
|
+
rspec-core (3.10.1)
|
34
|
+
rspec-support (~> 3.10.0)
|
35
|
+
rspec-expectations (3.10.1)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.10.0)
|
38
|
+
rspec-mocks (3.10.2)
|
39
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
+
rspec-support (~> 3.10.0)
|
41
|
+
rspec-support (3.10.2)
|
42
|
+
rubocop (1.21.0)
|
43
|
+
parallel (~> 1.10)
|
44
|
+
parser (>= 3.0.0.0)
|
45
|
+
rainbow (>= 2.2.2, < 4.0)
|
46
|
+
regexp_parser (>= 1.8, < 3.0)
|
47
|
+
rexml
|
48
|
+
rubocop-ast (>= 1.9.1, < 2.0)
|
49
|
+
ruby-progressbar (~> 1.7)
|
50
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
51
|
+
rubocop-ast (1.12.0)
|
52
|
+
parser (>= 3.0.1.1)
|
53
|
+
ruby-progressbar (1.11.0)
|
54
|
+
simplecov (0.19.1)
|
55
|
+
docile (~> 1.1)
|
56
|
+
simplecov-html (~> 0.11)
|
57
|
+
simplecov-html (0.12.3)
|
58
|
+
tzinfo (2.0.4)
|
59
|
+
concurrent-ruby (~> 1.0)
|
60
|
+
unicode-display_width (2.1.0)
|
61
|
+
webrick (1.7.0)
|
62
|
+
yard (0.9.27)
|
63
|
+
webrick (~> 1.7.0)
|
64
|
+
zeitwerk (2.5.1)
|
65
|
+
|
66
|
+
PLATFORMS
|
67
|
+
aarch64-linux
|
68
|
+
|
69
|
+
DEPENDENCIES
|
70
|
+
activesupport (~> 6.1.4)
|
71
|
+
byebug (~> 11.1.3)
|
72
|
+
rspec (~> 3.10.0)
|
73
|
+
rubocop (~> 1.21.0)
|
74
|
+
ryquest!
|
75
|
+
simplecov (~> 0.19.1)
|
76
|
+
yard (~> 0.9.26)
|
77
|
+
|
78
|
+
BUNDLED WITH
|
79
|
+
2.2.22
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Pierre Guego
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Makefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
##
|
2
|
+
# Simplify docker usage
|
3
|
+
#
|
4
|
+
container = gem_ryquest
|
5
|
+
option = -ti --rm --user $(shell id -u):$(shell id -g) -v $(shell pwd):/app -e HOME=/app
|
6
|
+
|
7
|
+
.PHONY: doc
|
8
|
+
args = $(filter-out $@,$(MAKECMDGOALS))
|
9
|
+
%:
|
10
|
+
@:
|
11
|
+
|
12
|
+
# build the docker image
|
13
|
+
install:
|
14
|
+
@ docker build -t $(container) .
|
15
|
+
|
16
|
+
# run the test inside container
|
17
|
+
test:
|
18
|
+
@ docker run ${option} ${container} rspec $(args)
|
19
|
+
|
20
|
+
# display linter error
|
21
|
+
lint:
|
22
|
+
@ docker run $(option) ${container} rubocop ${args}
|
23
|
+
|
24
|
+
# documentation compilation
|
25
|
+
doc:
|
26
|
+
@ docker run $(option) $(container) yardoc --list-undoc $(args)
|
27
|
+
|
28
|
+
# exec the commande in the container: make exec bash
|
29
|
+
exec:
|
30
|
+
@ docker run $(option) $(container) $(args)
|
31
|
+
|
32
|
+
# remove everything created by makefile command
|
33
|
+
clean:
|
34
|
+
- rm -rf doc
|
35
|
+
- rm -rf coverage
|
36
|
+
- rm -rf .bundle
|
37
|
+
- rm -rf .yardoc
|
38
|
+
- rm -rf .cache
|
39
|
+
- rm -rf .local
|
40
|
+
- rm .rspec_status
|
41
|
+
- rm .byebug_history
|
42
|
+
- rm .irb_history
|
43
|
+
- rm .bash_history
|
44
|
+
- docker image rm ruby:3.0.2
|
45
|
+
- docker image rm $(container)
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# Ryquest
|
2
|
+
|
3
|
+
*(d)R(spec)y(re)quest*
|
4
|
+
|
5
|
+
Improve `type: :request` DSL provided by `rspec-rails`.
|
6
|
+
|
7
|
+
Testing controller with `type: :request` can lead to duplication in description and test.
|
8
|
+
```ruby
|
9
|
+
describe 'GET /path' do
|
10
|
+
it 'should ...' do
|
11
|
+
get '/path'
|
12
|
+
expect(response).to # ...
|
13
|
+
end
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
Ryquest remove this duplication by using parents description to setup the test.
|
18
|
+
```ruby
|
19
|
+
describe 'GET /path' do
|
20
|
+
it 'should ...' do
|
21
|
+
expect(response!).to # ...
|
22
|
+
end
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
## Requirements
|
27
|
+
|
28
|
+
- ryquest ~> 1.0: rspec-rails ~> 5.0
|
29
|
+
|
30
|
+
*Note: ryquest should be able to run with older version of rspec-rails but behaviour is not garented.*
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
1. Add `ryquest` to your application in `:test` env
|
35
|
+
```ruby
|
36
|
+
gem 'ryquest', '~> 1.0', require: false, groupe: :test
|
37
|
+
```
|
38
|
+
2. Setup `ryquest` in `spec/rails_helper.rb` file
|
39
|
+
```ruby
|
40
|
+
# Add additional requires below this line. Rails is not loaded until this point!
|
41
|
+
require 'ryquest'
|
42
|
+
```
|
43
|
+
|
44
|
+
## Usage
|
45
|
+
|
46
|
+
### Basic request
|
47
|
+
|
48
|
+
Ryquest use parent's description in order to setup the test.
|
49
|
+
It dig through all the test parents and stop on the first description which can be use to setup a request.
|
50
|
+
|
51
|
+
A valid parent's description is compose by:
|
52
|
+
1. An HTTP verbs: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
|
53
|
+
2. A path: `/user/comments`
|
54
|
+
|
55
|
+
Use `response!` to launch the request and get the result (same than `response` result).
|
56
|
+
Value is cached so it can be use several time without launch the request again.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
describe 'POST /user/comments' do # not used
|
60
|
+
describe 'GET /user/comments' do # response! stop here and use this description
|
61
|
+
it 'should list user comments' do
|
62
|
+
expect(response!).to have_http_status :ok
|
63
|
+
expect(JSON.parse(response!.body)).to eq ['comment_1', 'comment_2']
|
64
|
+
|
65
|
+
# equivalent to
|
66
|
+
get '/user/comments'
|
67
|
+
|
68
|
+
expect(response).to have_http_status :ok
|
69
|
+
expect(JSON.parse(response.body)).to eq ['comment_1', 'comment_2']
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
*Note:*
|
76
|
+
- *`response!` can launch only one request per test, other request must be setup trought rspec-rails way.*
|
77
|
+
- *if `get`, `post`, ... is use before `response!`, `response!` will return the `get`, `post`, ... result.*
|
78
|
+
|
79
|
+
### With headers and params
|
80
|
+
|
81
|
+
To use specific headers and params with `response!`, put their value in `let` variables `headers` and `params`.
|
82
|
+
`response!` automaticaly include theses values in the request if they exists.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
let(:headers) { { 'Authorization' => 'token' } }
|
86
|
+
let(:params) { { title: 'lorem', content: 'ipsum' } }
|
87
|
+
|
88
|
+
describe 'POST /user/comments' do
|
89
|
+
it 'should create a new comment' do
|
90
|
+
expect { response! }.to change { Comment.count }.by 1
|
91
|
+
|
92
|
+
# equivalent to
|
93
|
+
expect { post '/user/comments', headers: headers, params: params }.to change { Comment.count }.by 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
### With route parameters
|
99
|
+
|
100
|
+
`response!` handle route parameters by looking for a `let` variable with the same parameter name.
|
101
|
+
|
102
|
+
*Note: if variable have an `id` method it will use it instead convert the variable to string.*
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
let(:comment) { create :comment }
|
106
|
+
|
107
|
+
describe 'DELETE /user/comments/:comment' do
|
108
|
+
it 'should delete the comment' do
|
109
|
+
response!
|
110
|
+
|
111
|
+
expect { Comment.find comment.id }.to raise_error ActiveRecord::RecordNotFound
|
112
|
+
|
113
|
+
# equivalent to
|
114
|
+
delete "/user/comments/${comment.id}"
|
115
|
+
|
116
|
+
expect { Comment.find comment.id }.to raise_error ActiveRecord::RecordNotFound
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
### Helper
|
122
|
+
|
123
|
+
* `json!` call `response!` and return the body parsed into hash from json.
|
124
|
+
```ruby
|
125
|
+
describe 'GET /user/comments' do
|
126
|
+
it 'should list user comments' do
|
127
|
+
expect(json!).to eq ['comment_1', 'comment_2']
|
128
|
+
|
129
|
+
# equivalent to
|
130
|
+
get '/user/comments'
|
131
|
+
|
132
|
+
expect(JSON.parse(response.body)).to eq ['comment_1', 'comment_2']
|
133
|
+
end
|
134
|
+
end
|
135
|
+
```
|
data/lib/ryquest.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Context to include to get request DSL improvment
|
4
|
+
RSpec.shared_context 'ryquest helper' do # rubocop:disable Metrics/BlockLength
|
5
|
+
let(:headers) { nil }
|
6
|
+
let(:params) { nil }
|
7
|
+
|
8
|
+
# Execute request described in example description and return #response value.
|
9
|
+
# Example description must be formated as: "VERB /path".
|
10
|
+
#
|
11
|
+
# Request will not be launch if it not exist or response already have a value.
|
12
|
+
#
|
13
|
+
# VERB can be: GET, POST, PUT, PATCH, DELETE
|
14
|
+
#
|
15
|
+
# To add specific body or headers define them with `let(:headers/:params) { { key: :value } }
|
16
|
+
#
|
17
|
+
# Params path can be send as: 'VERB /path/:param',
|
18
|
+
# :param will be replaced by `param` value (let, method, ...) or their `id` value.
|
19
|
+
#
|
20
|
+
# @return [ActionDispatch::TestResponse] the #response value
|
21
|
+
def response!
|
22
|
+
match = match_verb
|
23
|
+
return response if response || match.nil?
|
24
|
+
|
25
|
+
verb = match[1]
|
26
|
+
path = match[2]
|
27
|
+
|
28
|
+
send verb.downcase, build_path(path), params: params, headers: headers
|
29
|
+
response
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash] the #response!.body parsed from json
|
33
|
+
def json!; JSON.parse response!.body end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Find request http verb and path in the parents example description.
|
38
|
+
# @return [MatchData] verb in [0] path in [1]
|
39
|
+
def match_verb
|
40
|
+
match = nil
|
41
|
+
|
42
|
+
self.class.parent_groups.each do |parent|
|
43
|
+
match = parent.description.match /^(GET|POST|PATCH|PUT|DELETE) (.+)/
|
44
|
+
break if match
|
45
|
+
end
|
46
|
+
|
47
|
+
match
|
48
|
+
end
|
49
|
+
|
50
|
+
# Replace params path with their value.
|
51
|
+
# Use param path #id if present.
|
52
|
+
# @return [String]
|
53
|
+
def build_path path
|
54
|
+
return path if path.exclude? ':'
|
55
|
+
|
56
|
+
path.scan(/:(\w+\b)/).flatten.each do |match|
|
57
|
+
value = send match
|
58
|
+
value = value.id if value.respond_to? :id
|
59
|
+
|
60
|
+
path = path.gsub ":#{match}", value.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Include the context when using the type: :request option
|
68
|
+
RSpec.configure { |config| config.include_context 'ryquest helper', type: :request }
|
data/ryquest.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/ryquest/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'ryquest'
|
7
|
+
spec.version = Ryquest::VERSION
|
8
|
+
spec.authors = ['Pierre Guego']
|
9
|
+
spec.email = ['pierre.guego@champagne-terroir.fr']
|
10
|
+
|
11
|
+
spec.summary = 'Improve type request DSL from rspec-rails.'
|
12
|
+
spec.homepage = 'https://github.com/faljie/ryquest'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
spec.required_ruby_version = '>= 2.5.0'
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
18
|
+
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
27
|
+
|
28
|
+
# Uncomment to register a new dependency of your gem
|
29
|
+
# spec.add_dependency 'example-gem', '~> 1.0'
|
30
|
+
|
31
|
+
# For more information and examples about making a new gem, checkout our
|
32
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ryquest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pierre Guego
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- pierre.guego@champagne-terroir.fr
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- ".rspec"
|
22
|
+
- ".rubocop.yml"
|
23
|
+
- Dockerfile
|
24
|
+
- Gemfile
|
25
|
+
- Gemfile.lock
|
26
|
+
- LICENSE.txt
|
27
|
+
- Makefile
|
28
|
+
- README.md
|
29
|
+
- lib/ryquest.rb
|
30
|
+
- lib/ryquest/version.rb
|
31
|
+
- ryquest.gemspec
|
32
|
+
homepage: https://github.com/faljie/ryquest
|
33
|
+
licenses:
|
34
|
+
- MIT
|
35
|
+
metadata:
|
36
|
+
homepage_uri: https://github.com/faljie/ryquest
|
37
|
+
source_code_uri: https://github.com/faljie/ryquest
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.5.0
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubygems_version: 3.2.22
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: Improve type request DSL from rspec-rails.
|
57
|
+
test_files: []
|