rspec-http 0.0.2 → 0.9.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.
- data/Gemfile +1 -0
- data/README.rdoc +13 -7
- data/lib/rspec/http.rb +3 -1
- data/lib/rspec/http/header_matchers.rb +118 -0
- data/lib/rspec/http/version.rb +1 -1
- data/spec/rspec/http/header_matchers_spec.rb +115 -0
- data/spec/rspec/http/response_code_matchers_spec.rb +1 -1
- data/spec/spec_helper.rb +8 -1
- data/spec/support/matchers.rb +8 -0
- metadata +34 -35
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
= RSpec HTTP 0.0
|
1
|
+
= RSpec HTTP 0.9.0
|
2
2
|
|
3
3
|
(c) Copyright 2010-2011 {C42 Engineering}[http://c42.in]. All Rights Reserved.
|
4
4
|
|
5
5
|
RSpec HTTP is a RSpec extension library that adds support for writing specs that cover HTTP based API (or more popularly, RESTful APIs).
|
6
6
|
|
7
7
|
To use this library, first add the rspec-http gem to your Gemfile like so:
|
8
|
-
gem 'rspec-http', '~> 0.
|
8
|
+
gem 'rspec-http', '~> 0.9'
|
9
9
|
|
10
10
|
Then add the following line to your spec_helper.rb:
|
11
11
|
require 'rspec/http'
|
@@ -19,15 +19,21 @@ This will make matchers such as the ones listed below available to you in your s
|
|
19
19
|
response.should be_http_unprocessable_entity
|
20
20
|
|
21
21
|
response.should be_http_im_a_teapot
|
22
|
+
|
23
|
+
response.should have_header('Content-Type')
|
24
|
+
|
25
|
+
response.should have_header('Content-Type' => 'application/json')
|
26
|
+
|
27
|
+
response.should have_header('Content-Type' => /json/)
|
22
28
|
|
23
29
|
== Rails
|
24
30
|
|
25
|
-
If you're using Rails (and implicitly, rspec-rails), the same matchers will also be available in your controller specs
|
31
|
+
If you're using Rails (and implicitly, rspec-rails), the same http code matchers will also be available in your controller specs *without* the <code>http</code> namespace. In other words, in your controller specs you can do:
|
26
32
|
|
27
|
-
response.should be_ok
|
33
|
+
response.should be_ok
|
28
34
|
|
29
|
-
response.should be_created
|
35
|
+
response.should be_created
|
30
36
|
|
31
|
-
response.should be_unprocessable_entity
|
37
|
+
response.should be_unprocessable_entity
|
32
38
|
|
33
|
-
response.should be_im_a_teapot
|
39
|
+
response.should be_im_a_teapot
|
data/lib/rspec/http.rb
CHANGED
@@ -3,9 +3,11 @@ require 'rspec/core'
|
|
3
3
|
require 'rspec/http/status_codes'
|
4
4
|
require 'rspec/http/response_code_matcher'
|
5
5
|
require 'rspec/http/response_code_matchers'
|
6
|
+
require 'rspec/http/header_matchers'
|
6
7
|
|
7
|
-
require 'rspec/http/rails'
|
8
|
+
require 'rspec/http/rails'
|
8
9
|
|
9
10
|
RSpec::configure do |config|
|
10
11
|
config.include(RSpec::Http::ResponseCodeMatchers)
|
12
|
+
config.include(RSpec::Http::HeaderMatchers)
|
11
13
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Http
|
3
|
+
class HeaderMatcher
|
4
|
+
attr_reader :header, :expected_value, :response
|
5
|
+
NO_VALUE = Object.new
|
6
|
+
|
7
|
+
def initialize(expected)
|
8
|
+
@header, @expected_value = expected.kind_of?(String) ? [expected, NO_VALUE] : expected.first
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(response)
|
12
|
+
if response[header]
|
13
|
+
@matcher = case expected_value
|
14
|
+
when String then HeaderStringMatcher.new(header, expected_value)
|
15
|
+
when Regexp then HeaderRegexpMatcher.new(header, expected_value)
|
16
|
+
when NO_VALUE then HeaderPresenceMatcher.new(header)
|
17
|
+
else raise RSpec::Matchers::MatcherError.new("The value for a header should be either a String or a Regexp and not of type #{expected_value.class}")
|
18
|
+
end
|
19
|
+
else
|
20
|
+
@matcher = HeaderPresenceMatcher.new(header)
|
21
|
+
end
|
22
|
+
@matcher.matches?(response)
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
@matcher.description
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message
|
30
|
+
@matcher.failure_message
|
31
|
+
end
|
32
|
+
|
33
|
+
def negative_failure_message
|
34
|
+
@matcher.negative_failure_message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class HeaderPresenceMatcher
|
39
|
+
attr_reader :header, :expected_value, :response
|
40
|
+
def initialize(header)
|
41
|
+
@header = header
|
42
|
+
end
|
43
|
+
|
44
|
+
def matches?(response)
|
45
|
+
@response = response
|
46
|
+
validate
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate
|
50
|
+
response[header]
|
51
|
+
end
|
52
|
+
|
53
|
+
def description
|
54
|
+
"Verify the presence of '#{header}' among the response headers"
|
55
|
+
end
|
56
|
+
|
57
|
+
def failure_message
|
58
|
+
"The header '#{header}' was not found"
|
59
|
+
end
|
60
|
+
|
61
|
+
def negative_failure_message
|
62
|
+
"The header '#{header}' should not have been found, but it was and it has a value of '#{response[header]}'"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class HeaderStringMatcher < HeaderPresenceMatcher
|
67
|
+
def initialize(header, expected_value)
|
68
|
+
super(header)
|
69
|
+
@expected_value = expected_value
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate
|
73
|
+
expected_value == response[header]
|
74
|
+
end
|
75
|
+
|
76
|
+
def description
|
77
|
+
"Verify that the value associated with '#{header}' is '#{expected_value}'"
|
78
|
+
end
|
79
|
+
|
80
|
+
def failure_message
|
81
|
+
"Expected the response header '#{header}' to have a value of '#{expected_value}' but it was '#{@response[header]}'"
|
82
|
+
end
|
83
|
+
|
84
|
+
def negative_failure_message
|
85
|
+
"Expected the response header '#{header}' to have a value that is not '#{expected_value}'"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class HeaderRegexpMatcher < HeaderPresenceMatcher
|
90
|
+
def initialize(header, expected_value)
|
91
|
+
super(header)
|
92
|
+
@expected_value = expected_value
|
93
|
+
end
|
94
|
+
|
95
|
+
def validate
|
96
|
+
expected_value =~ response[header]
|
97
|
+
end
|
98
|
+
|
99
|
+
def description
|
100
|
+
"Verify the value associated with '#{header}' matches '#{expected_value}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def failure_message
|
104
|
+
"Expected the response header '#{header}' to have a value that matched #{expected_value.inspect} but it was '#{@response[header]}'"
|
105
|
+
end
|
106
|
+
|
107
|
+
def negative_failure_message
|
108
|
+
"Expected the response header '#{header}' to have a value that does not match #{expected_value.inspect} but it was '#{@response[header]}'"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
module HeaderMatchers
|
113
|
+
def have_header(expected)
|
114
|
+
HeaderMatcher.new(expected)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/rspec/http/version.rb
CHANGED
@@ -0,0 +1,115 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module RSpec::Http
|
4
|
+
describe HeaderMatchers do
|
5
|
+
let(:response) { Rack::Response.new }
|
6
|
+
before(:each) { response["Content-Type"] = "text/plain"}
|
7
|
+
|
8
|
+
context "checking for the presence of a header" do
|
9
|
+
it "passes if the header is set" do
|
10
|
+
response.should have_header("Content-Type")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "fails if the header is not set" do
|
14
|
+
response.should_not have_header("Foobar")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns an appropriate failure message in the positive case" do
|
18
|
+
lambda {
|
19
|
+
response.should have_header("Foobar")
|
20
|
+
}.should fail_with("The header 'Foobar' was not found")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns an appropriate failure message in the negative case" do
|
24
|
+
lambda {
|
25
|
+
response.should_not have_header("Content-Type")
|
26
|
+
}.should fail_with("The header 'Content-Type' should not have been found, but it was and it has a value of 'text/plain'")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be case insensitive" do
|
30
|
+
response.should have_header("Content-Type")
|
31
|
+
response.should have_header("content-type")
|
32
|
+
response.should have_header("Content-type")
|
33
|
+
response.should have_header("CONTENT-TYPE")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "checking the value of the header" do
|
38
|
+
it "passes if the value is set correctly" do
|
39
|
+
response.should have_header("Content-Type" => "text/plain")
|
40
|
+
end
|
41
|
+
|
42
|
+
context "incorrect value" do
|
43
|
+
it "fails if the value is incorrect" do
|
44
|
+
response.should_not have_header("Content-Type" => "text/csv")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns an appropriate failure message in the positive case" do
|
48
|
+
lambda {
|
49
|
+
response.should have_header("Content-Type" => "text/csv")
|
50
|
+
}.should fail_with("Expected the response header 'Content-Type' to have a value of 'text/csv' but it was 'text/plain'")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns an appropriate failure message in the negative case" do
|
54
|
+
lambda {
|
55
|
+
response.should_not have_header("Content-Type" => "text/plain")
|
56
|
+
}.should fail_with("Expected the response header 'Content-Type' to have a value that is not 'text/plain'")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "missing header" do
|
61
|
+
it "fails if the header is missing" do
|
62
|
+
response.should_not have_header("Foobar" => "text/csv")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns an appropriate failure message in the positive case" do
|
66
|
+
lambda {
|
67
|
+
response.should have_header("Foobar" => "text/csv")
|
68
|
+
}.should fail_with("The header 'Foobar' was not found")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "comparing the value to a regex" do
|
74
|
+
it "passes if the value is set correctly" do
|
75
|
+
response.should have_header("Content-Type" => /plain/)
|
76
|
+
end
|
77
|
+
|
78
|
+
context "incorrect value" do
|
79
|
+
it "fails if the value is incorrect" do
|
80
|
+
response.should_not have_header("Content-Type" => /csv/)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns an appropriate failure message in the positive case" do
|
84
|
+
lambda {
|
85
|
+
response.should have_header("Content-Type" => /csv/)
|
86
|
+
}.should fail_with("Expected the response header 'Content-Type' to have a value that matched /csv/ but it was 'text/plain'")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns an appropriate failure message in the negative case" do
|
90
|
+
lambda {
|
91
|
+
response.should_not have_header("Content-Type" => /plain/)
|
92
|
+
}.should fail_with("Expected the response header 'Content-Type' to have a value that does not match /plain/ but it was 'text/plain'")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "missing header" do
|
97
|
+
it "fails if the header is missing" do
|
98
|
+
response.should_not have_header("Foobar" => /csv/)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns an appropriate failure message in the positive case" do
|
102
|
+
lambda {
|
103
|
+
response.should have_header("Foobar" => "text/csv")
|
104
|
+
}.should fail_with("The header 'Foobar' was not found")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "fails if the value is something other than a String or Regexp" do
|
109
|
+
lambda {
|
110
|
+
response.should have_header("Content-Type" => [])
|
111
|
+
}.should raise_error(RSpec::Matchers::MatcherError, 'The value for a header should be either a String or a Regexp and not of type Array')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,45 +1,44 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-http
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Sidu Ponnappa
|
9
9
|
- Niranjan Paranjape
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
|
14
|
-
date: 2011-04-21 00:00:00 +05:30
|
13
|
+
date: 2011-08-18 00:00:00.000000000 +05:30
|
15
14
|
default_executable:
|
16
|
-
dependencies:
|
17
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
18
17
|
name: rspec
|
19
|
-
|
20
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirement: &2152429900 !ruby/object:Gem::Requirement
|
21
19
|
none: false
|
22
|
-
requirements:
|
20
|
+
requirements:
|
23
21
|
- - ~>
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version:
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '2.0'
|
26
24
|
type: :runtime
|
27
|
-
|
28
|
-
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *2152429900
|
27
|
+
description: RSpec HTTP is an extension library that makes it easier to write specs
|
28
|
+
for HTTP/REST APIs
|
29
29
|
email: ckponnappa@gmail.com
|
30
30
|
executables: []
|
31
|
-
|
32
31
|
extensions: []
|
33
|
-
|
34
|
-
extra_rdoc_files:
|
32
|
+
extra_rdoc_files:
|
35
33
|
- README.rdoc
|
36
|
-
files:
|
34
|
+
files:
|
37
35
|
- CHANGELOG
|
38
36
|
- Gemfile
|
39
37
|
- LICENCE
|
40
38
|
- README.rdoc
|
41
39
|
- Rakefile
|
42
40
|
- lib/rspec/http.rb
|
41
|
+
- lib/rspec/http/header_matchers.rb
|
43
42
|
- lib/rspec/http/rails.rb
|
44
43
|
- lib/rspec/http/rails/controller_example_group.rb
|
45
44
|
- lib/rspec/http/rails/response_code_matchers.rb
|
@@ -48,35 +47,35 @@ files:
|
|
48
47
|
- lib/rspec/http/status_codes.rb
|
49
48
|
- lib/rspec/http/version.rb
|
50
49
|
- rspec-http.gemspec
|
50
|
+
- spec/rspec/http/header_matchers_spec.rb
|
51
51
|
- spec/rspec/http/response_code_matchers_spec.rb
|
52
52
|
- spec/spec_helper.rb
|
53
|
+
- spec/support/matchers.rb
|
53
54
|
has_rdoc: true
|
54
55
|
homepage: http://c42.in/open_source
|
55
56
|
licenses: []
|
56
|
-
|
57
57
|
post_install_message:
|
58
|
-
rdoc_options:
|
58
|
+
rdoc_options:
|
59
59
|
- --charset=UTF-8
|
60
|
-
require_paths:
|
60
|
+
require_paths:
|
61
61
|
- lib
|
62
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
|
-
requirements:
|
65
|
-
- -
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version:
|
68
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
69
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version:
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
74
|
requirements: []
|
75
|
-
|
76
75
|
rubyforge_project:
|
77
76
|
rubygems_version: 1.6.2
|
78
77
|
signing_key:
|
79
78
|
specification_version: 3
|
80
|
-
summary: RSpec HTTP is an extension library that makes it easier to write specs for
|
79
|
+
summary: RSpec HTTP is an extension library that makes it easier to write specs for
|
80
|
+
HTTP/REST APIs
|
81
81
|
test_files: []
|
82
|
-
|