Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Moved rspec-rails pull request #342 into a stand alone repo

  • Loading branch information...
commit b7cc91983ae52934df5517b69bdd20058e298581 1 parent 12394a1
@kaiwren kaiwren authored
View
2  .gitignore
@@ -0,0 +1,2 @@
+*.rbc
+Gemfile.lock
View
3  CHANGELOG
@@ -0,0 +1,3 @@
+== 0.0.1
+
+* Matchers for HTTP response codes
View
11 Gemfile
@@ -0,0 +1,11 @@
+source "http://rubygems.org"
+
+gem "ruby-debug", :platforms => [:ruby_18, :jruby]
+gem "ruby-debug19", :platforms => :ruby_19
+gem "rcov", :platforms => :ruby_18
+
+platforms :jruby do
+ gem "jruby-openssl"
+end
+
+gemspec
View
7 LICENCE
@@ -0,0 +1,7 @@
+Copyright 2011 C42 Engineering India Pvt. Ltd.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software distributed under the License
+is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and limitations under the License.
View
4 README.rdoc
@@ -1,4 +1,6 @@
-= Custom RSpec HTTP response code matchers
+= RSpec HTTP
+
+RSpec HTTP is a RSpec extension library that adds support for writing specs that cover HTTP based APIs.
response.should be_ok
View
11 Rakefile
@@ -0,0 +1,11 @@
+require "bundler"
+Bundler.setup
+
+require 'rspec/core/rake_task'
+
+desc "Run all examples"
+RSpec::Core::RakeTask.new(:spec) do |t|
+ t.rspec_opts = %w[--color]
+end
+
+task :default => :spec
View
62 lib/c42/http_response_code_matcher.rb
@@ -1,62 +0,0 @@
-module C42
- module Matchers
- STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES.merge({
- 102 => "Processing",
- 207 => "Multi-Status",
- 226 => "I'm Used",
- 409 => "Conflict",
- 418 => "I'm A Teapot",
- 422 => "Unprocessable Entity",
- 423 => "Locked",
- 424 => "Failed Dependency",
- 426 => "Upgrade Required",
- 507 => "Insufficient Storage",
- 510 => "Not Extended"
- }).freeze
-
- # Provides a symbol-to-fixnum lookup for converting a symbol (like
- # :created or :not_implemented) into its corresponding HTTP status
- # code (like 200 or 501).
- SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) { |hash, (code, message)|
- hash[message.gsub(/(\s|-)/, "_").gsub('\'', '').downcase.to_sym] = code
- hash
- }.freeze
-
- class HttpResponseCodeMatcher
- def initialize(expected_code)
- @expected_code = expected_code
- end
-
- def matches?(target)
- @target = target
- @target.code.to_i == @expected_code
- end
-
- def description
- "Response code should be #{@expected_code}"
- end
-
- def failure_message
- "Expected #{@target} to #{common_message}"
- end
-
- def negative_failure_message
- "Expected #{@target} to not #{common_message}"
- end
-
- def common_message
- message = "have a response code of #{@expected_code}, but got #{@target.code}"
- if @target.code.to_i == 302
- message += " with a location of #{@target['Location'] || @target['location']}"
- end
- message
- end
- end
-
- SYMBOL_TO_STATUS_CODE.each do |symbol, code|
- define_method("be_#{symbol}") do
- HttpResponseCodeMatcher.new(code)
- end
- end
- end
-end
View
4 lib/rspec/http.rb
@@ -0,0 +1,4 @@
+require 'rspec/core'
+
+require 'rspec/http/status_codes'
+require 'rspec/http/response_code_matchers'
View
53 lib/rspec/http/response_code_matchers.rb
@@ -0,0 +1,53 @@
+module RSpec
+ module Http
+ module ResponseCodeMatchers
+ def self.clean_up_status(message)
+ message.gsub(/(\s|-)/, "_").gsub('\'', '').downcase.to_sym
+ end
+
+ def self.status_as_valid_method_name(look_up_code)
+ (@status_codes ||= RSpec::Http::STATUS_CODES.inject({}) do |hash, (code, message)|
+ hash[code] = clean_up_status(message)
+ hash
+ end.freeze)[look_up_code]
+ end
+
+ class HttpResponseCodeMatcher
+ def initialize(expected_code)
+ @expected_code = expected_code
+ end
+
+ def matches?(target)
+ @target = target
+ @target.code.to_i == @expected_code
+ end
+
+ def description
+ "Response code should be #{@expected_code}"
+ end
+
+ def failure_message
+ "Expected #{@target} to #{common_message}"
+ end
+
+ def negative_failure_message
+ "Expected #{@target} to not #{common_message}"
+ end
+
+ def common_message
+ message = "have a response code of #{@expected_code}, but got #{@target.code}"
+ if @target.code.to_i == 302 || @target.code.to_i == 201
+ message += " with a location of #{@target['Location'] || @target['location']}"
+ end
+ message
+ end
+ end
+
+ RSpec::Http::STATUS_CODES.each do |code, status|
+ define_method("be_#{status_as_valid_method_name(code)}") do
+ HttpResponseCodeMatcher.new(code)
+ end
+ end
+ end
+ end
+end
View
59 lib/rspec/http/status_codes.rb
@@ -0,0 +1,59 @@
+module RSpec
+ module Http
+ STATUS_CODES = {
+ 100=>"Continue",
+ 101=>"Switching Protocols",
+ 102=>"Processing",
+ 200=>"OK",
+ 201=>"Created",
+ 202=>"Accepted",
+ 203=>"Non-Authoritative Information",
+ 204=>"No Content",
+ 205=>"Reset Content",
+ 206=>"Partial Content",
+ 207=>"Multi-Status",
+ 226=>"IM Used",
+ 300=>"Multiple Choices",
+ 301=>"Moved Permanently",
+ 302=>"Found",
+ 303=>"See Other",
+ 304=>"Not Modified",
+ 305=>"Use Proxy",
+ 306=>"Reserved",
+ 307=>"Temporary Redirect",
+ 400=>"Bad Request",
+ 401=>"Unauthorized",
+ 402=>"Payment Required",
+ 403=>"Forbidden",
+ 404=>"Not Found",
+ 405=>"Method Not Allowed",
+ 406=>"Not Acceptable",
+ 407=>"Proxy Authentication Required",
+ 408=>"Request Timeout",
+ 409=>"Conflict",
+ 410=>"Gone",
+ 411=>"Length Required",
+ 412=>"Precondition Failed",
+ 413=>"Request Entity Too Large",
+ 414=>"Request-URI Too Long",
+ 415=>"Unsupported Media Type",
+ 416=>"Requested Range Not Satisfiable",
+ 417=>"Expectation Failed",
+ 418 => "I'm A Teapot",
+ 422=>"Unprocessable Entity",
+ 423=>"Locked",
+ 424=>"Failed Dependency",
+ 426=>"Upgrade Required",
+ 500=>"Internal Server Error",
+ 501=>"Not Implemented",
+ 502=>"Bad Gateway",
+ 503=>"Service Unavailable",
+ 504=>"Gateway Timeout",
+ 505=>"HTTP Version Not Supported",
+ 506=>"Variant Also Negotiates",
+ 507=>"Insufficient Storage",
+ 510=>"Not Extended"
+ }.freeze
+ end
+end
+
View
7 lib/rspec/http/version.rb
@@ -0,0 +1,7 @@
+module RSpec # :nodoc:
+ module Http # :nodoc:
+ module Version # :nodoc:
+ STRING = '0.0.1'
+ end
+ end
+end
View
25 rspec-http.gemspec
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
+require "rspec/http/version"
+
+Gem::Specification.new do |s|
+ s.name = "rspec-http"
+ s.version = RSpec::Http::Version::STRING
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Sidu Ponnappa", "Niranjan Paranjape"]
+ s.email = "ckponnappa@gmail.com"
+ s.homepage = "http://c42.in/open_source"
+ s.summary = "RSpec HTTP is an extension library that makes it easier to write specs for HTTP/REST APIs"
+ s.description = "RSpec HTTP is an extension library that makes it easier to write specs for HTTP/REST APIs"
+
+ s.rubygems_version = "1.3.7"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
+ s.extra_rdoc_files = [ "README.rdoc" ]
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_path = "lib"
+
+ s.add_runtime_dependency "rspec", "~> 2.0"
+end
+
View
57 spec/rspec/http/response_code_matchers_spec.rb
@@ -0,0 +1,57 @@
+require "spec_helper"
+
+module RSpec::Http
+ describe 'API matchers' do
+ include ResponseCodeMatchers
+
+ let(:response) { mock('HTTP Response') }
+
+ context 'status to matcher conversion' do
+ it "replaces spaces with underscores" do
+ ResponseCodeMatchers::clean_up_status("Method Not Allowed").should eq(:method_not_allowed)
+ end
+
+ it "downcases capital letters" do
+ ResponseCodeMatchers::clean_up_status("IM Used").should eq(:im_used)
+ end
+
+ it "removes apostrophes" do
+ ResponseCodeMatchers::clean_up_status("I'm A Teapot").should eq(:im_a_teapot)
+ end
+
+ it "replaces hyphens with underscores" do
+ ResponseCodeMatchers::clean_up_status("Non-Authoritative Information").should eq(:non_authoritative_information)
+ end
+ end
+
+ context "matching codes" do
+ STATUS_CODES.each do |code, status|
+ it "understands if a response is of type #{status}" do
+ response.stub(:code).and_return(code.to_s)
+ response.should send("be_#{ResponseCodeMatchers.status_as_valid_method_name(code)}")
+ end
+
+ it "understands if a response is not of type #{status}" do
+ response.stub(:code).and_return('0')
+ response.should_not send("be_#{ResponseCodeMatchers.status_as_valid_method_name(code)}")
+ end
+ end
+
+ context "where the value of the location header field can be important" do
+ before :each do
+ response.stub(:[]).with('Location').and_return('http://test.server')
+ end
+
+ it "response of type created" do
+ response.stub(:code).and_return('201')
+ expect{ response.should be_ok }.to raise_error(/with a location of http:\/\/test\.server$/)
+ end
+
+ it "response of type redirect" do
+ response.stub(:code).and_return('302')
+ expect{ response.should be_ok }.to raise_error(/with a location of http:\/\/test\.server$/)
+ end
+ end
+ end
+ end
+end
View
1  spec/spec_helper.rb
@@ -0,0 +1 @@
+require 'rspec/http'
Please sign in to comment.
Something went wrong with that request. Please try again.