flexmock 0.5.1 → 0.6.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 (39) hide show
  1. data/CHANGELOG +10 -1
  2. data/README +390 -209
  3. data/Rakefile +31 -10
  4. data/doc/GoogleExample.rdoc +275 -0
  5. data/doc/releases/flexmock-0.6.0.rdoc +136 -0
  6. data/lib/flexmock.rb +3 -1160
  7. data/lib/flexmock/argument_matchers.rb +57 -0
  8. data/lib/flexmock/argument_types.rb +42 -0
  9. data/lib/flexmock/base.rb +22 -0
  10. data/lib/flexmock/composite.rb +10 -0
  11. data/lib/flexmock/core.rb +206 -0
  12. data/lib/flexmock/core_class_methods.rb +92 -0
  13. data/lib/flexmock/default_framework_adapter.rb +31 -0
  14. data/lib/flexmock/expectation.rb +334 -0
  15. data/lib/flexmock/expectation_director.rb +59 -0
  16. data/lib/flexmock/mock_container.rb +159 -0
  17. data/lib/flexmock/noop.rb +13 -0
  18. data/lib/flexmock/partial_mock.rb +226 -0
  19. data/lib/flexmock/recorder.rb +71 -0
  20. data/lib/flexmock/rspec.rb +34 -0
  21. data/lib/flexmock/test_unit.rb +32 -0
  22. data/lib/flexmock/test_unit_integration.rb +53 -0
  23. data/lib/flexmock/validators.rb +77 -0
  24. data/test/rspec_integration/integration_spec.rb +36 -0
  25. data/test/test_container_methods.rb +119 -0
  26. data/test/test_default_framework_adapter.rb +39 -0
  27. data/test/test_example.rb +1 -1
  28. data/test/test_extended_should_receive.rb +63 -0
  29. data/test/test_mock.rb +1 -1
  30. data/test/test_naming.rb +1 -1
  31. data/test/{test_any_instance.rb → test_new_instances.rb} +15 -8
  32. data/test/{test_stubbing.rb → test_partial_mock.rb} +44 -44
  33. data/test/test_record_mode.rb +1 -1
  34. data/test/test_samples.rb +6 -8
  35. data/test/test_should_receive.rb +7 -3
  36. data/test/test_tu_integration.rb +1 -1
  37. data/test/test_unit_integration/test_auto_test_unit.rb +34 -0
  38. metadata +30 -5
  39. data/test/test_class_interception.rb +0 -140
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+ #
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/noop'
13
+
14
+ class FlexMock
15
+ ####################################################################
16
+ # Match any object
17
+ class AnyMatcher
18
+ def ===(target)
19
+ true
20
+ end
21
+ def inspect
22
+ "ANY"
23
+ end
24
+ end
25
+
26
+ ####################################################################
27
+ # Match only things that are equal.
28
+ class EqualMatcher
29
+ def initialize(obj)
30
+ @obj = obj
31
+ end
32
+ def ===(target)
33
+ @obj == target
34
+ end
35
+ def inspect
36
+ "==(#{@obj.inspect})"
37
+ end
38
+ end
39
+
40
+ ANY = AnyMatcher.new
41
+
42
+ ####################################################################
43
+ # Match only things where the block evaluates to true.
44
+ class ProcMatcher
45
+ def initialize(&block)
46
+ @block = block
47
+ end
48
+ def ===(target)
49
+ @block.call(target)
50
+ end
51
+ def inspect
52
+ "on{...}"
53
+ end
54
+ end
55
+
56
+
57
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/argument_matchers'
13
+
14
+ class FlexMock
15
+
16
+ ####################################################################
17
+ # Include this module in your test class if you wish to use the +eq+
18
+ # and +any+ argument matching methods without a prefix. (Otherwise
19
+ # use <tt>FlexMock.any</tt> and <tt>FlexMock.eq(obj)</tt>.
20
+ #
21
+ module ArgumentTypes
22
+ # Return an argument matcher that matches any argument.
23
+ def any
24
+ ANY
25
+ end
26
+
27
+ # Return an argument matcher that only matches things equal to
28
+ # (==) the given object.
29
+ def eq(obj)
30
+ EqualMatcher.new(obj)
31
+ end
32
+
33
+ # Return an argument matcher that matches any object, that when
34
+ # passed to the supplied block, will cause the block to return
35
+ # true.
36
+ def on(&block)
37
+ ProcMatcher.new(&block)
38
+ end
39
+ end
40
+ extend ArgumentTypes
41
+
42
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/core'
13
+
14
+ require 'flexmock/default_framework_adapter'
15
+ require 'flexmock/expectation_director'
16
+ require 'flexmock/expectation'
17
+ require 'flexmock/argument_matchers'
18
+ require 'flexmock/argument_types'
19
+ require 'flexmock/validators'
20
+ require 'flexmock/recorder'
21
+ require 'flexmock/mock_container'
22
+ require 'flexmock/partial_mock'
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Jim Weirich on 2007-04-14.
4
+ # Copyright (c) 2007. All rights reserved.
5
+
6
+ require 'flexmock/noop'
7
+
8
+ class FlexMock
9
+
10
+ end
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+ #
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/composite'
13
+
14
+ ######################################################################
15
+ # FlexMock is a flexible mock object framework for supporting testing.
16
+ #
17
+ # FlexMock has a simple interface that's easy to remember, and leaves
18
+ # the hard stuff to all those other mock object implementations.
19
+ #
20
+ # Basic Usage:
21
+ #
22
+ # m = flexmock("name")
23
+ # m.should_receive(:upcase).with("stuff").
24
+ # and_return("STUFF")
25
+ # m.should_receive(:downcase).with(String).
26
+ # and_return { |s| s.downcase }.once
27
+ #
28
+ # With Test::Unit Integration:
29
+ #
30
+ # class TestSomething < Test::Unit::TestCase
31
+ # include FlexMock::TestCase
32
+ #
33
+ # def test_something
34
+ # m = flexmock("name")
35
+ # m.should_receive(:hi).and_return("Hello")
36
+ # m.hi
37
+ # end
38
+ # end
39
+ #
40
+ # Note: When using Test::Unit integeration, don't forget to include
41
+ # FlexMock::TestCase. Also, if you override +teardown+, make sure you
42
+ # call +super+.
43
+ #
44
+ class FlexMock
45
+ attr_reader :mock_name, :mock_groups
46
+ attr_accessor :mock_current_order, :mock_container
47
+
48
+ # Create a FlexMock object with the given name. The name is used in
49
+ # error messages.
50
+ def initialize(name="unknown")
51
+ @mock_name = name
52
+ @expectations = Hash.new
53
+ @allocated_order = 0
54
+ @mock_current_order = 0
55
+ @mock_container = nil
56
+ @mock_groups = {}
57
+ @ignore_missing = false
58
+ @verified = false
59
+ end
60
+
61
+ # Handle all messages denoted by +sym+ by calling the given block
62
+ # and passing any parameters to the block. If we know exactly how
63
+ # many calls are to be made to a particular method, we may check
64
+ # that by passing in the number of expected calls as a second
65
+ # paramter.
66
+ def mock_handle(sym, expected_count=nil, &block) # :nodoc:
67
+ self.should_receive(sym).times(expected_count).returns(&block)
68
+ end
69
+
70
+ # Verify that each method that had an explicit expected count was
71
+ # actually called that many times.
72
+ def mock_verify
73
+ return if @verified
74
+ @verified = true
75
+ mock_wrap do
76
+ @expectations.each do |sym, handler|
77
+ handler.mock_verify
78
+ end
79
+ end
80
+ end
81
+
82
+ # Teardown and infrastructure setup for this mock.
83
+ def mock_teardown
84
+ end
85
+
86
+ # Allocation a new order number from the mock.
87
+ def mock_allocate_order
88
+ @auto_allocate = true
89
+ @allocated_order += 1
90
+ end
91
+
92
+ # Ignore all undefined (missing) method calls.
93
+ def should_ignore_missing
94
+ @ignore_missing = true
95
+ end
96
+ alias mock_ignore_missing should_ignore_missing
97
+
98
+ # Handle missing methods by attempting to look up a handler.
99
+ def method_missing(sym, *args, &block)
100
+ mock_wrap do
101
+ if handler = @expectations[sym]
102
+ args << block if block_given?
103
+ handler.call(*args)
104
+ else
105
+ super(sym, *args, &block) unless @ignore_missing
106
+ end
107
+ end
108
+ end
109
+
110
+ # Save the original definition of respond_to? for use a bit later.
111
+ alias mock_respond_to? respond_to?
112
+
113
+ # Override the built-in respond_to? to include the mocked methods.
114
+ def respond_to?(sym)
115
+ super || (@expectations[sym] ? true : @ignore_missing)
116
+ end
117
+
118
+ # Override the built-in +method+ to include the mocked methods.
119
+ def method(sym)
120
+ @expectations[sym] || super
121
+ rescue NameError => ex
122
+ if @ignore_missing
123
+ proc { }
124
+ else
125
+ raise ex
126
+ end
127
+ end
128
+
129
+ # :call-seq:
130
+ # mock.should_receive(:method_name)
131
+ # mock.should_receive(:method1, method2, ...)
132
+ # mock.should_receive(:meth1 => result1, :meth2 => result2, ...)
133
+ #
134
+ # Declare that the mock object should receive a message with the given name.
135
+ #
136
+ # If more than one method name is given, then the mock object should expect
137
+ # to receive all the listed melthods. If a hash of method name/value pairs
138
+ # is given, then the each method will return the associated result. Any
139
+ # expectations applied to the result of +should_receive+ will be applied to
140
+ # all the methods defined in the argument list.
141
+ #
142
+ # An expectation object for the method name is returned as the result of
143
+ # this method. Further expectation constraints can be added by chaining to
144
+ # the result.
145
+ #
146
+ # See Expectation for a list of declarators that can be used.
147
+ #
148
+ def should_receive(*args)
149
+ FlexMock.should_receive(args) do |sym|
150
+ @expectations[sym] ||= ExpectationDirector.new(sym)
151
+ result = Expectation.new(self, sym)
152
+ @expectations[sym] << result
153
+ override_existing_method(sym) if mock_respond_to?(sym)
154
+ result
155
+ end
156
+ end
157
+
158
+ # Declare that the mock object should expect methods by providing a
159
+ # recorder for the methods and having the user invoke the expected
160
+ # methods in a block. Further expectations may be applied the
161
+ # result of the recording call.
162
+ #
163
+ # Example Usage:
164
+ #
165
+ # mock.should_expect do |record|
166
+ # record.add(Integer, 4) { |a, b|
167
+ # a + b
168
+ # }.at_least.once
169
+ #
170
+ def should_expect
171
+ yield Recorder.new(self)
172
+ end
173
+
174
+ private
175
+
176
+ # Wrap a block of code so the any assertion errors are wrapped so
177
+ # that the mock name is added to the error message .
178
+ def mock_wrap(&block)
179
+ yield
180
+ rescue FlexMock.framework_adapter.assertion_failed_error => ex
181
+ raise FlexMock.framework_adapter.assertion_failed_error,
182
+ "in mock '#{@mock_name}': #{ex.message}",
183
+ ex.backtrace
184
+ end
185
+
186
+
187
+ # Override the existing definition of method +sym+ in the mock.
188
+ # Most methods depend on the method_missing trick to be invoked.
189
+ # However, if the method already exists, it will not call
190
+ # method_missing. This method defines a singleton method on the
191
+ # mock to explicitly invoke the method_missing logic.
192
+ def override_existing_method(sym)
193
+ sclass.class_eval <<-EOS
194
+ def #{sym}(*args, &block)
195
+ method_missing(:#{sym}, *args, &block)
196
+ end
197
+ EOS
198
+ end
199
+
200
+ # Return the singleton class of the mock object.
201
+ def sclass
202
+ class << self; self; end
203
+ end
204
+ end
205
+
206
+ require 'flexmock/core_class_methods'
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/noop'
13
+
14
+ class FlexMock
15
+ class << self
16
+ attr_reader :framework_adapter
17
+
18
+ # :call-seq:
19
+ # should_receive(args) { |symbol| ... }
20
+ #
21
+ # This method provides common handling for the various should_receive
22
+ # argument lists. It sorts out the differences between symbols, arrays and
23
+ # hashes, and identifies the method names specified by each. As each
24
+ # method name is identified, create a mock expectation for it using the
25
+ # supplied block.
26
+ def should_receive(args) # :nodoc:
27
+ result = CompositeExpectation.new
28
+ args.each do |arg|
29
+ case arg
30
+ when Hash
31
+ arg.each do |k,v|
32
+ result.add(yield(k.to_sym).and_return(v))
33
+ end
34
+ when Symbol, String
35
+ result.add(yield(arg.to_sym))
36
+ end
37
+ end
38
+ result
39
+ end
40
+
41
+ # Class method to make sure that verify is called at the end of a
42
+ # test. One mock object will be created for each name given to
43
+ # the use method. The mocks will be passed to the block as
44
+ # arguments. If no names are given, then a single anonymous mock
45
+ # object will be created.
46
+ #
47
+ # At the end of the use block, each mock object will be verified
48
+ # to make sure the proper number of calls have been made.
49
+ #
50
+ # Usage:
51
+ #
52
+ # FlexMock.use("name") do |mock| # Creates a mock named "name"
53
+ # mock.should_receive(:meth).
54
+ # returns(0).once
55
+ # end # mock is verified here
56
+ #
57
+ # NOTE: If you include FlexMock::TestCase into your test case
58
+ # file, you can create mocks that will be automatically verified in
59
+ # the test teardown by using the +flexmock+ method.
60
+ #
61
+ def use(*names)
62
+ names = ["unknown"] if names.empty?
63
+ got_excecption = false
64
+ mocks = names.collect { |n| new(n) }
65
+ yield(*mocks)
66
+ rescue Exception => ex
67
+ got_exception = true
68
+ raise
69
+ ensure
70
+ mocks.each do |mock|
71
+ mock.mock_verify unless got_exception
72
+ end
73
+ end
74
+
75
+ # Class method to format a method name and argument list as a nice
76
+ # looking string.
77
+ def format_args(sym, args) # :nodoc:
78
+ if args
79
+ "#{sym}(#{args.collect { |a| a.inspect }.join(', ')})"
80
+ else
81
+ "#{sym}(*args)"
82
+ end
83
+ end
84
+
85
+ # Check will assert the block returns true. If it doesn't, an
86
+ # assertion failure is triggered with the given message.
87
+ def check(msg, &block) # :nodoc:
88
+ FlexMock.framework_adapter.assert_block(msg, &block)
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #---
4
+ # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #+++
11
+
12
+ require 'flexmock/noop'
13
+
14
+ class FlexMock
15
+ class DefaultFrameworkAdapter
16
+ def assert_block(msg, &block)
17
+ unless yield
18
+ fail assertion_failed_error, msg
19
+ end
20
+ end
21
+
22
+ def assert_equal(a, b, msg=nil)
23
+ assert_block(msg || "Expected equal") { a == b }
24
+ end
25
+
26
+ class AssertionFailedError < StandardError; end
27
+ def assertion_failed_error
28
+ AssertionFailedError
29
+ end
30
+ end
31
+ end