rr 0.3.1 → 0.3.2

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.
data/CHANGES CHANGED
@@ -1,3 +1,6 @@
1
+ * 0.3.2
2
+ - Fixed [#12486] ScenarioMethodProxy when Kernel passed into instance methods
3
+
1
4
  * 0.3.1
2
5
  - Automatically require Test::Unit and Rspec adapters
3
6
 
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ def run_suite
21
21
  end
22
22
 
23
23
  PKG_NAME = "rr"
24
- PKG_VERSION = "0.3.1"
24
+ PKG_VERSION = "0.3.2"
25
25
  PKG_FILES = FileList[
26
26
  '[A-Z]*',
27
27
  '*.rb',
@@ -21,6 +21,11 @@ describe ScenarioCreator, " strategy definition", :shared => true do
21
21
  scenario.should be_instance_of(Scenario)
22
22
  end
23
23
 
24
+ it "returns a ScenarioMethodProxy when passed Kernel" do
25
+ scenario = @creator.__send__(@method_name, Kernel).foobar
26
+ scenario.should be_instance_of(Scenario)
27
+ end
28
+
24
29
  it "raises error if passed a method name and a block" do
25
30
  proc do
26
31
  @creator.__send__(@method_name, @subject, :foobar) {}
@@ -203,9 +208,17 @@ describe ScenarioCreator, "#do_not_call" do
203
208
  end
204
209
  end
205
210
 
206
- describe ScenarioCreator, "#probe" do
211
+ describe ScenarioCreator, "#probe and #stub" do
207
212
  it_should_behave_like "RR::ScenarioCreator"
208
213
 
214
+ before do
215
+ class << @subject
216
+ def foobar(*args)
217
+ :original_foobar
218
+ end
219
+ end
220
+ end
221
+
209
222
  it "raises error when using do_not_call strategy" do
210
223
  @creator.do_not_call
211
224
  proc do
@@ -216,30 +229,47 @@ describe ScenarioCreator, "#probe" do
216
229
  )
217
230
  end
218
231
 
219
- it "sets up the RR stub call chain" do
220
- should create_probe_call_chain(@creator.stub.probe(@subject))
221
- end
222
-
223
- it "creates a probe Scenario for method when passed a second argument" do
224
- should create_scenario_with_method_name(@creator.stub.probe(@subject, :foobar))
225
- end
226
-
227
- def create_scenario_with_method_name(scenario)
228
- method_name = scenario.method_name
229
- scenario.with(1, 2) {:baz}
232
+ it "sets up the RR probe call chain" do
233
+ scenario = @creator.stub.probe(@subject).foobar(1, 2) {:baz}
230
234
  scenario.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
231
235
  scenario.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
232
- @subject.__send__(method_name, 1, 2).should == :baz
236
+ @subject.foobar(1, 2).should == :baz
233
237
  end
234
238
 
235
- def create_probe_call_chain(creator)
236
- scenario = creator.foobar(1, 2) {:baz}
239
+ it "creates a probe Scenario for method when passed a second argument" do
240
+ scenario = @creator.stub.probe(@subject, :foobar)
241
+ scenario.with(1, 2) {:baz}
237
242
  scenario.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
238
243
  scenario.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
239
244
  @subject.foobar(1, 2).should == :baz
240
245
  end
241
246
  end
242
247
 
248
+ describe ScenarioCreator, "#instance_of" do
249
+ it_should_behave_like "RR::ScenarioCreator"
250
+
251
+ it "raises an error when not passed a class" #do
252
+ # proc do
253
+ # @creator.instance_of(Object.new)
254
+ # end.should raise_error(ArgumentError, "instance_of only accepts class objects")
255
+ # end
256
+
257
+ it "sets up the RR probe call chain" #do
258
+ # scenario = @creator.stub.instance_of(Class).foobar(1, 2) {:baz}
259
+ # scenario.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
260
+ # scenario.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
261
+ # Class.new.foobar(1, 2).should == :baz
262
+ # end
263
+
264
+ it "creates a probe Scenario for method when passed a second argument" #do
265
+ # scenario = @creator.stub.instance_of(Class, :foobar)
266
+ # scenario.with(1, 2) {:baz}
267
+ # scenario.times_matcher.should == TimesCalledMatchers::AnyTimesMatcher.new
268
+ # scenario.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
269
+ # Class.new.foobar(1, 2).should == :baz
270
+ # end
271
+ end
272
+
243
273
  describe ScenarioCreator, "#create! using no strategy" do
244
274
  it_should_behave_like "RR::ScenarioCreator"
245
275
 
@@ -78,12 +78,12 @@ describe Scenario, "#never" do
78
78
 
79
79
  it "sets up a Times Called Expectation with 0" do
80
80
  @scenario.never
81
- proc {@scenario.call}.should raise_error(Errors::TimesCalledError)
81
+ proc {@scenario.call(@double)}.should raise_error(Errors::TimesCalledError)
82
82
  end
83
83
 
84
84
  it "sets return value when block passed in" do
85
85
  @scenario.with_any_args.never
86
- proc {@scenario.call}.should raise_error(Errors::TimesCalledError)
86
+ proc {@scenario.call(@double)}.should raise_error(Errors::TimesCalledError)
87
87
  end
88
88
  end
89
89
 
@@ -92,8 +92,8 @@ describe Scenario, "#once" do
92
92
 
93
93
  it "sets up a Times Called Expectation with 1" do
94
94
  @scenario.once.should === @scenario
95
- @scenario.call
96
- proc {@scenario.call}.should raise_error(Errors::TimesCalledError)
95
+ @scenario.call(@double)
96
+ proc {@scenario.call(@double)}.should raise_error(Errors::TimesCalledError)
97
97
  end
98
98
 
99
99
  it "sets return value when block passed in" do
@@ -107,9 +107,9 @@ describe Scenario, "#twice" do
107
107
 
108
108
  it "sets up a Times Called Expectation with 2" do
109
109
  @scenario.twice.should === @scenario
110
- @scenario.call
111
- @scenario.call
112
- proc {@scenario.call}.should raise_error(Errors::TimesCalledError)
110
+ @scenario.call(@double)
111
+ @scenario.call(@double)
112
+ proc {@scenario.call(@double)}.should raise_error(Errors::TimesCalledError)
113
113
  end
114
114
 
115
115
  it "sets return value when block passed in" do
@@ -145,10 +145,10 @@ describe Scenario, "#at_most" do
145
145
 
146
146
  it "sets up a Times Called Expectation with 1" do
147
147
  @scenario.at_most(2)
148
- @scenario.call
149
- @scenario.call
148
+ @scenario.call(@double)
149
+ @scenario.call(@double)
150
150
  proc do
151
- @scenario.call
151
+ @scenario.call(@double)
152
152
  end.should raise_error(
153
153
  Errors::TimesCalledError,
154
154
  "Called 3 times.\nExpected at most 2 times."
@@ -166,10 +166,10 @@ describe Scenario, "#times" do
166
166
 
167
167
  it "sets up a Times Called Expectation with passed in times" do
168
168
  @scenario.times(3).should === @scenario
169
- @scenario.call
170
- @scenario.call
171
- @scenario.call
172
- proc {@scenario.call}.should raise_error(Errors::TimesCalledError)
169
+ @scenario.call(@double)
170
+ @scenario.call(@double)
171
+ @scenario.call(@double)
172
+ proc {@scenario.call(@double)}.should raise_error(Errors::TimesCalledError)
173
173
  end
174
174
 
175
175
  it "sets return value when block passed in" do
@@ -271,7 +271,7 @@ describe Scenario, "#after_call" do
271
271
  value
272
272
  end
273
273
 
274
- actual_value = @scenario.call
274
+ actual_value = @scenario.call(@double)
275
275
  actual_value.should === return_value
276
276
  actual_value.should == {:foo => :bar}
277
277
  end
@@ -282,7 +282,7 @@ describe Scenario, "#after_call" do
282
282
  :after_call_value
283
283
  end
284
284
 
285
- actual_value = @scenario.call
285
+ actual_value = @scenario.call(@double)
286
286
  actual_value.should == :after_call_value
287
287
  end
288
288
 
@@ -313,17 +313,17 @@ describe Scenario, "#returns" do
313
313
 
314
314
  it "sets the value of the method when passed a block" do
315
315
  @scenario.returns {:baz}
316
- @scenario.call.should == :baz
316
+ @scenario.call(@double).should == :baz
317
317
  end
318
318
 
319
319
  it "sets the value of the method when passed an argument" do
320
320
  @scenario.returns(:baz)
321
- @scenario.call.should == :baz
321
+ @scenario.call(@double).should == :baz
322
322
  end
323
323
 
324
324
  it "returns false when passed false" do
325
325
  @scenario.returns(false)
326
- @scenario.call.should == false
326
+ @scenario.call(@double).should == false
327
327
  end
328
328
 
329
329
  it "raises an error when both argument and block is passed in" do
@@ -342,7 +342,7 @@ describe Scenario, "#implemented_by" do
342
342
 
343
343
  it "sets the implementation to the passed in proc" do
344
344
  @scenario.implemented_by(proc{:baz})
345
- @scenario.call.should == :baz
345
+ @scenario.call(@double).should == :baz
346
346
  end
347
347
 
348
348
  it "sets the implementation to the passed in method" do
@@ -350,7 +350,7 @@ describe Scenario, "#implemented_by" do
350
350
  [b, a]
351
351
  end
352
352
  @scenario.implemented_by(@object.method(:foobar))
353
- @scenario.call(1, 2).should == [2, 1]
353
+ @scenario.call(@double, 1, 2).should == [2, 1]
354
354
  end
355
355
  end
356
356
 
@@ -363,7 +363,21 @@ describe Scenario, "#implemented_by_original_method" do
363
363
 
364
364
  it "sets the implementation to the original method" do
365
365
  @scenario.implemented_by_original_method
366
- @scenario.call(1, 2).should == [2, 1]
366
+ @scenario.call(@double, 1, 2).should == [2, 1]
367
+ end
368
+
369
+ it "raises error when original_method does not exist" do
370
+ double = @space.double(@object, :does_not_exist)
371
+ scenario = @space.scenario(double)
372
+ scenario.with_any_args
373
+ scenario.implemented_by_original_method
374
+
375
+ proc do
376
+ @object.does_not_exist(1, 2)
377
+ end.should raise_error(
378
+ Errors::ScenarioDefinitionError,
379
+ "implemented_by_original_method (probe) cannot be used when method does not exist on the object"
380
+ )
367
381
  end
368
382
  end
369
383
 
@@ -372,31 +386,31 @@ describe Scenario, "#call implemented by a proc" do
372
386
 
373
387
  it "calls the return proc when implemented by a proc" do
374
388
  @scenario.returns {|arg| "returning #{arg}"}
375
- @scenario.call(:foobar).should == "returning foobar"
389
+ @scenario.call(@double, :foobar).should == "returning foobar"
376
390
  end
377
391
 
378
392
  it "calls and returns the after_call when after_call is set" do
379
393
  @scenario.returns {|arg| "returning #{arg}"}.after_call do |value|
380
394
  "#{value} after call"
381
395
  end
382
- @scenario.call(:foobar).should == "returning foobar after call"
396
+ @scenario.call(@double, :foobar).should == "returning foobar after call"
383
397
  end
384
398
 
385
399
  it "returns nil when to returns is not set" do
386
- @scenario.call.should be_nil
400
+ @scenario.call(@double).should be_nil
387
401
  end
388
402
 
389
403
  it "works when times_called is not set" do
390
404
  @scenario.returns {:value}
391
- @scenario.call
405
+ @scenario.call(@double)
392
406
  end
393
407
 
394
408
  it "verifes the times_called does not exceed the TimesCalledExpectation" do
395
409
  @scenario.times(2).returns {:value}
396
410
 
397
- @scenario.call(:foobar)
398
- @scenario.call(:foobar)
399
- proc {@scenario.call(:foobar)}.should raise_error(Errors::TimesCalledError)
411
+ @scenario.call(@double, :foobar)
412
+ @scenario.call(@double, :foobar)
413
+ proc {@scenario.call(@double, :foobar)}.should raise_error(Errors::TimesCalledError)
400
414
  end
401
415
 
402
416
  it "raises ScenarioOrderError when ordered and called out of order" do
@@ -428,7 +442,7 @@ describe Scenario, "#call implemented by a proc" do
428
442
  end
429
443
 
430
444
  @scenario.returns {:value}.ordered
431
- @scenario.call(:foobar)
445
+ @scenario.call(@double, :foobar)
432
446
  verify_ordered_scenario_called.should be_true
433
447
  passed_in_scenario.should === @scenario
434
448
  end
@@ -443,7 +457,7 @@ describe Scenario, "#call implemented by a proc" do
443
457
  end
444
458
 
445
459
  @scenario.returns {:value}
446
- @scenario.call(:foobar)
460
+ @scenario.call(@double, :foobar)
447
461
  verify_ordered_scenario_called.should be_false
448
462
  end
449
463
 
@@ -543,15 +557,15 @@ describe Scenario, "#attempt?" do
543
557
 
544
558
  it "returns true when TimesCalledExpectation#attempt? is true" do
545
559
  @scenario.with(1, 2, 3).twice
546
- @scenario.call(1, 2, 3)
560
+ @scenario.call(@double, 1, 2, 3)
547
561
  @scenario.times_called_expectation.should be_attempt
548
562
  @scenario.should be_attempt
549
563
  end
550
564
 
551
565
  it "returns false when TimesCalledExpectation#attempt? is true" do
552
566
  @scenario.with(1, 2, 3).twice
553
- @scenario.call(1, 2, 3)
554
- @scenario.call(1, 2, 3)
567
+ @scenario.call(@double, 1, 2, 3)
568
+ @scenario.call(@double, 1, 2, 3)
555
569
  @scenario.times_called_expectation.should_not be_attempt
556
570
  @scenario.should_not be_attempt
557
571
  end
@@ -570,18 +584,18 @@ describe Scenario, "#verify" do
570
584
  @scenario.twice.returns {:return_value}
571
585
 
572
586
  proc {@scenario.verify}.should raise_error(Errors::TimesCalledError)
573
- @scenario.call
587
+ @scenario.call(@double)
574
588
  proc {@scenario.verify}.should raise_error(Errors::TimesCalledError)
575
- @scenario.call
589
+ @scenario.call(@double)
576
590
 
577
591
  proc {@scenario.verify}.should_not raise_error
578
592
  end
579
593
 
580
594
  it "does not raise an error when there is no times called expectation" do
581
595
  proc {@scenario.verify}.should_not raise_error
582
- @scenario.call
596
+ @scenario.call(@double)
583
597
  proc {@scenario.verify}.should_not raise_error
584
- @scenario.call
598
+ @scenario.call(@double)
585
599
  proc {@scenario.verify}.should_not raise_error
586
600
  end
587
601
  end
@@ -74,7 +74,7 @@ module RR
74
74
 
75
75
  def call_method(args, block)
76
76
  if scenario = find_scenario_to_attempt(args)
77
- return scenario.call(*args, &block)
77
+ return scenario.call(self, *args, &block)
78
78
  end
79
79
  scenario_not_found_error(*args)
80
80
  end
@@ -15,6 +15,7 @@ module RR
15
15
  end.join("\n")
16
16
  end
17
17
  end
18
+ ORIGINAL_METHOD = Object.new
18
19
 
19
20
  attr_reader :times_called, :argument_expectation, :times_called_expectation, :double
20
21
 
@@ -247,7 +248,7 @@ module RR
247
248
  # mock(obj).method_name.implemented_by_original_method
248
249
  # obj.foobar {|arg| puts arg} # puts 1
249
250
  def implemented_by_original_method
250
- implemented_by @double.original_method
251
+ implemented_by ORIGINAL_METHOD
251
252
  self
252
253
  end
253
254
 
@@ -256,23 +257,36 @@ module RR
256
257
  #
257
258
  # A TimesCalledError is raised when the times called
258
259
  # exceeds the expected TimesCalledExpectation.
259
- def call(*args, &block)
260
- return_value = call_implementation(*args, &block)
260
+ def call(double, *args, &block)
261
+ @times_called_expectation.attempt! if @times_called_expectation
262
+ @space.verify_ordered_scenario(self) if ordered?
263
+ yields!(block)
264
+ return_value = call_implementation(double, *args, &block)
261
265
  return return_value unless @after_call
262
266
  @after_call.call(return_value)
263
267
  end
264
268
 
265
- def call_implementation(*args, &block)
266
- @times_called_expectation.attempt! if @times_called_expectation
267
- @space.verify_ordered_scenario(self) if ordered?
269
+ def yields!(block)
268
270
  if @yields
269
271
  unless block
270
272
  raise ArgumentError, "A Block must be passed into the method call when using yields"
271
273
  end
272
274
  block.call(*@yields)
273
275
  end
276
+ end
277
+ protected :yields!
278
+
279
+ def call_implementation(double, *args, &block)
274
280
  return nil unless @implementation
275
281
 
282
+ if @implementation === ORIGINAL_METHOD
283
+ if !double.original_method
284
+ raise Errors::ScenarioDefinitionError,
285
+ "implemented_by_original_method (probe) cannot be used when method does not exist on the object"
286
+ end
287
+ return double.original_method.call(*args, &block)
288
+ end
289
+
276
290
  if @implementation.is_a?(Method)
277
291
  return @implementation.call(*args, &block)
278
292
  else
@@ -16,6 +16,7 @@ module RR
16
16
  @space = space
17
17
  @strategy = nil
18
18
  @probe = false
19
+ @instance_of = nil
19
20
  end
20
21
 
21
22
  def create!(subject, method_name, *args, &handler)
@@ -29,6 +30,13 @@ module RR
29
30
  @scenario
30
31
  end
31
32
 
33
+ # def instance_of(subject=NO_SUBJECT_ARG, method_name=nil, &definition)
34
+ # return self if subject === NO_SUBJECT_ARG
35
+ # raise ArgumentError, "instance_of only accepts class objects" unless subject.is_a?(Class)
36
+ # @instance_of = true
37
+ # RR::Space.scenario_method_proxy(self, subject, method_name, &definition)
38
+ # end
39
+
32
40
  # This method sets the Scenario to have a mock strategy. A mock strategy
33
41
  # sets the default state of the Scenario to expect the method call
34
42
  # with arguments exactly one time. The Scenario's expectations can be
@@ -59,7 +67,7 @@ module RR
59
67
  def mock(subject=NO_SUBJECT_ARG, method_name=nil, &definition)
60
68
  strategy_error! if @strategy
61
69
  @strategy = :mock
62
- return self if subject === NO_SUBJECT_ARG
70
+ return self if subject.__id__ === NO_SUBJECT_ARG.__id__
63
71
  RR::Space.scenario_method_proxy(self, subject, method_name, &definition)
64
72
  end
65
73
 
@@ -94,15 +102,31 @@ module RR
94
102
  def stub(subject=NO_SUBJECT_ARG, method_name=nil, &definition)
95
103
  strategy_error! if @strategy
96
104
  @strategy = :stub
97
- return self if subject === NO_SUBJECT_ARG
105
+ return self if subject.__id__ === NO_SUBJECT_ARG.__id__
98
106
  RR::Space.scenario_method_proxy(self, subject, method_name, &definition)
99
107
  end
100
108
 
109
+ # This method sets the Scenario to have a do_not_call strategy.
110
+ # A do_not_call strategy sets the default state of the Scenario
111
+ # to expect never to be called. The Scenario's expectations can be
112
+ # changed.
113
+ #
114
+ # The following example sets the expectation that subject.method_name
115
+ # will never be called with arg1 and arg2.
116
+ #
117
+ # do_not_allow(subject).method_name(arg1, arg2)
118
+ #
119
+ # do_not_call also supports a block sytnax.
120
+ # do_not_call(subject) do |m|
121
+ # m.method1 # Do not allow method1 with any arguments
122
+ # m.method2(arg1, arg2) # Do not allow method2 with arguments arg1 and arg2
123
+ # m.method3.with_no_args # Do not allow method3 with no arguments
124
+ # end
101
125
  def do_not_call(subject=NO_SUBJECT_ARG, method_name=nil, &definition)
102
126
  strategy_error! if @strategy
103
127
  probe_when_do_not_call_error! if @probe
104
128
  @strategy = :do_not_call
105
- return self if subject === NO_SUBJECT_ARG
129
+ return self if subject.__id__ === NO_SUBJECT_ARG.__id__
106
130
  RR::Space.scenario_method_proxy(self, subject, method_name, &definition)
107
131
  end
108
132
  alias_method :dont_call, :do_not_call
@@ -157,7 +181,7 @@ module RR
157
181
  def probe(subject=NO_SUBJECT_ARG, method_name=nil, &definition)
158
182
  probe_when_do_not_call_error! if @strategy == :do_not_call
159
183
  @probe = true
160
- return self if subject === NO_SUBJECT_ARG
184
+ return self if subject.__id__ === NO_SUBJECT_ARG.__id__
161
185
  RR::Space.scenario_method_proxy(self, subject, method_name, &definition)
162
186
  end
163
187
 
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.3
3
3
  specification_version: 1
4
4
  name: rr
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.1
6
+ version: 0.3.2
7
7
  date: 2007-07-22 00:00:00 -07:00
8
8
  summary: RR (Double Ruby) is a double framework that features a rich selection of double techniques and a terse syntax. http://xunitpatterns.com/Test%20Double.html
9
9
  require_paths: