mocha-macruby 0.9.8.20100129120100

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 (172) hide show
  1. data/COPYING +3 -0
  2. data/MIT-LICENSE +7 -0
  3. data/README +39 -0
  4. data/RELEASE +294 -0
  5. data/Rakefile +214 -0
  6. data/examples/misc.rb +43 -0
  7. data/examples/mocha.rb +25 -0
  8. data/examples/stubba.rb +64 -0
  9. data/lib/mocha.rb +3 -0
  10. data/lib/mocha/any_instance_method.rb +59 -0
  11. data/lib/mocha/api.rb +173 -0
  12. data/lib/mocha/argument_iterator.rb +21 -0
  13. data/lib/mocha/backtrace_filter.rb +17 -0
  14. data/lib/mocha/cardinality.rb +95 -0
  15. data/lib/mocha/central.rb +27 -0
  16. data/lib/mocha/change_state_side_effect.rb +19 -0
  17. data/lib/mocha/class_method.rb +117 -0
  18. data/lib/mocha/configuration.rb +79 -0
  19. data/lib/mocha/deprecation.rb +22 -0
  20. data/lib/mocha/exception_raiser.rb +17 -0
  21. data/lib/mocha/expectation.rb +476 -0
  22. data/lib/mocha/expectation_error.rb +15 -0
  23. data/lib/mocha/expectation_list.rb +50 -0
  24. data/lib/mocha/in_state_ordering_constraint.rb +19 -0
  25. data/lib/mocha/inspect.rb +67 -0
  26. data/lib/mocha/instance_method.rb +16 -0
  27. data/lib/mocha/integration.rb +38 -0
  28. data/lib/mocha/integration/mini_test.rb +21 -0
  29. data/lib/mocha/integration/mini_test/assertion_counter.rb +23 -0
  30. data/lib/mocha/integration/mini_test/version_131_and_above.rb +50 -0
  31. data/lib/mocha/integration/test_unit.rb +40 -0
  32. data/lib/mocha/integration/test_unit/assertion_counter.rb +23 -0
  33. data/lib/mocha/integration/test_unit/gem_version_200.rb +49 -0
  34. data/lib/mocha/integration/test_unit/gem_version_201_and_above.rb +49 -0
  35. data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +48 -0
  36. data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +50 -0
  37. data/lib/mocha/is_a.rb +9 -0
  38. data/lib/mocha/logger.rb +15 -0
  39. data/lib/mocha/metaclass.rb +13 -0
  40. data/lib/mocha/method_matcher.rb +21 -0
  41. data/lib/mocha/mock.rb +200 -0
  42. data/lib/mocha/mockery.rb +181 -0
  43. data/lib/mocha/module_method.rb +16 -0
  44. data/lib/mocha/multiple_yields.rb +20 -0
  45. data/lib/mocha/names.rb +53 -0
  46. data/lib/mocha/no_yields.rb +11 -0
  47. data/lib/mocha/object.rb +187 -0
  48. data/lib/mocha/parameter_matchers.rb +27 -0
  49. data/lib/mocha/parameter_matchers/all_of.rb +42 -0
  50. data/lib/mocha/parameter_matchers/any_of.rb +47 -0
  51. data/lib/mocha/parameter_matchers/any_parameters.rb +40 -0
  52. data/lib/mocha/parameter_matchers/anything.rb +33 -0
  53. data/lib/mocha/parameter_matchers/base.rb +15 -0
  54. data/lib/mocha/parameter_matchers/equals.rb +42 -0
  55. data/lib/mocha/parameter_matchers/has_entries.rb +45 -0
  56. data/lib/mocha/parameter_matchers/has_entry.rb +57 -0
  57. data/lib/mocha/parameter_matchers/has_key.rb +43 -0
  58. data/lib/mocha/parameter_matchers/has_value.rb +43 -0
  59. data/lib/mocha/parameter_matchers/includes.rb +41 -0
  60. data/lib/mocha/parameter_matchers/instance_of.rb +42 -0
  61. data/lib/mocha/parameter_matchers/is_a.rb +42 -0
  62. data/lib/mocha/parameter_matchers/kind_of.rb +42 -0
  63. data/lib/mocha/parameter_matchers/not.rb +42 -0
  64. data/lib/mocha/parameter_matchers/object.rb +15 -0
  65. data/lib/mocha/parameter_matchers/optionally.rb +55 -0
  66. data/lib/mocha/parameter_matchers/regexp_matches.rb +44 -0
  67. data/lib/mocha/parameter_matchers/responds_with.rb +43 -0
  68. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +43 -0
  69. data/lib/mocha/parameters_matcher.rb +37 -0
  70. data/lib/mocha/pretty_parameters.rb +28 -0
  71. data/lib/mocha/return_values.rb +31 -0
  72. data/lib/mocha/sequence.rb +42 -0
  73. data/lib/mocha/single_return_value.rb +17 -0
  74. data/lib/mocha/single_yield.rb +18 -0
  75. data/lib/mocha/standalone.rb +1 -0
  76. data/lib/mocha/state_machine.rb +91 -0
  77. data/lib/mocha/stubbing_error.rb +16 -0
  78. data/lib/mocha/unexpected_invocation.rb +18 -0
  79. data/lib/mocha/yield_parameters.rb +31 -0
  80. data/lib/mocha_standalone.rb +2 -0
  81. data/lib/stubba.rb +4 -0
  82. data/test/acceptance/acceptance_test_helper.rb +38 -0
  83. data/test/acceptance/api_test.rb +139 -0
  84. data/test/acceptance/bug_18914_test.rb +43 -0
  85. data/test/acceptance/bug_21465_test.rb +34 -0
  86. data/test/acceptance/bug_21563_test.rb +25 -0
  87. data/test/acceptance/expected_invocation_count_test.rb +196 -0
  88. data/test/acceptance/failure_messages_test.rb +64 -0
  89. data/test/acceptance/minitest_test.rb +153 -0
  90. data/test/acceptance/mocha_example_test.rb +98 -0
  91. data/test/acceptance/mocha_test_result_test.rb +84 -0
  92. data/test/acceptance/mock_test.rb +100 -0
  93. data/test/acceptance/mock_with_initializer_block_test.rb +51 -0
  94. data/test/acceptance/mocked_methods_dispatch_test.rb +78 -0
  95. data/test/acceptance/optional_parameters_test.rb +70 -0
  96. data/test/acceptance/parameter_matcher_test.rb +209 -0
  97. data/test/acceptance/partial_mocks_test.rb +47 -0
  98. data/test/acceptance/return_value_test.rb +52 -0
  99. data/test/acceptance/sequence_test.rb +186 -0
  100. data/test/acceptance/states_test.rb +70 -0
  101. data/test/acceptance/stub_any_instance_method_test.rb +195 -0
  102. data/test/acceptance/stub_class_method_test.rb +203 -0
  103. data/test/acceptance/stub_everything_test.rb +56 -0
  104. data/test/acceptance/stub_instance_method_test.rb +203 -0
  105. data/test/acceptance/stub_module_method_test.rb +163 -0
  106. data/test/acceptance/stub_test.rb +52 -0
  107. data/test/acceptance/stubba_example_test.rb +102 -0
  108. data/test/acceptance/stubba_test.rb +15 -0
  109. data/test/acceptance/stubba_test_result_test.rb +66 -0
  110. data/test/acceptance/stubbing_error_backtrace_test.rb +64 -0
  111. data/test/acceptance/stubbing_method_unnecessarily_test.rb +65 -0
  112. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +130 -0
  113. data/test/acceptance/stubbing_non_existent_class_method_test.rb +157 -0
  114. data/test/acceptance/stubbing_non_existent_instance_method_test.rb +147 -0
  115. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +130 -0
  116. data/test/acceptance/stubbing_non_public_class_method_test.rb +163 -0
  117. data/test/acceptance/stubbing_non_public_instance_method_test.rb +143 -0
  118. data/test/acceptance/stubbing_on_non_mock_object_test.rb +64 -0
  119. data/test/deprecation_disabler.rb +15 -0
  120. data/test/execution_point.rb +36 -0
  121. data/test/method_definer.rb +24 -0
  122. data/test/simple_counter.rb +13 -0
  123. data/test/test_helper.rb +25 -0
  124. data/test/test_runner.rb +33 -0
  125. data/test/unit/any_instance_method_test.rb +126 -0
  126. data/test/unit/array_inspect_test.rb +16 -0
  127. data/test/unit/backtrace_filter_test.rb +19 -0
  128. data/test/unit/cardinality_test.rb +56 -0
  129. data/test/unit/central_test.rb +65 -0
  130. data/test/unit/change_state_side_effect_test.rb +41 -0
  131. data/test/unit/class_method_test.rb +295 -0
  132. data/test/unit/configuration_test.rb +38 -0
  133. data/test/unit/date_time_inspect_test.rb +21 -0
  134. data/test/unit/exception_raiser_test.rb +42 -0
  135. data/test/unit/expectation_list_test.rb +57 -0
  136. data/test/unit/expectation_test.rb +480 -0
  137. data/test/unit/hash_inspect_test.rb +16 -0
  138. data/test/unit/in_state_ordering_constraint_test.rb +43 -0
  139. data/test/unit/metaclass_test.rb +22 -0
  140. data/test/unit/method_matcher_test.rb +23 -0
  141. data/test/unit/mock_test.rb +302 -0
  142. data/test/unit/mockery_test.rb +149 -0
  143. data/test/unit/multiple_yields_test.rb +18 -0
  144. data/test/unit/no_yields_test.rb +18 -0
  145. data/test/unit/object_inspect_test.rb +37 -0
  146. data/test/unit/object_test.rb +82 -0
  147. data/test/unit/parameter_matchers/all_of_test.rb +26 -0
  148. data/test/unit/parameter_matchers/any_of_test.rb +26 -0
  149. data/test/unit/parameter_matchers/anything_test.rb +21 -0
  150. data/test/unit/parameter_matchers/equals_test.rb +25 -0
  151. data/test/unit/parameter_matchers/has_entries_test.rb +51 -0
  152. data/test/unit/parameter_matchers/has_entry_test.rb +82 -0
  153. data/test/unit/parameter_matchers/has_key_test.rb +55 -0
  154. data/test/unit/parameter_matchers/has_value_test.rb +57 -0
  155. data/test/unit/parameter_matchers/includes_test.rb +44 -0
  156. data/test/unit/parameter_matchers/instance_of_test.rb +25 -0
  157. data/test/unit/parameter_matchers/is_a_test.rb +25 -0
  158. data/test/unit/parameter_matchers/kind_of_test.rb +25 -0
  159. data/test/unit/parameter_matchers/not_test.rb +26 -0
  160. data/test/unit/parameter_matchers/regexp_matches_test.rb +46 -0
  161. data/test/unit/parameter_matchers/responds_with_test.rb +25 -0
  162. data/test/unit/parameter_matchers/stub_matcher.rb +27 -0
  163. data/test/unit/parameter_matchers/yaml_equivalent_test.rb +25 -0
  164. data/test/unit/parameters_matcher_test.rb +121 -0
  165. data/test/unit/return_values_test.rb +63 -0
  166. data/test/unit/sequence_test.rb +104 -0
  167. data/test/unit/single_return_value_test.rb +14 -0
  168. data/test/unit/single_yield_test.rb +18 -0
  169. data/test/unit/state_machine_test.rb +98 -0
  170. data/test/unit/string_inspect_test.rb +11 -0
  171. data/test/unit/yield_parameters_test.rb +93 -0
  172. metadata +240 -0
@@ -0,0 +1,48 @@
1
+ require 'test/unit/testcase'
2
+ require 'mocha/integration/test_unit/assertion_counter'
3
+ require 'mocha/expectation_error'
4
+
5
+ module Mocha
6
+
7
+ module Integration
8
+
9
+ module TestUnit
10
+
11
+ module RubyVersion185AndBelow
12
+ def run(result)
13
+ assertion_counter = AssertionCounter.new(result)
14
+ yield(Test::Unit::TestCase::STARTED, name)
15
+ @_result = result
16
+ begin
17
+ begin
18
+ setup
19
+ __send__(@method_name)
20
+ mocha_verify(assertion_counter)
21
+ rescue Mocha::ExpectationError => e
22
+ add_failure(e.message, e.backtrace)
23
+ rescue Test::Unit::AssertionFailedError => e
24
+ add_failure(e.message, e.backtrace)
25
+ rescue StandardError, ScriptError
26
+ add_error($!)
27
+ ensure
28
+ begin
29
+ teardown
30
+ rescue Test::Unit::AssertionFailedError => e
31
+ add_failure(e.message, e.backtrace)
32
+ rescue StandardError, ScriptError
33
+ add_error($!)
34
+ end
35
+ end
36
+ ensure
37
+ mocha_teardown
38
+ end
39
+ result.add_run
40
+ yield(Test::Unit::TestCase::FINISHED, name)
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,50 @@
1
+ require 'test/unit/testcase'
2
+ require 'mocha/integration/test_unit/assertion_counter'
3
+ require 'mocha/expectation_error'
4
+
5
+ module Mocha
6
+
7
+ module Integration
8
+
9
+ module TestUnit
10
+
11
+ module RubyVersion186AndAbove
12
+ def run(result)
13
+ assertion_counter = AssertionCounter.new(result)
14
+ yield(Test::Unit::TestCase::STARTED, name)
15
+ @_result = result
16
+ begin
17
+ begin
18
+ setup
19
+ __send__(@method_name)
20
+ mocha_verify(assertion_counter)
21
+ rescue Mocha::ExpectationError => e
22
+ add_failure(e.message, e.backtrace)
23
+ rescue Test::Unit::AssertionFailedError => e
24
+ add_failure(e.message, e.backtrace)
25
+ rescue Exception
26
+ raise if Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS.include? $!.class
27
+ add_error($!)
28
+ ensure
29
+ begin
30
+ teardown
31
+ rescue Test::Unit::AssertionFailedError => e
32
+ add_failure(e.message, e.backtrace)
33
+ rescue Exception
34
+ raise if Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS.include? $!.class
35
+ add_error($!)
36
+ end
37
+ end
38
+ ensure
39
+ mocha_teardown
40
+ end
41
+ result.add_run
42
+ yield(Test::Unit::TestCase::FINISHED, name)
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
data/lib/mocha/is_a.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Object
2
+
3
+ # :stopdoc:
4
+
5
+ alias_method :__is_a__, :is_a?
6
+
7
+ # :startdoc:
8
+
9
+ end
@@ -0,0 +1,15 @@
1
+ module Mocha
2
+
3
+ class Logger
4
+
5
+ def initialize(io)
6
+ @io = io
7
+ end
8
+
9
+ def warn(message)
10
+ @io.puts "WARNING: #{message}"
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,13 @@
1
+ module Mocha
2
+
3
+ module ObjectMethods
4
+ def __metaclass__
5
+ class << self; self; end
6
+ end
7
+ end
8
+
9
+ end
10
+
11
+ class Object
12
+ include Mocha::ObjectMethods
13
+ end
@@ -0,0 +1,21 @@
1
+ module Mocha
2
+
3
+ class MethodMatcher
4
+
5
+ attr_reader :expected_method_name
6
+
7
+ def initialize(expected_method_name)
8
+ @expected_method_name = expected_method_name
9
+ end
10
+
11
+ def match?(actual_method_name)
12
+ @expected_method_name == actual_method_name
13
+ end
14
+
15
+ def mocha_inspect
16
+ "#{@expected_method_name}"
17
+ end
18
+
19
+ end
20
+
21
+ end
data/lib/mocha/mock.rb ADDED
@@ -0,0 +1,200 @@
1
+ require 'mocha/expectation'
2
+ require 'mocha/expectation_list'
3
+ require 'mocha/metaclass'
4
+ require 'mocha/names'
5
+ require 'mocha/mockery'
6
+ require 'mocha/method_matcher'
7
+ require 'mocha/parameters_matcher'
8
+ require 'mocha/unexpected_invocation'
9
+ require 'mocha/argument_iterator'
10
+
11
+ module Mocha # :nodoc:
12
+
13
+ # Traditional mock object.
14
+ #
15
+ # Methods return an Expectation which can be further modified by methods on Expectation.
16
+ class Mock
17
+
18
+ # :call-seq: expects(method_name) -> expectation
19
+ # expects(method_names_vs_return_values) -> last expectation
20
+ #
21
+ # Adds an expectation that a method identified by +method_name+ Symbol/String must be called exactly once with any parameters.
22
+ # Returns the new expectation which can be further modified by methods on Expectation.
23
+ # object = mock()
24
+ # object.expects(:method1)
25
+ # object.method1
26
+ # # no error raised
27
+ #
28
+ # object = mock()
29
+ # object.expects(:method1)
30
+ # # error raised, because method1 not called exactly once
31
+ # If +method_names_vs_return_values+ is a +Hash+, an expectation will be set up for each entry using the key as +method_name+ and value as +return_value+.
32
+ # object = mock()
33
+ # object.expects(:method1 => :result1, :method2 => :result2)
34
+ #
35
+ # # exactly equivalent to
36
+ #
37
+ # object = mock()
38
+ # object.expects(:method1).returns(:result1)
39
+ # object.expects(:method2).returns(:result2)
40
+ #
41
+ # Aliased by <tt>\_\_expects\_\_</tt>
42
+ def expects(method_name_or_hash, backtrace = nil)
43
+ iterator = ArgumentIterator.new(method_name_or_hash)
44
+ iterator.each { |*args|
45
+ method_name = args.shift
46
+ ensure_method_not_already_defined(method_name)
47
+ expectation = Expectation.new(self, method_name, backtrace)
48
+ expectation.returns(args.shift) if args.length > 0
49
+ @expectations.add(expectation)
50
+ }
51
+ end
52
+
53
+ # :call-seq: stubs(method_name) -> expectation
54
+ # stubs(method_names_vs_return_values) -> last expectation
55
+ #
56
+ # Adds an expectation that a method identified by +method_name+ Symbol/String may be called any number of times with any parameters.
57
+ # Returns the new expectation which can be further modified by methods on Expectation.
58
+ # object = mock()
59
+ # object.stubs(:method1)
60
+ # object.method1
61
+ # object.method1
62
+ # # no error raised
63
+ # If +method_names_vs_return_values+ is a +Hash+, an expectation will be set up for each entry using the key as +method_name+ and value as +return_value+.
64
+ # object = mock()
65
+ # object.stubs(:method1 => :result1, :method2 => :result2)
66
+ #
67
+ # # exactly equivalent to
68
+ #
69
+ # object = mock()
70
+ # object.stubs(:method1).returns(:result1)
71
+ # object.stubs(:method2).returns(:result2)
72
+ #
73
+ # Aliased by <tt>\_\_stubs\_\_</tt>
74
+ def stubs(method_name_or_hash, backtrace = nil)
75
+ iterator = ArgumentIterator.new(method_name_or_hash)
76
+ iterator.each { |*args|
77
+ method_name = args.shift
78
+ ensure_method_not_already_defined(method_name)
79
+ expectation = Expectation.new(self, method_name, backtrace)
80
+ expectation.at_least(0)
81
+ expectation.returns(args.shift) if args.length > 0
82
+ @expectations.add(expectation)
83
+ }
84
+ end
85
+
86
+ # :call-seq: responds_like(responder) -> mock
87
+ #
88
+ # Constrains the +mock+ so that it can only expect or stub methods to which +responder+ responds. The constraint is only applied at method invocation time.
89
+ #
90
+ # A +NoMethodError+ will be raised if the +responder+ does not <tt>respond_to?</tt> a method invocation (even if the method has been expected or stubbed).
91
+ #
92
+ # The +mock+ will delegate its <tt>respond_to?</tt> method to the +responder+.
93
+ # class Sheep
94
+ # def chew(grass); end
95
+ # def self.number_of_legs; end
96
+ # end
97
+ #
98
+ # sheep = mock('sheep')
99
+ # sheep.expects(:chew)
100
+ # sheep.expects(:foo)
101
+ # sheep.respond_to?(:chew) # => true
102
+ # sheep.respond_to?(:foo) # => true
103
+ # sheep.chew
104
+ # sheep.foo
105
+ # # no error raised
106
+ #
107
+ # sheep = mock('sheep')
108
+ # sheep.responds_like(Sheep.new)
109
+ # sheep.expects(:chew)
110
+ # sheep.expects(:foo)
111
+ # sheep.respond_to?(:chew) # => true
112
+ # sheep.respond_to?(:foo) # => false
113
+ # sheep.chew
114
+ # sheep.foo # => raises NoMethodError exception
115
+ #
116
+ # sheep_class = mock('sheep_class')
117
+ # sheep_class.responds_like(Sheep)
118
+ # sheep_class.stubs(:number_of_legs).returns(4)
119
+ # sheep_class.expects(:foo)
120
+ # sheep_class.respond_to?(:number_of_legs) # => true
121
+ # sheep_class.respond_to?(:foo) # => false
122
+ # assert_equal 4, sheep_class.number_of_legs
123
+ # sheep_class.foo # => raises NoMethodError exception
124
+ #
125
+ # Aliased by +quacks_like+
126
+ def responds_like(object)
127
+ @responder = object
128
+ self
129
+ end
130
+
131
+ # :stopdoc:
132
+
133
+ def initialize(name = nil, &block)
134
+ @name = name || DefaultName.new(self)
135
+ @expectations = ExpectationList.new
136
+ @everything_stubbed = false
137
+ @responder = nil
138
+ instance_eval(&block) if block
139
+ end
140
+
141
+ attr_reader :everything_stubbed, :expectations
142
+
143
+ alias_method :__expects__, :expects
144
+
145
+ alias_method :__stubs__, :stubs
146
+
147
+ alias_method :quacks_like, :responds_like
148
+
149
+ def stub_everything
150
+ @everything_stubbed = true
151
+ end
152
+
153
+ def method_missing(symbol, *arguments, &block)
154
+ if @responder and not @responder.respond_to?(symbol)
155
+ raise NoMethodError, "undefined method `#{symbol}' for #{self.mocha_inspect} which responds like #{@responder.mocha_inspect}"
156
+ end
157
+ if matching_expectation_allowing_invocation = @expectations.match_allowing_invocation(symbol, *arguments)
158
+ matching_expectation_allowing_invocation.invoke(&block)
159
+ else
160
+ if (matching_expectation = @expectations.match(symbol, *arguments)) || (!matching_expectation && !@everything_stubbed)
161
+ message = UnexpectedInvocation.new(self, symbol, *arguments).to_s
162
+ message << Mockery.instance.mocha_inspect
163
+ raise ExpectationError.new(message, caller)
164
+ end
165
+ end
166
+ end
167
+
168
+ def respond_to?(symbol, include_private = false)
169
+ if @responder then
170
+ if @responder.method(:respond_to?).arity > 1
171
+ @responder.respond_to?(symbol, include_private)
172
+ else
173
+ @responder.respond_to?(symbol)
174
+ end
175
+ else
176
+ @everything_stubbed || @expectations.matches_method?(symbol)
177
+ end
178
+ end
179
+
180
+ def __verified__?(assertion_counter = nil)
181
+ @expectations.verified?(assertion_counter)
182
+ end
183
+
184
+ def mocha_inspect
185
+ @name.mocha_inspect
186
+ end
187
+
188
+ def inspect
189
+ mocha_inspect
190
+ end
191
+
192
+ def ensure_method_not_already_defined(method_name)
193
+ self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
194
+ end
195
+
196
+ # :startdoc:
197
+
198
+ end
199
+
200
+ end
@@ -0,0 +1,181 @@
1
+ require 'mocha/central'
2
+ require 'mocha/mock'
3
+ require 'mocha/names'
4
+ require 'mocha/state_machine'
5
+ require 'mocha/logger'
6
+ require 'mocha/configuration'
7
+ require 'mocha/stubbing_error'
8
+
9
+ module Mocha
10
+
11
+ class Mockery
12
+
13
+ class << self
14
+
15
+ def instance
16
+ @instance ||= new
17
+ end
18
+
19
+ def reset_instance
20
+ @instance = nil
21
+ end
22
+
23
+ end
24
+
25
+ def named_mock(name, &block)
26
+ add_mock(Mock.new(Name.new(name), &block))
27
+ end
28
+
29
+ def unnamed_mock(&block)
30
+ add_mock(Mock.new(&block))
31
+ end
32
+
33
+ def mock_impersonating(object, &block)
34
+ add_mock(Mock.new(ImpersonatingName.new(object), &block))
35
+ end
36
+
37
+ def mock_impersonating_any_instance_of(klass, &block)
38
+ add_mock(Mock.new(ImpersonatingAnyInstanceName.new(klass), &block))
39
+ end
40
+
41
+ def new_state_machine(name)
42
+ add_state_machine(StateMachine.new(name))
43
+ end
44
+
45
+ def verify(assertion_counter = nil)
46
+ unless mocks.all? { |mock| mock.__verified__?(assertion_counter) }
47
+ message = "not all expectations were satisfied\n#{mocha_inspect}"
48
+ if unsatisfied_expectations.empty?
49
+ backtrace = caller
50
+ else
51
+ backtrace = unsatisfied_expectations[0].backtrace
52
+ end
53
+ raise ExpectationError.new(message, backtrace)
54
+ end
55
+ expectations.each do |e|
56
+ unless Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
57
+ unless e.used?
58
+ on_stubbing_method_unnecessarily(e)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def teardown
65
+ stubba.unstub_all
66
+ reset
67
+ end
68
+
69
+ def stubba
70
+ @stubba ||= Central.new
71
+ end
72
+
73
+ def mocks
74
+ @mocks ||= []
75
+ end
76
+
77
+ def state_machines
78
+ @state_machines ||= []
79
+ end
80
+
81
+ def mocha_inspect
82
+ message = ""
83
+ message << "unsatisfied expectations:\n- #{unsatisfied_expectations.map { |e| e.mocha_inspect }.join("\n- ")}\n" unless unsatisfied_expectations.empty?
84
+ message << "satisfied expectations:\n- #{satisfied_expectations.map { |e| e.mocha_inspect }.join("\n- ")}\n" unless satisfied_expectations.empty?
85
+ message << "states:\n- #{state_machines.map { |sm| sm.mocha_inspect }.join("\n- ")}" unless state_machines.empty?
86
+ message
87
+ end
88
+
89
+ def on_stubbing(object, method)
90
+ method = RUBY_VERSION < '1.9' ? method.to_s : method.to_sym
91
+ unless Mocha::Configuration.allow?(:stubbing_non_existent_method)
92
+ unless object.method_exists?(method, include_public_methods = true)
93
+ on_stubbing_non_existent_method(object, method)
94
+ end
95
+ end
96
+ unless Mocha::Configuration.allow?(:stubbing_non_public_method)
97
+ if object.method_exists?(method, include_public_methods = false)
98
+ on_stubbing_non_public_method(object, method)
99
+ end
100
+ end
101
+ unless Mocha::Configuration.allow?(:stubbing_method_on_non_mock_object)
102
+ on_stubbing_method_on_non_mock_object(object, method)
103
+ end
104
+ end
105
+
106
+ def on_stubbing_non_existent_method(object, method)
107
+ if Mocha::Configuration.prevent?(:stubbing_non_existent_method)
108
+ raise StubbingError.new("stubbing non-existent method: #{object.mocha_inspect}.#{method}", caller)
109
+ end
110
+ if Mocha::Configuration.warn_when?(:stubbing_non_existent_method)
111
+ logger.warn "stubbing non-existent method: #{object.mocha_inspect}.#{method}"
112
+ end
113
+ end
114
+
115
+ def on_stubbing_non_public_method(object, method)
116
+ if Mocha::Configuration.prevent?(:stubbing_non_public_method)
117
+ raise StubbingError.new("stubbing non-public method: #{object.mocha_inspect}.#{method}", caller)
118
+ end
119
+ if Mocha::Configuration.warn_when?(:stubbing_non_public_method)
120
+ logger.warn "stubbing non-public method: #{object.mocha_inspect}.#{method}"
121
+ end
122
+ end
123
+
124
+ def on_stubbing_method_on_non_mock_object(object, method)
125
+ if Mocha::Configuration.prevent?(:stubbing_method_on_non_mock_object)
126
+ raise StubbingError.new("stubbing method on non-mock object: #{object.mocha_inspect}.#{method}", caller)
127
+ end
128
+ if Mocha::Configuration.warn_when?(:stubbing_method_on_non_mock_object)
129
+ logger.warn "stubbing method on non-mock object: #{object.mocha_inspect}.#{method}"
130
+ end
131
+ end
132
+
133
+ def on_stubbing_method_unnecessarily(expectation)
134
+ if Mocha::Configuration.prevent?(:stubbing_method_unnecessarily)
135
+ raise StubbingError.new("stubbing method unnecessarily: #{expectation.method_signature}", expectation.backtrace)
136
+ end
137
+ if Mocha::Configuration.warn_when?(:stubbing_method_unnecessarily)
138
+ logger.warn "stubbing method unnecessarily: #{expectation.method_signature}"
139
+ end
140
+ end
141
+
142
+ attr_writer :logger
143
+
144
+ def logger
145
+ @logger ||= Logger.new($stderr)
146
+ end
147
+
148
+
149
+ private
150
+
151
+ def expectations
152
+ mocks.map { |mock| mock.expectations.to_a }.flatten
153
+ end
154
+
155
+ def unsatisfied_expectations
156
+ expectations.reject { |e| e.verified? }
157
+ end
158
+
159
+ def satisfied_expectations
160
+ expectations.select { |e| e.verified? }
161
+ end
162
+
163
+ def add_mock(mock)
164
+ mocks << mock
165
+ mock
166
+ end
167
+
168
+ def add_state_machine(state_machine)
169
+ state_machines << state_machine
170
+ state_machine
171
+ end
172
+
173
+ def reset
174
+ @stubba = nil
175
+ @mocks = nil
176
+ @state_machines = nil
177
+ end
178
+
179
+ end
180
+
181
+ end