redinger-rr 0.10.3

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.
Files changed (133) hide show
  1. data/CHANGES +221 -0
  2. data/README.rdoc +343 -0
  3. data/Rakefile +88 -0
  4. data/VERSION.yml +4 -0
  5. data/lib/rr.rb +88 -0
  6. data/lib/rr/adapters/rr_methods.rb +122 -0
  7. data/lib/rr/adapters/rspec.rb +59 -0
  8. data/lib/rr/adapters/test_unit.rb +29 -0
  9. data/lib/rr/double.rb +152 -0
  10. data/lib/rr/double_definitions/child_double_definition_creator.rb +27 -0
  11. data/lib/rr/double_definitions/double_definition.rb +348 -0
  12. data/lib/rr/double_definitions/double_definition_creator.rb +167 -0
  13. data/lib/rr/double_definitions/double_definition_creator_proxy.rb +37 -0
  14. data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
  15. data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
  16. data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
  17. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +17 -0
  18. data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
  19. data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +50 -0
  20. data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
  21. data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
  22. data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
  23. data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
  24. data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
  25. data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
  26. data/lib/rr/double_injection.rb +180 -0
  27. data/lib/rr/double_matches.rb +51 -0
  28. data/lib/rr/errors/argument_equality_error.rb +6 -0
  29. data/lib/rr/errors/double_definition_error.rb +6 -0
  30. data/lib/rr/errors/double_not_found_error.rb +6 -0
  31. data/lib/rr/errors/double_order_error.rb +6 -0
  32. data/lib/rr/errors/rr_error.rb +20 -0
  33. data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
  34. data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
  35. data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
  36. data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
  37. data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
  38. data/lib/rr/errors/times_called_error.rb +6 -0
  39. data/lib/rr/expectations/any_argument_expectation.rb +21 -0
  40. data/lib/rr/expectations/argument_equality_expectation.rb +41 -0
  41. data/lib/rr/expectations/times_called_expectation.rb +57 -0
  42. data/lib/rr/hash_with_object_id_key.rb +44 -0
  43. data/lib/rr/method_dispatches/base_method_dispatch.rb +108 -0
  44. data/lib/rr/method_dispatches/method_dispatch.rb +61 -0
  45. data/lib/rr/method_dispatches/method_missing_dispatch.rb +49 -0
  46. data/lib/rr/proc_from_block.rb +7 -0
  47. data/lib/rr/recorded_calls.rb +103 -0
  48. data/lib/rr/space.rb +123 -0
  49. data/lib/rr/spy_verification.rb +48 -0
  50. data/lib/rr/spy_verification_proxy.rb +18 -0
  51. data/lib/rr/times_called_matchers/any_times_matcher.rb +18 -0
  52. data/lib/rr/times_called_matchers/at_least_matcher.rb +15 -0
  53. data/lib/rr/times_called_matchers/at_most_matcher.rb +23 -0
  54. data/lib/rr/times_called_matchers/integer_matcher.rb +19 -0
  55. data/lib/rr/times_called_matchers/non_terminal.rb +27 -0
  56. data/lib/rr/times_called_matchers/proc_matcher.rb +11 -0
  57. data/lib/rr/times_called_matchers/range_matcher.rb +21 -0
  58. data/lib/rr/times_called_matchers/terminal.rb +20 -0
  59. data/lib/rr/times_called_matchers/times_called_matcher.rb +44 -0
  60. data/lib/rr/wildcard_matchers.rb +158 -0
  61. data/lib/rr/wildcard_matchers/anything.rb +18 -0
  62. data/lib/rr/wildcard_matchers/boolean.rb +23 -0
  63. data/lib/rr/wildcard_matchers/duck_type.rb +32 -0
  64. data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
  65. data/lib/rr/wildcard_matchers/is_a.rb +25 -0
  66. data/lib/rr/wildcard_matchers/numeric.rb +13 -0
  67. data/lib/rr/wildcard_matchers/range.rb +7 -0
  68. data/lib/rr/wildcard_matchers/regexp.rb +7 -0
  69. data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
  70. data/spec/core_spec_suite.rb +19 -0
  71. data/spec/environment_fixture_setup.rb +7 -0
  72. data/spec/high_level_spec.rb +398 -0
  73. data/spec/proc_from_block_spec.rb +14 -0
  74. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  75. data/spec/rr/adapters/rr_methods_creator_spec.rb +149 -0
  76. data/spec/rr/adapters/rr_methods_space_spec.rb +115 -0
  77. data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
  78. data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +17 -0
  79. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +112 -0
  80. data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +155 -0
  81. data/spec/rr/double_definitions/double_definition_creator_spec.rb +502 -0
  82. data/spec/rr/double_definitions/double_definition_spec.rb +1165 -0
  83. data/spec/rr/double_injection/double_injection_spec.rb +339 -0
  84. data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
  85. data/spec/rr/double_spec.rb +352 -0
  86. data/spec/rr/errors/rr_error_spec.rb +67 -0
  87. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  88. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  89. data/spec/rr/expectations/argument_equality_expectation_spec.rb +135 -0
  90. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +34 -0
  91. data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
  92. data/spec/rr/expectations/hash_including_spec.rb +17 -0
  93. data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
  94. data/spec/rr/expectations/satisfy_spec.rb +14 -0
  95. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +46 -0
  96. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +69 -0
  97. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
  98. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +23 -0
  99. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +104 -0
  100. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +81 -0
  101. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +83 -0
  102. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +38 -0
  103. data/spec/rr/rspec/invocation_matcher_spec.rb +279 -0
  104. data/spec/rr/rspec/rspec_adapter_spec.rb +66 -0
  105. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +31 -0
  106. data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +11 -0
  107. data/spec/rr/rspec/rspec_usage_spec.rb +86 -0
  108. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  109. data/spec/rr/space/space_spec.rb +550 -0
  110. data/spec/rr/test_unit/test_helper.rb +7 -0
  111. data/spec/rr/test_unit/test_unit_backtrace_test.rb +36 -0
  112. data/spec/rr/test_unit/test_unit_integration_test.rb +57 -0
  113. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  114. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  115. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  116. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  117. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  118. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  119. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  120. data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
  121. data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
  122. data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
  123. data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
  124. data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
  125. data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
  126. data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
  127. data/spec/rr_spec.rb +28 -0
  128. data/spec/rspec_spec_suite.rb +17 -0
  129. data/spec/spec_helper.rb +109 -0
  130. data/spec/spec_suite.rb +31 -0
  131. data/spec/spy_verification_spec.rb +129 -0
  132. data/spec/test_unit_spec_suite.rb +21 -0
  133. metadata +193 -0
@@ -0,0 +1,155 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module DoubleDefinitions
5
+ describe DoubleDefinitionCreatorProxy do
6
+ attr_reader :subject, :creator, :the_proxy
7
+ it_should_behave_like "Swapped Space"
8
+
9
+ before(:each) do
10
+ @subject = Object.new
11
+ @creator = DoubleDefinitionCreator.new
12
+ creator.mock(subject)
13
+ end
14
+
15
+ macro("initializes proxy with passed in creator") do
16
+ it "initializes proxy with passed in creator" do
17
+ class << the_proxy
18
+ attr_reader :creator
19
+ end
20
+ the_proxy.creator.should === creator
21
+ end
22
+ end
23
+
24
+ describe ".new" do
25
+ it "does not undefine object_id" do
26
+ the_proxy = DoubleDefinitionCreatorProxy.new(creator)
27
+ the_proxy.object_id.class.should == Fixnum
28
+ end
29
+
30
+ context "without block" do
31
+ before do
32
+ @the_proxy = DoubleDefinitionCreatorProxy.new(creator)
33
+ end
34
+
35
+ send "initializes proxy with passed in creator"
36
+
37
+ it "clears out all methods from proxy" do
38
+ proxy_subclass = Class.new(DoubleDefinitionCreatorProxy) do
39
+ def i_should_be_a_double
40
+ end
41
+ end
42
+ proxy_subclass.instance_methods.map {|m| m.to_s}.should include('i_should_be_a_double')
43
+
44
+ proxy = proxy_subclass.new(creator)
45
+ proxy.i_should_be_a_double.should be_instance_of(DoubleDefinition)
46
+ end
47
+ end
48
+
49
+ context "when passed a block" do
50
+ macro("calls the block to define the Doubles") do
51
+ send "initializes proxy with passed in creator"
52
+
53
+ it "creates double_injections" do
54
+ subject.foobar(1, 2).should == :one_two
55
+ subject.foobar(1).should == :one
56
+ subject.foobar(:something).should == :default
57
+ subject.baz.should == :baz_result
58
+ end
59
+
60
+ it "clears out all methods from proxy" do
61
+ proxy_subclass = Class.new(DoubleDefinitionCreatorProxy) do
62
+ def i_should_be_a_double
63
+ end
64
+ end
65
+ proxy_subclass.instance_methods.map {|m| m.to_s}.should include('i_should_be_a_double')
66
+
67
+ proxy_subclass.new(creator) do |m|
68
+ m.i_should_be_a_double.should be_instance_of(DoubleDefinition)
69
+ end
70
+ end
71
+ end
72
+
73
+ context "when the block has an arity of 1" do
74
+ attr_reader :passed_in_argument
75
+ before do
76
+ passed_in_argument = nil
77
+ block = lambda do |b|
78
+ passed_in_argument = b
79
+ b.foobar(1, 2) {:one_two}
80
+ b.foobar(1) {:one}
81
+ b.foobar.with_any_args {:default}
82
+ b.baz() {:baz_result}
83
+ end
84
+ block.arity.should == 1
85
+
86
+ @the_proxy = DoubleDefinitionCreatorProxy.new(creator, &block)
87
+ @passed_in_argument = passed_in_argument
88
+ end
89
+
90
+ send("calls the block to define the Doubles")
91
+
92
+ it "passes the self into the block" do
93
+ passed_in_argument.__creator__.should == creator
94
+ end
95
+ end
96
+
97
+ context "when the block has an arity of -1" do
98
+ attr_reader :self_value, :passed_in_arguments
99
+ before do
100
+ self_value = nil
101
+ passed_in_arguments = nil
102
+ block = lambda do |*args|
103
+ self_value = self
104
+ passed_in_arguments = args
105
+ args[0].foobar(1, 2) {:one_two}
106
+ args[0].foobar(1) {:one}
107
+ args[0].foobar.with_any_args {:default}
108
+ args[0].baz() {:baz_result}
109
+ end
110
+ block.arity.should == -1
111
+
112
+ @the_proxy = DoubleDefinitionCreatorProxy.new(creator, &block)
113
+ @self_value = self_value
114
+ @passed_in_arguments = passed_in_arguments
115
+ end
116
+
117
+ send("calls the block to define the Doubles")
118
+
119
+ it "passes the self into the block" do
120
+ passed_in_arguments.map {|a| a.__creator__}.should == [creator]
121
+ end
122
+
123
+ it "evaluates the block with the context of self" do
124
+ self_value.__creator__.should == creator
125
+ end
126
+ end
127
+
128
+ context "when the block has an arity of 0" do
129
+ attr_reader :self_value
130
+ before do
131
+ self_value = nil
132
+ block = lambda do ||
133
+ self_value = self
134
+ foobar(1, 2) {:one_two}
135
+ foobar(1) {:one}
136
+ foobar.with_any_args {:default}
137
+ baz() {:baz_result}
138
+ end
139
+ block.arity.should == 0
140
+
141
+ @the_proxy = DoubleDefinitionCreatorProxy.new(creator, &block)
142
+ @self_value = self_value
143
+ end
144
+
145
+ send("calls the block to define the Doubles")
146
+
147
+ it "evaluates the block with the context of self" do
148
+ self_value.__creator__.should == creator
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,502 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module DoubleDefinitions
5
+ describe DoubleDefinitionCreator do
6
+ attr_reader :creator, :subject, :strategy_method_name
7
+ it_should_behave_like "Swapped Space"
8
+ before(:each) do
9
+ @subject = Object.new
10
+ @creator = DoubleDefinitionCreator.new
11
+ end
12
+
13
+ describe "#root_subject" do
14
+ it "returns #subject" do
15
+ creator.stub(subject).foobar
16
+ creator.root_subject.should == subject
17
+ end
18
+ end
19
+
20
+ describe "StrategySetupMethods" do
21
+ describe "normal strategy definitions" do
22
+ def call_strategy(*args, &block)
23
+ creator.__send__(strategy_method_name, *args, &block)
24
+ end
25
+
26
+ describe "#mock" do
27
+ before do
28
+ @strategy_method_name = :mock
29
+ end
30
+
31
+ send("normal strategy definition")
32
+
33
+ context "when passing no args" do
34
+ it "returns self" do
35
+ call_strategy.should === creator
36
+ end
37
+ end
38
+
39
+ context "when passed a subject and a method_name argument" do
40
+ it "creates a mock Double for method" do
41
+ double_definition = creator.mock(subject, :foobar).returns {:baz}
42
+ double_definition.times_matcher.should == TimesCalledMatchers::IntegerMatcher.new(1)
43
+ double_definition.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
44
+ double_definition.argument_expectation.expected_arguments.should == []
45
+ subject.foobar.should == :baz
46
+ end
47
+ end
48
+
49
+ context "when already using an ImplementationStrategy" do
50
+ it "raises a DoubleDefinitionError" do
51
+ creator.mock
52
+ lambda do
53
+ call_strategy
54
+ end.should raise_error(RR::Errors::DoubleDefinitionError, "This Double already has a mock strategy")
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "#stub" do
60
+ before do
61
+ @strategy_method_name = :stub
62
+ end
63
+
64
+ send("normal strategy definition")
65
+
66
+ context "when passing no args" do
67
+ it "returns self" do
68
+ call_strategy.should === creator
69
+ end
70
+ end
71
+
72
+ context "when passed subject and a method_name argument" do
73
+ it "creates a stub Double for method when passed a method_name argument" do
74
+ double_definition = creator.stub(subject, :foobar).returns {:baz}
75
+ double_definition.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
76
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
77
+ subject.foobar.should == :baz
78
+ end
79
+ end
80
+
81
+ context "when already using an ImplementationStrategy" do
82
+ it "raises a DoubleDefinitionError" do
83
+ creator.mock
84
+ lambda do
85
+ call_strategy
86
+ end.should raise_error(RR::Errors::DoubleDefinitionError, "This Double already has a mock strategy")
87
+ end
88
+ end
89
+ end
90
+
91
+ describe "#dont_allow" do
92
+ before do
93
+ @strategy_method_name = :dont_allow
94
+ end
95
+
96
+ send("normal strategy definition")
97
+
98
+ context "when passing no args" do
99
+ it "returns self" do
100
+ call_strategy.should === creator
101
+ end
102
+ end
103
+
104
+ it "raises error when proxied" do
105
+ creator.proxy
106
+ lambda do
107
+ creator.dont_allow
108
+ end.should raise_error(Errors::DoubleDefinitionError, "Doubles cannot be proxied when using dont_allow strategy")
109
+ end
110
+
111
+ context "when passed a subject and a method_name argument_expectation" do
112
+ it "creates a mock Double for method" do
113
+ double_definition = creator.dont_allow(subject, :foobar)
114
+ double_definition.times_matcher.should == TimesCalledMatchers::IntegerMatcher.new(0)
115
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
116
+
117
+ lambda do
118
+ subject.foobar
119
+ end.should raise_error(Errors::TimesCalledError)
120
+ RR.reset
121
+ end
122
+ end
123
+
124
+ context "when already using an ImplementationStrategy" do
125
+ it "raises a DoubleDefinitionError" do
126
+ creator.mock
127
+ lambda do
128
+ call_strategy
129
+ end.should raise_error(RR::Errors::DoubleDefinitionError, "This Double already has a mock strategy")
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "! strategy definitions" do
136
+ attr_reader :strategy_method_name
137
+ def call_strategy(*args, &definition_eval_block)
138
+ creator.__send__(strategy_method_name, *args, &definition_eval_block)
139
+ end
140
+
141
+ describe "#mock!" do
142
+ before do
143
+ @strategy_method_name = :mock!
144
+ end
145
+
146
+ send("! strategy definition")
147
+
148
+ context "when passed a method_name argument" do
149
+ it "sets #verification_strategy to Mock" do
150
+ creator.mock!(:foobar)
151
+ creator.verification_strategy.class.should == Strategies::Verification::Mock
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "#stub!" do
157
+ before do
158
+ @strategy_method_name = :stub!
159
+ end
160
+
161
+ send("! strategy definition")
162
+
163
+ context "when passed a method_name argument" do
164
+ it "sets #verification_strategy to Stub" do
165
+ creator.stub!(:foobar)
166
+ creator.verification_strategy.class.should == Strategies::Verification::Stub
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "#dont_allow!" do
172
+ before do
173
+ @strategy_method_name = :dont_allow!
174
+ end
175
+
176
+ send("! strategy definition")
177
+
178
+ context "when passed a method_name argument" do
179
+ it "sets #verification_strategy to DontAllow" do
180
+ creator.dont_allow!(:foobar)
181
+ creator.verification_strategy.class.should == Strategies::Verification::DontAllow
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ describe "#stub.proxy" do
188
+ before do
189
+ class << subject
190
+ def foobar(*args)
191
+ :original_foobar
192
+ end
193
+ end
194
+ end
195
+
196
+ context "when already using Strategies::Verification::DontAllow" do
197
+ it "raises error" do
198
+ creator.dont_allow
199
+ lambda do
200
+ creator.proxy
201
+ end.should raise_error(Errors::DoubleDefinitionError, "Doubles cannot be proxied when using dont_allow strategy")
202
+ end
203
+ end
204
+
205
+ context "when passed a method_name argument" do
206
+ it "creates a proxy Double for method" do
207
+ double_definition = creator.stub.proxy(subject, :foobar).after_call {:baz}
208
+ double_definition.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
209
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
210
+ subject.foobar.should == :baz
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "#instance_of" do
216
+ context "when not passed a class" do
217
+ it "raises an ArgumentError" do
218
+ lambda do
219
+ creator.instance_of(Object.new)
220
+ end.should raise_error(ArgumentError, "instance_of only accepts class objects")
221
+ end
222
+ end
223
+
224
+ context "when passed a method_name argument" do
225
+ it "creates a proxy Double for method" do
226
+ klass = Class.new
227
+ double_definition = creator.stub.instance_of(klass, :foobar).returns {:baz}
228
+ double_definition.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
229
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
230
+ klass.new.foobar.should == :baz
231
+ end
232
+ end
233
+ end
234
+
235
+ describe "#instance_of.mock" do
236
+ before do
237
+ @klass = Class.new
238
+ end
239
+
240
+ context "when passed no arguments" do
241
+ it "returns a DoubleDefinitionCreator" do
242
+ instance_of.instance_of.should be_instance_of(DoubleDefinitionCreator)
243
+ end
244
+ end
245
+
246
+ context "when passed a method_name argument" do
247
+ it "creates a instance_of Double for method" do
248
+ double_definition = instance_of.mock(@klass, :foobar)
249
+ double_definition.with(1, 2) {:baz}
250
+ double_definition.times_matcher.should == TimesCalledMatchers::IntegerMatcher.new(1)
251
+ double_definition.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
252
+ double_definition.argument_expectation.expected_arguments.should == [1, 2]
253
+
254
+ @klass.new.foobar(1, 2).should == :baz
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ describe "StrategyExecutionMethods" do
261
+ describe "#create" do
262
+ context "when #verification_strategy is not set" do
263
+ it "raises a DoubleDefinitionError" do
264
+ lambda do
265
+ creator.create(:foobar, 1, 2)
266
+ end.should raise_error(Errors::DoubleDefinitionError, "This Double has no strategy")
267
+ end
268
+ end
269
+
270
+ context "when #verification_strategy is a Mock" do
271
+ context "when #implementation_strategy is a Reimplementation" do
272
+ before do
273
+ creator.mock(subject)
274
+ end
275
+
276
+ it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do
277
+ creator.create(:foobar, 1, 2)
278
+ subject.foobar(1, 2)
279
+ lambda {subject.foobar(1, 2)}.should raise_error(Errors::TimesCalledError)
280
+ end
281
+
282
+ describe "#subject.method_name being called" do
283
+ it "returns the return value of the Double#returns block" do
284
+ creator.create(:foobar, 1, 2) {:baz}
285
+ subject.foobar(1, 2).should == :baz
286
+ end
287
+ end
288
+ end
289
+
290
+ context "when #implementation_strategy is a Proxy" do
291
+ before do
292
+ creator.mock
293
+ creator.proxy(subject)
294
+ end
295
+
296
+ it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do
297
+ def subject.foobar(*args)
298
+ :baz;
299
+ end
300
+ creator.create(:foobar, 1, 2)
301
+ subject.foobar(1, 2)
302
+ lambda {subject.foobar(1, 2)}.should raise_error(Errors::TimesCalledError)
303
+ end
304
+
305
+ describe "#subject.method_name being called" do
306
+ it "calls the original method" do
307
+ original_method_called = false
308
+ (class << subject; self; end).class_eval do
309
+ define_method(:foobar) do |*args|
310
+ original_method_called = true
311
+ end
312
+ end
313
+ creator.create(:foobar, 1, 2)
314
+ subject.foobar(1, 2)
315
+ original_method_called.should be_true
316
+ end
317
+
318
+ context "when not passed a block" do
319
+ it "returns the value of the original method" do
320
+ def subject.foobar(*args)
321
+ :baz;
322
+ end
323
+ creator.create(:foobar, 1, 2)
324
+ subject.foobar(1, 2).should == :baz
325
+ end
326
+ end
327
+
328
+ context "when passed a block" do
329
+ attr_reader :real_value
330
+ before do
331
+ @real_value = real_value = Object.new
332
+ (class << subject; self; end).class_eval do
333
+ define_method(:foobar) {real_value}
334
+ end
335
+ end
336
+
337
+ it "calls the block with the return value of the original method" do
338
+ creator.create(:foobar, 1, 2) do |value|
339
+ mock(value).a_method {99}
340
+ value
341
+ end
342
+ subject.foobar(1, 2)
343
+ real_value.a_method.should == 99
344
+ end
345
+
346
+ it "returns the return value of the block" do
347
+ creator.create(:foobar, 1, 2) do |value|
348
+ :something_else
349
+ end
350
+ subject.foobar(1, 2).should == :something_else
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end
356
+
357
+ context "when #verification_strategy is a Stub" do
358
+ context "when #implementation_strategy is a Reimplementation" do
359
+ before do
360
+ creator.stub(subject)
361
+ end
362
+
363
+ context "when not passed a block" do
364
+ it "returns nil" do
365
+ creator.create(:foobar)
366
+ subject.foobar.should be_nil
367
+ end
368
+ end
369
+
370
+ context "when passed a block" do
371
+ describe "#subject.method_name being called" do
372
+ it "returns the return value of the block" do
373
+ creator.create(:foobar) {:baz}
374
+ subject.foobar.should == :baz
375
+ end
376
+ end
377
+ end
378
+
379
+ context "when not passed args" do
380
+ describe "#subject.method_name being called with any arguments" do
381
+ it "invokes the implementation of the Stub" do
382
+ creator.create(:foobar) {:baz}
383
+ subject.foobar(1, 2).should == :baz
384
+ subject.foobar().should == :baz
385
+ subject.foobar([]).should == :baz
386
+ end
387
+ end
388
+ end
389
+
390
+ context "when passed args" do
391
+ describe "#subject.method_name being called with the passed-in arguments" do
392
+ it "invokes the implementation of the Stub" do
393
+ creator.create(:foobar, 1, 2) {:baz}
394
+ subject.foobar(1, 2).should == :baz
395
+ end
396
+ end
397
+
398
+ describe "#subject.method_name being called with different arguments" do
399
+ it "raises a DoubleNotFoundError" do
400
+ creator.create(:foobar, 1, 2) {:baz}
401
+ lambda do
402
+ subject.foobar
403
+ end.should raise_error(Errors::DoubleNotFoundError)
404
+ end
405
+ end
406
+ end
407
+ end
408
+
409
+ context "when #implementation_strategy is a Proxy" do
410
+ before do
411
+ def subject.foobar(*args)
412
+ :original_return_value
413
+ end
414
+ creator.stub
415
+ creator.proxy(subject)
416
+ end
417
+
418
+ context "when not passed a block" do
419
+ describe "#subject.method_name being called" do
420
+ it "invokes the original implementanion" do
421
+ creator.create(:foobar)
422
+ subject.foobar.should == :original_return_value
423
+ end
424
+ end
425
+ end
426
+
427
+ context "when passed a block" do
428
+ describe "#subject.method_name being called" do
429
+ it "invokes the original implementanion and invokes the block with the return value of the original implementanion" do
430
+ passed_in_value = nil
431
+ creator.create(:foobar) do |original_return_value|
432
+ passed_in_value = original_return_value
433
+ end
434
+ subject.foobar
435
+ passed_in_value.should == :original_return_value
436
+ end
437
+
438
+ it "returns the return value of the block" do
439
+ creator.create(:foobar) do |original_return_value|
440
+ :new_return_value
441
+ end
442
+ subject.foobar.should == :new_return_value
443
+ end
444
+ end
445
+ end
446
+
447
+ context "when passed args" do
448
+ describe "#subject.method_name being called with the passed-in arguments" do
449
+ it "invokes the implementation of the Stub" do
450
+ creator.create(:foobar, 1, 2) {:baz}
451
+ subject.foobar(1, 2).should == :baz
452
+ end
453
+ end
454
+
455
+ describe "#subject.method_name being called with different arguments" do
456
+ it "raises a DoubleNotFoundError" do
457
+ creator.create(:foobar, 1, 2) {:baz}
458
+ lambda do
459
+ subject.foobar
460
+ end.should raise_error(Errors::DoubleNotFoundError)
461
+ end
462
+ end
463
+ end
464
+ end
465
+ end
466
+
467
+ context "when #verification_strategy is a DontAllow" do
468
+ before do
469
+ creator.dont_allow(subject)
470
+ end
471
+
472
+ context "when not passed args" do
473
+ describe "#subject.method_name being called with any arguments" do
474
+ it "raises a TimesCalledError" do
475
+ creator.create(:foobar)
476
+ lambda {subject.foobar}.should raise_error(Errors::TimesCalledError)
477
+ lambda {subject.foobar(1, 2)}.should raise_error(Errors::TimesCalledError)
478
+ end
479
+ end
480
+ end
481
+
482
+ context "when passed args" do
483
+ describe "#subject.method_name being called with the passed-in arguments" do
484
+ it "raises a TimesCalledError" do
485
+ creator.create(:foobar, 1, 2)
486
+ lambda {subject.foobar(1, 2)}.should raise_error(Errors::TimesCalledError)
487
+ end
488
+ end
489
+
490
+ describe "#subject.method_name being called with different arguments" do
491
+ it "raises a DoubleNotFoundError" do
492
+ creator.create(:foobar, 1, 2)
493
+ lambda {subject.foobar()}.should raise_error(Errors::DoubleNotFoundError)
494
+ end
495
+ end
496
+ end
497
+ end
498
+ end
499
+ end
500
+ end
501
+ end
502
+ end