flexmock 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -2,13 +2,23 @@
2
2
 
3
3
  = Changes for FlexMock
4
4
 
5
+ == Pre Version 0.5.1
6
+
7
+ * Changed the name of any_instance to new_instances.
8
+ Deprecated any_instance.
9
+ * Added ability to stub any class method in new_instances.
10
+ * Added RCov task
11
+ * Reworked original behavior hooks to use method aliasing rather than method
12
+ procs.
13
+ * Fixed bug in stubbing File class methods.
14
+
5
15
  == Version 0.5.0
6
16
 
7
17
  * Added any_instance stubbing to class objects.
8
18
 
9
19
  == Version 0.4.5
10
20
 
11
- * Fixed version typo in 0.4.4 (internall claimed to be 0.4.3.1)
21
+ * Fixed version typo in 0.4.4 (internally claimed to be 0.4.3.1)
12
22
 
13
23
  == Version 0.4.4
14
24
 
data/README CHANGED
@@ -3,7 +3,7 @@
3
3
  FlexMock is a simple, but flexible, mock object library for Ruby unit
4
4
  testing.
5
5
 
6
- Version :: 0.5.0
6
+ Version :: 0.5.1
7
7
 
8
8
  = Links
9
9
 
@@ -320,8 +320,8 @@ version of the object.
320
320
  <em>Class Interception is now deprecated. It only worked in a
321
321
  small number of cases. See the "Mocking Existing Objects"
322
322
  example above for a much better approach to the same problem.
323
- The Class Interception API will probably disappear in a future
324
- version of FlexMock.</em>
323
+ Version 0.5.x will be the last version of FlexMock that supports the
324
+ Class Interception API.</em>
325
325
 
326
326
  FlexMock now supports simple class interception. For the duration of a test, a
327
327
  mock class take the place of a named class inside the class to be tested.
@@ -380,7 +380,7 @@ but the third query (which matches any query call with a four
380
380
  character parameter) may be called multiple times (but at least once).
381
381
  Startup and finish must also happen exactly once.
382
382
 
383
- Also note that we use the +with+ method to match different arguement
383
+ Also note that we use the +with+ method to match different argument
384
384
  values to figure out what value to return.
385
385
 
386
386
  def test_ordered_queries
@@ -482,6 +482,7 @@ following:
482
482
  ruby-mock :: http://www.b13media.com/dev/ruby/mock.html
483
483
  test-unit-mock :: http://www.deveiate.org/code/Test-Unit-Mock.shtml
484
484
  mocha/stubba :: http://mocha.rubyforge.org/
485
+
485
486
  == License
486
487
 
487
488
  Copyright 2003, 2004, 2005, 2006 by Jim Weirich (jim@weirichhouse.org).
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require 'rake/testtask'
9
9
  CLEAN.include('*.tmp')
10
10
  CLOBBER.include("html", 'pkg')
11
11
 
12
- PKG_VERSION = '0.5.0'
12
+ PKG_VERSION = '0.5.1'
13
13
 
14
14
  PKG_FILES = FileList[
15
15
  '[A-Z]*',
@@ -29,6 +29,7 @@ RDOC_FILES = FileList[
29
29
 
30
30
  task :default => [:test_all]
31
31
  task :test_all => [:test]
32
+ task :test_units => [:test]
32
33
  task :ta => [:test_all]
33
34
 
34
35
  # Test Targets -------------------------------------------------------
@@ -39,6 +40,23 @@ Rake::TestTask.new do |t|
39
40
  t.warning = true
40
41
  end
41
42
 
43
+ Rake::TestTask.new(:test_extended) do |t|
44
+ t.test_files = FileList['test/extended/test_*.rb']
45
+ t.verbose = true
46
+ t.verbose = true
47
+ end
48
+
49
+ # RCov Target --------------------------------------------------------
50
+
51
+ require 'rcov/rcovtask'
52
+
53
+ Rcov::RcovTask.new do |t|
54
+ t.libs << "test"
55
+ t.rcov_opts = ['-xRakefile', '-xrakefile', '-xpublish.rf', '--text-report']
56
+ t.test_files = FileList['test/test*.rb']
57
+ t.verbose = true
58
+ end
59
+
42
60
  # RDoc Target --------------------------------------------------------
43
61
 
44
62
  task :rdoc => ["README"]
@@ -0,0 +1,86 @@
1
+ = FlexMock 0.5.0 Released
2
+
3
+ FlexMock is a flexible mocking library for use in Ruby's Test::Unit
4
+ test framework. Version 0.5.1 is a minor bug fix release.
5
+
6
+ == New in 0.5.1
7
+
8
+ * Version 0.5.1 fixes a problem that caused some older versions of
9
+ RCov to core dump.
10
+
11
+ == What is FlexMock?
12
+
13
+ FlexMock is a flexible Ruby mocking library that works with Ruby's
14
+ Test::Unit framework to create easy to use mocks.
15
+
16
+ === Features
17
+
18
+ * Easy integration with Test::Unit. Mocks created with the flexmock
19
+ method are automatically verified at the end of the test.
20
+
21
+ * A fluent interface that allows mock behavior to be specified very
22
+ easily.
23
+
24
+ * A "record mode" where an existing implementation can record its
25
+ interaction with a mock for later validation against a new
26
+ implementation.
27
+
28
+ * Easy mocking of individual methods in existing, non-mock objects.
29
+
30
+ === Example
31
+
32
+ Suppose you had a Dog object that wagged a tail when it was happy.
33
+ Something like this:
34
+
35
+ class Dog
36
+ def initialize(a_tail)
37
+ @tail = a_tail
38
+ end
39
+ def happy
40
+ @tail.wag
41
+ end
42
+ end
43
+
44
+ To test the +Dog+ class without a real +Tail+ object (perhaps because
45
+ real +Tail+ objects activate servos in some robotic equipment), you
46
+ can do something like this:
47
+
48
+ require 'test/unit'
49
+ require 'flexmock'
50
+
51
+ class TestDog < Test::Unit::TestCase
52
+ include FlexMock::TestCase
53
+
54
+ def test_dog_wags_tail_when_happy
55
+ tail = flexmock("tail")
56
+ tail.should_receive(:wag).once
57
+ dog = Dog.new(tail)
58
+ dog.happy
59
+ end
60
+ end
61
+
62
+ FlexMock will automatically verify that the mocked tail object
63
+ received the message +wag+ exactly one time. If it doesn't, the test
64
+ will not pass.
65
+
66
+ See the FlexMock documentation at
67
+ http://onestepback.org/software/flexmock for details on specifying
68
+ arguments and return values on mocked methods, as well as a simple
69
+ technique for mocking tail objects when the Dog class creates the tail
70
+ objects directly.
71
+
72
+ == Availability
73
+
74
+ You can make sure you have the latest version with a quick RubyGems command:
75
+
76
+ gem install flexmock (you may need root/admin privileges)
77
+
78
+ Otherwise, you can get it from the more traditional places:
79
+
80
+ Download:: http://rubyforge.org/project/showfiles.php?group_id=170
81
+
82
+ You will find documentation at:
83
+ http://onestepback.org/software/flexmock/
84
+
85
+ -- Jim Weirich
86
+
data/lib/flexmock.rb CHANGED
@@ -66,7 +66,7 @@ class FlexMock
66
66
  @ignore_missing = false
67
67
  @verified = false
68
68
  end
69
-
69
+
70
70
  # Handle all messages denoted by +sym+ by calling the given block
71
71
  # and passing any parameters to the block. If we know exactly how
72
72
  # many calls are to be made to a particular method, we may check
@@ -155,10 +155,14 @@ class FlexMock
155
155
  # method_missing. This method defines a singleton method on the
156
156
  # mock to explicitly invoke the method_missing logic.
157
157
  def override_existing_method(sym)
158
- sclass.class_eval "def #{sym}(*args, &block) method_missing(:#{sym}, *args, &block) end"
158
+ sclass.class_eval <<-EOS
159
+ def #{sym}(*args, &block)
160
+ method_missing(:#{sym}, *args, &block)
161
+ end
162
+ EOS
159
163
  end
160
164
  private :override_existing_method
161
-
165
+
162
166
  # Return the singleton class of the mock object.
163
167
  def sclass
164
168
  class << self; self; end
@@ -208,7 +212,7 @@ class FlexMock
208
212
  #
209
213
  # NOTE: If you include FlexMock::TestCase into your test case
210
214
  # file, you can create mocks that will be automatically verified in
211
- # the test teardown by using the +flexmock+ method.
215
+ # the test teardown by using the +flexmock+ method.
212
216
  #
213
217
  def use(*names)
214
218
  names = ["unknown"] if names.empty?
@@ -223,7 +227,7 @@ class FlexMock
223
227
  mock.mock_verify unless got_exception
224
228
  end
225
229
  end
226
-
230
+
227
231
  # Class method to format a method name and argument list as a nice
228
232
  # looking string.
229
233
  def format_args(sym, args)
@@ -233,7 +237,7 @@ class FlexMock
233
237
  "#{sym}(*args)"
234
238
  end
235
239
  end
236
-
240
+
237
241
  # Check will assert the block returns true. If it doesn't, an
238
242
  # assertion failure is triggered with the given message.
239
243
  def check(msg, &block)
@@ -248,9 +252,9 @@ class FlexMock
248
252
  def mock_wrap(&block)
249
253
  yield
250
254
  rescue Test::Unit::AssertionFailedError => ex
251
- raise Test::Unit::AssertionFailedError,
252
- "in mock '#{@mock_name}': #{ex.message}",
253
- ex.backtrace
255
+ raise Test::Unit::AssertionFailedError,
256
+ "in mock '#{@mock_name}': #{ex.message}",
257
+ ex.backtrace
254
258
  end
255
259
 
256
260
  ####################################################################
@@ -297,18 +301,12 @@ class FlexMock
297
301
  # criteria.
298
302
  def call(*args)
299
303
  exp = @expectations.find { |e| e.match_args(args) && e.eligible? } ||
300
- @expectations.find { |e| e.match_args(args) } ||
301
- @expectations.find { |e| e.expected_args.nil? }
304
+ @expectations.find { |e| e.match_args(args) }
302
305
  FlexMock.check("no matching handler found for " +
303
306
  FlexMock.format_args(@sym, args)) { ! exp.nil? }
304
307
  exp.verify_call(*args)
305
308
  end
306
309
 
307
- # Same as call.
308
- def [](*args)
309
- call(*args)
310
- end
311
-
312
310
  # Append an expectation to this director.
313
311
  def <<(expectation)
314
312
  @expectations << expectation
@@ -333,7 +331,7 @@ class FlexMock
333
331
  "ANY"
334
332
  end
335
333
  end
336
-
334
+
337
335
  ####################################################################
338
336
  # Match only things that are equal.
339
337
  class EqualMatcher
@@ -347,7 +345,7 @@ class FlexMock
347
345
  "==(#{@obj.inspect})"
348
346
  end
349
347
  end
350
-
348
+
351
349
  ANY = AnyMatcher.new
352
350
 
353
351
  ####################################################################
@@ -415,8 +413,8 @@ class FlexMock
415
413
  # Validate that the method expectation was called exactly +n+
416
414
  # times.
417
415
  def validate(n)
418
- assert_equal @limit, n,
419
- "method '#{@exp}' called incorrect number of times"
416
+ assert_equal @limit, n,
417
+ "method '#{@exp}' called incorrect number of times"
420
418
  end
421
419
  end
422
420
 
@@ -428,8 +426,8 @@ class FlexMock
428
426
  # times.
429
427
  def validate(n)
430
428
  assert n >= @limit,
431
- "Method '#{@exp}' should be called at least #{@limit} times,\n" +
432
- "only called #{n} times"
429
+ "Method '#{@exp}' should be called at least #{@limit} times,\n" +
430
+ "only called #{n} times"
433
431
  end
434
432
 
435
433
  # If the expectation has been called +n+ times, is it still
@@ -448,8 +446,8 @@ class FlexMock
448
446
  # Validate the method expectation was called at least +n+ times.
449
447
  def validate(n)
450
448
  assert n <= @limit,
451
- "Method '#{@exp}' should be called at most #{@limit} times,\n" +
452
- "only called #{n} times"
449
+ "Method '#{@exp}' should be called at most #{@limit} times,\n" +
450
+ "only called #{n} times"
453
451
  end
454
452
  end
455
453
 
@@ -501,11 +499,11 @@ class FlexMock
501
499
  @count_validators.all? { |v| v.eligible?(@actual_count) }
502
500
  end
503
501
 
504
- # Validate that the order
502
+ # Validate that the order
505
503
  def validate_order
506
504
  return if @order_number.nil?
507
505
  FlexMock.check("method #{to_s} called out of order " +
508
- "(expected order #{@order_number}, was #{@mock.mock_current_order})") {
506
+ "(expected order #{@order_number}, was #{@mock.mock_current_order})") {
509
507
  @order_number >= @mock.mock_current_order
510
508
  }
511
509
  @mock.mock_current_order = @order_number
@@ -523,7 +521,9 @@ class FlexMock
523
521
  # Does the argument list match this expectation's argument
524
522
  # specification.
525
523
  def match_args(args)
526
- return false if @expected_args.nil?
524
+ # TODO: Rethink this:
525
+ # return false if @expected_args.nil?
526
+ return true if @expected_args.nil?
527
527
  return false if args.size != @expected_args.size
528
528
  (0...args.size).all? { |i| match_arg(@expected_args[i], args[i]) }
529
529
  end
@@ -531,8 +531,8 @@ class FlexMock
531
531
  # Does the expected argument match the corresponding actual value.
532
532
  def match_arg(expected, actual)
533
533
  expected === actual ||
534
- expected == actual ||
535
- ( Regexp === expected && expected === actual.to_s )
534
+ expected == actual ||
535
+ ( Regexp === expected && expected === actual.to_s )
536
536
  end
537
537
 
538
538
  # Declare that the method should expect the given argument list.
@@ -558,15 +558,15 @@ class FlexMock
558
558
  #
559
559
  # * If a single value is given, it will be returned for all matching
560
560
  # calls.
561
- # * If multiple values are given, each value will be returned in turn for
561
+ # * If multiple values are given, each value will be returned in turn for
562
562
  # each successive call. If the number of matching calls is greater
563
- # than the number of values, the last value will be returned for
563
+ # than the number of values, the last value will be returned for
564
564
  # the extra matching calls.
565
- # * If a block is given, it is evaluated on each call and its
566
- # value is returned.
567
- #
565
+ # * If a block is given, it is evaluated on each call and its
566
+ # value is returned.
567
+ #
568
568
  # For example:
569
- #
569
+ #
570
570
  # mock.should_receive(:f).returns(12) # returns 12
571
571
  #
572
572
  # mock.should_receive(:f).with(String). # returns an
@@ -575,9 +575,12 @@ class FlexMock
575
575
  # +and_return+ is an alias for +returns+.
576
576
  #
577
577
  def returns(*args, &block)
578
- @return_block = block_given? ?
579
- block :
580
- lambda { args.size == 1 ? args.first : args.shift }
578
+ @return_block =
579
+ if block_given?
580
+ block
581
+ else
582
+ lambda { args.size == 1 ? args.first : args.shift }
583
+ end
581
584
  self
582
585
  end
583
586
  alias :and_return :returns # :nodoc:
@@ -725,7 +728,7 @@ class FlexMock
725
728
  # given arguments.
726
729
  def method_missing(sym, *args, &block)
727
730
  expectation = @mock.should_receive(sym).and_return(&block)
728
- if @strict
731
+ if strict?
729
732
  args = args.collect { |arg| eq(arg) }
730
733
  expectation.with(*args).ordered.once
731
734
  else
@@ -734,7 +737,7 @@ class FlexMock
734
737
  expectation
735
738
  end
736
739
  end
737
-
740
+
738
741
  ####################################################################
739
742
  # Test::Unit::TestCase Integration.
740
743
  #
@@ -757,7 +760,7 @@ class FlexMock
757
760
  super
758
761
  flexmock_teardown
759
762
  end
760
-
763
+
761
764
  # Do the flexmock specific teardown stuff.
762
765
  def flexmock_teardown
763
766
  @flexmock_created_mocks ||= []
@@ -770,6 +773,7 @@ class FlexMock
770
773
  @flexmock_created_mocks.each do |m|
771
774
  m.mock_teardown
772
775
  end
776
+ @flexmock_created_mocks = []
773
777
  @flexmock_interceptors ||= []
774
778
  @flexmock_interceptors.each do |i|
775
779
  i.restore
@@ -788,10 +792,10 @@ class FlexMock
788
792
  flexmock_remember(mock)
789
793
  mock
790
794
  end
791
-
795
+
792
796
  # Stub the given object by overriding the behavior of individual
793
797
  # methods. The stub object returned will respond to the
794
- # +should_receive+ method, just like normal stubs.
798
+ # +should_receive+ method, just like normal stubs.
795
799
  #
796
800
  # If a block is given, then the stub object is passed to the block
797
801
  # and may be configured within the block.
@@ -815,7 +819,7 @@ class FlexMock
815
819
  yield(proxy) if block_given?
816
820
  flexmock_remember(proxy)
817
821
  end
818
-
822
+
819
823
  # Intercept the named class in the target class for the duration
820
824
  # of the test. Class interception is very simple-minded and has a
821
825
  # number of restrictions. First, the intercepted class must be
@@ -838,9 +842,9 @@ class FlexMock
838
842
  @flexmock_interceptors << result
839
843
  result
840
844
  end
841
-
845
+
842
846
  private
843
-
847
+
844
848
  def flexmock_remember(mocking_object)
845
849
  @flexmock_created_mocks ||= []
846
850
  @flexmock_created_mocks << mocking_object
@@ -868,11 +872,12 @@ class FlexMock
868
872
 
869
873
  # Intercept this class in the class to be tested.
870
874
  def intercept(intercepted_class)
875
+ self.class.show_intercept_warning
871
876
  @intercepted = intercepted_class
872
877
  update
873
878
  self
874
879
  end
875
-
880
+
876
881
  # Define the class number test that will receive the
877
882
  # interceptioned definition.
878
883
  def in(target_class)
@@ -893,16 +898,16 @@ class FlexMock
893
898
  def restore
894
899
  @proxy.proxied_class = @restore_class if @proxy
895
900
  end
896
-
901
+
897
902
  private
898
-
903
+
899
904
  # Update the interception if the definition is complete.
900
905
  def update
901
906
  if complete?
902
907
  do_interception
903
908
  end
904
909
  end
905
-
910
+
906
911
  # Is the interception definition complete. In other words, are
907
912
  # all three actors defined?
908
913
  def complete?
@@ -949,6 +954,17 @@ class FlexMock
949
954
  raise BadInterceptionError, "in #{where} class #{name}"
950
955
  end
951
956
  end
957
+
958
+ @shown_warning = false
959
+
960
+ class << self
961
+ def show_intercept_warning
962
+ unless @shown_warning
963
+ @shown_warning = true
964
+ $stderr.puts "FlexMock Class Interception is deprecated and will be removed in future versions."
965
+ end
966
+ end
967
+ end
952
968
  end
953
969
 
954
970
  ####################################################################
@@ -964,21 +980,21 @@ class FlexMock
964
980
  @proxied_class.__send__(sym, *args, &block)
965
981
  end
966
982
  end
967
-
983
+
968
984
  ####################################################################
969
985
  # StubProxy is used to mate the mock framework to an existing
970
986
  # object. The object is "enhanced" with a reference to a mock
971
- # object (stored in <tt>@flexmock_mock</tt>). When the
972
- # +should_receive+ method is sent to the proxy, it overrides the
973
- # existing object's method by creating singleton method that
987
+ # object (stored in <tt>@flexmock_mock</tt>). When the
988
+ # +should_receive+ method is sent to the proxy, it overrides the
989
+ # existing object's method by creating singleton method that
974
990
  # forwards to the mock. When testing is complete, StubProxy
975
- # will erase the mocking infrastructure from the object being
976
- # stubbed (e.g. remove instance variables and mock singleton
991
+ # will erase the mocking infrastructure from the object being
992
+ # stubbed (e.g. remove instance variables and mock singleton
977
993
  # methods).
978
994
  #
979
995
  class StubProxy
980
996
  attr_reader :mock
981
-
997
+
982
998
  # Initialize a StubProxy object.
983
999
  def initialize(obj, mock)
984
1000
  @obj = obj
@@ -986,8 +1002,8 @@ class FlexMock
986
1002
  @method_definitions = {}
987
1003
  @methods_proxied = []
988
1004
  end
989
-
990
- # Stub out the given method in the existing object and then let the
1005
+
1006
+ # Stub out the given method in the existing object and then let the
991
1007
  # mock object handle should_receive.
992
1008
  def should_receive(method_name)
993
1009
  method_name = method_name.to_sym
@@ -997,34 +1013,52 @@ class FlexMock
997
1013
  end
998
1014
  @mock.should_receive(method_name)
999
1015
  end
1000
-
1001
- # any_instance is a short cut method for overriding the behavior of any
1002
- # instance created via a stubbed class object.
1003
- def any_instance(&block)
1004
- fail ArgumentError, "any_instance requires a Class to stub" unless Class === @obj
1005
- self.should_receive(:new).and_return { |*args|
1006
- new_obj = invoke_original(:new, args)
1007
- mock = mock_container.flexstub(new_obj)
1008
- block.call(mock)
1009
- new_obj
1010
- }
1016
+
1017
+ # new_instances is a short cut method for overriding the behavior of any
1018
+ # new instances created via a stubbed class object.
1019
+ #
1020
+ # By default, new_instances will stub the behaviour of the :new and
1021
+ # :allocate methods. If you wish to stub a different set of class
1022
+ # methods, just pass a list of symbols to as arguments.
1023
+ #
1024
+ # For example, to stub only objects created by :make (and not :new
1025
+ # or :allocate), use:
1026
+ #
1027
+ # flexstub(ClassName).new_instances(:make) do |obj|
1028
+ # obj.should_receive(...)
1029
+ # end
1030
+ #
1031
+ def new_instances(*allocators, &block)
1032
+ fail ArgumentError, "new_instances requires a Class to stub" unless Class === @obj
1033
+ fail ArgumentError, "new_instances requires a block" unless block_given?
1034
+ allocators = [:new, :allocate] if allocators.empty?
1035
+ allocators.each do |m|
1036
+ self.should_receive(m).and_return { |*args|
1037
+ new_obj = invoke_original(m, args)
1038
+ mock = mock_container.flexstub(new_obj)
1039
+ block.call(mock)
1040
+ new_obj
1041
+ }
1042
+ end
1011
1043
  nil
1012
1044
  end
1013
1045
 
1014
- # Invoke the original definition of method on the object supported by
1046
+ # any_instance is present for backwards compatibility with version 0.5.0.
1047
+ # @deprecated
1048
+ def any_instance(&block)
1049
+ $stderr.puts "any_instance is deprecated, use new_instances instead."
1050
+ new_instances(&block)
1051
+ end
1052
+
1053
+ # Invoke the original definition of method on the object supported by
1015
1054
  # the stub.
1016
1055
  def invoke_original(method, args)
1017
- method_proc = @method_definitions[:new]
1018
- block = nil
1019
- if Proc === args.last
1020
- block = args.last
1021
- args = args[0...-1]
1022
- end
1023
- method_proc.call(*args, &block)
1056
+ method_proc = @method_definitions[method]
1057
+ method_proc.call(*args)
1024
1058
  end
1025
1059
  private :invoke_original
1026
1060
 
1027
- # Verify that the mock has been properly called. After verification,
1061
+ # Verify that the mock has been properly called. After verification,
1028
1062
  # detach the mocking infrastructure from the existing object.
1029
1063
  def mock_verify
1030
1064
  @mock.mock_verify
@@ -1041,14 +1075,14 @@ class FlexMock
1041
1075
  @obj = nil
1042
1076
  end
1043
1077
  end
1044
-
1045
- # Return the container for this mocking object. Returns nil if the
1078
+
1079
+ # Return the container for this mocking object. Returns nil if the
1046
1080
  # mock is not in a container. Mock containers make sure that mock objects
1047
1081
  # inside the container are torn down at the end of a test
1048
1082
  def mock_container
1049
1083
  @mock.mock_container
1050
1084
  end
1051
-
1085
+
1052
1086
  # Set the container for this mock object.
1053
1087
  def mock_container=(container)
1054
1088
  @mock.mock_container = container
@@ -1074,7 +1108,23 @@ class FlexMock
1074
1108
  # not a singleton, all we need to do is override it with our own
1075
1109
  # singleton.
1076
1110
  def hide_existing_method(method_name)
1077
- @method_definitions[method_name] = @obj.method(method_name) if @obj.respond_to?(method_name)
1111
+ if @obj.respond_to?(method_name)
1112
+ new_alias = new_name(method_name)
1113
+ unless @obj.respond_to?(new_alias)
1114
+ sclass.class_eval do
1115
+ alias_method(new_alias, method_name)
1116
+ end
1117
+ end
1118
+ my_object = @obj
1119
+ @method_definitions[method_name] = Proc.new { |*args|
1120
+ block = nil
1121
+ if Proc === args.last
1122
+ block = args.last
1123
+ args = args[0...-1]
1124
+ end
1125
+ my_object.send(new_alias, *args, &block)
1126
+ }
1127
+ end
1078
1128
  remove_current_method(method_name) if singleton?(method_name)
1079
1129
  define_proxy_method(method_name)
1080
1130
  end
@@ -1084,9 +1134,7 @@ class FlexMock
1084
1134
  # being mocked.
1085
1135
  def define_proxy_method(method_name)
1086
1136
  sclass.class_eval %{
1087
- def #{method_name}(*args, &block)
1088
- @flexmock_proxy.mock.#{method_name}(*args, &block)
1089
- end
1137
+ def #{method_name}(*args, &block) @flexmock_proxy.mock.#{method_name}(*args, &block) end
1090
1138
  }
1091
1139
  end
1092
1140
 
@@ -1095,9 +1143,10 @@ class FlexMock
1095
1143
  def restore_original_definition(method_name)
1096
1144
  method_def = @method_definitions[method_name]
1097
1145
  if method_def
1098
- sclass.class_eval {
1099
- define_method(method_name, &method_def)
1100
- }
1146
+ the_alias = new_name(method_name)
1147
+ sclass.class_eval do
1148
+ alias_method(method_name, the_alias)
1149
+ end
1101
1150
  end
1102
1151
  end
1103
1152
 
@@ -1111,6 +1160,11 @@ class FlexMock
1111
1160
  def detached?
1112
1161
  @obj.nil?
1113
1162
  end
1114
-
1163
+
1164
+ # Generate a name to be used to alias the original behavior.
1165
+ def new_name(old_name)
1166
+ "flexmock_original_behavior_for_#{old_name}"
1167
+ end
1168
+
1115
1169
  end
1116
1170
  end
@@ -22,6 +22,9 @@ class TestStubbingOnNew < Test::Unit::TestCase
22
22
  def wag
23
23
  :tail
24
24
  end
25
+ def self.make
26
+ new
27
+ end
25
28
  end
26
29
 
27
30
  class Cat
@@ -43,25 +46,42 @@ class TestStubbingOnNew < Test::Unit::TestCase
43
46
  :unstubbed
44
47
  end
45
48
  end
49
+
50
+ def test_new_instances_requires_block
51
+ ex = assert_raise(ArgumentError) {
52
+ flexstub(Dog).new_instances
53
+ }
54
+ end
46
55
 
47
- def test_any_instance_allows_stubbing_of_existing_methods
48
- flexstub(Dog).any_instance do |obj|
56
+ def test_new_instances_allows_stubbing_of_existing_methods
57
+ flexstub(Dog).new_instances do |obj|
49
58
  obj.should_receive(:bark).and_return(:whimper)
50
59
  end
51
60
  m = Dog.new
52
61
  assert_equal :whimper, m.bark
53
62
  end
54
63
 
55
- def test_any_instance_stubs_still_have_existing_methods
56
- flexstub(Dog).any_instance do |obj|
64
+ def test_any_instance_still_works_for_backwards_compatibility
65
+ message = redirect_error {
66
+ flexstub(Dog).any_instance do |obj|
67
+ obj.should_receive(:bark).and_return(:whimper)
68
+ assert_match(/deprecated/, message)
69
+ end
70
+ }
71
+ m = Dog.new
72
+ assert_equal :whimper, m.bark
73
+ end
74
+
75
+ def test_new_instances_stubs_still_have_existing_methods
76
+ flexstub(Dog).new_instances do |obj|
57
77
  obj.should_receive(:bark).and_return(:whimper)
58
78
  end
59
79
  m = Dog.new
60
80
  assert_equal :tail, m.wag
61
81
  end
62
82
 
63
- def test_any_instance_will_pass_args_to_new
64
- flexstub(Cat).any_instance do |obj|
83
+ def test_new_instances_will_pass_args_to_new
84
+ flexstub(Cat).new_instances do |obj|
65
85
  obj.should_receive(:meow).and_return(:scratch)
66
86
  end
67
87
  x = :not_called
@@ -71,8 +91,23 @@ class TestStubbingOnNew < Test::Unit::TestCase
71
91
  assert_equal :called, x
72
92
  end
73
93
 
74
- def test_any_instance_stub_verification_happens_on_teardown
75
- flexstub(Dog).any_instance do |obj|
94
+ # Some versions of the software had problems invoking the block after a
95
+ # second stubbing.
96
+ def test_new_gets_block_after_restubbing
97
+ flexstub(Cat).new_instances { }
98
+ x = :not_called
99
+ m = Cat.new("Fido") { x = :called }
100
+ assert_equal :called, x
101
+ flexmock_teardown
102
+
103
+ flexstub(Cat).new_instances { }
104
+ x = :not_called
105
+ m = Cat.new("Fido") { x = :called }
106
+ assert_equal :called, x
107
+ end
108
+
109
+ def test_new_instances_stub_verification_happens_on_teardown
110
+ flexstub(Dog).new_instances do |obj|
76
111
  obj.should_receive(:bark).once.and_return(nil)
77
112
  end
78
113
 
@@ -81,14 +116,54 @@ class TestStubbingOnNew < Test::Unit::TestCase
81
116
  assert_match(/method 'bark\(.*\)' called incorrect number of times/, ex.message)
82
117
  end
83
118
 
84
- def test_any_instance_reports_error_on_non_classes
119
+ def test_new_instances_reports_error_on_non_classes
85
120
  ex = assert_raise(ArgumentError) {
86
- flexstub(Dog.new).any_instance do |obj|
121
+ flexstub(Dog.new).new_instances do |obj|
87
122
  obj.should_receive(:hi)
88
123
  end
89
124
  }
90
125
  assert_match(/Class/, ex.message)
91
- assert_match(/any_instance/, ex.message)
126
+ assert_match(/new_instances/, ex.message)
127
+ end
128
+
129
+ def test_can_stub_objects_created_with_allocate_instead_of_new
130
+ flexstub(Dog).new_instances do |obj|
131
+ obj.should_receive(:bark).and_return(:whimper)
132
+ end
133
+ m = Dog.allocate
134
+ assert_equal :whimper, m.bark
135
+ end
136
+
137
+ def test_can_stub_objects_created_with_arbitrary_class_methods
138
+ flexstub(Dog).new_instances(:make) do |obj|
139
+ obj.should_receive(:bark).and_return(:whimper)
140
+ end
141
+ assert_equal :whimper, Dog.make.bark
142
+ end
143
+
144
+ def test_stubbing_arbitrary_class_methods_leaves_new_alone
145
+ flexstub(Dog).new_instances(:make) do |obj|
146
+ obj.should_receive(:bark).and_return(:whimper)
147
+ end
148
+ assert_equal :woof, Dog.new.bark
149
+ end
150
+
151
+ def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new
152
+ counter = 0
153
+ flexstub(Dog).new_instances do |obj|
154
+ counter += 1
155
+ end
156
+ Dog.new
157
+ assert_equal 1, counter
158
+ end
159
+
160
+ def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_allocate
161
+ counter = 0
162
+ flexstub(Dog).new_instances do |obj|
163
+ counter += 1
164
+ end
165
+ Dog.allocate
166
+ assert_equal 1, counter
92
167
  end
93
168
 
94
169
  # Current behavior does not install stubs into the block passed to new.
@@ -96,7 +171,7 @@ class TestStubbingOnNew < Test::Unit::TestCase
96
171
  # moment, we assure that they are not stubbed, but I am willing to change
97
172
  # this in the future.
98
173
  def test_blocks_on_new_do_not_have_stubs_installed
99
- flexstub(Connection).any_instance do |new_con|
174
+ flexstub(Connection).new_instances do |new_con|
100
175
  new_con.should_receive(:post).and_return {
101
176
  :stubbed
102
177
  }
@@ -108,4 +183,17 @@ class TestStubbingOnNew < Test::Unit::TestCase
108
183
  end
109
184
  assert block_run
110
185
  end
186
+
187
+ def redirect_error
188
+ require 'stringio'
189
+ old_err = $stderr
190
+ $stderr = StringIO.new
191
+ yield
192
+ $stderr.string
193
+ rescue
194
+ $stderr = old_err
195
+ end
196
+ private :redirect_error
111
197
  end
198
+
199
+
data/test/test_mock.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2006 by Jim Weirich (jweirich@one.net).
4
+ # Copyright 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
5
  # All rights reserved.
6
6
 
7
7
  # Permission is granted for use, copying, modification, distribution,
@@ -25,6 +25,13 @@ end
25
25
 
26
26
  class TestFlexMockShoulds < Test::Unit::TestCase
27
27
 
28
+ # Expected error messages on failures
29
+ COUNT_ERROR_MESSAGE = /\bcalled\s+incorrect\s+number\s+of\s+times\b/
30
+ NO_MATCH_ERROR_MESSAGE = /\bno\s+matching\s+handler\b/
31
+ AT_LEAST_ERROR_MESSAGE = /\bshould\s+be\s+called\s+at\s+least\b/
32
+ AT_MOST_ERROR_MESSAGE = /\bshould\s+be\s+called\s+at\s+most\b/
33
+ OUT_OF_ORDER_ERROR_MESSAGE = /\bcalled\s+out\s+of\s+order\b/
34
+
28
35
  def test_defaults
29
36
  FlexMock.use do |m|
30
37
  m.should_receive(:hi)
@@ -87,10 +94,10 @@ class TestFlexMockShoulds < Test::Unit::TestCase
87
94
  end
88
95
 
89
96
  def test__with_no_args_but_with_args
90
- ex = assert_failure do
97
+ ex = assert_failure(NO_MATCH_ERROR_MESSAGE) do
91
98
  FlexMock.use do |m|
92
- m.should_receive(:hi).with_no_args
93
- m.hi(1)
99
+ m.should_receive(:hi).with_no_args
100
+ m.hi(1)
94
101
  end
95
102
  end
96
103
  end
@@ -187,8 +194,8 @@ class TestFlexMockShoulds < Test::Unit::TestCase
187
194
  def test_arg_matching_with_no_match
188
195
  FlexMock.use do |m|
189
196
  m.should_receive(:hi).with(1).returns(10)
190
- assert_failure {
191
- assert_equal 20, m.hi(2)
197
+ assert_failure(NO_MATCH_ERROR_MESSAGE) {
198
+ assert_equal 20, m.hi(2)
192
199
  }
193
200
  end
194
201
  end
@@ -196,8 +203,8 @@ class TestFlexMockShoulds < Test::Unit::TestCase
196
203
  def test_arg_matching_with_string_doesnt_over_match
197
204
  FlexMock.use do |m|
198
205
  m.should_receive(:hi).with(String).returns(20)
199
- assert_failure {
200
- m.hi(1.0)
206
+ assert_failure(NO_MATCH_ERROR_MESSAGE) {
207
+ m.hi(1.0)
201
208
  }
202
209
  end
203
210
  end
@@ -205,8 +212,8 @@ class TestFlexMockShoulds < Test::Unit::TestCase
205
212
  def test_block_arg_given_to_no_args
206
213
  FlexMock.use do |m|
207
214
  m.should_receive(:hi).with_no_args.returns(20)
208
- assert_failure {
209
- m.hi { 1 }
215
+ assert_failure(NO_MATCH_ERROR_MESSAGE) {
216
+ m.hi { 1 }
210
217
  }
211
218
  end
212
219
  end
@@ -245,10 +252,10 @@ class TestFlexMockShoulds < Test::Unit::TestCase
245
252
  end
246
253
 
247
254
  def test_never_and_called_once
248
- ex = assert_failure do
255
+ ex = assert_failure(COUNT_ERROR_MESSAGE) do
249
256
  FlexMock.use do |m|
250
- m.should_receive(:hi).with(1).never
251
- m.hi(1)
257
+ m.should_receive(:hi).with(1).never
258
+ m.hi(1)
252
259
  end
253
260
  end
254
261
  end
@@ -261,19 +268,19 @@ class TestFlexMockShoulds < Test::Unit::TestCase
261
268
  end
262
269
 
263
270
  def test_once_but_never_called
264
- ex = assert_failure do
271
+ ex = assert_failure(COUNT_ERROR_MESSAGE) do
265
272
  FlexMock.use do |m|
266
- m.should_receive(:hi).with(1).returns(10).once
273
+ m.should_receive(:hi).with(1).returns(10).once
267
274
  end
268
275
  end
269
276
  end
270
277
 
271
278
  def test_once_but_called_twice
272
- ex = assert_failure do
279
+ ex = assert_failure(COUNT_ERROR_MESSAGE) do
273
280
  FlexMock.use do |m|
274
- m.should_receive(:hi).with(1).returns(10).once
275
- m.hi(1)
276
- m.hi(1)
281
+ m.should_receive(:hi).with(1).returns(10).once
282
+ m.hi(1)
283
+ m.hi(1)
277
284
  end
278
285
  end
279
286
  end
@@ -321,9 +328,9 @@ class TestFlexMockShoulds < Test::Unit::TestCase
321
328
  end
322
329
 
323
330
  def test_at_least_but_never_called
324
- ex = assert_failure do
331
+ ex = assert_failure(AT_LEAST_ERROR_MESSAGE) do
325
332
  FlexMock.use do |m|
326
- m.should_receive(:hi).with(1).returns(10).at_least.once
333
+ m.should_receive(:hi).with(1).returns(10).at_least.once
327
334
  end
328
335
  end
329
336
  end
@@ -337,11 +344,11 @@ class TestFlexMockShoulds < Test::Unit::TestCase
337
344
  end
338
345
 
339
346
  def test_at_least_and_exact
340
- ex = assert_failure do
347
+ ex = assert_failure(COUNT_ERROR_MESSAGE) do
341
348
  FlexMock.use do |m|
342
- m.should_receive(:hi).with(1).returns(10).at_least.once.once
343
- m.hi(1)
344
- m.hi(1)
349
+ m.should_receive(:hi).with(1).returns(10).at_least.once.once
350
+ m.hi(1)
351
+ m.hi(1)
345
352
  end
346
353
  end
347
354
  end
@@ -360,19 +367,19 @@ class TestFlexMockShoulds < Test::Unit::TestCase
360
367
  end
361
368
 
362
369
  def test_at_most_called_twice
363
- ex = assert_failure do
370
+ ex = assert_failure(AT_MOST_ERROR_MESSAGE) do
364
371
  FlexMock.use do |m|
365
- m.should_receive(:hi).with(1).returns(10).at_most.once
366
- m.hi(1)
367
- m.hi(1)
372
+ m.should_receive(:hi).with(1).returns(10).at_most.once
373
+ m.hi(1)
374
+ m.hi(1)
368
375
  end
369
376
  end
370
377
  end
371
378
 
372
379
  def test_at_most_and_at_least_called_never
373
- ex = assert_failure do
380
+ ex = assert_failure(AT_LEAST_ERROR_MESSAGE) do
374
381
  FlexMock.use do |m|
375
- m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
382
+ m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
376
383
  end
377
384
  end
378
385
  end
@@ -393,12 +400,12 @@ class TestFlexMockShoulds < Test::Unit::TestCase
393
400
  end
394
401
 
395
402
  def test_at_most_and_at_least_called_three_times
396
- ex = assert_failure do
403
+ ex = assert_failure(AT_MOST_ERROR_MESSAGE) do
397
404
  FlexMock.use do |m|
398
- m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
399
- m.hi(1)
400
- m.hi(1)
401
- m.hi(1)
405
+ m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice
406
+ m.hi(1)
407
+ m.hi(1)
408
+ m.hi(1)
402
409
  end
403
410
  end
404
411
  end
@@ -416,18 +423,19 @@ class TestFlexMockShoulds < Test::Unit::TestCase
416
423
  end
417
424
 
418
425
  def test_call_counts_only_apply_to_matching_args_with_mismatch
419
- ex = assert_failure do
426
+ ex = assert_failure(COUNT_ERROR_MESSAGE) do
420
427
  FlexMock.use do |m|
421
- m.should_receive(:hi).with(1).once
422
- m.should_receive(:hi).with(2).twice
423
- m.should_receive(:hi).with(3)
424
- m.should_receive(:lo)
425
- m.hi(1)
426
- m.hi(2)
427
- m.lo
428
- 20.times { m.hi(3) }
428
+ m.should_receive(:hi).with(1).once
429
+ m.should_receive(:hi).with(2).twice
430
+ m.should_receive(:hi).with(3)
431
+ m.should_receive(:lo)
432
+ m.hi(1)
433
+ m.hi(2)
434
+ m.lo
435
+ 20.times { m.hi(3) }
429
436
  end
430
437
  end
438
+ assert_match(/hi\(2\)/, ex.message)
431
439
  end
432
440
 
433
441
  def test_ordered_calls_in_order
@@ -441,13 +449,13 @@ class TestFlexMockShoulds < Test::Unit::TestCase
441
449
  end
442
450
 
443
451
  def test_ordered_calls_out_of_order
444
- ex = assert_failure do
452
+ ex = assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
445
453
  FlexMock.use 'm' do |m|
446
- m.should_receive(:hi).ordered
447
- m.should_receive(:lo).ordered
448
-
449
- m.lo
450
- m.hi
454
+ m.should_receive(:hi).ordered
455
+ m.should_receive(:lo).ordered
456
+
457
+ m.lo
458
+ m.hi
451
459
  end
452
460
  end
453
461
  end
@@ -463,13 +471,13 @@ class TestFlexMockShoulds < Test::Unit::TestCase
463
471
  end
464
472
 
465
473
  def test_order_calls_with_different_arg_lists_and_out_of_order
466
- ex = assert_failure do
474
+ ex = assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
467
475
  FlexMock.use 'm' do |m|
468
- m.should_receive(:hi).with("one").ordered
469
- m.should_receive(:hi).with("two").ordered
470
-
471
- m.hi("two")
472
- m.hi("one")
476
+ m.should_receive(:hi).with("one").ordered
477
+ m.should_receive(:hi).with("two").ordered
478
+
479
+ m.hi("two")
480
+ m.hi("one")
473
481
  end
474
482
  end
475
483
  end
@@ -500,11 +508,11 @@ class TestFlexMockShoulds < Test::Unit::TestCase
500
508
  end
501
509
  end
502
510
 
503
- def test_grouped_ordering
511
+ def test_grouped_ordering_with_numbers
504
512
  FlexMock.use 'm' do |m|
505
- m.should_receive(:start).ordered(:start_group)
506
- m.should_receive(:flip).ordered(:flip_flop_group)
507
- m.should_receive(:flop).ordered(:flip_flop_group)
513
+ m.should_receive(:start).ordered(1)
514
+ m.should_receive(:flip).ordered(2)
515
+ m.should_receive(:flop).ordered(2)
508
516
  m.should_receive(:final).ordered
509
517
 
510
518
  m.start
@@ -517,9 +525,9 @@ class TestFlexMockShoulds < Test::Unit::TestCase
517
525
 
518
526
  def test_grouped_ordering_with_symbols
519
527
  FlexMock.use 'm' do |m|
520
- m.should_receive(:start).ordered(:group_one)
521
- m.should_receive(:flip).ordered(:group_two)
522
- m.should_receive(:flop).ordered(:group_two)
528
+ m.should_receive(:start).ordered(:start_group)
529
+ m.should_receive(:flip).ordered(:flip_flop_group)
530
+ m.should_receive(:flop).ordered(:flip_flop_group)
523
531
  m.should_receive(:final).ordered
524
532
 
525
533
  m.start
@@ -541,17 +549,44 @@ class TestFlexMockShoulds < Test::Unit::TestCase
541
549
  end
542
550
 
543
551
  def test_explicit_ordering_with_explicit_misorders
544
- assert_failure do
552
+ ex = assert_failure(OUT_OF_ORDER_ERROR_MESSAGE) do
545
553
  FlexMock.use 'm' do |m|
546
- m.should_receive(:hi).ordered(:first_group)
547
- m.should_receive(:lo).ordered(:second_group)
548
-
549
- m.lo
550
- m.hi
554
+ m.should_receive(:hi).ordered(:first_group)
555
+ m.should_receive(:lo).ordered(:second_group)
556
+
557
+ m.lo
558
+ m.hi
551
559
  end
552
560
  end
561
+ # TODO: It would be nice to get the group names in the error message.
562
+ # assert_match /first_group/, ex.message
563
+ # assert_match /second_group/, ex.message
553
564
  end
554
-
565
+
566
+ # Test submitted by Mikael Pahmp to correct expectation matching.
567
+ def test_ordering_with_explicit_no_args_matches_correctly
568
+ FlexMock.use("m") do |m|
569
+ m.should_receive(:foo).with_no_args.once.ordered
570
+ m.should_receive(:bar).with_no_args.once.ordered
571
+ m.should_receive(:foo).with_no_args.once.ordered
572
+ m.foo
573
+ m.bar
574
+ m.foo
575
+ end
576
+ end
577
+
578
+ # Test submitted by Mikael Pahmp to correct expectation matching.
579
+ def test_ordering_with_any_arg_matching_correctly_matches
580
+ FlexMock.use("m") do |m|
581
+ m.should_receive(:foo).with_any_args.once.ordered
582
+ m.should_receive(:bar).with_any_args.once.ordered
583
+ m.should_receive(:foo).with_any_args.once.ordered
584
+ m.foo
585
+ m.bar
586
+ m.foo
587
+ end
588
+ end
589
+
555
590
  def test_expectation_formating
556
591
  m = FlexMock.new("m")
557
592
  exp = m.should_receive(:f).with(1,"two", /^3$/).and_return(0).at_least.once
@@ -597,18 +632,41 @@ class TestFlexMockShoulds < Test::Unit::TestCase
597
632
  assert_equal :mkf, m2.mock_kernel_function
598
633
  end
599
634
 
600
- def assert_failure
601
- assert_raises(Test::Unit::AssertionFailedError) do yield end
635
+ # Assertion helper used to assert validation failure. If a
636
+ # message is given, then the error message should match the
637
+ # expected error message.
638
+ def assert_failure(message=nil)
639
+ ex = assert_raises(Test::Unit::AssertionFailedError) { yield }
640
+ if message
641
+ case message
642
+ when Regexp
643
+ assert_match message, ex.message
644
+ when String
645
+ assert ex.message.index(message), "Error message '#{ex.message}' should contain '#{message}'"
646
+ end
647
+ end
648
+ ex
602
649
  end
603
-
604
650
  end
605
651
 
606
652
  class TestFlexMockShouldsWithInclude < Test::Unit::TestCase
607
653
  include FlexMock::ArgumentTypes
608
- def test_include
654
+ def test_include_enables_unqualified_arg_type_references
609
655
  FlexMock.use("x") do |m|
610
656
  m.should_receive(:hi).with(any).once
611
657
  m.hi(1)
612
658
  end
613
659
  end
614
660
  end
661
+
662
+ class TestFlexMockArgTypesDontLeak < Test::Unit::TestCase
663
+ def test_unqualified_arg_type_references_are_undefined_by_default
664
+ ex = assert_raise(NameError) do
665
+ FlexMock.use("x") do |m|
666
+ m.should_receive(:hi).with(any).once
667
+ m.hi(1)
668
+ end
669
+ end
670
+ assert_match(/\bany\b/, ex.message, "Error message should mention 'any'")
671
+ end
672
+ end
@@ -10,6 +10,7 @@
10
10
  #+++
11
11
 
12
12
  require 'test/unit'
13
+ require 'fileutils'
13
14
  require 'flexmock'
14
15
 
15
16
  class TestStubbing < Test::Unit::TestCase
@@ -127,11 +128,35 @@ class TestStubbing < Test::Unit::TestCase
127
128
  end
128
129
 
129
130
  def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs
130
- flexstub(File).should_receive(:open).with("foo").once.and_return(:ok)
131
- flexstub(File).should_receive(:open).with("bar").once.and_return(:ok)
131
+ flexstub(Dir).should_receive(:chdir).with("xx").once.and_return(:ok1)
132
+ flexstub(Dir).should_receive(:chdir).with("yy").once.and_return(:ok2)
133
+ assert_equal :ok1, Dir.chdir("xx")
134
+ assert_equal :ok2, Dir.chdir("yy")
135
+
136
+ flexstub(Dir).mock_teardown
137
+
138
+ x = :not_called
139
+ Dir.chdir("test") do
140
+ assert_match %r{/test$}, Dir.pwd
141
+ x = :called
142
+ end
143
+ assert_equal :called, x
144
+ end
132
145
 
146
+ def test_stubbing_file_shouldnt_break_writing
147
+ flexstub(File).should_receive(:open).with("foo").once.and_return(:ok)
133
148
  assert_equal :ok, File.open("foo")
134
- assert_equal :ok, File.open("bar")
149
+ flexstub(File).mock_teardown
150
+
151
+ File.open("dummy.txt", "w") do |out|
152
+ assert out.is_a?(IO)
153
+ out.puts "XYZ"
154
+ end
155
+ text = nil
156
+ File.open("dummy.txt") { |f| text = f.read }
157
+ assert_equal "XYZ\n", text
158
+ ensure
159
+ FileUtils.rm_f("dummy.txt")
135
160
  end
136
161
 
137
162
  def test_original_behavior_is_restored_even_when_errors
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: flexmock
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.5.0
7
- date: 2007-02-10 00:00:00 -05:00
6
+ version: 0.5.1
7
+ date: 2007-04-09 00:00:00 -04:00
8
8
  summary: Simple and Flexible Mock Objects for Testing
9
9
  require_paths:
10
10
  - lib
@@ -50,6 +50,7 @@ files:
50
50
  - doc/releases/flexmock-0.4.2.rdoc
51
51
  - doc/releases/flexmock-0.4.3.rdoc
52
52
  - doc/releases/flexmock-0.5.0.rdoc
53
+ - doc/releases/flexmock-0.5.1.rdoc
53
54
  test_files: []
54
55
 
55
56
  rdoc_options:
@@ -66,6 +67,7 @@ extra_rdoc_files:
66
67
  - doc/releases/flexmock-0.4.2.rdoc
67
68
  - doc/releases/flexmock-0.4.3.rdoc
68
69
  - doc/releases/flexmock-0.5.0.rdoc
70
+ - doc/releases/flexmock-0.5.1.rdoc
69
71
  executables: []
70
72
 
71
73
  extensions: []