require 'rubygems'
require 'spec'
module SpyMatchers
class MethodRecorder
def method_missing(sym, *args)
MethodVerifier.new({sym => args})
end
end
def have_received
MethodRecorder.new
end
class MethodVerifier
def initialize(expected)
@expected = expected
end
def matches?(target)
@target = target
@target.was_method_called?(@expected)
end
def failure_message
"expected #{@target.__subject__.inspect} to have received #{@expected.keys[0]}(#{@expected.values[0]})"
end
def negative_failure_message
"expected #{@target.__subject__.inspect} not to have received #{@expected.keys[0]}(#{@expected.values[0]})"
end
end
end
class Spy
def self.on(subject)
Spy.new(subject)
end
def initialize(subject)
@subject = subject
@method_calls = []
end
def was_method_called?(method_with_args)
return @method_calls.include?(method_with_args)
end
def __subject__
@subject
end
def method_missing(sym, *args)
@method_calls << {sym => args}
@subject.send(sym, *args)
end
end
describe "ubiquitous assertion syntax" do
include SpyMatchers
it "should test state" do
2.should == 1+1
end
it "should test an error" do
lambda { [].not_a_method }.should raise_error(NoMethodError)
end
it "should test behavior" do
array = Spy.on []
[1, 2].each do |number|
array << number
end
array.should have_received << 1
array.should have_received << 2
end
end