require 'spec_helper' module Spec module Matchers describe Matcher do context "without overrides" do before(:each) do @matcher = Spec::Matchers::Matcher.new(:be_a_multiple_of, 3) do |multiple| match do |actual| actual % multiple == 0 end end end it "provides a default description" do @matcher.description.should == "be a multiple of 3" end it "provides a default failure message for #should" do @matcher.matches?(8) @matcher.failure_message_for_should.should == "expected 8 to be a multiple of 3" end it "provides a default failure message for #should_not" do @matcher.matches?(9) @matcher.failure_message_for_should_not.should == "expected 9 not to be a multiple of 3" end end it "is not diffable by default" do matcher = Spec::Matchers::Matcher.new(:name) {} matcher.should_not be_diffable end it "is diffable when told to be" do matcher = Spec::Matchers::Matcher.new(:name) { diffable } matcher.should be_diffable end it "provides expected" do matcher = Spec::Matchers::Matcher.new(:name, 'expected string') {} matcher.expected.should == ['expected string'] end it "provides actual" do matcher = Spec::Matchers::Matcher.new(:name, 'expected string') do match {|actual|} end matcher.matches?('actual string') matcher.actual.should == 'actual string' end context "with overrides" do before(:each) do @matcher = Spec::Matchers::Matcher.new(:be_boolean, true) do |boolean| match do |actual| actual end description do "be the boolean #{boolean}" end failure_message_for_should do |actual| "expected #{actual} to be the boolean #{boolean}" end failure_message_for_should_not do |actual| "expected #{actual} not to be the boolean #{boolean}" end end end it "does not hide result of match block when true" do @matcher.matches?(true).should be_true end it "does not hide result of match block when false" do @matcher.matches?(false).should be_false end it "overrides the description" do @matcher.description.should == "be the boolean true" end it "overrides the failure message for #should" do @matcher.matches?(false) @matcher.failure_message_for_should.should == "expected false to be the boolean true" end it "overrides the failure message for #should_not" do @matcher.matches?(true) @matcher.failure_message_for_should_not.should == "expected true not to be the boolean true" end end context "#new" do it "passes matches? arg to match block" do matcher = Spec::Matchers::Matcher.new(:ignore) do match do |actual| actual == 5 end end matcher.matches?(5).should be_true end it "exposes arg submitted through #new to matcher block" do matcher = Spec::Matchers::Matcher.new(:ignore, 4) do |expected| match do |actual| actual > expected end end matcher.matches?(5).should be_true end end context "with no args" do before(:each) do @matcher = Spec::Matchers::Matcher.new(:matcher_name) do match do |actual| actual == 5 end end end it "matches" do @matcher.matches?(5).should be_true end it "describes" do @matcher.description.should == "matcher name" end end context "with 1 arg" do before(:each) do @matcher = Spec::Matchers::Matcher.new(:matcher_name, 1) do |expected| match do |actual| actual == 5 && expected == 1 end end end it "matches" do @matcher.matches?(5).should be_true end it "describes" do @matcher.description.should == "matcher name 1" end end context "with multiple args" do before(:each) do @matcher = Spec::Matchers::Matcher.new(:matcher_name, 1, 2, 3, 4) do |a,b,c,d| match do |sum| a + b + c + d == sum end end end it "matches" do @matcher.matches?(10).should be_true end it "describes" do @matcher.description.should == "matcher name 1, 2, 3, and 4" end end it "supports helper methods" do matcher = Spec::Matchers::Matcher.new(:be_similar_to, [1,2,3]) do |sample| match do |actual| similar?(sample, actual) end def similar?(a, b) a.sort == b.sort end end matcher.matches?([2,3,1]).should be_true end it "supports fluent interface" do matcher = Spec::Matchers::Matcher.new(:first_word) do def second_word self end end matcher.second_word.should == matcher end it "treats method missing normally for undeclared methods" do matcher = Spec::Matchers::Matcher.new(:ignore) { } expect { matcher.non_existent_method }.to raise_error(NoMethodError) end it "has access to other matchers" do matcher = Spec::Matchers::Matcher.new(:ignore, 3) do |expected| match do |actual| extend Spec::Matchers actual.should eql(5 + expected) end end matcher.matches?(8).should be_true end it "lets you override the actual() in messages" do matcher = Spec::Matchers::Matcher.new(:be_foo) do match do |actual| @submitted = actual false end def actual "replaced" end end matcher.matches?("foo") matcher.failure_message_for_should.should =~ /replaced/ end end end end