rr 0.4.8 → 0.4.9

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 (52) hide show
  1. data/CHANGES +3 -0
  2. data/{README → README.rdoc} +14 -6
  3. data/Rakefile +2 -2
  4. data/lib/rr.rb +11 -3
  5. data/lib/rr/adapters/rr_methods.rb +12 -12
  6. data/lib/rr/adapters/rspec.rb +3 -3
  7. data/lib/rr/adapters/test_unit.rb +3 -3
  8. data/lib/rr/double.rb +12 -10
  9. data/lib/rr/double_creator.rb +48 -45
  10. data/lib/rr/double_definition.rb +17 -149
  11. data/lib/rr/double_definition_builder.rb +11 -11
  12. data/lib/rr/double_definition_creator.rb +156 -0
  13. data/lib/rr/{double_method_proxy.rb → double_definition_creator_proxy.rb} +2 -2
  14. data/lib/rr/double_injection.rb +6 -6
  15. data/lib/rr/double_matches.rb +40 -40
  16. data/lib/rr/errors/rr_error.rb +1 -1
  17. data/lib/rr/expectations/times_called_expectation.rb +1 -1
  18. data/lib/rr/space.rb +9 -30
  19. data/spec/high_level_spec.rb +140 -143
  20. data/spec/rr/adapters/rr_methods_creator_spec.rb +21 -21
  21. data/spec/rr/adapters/rr_methods_space_spec.rb +2 -2
  22. data/spec/rr/double/double_injection_dispatching_spec.rb +15 -15
  23. data/spec/rr/double/double_injection_reset_spec.rb +1 -1
  24. data/spec/rr/double/double_injection_verify_spec.rb +5 -4
  25. data/spec/rr/{double_method_proxy_spec.rb → double_definition_creator_proxy_spec.rb} +12 -10
  26. data/spec/rr/{double_creator_spec.rb → double_definition_creator_spec.rb} +166 -124
  27. data/spec/rr/double_definition_spec.rb +637 -642
  28. data/spec/rr/double_spec.rb +44 -43
  29. data/spec/rr/errors/rr_error_spec.rb +6 -6
  30. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +3 -3
  31. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +8 -8
  32. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +11 -13
  33. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +2 -2
  34. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +19 -19
  35. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +16 -16
  36. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +16 -16
  37. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +7 -11
  38. data/spec/rr/rspec/rspec_adapter_spec.rb +10 -10
  39. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +1 -1
  40. data/spec/rr/space/space_spec.rb +372 -18
  41. data/spec/rr/test_unit/test_unit_backtrace_test.rb +1 -1
  42. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +3 -3
  43. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +3 -3
  44. data/spec/spec_helper.rb +14 -3
  45. data/spec/spec_suite.rb +2 -2
  46. metadata +47 -45
  47. data/spec/rr/double/double_injection_register_scenario_spec.rb +0 -24
  48. data/spec/rr/space/space_create_spec.rb +0 -268
  49. data/spec/rr/space/space_helper.rb +0 -7
  50. data/spec/rr/space/space_register_spec.rb +0 -32
  51. data/spec/rr/space/space_reset_spec.rb +0 -131
  52. data/spec/rr/space/space_verify_spec.rb +0 -181
@@ -15,33 +15,33 @@ module RR
15
15
  describe "#verify" do
16
16
  it "returns true when times called exactly matches an integer" do
17
17
  expectation.verify.should == false
18
- expectation.attempt!
18
+ expectation.attempt
19
19
  expectation.verify.should == false
20
- expectation.attempt!
20
+ expectation.attempt
21
21
  expectation.verify.should == true
22
22
  end
23
23
  end
24
24
 
25
25
  describe "#verify! when passed an Integer (2)" do
26
26
  it "passes after attempt! called 2 times" do
27
- expectation.attempt!
28
- expectation.attempt!
27
+ expectation.attempt
28
+ expectation.attempt
29
29
  expectation.verify!
30
30
  end
31
31
 
32
32
  it "fails after attempt! called 1 time" do
33
- expectation.attempt!
34
- proc {expectation.verify!}.should raise_error(
33
+ expectation.attempt
34
+ lambda {expectation.verify!}.should raise_error(
35
35
  Errors::TimesCalledError,
36
36
  "foobar()\nCalled 1 time.\nExpected 2 times."
37
37
  )
38
38
  end
39
39
 
40
40
  it "can't be called when attempt! is called 3 times" do
41
- expectation.attempt!
42
- expectation.attempt!
43
- proc do
44
- expectation.attempt!
41
+ expectation.attempt
42
+ expectation.attempt
43
+ lambda do
44
+ expectation.attempt
45
45
  end.should raise_error(Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 2 times.")
46
46
  end
47
47
 
@@ -57,7 +57,7 @@ module RR
57
57
  end
58
58
 
59
59
  it "has an error message that includes the number of times called and expected number of times" do
60
- proc do
60
+ lambda do
61
61
  expectation.verify!
62
62
  end.should raise_error(Errors::TimesCalledError, "foobar()\nCalled 0 times.\nExpected 2 times.")
63
63
  end
@@ -65,18 +65,18 @@ module RR
65
65
 
66
66
  describe "#attempt?" do
67
67
  it "returns true when attempted less than expected times" do
68
- 1.times {expectation.attempt!}
68
+ 1.times {expectation.attempt}
69
69
  expectation.should be_attempt
70
70
  end
71
71
 
72
72
  it "returns false when attempted expected times" do
73
- 2.times {expectation.attempt!}
73
+ 2.times {expectation.attempt}
74
74
  expectation.should_not be_attempt
75
75
  end
76
76
 
77
77
  it "raises error before attempted more than expected times" do
78
- 2.times {expectation.attempt!}
79
- proc {expectation.attempt!}.should raise_error(
78
+ 2.times {expectation.attempt}
79
+ lambda {expectation.attempt}.should raise_error(
80
80
  Errors::TimesCalledError
81
81
  )
82
82
  end
@@ -84,10 +84,10 @@ module RR
84
84
 
85
85
  describe "#attempt! for an IntegerMatcher" do
86
86
  it "raises error when attempt! called more than the expected number of times" do
87
- expectation.attempt!
88
- expectation.attempt!
89
- proc do
90
- expectation.attempt!
87
+ expectation.attempt
88
+ expectation.attempt
89
+ lambda do
90
+ expectation.attempt
91
91
  end.should raise_error(Errors::TimesCalledError)
92
92
  end
93
93
  end
@@ -7,60 +7,60 @@ module RR
7
7
  attr_reader :matcher
8
8
 
9
9
  before do
10
- @matcher = TimesCalledMatchers::ProcMatcher.new(proc {|value| value == 2})
10
+ @matcher = TimesCalledMatchers::ProcMatcher.new(lambda {|value| value == 2})
11
11
  @expectation = TimesCalledExpectation.new(double, matcher)
12
12
  end
13
13
 
14
14
  describe "#verify" do
15
15
  it "matches a block" do
16
16
  expectation.verify.should == false
17
- expectation.attempt!
17
+ expectation.attempt
18
18
  expectation.verify.should == false
19
- expectation.attempt!
19
+ expectation.attempt
20
20
  expectation.verify.should == true
21
- expectation.attempt!
21
+ expectation.attempt
22
22
  expectation.verify.should == false
23
23
  end
24
24
  end
25
25
 
26
26
  describe "#verify! when passed a block (== 2 times)" do
27
27
  it "passes after attempt! called 2 times" do
28
- expectation.attempt!
29
- expectation.attempt!
28
+ expectation.attempt
29
+ expectation.attempt
30
30
  expectation.verify!
31
31
  end
32
32
 
33
33
  it "fails after attempt! called 1 time" do
34
- expectation.attempt!
35
- proc {expectation.verify!}.should raise_error(Errors::TimesCalledError)
34
+ expectation.attempt
35
+ lambda {expectation.verify!}.should raise_error(Errors::TimesCalledError)
36
36
  end
37
37
 
38
38
  it "fails after attempt! called 3 times" do
39
- expectation.attempt!
40
- expectation.attempt!
41
- expectation.attempt!
42
- proc {expectation.verify!}.should raise_error(Errors::TimesCalledError)
39
+ expectation.attempt
40
+ expectation.attempt
41
+ expectation.attempt
42
+ lambda {expectation.verify!}.should raise_error(Errors::TimesCalledError)
43
43
  end
44
44
  end
45
45
 
46
46
  describe "#attempt? with IntegerMatcher" do
47
47
  it "returns true when attempted less than expected times" do
48
- 1.times {expectation.attempt!}
48
+ 1.times {expectation.attempt}
49
49
  expectation.should be_attempt
50
50
  end
51
51
 
52
52
  it "returns true when attempted expected times" do
53
- 2.times {expectation.attempt!}
53
+ 2.times {expectation.attempt}
54
54
  expectation.should be_attempt
55
55
  end
56
56
 
57
57
  it "returns true when attempted more than expected times" do
58
- 3.times {expectation.attempt!}
58
+ 3.times {expectation.attempt}
59
59
  expectation.should be_attempt
60
60
  end
61
61
  end
62
62
 
63
- describe "#attempt! for a proc expectation" do
63
+ describe "#attempt! for a lambda expectation" do
64
64
  it "lets everything pass" do
65
65
  @object.foobar
66
66
  @object.foobar
@@ -14,30 +14,30 @@ module RR
14
14
  describe "#verify" do
15
15
  it "returns true when times called falls within a range" do
16
16
  expectation.verify.should == false
17
- expectation.attempt!
17
+ expectation.attempt
18
18
  expectation.verify.should == true
19
- expectation.attempt!
19
+ expectation.attempt
20
20
  expectation.verify.should == true
21
21
  end
22
22
  end
23
23
 
24
24
  describe "#verify! when passed a Range (1..2)" do
25
25
  it "passes after attempt! called 1 time" do
26
- expectation.attempt!
26
+ expectation.attempt
27
27
  expectation.verify!
28
28
  end
29
29
 
30
30
  it "passes after attempt! called 2 times" do
31
- expectation.attempt!
32
- expectation.attempt!
31
+ expectation.attempt
32
+ expectation.attempt
33
33
  expectation.verify!
34
34
  end
35
35
 
36
36
  it "can't be called when attempt! is called 3 times" do
37
- expectation.attempt!
38
- expectation.attempt!
39
- proc do
40
- expectation.attempt!
37
+ expectation.attempt
38
+ expectation.attempt
39
+ lambda do
40
+ expectation.attempt
41
41
  end.should raise_error(Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 1..2 times.")
42
42
  end
43
43
  end
@@ -48,15 +48,15 @@ module RR
48
48
  end
49
49
 
50
50
  it "returns false when attempted in range" do
51
- expectation.attempt!
51
+ expectation.attempt
52
52
  expectation.should be_attempt
53
- expectation.attempt!
53
+ expectation.attempt
54
54
  expectation.should be_attempt
55
55
  end
56
56
 
57
57
  it "raises error before attempted more than expected times" do
58
- 2.times {expectation.attempt!}
59
- proc {expectation.attempt!}.should raise_error(
58
+ 2.times {expectation.attempt}
59
+ lambda {expectation.attempt}.should raise_error(
60
60
  Errors::TimesCalledError
61
61
  )
62
62
  end
@@ -64,9 +64,9 @@ module RR
64
64
 
65
65
  describe "#attempt! for a range expectation" do
66
66
  it "raises error when attempt! called more than range permits" do
67
- expectation.attempt!
68
- expectation.attempt!
69
- raises_expectation_error {expectation.attempt!}
67
+ expectation.attempt
68
+ expectation.attempt
69
+ raises_expectation_error {expectation.attempt}
70
70
  end
71
71
  end
72
72
 
@@ -11,14 +11,12 @@ module RR
11
11
  @matcher = TimesCalledMatchers::IntegerMatcher.new(times)
12
12
  @expectation = TimesCalledExpectation.new(double, matcher)
13
13
  end
14
-
14
+
15
15
  describe "#attempt!" do
16
16
  it "raises error that includes the double" do
17
- proc do
18
- expectation.attempt!
19
- end.should raise_error(
20
- Errors::TimesCalledError,
21
- "#{double.formatted_name}\n#{matcher.error_message(1)}"
17
+ lambda {expectation.attempt}.should raise_error(
18
+ Errors::TimesCalledError,
19
+ "#{double.formatted_name}\n#{matcher.error_message(1)}"
22
20
  )
23
21
  end
24
22
  end
@@ -26,11 +24,9 @@ module RR
26
24
  describe "#verify!" do
27
25
  it "raises error with passed in message prepended" do
28
26
  expectation.instance_variable_set(:@times_called, 1)
29
- proc do
30
- expectation.verify!
31
- end.should raise_error(
32
- Errors::TimesCalledError,
33
- "#{double.formatted_name}\n#{matcher.error_message(1)}"
27
+ lambda {expectation.verify!}.should raise_error(
28
+ Errors::TimesCalledError,
29
+ "#{double.formatted_name}\n#{matcher.error_message(1)}"
34
30
  )
35
31
  end
36
32
  end
@@ -13,11 +13,11 @@ module RR
13
13
  end
14
14
 
15
15
  it "resets the double_injections" do
16
- RR::Space.double_injection(@subject, @method_name)
17
- RR::Space.double_injections.should_not be_empty
16
+ RR.double_injection(@subject, @method_name)
17
+ RR.double_injections.should_not be_empty
18
18
 
19
19
  @fixture.setup_mocks_for_rspec
20
- RR::Space.double_injections.should be_empty
20
+ RR.double_injections.should be_empty
21
21
  end
22
22
  end
23
23
 
@@ -31,15 +31,15 @@ module RR
31
31
  end
32
32
 
33
33
  it "verifies the double_injections" do
34
- double_injection = RR::Space.double_injection(@subject, @method_name)
35
- double = RR::Space.double(double_injection)
34
+ double_injection = RR.double_injection(@subject, @method_name)
35
+ double = RR::Double.new(double_injection)
36
36
 
37
37
  double.once
38
38
 
39
- proc do
39
+ lambda do
40
40
  @fixture.verify_mocks_for_rspec
41
41
  end.should raise_error(::RR::Errors::TimesCalledError)
42
- RR::Space.double_injections.should be_empty
42
+ RR.double_injections.should be_empty
43
43
  end
44
44
  end
45
45
 
@@ -53,11 +53,11 @@ module RR
53
53
  end
54
54
 
55
55
  it "resets the double_injections" do
56
- RR::Space.double_injection(@subject, @method_name)
57
- RR::Space.double_injections.should_not be_empty
56
+ RR.double_injection(@subject, @method_name)
57
+ RR.double_injections.should_not be_empty
58
58
 
59
59
  @fixture.teardown_mocks_for_rspec
60
- RR::Space.double_injections.should be_empty
60
+ RR.double_injections.should be_empty
61
61
  end
62
62
  end
63
63
  end
@@ -5,7 +5,7 @@ module RR
5
5
  describe Rspec do
6
6
  describe "#trim_backtrace" do
7
7
  it "does not set trim_backtrace" do
8
- RR::Space.trim_backtrace.should == false
8
+ RR.trim_backtrace.should == false
9
9
  end
10
10
  end
11
11
 
@@ -1,32 +1,386 @@
1
1
  require "spec/spec_helper"
2
2
 
3
3
  module RR
4
- describe Space, " class" do
5
- it_should_behave_like "RR::Space"
4
+ describe Space do
5
+ it_should_behave_like "Swapped Space"
6
6
 
7
- before(:each) do
8
- @original_space = Space.instance
9
- @space = Space.new
10
- Space.instance = @space
7
+ describe ".method_missing" do
8
+ it "proxies to a singleton instance of Space" do
9
+ create_double_args = nil
10
+ (class << @space; self; end).class_eval do
11
+ define_method :double_injection do |*args|
12
+ create_double_args = args
13
+ end
14
+ end
15
+
16
+ Space.double_injection(:foo, :bar)
17
+ create_double_args.should == [:foo, :bar]
18
+ end
19
+ end
20
+
21
+ describe "#double_injection" do
22
+ before do
23
+ @space = Space.new
24
+ end
25
+
26
+ it "creates a new double_injection when existing object == but not === with the same method name" do
27
+ object1 = []
28
+ object2 = []
29
+ (object1 === object2).should be_true
30
+ object1.__id__.should_not == object2.__id__
31
+
32
+ double1 = @space.double_injection(object1, :foobar)
33
+ double2 = @space.double_injection(object2, :foobar)
34
+
35
+ double1.should_not == double2
36
+ end
37
+
38
+ context "when double_injection does not exist" do
39
+ before do
40
+ @object = Object.new
41
+ def @object.foobar(*args)
42
+ :original_foobar
43
+ end
44
+ @method_name = :foobar
45
+ end
46
+
47
+ it "returns double_injection and adds double_injection to double_injection list when method_name is a symbol" do
48
+ double_injection = @space.double_injection(@object, @method_name)
49
+ @space.double_injection(@object, @method_name).should === double_injection
50
+ double_injection.object.should === @object
51
+ double_injection.method_name.should === @method_name
52
+ end
53
+
54
+ it "returns double_injection and adds double_injection to double_injection list when method_name is a string" do
55
+ double_injection = @space.double_injection(@object, 'foobar')
56
+ @space.double_injection(@object, @method_name).should === double_injection
57
+ double_injection.object.should === @object
58
+ double_injection.method_name.should === @method_name
59
+ end
60
+
61
+ it "overrides the method when passing a block" do
62
+ double_injection = @space.double_injection(@object, @method_name)
63
+ @object.methods.should include("__rr__#{@method_name}")
64
+ end
65
+ end
66
+
67
+ context "when double_injection exists" do
68
+ before do
69
+ @object = Object.new
70
+ def @object.foobar(*args)
71
+ :original_foobar
72
+ end
73
+ @method_name = :foobar
74
+ end
75
+
76
+ it "returns the existing double_injection" do
77
+ original_foobar_method = @object.method(:foobar)
78
+ double_injection = @space.double_injection(@object, 'foobar')
79
+
80
+ double_injection.object_has_original_method?.should be_true
81
+
82
+ @space.double_injection(@object, 'foobar').should === double_injection
83
+
84
+ double_injection.reset
85
+ @object.foobar.should == :original_foobar
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "#reset" do
91
+ before do
92
+ @space = Space.instance
93
+ @object1 = Object.new
94
+ @object2 = Object.new
95
+ @method_name = :foobar
96
+ end
97
+
98
+ it "removes the ordered doubles" do
99
+ double1 = @space.double_injection(@object1, :foobar1)
100
+ double2 = @space.double_injection(@object1, :foobar2)
101
+
102
+ double1 = Double.new(double1)
103
+ double2 = Double.new(double2)
104
+
105
+ double1.ordered
106
+ double2.ordered
107
+
108
+ @space.ordered_doubles.should_not be_empty
109
+
110
+ @space.reset
111
+ @space.ordered_doubles.should be_empty
112
+ end
113
+
114
+ it "resets all double_injections" do
115
+ double1 = @space.double_injection(@object1, @method_name)
116
+ double1_reset_calls = 0
117
+ (
118
+ class << double1;
119
+ self;
120
+ end).class_eval do
121
+ define_method(:reset) do ||
122
+ double1_reset_calls += 1
123
+ end
124
+ end
125
+ double2 = @space.double_injection(@object2, @method_name)
126
+ double2_reset_calls = 0
127
+ (
128
+ class << double2;
129
+ self;
130
+ end).class_eval do
131
+ define_method(:reset) do ||
132
+ double2_reset_calls += 1
133
+ end
134
+ end
135
+
136
+ @space.reset
137
+ double1_reset_calls.should == 1
138
+ double2_reset_calls.should == 1
139
+ end
140
+ end
141
+
142
+ describe "#reset_double" do
143
+ before do
144
+ @space = Space.new
145
+ @object = Object.new
146
+ @method_name = :foobar
147
+ end
148
+
149
+ it "resets the double_injections" do
150
+ double_injection = @space.double_injection(@object, @method_name)
151
+ @space.double_injections[@object][@method_name].should === double_injection
152
+ @object.methods.should include("__rr__#{@method_name}")
153
+
154
+ @space.reset_double(@object, @method_name)
155
+ @space.double_injections[@object][@method_name].should be_nil
156
+ @object.methods.should_not include("__rr__#{@method_name}")
157
+ end
158
+
159
+ it "removes the object from the double_injections map when it has no double_injections" do
160
+ double1 = @space.double_injection(@object, :foobar1)
161
+ double2 = @space.double_injection(@object, :foobar2)
162
+
163
+ @space.double_injections.include?(@object).should == true
164
+ @space.double_injections[@object][:foobar1].should_not be_nil
165
+ @space.double_injections[@object][:foobar2].should_not be_nil
166
+
167
+ @space.reset_double(@object, :foobar1)
168
+ @space.double_injections.include?(@object).should == true
169
+ @space.double_injections[@object][:foobar1].should be_nil
170
+ @space.double_injections[@object][:foobar2].should_not be_nil
171
+
172
+ @space.reset_double(@object, :foobar2)
173
+ @space.double_injections.include?(@object).should == false
174
+ end
11
175
  end
12
176
 
13
- after(:each) do
14
- Space.instance = @original_space
177
+ describe "#reset_double_injections" do
178
+ before do
179
+ @object1 = Object.new
180
+ @object2 = Object.new
181
+ @method_name = :foobar
182
+ end
183
+
184
+ it "resets the double_injection and removes it from the double_injections list" do
185
+ double1 = @space.double_injection(@object1, @method_name)
186
+ double1_reset_calls = 0
187
+ (class << double1; self; end).class_eval do
188
+ define_method(:reset) do ||
189
+ double1_reset_calls += 1
190
+ end
191
+ end
192
+ double2 = @space.double_injection(@object2, @method_name)
193
+ double2_reset_calls = 0
194
+ (class << double2; self; end).class_eval do
195
+ define_method(:reset) do ||
196
+ double2_reset_calls += 1
197
+ end
198
+ end
199
+
200
+ @space.__send__(:reset_double_injections)
201
+ double1_reset_calls.should == 1
202
+ double2_reset_calls.should == 1
203
+ end
204
+ end
205
+
206
+ describe "#register_ordered_double" do
207
+ before(:each) do
208
+ @object = Object.new
209
+ @method_name = :foobar
210
+ @double_injection = @space.double_injection(@object, @method_name)
211
+ end
212
+
213
+ it "adds the ordered double to the ordered_doubles collection" do
214
+ double1 = Double.new(@double_injection)
215
+
216
+ @space.ordered_doubles.should == []
217
+ @space.register_ordered_double double1
218
+ @space.ordered_doubles.should == [double1]
219
+
220
+ double2 = Double.new(@double_injection)
221
+ @space.register_ordered_double double2
222
+ @space.ordered_doubles.should == [double1, double2]
223
+ end
224
+ end
225
+
226
+ describe "#verify_doubles" do
227
+ before do
228
+ @object1 = Object.new
229
+ @object2 = Object.new
230
+ @method_name = :foobar
231
+ end
232
+
233
+ it "verifies and deletes the double_injections" do
234
+ double1 = @space.double_injection(@object1, @method_name)
235
+ double1_verify_calls = 0
236
+ double1_reset_calls = 0
237
+ (class << double1; self; end).class_eval do
238
+ define_method(:verify) do ||
239
+ double1_verify_calls += 1
240
+ end
241
+ define_method(:reset) do ||
242
+ double1_reset_calls += 1
243
+ end
244
+ end
245
+ double2 = @space.double_injection(@object2, @method_name)
246
+ double2_verify_calls = 0
247
+ double2_reset_calls = 0
248
+ (class << double2; self; end).class_eval do
249
+ define_method(:verify) do ||
250
+ double2_verify_calls += 1
251
+ end
252
+ define_method(:reset) do ||
253
+ double2_reset_calls += 1
254
+ end
255
+ end
256
+
257
+ @space.verify_doubles
258
+ double1_verify_calls.should == 1
259
+ double2_verify_calls.should == 1
260
+ double1_reset_calls.should == 1
261
+ double1_reset_calls.should == 1
262
+ end
263
+ end
264
+
265
+ describe "#verify_double" do
266
+ before do
267
+ @object = Object.new
268
+ @method_name = :foobar
269
+ end
270
+
271
+ it "verifies and deletes the double_injection" do
272
+ double_injection = @space.double_injection(@object, @method_name)
273
+ @space.double_injections[@object][@method_name].should === double_injection
274
+ @object.methods.should include("__rr__#{@method_name}")
275
+
276
+ verify_calls = 0
277
+ (class << double_injection; self; end).class_eval do
278
+ define_method(:verify) do ||
279
+ verify_calls += 1
280
+ end
281
+ end
282
+ @space.verify_double(@object, @method_name)
283
+ verify_calls.should == 1
284
+
285
+ @space.double_injections[@object][@method_name].should be_nil
286
+ @object.methods.should_not include("__rr__#{@method_name}")
287
+ end
288
+
289
+ it "deletes the double_injection when verifying the double_injection raises an error" do
290
+ double_injection = @space.double_injection(@object, @method_name)
291
+ @space.double_injections[@object][@method_name].should === double_injection
292
+ @object.methods.should include("__rr__#{@method_name}")
293
+
294
+ verify_called = true
295
+ (class << double_injection; self; end).class_eval do
296
+ define_method(:verify) do ||
297
+ verify_called = true
298
+ raise "An Error"
299
+ end
300
+ end
301
+ lambda {@space.verify_double(@object, @method_name)}.should raise_error
302
+ verify_called.should be_true
303
+
304
+ @space.double_injections[@object][@method_name].should be_nil
305
+ @object.methods.should_not include("__rr__#{@method_name}")
306
+ end
15
307
  end
16
308
 
17
- it "proxies to a singleton instance of Space" do
18
- create_double_args = nil
19
- (
20
- class << @space;
21
- self;
22
- end).class_eval do
23
- define_method :double_injection do |*args|
24
- create_double_args = args
309
+ describe "#verify_ordered_double" do
310
+ before do
311
+ @object = Object.new
312
+ @method_name = :foobar
313
+ @double_injection = @space.double_injection(@object, @method_name)
314
+ end
315
+
316
+ class << self
317
+ define_method "#verify_ordered_double" do
318
+ it "raises an error when Double is NonTerminal" do
319
+ double = Double.new(@double_injection)
320
+ @space.register_ordered_double(double)
321
+
322
+ double.any_number_of_times
323
+ double.should_not be_terminal
324
+
325
+ lambda do
326
+ @space.verify_ordered_double(double)
327
+ end.should raise_error(
328
+ Errors::DoubleOrderError,
329
+ "Ordered Doubles cannot have a NonTerminal TimesCalledExpectation"
330
+ )
331
+ end
332
+ end
333
+ end
334
+
335
+ context "when the passed in double is at the front of the queue" do
336
+ send "#verify_ordered_double"
337
+ it "keeps the double when times called is not verified" do
338
+ double = Double.new(@double_injection)
339
+ @space.register_ordered_double(double)
340
+
341
+ double.twice
342
+ double.should be_attempt
343
+
344
+ @space.verify_ordered_double(double)
345
+ @space.ordered_doubles.should include(double)
346
+ end
347
+
348
+ it "removes the double when times called expectation should no longer be attempted" do
349
+ double = Double.new(@double_injection)
350
+ @space.register_ordered_double(double)
351
+
352
+ double.with(1).once
353
+ @object.foobar(1)
354
+ double.should_not be_attempt
355
+
356
+ @space.verify_ordered_double(double)
357
+ @space.ordered_doubles.should_not include(double)
25
358
  end
26
359
  end
27
360
 
28
- Space.double_injection(:foo, :bar)
29
- create_double_args.should == [:foo, :bar]
361
+ context "when the passed in double is not at the front of the queue" do
362
+ send "#verify_ordered_double"
363
+ it "raises error" do
364
+ first_double = double
365
+ second_double = double
366
+
367
+ lambda do
368
+ @space.verify_ordered_double(second_double)
369
+ end.should raise_error(
370
+ Errors::DoubleOrderError,
371
+ "foobar() called out of order in list\n" <<
372
+ "- foobar()\n" <<
373
+ "- foobar()"
374
+ )
375
+ end
376
+
377
+ def double
378
+ double = Double.new(@double_injection).once
379
+ @space.register_ordered_double(double.double)
380
+ double.double
381
+ end
382
+ end
30
383
  end
31
384
  end
385
+
32
386
  end