mocha 1.4.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +58 -0
  3. data/.rubocop_todo.yml +50 -0
  4. data/README.md +12 -71
  5. data/RELEASE.md +19 -0
  6. data/Rakefile +35 -28
  7. data/bin/build-matrix +17 -18
  8. data/lib/mocha/any_instance_method.rb +19 -25
  9. data/lib/mocha/api.rb +1 -5
  10. data/lib/mocha/argument_iterator.rb +4 -8
  11. data/lib/mocha/backtrace_filter.rb +1 -5
  12. data/lib/mocha/cardinality.rb +20 -27
  13. data/lib/mocha/central.rb +21 -12
  14. data/lib/mocha/change_state_side_effect.rb +0 -4
  15. data/lib/mocha/class_method.rb +31 -37
  16. data/lib/mocha/class_methods.rb +11 -15
  17. data/lib/mocha/configuration.rb +69 -10
  18. data/lib/mocha/debug.rb +3 -2
  19. data/lib/mocha/deprecation.rb +4 -11
  20. data/lib/mocha/detection/mini_test.rb +0 -2
  21. data/lib/mocha/detection/test_unit.rb +4 -4
  22. data/lib/mocha/error_with_filtered_backtrace.rb +13 -0
  23. data/lib/mocha/exception_raiser.rb +2 -5
  24. data/lib/mocha/expectation.rb +15 -18
  25. data/lib/mocha/expectation_error.rb +2 -0
  26. data/lib/mocha/expectation_error_factory.rb +0 -1
  27. data/lib/mocha/expectation_list.rb +2 -6
  28. data/lib/mocha/hooks.rb +1 -3
  29. data/lib/mocha/in_state_ordering_constraint.rb +0 -4
  30. data/lib/mocha/inspect.rb +3 -5
  31. data/lib/mocha/instance_method.rb +0 -2
  32. data/lib/mocha/integration/mini_test/adapter.rb +2 -4
  33. data/lib/mocha/integration/mini_test/exception_translation.rb +1 -1
  34. data/lib/mocha/integration/mini_test/nothing.rb +4 -4
  35. data/lib/mocha/integration/mini_test/version_13.rb +4 -1
  36. data/lib/mocha/integration/mini_test/version_140.rb +4 -1
  37. data/lib/mocha/integration/mini_test/version_141.rb +4 -1
  38. data/lib/mocha/integration/mini_test/version_142_to_172.rb +4 -1
  39. data/lib/mocha/integration/mini_test/version_200.rb +4 -1
  40. data/lib/mocha/integration/mini_test/version_201_to_222.rb +4 -1
  41. data/lib/mocha/integration/mini_test/version_2110_to_2111.rb +4 -1
  42. data/lib/mocha/integration/mini_test/version_2112_to_320.rb +4 -1
  43. data/lib/mocha/integration/mini_test/version_230_to_2101.rb +4 -1
  44. data/lib/mocha/integration/monkey_patcher.rb +5 -7
  45. data/lib/mocha/integration/test_unit/adapter.rb +5 -6
  46. data/lib/mocha/integration/test_unit/gem_version_200.rb +5 -2
  47. data/lib/mocha/integration/test_unit/gem_version_201_to_202.rb +5 -2
  48. data/lib/mocha/integration/test_unit/gem_version_203_to_220.rb +5 -2
  49. data/lib/mocha/integration/test_unit/gem_version_230_to_250.rb +5 -2
  50. data/lib/mocha/integration/test_unit/nothing.rb +4 -4
  51. data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +4 -1
  52. data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +4 -1
  53. data/lib/mocha/integration.rb +3 -4
  54. data/lib/mocha/is_a.rb +0 -2
  55. data/lib/mocha/logger.rb +0 -4
  56. data/lib/mocha/method_matcher.rb +1 -5
  57. data/lib/mocha/minitest.rb +1 -1
  58. data/lib/mocha/mock.rb +25 -30
  59. data/lib/mocha/mockery.rb +62 -43
  60. data/lib/mocha/module_method.rb +0 -10
  61. data/lib/mocha/module_methods.rb +0 -4
  62. data/lib/mocha/multiple_yields.rb +0 -5
  63. data/lib/mocha/names.rb +1 -11
  64. data/lib/mocha/no_yields.rb +1 -7
  65. data/lib/mocha/not_initialized_error.rb +7 -0
  66. data/lib/mocha/object_methods.rb +16 -16
  67. data/lib/mocha/parameter_matchers/all_of.rb +1 -7
  68. data/lib/mocha/parameter_matchers/any_of.rb +1 -7
  69. data/lib/mocha/parameter_matchers/any_parameters.rb +3 -9
  70. data/lib/mocha/parameter_matchers/anything.rb +2 -8
  71. data/lib/mocha/parameter_matchers/base.rb +6 -12
  72. data/lib/mocha/parameter_matchers/equals.rb +0 -6
  73. data/lib/mocha/parameter_matchers/equivalent_uri.rb +6 -6
  74. data/lib/mocha/parameter_matchers/has_entries.rb +2 -6
  75. data/lib/mocha/parameter_matchers/has_entry.rb +8 -11
  76. data/lib/mocha/parameter_matchers/has_key.rb +2 -6
  77. data/lib/mocha/parameter_matchers/has_value.rb +2 -6
  78. data/lib/mocha/parameter_matchers/includes.rb +2 -6
  79. data/lib/mocha/parameter_matchers/instance_of.rb +0 -6
  80. data/lib/mocha/parameter_matchers/is_a.rb +2 -6
  81. data/lib/mocha/parameter_matchers/kind_of.rb +2 -6
  82. data/lib/mocha/parameter_matchers/not.rb +2 -6
  83. data/lib/mocha/parameter_matchers/object.rb +0 -2
  84. data/lib/mocha/parameter_matchers/optionally.rb +4 -10
  85. data/lib/mocha/parameter_matchers/regexp_matches.rb +0 -6
  86. data/lib/mocha/parameter_matchers/responds_with.rb +3 -8
  87. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +2 -6
  88. data/lib/mocha/parameter_matchers.rb +0 -2
  89. data/lib/mocha/parameters_matcher.rb +6 -9
  90. data/lib/mocha/pretty_parameters.rb +0 -4
  91. data/lib/mocha/receivers.rb +10 -14
  92. data/lib/mocha/return_values.rb +3 -7
  93. data/lib/mocha/sequence.rb +4 -9
  94. data/lib/mocha/single_return_value.rb +0 -4
  95. data/lib/mocha/single_yield.rb +0 -5
  96. data/lib/mocha/state_machine.rb +6 -10
  97. data/lib/mocha/stubbing_error.rb +2 -13
  98. data/lib/mocha/test_unit.rb +1 -1
  99. data/lib/mocha/thrower.rb +2 -5
  100. data/lib/mocha/unexpected_invocation.rb +3 -5
  101. data/lib/mocha/version.rb +1 -1
  102. data/lib/mocha/yield_parameters.rb +3 -7
  103. data/mocha.gemspec +34 -58
  104. data/test/acceptance/acceptance_test_helper.rb +0 -6
  105. data/test/acceptance/bug_18914_test.rb +7 -12
  106. data/test/acceptance/bug_21465_test.rb +0 -2
  107. data/test/acceptance/bug_21563_test.rb +0 -2
  108. data/test/acceptance/exception_rescue_test.rb +7 -8
  109. data/test/acceptance/expectations_on_multiple_methods_test.rb +2 -1
  110. data/test/acceptance/expected_invocation_count_test.rb +27 -29
  111. data/test/acceptance/failure_messages_test.rb +3 -5
  112. data/test/acceptance/issue_272_test.rb +0 -1
  113. data/test/acceptance/issue_65_test.rb +15 -13
  114. data/test/acceptance/issue_70_test.rb +0 -1
  115. data/test/acceptance/mocha_example_test.rb +5 -6
  116. data/test/acceptance/mocha_test_result_test.rb +7 -7
  117. data/test/acceptance/mock_test.rb +2 -4
  118. data/test/acceptance/mock_with_initializer_block_test.rb +0 -2
  119. data/test/acceptance/mocked_methods_dispatch_test.rb +0 -2
  120. data/test/acceptance/multiple_expectations_failure_message_test.rb +16 -17
  121. data/test/acceptance/optional_parameters_test.rb +0 -2
  122. data/test/acceptance/parameter_matcher_test.rb +2 -3
  123. data/test/acceptance/partial_mocks_test.rb +4 -6
  124. data/test/acceptance/prepend_test.rb +14 -16
  125. data/test/acceptance/prevent_use_of_mocha_outside_test_test.rb +77 -0
  126. data/test/acceptance/raise_exception_test.rb +2 -4
  127. data/test/acceptance/return_value_test.rb +0 -2
  128. data/test/acceptance/sequence_test.rb +9 -11
  129. data/test/acceptance/states_test.rb +6 -4
  130. data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +33 -2
  131. data/test/acceptance/stub_any_instance_method_test.rb +19 -17
  132. data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +8 -8
  133. data/test/acceptance/stub_class_method_defined_on_class_test.rb +2 -1
  134. data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -1
  135. data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +34 -1
  136. data/test/acceptance/stub_everything_test.rb +1 -3
  137. data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +6 -7
  138. data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -1
  139. data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -1
  140. data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +63 -1
  141. data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -1
  142. data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +2 -1
  143. data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -2
  144. data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -1
  145. data/test/acceptance/stub_module_method_test.rb +13 -13
  146. data/test/acceptance/stub_test.rb +1 -3
  147. data/test/acceptance/stubba_example_test.rb +6 -14
  148. data/test/acceptance/stubba_test_result_test.rb +5 -8
  149. data/test/acceptance/stubbing_error_backtrace_test.rb +2 -2
  150. data/test/acceptance/stubbing_frozen_object_test.rb +2 -1
  151. data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +12 -7
  152. data/test/acceptance/stubbing_method_unnecessarily_test.rb +0 -2
  153. data/test/acceptance/stubbing_nil_test.rb +4 -5
  154. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +1 -3
  155. data/test/acceptance/stubbing_non_existent_class_method_test.rb +3 -3
  156. data/test/acceptance/stubbing_non_existent_instance_method_test.rb +1 -3
  157. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +0 -2
  158. data/test/acceptance/stubbing_non_public_class_method_test.rb +3 -3
  159. data/test/acceptance/stubbing_non_public_instance_method_test.rb +1 -3
  160. data/test/acceptance/stubbing_on_non_mock_object_test.rb +4 -10
  161. data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +3 -4
  162. data/test/acceptance/throw_test.rb +0 -2
  163. data/test/acceptance/unexpected_invocation_test.rb +2 -3
  164. data/test/acceptance/unstubbing_test.rb +41 -14
  165. data/test/deprecation_disabler.rb +0 -1
  166. data/test/execution_point.rb +2 -4
  167. data/test/integration/mini_test_test.rb +2 -2
  168. data/test/integration/shared_tests.rb +24 -22
  169. data/test/integration/test_unit_test.rb +2 -2
  170. data/test/method_definer.rb +1 -3
  171. data/test/mini_test_result.rb +17 -11
  172. data/test/minitest_result.rb +0 -1
  173. data/test/simple_counter.rb +0 -2
  174. data/test/test_helper.rb +13 -5
  175. data/test/test_runner.rb +2 -4
  176. data/test/test_unit_result.rb +4 -2
  177. data/test/unit/any_instance_method_test.rb +31 -17
  178. data/test/unit/array_inspect_test.rb +2 -4
  179. data/test/unit/backtrace_filter_test.rb +3 -5
  180. data/test/unit/cardinality_test.rb +0 -2
  181. data/test/unit/central_test.rb +26 -27
  182. data/test/unit/change_state_side_effect_test.rb +0 -4
  183. data/test/unit/class_method_test.rb +59 -34
  184. data/test/unit/class_methods_test.rb +34 -5
  185. data/test/unit/configuration_test.rb +1 -2
  186. data/test/unit/date_time_inspect_test.rb +1 -3
  187. data/test/unit/exception_raiser_test.rb +0 -2
  188. data/test/unit/expectation_list_test.rb +0 -2
  189. data/test/unit/expectation_test.rb +41 -46
  190. data/test/unit/hash_inspect_test.rb +3 -5
  191. data/test/unit/hooks_test.rb +14 -8
  192. data/test/unit/in_state_ordering_constraint_test.rb +0 -4
  193. data/test/unit/method_matcher_test.rb +1 -3
  194. data/test/unit/mock_test.rb +35 -22
  195. data/test/unit/mockery_test.rb +45 -28
  196. data/test/unit/module_methods_test.rb +0 -2
  197. data/test/unit/multiple_yields_test.rb +0 -2
  198. data/test/unit/no_yields_test.rb +0 -2
  199. data/test/unit/object_inspect_test.rb +16 -7
  200. data/test/unit/object_methods_test.rb +22 -6
  201. data/test/unit/parameter_matchers/all_of_test.rb +0 -2
  202. data/test/unit/parameter_matchers/any_of_test.rb +0 -2
  203. data/test/unit/parameter_matchers/anything_test.rb +2 -4
  204. data/test/unit/parameter_matchers/equals_test.rb +1 -3
  205. data/test/unit/parameter_matchers/equivalent_uri_test.rb +0 -1
  206. data/test/unit/parameter_matchers/has_entries_test.rb +2 -2
  207. data/test/unit/parameter_matchers/has_entry_test.rb +13 -14
  208. data/test/unit/parameter_matchers/has_key_test.rb +0 -1
  209. data/test/unit/parameter_matchers/has_value_test.rb +0 -2
  210. data/test/unit/parameter_matchers/includes_test.rb +8 -9
  211. data/test/unit/parameter_matchers/instance_of_test.rb +1 -3
  212. data/test/unit/parameter_matchers/is_a_test.rb +1 -3
  213. data/test/unit/parameter_matchers/kind_of_test.rb +1 -3
  214. data/test/unit/parameter_matchers/not_test.rb +0 -2
  215. data/test/unit/parameter_matchers/regexp_matches_test.rb +1 -2
  216. data/test/unit/parameter_matchers/responds_with_test.rb +9 -3
  217. data/test/unit/parameter_matchers/stub_matcher.rb +0 -4
  218. data/test/unit/parameter_matchers/yaml_equivalent_test.rb +1 -3
  219. data/test/unit/parameters_matcher_test.rb +2 -4
  220. data/test/unit/receivers_test.rb +35 -5
  221. data/test/unit/return_values_test.rb +3 -5
  222. data/test/unit/sequence_test.rb +1 -5
  223. data/test/unit/single_return_value_test.rb +0 -2
  224. data/test/unit/single_yield_test.rb +0 -2
  225. data/test/unit/state_machine_test.rb +1 -3
  226. data/test/unit/string_inspect_test.rb +2 -4
  227. data/test/unit/thrower_test.rb +0 -2
  228. data/test/unit/yield_parameters_test.rb +0 -2
  229. data/yard-templates/default/layout/html/setup.rb +2 -3
  230. metadata +25 -6
@@ -1,11 +1,8 @@
1
1
  module Mocha
2
-
3
2
  class Cardinality
4
-
5
3
  INFINITY = 1 / 0.0
6
4
 
7
5
  class << self
8
-
9
6
  def exactly(count)
10
7
  new(count, count)
11
8
  end
@@ -20,15 +17,15 @@ module Mocha
20
17
 
21
18
  def times(range_or_count)
22
19
  case range_or_count
23
- when Range then new(range_or_count.first, range_or_count.last)
24
- else new(range_or_count, range_or_count)
20
+ when Range then new(range_or_count.first, range_or_count.last)
21
+ else new(range_or_count, range_or_count)
25
22
  end
26
23
  end
27
-
28
24
  end
29
25
 
30
26
  def initialize(required, maximum)
31
- @required, @maximum = required, maximum
27
+ @required = required
28
+ @maximum = maximum
32
29
  end
33
30
 
34
31
  def invocations_allowed?(invocation_count)
@@ -48,28 +45,26 @@ module Mocha
48
45
  end
49
46
 
50
47
  def allowed_any_number_of_times?
51
- required == 0 && infinite?(maximum)
48
+ required.zero? && infinite?(maximum)
52
49
  end
53
50
 
54
51
  def used?(invocation_count)
55
- (invocation_count > 0) || (maximum == 0)
52
+ (invocation_count > 0) || maximum.zero?
56
53
  end
57
54
 
58
55
  def mocha_inspect
59
56
  if allowed_any_number_of_times?
60
- "allowed any number of times"
57
+ 'allowed any number of times'
58
+ elsif required.zero? && maximum.zero?
59
+ 'expected never'
60
+ elsif required == maximum
61
+ "expected exactly #{times(required)}"
62
+ elsif infinite?(maximum)
63
+ "expected at least #{times(required)}"
64
+ elsif required.zero?
65
+ "expected at most #{times(maximum)}"
61
66
  else
62
- if required == 0 && maximum == 0
63
- "expected never"
64
- elsif required == maximum
65
- "expected exactly #{times(required)}"
66
- elsif infinite?(maximum)
67
- "expected at least #{times(required)}"
68
- elsif required == 0
69
- "expected at most #{times(maximum)}"
70
- else
71
- "expected between #{required} and #{times(maximum)}"
72
- end
67
+ "expected between #{required} and #{times(maximum)}"
73
68
  end
74
69
  end
75
70
 
@@ -79,17 +74,15 @@ module Mocha
79
74
 
80
75
  def times(number)
81
76
  case number
82
- when 0 then "no times"
83
- when 1 then "once"
84
- when 2 then "twice"
85
- else "#{number} times"
77
+ when 0 then 'no times'
78
+ when 1 then 'once'
79
+ when 2 then 'twice'
80
+ else "#{number} times"
86
81
  end
87
82
  end
88
83
 
89
84
  def infinite?(number)
90
85
  number.respond_to?(:infinite?) && number.infinite?
91
86
  end
92
-
93
87
  end
94
-
95
88
  end
data/lib/mocha/central.rb CHANGED
@@ -1,6 +1,19 @@
1
1
  module Mocha
2
-
3
2
  class Central
3
+ class Null < self
4
+ def initialize(&block)
5
+ super
6
+ @raise_not_initialized_error = block
7
+ end
8
+
9
+ def stub(*)
10
+ @raise_not_initialized_error.call
11
+ end
12
+
13
+ def unstub(*)
14
+ @raise_not_initialized_error.call
15
+ end
16
+ end
4
17
 
5
18
  attr_accessor :stubba_methods
6
19
 
@@ -9,25 +22,21 @@ module Mocha
9
22
  end
10
23
 
11
24
  def stub(method)
12
- unless stubba_methods.detect { |m| m.matches?(method) }
13
- method.stub
14
- stubba_methods.push(method)
15
- end
25
+ return if stubba_methods.detect { |m| m.matches?(method) }
26
+ method.stub
27
+ stubba_methods.push(method)
16
28
  end
17
29
 
18
30
  def unstub(method)
19
- if existing = stubba_methods.detect { |m| m.matches?(method) }
20
- existing.unstub
21
- stubba_methods.delete(existing)
22
- end
31
+ return unless (existing = stubba_methods.detect { |m| m.matches?(method) })
32
+ existing.unstub
33
+ stubba_methods.delete(existing)
23
34
  end
24
35
 
25
36
  def unstub_all
26
- while stubba_methods.any? do
37
+ while stubba_methods.any?
27
38
  unstub(stubba_methods.first)
28
39
  end
29
40
  end
30
-
31
41
  end
32
-
33
42
  end
@@ -1,7 +1,5 @@
1
1
  module Mocha
2
-
3
2
  class ChangeStateSideEffect
4
-
5
3
  def initialize(state)
6
4
  @state = state
7
5
  end
@@ -13,7 +11,5 @@ module Mocha
13
11
  def mocha_inspect
14
12
  "then #{@state.mocha_inspect}"
15
13
  end
16
-
17
14
  end
18
-
19
15
  end
@@ -2,16 +2,15 @@ require 'mocha/ruby_version'
2
2
  require 'metaclass'
3
3
 
4
4
  module Mocha
5
-
6
5
  class ClassMethod
7
-
8
6
  PrependedModule = Class.new(Module)
9
7
 
10
8
  attr_reader :stubbee, :method
11
9
 
12
10
  def initialize(stubbee, method)
13
11
  @stubbee = stubbee
14
- @original_method, @original_visibility = nil, nil
12
+ @original_method = nil
13
+ @original_visibility = nil
15
14
  @method = PRE_RUBY_V19 ? method.to_s : method.to_sym
16
15
  end
17
16
 
@@ -24,9 +23,8 @@ module Mocha
24
23
  remove_new_method
25
24
  restore_original_method
26
25
  mock.unstub(method.to_sym)
27
- unless mock.any_expectations?
28
- reset_mocha
29
- end
26
+ return if mock.any_expectations?
27
+ reset_mocha
30
28
  end
31
29
 
32
30
  def mock
@@ -38,21 +36,22 @@ module Mocha
38
36
  end
39
37
 
40
38
  def hide_original_method
41
- if @original_visibility = method_visibility(method)
42
- begin
43
- if RUBY_V2_PLUS
44
- @definition_target = PrependedModule.new
45
- stubbee.__metaclass__.__send__ :prepend, @definition_target
46
- else
47
- @original_method = stubbee._method(method)
48
- if @original_method && @original_method.owner == stubbee.__metaclass__
49
- stubbee.__metaclass__.send(:remove_method, method)
50
- end
39
+ return unless (@original_visibility = method_visibility(method))
40
+ begin
41
+ if RUBY_V2_PLUS
42
+ @definition_target = PrependedModule.new
43
+ stubbee.__metaclass__.__send__ :prepend, @definition_target
44
+ else
45
+ @original_method = stubbee._method(method)
46
+ if @original_method && @original_method.owner == stubbee.__metaclass__
47
+ stubbee.__metaclass__.send(:remove_method, method)
51
48
  end
52
- rescue NameError
53
- # deal with nasties like ActiveRecord::Associations::AssociationProxy
54
49
  end
50
+ # rubocop:disable Lint/HandleExceptions
51
+ rescue NameError
52
+ # deal with nasties like ActiveRecord::Associations::AssociationProxy
55
53
  end
54
+ # rubocop:enable Lint/HandleExceptions
56
55
  end
57
56
 
58
57
  def define_new_method
@@ -61,9 +60,8 @@ module Mocha
61
60
  mocha.method_missing(:#{method}, *args, &block)
62
61
  end
63
62
  CODE
64
- if @original_visibility
65
- Module.instance_method(@original_visibility).bind(definition_target).call(method)
66
- end
63
+ return unless @original_visibility
64
+ Module.instance_method(@original_visibility).bind(definition_target).call(method)
67
65
  end
68
66
 
69
67
  def remove_new_method
@@ -71,26 +69,24 @@ module Mocha
71
69
  end
72
70
 
73
71
  def restore_original_method
74
- unless RUBY_V2_PLUS
75
- if @original_method && @original_method.owner == stubbee.__metaclass__
76
- if PRE_RUBY_V19
77
- original_method = @original_method
78
- stubbee.__metaclass__.send(:define_method, method) do |*args, &block|
79
- original_method.call(*args, &block)
80
- end
81
- else
82
- stubbee.__metaclass__.send(:define_method, method, @original_method)
72
+ return if RUBY_V2_PLUS
73
+ if @original_method && @original_method.owner == stubbee.__metaclass__
74
+ if PRE_RUBY_V19
75
+ original_method = @original_method
76
+ stubbee.__metaclass__.send(:define_method, method) do |*args, &block|
77
+ original_method.call(*args, &block)
83
78
  end
84
- end
85
- if @original_visibility
86
- Module.instance_method(@original_visibility).bind(stubbee.__metaclass__).call(method)
79
+ else
80
+ stubbee.__metaclass__.send(:define_method, method, @original_method)
87
81
  end
88
82
  end
83
+ return unless @original_visibility
84
+ Module.instance_method(@original_visibility).bind(stubbee.__metaclass__).call(method)
89
85
  end
90
86
 
91
87
  def matches?(other)
92
- return false unless (other.class == self.class)
93
- (stubbee.object_id == other.stubbee.object_id) and (method == other.method)
88
+ return false unless other.class == self.class
89
+ (stubbee.object_id == other.stubbee.object_id) && (method == other.method)
94
90
  end
95
91
 
96
92
  alias_method :==, :eql?
@@ -113,7 +109,5 @@ module Mocha
113
109
  def definition_target
114
110
  @definition_target ||= stubbee.__metaclass__
115
111
  end
116
-
117
112
  end
118
-
119
113
  end
@@ -3,10 +3,8 @@ require 'mocha/class_method'
3
3
  require 'mocha/any_instance_method'
4
4
 
5
5
  module Mocha
6
-
7
6
  # Methods added to all classes to allow mocking and stubbing on real (i.e. non-mock) objects.
8
7
  module ClassMethods
9
-
10
8
  # @private
11
9
  def stubba_method
12
10
  Mocha::ClassMethod
@@ -14,33 +12,33 @@ module Mocha
14
12
 
15
13
  # @private
16
14
  class AnyInstance
17
-
18
15
  def initialize(klass)
19
16
  @stubba_object = klass
20
17
  end
21
18
 
22
- def mocha
23
- @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object)
19
+ def mocha(instantiate = true)
20
+ if instantiate
21
+ @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object)
22
+ else
23
+ defined?(@mocha) ? @mocha : nil
24
+ end
24
25
  end
25
26
 
26
27
  def stubba_method
27
28
  Mocha::AnyInstanceMethod
28
29
  end
29
30
 
30
- def stubba_object
31
- @stubba_object
32
- end
31
+ attr_reader :stubba_object
33
32
 
34
33
  def method_exists?(method, include_public_methods = true)
35
34
  if include_public_methods
36
- return true if @stubba_object.public_instance_methods(include_superclass_methods = true).include?(method)
35
+ return true if @stubba_object.public_instance_methods(true).include?(method)
37
36
  return true if @stubba_object.allocate.respond_to?(method.to_sym)
38
37
  end
39
- return true if @stubba_object.protected_instance_methods(include_superclass_methods = true).include?(method)
40
- return true if @stubba_object.private_instance_methods(include_superclass_methods = true).include?(method)
41
- return false
38
+ return true if @stubba_object.protected_instance_methods(true).include?(method)
39
+ return true if @stubba_object.private_instance_methods(true).include?(method)
40
+ false
42
41
  end
43
-
44
42
  end
45
43
 
46
44
  # @return [Mock] a mock object which will detect calls to any instance of this class.
@@ -58,7 +56,5 @@ module Mocha
58
56
  end
59
57
  @any_instance ||= AnyInstance.new(self)
60
58
  end
61
-
62
59
  end
63
-
64
60
  end
@@ -1,18 +1,80 @@
1
1
  module Mocha
2
-
3
- # Configuration settings.
2
+ # This class allows you to determine what should happen under certain circumstances. In each scenario, Mocha can be configured to {.allow do nothing}, {.warn_when display a warning message}, or {.prevent raise an exception}. The relevant scenario is identified using one of the following symbols:
3
+ #
4
+ # * +:stubbing_method_unnecessarily+ This is useful for identifying unused stubs. Unused stubs are often accidentally introduced when code is {http://martinfowler.com/bliki/DefinitionOfRefactoring.html refactored}. Allowed by default.
5
+ # * +:stubbing_non_existent_method+ - This is useful if you want to ensure that methods you're mocking really exist. A common criticism of unit tests with mock objects is that such a test may (incorrectly) pass when an equivalent non-mocking test would (correctly) fail. While you should always have some integration tests, particularly for critical business functionality, this Mocha configuration setting should catch scenarios when mocked methods and real methods have become misaligned. Allowed by default.
6
+ # * +:stubbing_non_public_method+ - Many people think that it's good practice only to mock public methods. This is one way to prevent your tests being too tightly coupled to the internal implementation of a class. Such tests tend to be very brittle and not much use when refactoring. Allowed by default.
7
+ # * +:stubbing_method_on_non_mock_object+ - If you like the idea of {http://www.jmock.org/oopsla2004.pdf mocking roles not objects} and {http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html you don't like stubbing concrete classes}, this is the setting for you. However, while this restriction makes a lot of sense in Java with its {http://java.sun.com/docs/books/tutorial/java/concepts/interface.html explicit interfaces}, it may be moot in Ruby where roles are probably best represented as Modules. Allowed by default.
8
+ # * +:stubbing_method_on_nil+ - This is usually done accidentally, but there might be rare cases where it is intended. Prevented by default.
9
+ #
10
+ # @example Preventing unnecessary stubbing of a method
11
+ # Mocha::Configuration.prevent(:stubbing_method_unnecessarily)
12
+ #
13
+ # example = mock('example')
14
+ # example.stubs(:unused_stub)
15
+ # # => Mocha::StubbingError: stubbing method unnecessarily:
16
+ # # => #<Mock:example>.unused_stub(any_parameters)
17
+ #
18
+ # @example Preventing stubbing of a method on a non-mock object
19
+ # Mocha::Configuration.prevent(:stubbing_method_on_non_mock_object)
20
+ #
21
+ # class Example
22
+ # def example_method; end
23
+ # end
24
+ #
25
+ # example = Example.new
26
+ # example.stubs(:example_method)
27
+ # # => Mocha::StubbingError: stubbing method on non-mock object:
28
+ # # => #<Example:0x593620>.example_method
29
+ #
30
+ # @example Preventing stubbing of a non-existent method
31
+ #
32
+ # Mocha::Configuration.prevent(:stubbing_non_existent_method)
33
+ #
34
+ # class Example
35
+ # end
36
+ #
37
+ # example = Example.new
38
+ # example.stubs(:method_that_doesnt_exist)
39
+ # # => Mocha::StubbingError: stubbing non-existent method:
40
+ # # => #<Example:0x593760>.method_that_doesnt_exist
41
+ #
42
+ # @example Preventing stubbing of a non-public method
43
+ # Mocha::Configuration.prevent(:stubbing_non_public_method)
44
+ #
45
+ # class Example
46
+ # def internal_method; end
47
+ # private :internal_method
48
+ # end
49
+ #
50
+ # example = Example.new
51
+ # example.stubs(:internal_method)
52
+ # # => Mocha::StubbingError: stubbing non-public method:
53
+ # # => #<Example:0x593530>.internal_method
54
+ #
55
+ # Typically the configuration would be set globally in a +test_helper.rb+ or +spec_helper.rb+ file. However, it can also be temporarily overridden locally using the block syntax of the relevant method. In the latter case, the original configuration settings are restored when the block is exited.
56
+ #
57
+ # @example Temporarily allowing stubbing of a non-existent method
58
+ # Mocha::Configuration.prevent(:stubbing_non_public_method)
59
+ #
60
+ # class Example
61
+ # end
62
+ #
63
+ # Mocha::Configuration.allow(:stubbing_non_existent_method) do
64
+ # example = Example.new
65
+ # example.stubs(:method_that_doesnt_exist)
66
+ # # => no exception raised
67
+ # end
4
68
  class Configuration
5
-
6
69
  DEFAULTS = {
7
70
  :stubbing_method_unnecessarily => :allow,
8
71
  :stubbing_method_on_non_mock_object => :allow,
9
72
  :stubbing_non_existent_method => :allow,
10
73
  :stubbing_non_public_method => :allow,
11
- :stubbing_method_on_nil => :prevent,
12
- }
74
+ :stubbing_method_on_nil => :prevent
75
+ }.freeze
13
76
 
14
77
  class << self
15
-
16
78
  # Allow the specified +action+.
17
79
  #
18
80
  # @param [Symbol] action one of +:stubbing_method_unnecessarily+, +:stubbing_method_on_non_mock_object+, +:stubbing_non_existent_method+, +:stubbing_non_public_method+, +:stubbing_method_on_nil+.
@@ -74,16 +136,13 @@ module Mocha
74
136
  end
75
137
 
76
138
  # @private
77
- def temporarily_change_config(action, new_value, &block)
139
+ def temporarily_change_config(action, new_value)
78
140
  original_value = configuration[action]
79
141
  configuration[action] = new_value
80
142
  yield
81
143
  ensure
82
144
  configuration[action] = original_value
83
145
  end
84
-
85
146
  end
86
-
87
147
  end
88
-
89
148
  end
data/lib/mocha/debug.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Mocha
2
2
  module Debug
3
3
  OPTIONS = (ENV['MOCHA_OPTIONS'] || '').split(',').inject({}) do |hash, key|
4
- hash[key] = true; hash
4
+ hash[key] = true
5
+ hash
5
6
  end.freeze
6
7
 
7
8
  def self.puts(message)
8
- $stderr.puts(message) if OPTIONS['debug']
9
+ warn(message) if OPTIONS['debug']
9
10
  end
10
11
  end
11
12
  end
@@ -1,27 +1,20 @@
1
1
  require 'mocha/backtrace_filter'
2
2
 
3
3
  module Mocha
4
-
5
4
  class Deprecation
6
-
7
5
  class << self
8
-
9
6
  attr_accessor :mode, :messages
10
7
 
11
8
  def warning(message)
12
9
  @messages << message
13
- unless mode == :disabled
14
- filter = BacktraceFilter.new
15
- location = filter.filtered(caller)[0]
16
- $stderr.puts "Mocha deprecation warning at #{location}: #{message}"
17
- end
10
+ return if mode == :disabled
11
+ filter = BacktraceFilter.new
12
+ location = filter.filtered(caller)[0]
13
+ warn "Mocha deprecation warning at #{location}: #{message}"
18
14
  end
19
-
20
15
  end
21
16
 
22
17
  self.mode = :enabled
23
18
  self.messages = []
24
-
25
19
  end
26
-
27
20
  end
@@ -6,8 +6,6 @@ module Mocha
6
6
  ::Minitest::Test
7
7
  elsif defined?(::MiniTest::Unit::TestCase)
8
8
  ::MiniTest::Unit::TestCase
9
- else
10
- nil
11
9
  end
12
10
  end
13
11
 
@@ -3,11 +3,9 @@ module Mocha
3
3
  module TestUnit
4
4
  def self.testcase
5
5
  if defined?(::Test::Unit::TestCase) &&
6
- !(defined?(::MiniTest::Unit::TestCase) && (::Test::Unit::TestCase < ::MiniTest::Unit::TestCase)) &&
7
- !(defined?(::MiniTest::Spec) && (::Test::Unit::TestCase < ::MiniTest::Spec))
6
+ !(defined?(::MiniTest::Unit::TestCase) && (::Test::Unit::TestCase < ::MiniTest::Unit::TestCase)) &&
7
+ !(defined?(::MiniTest::Spec) && (::Test::Unit::TestCase < ::MiniTest::Spec))
8
8
  ::Test::Unit::TestCase
9
- else
10
- nil
11
9
  end
12
10
  end
13
11
 
@@ -16,8 +14,10 @@ module Mocha
16
14
  if testcase
17
15
  begin
18
16
  require 'test/unit/version'
17
+ # rubocop:disable Lint/HandleExceptions
19
18
  rescue LoadError
20
19
  end
20
+ # rubocop:enable Lint/HandleExceptions
21
21
  if defined?(::Test::Unit::VERSION)
22
22
  version = ::Test::Unit::VERSION
23
23
  end
@@ -0,0 +1,13 @@
1
+ require 'mocha/backtrace_filter'
2
+
3
+ module Mocha
4
+ # @private
5
+ class ErrorWithFilteredBacktrace < StandardError
6
+ # @private
7
+ def initialize(message = nil, backtrace = [])
8
+ super(message)
9
+ filter = BacktraceFilter.new
10
+ set_backtrace(filter.filtered(backtrace))
11
+ end
12
+ end
13
+ end
@@ -1,9 +1,8 @@
1
1
  module Mocha
2
-
3
2
  class ExceptionRaiser
4
-
5
3
  def initialize(exception, message)
6
- @exception, @message = exception, message
4
+ @exception = exception
5
+ @message = message
7
6
  end
8
7
 
9
8
  def evaluate
@@ -11,7 +10,5 @@ module Mocha
11
10
  raise @exception, @message if @message
12
11
  raise @exception
13
12
  end
14
-
15
13
  end
16
-
17
14
  end
@@ -11,10 +11,8 @@ require 'mocha/change_state_side_effect'
11
11
  require 'mocha/cardinality'
12
12
 
13
13
  module Mocha
14
-
15
14
  # Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}.
16
15
  class Expectation
17
-
18
16
  # Modifies expectation so that the number of calls to the expected method must be within a specific +range+.
19
17
  #
20
18
  # @param [Range,Integer] range specifies the allowable range in the number of expected invocations.
@@ -184,7 +182,7 @@ module Mocha
184
182
  # object = mock()
185
183
  # object.expects(:expected_method).at_most_once
186
184
  # 2.times { object.expected_method } # => unexpected invocation
187
- def at_most_once()
185
+ def at_most_once
188
186
  at_most(1)
189
187
  self
190
188
  end
@@ -506,7 +504,8 @@ module Mocha
506
504
  @parameters_matcher = ParametersMatcher.new
507
505
  @ordering_constraints = []
508
506
  @side_effects = []
509
- @cardinality, @invocation_count = Cardinality.exactly(1), 0
507
+ @cardinality = Cardinality.exactly(1)
508
+ @invocation_count = 0
510
509
  @return_values = ReturnValues.new
511
510
  @yield_parameters = YieldParameters.new
512
511
  @backtrace = backtrace || caller
@@ -529,12 +528,12 @@ module Mocha
529
528
 
530
529
  # @private
531
530
  def perform_side_effects
532
- @side_effects.each { |side_effect| side_effect.perform }
531
+ @side_effects.each(&:perform)
533
532
  end
534
533
 
535
534
  # @private
536
535
  def in_correct_order?
537
- @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? }
536
+ @ordering_constraints.all?(&:allows_invocation_now?)
538
537
  end
539
538
 
540
539
  # @private
@@ -560,8 +559,8 @@ module Mocha
560
559
  # @private
561
560
  def invoke
562
561
  @invocation_count += 1
563
- perform_side_effects()
564
- if block_given? then
562
+ perform_side_effects
563
+ if block_given?
565
564
  @yield_parameters.next_invocation.each do |yield_parameters|
566
565
  yield(*yield_parameters)
567
566
  end
@@ -584,21 +583,21 @@ module Mocha
584
583
  def inspect
585
584
  address = __id__ * 2
586
585
  address += 0x100000000 if address < 0
587
- "#<Expectation:0x#{'%x' % address} #{mocha_inspect} >"
586
+ "#<Expectation:0x#{format('%x', address)} #{mocha_inspect} >"
588
587
  end
589
588
 
590
589
  # @private
591
590
  def mocha_inspect
592
591
  message = "#{@cardinality.mocha_inspect}, "
593
592
  message << case @invocation_count
594
- when 0 then "not yet invoked"
595
- when 1 then "invoked once"
596
- when 2 then "invoked twice"
597
- else "invoked #{@invocation_count} times"
598
- end
599
- message << ": "
593
+ when 0 then 'not yet invoked'
594
+ when 1 then 'invoked once'
595
+ when 2 then 'invoked twice'
596
+ else "invoked #{@invocation_count} times"
597
+ end
598
+ message << ': '
600
599
  message << method_signature
601
- message << "; #{@ordering_constraints.map { |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty?
600
+ message << "; #{@ordering_constraints.map(&:mocha_inspect).join('; ')}" unless @ordering_constraints.empty?
602
601
  message
603
602
  end
604
603
 
@@ -606,7 +605,5 @@ module Mocha
606
605
  def method_signature
607
606
  "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
608
607
  end
609
-
610
608
  end
611
-
612
609
  end
@@ -4,5 +4,7 @@ module Mocha
4
4
  # Authors of test libraries may use +Mocha::ExpectationErrorFactory+ to have Mocha raise a different exception.
5
5
  #
6
6
  # @see Mocha::ExpectationErrorFactory
7
+ # rubocop:disable Lint/InheritException
7
8
  class ExpectationError < Exception; end
9
+ # rubocop:enable Lint/InheritException
8
10
  end