cucumber-rest 0.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 +15 -0
- data/.gitignore +18 -0
- data/.rspec +5 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.md +83 -0
- data/Gemfile +3 -0
- data/LICENCE +21 -0
- data/README.md +3 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/cucumber-rest.gemspec +33 -0
- data/lib/cucumber/rest/body.rb +12 -0
- data/lib/cucumber/rest/caching.rb +152 -0
- data/lib/cucumber/rest/status.rb +37 -0
- data/lib/cucumber/rest/steps/caching.rb +20 -0
- data/lib/cucumber/rest/steps/status.rb +47 -0
- data/lib/cucumber/rest/steps.rb +2 -0
- data/lib/cucumber/rest/version.rb +5 -0
- data/lib/cucumber/rest.rb +6 -0
- data/spec/cucumber/rest/body_spec.rb +21 -0
- data/spec/cucumber/rest/caching_spec.rb +304 -0
- data/spec/cucumber/rest/status_spec.rb +40 -0
- data/spec/spec_helper.rb +31 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZGZhNzhkMDJlMzgyZTFjMTNlNjUzM2VkODM2NjhiYjUxODc4ZWIxZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MmM1ZGIwMTQ2ZDlkNGQ3OWIwYTJjNzQxNWJiYzc3OWZiZTA2ODUwNg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTVlYjc2ZTFkN2ZmNGUwYmFjMDVlZmYyMzUzM2FkODU2NTNiMjFhY2ZlYTE0
|
10
|
+
ZDdhYzhkMzlmOGI1YTNmNzc2YTZiMzkxOTlhOGM1NjUyY2E0NmIyNzBjMzRi
|
11
|
+
MzljZmRkNTFlNmM5ZjdhNTY1NTFlNTg3YjRmMmVhNGE1ZjRmZWU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NWNlNDBlMjgyOTcxODRjNzVkZDg4NGMxMTYwZjU2M2IzMTRhYzdkZmM0NzBi
|
14
|
+
ZjM5OTc4M2EzM2U2NzljYjA2MTE4NGQ2ZTBiZDExMjQwY2I4MzY4MDdmOGU1
|
15
|
+
ZTI3NmU5MTYwOGE2ZWRlZmMxYzkyOTgyNTBjZGM3YWU3MTZkOTM=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.0.0
|
4
|
+
- 2.1.2
|
5
|
+
deploy:
|
6
|
+
provider: rubygems
|
7
|
+
api_key:
|
8
|
+
secure: DfssT15CddiWJaakPGmBqroMixeyvSDtJsDa6dXW1qfO7gnoYQ1VGc0pevMs/1NsJBS/LDPGMN30Y+aTQ/JceiItp6O4LZaWN894C9+tXb3/9QKmTUFQkLqsb44lQeuRESPTtmtVKqMwbaLfiya6BActAfQvNdGY1JmBNAQsx8g=
|
9
|
+
gem: cucumber-rest
|
10
|
+
on:
|
11
|
+
repo: blinkboxbooks/cucumber-rest.rb
|
12
|
+
branch: master
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## 0.1.10 ([#27](https://git.mobcastdev.com/TEST/cucumber-rest/pull/27) 2014-12-16 13:37:19)
|
4
|
+
|
5
|
+
Step def for asserting HTTP 501 responses
|
6
|
+
|
7
|
+
Patch
|
8
|
+
|
9
|
+
* Step def for asserting HTTP 501 responses
|
10
|
+
|
11
|
+
## 0.1.9 ([#26](https://git.mobcastdev.com/TEST/cucumber-rest/pull/26) 2014-12-16 11:09:35)
|
12
|
+
|
13
|
+
Add a step for checking we specifically return a HTTP 202
|
14
|
+
|
15
|
+
Patch
|
16
|
+
|
17
|
+
* Adds a step def for checking HTTP 202 responses
|
18
|
+
|
19
|
+
## 0.1.8 ([#25](https://git.mobcastdev.com/TEST/cucumber-rest/pull/25) 2014-12-10 16:31:08)
|
20
|
+
|
21
|
+
Http 204 status codes
|
22
|
+
|
23
|
+
Patch
|
24
|
+
|
25
|
+
Add support for handling HTTP 204 responses, checking that the body is empty.
|
26
|
+
|
27
|
+
Also whitespace changes because hard tabs are bad, mmkay?
|
28
|
+
|
29
|
+
## 0.1.7 ([#24](https://git.mobcastdev.com/TEST/cucumber-rest/pull/24) 2014-12-08 16:47:02)
|
30
|
+
|
31
|
+
Using `ensure_status` instead of `ensure_status_class`
|
32
|
+
|
33
|
+
A patch to fix checking the status with the correct method.
|
34
|
+
|
35
|
+
## 0.1.6 ([#23](https://git.mobcastdev.com/TEST/cucumber-rest/pull/23) 2014-12-08 16:18:09)
|
36
|
+
|
37
|
+
Made the item specified that is being create non capturing
|
38
|
+
|
39
|
+
A patch to make the user specified resource being created in the step's regex non-capturing.
|
40
|
+
|
41
|
+
## 0.1.5 ([#22](https://git.mobcastdev.com/TEST/cucumber-rest/pull/22) 2014-12-01 14:58:07)
|
42
|
+
|
43
|
+
adding step for checking 201 Created response
|
44
|
+
|
45
|
+
patch: adding step for checking 201 Created response
|
46
|
+
|
47
|
+
## 0.1.4 ([#21](https://git.mobcastdev.com/TEST/cucumber-rest/pull/21) 2014-10-14 16:38:44)
|
48
|
+
|
49
|
+
RSpec 3
|
50
|
+
|
51
|
+
### Improvements
|
52
|
+
|
53
|
+
- Move to RSpec 3
|
54
|
+
|
55
|
+
## 0.1.3 ([#20](https://git.mobcastdev.com/TEST/cucumber-rest/pull/20) 2014-10-13 10:21:36)
|
56
|
+
|
57
|
+
Fix where the version file is read from
|
58
|
+
|
59
|
+
Patch
|
60
|
+
|
61
|
+
VERSION file location was misdefined as one level too deep. If the VERSION file can't be found in the right folder, default to a more sane "0.0.0".
|
62
|
+
|
63
|
+
## 0.1.2 ([#19](https://git.mobcastdev.com/TEST/cucumber-rest/pull/19) 2014-10-09 17:28:41)
|
64
|
+
|
65
|
+
410 Gone step
|
66
|
+
|
67
|
+
Patch
|
68
|
+
|
69
|
+
## 0.1.1 ([#18](https://git.mobcastdev.com/TEST/cucumber-rest/pull/18) 2014-07-15 10:52:31)
|
70
|
+
|
71
|
+
CP-1598 - Make Cucumber-Rest stricter about what it considers a valid Date in HTTP headers
|
72
|
+
|
73
|
+
Patch to make Cucumber-Rest fall back to using DateTime.httpdate as opposed to generic Date parsing; such that it's more in keeping with the HTTP RFCs
|
74
|
+
|
75
|
+
## 0.1.0 ([#17](https://git.mobcastdev.com/TEST/cucumber-rest/pull/17) 2014-06-30 17:42:16)
|
76
|
+
|
77
|
+
Moved to artifactory
|
78
|
+
|
79
|
+
### New Features
|
80
|
+
|
81
|
+
- Moved to Artifactory
|
82
|
+
- Moved to using VERSION file.
|
83
|
+
|
data/Gemfile
ADDED
data/LICENCE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 blinkbox Books Ltd.
|
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/README.md
ADDED
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.10
|
@@ -0,0 +1,33 @@
|
|
1
|
+
($LOAD_PATH << File.expand_path("../lib", __FILE__)).uniq!
|
2
|
+
require "cucumber/rest/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "cucumber-rest"
|
6
|
+
s.version = Cucumber::Rest::VERSION
|
7
|
+
s.summary = "Cucumber steps and support for testing RESTful services."
|
8
|
+
s.description = "A set of Cucumber step definitions and support functions which encapsulate common RESTful functionality."
|
9
|
+
s.author = "blinkbox books"
|
10
|
+
s.email = "greg@blinkbox.com"
|
11
|
+
s.homepage = "http://www.blinkboxbooks.com"
|
12
|
+
s.license = "MIT"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split($/)
|
15
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.extra_rdoc_files = ["README.md"]
|
19
|
+
|
20
|
+
s.post_install_message = ":: Coded for blinkbox books :: Love books, love code? Get in touch ::"
|
21
|
+
|
22
|
+
s.add_runtime_dependency "activesupport", ">= 3.2"
|
23
|
+
s.add_runtime_dependency "cucumber", "~> 1.3"
|
24
|
+
s.add_runtime_dependency "multi_json", "~> 1.7"
|
25
|
+
s.add_runtime_dependency "rspec", "~> 3.0"
|
26
|
+
s.add_runtime_dependency "rack", "~> 1.5"
|
27
|
+
s.add_runtime_dependency "http_capture", "~> 0.0", ">= 0.0.4"
|
28
|
+
|
29
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
30
|
+
s.add_development_dependency "rake", "~> 10.1"
|
31
|
+
|
32
|
+
s.add_development_dependency "cucumber_spinner"
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'http_capture'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Rest
|
5
|
+
# Helper functions for the handling of response bodies
|
6
|
+
module Body
|
7
|
+
def self.ensure_empty(response: HttpCapture::RESPONSES.last)
|
8
|
+
raise "Request body was not empty:\n #{response.body}" if response.body.to_s.size != 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require "date"
|
2
|
+
require "http_capture"
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Rest
|
6
|
+
# Helper functions for checking the cacheability of responses.
|
7
|
+
module Caching
|
8
|
+
|
9
|
+
class EmptyHTTPDateError < RuntimeError; end
|
10
|
+
|
11
|
+
# Ensures that a response is privately cacheable.
|
12
|
+
#
|
13
|
+
# This function uses a strict interpretation of RFC 2616 to ensure the widest interoperability with
|
14
|
+
# implementations, including HTTP 1.0.
|
15
|
+
#
|
16
|
+
# @param response [HttpCapture::Response] The response to check. If not supplied defaults to the last response.
|
17
|
+
# @param min_duration [Integer] The minimum permitted cache duration, in seconds.
|
18
|
+
# @param max_duration [Integer] The maximum permitted cache duration, in seconds.
|
19
|
+
# @param duration [Integer] The required cache duration, in seconds. Convenient if min and max are the same.
|
20
|
+
# @return [nil]
|
21
|
+
def self.ensure_response_is_publicly_cacheable(args = {})
|
22
|
+
response, min_duration, max_duration = extract_args(args)
|
23
|
+
ensure_cache_headers(response, false)
|
24
|
+
|
25
|
+
cache_control = parse_cache_control(response["Cache-Control"])
|
26
|
+
ensure_cache_directives(cache_control, "public", "max-age")
|
27
|
+
prohibit_cache_directives(cache_control, "private", "no-cache", "no-store")
|
28
|
+
|
29
|
+
age = response["Age"].to_i
|
30
|
+
date = parse_httpdate(response["Date"])
|
31
|
+
expires = parse_expires_httpdate(response["Expires"])
|
32
|
+
max_age = cache_control["max-age"]
|
33
|
+
expected_max_age = age + ((expires - date) * 24 * 3600).to_i
|
34
|
+
unless (max_age - expected_max_age).abs <= 1 # 1 second leeway
|
35
|
+
raise "Age, Date, Expires and Cache-Control:max-age are inconsistent"
|
36
|
+
end
|
37
|
+
|
38
|
+
ensure_cache_duration(max_age, min_duration, max_duration)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Ensures that a response is privately cacheable.
|
42
|
+
#
|
43
|
+
# This function uses a strict interpretation of RFC 2616, including precedence rules for Date, Expires and
|
44
|
+
# Cache-Control:max-age to ensure the widest interoperability with implementations, including HTTP 1.0.
|
45
|
+
#
|
46
|
+
# @param response [HttpCapture::Response] The response to check. If not supplied defaults to the last response.
|
47
|
+
# @param min_duration [Integer] The minimum permitted cache duration, in seconds.
|
48
|
+
# @param max_duration [Integer] The maximum permitted cache duration, in seconds.
|
49
|
+
# @param duration [Integer] The required cache duration, in seconds. Convenient if min and max are the same.
|
50
|
+
# @return [nil]
|
51
|
+
def self.ensure_response_is_privately_cacheable(args = {})
|
52
|
+
response, min_duration, max_duration = extract_args(args)
|
53
|
+
ensure_cache_headers(response, false)
|
54
|
+
|
55
|
+
cache_control = parse_cache_control(response["Cache-Control"])
|
56
|
+
ensure_cache_directives(cache_control, "private", "max-age")
|
57
|
+
prohibit_cache_directives(cache_control, "public", "no-cache", "no-store")
|
58
|
+
|
59
|
+
date = parse_httpdate(response["Date"])
|
60
|
+
expires = parse_expires_httpdate(response["Expires"])
|
61
|
+
raise "Expires should not be later than Date" if expires && expires > date
|
62
|
+
|
63
|
+
ensure_cache_duration(cache_control["max-age"], min_duration, max_duration)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Ensures that a response is not cacheable.
|
67
|
+
#
|
68
|
+
# This function uses a strict interpretation of RFC 2616, to ensure the widest interoperability with
|
69
|
+
# implementations, including HTTP 1.0.
|
70
|
+
#
|
71
|
+
# @param response [HttpCapture::Response] The response to check. If not supplied defaults to the last response.
|
72
|
+
# @return [nil]
|
73
|
+
def self.ensure_response_is_not_cacheable(args = {})
|
74
|
+
response, * = extract_args(args)
|
75
|
+
ensure_cache_headers(response, true)
|
76
|
+
|
77
|
+
cache_control = parse_cache_control(response["Cache-Control"])
|
78
|
+
ensure_cache_directives(cache_control, "no-store")
|
79
|
+
prohibit_cache_directives(cache_control, "public", "private", "max-age") # TODO: prohibit no-cache?
|
80
|
+
|
81
|
+
date = parse_httpdate(response["Date"])
|
82
|
+
expires = parse_expires_httpdate(response["Expires"]) rescue nil # invalid values are treated as < now, which is fine
|
83
|
+
raise "Expires should not be later than Date" if expires && expires > date
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def self.extract_args(args)
|
89
|
+
response = args[:response] || HttpCapture::RESPONSES.last
|
90
|
+
if response.nil?
|
91
|
+
raise "There is no response to check. Have you required the right capture file from HttpCapture?"
|
92
|
+
end
|
93
|
+
|
94
|
+
min_duration = args[:min_duration] || args[:duration]
|
95
|
+
max_duration = args[:max_duration] || args[:duration]
|
96
|
+
|
97
|
+
return response, min_duration, max_duration
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.ensure_cache_headers(response, pragma_nocache)
|
101
|
+
["Cache-Control", "Date", "Expires"].each { |h| raise "Required header '#{h}' is missing" if response[h].nil? }
|
102
|
+
|
103
|
+
unless (/\bno-cache\b/ === response["Pragma"]) == pragma_nocache
|
104
|
+
raise "Pragma should #{pragma_nocache ? "" : "not "}include the 'no-cache' directive"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.parse_cache_control(cache_control)
|
109
|
+
cache_control.split(",").each_with_object({}) do |entry, hash|
|
110
|
+
key, value = entry.split("=", 2).map(&:strip)
|
111
|
+
hash[key] = value =~ /^\d+$/ ? value.to_i : value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.ensure_cache_directives(cache_control, *directives)
|
116
|
+
directives.each do |directive|
|
117
|
+
raise "Cache-Control should include the '#{directive}' directive" unless cache_control.has_key?(directive)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.prohibit_cache_directives(cache_control, *directives)
|
122
|
+
directives.each do |directive|
|
123
|
+
raise "Cache-Control should not include the '#{directive}' directive" if cache_control.has_key?(directive)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.ensure_cache_duration(actual, min_expected, max_expected)
|
128
|
+
if min_expected && actual < min_expected
|
129
|
+
raise "Cache duration is #{actual}s but expected at least #{min_expected}s"
|
130
|
+
end
|
131
|
+
if max_expected && actual > max_expected
|
132
|
+
raise "Cache duration is #{actual}s but expected no more than #{max_expected}s"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.parse_httpdate(date)
|
137
|
+
raise EmptyHTTPDateError, "Empty date value" if (date.empty? || date.nil?)
|
138
|
+
DateTime.httpdate(date)
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.parse_expires_httpdate(date)
|
142
|
+
begin
|
143
|
+
parse_httpdate(date)
|
144
|
+
rescue EmptyHTTPDateError, ArgumentError => e
|
145
|
+
warn "Invalid Expires header value, handling as a past value"
|
146
|
+
DateTime.httpdate()
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "http_capture"
|
2
|
+
require "rack"
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Rest
|
6
|
+
# Helper functions for checking the cacheability of responses.
|
7
|
+
module Status
|
8
|
+
|
9
|
+
def self.ensure_status(expected, response: HttpCapture::RESPONSES.last)
|
10
|
+
actual = response.status
|
11
|
+
unless expected == actual
|
12
|
+
actual_name = Rack::Utils::HTTP_STATUS_CODES[actual]
|
13
|
+
expected_name = Rack::Utils::HTTP_STATUS_CODES[expected]
|
14
|
+
message = "Request status was #{actual} #{actual_name}; expected #{expected} #{expected_name}"
|
15
|
+
raise message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.ensure_status_class(expected, response: HttpCapture::RESPONSES.last)
|
20
|
+
min = case expected
|
21
|
+
when :informational then 100
|
22
|
+
when :success then 200
|
23
|
+
when :redirection then 300
|
24
|
+
when :client_error then 400
|
25
|
+
when :server_error then 500
|
26
|
+
end
|
27
|
+
max = min + 99
|
28
|
+
expected_range = min..max
|
29
|
+
actual = response.status
|
30
|
+
unless expected_range === actual
|
31
|
+
message = "Request status was #{actual} #{Rack::Utils::HTTP_STATUS_CODES[actual]}; expected #{expected_range}"
|
32
|
+
raise message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "active_support/core_ext/numeric/time"
|
2
|
+
require "cucumber/rest/caching"
|
3
|
+
|
4
|
+
Then(/^(?:the response|it)? is publicly cacheable$/) do
|
5
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^(?:the response|it)? is publicly cacheable for (a|\d+(?:\.\d+)?) (week|day|hour|minute|second)s?$/) do |num, unit|
|
9
|
+
num = num == "a" ? 1 : num.to_f
|
10
|
+
duration = num.send(unit.to_sym).to_i
|
11
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(duration: duration)
|
12
|
+
end
|
13
|
+
|
14
|
+
Then(/^(?:the response|it)? is privately cacheable$/) do
|
15
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable
|
16
|
+
end
|
17
|
+
|
18
|
+
Then(/^(?:the response|it)? is not cacheable$/) do
|
19
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "cucumber/rest/status"
|
2
|
+
require "cucumber/rest/body"
|
3
|
+
|
4
|
+
Then(/^the request (?:is|was) successful$/) do
|
5
|
+
Cucumber::Rest::Status.ensure_status_class(:success)
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^the request (?:is|was) successful and (?:a resource|.+) was created$/) do
|
9
|
+
Cucumber::Rest::Status.ensure_status(201)
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^the request (?:is|was) successfully accepted$/) do
|
13
|
+
Cucumber::Rest::Status.ensure_status(202)
|
14
|
+
end
|
15
|
+
|
16
|
+
Then(/^the request (?:is|was) successful and (?:no|an empty) response body is returned$/) do
|
17
|
+
Cucumber::Rest::Status.ensure_status(204)
|
18
|
+
Cucumber::Rest::Body.ensure_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
Then(/^(?:it|the request) fails because it (?:is|was) invalid$/) do
|
22
|
+
Cucumber::Rest::Status.ensure_status(400)
|
23
|
+
end
|
24
|
+
|
25
|
+
Then(/^(?:it|the request) fails because (?:.+) (?:is|was|am|are) unauthori[sz]ed$/) do
|
26
|
+
Cucumber::Rest::Status.ensure_status(401)
|
27
|
+
end
|
28
|
+
|
29
|
+
Then(/^(?:it|the request) fails because (?:.+) (?:is|was) forbidden$/) do
|
30
|
+
Cucumber::Rest::Status.ensure_status(403)
|
31
|
+
end
|
32
|
+
|
33
|
+
Then(/^(?:it|the request) fails because the (?:.+) (?:is|was) not found$/) do
|
34
|
+
Cucumber::Rest::Status.ensure_status(404)
|
35
|
+
end
|
36
|
+
|
37
|
+
Then(/^(?:it|the request) fails because there (?:is|was) a conflict(?: with .+)?$/) do
|
38
|
+
Cucumber::Rest::Status.ensure_status(409)
|
39
|
+
end
|
40
|
+
|
41
|
+
Then(/^(?:it|the request) fails because the (?:.+) (?:is|was|has) gone$/) do
|
42
|
+
Cucumber::Rest::Status.ensure_status(410)
|
43
|
+
end
|
44
|
+
|
45
|
+
Then(/^(?:it|the request) fails because the (?:.+) (?:is|was) not implemented$/) do
|
46
|
+
Cucumber::Rest::Status.ensure_status(501)
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "cucumber/rest/body"
|
2
|
+
|
3
|
+
describe Cucumber::Rest::Body, :body do
|
4
|
+
context "#ensure_empty" do
|
5
|
+
def generate_response(body: nil)
|
6
|
+
response = MockResponse.new
|
7
|
+
response.body = body
|
8
|
+
response
|
9
|
+
end
|
10
|
+
|
11
|
+
it "does not raise an error when the response body is empty" do
|
12
|
+
response = generate_response(body: nil)
|
13
|
+
expect { Cucumber::Rest::Body.ensure_empty(response: response) }.to_not raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an error when the response body is non-empty" do
|
17
|
+
response = generate_response(body: "something")
|
18
|
+
expect { Cucumber::Rest::Body.ensure_empty(response: response) }.to raise_error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
require "cucumber/rest/caching"
|
2
|
+
|
3
|
+
shared_examples "a cache header inspector" do |method, *header_names|
|
4
|
+
|
5
|
+
["Cache-Control", "Date", "Expires"].each do |header_name|
|
6
|
+
it "raises an error when the #{header_name} header is missing" do
|
7
|
+
response = generate_response
|
8
|
+
response[header_name] = nil
|
9
|
+
expect {
|
10
|
+
Cucumber::Rest::Caching.send(method, { response: response })
|
11
|
+
}.to raise_error "Required header '#{header_name}' is missing"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Cucumber::Rest::Caching, :caching do
|
18
|
+
|
19
|
+
context "#ensure_response_is_publicly_cacheable" do
|
20
|
+
|
21
|
+
def generate_response(duration = 3600, date = DateTime.now, age = nil)
|
22
|
+
response = MockResponse.new
|
23
|
+
response["Cache-Control"] = "public, max-age=#{duration}"
|
24
|
+
response["Expires"] = (date + (duration / (24.0 * 3600))).strftime(RFC822_DATE_FORMAT)
|
25
|
+
if age
|
26
|
+
date += age / 86400.0
|
27
|
+
response["Age"] = age.to_s if age
|
28
|
+
end
|
29
|
+
response["Date"] = date.strftime(RFC822_DATE_FORMAT)
|
30
|
+
response.body = "test"
|
31
|
+
response
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with cacheable responses" do
|
35
|
+
it_behaves_like "a cache header inspector", :ensure_response_is_publicly_cacheable
|
36
|
+
|
37
|
+
it "does not raise an error when the public cache headers are set correctly" do
|
38
|
+
duration = 3600
|
39
|
+
response = generate_response(duration)
|
40
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response, duration: duration)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does not raise an error when the public cache headers are set correctly, including an Age header" do
|
44
|
+
duration = 3600
|
45
|
+
response = generate_response(duration, DateTime.now, 243)
|
46
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response, duration: duration)
|
47
|
+
end
|
48
|
+
|
49
|
+
["max-age"].each do |directive| # TODO: Should include "public"
|
50
|
+
it "raises an error when the Cache-Control header does not include the #{directive} directive" do
|
51
|
+
response = generate_response
|
52
|
+
response["Cache-Control"] = response["Cache-Control"].split(/\s*,\s*/).reject { |d| d =~ /^#{directive}($|=)/ }.join(", ")
|
53
|
+
expect {
|
54
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response)
|
55
|
+
}.to raise_error "Cache-Control should include the '#{directive}' directive"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
["private", "no-cache", "no-store"].each do |directive|
|
60
|
+
it "raises an error when the Cache-Control header includes the #{directive} directive" do
|
61
|
+
response = generate_response
|
62
|
+
response["Cache-Control"] << ", #{directive}"
|
63
|
+
expect {
|
64
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response)
|
65
|
+
}.to raise_error "Cache-Control should not include the '#{directive}' directive"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "raises an error when Date, Expires and Cache-Control:max-age are inconsistent" do
|
70
|
+
response = generate_response
|
71
|
+
response["Expires"] = DateTime.now.strftime(RFC822_DATE_FORMAT)
|
72
|
+
expect {
|
73
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response)
|
74
|
+
}.to raise_error "Age, Date, Expires and Cache-Control:max-age are inconsistent"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "raises an error when Age, Date, Expires and Cache-Control:max-age are inconsistent" do
|
78
|
+
response = generate_response
|
79
|
+
response["Age"] = "5"
|
80
|
+
expect {
|
81
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response)
|
82
|
+
}.to raise_error "Age, Date, Expires and Cache-Control:max-age are inconsistent"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "raises an error when the Pragma header includes the no-cache directive" do
|
86
|
+
response = generate_response
|
87
|
+
response["Pragma"] = "no-cache"
|
88
|
+
expect {
|
89
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response)
|
90
|
+
}.to raise_error "Pragma should not include the 'no-cache' directive"
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
context "with application-level requirements" do
|
96
|
+
|
97
|
+
it "raises an error when the cache duration is higher than the expected duration" do
|
98
|
+
response = generate_response(3600)
|
99
|
+
expect {
|
100
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response, duration: 1800)
|
101
|
+
}.to raise_error "Cache duration is 3600s but expected no more than 1800s"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "raises an error when the cache duration is lower than the expected duration" do
|
105
|
+
response = generate_response(900)
|
106
|
+
expect {
|
107
|
+
Cucumber::Rest::Caching.ensure_response_is_publicly_cacheable(response: response, duration: 1800)
|
108
|
+
}.to raise_error "Cache duration is 900s but expected at least 1800s"
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
context "#ensure_response_is_privately_cacheable" do
|
116
|
+
|
117
|
+
def generate_response(duration = 3600, date = DateTime.now)
|
118
|
+
response = MockResponse.new
|
119
|
+
response["Cache-Control"] = "private, max-age=#{duration}"
|
120
|
+
response["Date"] = date.strftime(RFC822_DATE_FORMAT)
|
121
|
+
response["Expires"] = date.strftime(RFC822_DATE_FORMAT)
|
122
|
+
response.body = "test"
|
123
|
+
response
|
124
|
+
end
|
125
|
+
|
126
|
+
context "with non-cacheable responses" do
|
127
|
+
it_behaves_like "a cache header inspector", :ensure_response_is_privately_cacheable
|
128
|
+
|
129
|
+
it "does not raise an error when the private cache headers are set correctly" do
|
130
|
+
duration = 3600
|
131
|
+
response = generate_response(duration)
|
132
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response, duration: duration)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "does not raise an error when the private cache headers are set correctly, with Expires as -1" do
|
136
|
+
duration = 3600
|
137
|
+
response = generate_response(duration)
|
138
|
+
response["Expires"] = "-1" # invalid, but should be treated as in the past (i.e. already expired)
|
139
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response, duration: duration)
|
140
|
+
end
|
141
|
+
|
142
|
+
["private", "max-age"].each do |directive|
|
143
|
+
it "raises an error when the Cache-Control header does not include the #{directive} directive" do
|
144
|
+
response = generate_response
|
145
|
+
response["Cache-Control"] = response["Cache-Control"].split(/\s*,\s*/).reject { |d| d =~ /^#{directive}($|=)/ }.join(", ")
|
146
|
+
expect {
|
147
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response)
|
148
|
+
}.to raise_error "Cache-Control should include the '#{directive}' directive"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
["public", "no-cache", "no-store"].each do |directive|
|
153
|
+
it "raises an error when the Cache-Control header includes the #{directive} directive" do
|
154
|
+
response = generate_response
|
155
|
+
response["Cache-Control"] << ", #{directive}"
|
156
|
+
expect {
|
157
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response)
|
158
|
+
}.to raise_error "Cache-Control should not include the '#{directive}' directive"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
it "raises an error when Expires is a valid date later than Date" do
|
163
|
+
response = generate_response
|
164
|
+
response["Expires"] = (DateTime.now + 10).strftime(RFC822_DATE_FORMAT)
|
165
|
+
expect {
|
166
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response)
|
167
|
+
}.to raise_error "Expires should not be later than Date"
|
168
|
+
end
|
169
|
+
|
170
|
+
it "raises an error when the Pragma header includes the no-cache directive" do
|
171
|
+
response = generate_response
|
172
|
+
response["Pragma"] = "no-cache"
|
173
|
+
expect {
|
174
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response)
|
175
|
+
}.to raise_error "Pragma should not include the 'no-cache' directive"
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
context "with application-level requirements" do
|
181
|
+
|
182
|
+
it "raises an error when the cache duration is higher than the expected duration" do
|
183
|
+
response = generate_response(3600)
|
184
|
+
expect {
|
185
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response, duration: 1800)
|
186
|
+
}.to raise_error "Cache duration is 3600s but expected no more than 1800s"
|
187
|
+
end
|
188
|
+
|
189
|
+
it "raises an error when the cache duration is lower than the expected duration" do
|
190
|
+
response = generate_response(900)
|
191
|
+
expect {
|
192
|
+
Cucumber::Rest::Caching.ensure_response_is_privately_cacheable(response: response, duration: 1800)
|
193
|
+
}.to raise_error "Cache duration is 900s but expected at least 1800s"
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
context "#ensure_response_is_not_cacheable" do
|
201
|
+
|
202
|
+
def generate_response(date = DateTime.now)
|
203
|
+
response = MockResponse.new
|
204
|
+
response["Cache-Control"] = "no-store"
|
205
|
+
response["Date"] = date.strftime(RFC822_DATE_FORMAT)
|
206
|
+
response["Expires"] = date.strftime(RFC822_DATE_FORMAT)
|
207
|
+
response["Pragma"] = "no-cache"
|
208
|
+
response.body = "test"
|
209
|
+
response
|
210
|
+
end
|
211
|
+
|
212
|
+
context "with non-cacheable responses" do
|
213
|
+
it_behaves_like "a cache header inspector", :ensure_response_is_not_cacheable
|
214
|
+
|
215
|
+
it "does not raise an error when the prevent cache headers are set correctly" do
|
216
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: generate_response)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "does not raise an error when the public cache headers are set correctly, with Expires as -1" do
|
220
|
+
response = generate_response
|
221
|
+
response["Expires"] = "-1" # invalid, but should be treated as in the past (i.e. already expired)
|
222
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: response)
|
223
|
+
end
|
224
|
+
|
225
|
+
["no-store"].each do |directive|
|
226
|
+
it "raises an error when the Cache-Control header does not include the #{directive} directive" do
|
227
|
+
response = generate_response
|
228
|
+
response["Cache-Control"] = response["Cache-Control"].split(/\s*,\s*/).reject { |d| d =~ /^#{directive}($|=)/ }.join(", ")
|
229
|
+
expect {
|
230
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: response)
|
231
|
+
}.to raise_error "Cache-Control should include the '#{directive}' directive"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
["public", "private", "max-age"].each do |directive|
|
236
|
+
it "raises an error when the Cache-Control header includes the #{directive} directive" do
|
237
|
+
response = generate_response
|
238
|
+
response["Cache-Control"] << ", #{directive}"
|
239
|
+
expect {
|
240
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: response)
|
241
|
+
}.to raise_error "Cache-Control should not include the '#{directive}' directive"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
it "raises an error when Expires is a valid date later than Date" do
|
246
|
+
response = generate_response
|
247
|
+
response["Expires"] = (DateTime.now + 10).strftime(RFC822_DATE_FORMAT)
|
248
|
+
expect {
|
249
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: response)
|
250
|
+
}.to raise_error "Expires should not be later than Date"
|
251
|
+
end
|
252
|
+
|
253
|
+
it "raises an error when the Pragma header does not include the no-cache directive" do
|
254
|
+
response = generate_response
|
255
|
+
response["Pragma"] = nil
|
256
|
+
expect {
|
257
|
+
Cucumber::Rest::Caching.ensure_response_is_not_cacheable(response: response)
|
258
|
+
}.to raise_error "Pragma should include the 'no-cache' directive"
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
context "#parse_httpdate" do
|
266
|
+
|
267
|
+
it "doesn't raise an error when an RFC822 date is passed" do
|
268
|
+
date = DateTime.now.strftime(RFC822_DATE_FORMAT)
|
269
|
+
Cucumber::Rest::Caching.parse_httpdate(date)
|
270
|
+
end
|
271
|
+
|
272
|
+
it "doesn't raise an error when an ANCI C asctime format date is passed" do
|
273
|
+
date = DateTime.now.strftime(ANSI_C_DATE_FORMAT)
|
274
|
+
Cucumber::Rest::Caching.parse_httpdate(date)
|
275
|
+
end
|
276
|
+
|
277
|
+
it "doesn't raise an error when an RFC850 date is passed" do
|
278
|
+
date = DateTime.now.strftime(RFC850_DATE_FORMAT)
|
279
|
+
Cucumber::Rest::Caching.parse_httpdate(date)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "raises an error when a non-English date is passed" do
|
283
|
+
date = "ma, 14 heinä 2014 16:08:33 GMT"
|
284
|
+
expect {
|
285
|
+
Cucumber::Rest::Caching.parse_httpdate(date)
|
286
|
+
}.to raise_error("invalid date")
|
287
|
+
end
|
288
|
+
|
289
|
+
it "raises an error when a non-GMT date is passed" do
|
290
|
+
date = "Mon, 14 Jul 2014 16:33:04 +0100"
|
291
|
+
expect {
|
292
|
+
Cucumber::Rest::Caching.parse_httpdate(date)
|
293
|
+
}.to raise_error("invalid date")
|
294
|
+
end
|
295
|
+
|
296
|
+
it "raises an error when empty date values are passed" do
|
297
|
+
expect {
|
298
|
+
Cucumber::Rest::Caching.parse_httpdate("")
|
299
|
+
}.to raise_error("Empty date value")
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "cucumber/rest/status"
|
2
|
+
|
3
|
+
shared_examples "a status class inspector" do |status_class, min, max|
|
4
|
+
def generate_response(status_code)
|
5
|
+
response = MockResponse.new
|
6
|
+
response.status = status_code
|
7
|
+
response
|
8
|
+
end
|
9
|
+
|
10
|
+
Rack::Utils::HTTP_STATUS_CODES.keys.keep_if { |code| code >= min && code <= max }.each do |status_code|
|
11
|
+
it "does not raise an error for status code #{status_code}" do
|
12
|
+
Cucumber::Rest::Status.ensure_status_class(status_class, response: generate_response(status_code))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
Rack::Utils::HTTP_STATUS_CODES.keys.keep_if { |code| code < min || code > max }.each do |status_code|
|
16
|
+
it "raises an error for status code #{status_code}" do
|
17
|
+
expect {
|
18
|
+
Cucumber::Rest::Status.ensure_status_class(status_class, response: generate_response(status_code))
|
19
|
+
}.to raise_error
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Cucumber::Rest::Status, :status do
|
25
|
+
context "#ensure_status_class(:informational)" do
|
26
|
+
it_behaves_like "a status class inspector", :informational, 100, 199
|
27
|
+
end
|
28
|
+
context "#ensure_status_class(:success)" do
|
29
|
+
it_behaves_like "a status class inspector", :success, 200, 299
|
30
|
+
end
|
31
|
+
context "#ensure_status_class(:redirection)" do
|
32
|
+
it_behaves_like "a status class inspector", :redirection, 300, 399
|
33
|
+
end
|
34
|
+
context "#ensure_status_class(:client_error)" do
|
35
|
+
it_behaves_like "a status class inspector", :client_error, 400, 499
|
36
|
+
end
|
37
|
+
context "#ensure_status_class(:server_error)" do
|
38
|
+
it_behaves_like "a status class inspector", :server_error, 500, 599
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "cucumber"
|
2
|
+
|
3
|
+
RFC822_DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"
|
4
|
+
RFC850_DATE_FORMAT = "%A, %d-%b-%y %H:%M:%S GMT"
|
5
|
+
ANSI_C_DATE_FORMAT = "%a %b %e %H:%M:%S %Y"
|
6
|
+
|
7
|
+
# A mock response class that looks like HttpCapture::Response
|
8
|
+
class MockResponse
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_accessor :status
|
12
|
+
attr_accessor :body
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@header = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# The default header accessor
|
19
|
+
def [](key)
|
20
|
+
@header[key]
|
21
|
+
end
|
22
|
+
|
23
|
+
# The default header accessor
|
24
|
+
def []=(key, value)
|
25
|
+
@header[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def each(&block)
|
29
|
+
@header.each(&block)
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cucumber-rest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- blinkbox books
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cucumber
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.5'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.5'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: http_capture
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.0'
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 0.0.4
|
93
|
+
type: :runtime
|
94
|
+
prerelease: false
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ~>
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.0'
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.0.4
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: bundler
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.3'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ~>
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '1.3'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rake
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ~>
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '10.1'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ~>
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '10.1'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: cucumber_spinner
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
description: A set of Cucumber step definitions and support functions which encapsulate
|
146
|
+
common RESTful functionality.
|
147
|
+
email: greg@blinkbox.com
|
148
|
+
executables: []
|
149
|
+
extensions: []
|
150
|
+
extra_rdoc_files:
|
151
|
+
- README.md
|
152
|
+
files:
|
153
|
+
- .gitignore
|
154
|
+
- .rspec
|
155
|
+
- .travis.yml
|
156
|
+
- CHANGELOG.md
|
157
|
+
- Gemfile
|
158
|
+
- LICENCE
|
159
|
+
- README.md
|
160
|
+
- Rakefile
|
161
|
+
- VERSION
|
162
|
+
- cucumber-rest.gemspec
|
163
|
+
- lib/cucumber/rest.rb
|
164
|
+
- lib/cucumber/rest/body.rb
|
165
|
+
- lib/cucumber/rest/caching.rb
|
166
|
+
- lib/cucumber/rest/status.rb
|
167
|
+
- lib/cucumber/rest/steps.rb
|
168
|
+
- lib/cucumber/rest/steps/caching.rb
|
169
|
+
- lib/cucumber/rest/steps/status.rb
|
170
|
+
- lib/cucumber/rest/version.rb
|
171
|
+
- spec/cucumber/rest/body_spec.rb
|
172
|
+
- spec/cucumber/rest/caching_spec.rb
|
173
|
+
- spec/cucumber/rest/status_spec.rb
|
174
|
+
- spec/spec_helper.rb
|
175
|
+
homepage: http://www.blinkboxbooks.com
|
176
|
+
licenses:
|
177
|
+
- MIT
|
178
|
+
metadata: {}
|
179
|
+
post_install_message: ':: Coded for blinkbox books :: Love books, love code? Get in
|
180
|
+
touch ::'
|
181
|
+
rdoc_options: []
|
182
|
+
require_paths:
|
183
|
+
- lib
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ! '>='
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ! '>='
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
requirements: []
|
195
|
+
rubyforge_project:
|
196
|
+
rubygems_version: 2.4.5
|
197
|
+
signing_key:
|
198
|
+
specification_version: 4
|
199
|
+
summary: Cucumber steps and support for testing RESTful services.
|
200
|
+
test_files:
|
201
|
+
- spec/cucumber/rest/body_spec.rb
|
202
|
+
- spec/cucumber/rest/caching_spec.rb
|
203
|
+
- spec/cucumber/rest/status_spec.rb
|
204
|
+
- spec/spec_helper.rb
|