rspec-expectations 2.0.0.a1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/License.txt +22 -0
- data/README.markdown +8 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/VERSION.yml +5 -0
- data/lib/rspec/expectations.rb +36 -0
- data/lib/rspec/expectations/differs/default.rb +62 -0
- data/lib/rspec/expectations/differs/load-diff-lcs.rb +12 -0
- data/lib/rspec/expectations/errors.rb +12 -0
- data/lib/rspec/expectations/extensions.rb +1 -0
- data/lib/rspec/expectations/extensions/kernel.rb +52 -0
- data/lib/rspec/expectations/fail_with.rb +43 -0
- data/lib/rspec/expectations/handler.rb +50 -0
- data/lib/rspec/matchers.rb +195 -0
- data/lib/rspec/matchers/be.rb +210 -0
- data/lib/rspec/matchers/be_close.rb +32 -0
- data/lib/rspec/matchers/be_instance_of.rb +26 -0
- data/lib/rspec/matchers/be_kind_of.rb +26 -0
- data/lib/rspec/matchers/change.rb +151 -0
- data/lib/rspec/matchers/compatibility.rb +14 -0
- data/lib/rspec/matchers/dsl.rb +14 -0
- data/lib/rspec/matchers/eql.rb +42 -0
- data/lib/rspec/matchers/equal.rb +53 -0
- data/lib/rspec/matchers/errors.rb +5 -0
- data/lib/rspec/matchers/exist.rb +16 -0
- data/lib/rspec/matchers/extensions/instance_exec.rb +23 -0
- data/lib/rspec/matchers/generated_descriptions.rb +36 -0
- data/lib/rspec/matchers/has.rb +35 -0
- data/lib/rspec/matchers/have.rb +151 -0
- data/lib/rspec/matchers/include.rb +44 -0
- data/lib/rspec/matchers/match.rb +21 -0
- data/lib/rspec/matchers/match_array.rb +71 -0
- data/lib/rspec/matchers/matcher.rb +86 -0
- data/lib/rspec/matchers/method_missing.rb +9 -0
- data/lib/rspec/matchers/operator_matcher.rb +78 -0
- data/lib/rspec/matchers/pretty.rb +37 -0
- data/lib/rspec/matchers/raise_error.rb +129 -0
- data/lib/rspec/matchers/respond_to.rb +71 -0
- data/lib/rspec/matchers/satisfy.rb +47 -0
- data/lib/rspec/matchers/simple_matcher.rb +133 -0
- data/lib/rspec/matchers/throw_symbol.rb +104 -0
- data/lib/rspec/matchers/wrap_expectation.rb +55 -0
- data/rspec-expectations.gemspec +104 -0
- data/spec/rspec/expectations/differs/default_spec.rb +128 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +45 -0
- data/spec/rspec/expectations/fail_with_spec.rb +88 -0
- data/spec/rspec/expectations/handler_spec.rb +206 -0
- data/spec/rspec/expectations/wrap_expectation_spec.rb +30 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/suite.rb +1 -0
- data/spec/support/macros.rb +29 -0
- metadata +135 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
# :call-seq:
|
4
|
+
# should match(pattern)
|
5
|
+
# should_not match(pattern)
|
6
|
+
#
|
7
|
+
# Given a Regexp or String, passes if actual.match(pattern)
|
8
|
+
#
|
9
|
+
# == Examples
|
10
|
+
#
|
11
|
+
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
12
|
+
# email.should match("@example.com")
|
13
|
+
def match(expected)
|
14
|
+
Matcher.new :match, expected do |_expected_|
|
15
|
+
match do |actual|
|
16
|
+
actual.match(_expected_)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class MatchArray #:nodoc:
|
5
|
+
include Rspec::Matchers::Pretty
|
6
|
+
|
7
|
+
def initialize(expected)
|
8
|
+
@expected = expected
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
@extra_items = difference_between_arrays(@actual, @expected)
|
14
|
+
@missing_items = difference_between_arrays(@expected, @actual)
|
15
|
+
@extra_items.empty? & @missing_items.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message_for_should
|
19
|
+
message = "expected collection contained: #{safe_sort(@expected).inspect}\n"
|
20
|
+
message += "actual collection contained: #{safe_sort(@actual).inspect}\n"
|
21
|
+
message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty?
|
22
|
+
message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty?
|
23
|
+
message
|
24
|
+
end
|
25
|
+
|
26
|
+
def failure_message_for_should_not
|
27
|
+
"Matcher does not support should_not"
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
"contain exactly #{_pretty_print(@expected)}"
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def safe_sort(array)
|
37
|
+
array.all?{|item| item.respond_to?(:<=>)} ? array.sort : array
|
38
|
+
end
|
39
|
+
|
40
|
+
def difference_between_arrays(array_1, array_2)
|
41
|
+
difference = array_1.dup
|
42
|
+
array_2.each do |element|
|
43
|
+
if index = difference.index(element)
|
44
|
+
difference.delete_at(index)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
difference
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# :call-seq:
|
54
|
+
# should =~ expected
|
55
|
+
#
|
56
|
+
# Passes if actual contains all of the expected regardless of order.
|
57
|
+
# This works for collections. Pass in multiple args and it will only
|
58
|
+
# pass if all args are found in collection.
|
59
|
+
#
|
60
|
+
# NOTE: there is no should_not version of array.should =~ other_array
|
61
|
+
#
|
62
|
+
# == Examples
|
63
|
+
#
|
64
|
+
# [1,2,3].should =~ [1,2,3] # => would pass
|
65
|
+
# [1,2,3].should =~ [2,3,1] # => would pass
|
66
|
+
# [1,2,3,4].should =~ [1,2,3] # => would fail
|
67
|
+
# [1,2,2,3].should =~ [1,2,3] # => would fail
|
68
|
+
# [1,2,3].should =~ [1,2,3,4] # => would fail
|
69
|
+
OperatorMatcher.register(Array, '=~', Rspec::Matchers::MatchArray)
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
class Matcher
|
4
|
+
include Rspec::Matchers::Pretty
|
5
|
+
|
6
|
+
attr_reader :expected, :actual
|
7
|
+
|
8
|
+
def initialize(name, *expected, &declarations)
|
9
|
+
@name = name
|
10
|
+
@expected = expected
|
11
|
+
@actual = nil
|
12
|
+
@diffable = false
|
13
|
+
@messages = {
|
14
|
+
:description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
|
15
|
+
:failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"},
|
16
|
+
:failure_message_for_should_not => lambda {|actual| "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"}
|
17
|
+
}
|
18
|
+
making_declared_methods_public do
|
19
|
+
instance_exec(*@expected, &declarations)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def matches?(actual)
|
24
|
+
@actual = actual
|
25
|
+
instance_exec(@actual, &@match_block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def description(&block)
|
29
|
+
cache_or_call_cached(:description, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def failure_message_for_should(&block)
|
33
|
+
cache_or_call_cached(:failure_message_for_should, @actual, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def failure_message_for_should_not(&block)
|
37
|
+
cache_or_call_cached(:failure_message_for_should_not, @actual, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def match(&block)
|
41
|
+
@match_block = block
|
42
|
+
end
|
43
|
+
|
44
|
+
def diffable?
|
45
|
+
@diffable
|
46
|
+
end
|
47
|
+
|
48
|
+
def diffable
|
49
|
+
@diffable = true
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def making_declared_methods_public # :nodoc:
|
55
|
+
# Our home-grown instance_exec in ruby 1.8.6 results in any methods
|
56
|
+
# declared in the block eval'd by instance_exec in the block to which we
|
57
|
+
# are yielding here are scoped private. This is NOT the case for Ruby
|
58
|
+
# 1.8.7 or 1.9.
|
59
|
+
#
|
60
|
+
# Also, due some crazy scoping that I don't understand, these methods
|
61
|
+
# are actually available in the specs (something about the matcher being
|
62
|
+
# defined in the scope of Rspec::Matchers or within an example), so not
|
63
|
+
# doing the following will not cause specs to fail, but they *will*
|
64
|
+
# cause features to fail and that will make users unhappy. So don't.
|
65
|
+
orig_private_methods = private_methods
|
66
|
+
yield
|
67
|
+
st = (class << self; self; end)
|
68
|
+
(private_methods - orig_private_methods).each {|m| st.__send__ :public, m}
|
69
|
+
end
|
70
|
+
|
71
|
+
def cache_or_call_cached(key, actual=nil, &block)
|
72
|
+
block ? @messages[key] = block :
|
73
|
+
actual.nil? ? @messages[key].call : @messages[key].call(actual)
|
74
|
+
end
|
75
|
+
|
76
|
+
def name_to_sentence
|
77
|
+
split_words(@name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def expected_to_sentence
|
81
|
+
to_sentence(@expected)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class OperatorMatcher
|
5
|
+
class << self
|
6
|
+
def registry
|
7
|
+
@registry ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(klass, operator, matcher)
|
11
|
+
registry[klass] ||= {}
|
12
|
+
registry[klass][operator] = matcher
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(klass, operator)
|
16
|
+
registry[klass] && registry[klass][operator]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(actual)
|
21
|
+
@actual = actual
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.use_custom_matcher_or_delegate(operator)
|
25
|
+
define_method(operator) do |expected|
|
26
|
+
if matcher = OperatorMatcher.get(@actual.class, operator)
|
27
|
+
@actual.send(::Rspec::Matchers.last_should, matcher.new(expected))
|
28
|
+
else
|
29
|
+
eval_match(@actual, operator, expected)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
|
35
|
+
use_custom_matcher_or_delegate operator
|
36
|
+
end
|
37
|
+
|
38
|
+
def fail_with_message(message)
|
39
|
+
Rspec::Expectations.fail_with(message, @expected, @actual)
|
40
|
+
end
|
41
|
+
|
42
|
+
def description
|
43
|
+
"#{@operator} #{@expected.inspect}"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def eval_match(actual, operator, expected)
|
49
|
+
::Rspec::Matchers.last_matcher = self
|
50
|
+
@operator, @expected = operator, expected
|
51
|
+
__delegate_operator(actual, operator, expected)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class PositiveOperatorMatcher < OperatorMatcher #:nodoc:
|
57
|
+
def __delegate_operator(actual, operator, expected)
|
58
|
+
if actual.__send__(operator, expected)
|
59
|
+
true
|
60
|
+
elsif ['==','===', '=~'].include?(operator)
|
61
|
+
fail_with_message("expected: #{expected.inspect},\n got: #{actual.inspect} (using #{operator})")
|
62
|
+
else
|
63
|
+
fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
class NegativeOperatorMatcher < OperatorMatcher #:nodoc:
|
70
|
+
def __delegate_operator(actual, operator, expected)
|
71
|
+
return false unless actual.__send__(operator, expected)
|
72
|
+
return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
module Pretty
|
4
|
+
def split_words(sym)
|
5
|
+
sym.to_s.gsub(/_/,' ')
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_sentence(words)
|
9
|
+
words = words.map{|w| w.inspect}
|
10
|
+
case words.length
|
11
|
+
when 0
|
12
|
+
""
|
13
|
+
when 1
|
14
|
+
" #{words[0]}"
|
15
|
+
when 2
|
16
|
+
" #{words[0]} and #{words[1]}"
|
17
|
+
else
|
18
|
+
" #{words[0...-1].join(', ')}, and #{words[-1]}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def _pretty_print(array)
|
23
|
+
result = ""
|
24
|
+
array.each_with_index do |item, index|
|
25
|
+
if index < (array.length - 2)
|
26
|
+
result << "#{item.inspect}, "
|
27
|
+
elsif index < (array.length - 1)
|
28
|
+
result << "#{item.inspect} and "
|
29
|
+
else
|
30
|
+
result << "#{item.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
class RaiseError #:nodoc:
|
4
|
+
def initialize(expected_error_or_message=Exception, expected_message=nil, &block)
|
5
|
+
@block = block
|
6
|
+
@actual_error = nil
|
7
|
+
case expected_error_or_message
|
8
|
+
when String, Regexp
|
9
|
+
@expected_error, @expected_message = Exception, expected_error_or_message
|
10
|
+
else
|
11
|
+
@expected_error, @expected_message = expected_error_or_message, expected_message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(given_proc)
|
16
|
+
@raised_expected_error = false
|
17
|
+
@with_expected_message = false
|
18
|
+
@eval_block = false
|
19
|
+
@eval_block_passed = false
|
20
|
+
begin
|
21
|
+
given_proc.call
|
22
|
+
rescue @expected_error => @actual_error
|
23
|
+
@raised_expected_error = true
|
24
|
+
@with_expected_message = verify_message
|
25
|
+
rescue Exception => @actual_error
|
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_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
|
29
|
+
end
|
30
|
+
|
31
|
+
unless negative_expectation?
|
32
|
+
eval_block if @raised_expected_error && @with_expected_message && @block
|
33
|
+
end
|
34
|
+
ensure
|
35
|
+
return (@raised_expected_error & @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_error]
|
42
|
+
@eval_block_passed = true
|
43
|
+
rescue Exception => err
|
44
|
+
@actual_error = 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_error.message
|
54
|
+
else
|
55
|
+
@expected_message == @actual_error.message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def failure_message_for_should
|
60
|
+
@eval_block ? @actual_error.message : "expected #{expected_error}#{given_error}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def failure_message_for_should_not
|
64
|
+
"expected no #{expected_error}#{given_error}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def description
|
68
|
+
"raise #{expected_error}"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def expected_error
|
73
|
+
case @expected_message
|
74
|
+
when nil
|
75
|
+
@expected_error
|
76
|
+
when Regexp
|
77
|
+
"#{@expected_error} with message matching #{@expected_message.inspect}"
|
78
|
+
else
|
79
|
+
"#{@expected_error} with #{@expected_message.inspect}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def given_error
|
84
|
+
@actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.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_error()
|
95
|
+
# should raise_error(NamedError)
|
96
|
+
# should raise_error(NamedError, String)
|
97
|
+
# should raise_error(NamedError, Regexp)
|
98
|
+
# should raise_error() { |error| ... }
|
99
|
+
# should raise_error(NamedError) { |error| ... }
|
100
|
+
# should raise_error(NamedError, String) { |error| ... }
|
101
|
+
# should raise_error(NamedError, Regexp) { |error| ... }
|
102
|
+
# should_not raise_error()
|
103
|
+
# should_not raise_error(NamedError)
|
104
|
+
# should_not raise_error(NamedError, String)
|
105
|
+
# should_not raise_error(NamedError, Regexp)
|
106
|
+
#
|
107
|
+
# With no args, matches if any error is raised.
|
108
|
+
# With a named error, matches only if that specific error is raised.
|
109
|
+
# With a named error and messsage specified as a String, matches only if both match.
|
110
|
+
# With a named error 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_error
|
116
|
+
# lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
|
117
|
+
# lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) { |error| error.data.should == 42 }
|
118
|
+
# lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky")
|
119
|
+
# lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/)
|
120
|
+
#
|
121
|
+
# lambda { do_something_risky }.should_not raise_error
|
122
|
+
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
|
123
|
+
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
|
124
|
+
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
|
125
|
+
def raise_error(error=Exception, message=nil, &block)
|
126
|
+
Matchers::RaiseError.new(error, message, &block)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class RespondTo #:nodoc:
|
5
|
+
def initialize(*names)
|
6
|
+
@names = names
|
7
|
+
@expected_arity = nil
|
8
|
+
@names_not_responded_to = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
@names.each do |name|
|
14
|
+
@names_not_responded_to << name unless actual.respond_to?(name) && matches_arity?(actual, name)
|
15
|
+
end
|
16
|
+
return @names_not_responded_to.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def failure_message_for_should
|
20
|
+
"expected #{@actual.inspect} to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}#{with_arity}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message_for_should_not
|
24
|
+
"expected #{@actual.inspect} not to respond to #{@names.collect {|name| name.inspect }.join(', ')}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def description
|
28
|
+
"respond to #{pp_names}#{with_arity}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def with(n)
|
32
|
+
@expected_arity = n
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def argument
|
37
|
+
self
|
38
|
+
end
|
39
|
+
alias :arguments :argument
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def matches_arity?(actual, name)
|
44
|
+
@expected_arity.nil?? true : @expected_arity == actual.method(name).arity
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_arity
|
48
|
+
@expected_arity.nil?? "" :
|
49
|
+
" with #{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def pp_names
|
53
|
+
# Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here
|
54
|
+
@names.length == 1 ? "##{@names.first}" : @names.inspect
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# :call-seq:
|
59
|
+
# should respond_to(*names)
|
60
|
+
# should_not respond_to(*names)
|
61
|
+
#
|
62
|
+
# Matches if the target object responds to all of the names
|
63
|
+
# provided. Names can be Strings or Symbols.
|
64
|
+
#
|
65
|
+
# == Examples
|
66
|
+
#
|
67
|
+
def respond_to(*names)
|
68
|
+
Matchers::RespondTo.new(*names)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|