http-rspec 0.1.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/.github/workflows/ci.yml +65 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.rubocop/layout.yml +8 -0
- data/.rubocop/style.yml +32 -0
- data/.rubocop.yml +25 -0
- data/.yardopts +2 -0
- data/CHANGES.md +1 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +44 -0
- data/LICENSE.txt +20 -0
- data/README.md +135 -0
- data/Rakefile +22 -0
- data/httprb_rspec.gemspec +37 -0
- data/lib/http/rspec.rb +3 -0
- data/lib/http/support/rspec_matchers.rb +108 -0
- data/lib/http_rspec/version.rb +5 -0
- data/logo-rspec.png +0 -0
- data/logo.png +0 -0
- data/spec/http/support/rspec_matchers_spec.rb +231 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/support/fuubar.rb +21 -0
- data/spec/support/simplecov.rb +19 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 38440a523361f901def6f25ea16d718e7616987b9a6627aea7ba945a0fd7b1d0
|
4
|
+
data.tar.gz: 29da744fc13a86642fb3ea3546861aa5c898b318ed57b58c567963583fa04982
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 191c06d510be6887890a5d5dc2c76a1fc6ce2cf342ffbe0e18fe7e11c2a1026e5a56565122bb634bbfafdb8030db65094b8f5a13466557df6ff96b63bb9cc79e
|
7
|
+
data.tar.gz: '0976adaafc6acbd319ab725dcf7eff2febeeb08d43e5d243444846aea3a36e7aac4547192209fa20797e116fe2928f14e5b58ee8348cc7cb8562845a07372984'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
|
9
|
+
env:
|
10
|
+
BUNDLE_WITHOUT: "development"
|
11
|
+
JRUBY_OPTS: "--dev --debug"
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
runs-on: ${{ matrix.os }}
|
16
|
+
|
17
|
+
strategy:
|
18
|
+
matrix:
|
19
|
+
ruby: [ ruby-3.0, ruby-3.1, ruby-3.2 ]
|
20
|
+
os: [ ubuntu-latest ]
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v3
|
24
|
+
|
25
|
+
- uses: ruby/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: ${{ matrix.ruby }}
|
28
|
+
bundler-cache: true
|
29
|
+
|
30
|
+
- name: bundle exec rspec
|
31
|
+
run: bundle exec rspec --format progress --force-colour
|
32
|
+
|
33
|
+
- name: Prepare Coveralls test coverage report
|
34
|
+
uses: coverallsapp/github-action@v1.1.2
|
35
|
+
with:
|
36
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
37
|
+
flag-name: "${{ matrix.ruby }} @${{ matrix.os }}"
|
38
|
+
path-to-lcov: ./coverage/lcov/lcov.info
|
39
|
+
parallel: true
|
40
|
+
|
41
|
+
coveralls:
|
42
|
+
needs: test
|
43
|
+
runs-on: ubuntu-latest
|
44
|
+
steps:
|
45
|
+
- name: Finalize Coveralls test coverage report
|
46
|
+
uses: coverallsapp/github-action@master
|
47
|
+
with:
|
48
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
49
|
+
parallel-finished: true
|
50
|
+
|
51
|
+
lint:
|
52
|
+
runs-on: ubuntu-latest
|
53
|
+
|
54
|
+
steps:
|
55
|
+
- uses: actions/checkout@v3
|
56
|
+
|
57
|
+
- uses: ruby/setup-ruby@v1
|
58
|
+
with:
|
59
|
+
ruby-version: 3.2
|
60
|
+
bundler-cache: true
|
61
|
+
|
62
|
+
- name: bundle exec rubocop
|
63
|
+
run: bundle exec rubocop --format progress --color
|
64
|
+
|
65
|
+
- run: bundle exec rake verify_measurements
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop/layout.yml
ADDED
data/.rubocop/style.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
Style/Documentation:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Style/DocumentDynamicEvalDefinition:
|
5
|
+
Enabled: true
|
6
|
+
Exclude:
|
7
|
+
- 'spec/**/*.rb'
|
8
|
+
|
9
|
+
Style/FormatStringToken:
|
10
|
+
Enabled: true
|
11
|
+
EnforcedStyle: unannotated
|
12
|
+
|
13
|
+
Style/HashSyntax:
|
14
|
+
Enabled: true
|
15
|
+
EnforcedStyle: hash_rockets
|
16
|
+
|
17
|
+
Style/OptionHash:
|
18
|
+
Enabled: true
|
19
|
+
|
20
|
+
Style/RescueStandardError:
|
21
|
+
Enabled: true
|
22
|
+
EnforcedStyle: implicit
|
23
|
+
|
24
|
+
Style/StringLiterals:
|
25
|
+
Enabled: true
|
26
|
+
EnforcedStyle: double_quotes
|
27
|
+
|
28
|
+
Style/WordArray:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
Style/YodaCondition:
|
32
|
+
Enabled: false
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- .rubocop/layout.yml
|
3
|
+
- .rubocop/style.yml
|
4
|
+
|
5
|
+
require:
|
6
|
+
- rubocop-rake
|
7
|
+
- rubocop-rspec
|
8
|
+
|
9
|
+
AllCops:
|
10
|
+
DefaultFormatter: fuubar
|
11
|
+
DisplayCopNames: true
|
12
|
+
NewCops: enable
|
13
|
+
TargetRubyVersion: 3.0
|
14
|
+
|
15
|
+
Metrics/BlockLength:
|
16
|
+
Exclude:
|
17
|
+
- spec/**/*.rb
|
18
|
+
|
19
|
+
Metrics/MethodLength:
|
20
|
+
Max: 20
|
21
|
+
|
22
|
+
RSpec/MultipleExpectations:
|
23
|
+
Max: 10
|
24
|
+
RSpec/ExampleLength:
|
25
|
+
Max: 20
|
data/.yardopts
ADDED
data/CHANGES.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
## 0.1.0 (Unreleased)
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Help and Discussion
|
2
|
+
|
3
|
+
If you need help or just want to talk about the http.rb,
|
4
|
+
visit the http.rb Google Group:
|
5
|
+
|
6
|
+
https://groups.google.com/forum/#!forum/httprb
|
7
|
+
|
8
|
+
You can join by email by sending a message to:
|
9
|
+
|
10
|
+
[httprb+subscribe@googlegroups.com](mailto:httprb+subscribe@googlegroups.com)
|
11
|
+
|
12
|
+
|
13
|
+
# Reporting bugs
|
14
|
+
|
15
|
+
The best way to report a bug is by providing a reproduction script. A half
|
16
|
+
working script with comments for the parts you were unable to automate is still
|
17
|
+
appreciated.
|
18
|
+
|
19
|
+
In any case, specify following info in description of your issue:
|
20
|
+
|
21
|
+
- What you're trying to accomplish
|
22
|
+
- What you expected to happen
|
23
|
+
- What actually happened
|
24
|
+
- The exception backtrace(s), if any
|
25
|
+
- Version of gem or commit ref you are using
|
26
|
+
- Version of ruby you are using
|
data/Gemfile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
ruby RUBY_VERSION
|
5
|
+
|
6
|
+
gem "rake"
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem "pry", :require => false
|
10
|
+
|
11
|
+
# RSpec formatter
|
12
|
+
gem "fuubar", :require => false
|
13
|
+
|
14
|
+
platform :mri do
|
15
|
+
gem "pry-byebug"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem "certificate_authority", "~> 1.0", :require => false
|
21
|
+
|
22
|
+
gem "backports"
|
23
|
+
|
24
|
+
gem "rubocop", "~> 1.55.0"
|
25
|
+
gem "rubocop-performance"
|
26
|
+
gem "rubocop-rake"
|
27
|
+
gem "rubocop-rspec"
|
28
|
+
|
29
|
+
gem "simplecov", :require => false
|
30
|
+
gem "simplecov-lcov", :require => false
|
31
|
+
|
32
|
+
gem "rspec", "~> 3.10"
|
33
|
+
gem "webmock", "~> 3.18"
|
34
|
+
|
35
|
+
gem "yardstick"
|
36
|
+
end
|
37
|
+
|
38
|
+
group :doc do
|
39
|
+
gem "kramdown"
|
40
|
+
gem "yard"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Specify your gem's dependencies in http.gemspec
|
44
|
+
gemspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011-2022 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# 
|
2
|
+
|
3
|
+
[![Gem Version][gem-image]][gem-link]
|
4
|
+
[![MIT licensed][license-image]][license-link]
|
5
|
+
[![Build Status][build-image]][build-link]
|
6
|
+
|
7
|
+
[Documentation]
|
8
|
+
|
9
|
+
## About
|
10
|
+
|
11
|
+
HTTP (The Gem! a.k.a. http.rb) is an easy-to-use client library for making requests
|
12
|
+
from Ruby. RSpec is a Behaviour Driven Development spec libary for Ruby. Making TDD
|
13
|
+
Productive and Fun.
|
14
|
+
|
15
|
+
This gem adds custom matchers to make it easier to check http requests.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add the gem to your gemfile with bundler
|
20
|
+
```bash
|
21
|
+
$ bunlde add http-rspec --require
|
22
|
+
```
|
23
|
+
or manually
|
24
|
+
```
|
25
|
+
gem "http-rspec", require: false
|
26
|
+
````
|
27
|
+
|
28
|
+
Inside of your spec helper (default spec_helper.rb):
|
29
|
+
```ruby
|
30
|
+
require "http/rspec"
|
31
|
+
```
|
32
|
+
|
33
|
+
Now you have to include the matchers you want for the blocks you want
|
34
|
+
```ruby
|
35
|
+
# in spec_helper.rb to include matchers everywhere
|
36
|
+
RSpec.configure do |config|
|
37
|
+
config.include HTTP::Support::RspecMatchers
|
38
|
+
end
|
39
|
+
|
40
|
+
# in spec_helper.rb to include where the type is service
|
41
|
+
RSpec.configure do |config|
|
42
|
+
config.include HTTP::Support::RspecMatchers, type: :service
|
43
|
+
end
|
44
|
+
|
45
|
+
# in the individual describe blocks
|
46
|
+
RSpec.describe Service do
|
47
|
+
include HTTP::Support::RspecMatchers
|
48
|
+
|
49
|
+
it "makes request" do
|
50
|
+
expect(response).to be_an_http_gem_response.with(status: 200)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
## Documentation
|
56
|
+
|
57
|
+
Most things are documented here in the readme
|
58
|
+
The following API documentation is also available:
|
59
|
+
|
60
|
+
- [YARD API documentation](https://www.rubydoc.info/github/httprb/http-rspec)
|
61
|
+
|
62
|
+
### Basic Usage
|
63
|
+
|
64
|
+
Here's some simple examples to get you started:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
it "has successful response" do
|
68
|
+
response = HTTP.get("www.nrk.no")
|
69
|
+
expect(response).to be_an_http_gem_response.with(status: :success) # will match 2xx status code
|
70
|
+
expect(response).to be_an_http_gem_response.with(status: :redirect) # will match 3xx status code
|
71
|
+
expect(response).to be_an_http_gem_response.with(status: :error) # will match 3xx status code
|
72
|
+
|
73
|
+
expect(response).to be_an_http_gem_response.with(status: :ok) # require 200 status code
|
74
|
+
expect(response).to be_an_http_gem_response.with(status: 200) # require 200 status code
|
75
|
+
expect(response).to be_an_http_gem_response.with(status: :not_found) # require 404 status code
|
76
|
+
expect(response).to be_an_http_gem_response.with(status: 404) # require 404 status code
|
77
|
+
|
78
|
+
# you can access HTTP::Support::RspecMatchers::STATUS_CODE_TO_SYMBOL to see the full
|
79
|
+
# mapping between code and symbol
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## Supported Ruby Versions
|
84
|
+
|
85
|
+
This library aims to support and is [tested against][build-link]
|
86
|
+
the following Ruby versions:
|
87
|
+
|
88
|
+
- Ruby 3.0
|
89
|
+
- Ruby 3.1
|
90
|
+
- Ruby 3.2
|
91
|
+
|
92
|
+
If something doesn't work on one of these versions, it's a bug.
|
93
|
+
|
94
|
+
This library may inadvertently work (or seem to work) on other Ruby versions,
|
95
|
+
however support will only be provided for the versions listed above.
|
96
|
+
|
97
|
+
If you would like this library to support another Ruby version or
|
98
|
+
implementation, you may volunteer to be a maintainer. Being a maintainer
|
99
|
+
entails making sure all tests run and pass on that implementation. When
|
100
|
+
something breaks on your implementation, you will be responsible for providing
|
101
|
+
patches in a timely fashion. If critical issues for a particular implementation
|
102
|
+
exist at the time of a major release, support for that Ruby version may be
|
103
|
+
dropped.
|
104
|
+
|
105
|
+
|
106
|
+
## Contributing to http.rb rspec
|
107
|
+
|
108
|
+
- Fork http.rb on GitHub
|
109
|
+
- Make your changes
|
110
|
+
- Ensure all tests pass (`bundle exec rake`)
|
111
|
+
- Send a pull request
|
112
|
+
- If we like them we'll merge them
|
113
|
+
- If we've accepted a patch, feel free to ask for commit access!
|
114
|
+
|
115
|
+
|
116
|
+
## Copyright
|
117
|
+
|
118
|
+
Copyright © 2011-2023 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker, Simon Toivo Telhaug
|
119
|
+
See LICENSE.txt for further details.
|
120
|
+
|
121
|
+
|
122
|
+
[//]: # (badges)
|
123
|
+
|
124
|
+
[gem-image]: https://img.shields.io/gem/v/httprb_status?logo=ruby
|
125
|
+
[gem-link]: https://rubygems.org/gems/http_rspec
|
126
|
+
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
|
127
|
+
[license-link]: https://github.com/httprb/http-rspec/blob/main/LICENSE.txt
|
128
|
+
[build-image]: https://github.com/httprb/http-rspec/workflows/CI/badge.svg
|
129
|
+
[build-link]: https://github.com/httprb/http-rspec/actions/workflows/ci.yml
|
130
|
+
|
131
|
+
[//]: # (links)
|
132
|
+
|
133
|
+
[documentation]: https://github.com/httprb/http-rspec/wiki
|
134
|
+
[requests]: https://docs.python-requests.org/en/latest/
|
135
|
+
[llhttp]: https://llhttp.org/
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
RSpec::Core::RakeTask.new
|
7
|
+
|
8
|
+
require "rubocop/rake_task"
|
9
|
+
RuboCop::RakeTask.new
|
10
|
+
|
11
|
+
require "yardstick/rake/measurement"
|
12
|
+
Yardstick::Rake::Measurement.new do |measurement|
|
13
|
+
measurement.output = "measurement/report.txt"
|
14
|
+
end
|
15
|
+
|
16
|
+
require "yardstick/rake/verify"
|
17
|
+
Yardstick::Rake::Verify.new do |verify|
|
18
|
+
verify.require_exact_threshold = false
|
19
|
+
verify.threshold = 55
|
20
|
+
end
|
21
|
+
|
22
|
+
task :default => %i[spec rubocop verify_measurements]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "http_rspec/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.authors = ["Simon Toivo Telhaug"]
|
9
|
+
gem.email = ["bascule@gmail.com"]
|
10
|
+
|
11
|
+
gem.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
12
|
+
Include helpfull matchers for mathing statuscodes
|
13
|
+
DESCRIPTION
|
14
|
+
|
15
|
+
gem.summary = "HTTP Rspec matchers"
|
16
|
+
gem.homepage = "https://github.com/httprb/http-rspec"
|
17
|
+
gem.licenses = ["MIT"]
|
18
|
+
|
19
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
20
|
+
gem.files = `git ls-files`.split("\n")
|
21
|
+
gem.name = "http-rspec"
|
22
|
+
gem.require_paths = ["lib"]
|
23
|
+
gem.version = HttpRspec::VERSION
|
24
|
+
|
25
|
+
gem.required_ruby_version = ">= 3.0"
|
26
|
+
|
27
|
+
gem.add_runtime_dependency "http", ">= 4.0"
|
28
|
+
|
29
|
+
gem.metadata = {
|
30
|
+
"source_code_uri" => "https://github.com/httprb/http-rspec",
|
31
|
+
"bug_tracker_uri" => "https://github.com/httprb/http-rspec/issues",
|
32
|
+
"changelog_uri" => "https://github.com/httprb/http-rspec/blob/v#{HttpRspec::VERSION}/CHANGES.md",
|
33
|
+
"rubygems_mfa_required" => "true"
|
34
|
+
}
|
35
|
+
|
36
|
+
gem.license = "MIT"
|
37
|
+
end
|
data/lib/http/rspec.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "http"
|
4
|
+
|
5
|
+
module HTTP
|
6
|
+
module Support
|
7
|
+
module RspecMatchers
|
8
|
+
extend RSpec::Matchers::DSL
|
9
|
+
|
10
|
+
STATUS_CODE_TO_SYMBOL = HTTP::Response::Status::REASONS
|
11
|
+
.transform_values do |name|
|
12
|
+
name.gsub(/[- ]/, "_")
|
13
|
+
.downcase.gsub(/[^a-z_]/, "")
|
14
|
+
.to_sym
|
15
|
+
end
|
16
|
+
STATUS_SYMBOL_TO_CODE = STATUS_CODE_TO_SYMBOL.invert
|
17
|
+
|
18
|
+
matcher :be_an_http_gem_response do |_expected| # rubocop:disable Metrics/BlockLength
|
19
|
+
chain :with do |options|
|
20
|
+
if options[:status]
|
21
|
+
raise ArgumentError, "status is all ready passed in" if @expected_status
|
22
|
+
|
23
|
+
@expected_status = options[:status]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def expected_code
|
28
|
+
case @expected_status
|
29
|
+
when Integer then @expected_status
|
30
|
+
when :success, :successful then 200..299
|
31
|
+
when :redirect then 300..399
|
32
|
+
when :error then 500..599
|
33
|
+
when Symbol
|
34
|
+
STATUS_SYMBOL_TO_CODE.fetch(@expected_status) do
|
35
|
+
raise ArgumentError, "unknown symbol #{@expected_status.inspect}"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
raise ArgumentError, "unknown status value. Should be either a Integer or a symbol"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
match do |actual|
|
43
|
+
@actual = actual
|
44
|
+
|
45
|
+
match_response_type && match_status_code
|
46
|
+
end
|
47
|
+
|
48
|
+
def match_response_type = @actual.is_a?(HTTP::Response)
|
49
|
+
|
50
|
+
def match_status_code
|
51
|
+
# without @expected_status we dont have anything to compare against
|
52
|
+
return true unless @expected_status
|
53
|
+
|
54
|
+
case expected_code
|
55
|
+
when Integer
|
56
|
+
expected_code == @actual.status.code
|
57
|
+
when Range
|
58
|
+
expected_code.cover?(@actual.status.code)
|
59
|
+
else
|
60
|
+
raise "Unknown expected code #{expected_code}. Please report this as an issue"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def status_code_to_name(code)
|
65
|
+
STATUS_CODE_TO_SYMBOL.fetch(code, "unkown name")
|
66
|
+
end
|
67
|
+
|
68
|
+
def expected_type
|
69
|
+
case expected_code
|
70
|
+
when Range then "#{expected_code} code"
|
71
|
+
else
|
72
|
+
"#{expected_code} #{status_code_to_name(expected_code).inspect}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
description do
|
77
|
+
"http gem respond"
|
78
|
+
.then { @expected_status ? "#{_1} with #{expected_type}" : _1 }
|
79
|
+
end
|
80
|
+
|
81
|
+
def invalid_response_type_message
|
82
|
+
"expected a HTTP::Response object, but an instance of " \
|
83
|
+
"#{@actual.class} was received"
|
84
|
+
end
|
85
|
+
|
86
|
+
def actual_type
|
87
|
+
"#{actual.status.code} #{status_code_to_name(actual.status.code).inspect}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def failure_message
|
91
|
+
return invalid_response_type_message unless match_response_type
|
92
|
+
|
93
|
+
return "expected the response to have #{expected_type} but it was #{actual_type}" unless match_status_code
|
94
|
+
|
95
|
+
"unknown reason why it fails, please report it"
|
96
|
+
end
|
97
|
+
|
98
|
+
def failure_message_when_negated
|
99
|
+
return invalid_response_type_message unless match_response_type
|
100
|
+
|
101
|
+
return "expected the response not to have #{expected_type} but it was #{actual_type}" if match_status_code
|
102
|
+
|
103
|
+
"unknown reason why it fails, please report it"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/logo-rspec.png
ADDED
Binary file
|
data/logo.png
ADDED
Binary file
|
@@ -0,0 +1,231 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
require "http/support/rspec_matchers"
|
6
|
+
|
7
|
+
RSpec.describe HTTP::Support::RspecMatchers do
|
8
|
+
include described_class
|
9
|
+
|
10
|
+
describe "be_an_http_gem_response" do
|
11
|
+
it "raises error if it gets unexpected argument" do
|
12
|
+
matcher = be_an_http_gem_response
|
13
|
+
|
14
|
+
expect(matcher.matches?("response")).to be(false)
|
15
|
+
expect(matcher.failure_message)
|
16
|
+
.to eq("expected a HTTP::Response object, but an instance of String was received")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "description with no other constrains" do
|
20
|
+
matcher = be_an_http_gem_response
|
21
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 200)
|
22
|
+
|
23
|
+
response = HTTP.get("https://nrk.no")
|
24
|
+
expect(matcher.matches?(response)).to be(true)
|
25
|
+
expect(matcher.description).to eq("http gem respond")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "description include status" do
|
29
|
+
matcher = be_an_http_gem_response.with(:status => 200)
|
30
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 200)
|
31
|
+
|
32
|
+
response = HTTP.get("https://nrk.no")
|
33
|
+
expect(matcher.matches?(response)).to be(true)
|
34
|
+
expect(matcher.description).to eq("http gem respond with 200 :ok")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has reasonable failure message for 200 ok failure" do
|
38
|
+
matcher = be_an_http_gem_response.with(:status => 200)
|
39
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 400)
|
40
|
+
|
41
|
+
response = HTTP.get("https://nrk.no")
|
42
|
+
expect(matcher.matches?(response)).to be(false)
|
43
|
+
expect(matcher.failure_message)
|
44
|
+
.to eq("expected the response to have 200 :ok but it was 400 :bad_request")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has reasonable description for negated 200 ok failure" do
|
48
|
+
matcher = be_an_http_gem_response.with(:status => 200)
|
49
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 200)
|
50
|
+
|
51
|
+
response = HTTP.get("https://nrk.no")
|
52
|
+
expect(matcher.matches?(response)).to be(true)
|
53
|
+
expect(matcher.failure_message_when_negated)
|
54
|
+
.to eq("expected the response not to have 200 :ok but it was 200 :ok")
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "convert symbol into code" do
|
58
|
+
before do
|
59
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 299)
|
60
|
+
end
|
61
|
+
|
62
|
+
let(:response) { HTTP.get("https://nrk.no") }
|
63
|
+
|
64
|
+
it "raises for unknown symbol" do
|
65
|
+
expect do
|
66
|
+
matcher = be_an_http_gem_response.with(:status => :ruby)
|
67
|
+
matcher.matches?(response)
|
68
|
+
end
|
69
|
+
.to raise_error(ArgumentError, "unknown symbol :ruby")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "raises for wrong type" do
|
73
|
+
expect do
|
74
|
+
matcher = be_an_http_gem_response.with(:status => "Coty")
|
75
|
+
matcher.matches?(response)
|
76
|
+
end
|
77
|
+
.to raise_error(ArgumentError, "unknown status value. Should be " \
|
78
|
+
"either a Integer or a symbol")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can take :continue and convert in into 100" do
|
82
|
+
matcher = be_an_http_gem_response.with(:status => :continue)
|
83
|
+
expect(matcher.matches?(response)).to be(false)
|
84
|
+
expect(matcher.failure_message)
|
85
|
+
.to match(/expected the response to have 100 :continue but/)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can take :switching_protocols and convert in into 101" do
|
89
|
+
matcher = be_an_http_gem_response.with(:status => :switching_protocols)
|
90
|
+
expect(matcher.matches?(response)).to be(false)
|
91
|
+
expect(matcher.failure_message)
|
92
|
+
.to match(/expected the response to have 101 :switching_protocols but/)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "can take :ok and convert in into 200" do
|
96
|
+
matcher = be_an_http_gem_response.with(:status => :ok)
|
97
|
+
expect(matcher.matches?(response)).to be(false)
|
98
|
+
expect(matcher.failure_message)
|
99
|
+
.to match(/expected the response to have 200 :ok but/)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "can take :created and convert in into 201" do
|
103
|
+
matcher = be_an_http_gem_response.with(:status => :created)
|
104
|
+
expect(matcher.matches?(response)).to be(false)
|
105
|
+
expect(matcher.failure_message)
|
106
|
+
.to match(/expected the response to have 201 :created but/)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "can take :non_authoritative_information and convert in into 203" do
|
110
|
+
matcher = be_an_http_gem_response.with(:status => :non_authoritative_information)
|
111
|
+
expect(matcher.matches?(response)).to be(false)
|
112
|
+
expect(matcher.failure_message)
|
113
|
+
.to match(/expected the response to have 203 :non_authoritative_information but/)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "can take :multi_status and convert in into 207" do
|
117
|
+
matcher = be_an_http_gem_response.with(:status => :multi_status)
|
118
|
+
expect(matcher.matches?(response)).to be(false)
|
119
|
+
expect(matcher.failure_message)
|
120
|
+
.to match(/expected the response to have 207 :multi_status but/)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "can take :not_found and convert in into 404" do
|
124
|
+
matcher = be_an_http_gem_response.with(:status => :not_found)
|
125
|
+
expect(matcher.matches?(response)).to be(false)
|
126
|
+
expect(matcher.failure_message)
|
127
|
+
.to match(/expected the response to have 404 :not_found but/)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "can take :uri_too_long and convert in into 414" do
|
131
|
+
matcher = be_an_http_gem_response.with(:status => :uri_too_long)
|
132
|
+
expect(matcher.matches?(response)).to be(false)
|
133
|
+
expect(matcher.failure_message)
|
134
|
+
.to match(/expected the response to have 414 :uri_too_long but/)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "can take :internal_server_error and convert in into 500" do
|
138
|
+
matcher = be_an_http_gem_response.with(:status => :internal_server_error)
|
139
|
+
expect(matcher.matches?(response)).to be(false)
|
140
|
+
expect(matcher.failure_message)
|
141
|
+
.to match(/expected the response to have 500 :internal_server_error but/)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "can take :gateway_timeout and convert in into 504" do
|
145
|
+
matcher = be_an_http_gem_response.with(:status => :gateway_timeout)
|
146
|
+
expect(matcher.matches?(response)).to be(false)
|
147
|
+
expect(matcher.failure_message)
|
148
|
+
.to match(/expected the response to have 504 :gateway_timeout but/)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
%i[success successful].each do |success_name|
|
153
|
+
it "accepts #{success_name} for all 2xx codes" do
|
154
|
+
matcher = be_an_http_gem_response.with(:status => success_name)
|
155
|
+
|
156
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 200)
|
157
|
+
response = HTTP.get("https://nrk.no")
|
158
|
+
expect(matcher.matches?(response)).to be(true)
|
159
|
+
|
160
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 201)
|
161
|
+
response = HTTP.get("https://nrk.no")
|
162
|
+
expect(matcher.matches?(response)).to be(true)
|
163
|
+
|
164
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 210)
|
165
|
+
response = HTTP.get("https://nrk.no")
|
166
|
+
expect(matcher.matches?(response)).to be(true)
|
167
|
+
|
168
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 400)
|
169
|
+
response = HTTP.get("https://nrk.no")
|
170
|
+
expect(matcher.matches?(response)).to be(false)
|
171
|
+
|
172
|
+
expect(matcher.failure_message)
|
173
|
+
.to eq("expected the response to have 200..299 code but it was 400 :bad_request")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "accepts :redirect for all 3xx codes" do
|
178
|
+
matcher = be_an_http_gem_response.with(:status => :redirect)
|
179
|
+
|
180
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 300)
|
181
|
+
response = HTTP.get("https://nrk.no")
|
182
|
+
expect(matcher.matches?(response)).to be(true)
|
183
|
+
|
184
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 301)
|
185
|
+
response = HTTP.get("https://nrk.no")
|
186
|
+
expect(matcher.matches?(response)).to be(true)
|
187
|
+
|
188
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 310)
|
189
|
+
response = HTTP.get("https://nrk.no")
|
190
|
+
expect(matcher.matches?(response)).to be(true)
|
191
|
+
|
192
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 400)
|
193
|
+
response = HTTP.get("https://nrk.no")
|
194
|
+
expect(matcher.matches?(response)).to be(false)
|
195
|
+
|
196
|
+
expect(matcher.failure_message)
|
197
|
+
.to eq("expected the response to have 300..399 code but it was 400 :bad_request")
|
198
|
+
end
|
199
|
+
|
200
|
+
it "accepts :error for all 5xx codes" do
|
201
|
+
matcher = be_an_http_gem_response.with(:status => :error)
|
202
|
+
|
203
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 500)
|
204
|
+
response = HTTP.get("https://nrk.no")
|
205
|
+
expect(matcher.matches?(response)).to be(true)
|
206
|
+
|
207
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 501)
|
208
|
+
response = HTTP.get("https://nrk.no")
|
209
|
+
expect(matcher.matches?(response)).to be(true)
|
210
|
+
|
211
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 510)
|
212
|
+
response = HTTP.get("https://nrk.no")
|
213
|
+
expect(matcher.matches?(response)).to be(true)
|
214
|
+
|
215
|
+
stub_request(:get, "https://nrk.no/").to_return(:status => 400)
|
216
|
+
response = HTTP.get("https://nrk.no")
|
217
|
+
expect(matcher.matches?(response)).to be(false)
|
218
|
+
|
219
|
+
expect(matcher.failure_message)
|
220
|
+
.to eq("expected the response to have 500..599 code but it was 400 :bad_request")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it "raises if you call it with twice with status" do
|
225
|
+
expect do
|
226
|
+
matcher = be_an_http_gem_response.with(:status => 200).with(:status => 300)
|
227
|
+
matcher.matches?(response)
|
228
|
+
end
|
229
|
+
.to raise_error(ArgumentError, "status is all ready passed in")
|
230
|
+
end
|
231
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "support/simplecov"
|
4
|
+
require_relative "support/fuubar" unless ENV["CI"]
|
5
|
+
|
6
|
+
require "http"
|
7
|
+
require "webmock/rspec"
|
8
|
+
|
9
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.expect_with :rspec do |expectations|
|
12
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
13
|
+
# and `failure_message` of custom matchers include text for helper methods
|
14
|
+
# defined using `chain`, e.g.:
|
15
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
16
|
+
# # => "be bigger than 2 and smaller than 4"
|
17
|
+
# ...rather than:
|
18
|
+
# # => "be bigger than 2"
|
19
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
20
|
+
end
|
21
|
+
|
22
|
+
config.mock_with :rspec do |mocks|
|
23
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
24
|
+
# a real object. This is generally recommended, and will default to
|
25
|
+
# `true` in RSpec 4.
|
26
|
+
mocks.verify_partial_doubles = true
|
27
|
+
end
|
28
|
+
|
29
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
30
|
+
# have no way to turn it off -- the option exists only for backwards
|
31
|
+
# compatibility in RSpec 3). It causes shared context metadata to be
|
32
|
+
# inherited by the metadata hash of host groups and examples, rather than
|
33
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
34
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
35
|
+
|
36
|
+
# These two settings work together to allow you to limit a spec run
|
37
|
+
# to individual examples or groups you care about by tagging them with
|
38
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
39
|
+
# get run.
|
40
|
+
config.filter_run :focus
|
41
|
+
config.filter_run_excluding :flaky if defined?(JRUBY_VERSION) && ENV["CI"]
|
42
|
+
config.run_all_when_everything_filtered = true
|
43
|
+
|
44
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
45
|
+
# be too noisy due to issues in dependencies.
|
46
|
+
config.warnings = 0 == ENV["GUARD_RSPEC"].to_i
|
47
|
+
|
48
|
+
# Allows RSpec to persist some state between runs in order to support
|
49
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
50
|
+
# you configure your source control system to ignore this file.
|
51
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
52
|
+
|
53
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
54
|
+
# recommended. For more details, see:
|
55
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
56
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
57
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
58
|
+
config.disable_monkey_patching!
|
59
|
+
|
60
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
61
|
+
# file, and it's useful to allow more verbose output when running an
|
62
|
+
# individual spec file.
|
63
|
+
if config.files_to_run.one?
|
64
|
+
# Use the documentation formatter for detailed output,
|
65
|
+
# unless a formatter has already been configured
|
66
|
+
# (e.g. via a command-line flag).
|
67
|
+
config.default_formatter = "doc"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Print the 10 slowest examples and example groups at the
|
71
|
+
# end of the spec run, to help surface which specs are running
|
72
|
+
# particularly slow.
|
73
|
+
# config.profile_examples = 10
|
74
|
+
|
75
|
+
# Run specs in random order to surface order dependencies. If you find an
|
76
|
+
# order dependency and want to debug it, you can fix the order by providing
|
77
|
+
# the seed, which is printed after each run.
|
78
|
+
# --seed 1234
|
79
|
+
config.order = :random
|
80
|
+
|
81
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
82
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
83
|
+
# test failures related to randomization by passing the same `--seed` value
|
84
|
+
# as the one that triggered the failure.
|
85
|
+
Kernel.srand config.seed
|
86
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fuubar"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# Use Fuubar instafail-alike formatter, unless a formatter has already been
|
7
|
+
# configured (e.g. via a command-line flag).
|
8
|
+
config.default_formatter = "Fuubar"
|
9
|
+
|
10
|
+
# Disable auto-refresh of the fuubar progress bar to avoid surprises during
|
11
|
+
# debugiing. And simply because there's next to absolutely no point in having
|
12
|
+
# this turned on.
|
13
|
+
#
|
14
|
+
# > By default fuubar will automatically refresh the bar (and therefore
|
15
|
+
# > the ETA) every second. Unfortunately this doesn't play well with things
|
16
|
+
# > like debuggers. When you're debugging, having a bar show up every second
|
17
|
+
# > is undesireable.
|
18
|
+
#
|
19
|
+
# See: https://github.com/thekompanee/fuubar#disabling-auto-refresh
|
20
|
+
config.fuubar_auto_refresh = false
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "simplecov"
|
4
|
+
|
5
|
+
if ENV["CI"]
|
6
|
+
require "simplecov-lcov"
|
7
|
+
|
8
|
+
SimpleCov::Formatter::LcovFormatter.config do |config|
|
9
|
+
config.report_with_single_file = true
|
10
|
+
config.lcov_file_name = "lcov.info"
|
11
|
+
end
|
12
|
+
|
13
|
+
SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
|
14
|
+
end
|
15
|
+
|
16
|
+
SimpleCov.start do
|
17
|
+
add_filter "/spec/"
|
18
|
+
minimum_coverage 80
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http-rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Simon Toivo Telhaug
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
description: Include helpfull matchers for mathing statuscodes
|
28
|
+
email:
|
29
|
+
- bascule@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".github/workflows/ci.yml"
|
35
|
+
- ".gitignore"
|
36
|
+
- ".rspec"
|
37
|
+
- ".rubocop.yml"
|
38
|
+
- ".rubocop/layout.yml"
|
39
|
+
- ".rubocop/style.yml"
|
40
|
+
- ".yardopts"
|
41
|
+
- CHANGES.md
|
42
|
+
- CONTRIBUTING.md
|
43
|
+
- Gemfile
|
44
|
+
- LICENSE.txt
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- httprb_rspec.gemspec
|
48
|
+
- lib/http/rspec.rb
|
49
|
+
- lib/http/support/rspec_matchers.rb
|
50
|
+
- lib/http_rspec/version.rb
|
51
|
+
- logo-rspec.png
|
52
|
+
- logo.png
|
53
|
+
- spec/http/support/rspec_matchers_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- spec/support/fuubar.rb
|
56
|
+
- spec/support/simplecov.rb
|
57
|
+
homepage: https://github.com/httprb/http-rspec
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata:
|
61
|
+
source_code_uri: https://github.com/httprb/http-rspec
|
62
|
+
bug_tracker_uri: https://github.com/httprb/http-rspec/issues
|
63
|
+
changelog_uri: https://github.com/httprb/http-rspec/blob/v0.1.0/CHANGES.md
|
64
|
+
rubygems_mfa_required: 'true'
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '3.0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubygems_version: 3.4.10
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: HTTP Rspec matchers
|
84
|
+
test_files: []
|