This repository has been archived by the owner on Oct 27, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 171
/
simple_matcher.rb
104 lines (97 loc) · 3.57 KB
/
simple_matcher.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
module Spec
module Matchers
class SimpleMatcher
attr_writer :failure_message, :negative_failure_message, :description
def initialize(description, &match_block)
@description = description
@match_block = match_block
end
def matches?(actual)
@actual = actual
case @match_block.arity
when 2
@match_block.call(@actual, self)
else
@match_block.call(@actual)
end
end
def description
@description || explanation
end
def failure_message
@failure_message || (@description.nil? ? explanation : %[expected #{@description.inspect} but got #{@actual.inspect}])
end
def negative_failure_message
@negative_failure_message || (@description.nil? ? explanation : %[expected not to get #{@description.inspect}, but got #{@actual.inspect}])
end
def explanation
"No description provided. See RDoc for simple_matcher()"
end
end
# +simple_matcher()+ makes it easy for you to create your own custom
# matchers in just a few lines of code when you don't need all the power
# of a completely custom matcher object.
#
# The description argument will appear as part of any failure message.
#
# The match block can have arity of 1 or 2. The first argument will be the
# given value. The second, if the block accepts it will be the matcher
# itself, giving you access to set custom failure messages in favor of the
# defaults.
#
# If you set custom messages, you don't have to pass the description
# argument to the simple_matcher method, but you must then provide any
# messages that might get invoked directly to the matcher (see Example
# with custom messages, below)
#
# The match_block should return a boolean: true indicates a match, which
# will pass if you use +should+ and fail if you use +should_not+. false
# (or nil) indicates no match, which will do the reverse: fail if you use
# +should+ and pass if you use +should_not+.
#
# An error in the +match_block+ will bubble up, resulting in a failure.
# This includes ExpectationNotMet errors (raised by +should+ and
# +should_not+), so you can wrap other expectations in a +simple_matcher+
# and they'll "do the right thing."
#
# == Example with default messages
#
# def be_even
# simple_matcher("an even number") { |given| given % 2 == 0 }
# end
#
# describe 2 do
# it "should be even" do
# 2.should be_even
# end
# end
#
# Given an odd number, this example would produce an error message stating
# 'expected "an even number"", got 3'
#
# == Example with custom messages
#
# def rhyme_with(expected)
# simple_matcher do |given, matcher|
# matcher.description = "string rhymer"
# matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
# matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
# actual.rhymes_with? expected
# end
# end
#
# describe "pecan" do
# it "should rhyme with 'be gone'" do
# nut = "pecan"
# nut.extend Rhymer
# nut.should rhyme_with("be gone")
# end
# end
#
# The resulting failure message would be 'expected "pecan" to rhyme with
# "be gone"'. (Grandma Rita would be proud!)
def simple_matcher(description=nil, &match_block)
SimpleMatcher.new(description, &match_block)
end
end
end