rr 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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: