Skip to content

Commit

Permalink
adding respond_with_content_type matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Croak authored and jferris committed Feb 7, 2009
1 parent 5d0ac37 commit 60ecc54
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 3 deletions.
1 change: 0 additions & 1 deletion controller_progress.txt
@@ -1,5 +1,4 @@
Unfinished:
should_respond_with
should_respond_with_content_type

Finished:
Expand Down
1 change: 1 addition & 0 deletions lib/shoulda/controller/matchers.rb
Expand Up @@ -3,6 +3,7 @@
require 'shoulda/controller/matchers/set_the_flash_matcher'
require 'shoulda/controller/matchers/render_with_layout_matcher'
require 'shoulda/controller/matchers/respond_with_matcher'
require 'shoulda/controller/matchers/respond_with_content_type_matcher'
require 'shoulda/controller/matchers/set_session_matcher'
require 'shoulda/controller/matchers/route_matcher'

Expand Down
@@ -0,0 +1,70 @@
module Shoulda # :nodoc:
module Controller # :nodoc:
module Matchers

# Ensures a controller responded with expected 'response' content type.
#
# You can pass an explicit content type such as 'application/rss+xml'
# or its symbolic equivalent :rss
# or a regular expression such as /rss/
#
# Example:
#
# it { should respond_with_content_type(:xml) }
# it { should respond_with_content_type(:csv) }
# it { should respond_with_content_type(:atom) }
# it { should respond_with_content_type(:yaml) }
# it { should respond_with_content_type(:text) }
# it { should respond_with_content_type('application/rss+xml') }
# it { should respond_with_content_type(/json/) }
def respond_with_content_type(content_type)
RespondWithContentTypeMatcher.new(content_type)
end

class RespondWithContentTypeMatcher # :nodoc:

def initialize(content_type)
@content_type = if content_type.is_a?(Symbol)
lookup_by_extension(content_type)
else
content_type
end
end

def matches?(controller)
@controller = controller
if @content_type.is_a?(Regexp)
response_content_type =~ @content_type
else
response_content_type == @content_type
end
end

def failure_message
"Expected #{expectation}"
end

def negative_failure_message
"Did not expect #{expectation}"
end

protected

def response_content_type
@controller.response.content_type
end

def lookup_by_extension(extension)
Mime::Type.lookup_by_extension(extension.to_s).to_s
end

def expectation
"content type to be #{@content_type}, " <<
"but was #{response_content_type}"
end

end

end
end
end
8 changes: 6 additions & 2 deletions lib/shoulda/controller/matchers/respond_with_matcher.rb
Expand Up @@ -31,11 +31,11 @@ def matches?(controller)
end

def failure_message
"Expected status to be #{@status}"
"Expected #{expectation}"
end

def negative_failure_message
"Did not expect status to be #{@status} but was #{response_code}"
"Did not expect #{expectation}"
end

protected
Expand Down Expand Up @@ -66,6 +66,10 @@ def symbol_to_status_code(potential_symbol)
end
end

def expectation
"response to be a #{@status}, but was #{response_code}"
end

end

end
Expand Down
27 changes: 27 additions & 0 deletions test/matchers/controller/respond_with_content_type_matcher_test.rb
@@ -0,0 +1,27 @@
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')

class RespondWithContentTypeMatcherTest < Test::Unit::TestCase # :nodoc:

context "a controller responding with content type :xml" do
setup do
@controller = build_response { render :xml => { :user => "thoughtbot" }.to_xml }
end

should "accept responding with content type :xml" do
assert_accepts respond_with_content_type(:xml), @controller
end

should "accept responding with content type 'application/xml'" do
assert_accepts respond_with_content_type('application/xml'), @controller
end

should "accept responding with content type /xml/" do
assert_accepts respond_with_content_type(/xml/), @controller
end

should "reject responding with another content type" do
assert_rejects respond_with_content_type(:json), @controller
end
end

end

0 comments on commit 60ecc54

Please sign in to comment.