Skip to content

Commit

Permalink
Lambda matcher for entire header.
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Bilski authored and Martin Bilski committed Sep 5, 2011
1 parent efc6407 commit 492aaca
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 12 deletions.
24 changes: 18 additions & 6 deletions lib/rspec/cramp/mock_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def matching_response_element?(what, actual, expected)
actual.to_i == expected
elsif expected.is_a? String
actual.to_s == expected
elsif expected.is_a? Proc
expected.call(actual)
else
raise "Unsupported type"
end
Expand Down Expand Up @@ -115,8 +117,13 @@ def matching_header_keys?(expected_header)
end

def matching_headers?(expected_header)
expected_header.nil? ||
(matching_header_keys?(expected_header) && matching_header_values?(expected_header))
if expected_header.nil?
true
elsif expected_header.is_a? Proc
matching_response_element?(:headers, @headers, expected_header)
else
matching_header_keys?(expected_header) && matching_header_values?(expected_header)
end
end

def matching_body?(expected_body)
Expand All @@ -125,10 +132,15 @@ def matching_body?(expected_body)
end

def matching_chunks?(expected_chunks)
expected_chunks.nil? || (@body.is_a?(Array) &&
@body.zip(expected_chunks).find do |actual, expected|
!matching_response_element?(:chunks, actual, expected)
end.nil?)
if expected_chunks.nil?
true
elsif expected_chunks.is_a? Proc
matching_response_element?(:chunks, @body, expected_chunks)
else
(@body.is_a?(Array) && @body.zip(expected_chunks).find do |actual, expected|
!matching_response_element?(:chunks, actual, expected)
end.nil?)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion rspec-cramp.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'rspec-cramp'
s.version = '0.1.0'
s.version = '0.1.1'
s.summary = 'RSpec helpers for Cramp.'
s.description = 'RSpec extension library for Cramp.'

Expand Down
71 changes: 66 additions & 5 deletions spec/rspec_cramp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ def app
end
end

# TODO Rewrite the repetitive code below using data-based spec generation.
describe "exact match on response status" do
it "should match successful response" do
send(method, "/200").should respond_with :status => 200
Expand Down Expand Up @@ -194,6 +193,15 @@ def app
end
end

describe "lambda match on response status" do
it "should match when true" do
send(method, "/200").should respond_with :status => lambda {|status| status == 200}
end
it "should not match when false" do
send(method, "/200").should_not respond_with :status => lambda {|status| status == 500}
end
end

describe "exact match on response header values" do
it "should match with one expected header" do
send(method, "/custom_header").should respond_with :headers => {"Extra-Header" => "ABCD"}
Expand Down Expand Up @@ -224,6 +232,15 @@ def app
end
end

describe "lambda match on response header values" do
it "should match when true" do
send(method, "/custom_header").should respond_with :headers => {"Extra-Header" => lambda {|value| value == "ABCD"}}
end
it "should not match when false" do
send(method, "/custom_header").should_not respond_with :headers => {"Extra-Header" => lambda {|value| value == "WRONG"}}
end
end

describe "regex match on response header fields" do
it "should match with one expected header" do
send(method, "/custom_header").should respond_with :headers => {/Extra\-Header/i => /^ABCD$/}
Expand All @@ -237,6 +254,21 @@ def app
it "should not match iff the header isn't there" do
send(method, "/custom_header").should_not respond_with :headers => {/Non\-Existent\-One/i => /^QWERTY$/}
end
end

describe "lambda match on entire header " do
it "should match when true" do
match_headers = lambda do |headers|
headers.find {|(k, v)| k == "Extra-Header" && v == "ABCD"}
end
send(method, "/custom_header").should respond_with :headers => match_headers
end
it "should not match when false" do
match_headers = lambda do |headers|
headers.find {|(k, v)| k == "Non-Existent-One" && v == "QWERTY"}
end
send(method, "/custom_header").should_not respond_with :headers => match_headers
end
end

# FIXME How to handle a situation where nothing is rendered? get reads the body...
Expand All @@ -261,6 +293,15 @@ def app
end
end

describe "lambda match on response body" do
it "should match when true" do
send(method, "/hello_world").should respond_with :body => lambda {|body| body =~ /.*Hello.*/}
end
it "should not match when false" do
send(method, "/hello_world").should_not respond_with :body => lambda {|body| body =~ /.*incorrect.*/}
end
end

describe "exact match on multipart response body" do
it "should match with successful response" do
send(method, "/multipart", :max_chunks => 2).should respond_with :body => "part1part2"
Expand Down Expand Up @@ -289,6 +330,20 @@ def app
end
end

describe "lambda match on response body chunks" do
it "should match when true" do
send(method, "/multipart", :max_chunks => 2).should respond_with(:chunks => lambda do |chunks|
chunks[0] =~ /part1/ && chunks[1] =~ /part2/
end)
end
it "should not match when false" do
send(method, "/multipart", :max_chunks => 2).should_not respond_with(:chunks => lambda do |chunks|
chunks[0] =~ /whatever1/ || chunks[1] =~ /whatever2/
end)
end
end


describe "multiple conditions" do
it "should match on status and body" do
send(method, "/200").should respond_with :status => :ok, :body => "ok"
Expand Down Expand Up @@ -334,9 +389,16 @@ def app
it "should support request params" do
get("/request_params", :params => {:text => "Hello, world!"}).should respond_with :body => "Hello, world!"
end

it "should pass body chunks to the block" do
actual_chunks = []
get("/sse", :max_chunks => 2).should respond_with(:chunks => lambda {|chunks| actual_chunks = chunks; true})
actual_chunks.should have(2).elements
actual_chunks[0].should include "Hello 1"
actual_chunks[1].should include "Hello 2"
end
end

# TODO Add method-specific paths to http routes and write specs.
describe "GET request" do
it_should_behave_like "async_request", :get

Expand Down Expand Up @@ -388,9 +450,8 @@ def app
routes
end

# TODO Only basic matching here because respond_with matcher uses the same method.
# It should be the other way around, i.e. all the tests should be here but I hate to rewrite the specs now.
# Anyway, we need more tests here.
# Note: Only basic specs here because respond_with matcher uses the same code and is extensively tested.

it "should support expectations on response status" do
get("/200") do |response|
response.should be_matching :status => 200
Expand Down

0 comments on commit 492aaca

Please sign in to comment.