rspec-http 0.0.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem "rack", "~> 1.0"
3
4
  gem "ruby-debug", :platforms => [:ruby_18, :jruby]
4
5
  gem "ruby-debug19", :platforms => :ruby_19
5
6
  gem "rcov", :platforms => :ruby_18
@@ -1,11 +1,11 @@
1
- = RSpec HTTP 0.0.2
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.0.1'
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 '''without''' the <code>http</code> namespace. In other words, in your controller specs you can do:
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
@@ -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'# if Kernel.const_defined?('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
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Http # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '0.0.2'
4
+ STRING = '0.9.0'
5
5
  end
6
6
  end
7
7
  end
@@ -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
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  module RSpec::Http
4
- describe 'API matchers' do
4
+ describe ResponseCodeMatchers do
5
5
  include ResponseCodeMatchers
6
6
 
7
7
  let(:response) { mock('HTTP Response') }
@@ -1 +1,8 @@
1
- require 'rspec/http'
1
+ require 'rspec/http'
2
+ require 'rack'
3
+
4
+ Dir['./spec/support/**/*'].each {|f| require f}
5
+
6
+ RSpec::configure do |config|
7
+ config.color_enabled = true
8
+ end
@@ -0,0 +1,8 @@
1
+ module RSpec
2
+ module Matchers
3
+ def fail_with(message)
4
+ raise_error(RSpec::Expectations::ExpectationNotMetError, message)
5
+ end
6
+ end
7
+ end
8
+
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
- prerelease: false
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: "2.0"
22
+ - !ruby/object:Gem::Version
23
+ version: '2.0'
26
24
  type: :runtime
27
- version_requirements: *id001
28
- description: RSpec HTTP is an extension library that makes it easier to write specs for HTTP/REST APIs
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: "0"
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: "0"
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 HTTP/REST APIs
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
-