rr 0.10.2 → 0.10.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +3 -0
- data/README.rdoc +1 -0
- data/Rakefile +5 -1
- data/VERSION.yml +1 -1
- data/lib/rr.rb +8 -1
- data/lib/rr/double.rb +18 -78
- data/lib/rr/double_definitions/double_definition_creator_proxy.rb +1 -1
- data/lib/rr/hash_with_object_id_key.rb +1 -3
- data/lib/rr/injections/double_injection.rb +119 -0
- data/lib/rr/injections/injection.rb +22 -0
- data/lib/rr/injections/method_missing_injection.rb +62 -0
- data/lib/rr/injections/singleton_method_added_injection.rb +58 -0
- data/lib/rr/method_dispatches/base_method_dispatch.rb +84 -0
- data/lib/rr/method_dispatches/method_dispatch.rb +58 -0
- data/lib/rr/method_dispatches/method_missing_dispatch.rb +59 -0
- data/lib/rr/space.rb +44 -4
- data/lib/rr/spy_verification_proxy.rb +1 -1
- data/spec/rr/double_injection/double_injection_spec.rb +523 -66
- data/spec/rr/double_injection/double_injection_verify_spec.rb +3 -3
- data/spec/rr/double_spec.rb +18 -18
- data/spec/rr/space/hash_with_object_id_key_spec.rb +1 -1
- data/spec/rr/space/space_spec.rb +250 -64
- data/spec/spec_helper.rb +5 -0
- metadata +9 -7
- data/lib/rr/double_injection.rb +0 -136
- data/spec/rr/double_injection/double_injection_bind_spec.rb +0 -99
- data/spec/rr/double_injection/double_injection_dispatching_spec.rb +0 -244
- data/spec/rr/double_injection/double_injection_has_original_method_spec.rb +0 -58
- data/spec/rr/double_injection/double_injection_reset_spec.rb +0 -72
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,7 @@ require "#{dir}/environment_fixture_setup"
|
|
3
3
|
require "#{dir}/rr/expectations/times_called_expectation/times_called_expectation_helper"
|
4
4
|
require "#{dir}/rr/adapters/rr_methods_spec_helper"
|
5
5
|
ARGV.push("--format", "nested") unless ARGV.include?("--format")
|
6
|
+
ARGV.push("-b")
|
6
7
|
|
7
8
|
Spec::Runner.configure do |config|
|
8
9
|
config.mock_with RR::Adapters::Rspec
|
@@ -105,4 +106,8 @@ class Spec::ExampleGroup
|
|
105
106
|
double_definition
|
106
107
|
)
|
107
108
|
end
|
109
|
+
|
110
|
+
def eigen(object)
|
111
|
+
class << object; self; end
|
112
|
+
end
|
108
113
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Takita
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-26 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -48,7 +48,6 @@ files:
|
|
48
48
|
- lib/rr/double_definitions/strategies/verification/mock.rb
|
49
49
|
- lib/rr/double_definitions/strategies/verification/stub.rb
|
50
50
|
- lib/rr/double_definitions/strategies/verification/verification_strategy.rb
|
51
|
-
- lib/rr/double_injection.rb
|
52
51
|
- lib/rr/double_matches.rb
|
53
52
|
- lib/rr/errors/argument_equality_error.rb
|
54
53
|
- lib/rr/errors/double_definition_error.rb
|
@@ -65,6 +64,13 @@ files:
|
|
65
64
|
- lib/rr/expectations/argument_equality_expectation.rb
|
66
65
|
- lib/rr/expectations/times_called_expectation.rb
|
67
66
|
- lib/rr/hash_with_object_id_key.rb
|
67
|
+
- lib/rr/injections/double_injection.rb
|
68
|
+
- lib/rr/injections/injection.rb
|
69
|
+
- lib/rr/injections/method_missing_injection.rb
|
70
|
+
- lib/rr/injections/singleton_method_added_injection.rb
|
71
|
+
- lib/rr/method_dispatches/base_method_dispatch.rb
|
72
|
+
- lib/rr/method_dispatches/method_dispatch.rb
|
73
|
+
- lib/rr/method_dispatches/method_missing_dispatch.rb
|
68
74
|
- lib/rr/proc_from_block.rb
|
69
75
|
- lib/rr/recorded_calls.rb
|
70
76
|
- lib/rr/space.rb
|
@@ -102,10 +108,6 @@ files:
|
|
102
108
|
- spec/rr/double_definitions/double_definition_creator_proxy_spec.rb
|
103
109
|
- spec/rr/double_definitions/double_definition_creator_spec.rb
|
104
110
|
- spec/rr/double_definitions/double_definition_spec.rb
|
105
|
-
- spec/rr/double_injection/double_injection_bind_spec.rb
|
106
|
-
- spec/rr/double_injection/double_injection_dispatching_spec.rb
|
107
|
-
- spec/rr/double_injection/double_injection_has_original_method_spec.rb
|
108
|
-
- spec/rr/double_injection/double_injection_reset_spec.rb
|
109
111
|
- spec/rr/double_injection/double_injection_spec.rb
|
110
112
|
- spec/rr/double_injection/double_injection_verify_spec.rb
|
111
113
|
- spec/rr/double_spec.rb
|
data/lib/rr/double_injection.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
module RR
|
2
|
-
# RR::DoubleInjection is the binding of an subject and a method.
|
3
|
-
# A double_injection has 0 to many Double objects. Each Double
|
4
|
-
# has Argument Expectations and Times called Expectations.
|
5
|
-
class DoubleInjection
|
6
|
-
include Space::Reader
|
7
|
-
|
8
|
-
LAZY_METHOD_DEFINITIONS = [
|
9
|
-
(lambda do |subject|
|
10
|
-
subject.respond_to?(:descends_from_active_record?) && subject.descends_from_active_record?
|
11
|
-
end)
|
12
|
-
]
|
13
|
-
|
14
|
-
MethodArguments = Struct.new(:arguments, :block)
|
15
|
-
attr_reader :subject, :method_name, :doubles, :subject_class
|
16
|
-
|
17
|
-
def initialize(subject, method_name, subject_class)
|
18
|
-
@subject = subject
|
19
|
-
@subject_class = subject_class
|
20
|
-
@method_name = method_name.to_sym
|
21
|
-
if subject_respond_to_method?(method_name)
|
22
|
-
if LAZY_METHOD_DEFINITIONS.any? {|definition| definition.call(subject)} && !subject.methods.include?(method_name)
|
23
|
-
subject.send(method_name)
|
24
|
-
end
|
25
|
-
subject_class.__send__(:alias_method, original_method_alias_name, method_name)
|
26
|
-
end
|
27
|
-
@doubles = []
|
28
|
-
end
|
29
|
-
|
30
|
-
# RR::DoubleInjection#register_double adds the passed in Double
|
31
|
-
# into this DoubleInjection's list of Double objects.
|
32
|
-
def register_double(double)
|
33
|
-
@doubles << double
|
34
|
-
end
|
35
|
-
|
36
|
-
# RR::DoubleInjection#bind injects a method that acts as a dispatcher
|
37
|
-
# that dispatches to the matching Double when the method
|
38
|
-
# is called.
|
39
|
-
def bind
|
40
|
-
returns_method = <<-METHOD
|
41
|
-
def #{@method_name}(*args, &block)
|
42
|
-
arguments = MethodArguments.new(args, block)
|
43
|
-
RR::Space.double_injection(self, :#{@method_name}).call_method(arguments.arguments, arguments.block)
|
44
|
-
end
|
45
|
-
METHOD
|
46
|
-
subject_class.class_eval(returns_method, __FILE__, __LINE__ - 5)
|
47
|
-
self
|
48
|
-
end
|
49
|
-
|
50
|
-
# RR::DoubleInjection#verify verifies each Double
|
51
|
-
# TimesCalledExpectation are met.
|
52
|
-
def verify
|
53
|
-
@doubles.each do |double|
|
54
|
-
double.verify
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# RR::DoubleInjection#reset removes the injected dispatcher method.
|
59
|
-
# It binds the original method implementation on the subject
|
60
|
-
# if one exists.
|
61
|
-
def reset
|
62
|
-
if object_has_original_method?
|
63
|
-
subject_class.__send__(:alias_method, @method_name, original_method_alias_name)
|
64
|
-
subject_class.__send__(:remove_method, original_method_alias_name)
|
65
|
-
else
|
66
|
-
subject_class.__send__(:remove_method, @method_name)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def call_original_method(*args, &block)
|
71
|
-
@subject.__send__(original_method_alias_name, *args, &block)
|
72
|
-
end
|
73
|
-
|
74
|
-
def object_has_original_method?
|
75
|
-
subject_respond_to_method?(original_method_alias_name)
|
76
|
-
end
|
77
|
-
|
78
|
-
def call_method(args, block)
|
79
|
-
space.record_call(subject, method_name, args, block)
|
80
|
-
if double = find_double_to_attempt(args)
|
81
|
-
double.call(self, *args, &block)
|
82
|
-
else
|
83
|
-
double_not_found_error(*args)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
protected
|
88
|
-
def find_double_to_attempt(args)
|
89
|
-
matches = DoubleMatches.new(@doubles).find_all_matches(args)
|
90
|
-
|
91
|
-
unless matches.exact_terminal_doubles_to_attempt.empty?
|
92
|
-
return matches.exact_terminal_doubles_to_attempt.first
|
93
|
-
end
|
94
|
-
|
95
|
-
unless matches.exact_non_terminal_doubles_to_attempt.empty?
|
96
|
-
return matches.exact_non_terminal_doubles_to_attempt.last
|
97
|
-
end
|
98
|
-
|
99
|
-
unless matches.wildcard_terminal_doubles_to_attempt.empty?
|
100
|
-
return matches.wildcard_terminal_doubles_to_attempt.first
|
101
|
-
end
|
102
|
-
|
103
|
-
unless matches.wildcard_non_terminal_doubles_to_attempt.empty?
|
104
|
-
return matches.wildcard_non_terminal_doubles_to_attempt.last
|
105
|
-
end
|
106
|
-
|
107
|
-
unless matches.matching_doubles.empty?
|
108
|
-
return matches.matching_doubles.first # This will raise a TimesCalledError
|
109
|
-
end
|
110
|
-
|
111
|
-
return nil
|
112
|
-
end
|
113
|
-
|
114
|
-
def double_not_found_error(*args)
|
115
|
-
message =
|
116
|
-
"On subject #{subject},\n" <<
|
117
|
-
"unexpected method invocation:\n" <<
|
118
|
-
" #{Double.formatted_name(@method_name, args)}\n" <<
|
119
|
-
"expected invocations:\n" <<
|
120
|
-
Double.list_message_part(@doubles)
|
121
|
-
raise Errors::DoubleNotFoundError, message
|
122
|
-
end
|
123
|
-
|
124
|
-
def original_method_alias_name
|
125
|
-
"__rr__original_#{@method_name}"
|
126
|
-
end
|
127
|
-
|
128
|
-
def subject_respond_to_method?(method_name)
|
129
|
-
subject_has_method_defined?(method_name) || @subject.respond_to?(method_name)
|
130
|
-
end
|
131
|
-
|
132
|
-
def subject_has_method_defined?(method_name)
|
133
|
-
@subject.methods.include?(method_name.to_s) || @subject.protected_methods.include?(method_name.to_s) || @subject.private_methods.include?(method_name.to_s)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
|
2
|
-
|
3
|
-
module RR
|
4
|
-
module DoubleDefinitions
|
5
|
-
describe DoubleInjection do
|
6
|
-
attr_reader :subject, :method_name, :double_injection, :original_method
|
7
|
-
describe "#bind" do
|
8
|
-
context "with an existing method" do
|
9
|
-
before do
|
10
|
-
@subject = Object.new
|
11
|
-
@method_name = :foobar
|
12
|
-
def subject.foobar;
|
13
|
-
:original_foobar;
|
14
|
-
end
|
15
|
-
@original_method = @subject.method(method_name)
|
16
|
-
@subject.methods.should include(method_name.to_s)
|
17
|
-
|
18
|
-
subject.method(:foobar).should == original_method
|
19
|
-
end
|
20
|
-
|
21
|
-
context "when the existing method is public" do
|
22
|
-
before do
|
23
|
-
stub(subject, method_name).returns {:new_foobar}
|
24
|
-
end
|
25
|
-
|
26
|
-
it "returns the value of the Double Injection" do
|
27
|
-
subject.foobar.should == :new_foobar
|
28
|
-
end
|
29
|
-
|
30
|
-
it "overrides the original method with the double_injection's dispatching methods" do
|
31
|
-
subject.method(:foobar).should_not == original_method
|
32
|
-
end
|
33
|
-
|
34
|
-
it "stores original method in __rr__original_method_alias_name" do
|
35
|
-
subject.respond_to?(:__rr__original_foobar).should == true
|
36
|
-
subject.method(:__rr__original_foobar).should == original_method
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context "when the existing method is private" do
|
41
|
-
before do
|
42
|
-
class << subject
|
43
|
-
private :foobar
|
44
|
-
end
|
45
|
-
@double_injection = RR::Space.double_injection(subject, method_name)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "overrides the original method with the double_injection's dispatching methods" do
|
49
|
-
double_injection.bind
|
50
|
-
subject.method(:foobar).should_not == original_method
|
51
|
-
end
|
52
|
-
|
53
|
-
it "stores original method in __rr__original_method_alias_name" do
|
54
|
-
subject.private_methods.should include('__rr__original_foobar')
|
55
|
-
subject.method(:__rr__original_foobar).should == original_method
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context "without an existing method" do
|
61
|
-
before do
|
62
|
-
@subject = Object.new
|
63
|
-
@method_name = :foobar
|
64
|
-
subject.methods.should_not include(method_name.to_s)
|
65
|
-
RR::Space.double_injection(subject, method_name)
|
66
|
-
end
|
67
|
-
|
68
|
-
it "creates a new method with the double_injection's dispatching methods" do
|
69
|
-
subject.method(method_name).should_not be_nil
|
70
|
-
end
|
71
|
-
|
72
|
-
it "does not create method __rr__original_method_alias_name" do
|
73
|
-
subject.respond_to?(:__rr__original_foobar).should == false
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context "with #==" do
|
78
|
-
before do
|
79
|
-
@subject = Object.new
|
80
|
-
@method_name = :'=='
|
81
|
-
subject.should respond_to(method_name)
|
82
|
-
@original_method = subject.method(method_name)
|
83
|
-
subject.methods.should include(method_name.to_s)
|
84
|
-
@double_injection = RR::Space.double_injection(subject, method_name)
|
85
|
-
end
|
86
|
-
|
87
|
-
it "overrides the original method with the double_injection's dispatching methods" do
|
88
|
-
subject.method(method_name).should_not == original_method
|
89
|
-
end
|
90
|
-
|
91
|
-
it "stores original method in __rr__original_method_alias_name" do
|
92
|
-
subject.respond_to?(:"__rr__original_#{method_name}").should == true
|
93
|
-
subject.method(:"__rr__original_#{method_name}").should == original_method
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,244 +0,0 @@
|
|
1
|
-
require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
|
2
|
-
|
3
|
-
module RR
|
4
|
-
describe DoubleInjection do
|
5
|
-
attr_reader :space, :subject, :double_injection
|
6
|
-
it_should_behave_like "Swapped Space"
|
7
|
-
before do
|
8
|
-
@subject = Object.new
|
9
|
-
subject.methods.should_not include(method_name.to_s)
|
10
|
-
@double_injection = space.double_injection(subject, method_name)
|
11
|
-
end
|
12
|
-
|
13
|
-
def new_double
|
14
|
-
Double.new(
|
15
|
-
double_injection,
|
16
|
-
DoubleDefinitions::DoubleDefinition.new(
|
17
|
-
DoubleDefinitions::DoubleDefinitionCreator.new,
|
18
|
-
subject
|
19
|
-
).any_number_of_times
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "methods whose name do not contain ! or ?" do
|
24
|
-
def method_name
|
25
|
-
:foobar
|
26
|
-
end
|
27
|
-
|
28
|
-
context "when the original method uses the passed-in block" do
|
29
|
-
it "executes the passed-in block" do
|
30
|
-
method_fixture = Object.new
|
31
|
-
class << method_fixture
|
32
|
-
def method_with_block(a, b)
|
33
|
-
yield(a, b)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
double = new_double
|
37
|
-
double.definition.with(1, 2).implemented_by(method_fixture.method(:method_with_block))
|
38
|
-
subject.foobar(1, 2) {|a, b| [b, a]}.should == [2, 1]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "when no other Double with duplicate ArgumentExpectations exists" do
|
43
|
-
it "dispatches to Double that have an exact match" do
|
44
|
-
double1_with_exact_match = new_double
|
45
|
-
double1_with_exact_match.definition.with(:exact_match_1).returns {:return_1}
|
46
|
-
double_with_no_match = new_double
|
47
|
-
double_with_no_match.definition.with("nothing that matches").returns {:no_match}
|
48
|
-
double2_with_exact_match = new_double
|
49
|
-
double2_with_exact_match.definition.with(:exact_match_2).returns {:return_2}
|
50
|
-
|
51
|
-
subject.foobar(:exact_match_1).should == :return_1
|
52
|
-
subject.foobar(:exact_match_2).should == :return_2
|
53
|
-
end
|
54
|
-
|
55
|
-
it "dispatches to Double that have a wildcard match" do
|
56
|
-
double_with_wildcard_match = new_double
|
57
|
-
double_with_wildcard_match.definition.with_any_args.returns {:wild_card_value}
|
58
|
-
double_with_no_match = new_double
|
59
|
-
double_with_no_match.definition.with("nothing that matches").returns {:no_match}
|
60
|
-
|
61
|
-
subject.foobar(:wildcard_match_1).should == :wild_card_value
|
62
|
-
subject.foobar(:wildcard_match_2, 3).should == :wild_card_value
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "when other Doubles exists but none of them match the passed-in arguments" do
|
67
|
-
it "raises DoubleNotFoundError error when arguments do not match a double" do
|
68
|
-
double_1 = new_double
|
69
|
-
double_1.definition.with(1, 2)
|
70
|
-
|
71
|
-
double_2 = new_double
|
72
|
-
double_2.definition.with(3)
|
73
|
-
|
74
|
-
error = nil
|
75
|
-
begin
|
76
|
-
subject.foobar(:arg1, :arg2)
|
77
|
-
viotated "Error should have been raised"
|
78
|
-
rescue Errors::DoubleNotFoundError => e
|
79
|
-
error = e
|
80
|
-
end
|
81
|
-
error.message.should include("On subject #<Object")
|
82
|
-
expected_double_message_part = "unexpected method invocation:\n" <<
|
83
|
-
" foobar(:arg1, :arg2)\n"
|
84
|
-
"expected invocations:\n"
|
85
|
-
"- foobar(1, 2)\n" <<
|
86
|
-
"- foobar(3)"
|
87
|
-
error.message.should include(expected_double_message_part)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "when at least one Double with NonTerminal TimesCalledMatchers exits" do
|
92
|
-
it "dispatches to Double with exact match" do
|
93
|
-
double = new_double(1, 2) {:return_value}
|
94
|
-
subject.foobar(1, 2).should == :return_value
|
95
|
-
end
|
96
|
-
|
97
|
-
it "matches to the last Double that was registered with an exact match" do
|
98
|
-
double_1 = new_double(1, 2) {:value_1}
|
99
|
-
double_2 = new_double(1, 2) {:value_2}
|
100
|
-
|
101
|
-
subject.foobar(1, 2).should == :value_2
|
102
|
-
end
|
103
|
-
|
104
|
-
it "dispatches to Double with wildcard match" do
|
105
|
-
new_double(anything) {:return_value}
|
106
|
-
subject.foobar(:dont_care).should == :return_value
|
107
|
-
end
|
108
|
-
|
109
|
-
it "matches to the last Double that was registered with a wildcard match" do
|
110
|
-
new_double(anything) {:value_1}
|
111
|
-
new_double(anything) {:value_2}
|
112
|
-
|
113
|
-
subject.foobar(:dont_care).should == :value_2
|
114
|
-
end
|
115
|
-
|
116
|
-
it "matches to Double with exact match Double even when a Double with wildcard match was registered later" do
|
117
|
-
new_double(1, 2) {:exact_first}
|
118
|
-
new_double(anything, anything) {:wildcard_last}
|
119
|
-
|
120
|
-
subject.foobar(1, 2).should == :exact_first
|
121
|
-
end
|
122
|
-
|
123
|
-
def new_double(*arguments, &return_value)
|
124
|
-
double = super()
|
125
|
-
double.definition.with(*arguments).any_number_of_times.returns(&return_value)
|
126
|
-
double.should_not be_terminal
|
127
|
-
double
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context "when two or more Terminal Doubles with duplicate Exact Match ArgumentExpectations exists" do
|
132
|
-
it "dispatches to Double that have an exact match" do
|
133
|
-
new_double(:exact_match) {:return_1}
|
134
|
-
|
135
|
-
subject.foobar(:exact_match).should == :return_1
|
136
|
-
end
|
137
|
-
|
138
|
-
it "dispatches to the first Double that have an exact match" do
|
139
|
-
new_double(:exact_match) {:return_1}
|
140
|
-
new_double(:exact_match) {:return_2}
|
141
|
-
|
142
|
-
subject.foobar(:exact_match).should == :return_1
|
143
|
-
end
|
144
|
-
|
145
|
-
it "dispatches the second Double with an exact match
|
146
|
-
when the first double's Times Called expectation is satisfied" do
|
147
|
-
new_double(:exact_match) {:return_1}
|
148
|
-
new_double(:exact_match) {:return_2}
|
149
|
-
|
150
|
-
subject.foobar(:exact_match)
|
151
|
-
subject.foobar(:exact_match).should == :return_2
|
152
|
-
end
|
153
|
-
|
154
|
-
it "raises TimesCalledError when all of the doubles Times Called expectation is satisfied" do
|
155
|
-
new_double(:exact_match) {:return_1}
|
156
|
-
new_double(:exact_match) {:return_2}
|
157
|
-
|
158
|
-
subject.foobar(:exact_match)
|
159
|
-
subject.foobar(:exact_match)
|
160
|
-
lambda do
|
161
|
-
subject.foobar(:exact_match)
|
162
|
-
end.should raise_error(Errors::TimesCalledError)
|
163
|
-
end
|
164
|
-
|
165
|
-
def new_double(*arguments, &return_value)
|
166
|
-
double = super()
|
167
|
-
double.definition.with(*arguments).once.returns(&return_value)
|
168
|
-
double.should be_terminal
|
169
|
-
double
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context "when two or more Doubles with duplicate Wildcard Match ArgumentExpectations exists" do
|
174
|
-
it "dispatches to Double that have a wildcard match" do
|
175
|
-
new_double {:return_1}
|
176
|
-
|
177
|
-
subject.foobar(:anything).should == :return_1
|
178
|
-
end
|
179
|
-
|
180
|
-
it "dispatches to the first Double that has a wildcard match" do
|
181
|
-
new_double {:return_1}
|
182
|
-
new_double {:return_2}
|
183
|
-
|
184
|
-
subject.foobar(:anything).should == :return_1
|
185
|
-
end
|
186
|
-
|
187
|
-
it "dispatches the second Double with a wildcard match
|
188
|
-
when the first double's Times Called expectation is satisfied" do
|
189
|
-
new_double {:return_1}
|
190
|
-
new_double {:return_2}
|
191
|
-
|
192
|
-
subject.foobar(:anything)
|
193
|
-
subject.foobar(:anything).should == :return_2
|
194
|
-
end
|
195
|
-
|
196
|
-
it "raises TimesCalledError when all of the doubles Times Called expectation is satisfied" do
|
197
|
-
new_double {:return_1}
|
198
|
-
new_double {:return_2}
|
199
|
-
|
200
|
-
subject.foobar(:anything)
|
201
|
-
subject.foobar(:anything)
|
202
|
-
lambda do
|
203
|
-
subject.foobar(:anything)
|
204
|
-
end.should raise_error(Errors::TimesCalledError)
|
205
|
-
end
|
206
|
-
|
207
|
-
def new_double(&return_value)
|
208
|
-
double = super
|
209
|
-
double.definition.with_any_args.once.returns(&return_value)
|
210
|
-
double.should be_terminal
|
211
|
-
double
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe "method names with !" do
|
217
|
-
def method_name
|
218
|
-
:foobar!
|
219
|
-
end
|
220
|
-
|
221
|
-
context "when the original method uses the passed-in block" do
|
222
|
-
it "executes the block" do
|
223
|
-
double = new_double
|
224
|
-
double.definition.with(1, 2) {:return_value}
|
225
|
-
subject.foobar!(1, 2).should == :return_value
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
describe "method names with ?" do
|
231
|
-
def method_name
|
232
|
-
:foobar?
|
233
|
-
end
|
234
|
-
|
235
|
-
context "when the original method uses the passed-in block" do
|
236
|
-
it "executes the block" do
|
237
|
-
double = new_double
|
238
|
-
double.definition.with(1, 2) {:return_value}
|
239
|
-
subject.foobar?(1, 2).should == :return_value
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|