jferris-rr 0.7.1.0.1239654108

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 (130) hide show
  1. data/CHANGES +196 -0
  2. data/README.rdoc +329 -0
  3. data/Rakefile +77 -0
  4. data/lib/rr.rb +84 -0
  5. data/lib/rr/adapters/rr_methods.rb +122 -0
  6. data/lib/rr/adapters/rspec.rb +58 -0
  7. data/lib/rr/adapters/test_unit.rb +29 -0
  8. data/lib/rr/double.rb +212 -0
  9. data/lib/rr/double_definitions/child_double_definition_creator.rb +27 -0
  10. data/lib/rr/double_definitions/double_definition.rb +346 -0
  11. data/lib/rr/double_definitions/double_definition_creator.rb +167 -0
  12. data/lib/rr/double_definitions/double_definition_creator_proxy.rb +37 -0
  13. data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
  14. data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
  15. data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
  16. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +17 -0
  17. data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
  18. data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +46 -0
  19. data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
  20. data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
  21. data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
  22. data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
  23. data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
  24. data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
  25. data/lib/rr/double_injection.rb +143 -0
  26. data/lib/rr/double_matches.rb +51 -0
  27. data/lib/rr/errors/argument_equality_error.rb +6 -0
  28. data/lib/rr/errors/double_definition_error.rb +6 -0
  29. data/lib/rr/errors/double_not_found_error.rb +6 -0
  30. data/lib/rr/errors/double_order_error.rb +6 -0
  31. data/lib/rr/errors/rr_error.rb +20 -0
  32. data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
  33. data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
  34. data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
  35. data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
  36. data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
  37. data/lib/rr/errors/times_called_error.rb +6 -0
  38. data/lib/rr/expectations/any_argument_expectation.rb +21 -0
  39. data/lib/rr/expectations/argument_equality_expectation.rb +41 -0
  40. data/lib/rr/expectations/times_called_expectation.rb +57 -0
  41. data/lib/rr/hash_with_object_id_key.rb +41 -0
  42. data/lib/rr/recorded_calls.rb +103 -0
  43. data/lib/rr/space.rb +123 -0
  44. data/lib/rr/spy_verification.rb +48 -0
  45. data/lib/rr/spy_verification_proxy.rb +18 -0
  46. data/lib/rr/times_called_matchers/any_times_matcher.rb +18 -0
  47. data/lib/rr/times_called_matchers/at_least_matcher.rb +15 -0
  48. data/lib/rr/times_called_matchers/at_most_matcher.rb +23 -0
  49. data/lib/rr/times_called_matchers/integer_matcher.rb +19 -0
  50. data/lib/rr/times_called_matchers/non_terminal.rb +27 -0
  51. data/lib/rr/times_called_matchers/proc_matcher.rb +11 -0
  52. data/lib/rr/times_called_matchers/range_matcher.rb +21 -0
  53. data/lib/rr/times_called_matchers/terminal.rb +20 -0
  54. data/lib/rr/times_called_matchers/times_called_matcher.rb +44 -0
  55. data/lib/rr/wildcard_matchers/anything.rb +18 -0
  56. data/lib/rr/wildcard_matchers/boolean.rb +23 -0
  57. data/lib/rr/wildcard_matchers/duck_type.rb +32 -0
  58. data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
  59. data/lib/rr/wildcard_matchers/is_a.rb +25 -0
  60. data/lib/rr/wildcard_matchers/numeric.rb +13 -0
  61. data/lib/rr/wildcard_matchers/range.rb +7 -0
  62. data/lib/rr/wildcard_matchers/regexp.rb +7 -0
  63. data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
  64. data/spec/core_spec_suite.rb +19 -0
  65. data/spec/environment_fixture_setup.rb +6 -0
  66. data/spec/high_level_spec.rb +368 -0
  67. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  68. data/spec/rr/adapters/rr_methods_creator_spec.rb +149 -0
  69. data/spec/rr/adapters/rr_methods_space_spec.rb +115 -0
  70. data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
  71. data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +17 -0
  72. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +112 -0
  73. data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +155 -0
  74. data/spec/rr/double_definitions/double_definition_creator_spec.rb +502 -0
  75. data/spec/rr/double_definitions/double_definition_spec.rb +1159 -0
  76. data/spec/rr/double_injection/double_injection_bind_spec.rb +111 -0
  77. data/spec/rr/double_injection/double_injection_dispatching_spec.rb +244 -0
  78. data/spec/rr/double_injection/double_injection_has_original_method_spec.rb +55 -0
  79. data/spec/rr/double_injection/double_injection_reset_spec.rb +90 -0
  80. data/spec/rr/double_injection/double_injection_spec.rb +77 -0
  81. data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
  82. data/spec/rr/double_spec.rb +352 -0
  83. data/spec/rr/errors/rr_error_spec.rb +67 -0
  84. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  85. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  86. data/spec/rr/expectations/argument_equality_expectation_spec.rb +135 -0
  87. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +34 -0
  88. data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
  89. data/spec/rr/expectations/hash_including_spec.rb +17 -0
  90. data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
  91. data/spec/rr/expectations/satisfy_spec.rb +14 -0
  92. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +46 -0
  93. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +69 -0
  94. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
  95. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +23 -0
  96. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +104 -0
  97. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +81 -0
  98. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +83 -0
  99. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +38 -0
  100. data/spec/rr/rspec/invocation_matcher_spec.rb +279 -0
  101. data/spec/rr/rspec/rspec_adapter_spec.rb +66 -0
  102. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +31 -0
  103. data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +11 -0
  104. data/spec/rr/rspec/rspec_usage_spec.rb +86 -0
  105. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  106. data/spec/rr/space/space_spec.rb +542 -0
  107. data/spec/rr/test_unit/test_helper.rb +7 -0
  108. data/spec/rr/test_unit/test_unit_backtrace_test.rb +35 -0
  109. data/spec/rr/test_unit/test_unit_integration_test.rb +57 -0
  110. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  111. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  112. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  113. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  114. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  115. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  116. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  117. data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
  118. data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
  119. data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
  120. data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
  121. data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
  122. data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
  123. data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
  124. data/spec/rr_spec.rb +28 -0
  125. data/spec/rspec_spec_suite.rb +16 -0
  126. data/spec/spec_helper.rb +107 -0
  127. data/spec/spec_suite.rb +27 -0
  128. data/spec/spy_verification_spec.rb +129 -0
  129. data/spec/test_unit_spec_suite.rb +21 -0
  130. metadata +187 -0
@@ -0,0 +1,88 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ describe HashWithObjectIdKey do
5
+ describe "#[] and #[]=" do
6
+ it "stores object via object id" do
7
+ hash = HashWithObjectIdKey.new
8
+ array_1 = []
9
+ hash[array_1] = 1
10
+ array_2 = []
11
+ hash[array_2] = 2
12
+
13
+ hash[array_1].should_not == hash[array_2]
14
+ end
15
+
16
+ it "stores the passed in object" do
17
+ hash = HashWithObjectIdKey.new
18
+ obj = Object.new
19
+ hash[obj] = 1
20
+ hash.instance_eval {@keys}.should == {obj.__id__ => obj}
21
+ end
22
+ end
23
+
24
+ describe "#each" do
25
+ it "iterates through the items in the hash" do
26
+ hash = HashWithObjectIdKey.new
27
+ hash['one'] = 1
28
+ hash['two'] = 2
29
+
30
+ keys = []
31
+ values = []
32
+ hash.each do |key, value|
33
+ keys << key
34
+ values << value
35
+ end
36
+
37
+ keys.sort.should == ['one', 'two']
38
+ values.sort.should == [1, 2]
39
+ end
40
+ end
41
+
42
+ describe "#delete" do
43
+ before do
44
+ @hash = HashWithObjectIdKey.new
45
+ @key = Object.new
46
+ @hash[@key] = 1
47
+ end
48
+
49
+ it "removes the object from the hash" do
50
+ @hash.delete(@key)
51
+ @hash[@key].should == {}
52
+ end
53
+
54
+ it "removes the object from the keys hash" do
55
+ @hash.delete(@key)
56
+ @hash.instance_eval {@keys}.should == {}
57
+ end
58
+ end
59
+
60
+ describe "#keys" do
61
+ before do
62
+ @hash = HashWithObjectIdKey.new
63
+ @key = Object.new
64
+ @hash[@key] = 1
65
+ end
66
+
67
+ it "returns an array of the keys" do
68
+ @hash.keys.should == [@key]
69
+ end
70
+ end
71
+
72
+ describe "#include?" do
73
+ before do
74
+ @hash = HashWithObjectIdKey.new
75
+ @key = Object.new
76
+ @hash[@key] = 1
77
+ end
78
+
79
+ it "returns true when the key is in the Hash" do
80
+ @hash.include?(@key).should be_true
81
+ end
82
+
83
+ it "returns false when the key is not in the Hash" do
84
+ @hash.include?(Object.new).should be_false
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,542 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ describe Space do
5
+ it_should_behave_like "Swapped Space"
6
+ attr_reader :space, :subject, :method_name, :double_injection
7
+
8
+ before do
9
+ @subject = Object.new
10
+ end
11
+
12
+ describe ".method_missing" do
13
+ it "proxies to a singleton instance of Space" do
14
+ create_double_args = nil
15
+ (class << space; self; end).class_eval do
16
+ define_method :double_injection do |*args|
17
+ create_double_args = args
18
+ end
19
+ end
20
+
21
+ space.double_injection(:foo, :bar)
22
+ create_double_args.should == [:foo, :bar]
23
+ end
24
+ end
25
+
26
+ describe "#record_call" do
27
+ it "should add a call to the list" do
28
+ object = Object.new
29
+ block = lambda {}
30
+ space.record_call(object,:to_s,[], block)
31
+ space.recorded_calls.should == RR::RecordedCalls.new([[object,:to_s,[], block]])
32
+ end
33
+ end
34
+
35
+ describe "#double_injection" do
36
+ context "when existing subject == but not === with the same method name" do
37
+ it "creates a new DoubleInjection" do
38
+ subject_1 = []
39
+ subject_2 = []
40
+ (subject_1 === subject_2).should be_true
41
+ subject_1.__id__.should_not == subject_2.__id__
42
+
43
+ double_1 = space.double_injection(subject_1, :foobar)
44
+ double_2 = space.double_injection(subject_2, :foobar)
45
+
46
+ double_1.should_not == double_2
47
+ end
48
+ end
49
+
50
+ context "when double_injection does not exist" do
51
+ before do
52
+ def subject.foobar(*args)
53
+ :original_foobar
54
+ end
55
+ @method_name = :foobar
56
+ end
57
+
58
+ context "when method_name is a symbol" do
59
+ it "returns double_injection and adds double_injection to double_injection list" do
60
+ @double_injection = space.double_injection(subject, method_name)
61
+ space.double_injection(subject, method_name).should === double_injection
62
+ double_injection.subject.should === subject
63
+ double_injection.method_name.should === method_name
64
+ end
65
+ end
66
+
67
+ context "when method_name is a string" do
68
+ it "returns double_injection and adds double_injection to double_injection list" do
69
+ @double_injection = space.double_injection(subject, 'foobar')
70
+ space.double_injection(subject, method_name).should === double_injection
71
+ double_injection.subject.should === subject
72
+ double_injection.method_name.should === method_name
73
+ end
74
+ end
75
+
76
+ it "overrides the method when passing a block" do
77
+ @double_injection = space.double_injection(subject, method_name)
78
+ subject.methods.should include("__rr__#{method_name}")
79
+ end
80
+ end
81
+
82
+ context "when double_injection exists" do
83
+ before do
84
+ def subject.foobar(*args)
85
+ :original_foobar
86
+ end
87
+ @method_name = :foobar
88
+ end
89
+
90
+ it "returns the existing double_injection" do
91
+ original_foobar_method = subject.method(:foobar)
92
+ @double_injection = space.double_injection(subject, 'foobar')
93
+
94
+ double_injection.object_has_original_method?.should be_true
95
+
96
+ space.double_injection(subject, 'foobar').should === double_injection
97
+
98
+ double_injection.reset
99
+ subject.foobar.should == :original_foobar
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#reset" do
105
+ attr_reader :subject_1, :subject_2
106
+ before do
107
+ @subject_1 = Object.new
108
+ @subject_2 = Object.new
109
+ @method_name = :foobar
110
+ end
111
+
112
+ it "should clear the #recorded_calls" do
113
+ object = Object.new
114
+ space.record_call(object,:to_s,[], nil)
115
+
116
+ space.reset
117
+ space.recorded_calls.should == RR::RecordedCalls.new([])
118
+ end
119
+
120
+ it "removes the ordered doubles" do
121
+ double_1 = new_double(
122
+ space.double_injection(subject_1, :foobar1),
123
+ RR::DoubleDefinitions::DoubleDefinition.new(creator = Object.new, subject_1)
124
+ )
125
+ double_2 = new_double(
126
+ space.double_injection(subject_2, :foobar2),
127
+ RR::DoubleDefinitions::DoubleDefinition.new(creator = Object.new, subject_2)
128
+ )
129
+ double_1.definition.ordered
130
+ double_2.definition.ordered
131
+
132
+ space.ordered_doubles.should_not be_empty
133
+
134
+ space.reset
135
+ space.ordered_doubles.should be_empty
136
+ end
137
+
138
+ it "resets all double_injections" do
139
+ double_1 = space.double_injection(subject_1, method_name)
140
+ double_1_reset_call_count = 0
141
+ (
142
+ class << double_1;
143
+ self;
144
+ end).class_eval do
145
+ define_method(:reset) do ||
146
+ double_1_reset_call_count += 1
147
+ end
148
+ end
149
+ double_2 = space.double_injection(subject_2, method_name)
150
+ double_2_reset_call_count = 0
151
+ (
152
+ class << double_2;
153
+ self;
154
+ end).class_eval do
155
+ define_method(:reset) do ||
156
+ double_2_reset_call_count += 1
157
+ end
158
+ end
159
+
160
+ space.reset
161
+ double_1_reset_call_count.should == 1
162
+ double_2_reset_call_count.should == 1
163
+ end
164
+ end
165
+
166
+ describe "#reset_double" do
167
+ before do
168
+ @method_name = :foobar
169
+ end
170
+
171
+ it "resets the double_injections" do
172
+ @double_injection = space.double_injection(subject, method_name)
173
+ space.double_injections[subject][method_name].should === double_injection
174
+ subject.methods.should include("__rr__#{method_name}")
175
+
176
+ space.reset_double(subject, method_name)
177
+ space.double_injections[subject][method_name].should be_nil
178
+ subject.methods.should_not include("__rr__#{method_name}")
179
+ end
180
+
181
+ context "when it has no double_injections" do
182
+ it "removes the subject from the double_injections map" do
183
+ double_1 = space.double_injection(subject, :foobar1)
184
+ double_2 = space.double_injection(subject, :foobar2)
185
+
186
+ space.double_injections.include?(subject).should == true
187
+ space.double_injections[subject][:foobar1].should_not be_nil
188
+ space.double_injections[subject][:foobar2].should_not be_nil
189
+
190
+ space.reset_double(subject, :foobar1)
191
+ space.double_injections.include?(subject).should == true
192
+ space.double_injections[subject][:foobar1].should be_nil
193
+ space.double_injections[subject][:foobar2].should_not be_nil
194
+
195
+ space.reset_double(subject, :foobar2)
196
+ space.double_injections.include?(subject).should == false
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "#reset_double_injections" do
202
+ attr_reader :subject_1, :subject_2
203
+ before do
204
+ @subject_1 = Object.new
205
+ @subject_2 = Object.new
206
+ @method_name = :foobar
207
+ end
208
+
209
+ it "resets the double_injection and removes it from the double_injections list" do
210
+ double_injection_1 = space.double_injection(subject_1, method_name)
211
+ double_1_reset_call_count = 0
212
+ (class << double_injection_1; self; end).class_eval do
213
+ define_method(:reset) do
214
+ double_1_reset_call_count += 1
215
+ end
216
+ end
217
+ double_injection_2 = space.double_injection(subject_2, method_name)
218
+ double_2_reset_call_count = 0
219
+ (class << double_injection_2; self; end).class_eval do
220
+ define_method(:reset) do
221
+ double_2_reset_call_count += 1
222
+ end
223
+ end
224
+
225
+ space.__send__(:reset_double_injections)
226
+ double_1_reset_call_count.should == 1
227
+ double_2_reset_call_count.should == 1
228
+ end
229
+ end
230
+
231
+ describe "#register_ordered_double" do
232
+ before(:each) do
233
+ @method_name = :foobar
234
+ @double_injection = space.double_injection(subject, method_name)
235
+ end
236
+
237
+ it "adds the ordered double to the ordered_doubles collection" do
238
+ double_1 = new_double
239
+
240
+ space.ordered_doubles.should == []
241
+ space.register_ordered_double double_1
242
+ space.ordered_doubles.should == [double_1]
243
+
244
+ double_2 = new_double
245
+ space.register_ordered_double double_2
246
+ space.ordered_doubles.should == [double_1, double_2]
247
+ end
248
+ end
249
+
250
+ describe "#verify_doubles" do
251
+ attr_reader :subject_1, :subject_2, :subject3, :double_1, :double_2, :double3
252
+ before do
253
+ @subject_1 = Object.new
254
+ @subject_2 = Object.new
255
+ @subject3 = Object.new
256
+ @method_name = :foobar
257
+ @double_1 = space.double_injection(subject_1, method_name)
258
+ @double_2 = space.double_injection(subject_2, method_name)
259
+ @double3 = space.double_injection(subject3, method_name)
260
+ end
261
+
262
+ context "when passed no arguments" do
263
+ it "verifies and deletes the double_injections" do
264
+ double_1_verify_call_count = 0
265
+ double_1_reset_call_count = 0
266
+ (class << double_1; self; end).class_eval do
267
+ define_method(:verify) do
268
+ double_1_verify_call_count += 1
269
+ end
270
+ define_method(:reset) do
271
+ double_1_reset_call_count += 1
272
+ end
273
+ end
274
+
275
+ double_2_verify_call_count = 0
276
+ double_2_reset_call_count = 0
277
+ (class << double_2; self; end).class_eval do
278
+ define_method(:verify) do
279
+ double_2_verify_call_count += 1
280
+ end
281
+ define_method(:reset) do
282
+ double_2_reset_call_count += 1
283
+ end
284
+ end
285
+
286
+ space.verify_doubles
287
+ double_1_verify_call_count.should == 1
288
+ double_2_verify_call_count.should == 1
289
+ double_1_reset_call_count.should == 1
290
+ double_1_reset_call_count.should == 1
291
+ end
292
+ end
293
+
294
+ context "when passed an Object that has at least one DoubleInjection" do
295
+ it "verifies all Doubles injected into the Object" do
296
+ double_1_verify_call_count = 0
297
+ double_1_reset_call_count = 0
298
+ (class << double_1; self; end).class_eval do
299
+ define_method(:verify) do
300
+ double_1_verify_call_count += 1
301
+ end
302
+ define_method(:reset) do
303
+ double_1_reset_call_count += 1
304
+ end
305
+ end
306
+
307
+ double_2_verify_call_count = 0
308
+ double_2_reset_call_count = 0
309
+ (class << double_2; self; end).class_eval do
310
+ define_method(:verify) do
311
+ double_2_verify_call_count += 1
312
+ end
313
+ define_method(:reset) do
314
+ double_2_reset_call_count += 1
315
+ end
316
+ end
317
+
318
+ space.verify_doubles(subject_1)
319
+
320
+ double_1_verify_call_count.should == 1
321
+ double_1_reset_call_count.should == 1
322
+ double_2_verify_call_count.should == 0
323
+ double_2_reset_call_count.should == 0
324
+ end
325
+ end
326
+
327
+ context "when passed multiple Objects with at least one DoubleInjection" do
328
+ it "verifies the Doubles injected into all of the Objects" do
329
+ double_1_verify_call_count = 0
330
+ double_1_reset_call_count = 0
331
+ (class << double_1; self; end).class_eval do
332
+ define_method(:verify) do
333
+ double_1_verify_call_count += 1
334
+ end
335
+ define_method(:reset) do
336
+ double_1_reset_call_count += 1
337
+ end
338
+ end
339
+
340
+ double_2_verify_call_count = 0
341
+ double_2_reset_call_count = 0
342
+ (class << double_2; self; end).class_eval do
343
+ define_method(:verify) do
344
+ double_2_verify_call_count += 1
345
+ end
346
+ define_method(:reset) do
347
+ double_2_reset_call_count += 1
348
+ end
349
+ end
350
+
351
+ double3_verify_call_count = 0
352
+ double3_reset_call_count = 0
353
+ (class << double3; self; end).class_eval do
354
+ define_method(:verify) do
355
+ double3_verify_call_count += 1
356
+ end
357
+ define_method(:reset) do
358
+ double3_reset_call_count += 1
359
+ end
360
+ end
361
+
362
+ space.verify_doubles(subject_1, subject_2)
363
+
364
+ double_1_verify_call_count.should == 1
365
+ double_1_reset_call_count.should == 1
366
+ double_2_verify_call_count.should == 1
367
+ double_2_reset_call_count.should == 1
368
+ double3_verify_call_count.should == 0
369
+ double3_reset_call_count.should == 0
370
+ end
371
+ end
372
+
373
+ context "when passed an subject that does not have a DoubleInjection" do
374
+ it "does not raise an error" do
375
+ double_1_verify_call_count = 0
376
+ double_1_reset_call_count = 0
377
+ (class << double_1; self; end).class_eval do
378
+ define_method(:verify) do
379
+ double_1_verify_call_count += 1
380
+ end
381
+ define_method(:reset) do
382
+ double_1_reset_call_count += 1
383
+ end
384
+ end
385
+
386
+ double_2_verify_call_count = 0
387
+ double_2_reset_call_count = 0
388
+ (class << double_2; self; end).class_eval do
389
+ define_method(:verify) do
390
+ double_2_verify_call_count += 1
391
+ end
392
+ define_method(:reset) do
393
+ double_2_reset_call_count += 1
394
+ end
395
+ end
396
+
397
+ double3_verify_call_count = 0
398
+ double3_reset_call_count = 0
399
+ (class << double3; self; end).class_eval do
400
+ define_method(:verify) do
401
+ double3_verify_call_count += 1
402
+ end
403
+ define_method(:reset) do
404
+ double3_reset_call_count += 1
405
+ end
406
+ end
407
+
408
+ no_double_injection_object = Object.new
409
+ space.verify_doubles(no_double_injection_object)
410
+
411
+ double_1_verify_call_count.should == 0
412
+ double_1_reset_call_count.should == 0
413
+ double_2_verify_call_count.should == 0
414
+ double_2_reset_call_count.should == 0
415
+ double3_verify_call_count.should == 0
416
+ double3_reset_call_count.should == 0
417
+ end
418
+ end
419
+ end
420
+
421
+ describe "#verify_double" do
422
+ before do
423
+ @method_name = :foobar
424
+ end
425
+
426
+ it "verifies and deletes the double_injection" do
427
+ @double_injection = space.double_injection(subject, method_name)
428
+ space.double_injections[subject][method_name].should === double_injection
429
+ subject.methods.should include("__rr__#{method_name}")
430
+
431
+ verify_call_count = 0
432
+ (class << double_injection; self; end).class_eval do
433
+ define_method(:verify) do
434
+ verify_call_count += 1
435
+ end
436
+ end
437
+ space.verify_double(subject, method_name)
438
+ verify_call_count.should == 1
439
+
440
+ space.double_injections[subject][method_name].should be_nil
441
+ subject.methods.should_not include("__rr__#{method_name}")
442
+ end
443
+
444
+ context "when verifying the double_injection raises an error" do
445
+ it "deletes the double_injection" do
446
+ @double_injection = space.double_injection(subject, method_name)
447
+ space.double_injections[subject][method_name].should === double_injection
448
+ subject.methods.should include("__rr__#{method_name}")
449
+
450
+ verify_called = true
451
+ (class << double_injection; self; end).class_eval do
452
+ define_method(:verify) do
453
+ verify_called = true
454
+ raise "An Error"
455
+ end
456
+ end
457
+ lambda {space.verify_double(subject, method_name)}.should raise_error
458
+ verify_called.should be_true
459
+
460
+ space.double_injections[subject][method_name].should be_nil
461
+ subject.methods.should_not include("__rr__#{method_name}")
462
+ end
463
+ end
464
+ end
465
+
466
+ describe "#verify_ordered_double" do
467
+ before do
468
+ @method_name = :foobar
469
+ @double_injection = space.double_injection(subject, method_name)
470
+ end
471
+
472
+ macro "#verify_ordered_double" do
473
+ it "raises an error when Double is NonTerminal" do
474
+ double = new_double
475
+ space.register_ordered_double(double)
476
+
477
+ double.definition.any_number_of_times
478
+ double.should_not be_terminal
479
+
480
+ lambda do
481
+ space.verify_ordered_double(double)
482
+ end.should raise_error(
483
+ Errors::DoubleOrderError,
484
+ "Ordered Doubles cannot have a NonTerminal TimesCalledExpectation"
485
+ )
486
+ end
487
+ end
488
+
489
+ context "when the passed in double is at the front of the queue" do
490
+ send "#verify_ordered_double"
491
+ it "keeps the double when times called is not verified" do
492
+ double = new_double
493
+ space.register_ordered_double(double)
494
+
495
+ double.definition.twice
496
+ double.should be_attempt
497
+
498
+ space.verify_ordered_double(double)
499
+ space.ordered_doubles.should include(double)
500
+ end
501
+
502
+ context "when Double#attempt? is false" do
503
+ it "removes the double" do
504
+ double = new_double
505
+ space.register_ordered_double(double)
506
+
507
+ double.definition.with(1).once
508
+ subject.foobar(1)
509
+ double.should_not be_attempt
510
+
511
+ space.verify_ordered_double(double)
512
+ space.ordered_doubles.should_not include(double)
513
+ end
514
+ end
515
+ end
516
+
517
+ context "when the passed in double is not at the front of the queue" do
518
+ send "#verify_ordered_double"
519
+ it "raises error" do
520
+ first_double = new_double
521
+ second_double = new_double
522
+
523
+ lambda do
524
+ space.verify_ordered_double(second_double)
525
+ end.should raise_error(
526
+ Errors::DoubleOrderError,
527
+ "foobar() called out of order in list\n" <<
528
+ "- foobar()\n" <<
529
+ "- foobar()"
530
+ )
531
+ end
532
+
533
+ def new_double
534
+ double = super
535
+ double.definition.once
536
+ space.register_ordered_double(double)
537
+ double
538
+ end
539
+ end
540
+ end
541
+ end
542
+ end