Skip to content

Commit

Permalink
Added def_matcher(), a custom matcher builder.
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy McAnally <jeremymcanally@gmail.com>
  • Loading branch information
mhennemeyer authored and jm committed Feb 11, 2009
1 parent 1186158 commit b90775a
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/matchy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
require 'matchy/expectation'
require 'matchy/modals'
require 'matchy/version'
require 'matchy/def_matcher'

require 'matchy/built_in/enumerable_expectations'
require 'matchy/built_in/error_expectations'
require 'matchy/built_in/truth_expectations'
require 'matchy/built_in/operator_expectations'

Test::Unit::TestCase.send(:include, Matchy::Expectations::TestCaseExtensions)
Test::Unit::TestCase.send(:include, Matchy::Expectations::TestCaseExtensions)

include Matchy::DefMatcher

46 changes: 46 additions & 0 deletions lib/matchy/def_matcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module Matchy
module DefMatcher
def def_matcher(matcher_name, &block)
self.class.send :define_method, matcher_name do |*args|
match_block = lambda do |actual, matcher|
block.call(actual, matcher, args)
end
body = lambda do |klass|
@matcher_name = matcher_name.to_s
def self.matcher_name
@matcher_name
end

attr_accessor :positive_msg, :negative_msg, :msgs
attr_reader :matcher_name
def initialize match_block, test_case
@test_case = test_case
@match_block = match_block
@matcher_name = self.class.matcher_name
end

def method_missing id, *args, &block
require 'ostruct'
(self.msgs ||= []) << OpenStruct.new( "name" => id, "args" => args, "block" => block )
self
end

def matches? given
@positive_msg ||= "Matching with '#{matcher_name}' failed, although it should match."
@negative_msg ||= "Matching with '#{matcher_name}' passed, although it should_not match."
@match_block.call(given, self)
end

def failure_message
self.positive_msg
end

def negative_failure_message
self.negative_msg
end
end
Class.new(Matchy::Expectations::Base, &body).new(match_block, self)
end
end
end
end
100 changes: 100 additions & 0 deletions test/test_def_matcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
require File.dirname(__FILE__) + '/test_helper.rb'

class TestDefMatcher < Test::Unit::TestCase

def setup
@obj = Object.new
end

def test_defines_method
def_matcher :method_ do |given, matcher, args|
end
self.should respond_to(:method_)
end

def test_object_responds_to_matches
def_matcher :method_ do |given, matcher, args|
end
method_.should respond_to(:matches?)
end

def test_fail_positive
def_matcher :matcher do |given, matcher, args|
false
end
lambda {1.should matcher}.should raise_error
end

def test_pass_positive
def_matcher :matcher do |given, matcher, args|
true
end
lambda {1.should matcher}.should_not raise_error
end

def test_fail_negative
def_matcher :matcher do |given, matcher, args|
true
end
lambda {1.should_not matcher}.should raise_error
end

def test_pass_negative
def_matcher :matcher do |given, matcher, args|
false
end
lambda {1.should_not matcher}.should_not raise_error
end

def test_takes_arguments
def_matcher :matcher do |given, matcher, args|
$args = args
true
end
@obj.should matcher(1,2,3)
$args.should eql([1,2,3])
end

def test_received_method
def_matcher :matcher do |given, matcher, args|
$msgs = matcher.msgs
true
end
@obj.should matcher.method1
$msgs[0].name.should eql(:method1)
end

def test_received_method_takes_args
def_matcher :matcher do |given, matcher, args|
$msgs = matcher.msgs
true
end
@obj.should matcher.method1(1,2,3)
$msgs[0].args.should eql([1,2,3])
end

def test_received_method_takes_block
def_matcher :matcher do |given, matcher, args|
$msgs = matcher.msgs
true
end
@obj.should matcher.method1 { "Hello, World!"}
$msgs[0].block.call.should eql("Hello, World!")
end

def test_received_method_chained
def_matcher :matcher do |given, matcher, args|
$msgs = matcher.msgs
true
end
@obj.should matcher.method1(1,2,3) { "Hello, World!"}.
method2(4,5,6) { "Hello chained messages" }

$msgs[0].name.should eql(:method1)
$msgs[1].name.should eql(:method2)
$msgs[0].args.should eql([1,2,3])
$msgs[1].args.should eql([4,5,6])
$msgs[0].block.call.should eql("Hello, World!")
$msgs[1].block.call.should eql("Hello chained messages")
end
end

0 comments on commit b90775a

Please sign in to comment.