rr 0.6.0 → 0.7.0

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 (57) hide show
  1. data/CHANGES +10 -0
  2. data/README.rdoc +56 -18
  3. data/Rakefile +1 -2
  4. data/lib/rr.rb +14 -5
  5. data/lib/rr/adapters/rr_methods.rb +11 -0
  6. data/lib/rr/adapters/rspec.rb +30 -0
  7. data/lib/rr/adapters/test_unit.rb +4 -0
  8. data/lib/rr/double.rb +79 -227
  9. data/lib/rr/double_definitions/child_double_definition_creator.rb +4 -0
  10. data/lib/rr/double_definitions/double_definition.rb +138 -4
  11. data/lib/rr/double_definitions/double_definition_creator.rb +18 -4
  12. data/lib/rr/double_definitions/double_definition_creator_proxy.rb +35 -3
  13. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +17 -0
  14. data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +3 -0
  15. data/lib/rr/double_injection.rb +10 -6
  16. data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
  17. data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
  18. data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
  19. data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
  20. data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
  21. data/lib/rr/expectations/times_called_expectation.rb +11 -9
  22. data/lib/rr/recorded_calls.rb +103 -0
  23. data/lib/rr/space.rb +18 -8
  24. data/lib/rr/spy_verification.rb +48 -0
  25. data/lib/rr/spy_verification_proxy.rb +18 -0
  26. data/lib/rr/times_called_matchers/any_times_matcher.rb +2 -3
  27. data/lib/rr/times_called_matchers/at_least_matcher.rb +2 -3
  28. data/lib/rr/times_called_matchers/at_most_matcher.rb +2 -3
  29. data/lib/rr/times_called_matchers/times_called_matcher.rb +4 -4
  30. data/spec/core_spec_suite.rb +1 -0
  31. data/spec/high_level_spec.rb +151 -14
  32. data/spec/rr/adapters/rr_methods_space_spec.rb +2 -2
  33. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +9 -0
  34. data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +91 -19
  35. data/spec/rr/double_definitions/double_definition_creator_spec.rb +7 -0
  36. data/spec/rr/double_definitions/double_definition_spec.rb +53 -10
  37. data/spec/rr/double_injection/double_injection_dispatching_spec.rb +14 -15
  38. data/spec/rr/double_injection/double_injection_verify_spec.rb +1 -1
  39. data/spec/rr/double_spec.rb +79 -445
  40. data/spec/rr/errors/rr_error_spec.rb +49 -47
  41. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +4 -3
  42. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +3 -2
  43. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +3 -2
  44. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +2 -2
  45. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +3 -3
  46. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +6 -5
  47. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +3 -2
  48. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +3 -2
  49. data/spec/rr/rspec/invocation_matcher_spec.rb +259 -0
  50. data/spec/rr/rspec/rspec_adapter_spec.rb +1 -1
  51. data/spec/rr/rspec/rspec_usage_spec.rb +43 -24
  52. data/spec/rr/space/hash_with_object_id_key_spec.rb +2 -2
  53. data/spec/rr/space/space_spec.rb +27 -9
  54. data/spec/rr/test_unit/test_unit_integration_test.rb +10 -0
  55. data/spec/spec_helper.rb +4 -1
  56. data/spec/spy_verification_spec.rb +129 -0
  57. metadata +100 -88
@@ -2,63 +2,65 @@ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
2
 
3
3
  module RR
4
4
  module Errors
5
- describe RRError, "#backtrace" do
6
- before do
7
- @original_trim_backtrace = RR.trim_backtrace
8
- end
9
- after do
10
- RR.trim_backtrace = @original_trim_backtrace
11
- end
5
+ describe RRError do
6
+ describe "#backtrace" do
7
+ before do
8
+ @original_trim_backtrace = RR.trim_backtrace
9
+ end
10
+ after do
11
+ RR.trim_backtrace = @original_trim_backtrace
12
+ end
13
+
14
+ it "does not include the rr library files when trim_backtrace is true" do
15
+ RR.trim_backtrace = true
12
16
 
13
- it "does not include the rr library files when trim_backtrace is true" do
14
- RR.trim_backtrace = true
17
+ error = nil
18
+ begin
19
+ obj = Object.new
20
+ mock(obj).foobar
21
+ RR.verify_double(obj, :foobar)
22
+ rescue RRError=> e
23
+ error = e
24
+ end
25
+ backtrace = error.backtrace.join("\n")
15
26
 
16
- error = nil
17
- begin
18
- obj = Object.new
19
- mock(obj).foobar
20
- RR.verify_double(obj, :foobar)
21
- rescue RRError=> e
22
- error = e
27
+ backtrace.should_not include("lib/rr")
23
28
  end
24
- backtrace = error.backtrace.join("\n")
25
29
 
26
- backtrace.should_not include("lib/rr")
27
- end
30
+ it "includes the rr library files when trim_backtrace is false" do
31
+ RR.trim_backtrace = false
28
32
 
29
- it "includes the rr library files when trim_backtrace is false" do
30
- RR.trim_backtrace = false
33
+ error = nil
34
+ begin
35
+ obj = Object.new
36
+ mock(obj).foobar
37
+ RR.verify_double(obj, :foobar)
38
+ rescue RRError=> e
39
+ error = e
40
+ end
41
+ backtrace = error.backtrace.join("\n")
31
42
 
32
- error = nil
33
- begin
34
- obj = Object.new
35
- mock(obj).foobar
36
- RR.verify_double(obj, :foobar)
37
- rescue RRError=> e
38
- error = e
43
+ backtrace.should include("lib/rr")
39
44
  end
40
- backtrace = error.backtrace.join("\n")
41
-
42
- backtrace.should include("lib/rr")
43
- end
44
45
 
45
- it "returns custom backtrace when backtrace is set" do
46
- error = RRError.new
47
- custom_backtrace = caller
48
- error.backtrace = custom_backtrace
49
- error.backtrace.should == custom_backtrace
50
- end
46
+ it "returns custom backtrace when backtrace is set" do
47
+ error = RRError.new
48
+ custom_backtrace = caller
49
+ error.backtrace = custom_backtrace
50
+ error.backtrace.should == custom_backtrace
51
+ end
51
52
 
52
- it "returns normal backtrace when backtrace is not set" do
53
- error = nil
54
- expected_line = __LINE__ + 2
55
- begin
56
- raise RRError
57
- rescue RRError => e
58
- error = e
53
+ it "returns normal backtrace when backtrace is not set" do
54
+ error = nil
55
+ expected_line = __LINE__ + 2
56
+ begin
57
+ raise RRError
58
+ rescue RRError => e
59
+ error = e
60
+ end
61
+ error.backtrace.first.should include(__FILE__)
62
+ error.backtrace.first.should include(expected_line.to_s)
59
63
  end
60
- error.backtrace.first.should include(__FILE__)
61
- error.backtrace.first.should include(expected_line.to_s)
62
64
  end
63
65
  end
64
66
  end
@@ -5,11 +5,12 @@ module RR
5
5
  describe TimesCalledExpectation do
6
6
  context "when using an AnyTimesMatcher" do
7
7
  it_should_behave_like "RR::Expectations::TimesCalledExpectation"
8
- attr_reader :at_least, :expectation
8
+ attr_reader :matcher, :expectation
9
9
 
10
10
  before do
11
- @at_least = TimesCalledMatchers::AnyTimesMatcher.new
12
- @expectation = TimesCalledExpectation.new(double, at_least)
11
+ double.definition.any_number_of_times
12
+ @matcher = double.definition.times_matcher
13
+ @expectation = TimesCalledExpectation.new(double)
13
14
  end
14
15
 
15
16
  describe "#verify!" do
@@ -9,8 +9,9 @@ module RR
9
9
 
10
10
  before do
11
11
  @times = 3
12
- @at_least = TimesCalledMatchers::AtLeastMatcher.new(times)
13
- @expectation = TimesCalledExpectation.new(double, at_least)
12
+ double.definition.at_least(times)
13
+ @at_least = double.definition.times_matcher
14
+ @expectation = TimesCalledExpectation.new(double)
14
15
  end
15
16
 
16
17
  describe "#verify!" do
@@ -9,8 +9,9 @@ module RR
9
9
 
10
10
  before do
11
11
  @times = 3
12
- @at_most = TimesCalledMatchers::AtMostMatcher.new(times)
13
- @expectation = TimesCalledExpectation.new(double, at_most)
12
+ double.definition.at_most(times)
13
+ @at_most = double.definition.times_matcher
14
+ @expectation = TimesCalledExpectation.new(double)
14
15
  end
15
16
 
16
17
  describe "#verify!" do
@@ -1,7 +1,7 @@
1
1
  module RR
2
2
  module Expectations
3
3
  describe TimesCalledExpectation, :shared => true do
4
- attr_reader :space, :subject, :method_name, :double_injection, :double, :double_definition
4
+ attr_reader :subject, :method_name, :double_injection, :double, :double_definition
5
5
  it_should_behave_like "Swapped Space"
6
6
  before do
7
7
  @subject = Object.new
@@ -12,7 +12,7 @@ module RR
12
12
  subject
13
13
  )
14
14
  @double = new_double(double_injection)
15
- double.with_any_args
15
+ double.definition.with_any_args.any_number_of_times
16
16
  end
17
17
 
18
18
  def raises_expectation_error(&block)
@@ -8,9 +8,9 @@ module RR
8
8
  attr_reader :matcher, :expected_line, :expectation
9
9
 
10
10
  before do
11
- @matcher = TimesCalledMatchers::IntegerMatcher.new(2)
12
- @expectation = TimesCalledExpectation.new(double, matcher)
13
- @expected_line = __LINE__ - 1
11
+ double.definition.times(2)
12
+ @matcher = double.definition.times_matcher
13
+ @expectation = TimesCalledExpectation.new(double)
14
14
  end
15
15
 
16
16
  describe "#verify" do
@@ -8,8 +8,9 @@ module RR
8
8
  attr_reader :matcher, :expectation
9
9
 
10
10
  before do
11
- @matcher = TimesCalledMatchers::ProcMatcher.new(lambda {|value| value == 2})
12
- @expectation = TimesCalledExpectation.new(double, matcher)
11
+ double.definition.times(lambda {|value| value == 2})
12
+ @matcher = double.definition.times_matcher
13
+ @expectation = TimesCalledExpectation.new(double)
13
14
  end
14
15
 
15
16
  describe "#verify" do
@@ -63,9 +64,9 @@ module RR
63
64
 
64
65
  describe "#attempt! for a lambda expectation" do
65
66
  it "lets everything pass" do
66
- @subject.foobar
67
- @subject.foobar
68
- @subject.foobar
67
+ subject.foobar
68
+ subject.foobar
69
+ subject.foobar
69
70
  end
70
71
  end
71
72
 
@@ -8,8 +8,9 @@ module RR
8
8
  attr_reader :matcher, :expectation
9
9
 
10
10
  before do
11
- @matcher = TimesCalledMatchers::RangeMatcher.new(1..2)
12
- @expectation = TimesCalledExpectation.new(double, matcher)
11
+ double.definition.times(1..2)
12
+ @matcher = double.definition.times_matcher
13
+ @expectation = TimesCalledExpectation.new(double)
13
14
  end
14
15
 
15
16
  describe "#verify" do
@@ -9,8 +9,9 @@ module RR
9
9
 
10
10
  before do
11
11
  @times = 0
12
- @matcher = TimesCalledMatchers::IntegerMatcher.new(times)
13
- @expectation = TimesCalledExpectation.new(double, matcher)
12
+ double.definition.times(0)
13
+ @matcher = double.definition.times_matcher
14
+ @expectation = TimesCalledExpectation.new(double)
14
15
  end
15
16
 
16
17
  describe "#attempt!" do
@@ -0,0 +1,259 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module Adapters
5
+ module Rspec
6
+ describe InvocationMatcher do
7
+ describe "matching against a method with no doubles" do
8
+ before do
9
+ @matcher = InvocationMatcher.new(:foobar)
10
+ @result = @matcher.matches?(Object.new)
11
+ end
12
+
13
+ it "does not match" do
14
+ @result.should_not be
15
+ end
16
+ end
17
+
18
+ describe "defining an expectation using a method invocation" do
19
+ before do
20
+ @subject = Object.new
21
+ stub(@subject).foobar
22
+ @subject.foobar(:args)
23
+ @result = InvocationMatcher.new.foobar(:args).matches?(@subject)
24
+ end
25
+
26
+ it "uses the invoked method as the expected method" do
27
+ @result.should be
28
+ end
29
+ end
30
+
31
+ describe "matching against a stubbed method that was never called" do
32
+ before do
33
+ @subject = Object.new
34
+ stub(@subject).foobar
35
+ @matcher = InvocationMatcher.new(:foobar)
36
+ @result = @matcher.matches?(@subject)
37
+ end
38
+
39
+ it "does not match" do
40
+ @result.should_not be
41
+ end
42
+ end
43
+
44
+ describe "matching against a stubbed method that was called once" do
45
+ before do
46
+ @subject = Object.new
47
+ stub(@subject).foobar
48
+ @subject.foobar
49
+ @result = InvocationMatcher.new(:foobar).matches?(@subject)
50
+ end
51
+
52
+ it "does match" do
53
+ @result.should be
54
+ end
55
+ end
56
+
57
+ describe "matching against a stubbed method that was called with unexpected arguments" do
58
+ before do
59
+ @args = %w(one two)
60
+ @subject = Object.new
61
+ stub(@subject).foobar
62
+ @subject.foobar(:other)
63
+ @result = InvocationMatcher.new(:foobar).with(*@args).matches?(@subject)
64
+ end
65
+
66
+ it "does not match" do
67
+ @result.should_not be
68
+ end
69
+ end
70
+
71
+ describe "matching against a stubbed method that was called with expected arguments" do
72
+ before do
73
+ @args = %w(one two)
74
+ @subject = Object.new
75
+ stub(@subject).foobar
76
+ @subject.foobar(*@args)
77
+ @result = InvocationMatcher.new(:foobar).with(*@args).matches?(@subject)
78
+ end
79
+
80
+ it "does match" do
81
+ @result.should be
82
+ end
83
+ end
84
+
85
+ describe "defining a fulfilled argument expectation using a method invocation" do
86
+ before do
87
+ @args = %w(one two)
88
+ @subject = Object.new
89
+ stub(@subject).foobar
90
+ @subject.foobar(*@args)
91
+ @result = InvocationMatcher.new.foobar(*@args).matches?(@subject)
92
+ end
93
+
94
+ it "does match" do
95
+ @result.should be
96
+ end
97
+ end
98
+
99
+ describe "defining an unfulfilled argument expectation using a method invocation" do
100
+ before do
101
+ @args = %w(one two)
102
+ @subject = Object.new
103
+ stub(@subject).foobar
104
+ @subject.foobar(:other)
105
+ @result = InvocationMatcher.new.foobar(*@args).matches?(@subject)
106
+ end
107
+
108
+ it "does not match" do
109
+ @result.should_not be
110
+ end
111
+ end
112
+
113
+ describe "matching against a stubbed method that was called more than once" do
114
+ before do
115
+ @subject = Object.new
116
+ stub(@subject).foobar
117
+ 2.times { @subject.foobar }
118
+ @result = InvocationMatcher.new(:foobar).twice.matches?(@subject)
119
+ end
120
+
121
+ it "does match" do
122
+ @result.should be
123
+ end
124
+ end
125
+
126
+ describe "matching a stubbed method with any arguments" do
127
+ before do
128
+ @subject = Object.new
129
+ stub(@subject).foobar
130
+ @subject.foobar(:args)
131
+ @result = InvocationMatcher.new(:foobar).with_any_args.matches?(@subject)
132
+ end
133
+
134
+ it "does match" do
135
+ @result.should be
136
+ end
137
+ end
138
+
139
+ describe "matching a stubbed method with no arguments when arguments are not provided" do
140
+ before do
141
+ @subject = Object.new
142
+ stub(@subject).foobar
143
+ @subject.foobar
144
+ @result = InvocationMatcher.new(:foobar).with_no_args.matches?(@subject)
145
+ end
146
+
147
+ it "does match" do
148
+ @result.should be
149
+ end
150
+ end
151
+
152
+ describe "matching a stubbed method with no arguments when arguments are provided" do
153
+ before do
154
+ @subject = Object.new
155
+ stub(@subject).foobar
156
+ @subject.foobar(:args)
157
+ @result = InvocationMatcher.new(:foobar).with_no_args.matches?(@subject)
158
+ end
159
+
160
+ it "does not match" do
161
+ @result.should_not be
162
+ end
163
+ end
164
+
165
+ describe "matching a method that was called twice when expected once" do
166
+ before do
167
+ @subject = Object.new
168
+ stub(@subject).foobar
169
+ 2.times { @subject.foobar }
170
+ @matcher = InvocationMatcher.new(:foobar).times(1)
171
+ @result = @matcher.matches?(@subject)
172
+ end
173
+
174
+ it "does not match" do
175
+ @result.should_not be
176
+ end
177
+ end
178
+
179
+ describe "matching a method that was called twice when expected twice" do
180
+ before do
181
+ @subject = Object.new
182
+ stub(@subject).foobar
183
+ 2.times { @subject.foobar }
184
+ @result = InvocationMatcher.new(:foobar).times(2).matches?(@subject)
185
+ end
186
+
187
+ it "does match" do
188
+ @result.should be
189
+ end
190
+ end
191
+
192
+ describe "matching a method that was called twice when any number of times" do
193
+ before do
194
+ @subject = Object.new
195
+ stub(@subject).foobar
196
+ 2.times { @subject.foobar }
197
+ @result = InvocationMatcher.new(:foobar).any_number_of_times.matches?(@subject)
198
+ end
199
+
200
+ it "does match" do
201
+ @result.should be
202
+ end
203
+ end
204
+
205
+ describe "matching a method that was called three times when expected at most twice" do
206
+ before do
207
+ @subject = Object.new
208
+ stub(@subject).foobar
209
+ 3.times { @subject.foobar }
210
+ @result = InvocationMatcher.new(:foobar).at_most(2).matches?(@subject)
211
+ end
212
+
213
+ it "does not match" do
214
+ @result.should_not be
215
+ end
216
+ end
217
+
218
+ describe "matching a method that was called once when expected at most twice" do
219
+ before do
220
+ @subject = Object.new
221
+ stub(@subject).foobar
222
+ @subject.foobar
223
+ @result = InvocationMatcher.new(:foobar).at_most(2).matches?(@subject)
224
+ end
225
+
226
+ it "does match" do
227
+ @result.should be
228
+ end
229
+ end
230
+
231
+ describe "matching a method that was called once when expected at least twice" do
232
+ before do
233
+ @subject = Object.new
234
+ stub(@subject).foobar
235
+ @subject.foobar
236
+ @result = InvocationMatcher.new(:foobar).at_least(2).matches?(@subject)
237
+ end
238
+
239
+ it "does not match" do
240
+ @result.should_not be
241
+ end
242
+ end
243
+
244
+ describe "matching a method that was called three times when expected at least twice" do
245
+ before do
246
+ @subject = Object.new
247
+ stub(@subject).foobar
248
+ 3.times { @subject.foobar }
249
+ @result = InvocationMatcher.new(:foobar).at_least(2).matches?(@subject)
250
+ end
251
+
252
+ it "does match" do
253
+ @result.should be
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end