rspec 1.2.9 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.rdoc +51 -1
- data/License.txt +1 -1
- data/Manifest.txt +11 -4
- data/README.rdoc +10 -24
- data/Rakefile +17 -13
- data/Upgrade.rdoc +63 -2
- data/examples/passing/shared_example_group_example.rb +0 -36
- data/examples/passing/simple_matcher_example.rb +3 -3
- data/features/formatters/nested_formatter.feature +32 -0
- data/features/interop/cucumber_stubs_dont_leak.feature +11 -0
- data/features/interop/test_but_not_test_unit.feature +1 -1
- data/features/interop/test_case_with_should_methods.feature +1 -1
- data/features/matchers/define_matcher_with_fluent_interface.feature +21 -0
- data/features/matchers/define_wrapped_matcher.feature +28 -1
- data/features/matchers/match_unless_raises.feature +60 -0
- data/features/matchers/match_unless_raises_unexpected_error.feature +39 -0
- data/features/mocks/block_local_expectations.feature +62 -0
- data/features/step_definitions/running_rspec_steps.rb +9 -0
- data/features/step_definitions/stubbing_steps.rb +16 -0
- data/features/support/env.rb +1 -0
- data/features/support/matchers/smart_match.rb +23 -4
- data/geminstaller.yml +29 -0
- data/lib/autotest/rspec.rb +14 -7
- data/lib/spec/deprecation.rb +2 -1
- data/lib/spec/dsl/main.rb +2 -1
- data/lib/spec/example/example_group_methods.rb +6 -1
- data/lib/spec/example/example_methods.rb +4 -0
- data/lib/spec/example/subject.rb +9 -3
- data/lib/spec/interop/test/unit/testsuite_adapter.rb +2 -0
- data/lib/spec/interop/test.rb +1 -1
- data/lib/spec/matchers/be.rb +167 -128
- data/lib/spec/matchers/has.rb +3 -3
- data/lib/spec/matchers/have.rb +1 -0
- data/lib/spec/matchers/matcher.rb +55 -10
- data/lib/spec/matchers/method_missing.rb +2 -2
- data/lib/spec/matchers/operator_matcher.rb +6 -1
- data/lib/spec/matchers/pretty.rb +2 -2
- data/lib/spec/matchers/raise_exception.rb +131 -0
- data/lib/spec/matchers/simple_matcher.rb +2 -1
- data/lib/spec/matchers/throw_symbol.rb +18 -22
- data/lib/spec/matchers.rb +21 -2
- data/lib/spec/mocks/message_expectation.rb +63 -48
- data/lib/spec/mocks/methods.rb +13 -8
- data/lib/spec/mocks/proxy.rb +45 -22
- data/lib/spec/runner/backtrace_tweaker.rb +3 -2
- data/lib/spec/runner/configuration.rb +8 -0
- data/lib/spec/runner/differs/default.rb +1 -1
- data/lib/spec/runner/drb_command_line.rb +8 -2
- data/lib/spec/runner/example_group_runner.rb +1 -2
- data/lib/spec/runner/formatter/nested_text_formatter.rb +6 -3
- data/lib/spec/runner/option_parser.rb +2 -0
- data/lib/spec/runner/options.rb +8 -2
- data/lib/spec/stubs/cucumber.rb +2 -2
- data/lib/spec/version.rb +2 -2
- data/spec/autotest/autotest_helper.rb +1 -1
- data/spec/autotest/discover_spec.rb +2 -2
- data/spec/autotest/failed_results_re_spec.rb +2 -2
- data/spec/autotest/rspec_spec.rb +21 -6
- data/spec/spec/dsl/main_spec.rb +10 -2
- data/spec/spec/example/example_group_methods_spec.rb +21 -1
- data/spec/spec/example/example_group_proxy_spec.rb +1 -1
- data/spec/spec/example/example_group_spec.rb +1 -12
- data/spec/spec/example/example_matcher_spec.rb +3 -4
- data/spec/spec/example/subject_spec.rb +7 -0
- data/spec/spec/expectations/wrap_expectation_spec.rb +2 -1
- data/spec/spec/interop/test/unit/spec_spec.rb +7 -7
- data/spec/spec/interop/test/unit/testcase_spec.rb +7 -7
- data/spec/spec/interop/test/unit/testsuite_adapter_spec.rb +1 -1
- data/spec/spec/matchers/be_spec.rb +159 -10
- data/spec/spec/matchers/has_spec.rb +109 -0
- data/spec/spec/matchers/have_spec.rb +278 -293
- data/spec/spec/matchers/match_array_spec.rb +8 -1
- data/spec/spec/matchers/matcher_spec.rb +70 -9
- data/spec/spec/matchers/raise_exception_spec.rb +345 -0
- data/spec/spec/matchers/simple_matcher_spec.rb +51 -44
- data/spec/spec/matchers/throw_symbol_spec.rb +83 -58
- data/spec/spec/mocks/and_yield_spec.rb +117 -0
- data/spec/spec/mocks/bug_report_496_spec.rb +2 -4
- data/spec/spec/mocks/mock_spec.rb +2 -2
- data/spec/spec/runner/command_line_spec.rb +26 -5
- data/spec/spec/runner/drb_command_line_spec.rb +39 -0
- data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +35 -11
- data/spec/spec/runner/option_parser_spec.rb +12 -6
- data/spec/spec/runner/options_spec.rb +7 -0
- data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +23 -5
- data/spec/spec_helper.rb +2 -1
- metadata +107 -38
- data/lib/spec/matchers/raise_error.rb +0 -129
- data/spec/spec/matchers/matcher_methods_spec.rb +0 -63
- data/spec/spec/matchers/raise_error_spec.rb +0 -333
- /data/lib/spec/{matchers/extensions → extensions}/instance_exec.rb +0 -0
data/lib/spec/matchers/have.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Spec
|
|
|
12
12
|
@expected = expected
|
|
13
13
|
@actual = nil
|
|
14
14
|
@diffable = false
|
|
15
|
+
@expected_exception = nil
|
|
15
16
|
@messages = {
|
|
16
17
|
:description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
|
|
17
18
|
:failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"},
|
|
@@ -22,33 +23,70 @@ module Spec
|
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
#Used internally by objects returns by +should+ and +should_not+.
|
|
25
27
|
def matches?(actual)
|
|
26
|
-
|
|
28
|
+
@actual = actual
|
|
29
|
+
if @expected_exception
|
|
30
|
+
begin
|
|
31
|
+
instance_exec(actual, &@match_block)
|
|
32
|
+
true
|
|
33
|
+
rescue @expected_exception
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
begin
|
|
38
|
+
instance_exec(actual, &@match_block)
|
|
39
|
+
rescue Spec::Expectations::ExpectationNotMetError
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
end
|
|
27
43
|
end
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
# See Spec::Matchers
|
|
46
|
+
def match(&block)
|
|
47
|
+
@match_block = block
|
|
31
48
|
end
|
|
32
49
|
|
|
50
|
+
# See Spec::Matchers
|
|
51
|
+
def match_unless_raises(exception=Exception, &block)
|
|
52
|
+
@expected_exception = exception
|
|
53
|
+
match(&block)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# See Spec::Matchers
|
|
33
57
|
def failure_message_for_should(&block)
|
|
34
|
-
cache_or_call_cached(:failure_message_for_should,
|
|
58
|
+
cache_or_call_cached(:failure_message_for_should, &block)
|
|
35
59
|
end
|
|
36
60
|
|
|
61
|
+
# See Spec::Matchers
|
|
37
62
|
def failure_message_for_should_not(&block)
|
|
38
|
-
cache_or_call_cached(:failure_message_for_should_not,
|
|
63
|
+
cache_or_call_cached(:failure_message_for_should_not, &block)
|
|
39
64
|
end
|
|
40
65
|
|
|
41
|
-
|
|
42
|
-
|
|
66
|
+
# See Spec::Matchers
|
|
67
|
+
def description(&block)
|
|
68
|
+
cache_or_call_cached(:description, &block)
|
|
43
69
|
end
|
|
44
70
|
|
|
71
|
+
#Used internally by objects returns by +should+ and +should_not+.
|
|
45
72
|
def diffable?
|
|
46
73
|
@diffable
|
|
47
74
|
end
|
|
48
75
|
|
|
76
|
+
# See Spec::Matchers
|
|
49
77
|
def diffable
|
|
50
78
|
@diffable = true
|
|
51
79
|
end
|
|
80
|
+
|
|
81
|
+
# See Spec::Matchers
|
|
82
|
+
def chain(method, &block)
|
|
83
|
+
self.class.class_eval do
|
|
84
|
+
define_method method do |*args|
|
|
85
|
+
block.call(*args)
|
|
86
|
+
self
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
52
90
|
|
|
53
91
|
private
|
|
54
92
|
|
|
@@ -69,9 +107,16 @@ module Spec
|
|
|
69
107
|
(private_methods - orig_private_methods).each {|m| st.__send__ :public, m}
|
|
70
108
|
end
|
|
71
109
|
|
|
72
|
-
def cache_or_call_cached(key,
|
|
73
|
-
block ?
|
|
74
|
-
|
|
110
|
+
def cache_or_call_cached(key, &block)
|
|
111
|
+
block ? cache(key, &block) : call_cached(key)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def cache(key, &block)
|
|
115
|
+
@messages[key] = block
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def call_cached(key)
|
|
119
|
+
@messages[key].arity == 1 ? @messages[key].call(@actual) : @messages[key].call
|
|
75
120
|
end
|
|
76
121
|
|
|
77
122
|
def name_to_sentence
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Spec
|
|
2
2
|
module Matchers
|
|
3
3
|
def method_missing(sym, *args, &block) # :nodoc:
|
|
4
|
-
return Matchers::
|
|
5
|
-
return Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/
|
|
4
|
+
return Matchers::BePredicate.new(sym, *args, &block) if sym.to_s =~ /^be_/
|
|
5
|
+
return Matchers::Has.new(sym, *args, &block) if sym.to_s =~ /^have_/
|
|
6
6
|
super
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -13,7 +13,12 @@ module Spec
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def get(klass, operator)
|
|
16
|
-
registry[klass] && registry[klass][operator]
|
|
16
|
+
matcher = registry[klass] && registry[klass][operator]
|
|
17
|
+
unless matcher
|
|
18
|
+
parent_class = registry.keys.detect {|pc| klass <= pc }
|
|
19
|
+
matcher = registry[parent_class] && registry[parent_class][operator]
|
|
20
|
+
end
|
|
21
|
+
matcher
|
|
17
22
|
end
|
|
18
23
|
end
|
|
19
24
|
|
data/lib/spec/matchers/pretty.rb
CHANGED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
module Spec
|
|
2
|
+
module Matchers
|
|
3
|
+
class RaiseException #:nodoc:
|
|
4
|
+
def initialize(expected_exception_or_message=Exception, expected_message=nil, &block)
|
|
5
|
+
@block = block
|
|
6
|
+
@actual_exception = nil
|
|
7
|
+
case expected_exception_or_message
|
|
8
|
+
when String, Regexp
|
|
9
|
+
@expected_exception, @expected_message = Exception, expected_exception_or_message
|
|
10
|
+
else
|
|
11
|
+
@expected_exception, @expected_message = expected_exception_or_message, expected_message
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def matches?(given_proc)
|
|
16
|
+
@raised_expected_exception = false
|
|
17
|
+
@with_expected_message = false
|
|
18
|
+
@eval_block = false
|
|
19
|
+
@eval_block_passed = false
|
|
20
|
+
begin
|
|
21
|
+
given_proc.call
|
|
22
|
+
rescue @expected_exception => @actual_exception
|
|
23
|
+
@raised_expected_exception = true
|
|
24
|
+
@with_expected_message = verify_message
|
|
25
|
+
rescue Exception => @actual_exception
|
|
26
|
+
# This clause should be empty, but rcov will not report it as covered
|
|
27
|
+
# unless something (anything) is executed within the clause
|
|
28
|
+
rcov_exception_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
unless negative_expectation?
|
|
32
|
+
eval_block if @raised_expected_exception && @with_expected_message && @block
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
(@raised_expected_exception & @with_expected_message) ? (@eval_block ? @eval_block_passed : true) : false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def eval_block
|
|
39
|
+
@eval_block = true
|
|
40
|
+
begin
|
|
41
|
+
@block[@actual_exception]
|
|
42
|
+
@eval_block_passed = true
|
|
43
|
+
rescue Exception => err
|
|
44
|
+
@actual_exception = err
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def verify_message
|
|
49
|
+
case @expected_message
|
|
50
|
+
when nil
|
|
51
|
+
true
|
|
52
|
+
when Regexp
|
|
53
|
+
@expected_message =~ @actual_exception.message
|
|
54
|
+
else
|
|
55
|
+
@expected_message == @actual_exception.message
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def failure_message_for_should
|
|
60
|
+
@eval_block ? @actual_exception.message : "expected #{expected_exception}#{given_exception}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def failure_message_for_should_not
|
|
64
|
+
"expected no #{expected_exception}#{given_exception}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def description
|
|
68
|
+
"raise #{expected_exception}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
def expected_exception
|
|
73
|
+
case @expected_message
|
|
74
|
+
when nil
|
|
75
|
+
@expected_exception
|
|
76
|
+
when Regexp
|
|
77
|
+
"#{@expected_exception} with message matching #{@expected_message.inspect}"
|
|
78
|
+
else
|
|
79
|
+
"#{@expected_exception} with #{@expected_message.inspect}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def given_exception
|
|
84
|
+
@actual_exception.nil? ? " but nothing was raised" : ", got #{@actual_exception.inspect}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def negative_expectation?
|
|
88
|
+
# YES - I'm a bad person... help me find a better way - ryand
|
|
89
|
+
caller.first(3).find { |s| s =~ /should_not/ }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# :call-seq:
|
|
94
|
+
# should raise_exception()
|
|
95
|
+
# should raise_exception(NamedError)
|
|
96
|
+
# should raise_exception(NamedError, String)
|
|
97
|
+
# should raise_exception(NamedError, Regexp)
|
|
98
|
+
# should raise_exception() { |exception| ... }
|
|
99
|
+
# should raise_exception(NamedError) { |exception| ... }
|
|
100
|
+
# should raise_exception(NamedError, String) { |exception| ... }
|
|
101
|
+
# should raise_exception(NamedError, Regexp) { |exception| ... }
|
|
102
|
+
# should_not raise_exception()
|
|
103
|
+
# should_not raise_exception(NamedError)
|
|
104
|
+
# should_not raise_exception(NamedError, String)
|
|
105
|
+
# should_not raise_exception(NamedError, Regexp)
|
|
106
|
+
#
|
|
107
|
+
# With no args, matches if any exception is raised.
|
|
108
|
+
# With a named exception, matches only if that specific exception is raised.
|
|
109
|
+
# With a named exception and messsage specified as a String, matches only if both match.
|
|
110
|
+
# With a named exception and messsage specified as a Regexp, matches only if both match.
|
|
111
|
+
# Pass an optional block to perform extra verifications on the exception matched
|
|
112
|
+
#
|
|
113
|
+
# == Examples
|
|
114
|
+
#
|
|
115
|
+
# lambda { do_something_risky }.should raise_exception
|
|
116
|
+
# lambda { do_something_risky }.should raise_exception(PoorRiskDecisionError)
|
|
117
|
+
# lambda { do_something_risky }.should raise_exception(PoorRiskDecisionError) { |exception| exception.data.should == 42 }
|
|
118
|
+
# lambda { do_something_risky }.should raise_exception(PoorRiskDecisionError, "that was too risky")
|
|
119
|
+
# lambda { do_something_risky }.should raise_exception(PoorRiskDecisionError, /oo ri/)
|
|
120
|
+
#
|
|
121
|
+
# lambda { do_something_risky }.should_not raise_exception
|
|
122
|
+
# lambda { do_something_risky }.should_not raise_exception(PoorRiskDecisionError)
|
|
123
|
+
# lambda { do_something_risky }.should_not raise_exception(PoorRiskDecisionError, "that was too risky")
|
|
124
|
+
# lambda { do_something_risky }.should_not raise_exception(PoorRiskDecisionError, /oo ri/)
|
|
125
|
+
def raise_exception(exception=Exception, message=nil, &block)
|
|
126
|
+
Matchers::RaiseException.new(exception, message, &block)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
alias_method :raise_error, :raise_exception
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -127,7 +127,8 @@ module Spec
|
|
|
127
127
|
# failing), will fail when you want it to pass.
|
|
128
128
|
#
|
|
129
129
|
def simple_matcher(description=nil, &match_block)
|
|
130
|
+
Spec.deprecate("simple_matcher", "Matcher DSL (http://rspec.rubyforge.org/rspec/1.3.0/classes/Spec/Matchers.html)")
|
|
130
131
|
SimpleMatcher.new(description, &match_block)
|
|
131
132
|
end
|
|
132
133
|
end
|
|
133
|
-
end
|
|
134
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module Spec
|
|
2
2
|
module Matchers
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
class ThrowSymbol #:nodoc:
|
|
5
5
|
def initialize(expected_symbol = nil, expected_arg=nil)
|
|
6
6
|
@expected_symbol = expected_symbol
|
|
7
7
|
@expected_arg = expected_arg
|
|
8
8
|
@caught_symbol = @caught_arg = nil
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def matches?(given_proc)
|
|
12
12
|
begin
|
|
13
13
|
if @expected_symbol.nil?
|
|
@@ -27,17 +27,13 @@ module Spec
|
|
|
27
27
|
rescue NameError, ArgumentError => e
|
|
28
28
|
raise e unless e.message =~ /uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/
|
|
29
29
|
@caught_symbol = $2.to_sym
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else
|
|
38
|
-
return (@caught_symbol == @expected_symbol) & (@caught_arg == @expected_arg)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
30
|
+
end
|
|
31
|
+
if @expected_symbol.nil?
|
|
32
|
+
!@caught_symbol.nil?
|
|
33
|
+
elsif @expected_arg.nil?
|
|
34
|
+
@caught_symbol == @expected_symbol
|
|
35
|
+
else
|
|
36
|
+
(@caught_symbol == @expected_symbol) & (@caught_arg == @expected_arg)
|
|
41
37
|
end
|
|
42
38
|
end
|
|
43
39
|
|
|
@@ -48,7 +44,7 @@ module Spec
|
|
|
48
44
|
"expected #{expected} but nothing was thrown"
|
|
49
45
|
end
|
|
50
46
|
end
|
|
51
|
-
|
|
47
|
+
|
|
52
48
|
def failure_message_for_should_not
|
|
53
49
|
if @expected_symbol
|
|
54
50
|
"expected #{expected} not to be thrown"
|
|
@@ -56,23 +52,23 @@ module Spec
|
|
|
56
52
|
"expected no Symbol, got :#{@caught_symbol}"
|
|
57
53
|
end
|
|
58
54
|
end
|
|
59
|
-
|
|
55
|
+
|
|
60
56
|
def description
|
|
61
57
|
"throw #{expected}"
|
|
62
58
|
end
|
|
63
|
-
|
|
59
|
+
|
|
64
60
|
private
|
|
65
|
-
|
|
61
|
+
|
|
66
62
|
def expected
|
|
67
63
|
@expected_symbol.nil? ? "a Symbol" : "#{@expected_symbol.inspect}#{args}"
|
|
68
64
|
end
|
|
69
|
-
|
|
65
|
+
|
|
70
66
|
def args
|
|
71
67
|
@expected_arg.nil? ? "" : " with #{@expected_arg.inspect}"
|
|
72
68
|
end
|
|
73
|
-
|
|
69
|
+
|
|
74
70
|
end
|
|
75
|
-
|
|
71
|
+
|
|
76
72
|
# :call-seq:
|
|
77
73
|
# should throw_symbol()
|
|
78
74
|
# should throw_symbol(:sym)
|
|
@@ -97,8 +93,8 @@ module Spec
|
|
|
97
93
|
# lambda { do_something_risky }.should_not throw_symbol
|
|
98
94
|
# lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
|
|
99
95
|
# lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit)
|
|
100
|
-
def throw_symbol(
|
|
101
|
-
Matchers::ThrowSymbol.new(
|
|
96
|
+
def throw_symbol(expected_symbol = nil, expected_arg=nil)
|
|
97
|
+
Matchers::ThrowSymbol.new(expected_symbol, expected_arg)
|
|
102
98
|
end
|
|
103
99
|
end
|
|
104
100
|
end
|
data/lib/spec/matchers.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'spec/
|
|
1
|
+
require 'spec/extensions/instance_exec'
|
|
2
2
|
require 'spec/matchers/pretty'
|
|
3
3
|
require 'spec/matchers/matcher'
|
|
4
4
|
require 'spec/matchers/operator_matcher'
|
|
@@ -18,7 +18,7 @@ require 'spec/matchers/include'
|
|
|
18
18
|
require 'spec/matchers/match'
|
|
19
19
|
require 'spec/matchers/match_array'
|
|
20
20
|
require 'spec/matchers/method_missing'
|
|
21
|
-
require 'spec/matchers/
|
|
21
|
+
require 'spec/matchers/raise_exception'
|
|
22
22
|
require 'spec/matchers/respond_to'
|
|
23
23
|
require 'spec/matchers/satisfy'
|
|
24
24
|
require 'spec/matchers/simple_matcher'
|
|
@@ -139,6 +139,25 @@ module Spec
|
|
|
139
139
|
# <tt>failure_message_for_should_not</tt>) are passed the actual value (the
|
|
140
140
|
# receiver of <tt>should</tt> or <tt>should_not</tt>).
|
|
141
141
|
#
|
|
142
|
+
# You can also create matchers that obey a fluent interface using the
|
|
143
|
+
# <tt>chain</tt> method:
|
|
144
|
+
#
|
|
145
|
+
# Spec::Matchers.define :tip do |expected_tip|
|
|
146
|
+
# chain :on do |bill|
|
|
147
|
+
# @bill = bill
|
|
148
|
+
# end
|
|
149
|
+
#
|
|
150
|
+
# match do |person|
|
|
151
|
+
# person.tip_for(bill) == expected_tip
|
|
152
|
+
# end
|
|
153
|
+
# end
|
|
154
|
+
#
|
|
155
|
+
# This matcher can be used as follows:
|
|
156
|
+
#
|
|
157
|
+
# describe Customer do
|
|
158
|
+
# it { should tip(10).on(50) }
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
142
161
|
# === Custom Matcher from scratch
|
|
143
162
|
#
|
|
144
163
|
# You could also write a custom matcher from scratch, as follows:
|