mocha 2.8.0 → 3.0.0.pre.rc.2

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +37 -3
  3. data/.rubocop_todo.yml +25 -13
  4. data/.yardopts +2 -0
  5. data/Gemfile +9 -28
  6. data/README.md +3 -4
  7. data/RELEASE.md +64 -0
  8. data/Rakefile +43 -22
  9. data/gemfiles/Gemfile.minitest.latest +3 -3
  10. data/gemfiles/Gemfile.rubocop +9 -0
  11. data/gemfiles/Gemfile.test-unit.latest +3 -3
  12. data/lib/mocha/any_instance_method.rb +6 -4
  13. data/lib/mocha/any_instance_receiver.rb +20 -0
  14. data/lib/mocha/api.rb +4 -2
  15. data/lib/mocha/argument_iterator.rb +5 -5
  16. data/lib/mocha/backtrace_filter.rb +2 -0
  17. data/lib/mocha/{block_matcher.rb → block_matchers.rb} +2 -0
  18. data/lib/mocha/cardinality.rb +2 -2
  19. data/lib/mocha/central.rb +4 -0
  20. data/lib/mocha/change_state_side_effect.rb +2 -0
  21. data/lib/mocha/class_methods.rb +14 -9
  22. data/lib/mocha/configuration.rb +18 -41
  23. data/lib/mocha/default_name.rb +15 -0
  24. data/lib/mocha/default_receiver.rb +13 -0
  25. data/lib/mocha/deprecation.rb +15 -9
  26. data/lib/mocha/detection/minitest.rb +2 -0
  27. data/lib/mocha/detection/test_unit.rb +4 -1
  28. data/lib/mocha/error_with_filtered_backtrace.rb +2 -0
  29. data/lib/mocha/exception_raiser.rb +3 -0
  30. data/lib/mocha/expectation.rb +57 -23
  31. data/lib/mocha/expectation_error.rb +2 -0
  32. data/lib/mocha/expectation_error_factory.rb +2 -0
  33. data/lib/mocha/expectation_list.rb +3 -1
  34. data/lib/mocha/hooks.rb +6 -4
  35. data/lib/mocha/ignoring_warning.rb +20 -0
  36. data/lib/mocha/impersonating_any_instance_name.rb +13 -0
  37. data/lib/mocha/impersonating_name.rb +13 -0
  38. data/lib/mocha/in_state_ordering_constraint.rb +2 -0
  39. data/lib/mocha/inspect.rb +13 -10
  40. data/lib/mocha/instance_method.rb +6 -4
  41. data/lib/mocha/integration/assertion_counter.rb +2 -0
  42. data/lib/mocha/integration/minitest/adapter.rb +7 -3
  43. data/lib/mocha/integration/minitest.rb +5 -4
  44. data/lib/mocha/integration/monkey_patcher.rb +4 -2
  45. data/lib/mocha/integration/test_unit/adapter.rb +10 -4
  46. data/lib/mocha/integration/test_unit.rb +5 -4
  47. data/lib/mocha/integration.rb +5 -0
  48. data/lib/mocha/invocation.rb +9 -6
  49. data/lib/mocha/logger.rb +2 -0
  50. data/lib/mocha/macos_version.rb +2 -0
  51. data/lib/mocha/method_matcher.rb +2 -0
  52. data/lib/mocha/minitest.rb +2 -1
  53. data/lib/mocha/mock.rb +16 -12
  54. data/lib/mocha/mockery.rb +35 -17
  55. data/lib/mocha/name.rb +13 -0
  56. data/lib/mocha/not_initialized_error.rb +2 -0
  57. data/lib/mocha/object_methods.rb +20 -6
  58. data/lib/mocha/object_receiver.rb +20 -0
  59. data/lib/mocha/parameter_matchers/all_of.rb +3 -6
  60. data/lib/mocha/parameter_matchers/any_of.rb +3 -6
  61. data/lib/mocha/parameter_matchers/any_parameters.rb +3 -6
  62. data/lib/mocha/parameter_matchers/anything.rb +3 -6
  63. data/lib/mocha/parameter_matchers/{base.rb → base_methods.rb} +2 -16
  64. data/lib/mocha/parameter_matchers/equals.rb +3 -6
  65. data/lib/mocha/parameter_matchers/equivalent_uri.rb +9 -10
  66. data/lib/mocha/parameter_matchers/has_entries.rb +4 -7
  67. data/lib/mocha/parameter_matchers/has_entry.rb +5 -7
  68. data/lib/mocha/parameter_matchers/has_key.rb +5 -7
  69. data/lib/mocha/parameter_matchers/has_keys.rb +5 -8
  70. data/lib/mocha/parameter_matchers/has_value.rb +5 -7
  71. data/lib/mocha/parameter_matchers/includes.rb +6 -12
  72. data/lib/mocha/parameter_matchers/instance_methods.rb +5 -3
  73. data/lib/mocha/parameter_matchers/instance_of.rb +3 -6
  74. data/lib/mocha/parameter_matchers/is_a.rb +4 -7
  75. data/lib/mocha/parameter_matchers/kind_of.rb +3 -6
  76. data/lib/mocha/parameter_matchers/not.rb +3 -6
  77. data/lib/mocha/parameter_matchers/optionally.rb +2 -5
  78. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +39 -19
  79. data/lib/mocha/parameter_matchers/regexp_matches.rb +4 -6
  80. data/lib/mocha/parameter_matchers/responds_with.rb +3 -6
  81. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +3 -6
  82. data/lib/mocha/parameter_matchers.rb +2 -1
  83. data/lib/mocha/parameters_matcher.rb +9 -1
  84. data/lib/mocha/raised_exception.rb +2 -0
  85. data/lib/mocha/return_values.rb +2 -0
  86. data/lib/mocha/ruby_version.rb +3 -0
  87. data/lib/mocha/sequence.rb +2 -0
  88. data/lib/mocha/single_return_value.rb +1 -1
  89. data/lib/mocha/state_machine.rb +3 -1
  90. data/lib/mocha/stubbed_method.rb +15 -8
  91. data/lib/mocha/stubbing_error.rb +2 -0
  92. data/lib/mocha/test_unit.rb +2 -1
  93. data/lib/mocha/thrower.rb +2 -0
  94. data/lib/mocha/thrown_object.rb +2 -0
  95. data/lib/mocha/version.rb +3 -1
  96. data/lib/mocha/yield_parameters.rb +2 -0
  97. data/lib/mocha.rb +20 -0
  98. data/mocha.gemspec +10 -4
  99. metadata +18 -12
  100. data/lib/mocha/debug.rb +0 -9
  101. data/lib/mocha/integration/minitest/exception_translation.rb +0 -14
  102. data/lib/mocha/is_a.rb +0 -7
  103. data/lib/mocha/names.rb +0 -43
  104. data/lib/mocha/parameter_matchers/deprecations.rb +0 -46
  105. data/lib/mocha/receivers.rb +0 -45
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/ruby_version'
2
4
  require 'mocha/deprecation'
3
5
 
@@ -14,7 +16,6 @@ module Mocha
14
16
  # Mocha.configure do |c|
15
17
  # c.stubbing_method_unnecessarily = :prevent
16
18
  # c.stubbing_method_on_non_mock_object = :warn
17
- # c.stubbing_method_on_nil = :allow
18
19
  # end
19
20
  #
20
21
  def self.configure
@@ -34,7 +35,6 @@ module Mocha
34
35
  # Mocha.configure do |c|
35
36
  # c.stubbing_method_unnecessarily = :prevent
36
37
  # c.stubbing_method_on_non_mock_object = :warn
37
- # c.stubbing_method_on_nil = :allow
38
38
  # end
39
39
  #
40
40
  class Configuration
@@ -44,9 +44,8 @@ module Mocha
44
44
  stubbing_method_on_non_mock_object: :allow,
45
45
  stubbing_non_existent_method: :allow,
46
46
  stubbing_non_public_method: :allow,
47
- stubbing_method_on_nil: :prevent,
48
47
  display_matching_invocations_on_failure: false,
49
- strict_keyword_argument_matching: false
48
+ strict_keyword_argument_matching: Mocha::RUBY_V30_PLUS
50
49
  }.freeze
51
50
 
52
51
  attr_reader :options
@@ -196,33 +195,6 @@ module Mocha
196
195
  @options[:stubbing_non_public_method]
197
196
  end
198
197
 
199
- # Configure whether stubbing methods on the +nil+ object is allowed.
200
- #
201
- # This is usually done accidentally, but there might be rare cases where it is intended.
202
- #
203
- # This option only works for Ruby < v2.2.0. In later versions of Ruby +nil+ is frozen and so a {StubbingError} will be raised if you attempt to stub a method on +nil+.
204
- #
205
- # When +value+ is +:allow+, do nothing.
206
- # When +value+ is +:warn+, display a warning.
207
- # When +value+ is +:prevent+, raise a {StubbingError}. This is the default.
208
- #
209
- # @param [Symbol] value one of +:allow+, +:warn+, +:prevent+.
210
- # @deprecated This method is deprecated and will be removed in a future release. +nil+ is frozen in Ruby >= v2.2 and Mocha will be dropping support for Ruby v2.1. At that point it won't be possible to stub methods on +nil+ any more.
211
- #
212
- def stubbing_method_on_nil=(value)
213
- Deprecation.warning([
214
- '`Mocha::Configuration#stubbing_method_on_nil=` is deprecated and will be removed in a future release.',
215
- '`nil` is frozen in Ruby >= v2.2 and Mocha will be dropping support for Ruby v2.1.',
216
- "At that point it won't be possible to stub methods on `nil` any more."
217
- ].join(' '))
218
- @options[:stubbing_method_on_nil] = value
219
- end
220
-
221
- # @private
222
- def stubbing_method_on_nil
223
- @options[:stubbing_method_on_nil]
224
- end
225
-
226
198
  # Display matching invocations alongside expectations on Mocha-related test failure.
227
199
  #
228
200
  # @param [Boolean] value +true+ to enable display of matching invocations; disabled by default.
@@ -259,17 +231,21 @@ module Mocha
259
231
 
260
232
  # Perform strict keyword argument comparison. Only supported in Ruby >= v2.7.
261
233
  #
262
- # When this option is set to +false+ a positional +Hash+ and a set of keyword arguments are treated the same during comparison, which can lead to misleading passing tests in Ruby >= v3.0 (see examples below). However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa. This is because {#strict_keyword_argument_matching=} will default to +true+ in the future.
234
+ # When this option is set to +false+ a positional +Hash+ and a set of keyword arguments are treated the same during comparison, which can lead to misleading passing tests in Ruby >= v3.0 (see examples below). However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa.
263
235
  #
264
236
  # For more details on keyword arguments in Ruby v3, refer to {https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0 this article}.
265
237
  #
266
238
  # Note that +Hash+-related matchers such as {ParameterMatchers::Methods#has_value} or {ParameterMatchers::Methods#has_key} will still treat a positional +Hash+ and a set of keyword arguments the same, so misleading passing tests are still possible when they are used.
267
239
  #
268
- # This configuration option is +false+ by default to enable gradual adoption, but will be +true+ by default in the future.
240
+ # This configuration option is +false+ by default in Ruby v2.7 to enable gradual adoption, but +true+ by default in Ruby >= v3.0.
269
241
  #
270
- # @param [Boolean] value +true+ to enable strict keyword argument matching; +false+ by default.
242
+ # @param [Boolean] value +true+ to enable strict keyword argument matching.
271
243
  #
272
- # @example Loose keyword argument matching (default)
244
+ # @example Loose keyword argument matching (default in Ruby v2.7)
245
+ #
246
+ # Mocha.configure do |c|
247
+ # c.strict_keyword_argument_matching = false
248
+ # end
273
249
  #
274
250
  # class Example
275
251
  # def foo(a, bar:); end
@@ -280,7 +256,7 @@ module Mocha
280
256
  # example.foo('a', { bar: 'b' })
281
257
  # # This passes the test, but would result in an ArgumentError in practice
282
258
  #
283
- # @example Strict keyword argument matching
259
+ # @example Strict keyword argument matching (default in Ruby >= v3.0)
284
260
  #
285
261
  # Mocha.configure do |c|
286
262
  # c.strict_keyword_argument_matching = true
@@ -296,6 +272,7 @@ module Mocha
296
272
  # # This now fails as expected
297
273
  def strict_keyword_argument_matching=(value)
298
274
  raise 'Strict keyword argument matching requires Ruby 2.7 and above.' unless Mocha::RUBY_V27_PLUS
275
+
299
276
  @options[:strict_keyword_argument_matching] = value
300
277
  end
301
278
 
@@ -318,9 +295,9 @@ module Mocha
318
295
  # @param [Hash] temporary_options the configuration options to apply for the duration of the block.
319
296
  # @yield block during which the configuration change will be in force.
320
297
  #
321
- # @example Temporarily allow stubbing of +nil+
322
- # Mocha::Configuration.override(stubbing_method_on_nil: :allow) do
323
- # nil.stubs(:foo)
298
+ # @example Temporarily prevent stubbing of non-mock object
299
+ # Mocha::Configuration.override(stubbing_method_on_non_mock_object: :prevent) do
300
+ # 123.stubs(:to_s).returns('456')
324
301
  # end
325
302
  def override(temporary_options)
326
303
  original_configuration = configuration
@@ -342,7 +319,7 @@ module Mocha
342
319
  if block_given?
343
320
  temporarily_change_config action, new_value, &block
344
321
  else
345
- configuration.send("#{action}=".to_sym, new_value)
322
+ configuration.send(:"#{action}=", new_value)
346
323
  end
347
324
  end
348
325
 
@@ -350,7 +327,7 @@ module Mocha
350
327
  def temporarily_change_config(action, new_value)
351
328
  original_configuration = configuration
352
329
  new_configuration = configuration.dup
353
- new_configuration.send("#{action}=".to_sym, new_value)
330
+ new_configuration.send(:"#{action}=", new_value)
354
331
  @configuration = new_configuration
355
332
  yield
356
333
  ensure
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class DefaultName
5
+ def initialize(mock)
6
+ @mock = mock
7
+ end
8
+
9
+ def mocha_inspect
10
+ address = @mock.__id__ * 2
11
+ address += 0x100000000 if address < 0
12
+ "#<Mock:0x#{format('%<address>x', address: address)}>"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class DefaultReceiver
5
+ def initialize(mock)
6
+ @mock = mock
7
+ end
8
+
9
+ def mocks
10
+ [@mock]
11
+ end
12
+ end
13
+ end
@@ -1,21 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/backtrace_filter'
2
4
 
3
5
  module Mocha
4
6
  class Deprecation
5
- class << self
6
- attr_accessor :mode, :messages
7
-
8
- def warning(*messages)
9
- message = messages.join
10
- @messages << message
11
- return if mode == :disabled
7
+ class Logger
8
+ def warning(message)
12
9
  filter = BacktraceFilter.new
13
10
  location = filter.filtered(caller)[0]
14
11
  warn "Mocha deprecation warning at #{location}: #{message}"
15
12
  end
16
13
  end
17
14
 
18
- self.mode = :enabled
19
- self.messages = []
15
+ class << self
16
+ attr_writer :logger
17
+
18
+ def warning(message)
19
+ logger.call(message)
20
+ end
21
+
22
+ def logger
23
+ @logger ||= Logger.new
24
+ end
25
+ end
20
26
  end
21
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module Detection
3
5
  module Minitest
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module Detection
3
5
  module TestUnit
@@ -14,7 +16,8 @@ module Mocha
14
16
  if testcase
15
17
  begin
16
18
  require 'test/unit/version'
17
- rescue LoadError # rubocop:disable Lint/HandleExceptions
19
+ rescue LoadError
20
+ warn "Unable to load 'test/unit/version', but continuing anyway" if $DEBUG
18
21
  end
19
22
  if defined?(::Test::Unit::VERSION)
20
23
  version = ::Test::Unit::VERSION
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/backtrace_filter'
2
4
 
3
5
  module Mocha
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  class ExceptionRaiser
3
5
  def initialize(exception, message)
@@ -9,6 +11,7 @@ module Mocha
9
11
  invocation.raised(@exception)
10
12
  raise @exception, @exception.to_s if @exception.is_a?(Module) && (@exception < Interrupt)
11
13
  raise @exception, @message if @message
14
+
12
15
  raise @exception
13
16
  end
14
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ruby2_keywords'
2
4
  require 'mocha/method_matcher'
3
5
  require 'mocha/parameters_matcher'
@@ -6,23 +8,22 @@ require 'mocha/return_values'
6
8
  require 'mocha/exception_raiser'
7
9
  require 'mocha/thrower'
8
10
  require 'mocha/yield_parameters'
9
- require 'mocha/is_a'
10
11
  require 'mocha/in_state_ordering_constraint'
11
12
  require 'mocha/change_state_side_effect'
12
13
  require 'mocha/cardinality'
13
14
  require 'mocha/configuration'
14
- require 'mocha/block_matcher'
15
+ require 'mocha/block_matchers'
15
16
  require 'mocha/backtrace_filter'
16
17
 
17
18
  module Mocha
18
19
  # Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}.
19
20
  class Expectation
20
- # Modifies expectation so that the number of calls to the expected method must be within a specific +range+.
21
+ # Modifies expectation so that the number of invocations of the expected method must be within a specified range or exactly equal to a specified number.
21
22
  #
22
- # @param [Range,Integer] range specifies the allowable range in the number of expected invocations.
23
+ # @param [Range,Integer] range_or_number specifies the allowable range for the number of expected invocations or the specified number of expected invocations.
23
24
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
24
25
  #
25
- # @example Specifying a specific number of expected invocations.
26
+ # @example Specifying an exact number of expected invocations.
26
27
  # object = mock()
27
28
  # object.expects(:expected_method).times(3)
28
29
  # 3.times { object.expected_method }
@@ -33,7 +34,7 @@ module Mocha
33
34
  # 2.times { object.expected_method }
34
35
  # # => verify fails
35
36
  #
36
- # @example Specifying a range in the number of expected invocations.
37
+ # @example Specifying a range for the number of expected invocations.
37
38
  # object = mock()
38
39
  # object.expects(:expected_method).times(2..4)
39
40
  # 3.times { object.expected_method }
@@ -43,12 +44,41 @@ module Mocha
43
44
  # object.expects(:expected_method).times(2..4)
44
45
  # object.expected_method
45
46
  # # => verify fails
46
- def times(range)
47
- @cardinality.times(range)
47
+ def times(range_or_number)
48
+ @cardinality.times(range_or_number)
49
+ self
50
+ end
51
+
52
+ # Modifies expectation so that the expected method must be called exactly three times. This is equivalent to calling {#times} with an argument of +3+.
53
+ #
54
+ # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
55
+ #
56
+ # @example Expected method must be invoked exactly three times.
57
+ # object = mock()
58
+ # object.expects(:expected_method).thrice
59
+ # object.expected_method
60
+ # object.expected_method
61
+ # object.expected_method
62
+ # # => verify succeeds
63
+ #
64
+ # object = mock()
65
+ # object.expects(:expected_method).thrice
66
+ # object.expected_method
67
+ # object.expected_method
68
+ # object.expected_method
69
+ # object.expected_method # => unexpected invocation
70
+ #
71
+ # object = mock()
72
+ # object.expects(:expected_method).thrice
73
+ # object.expected_method
74
+ # object.expected_method
75
+ # # => verify fails
76
+ def thrice
77
+ @cardinality.exactly(3)
48
78
  self
49
79
  end
50
80
 
51
- # Modifies expectation so that the expected method must be called exactly twice.
81
+ # Modifies expectation so that the expected method must be called exactly twice. This is equivalent to calling {#times} with an argument of +2+.
52
82
  #
53
83
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
54
84
  #
@@ -74,7 +104,7 @@ module Mocha
74
104
  self
75
105
  end
76
106
 
77
- # Modifies expectation so that the expected method must be called exactly once.
107
+ # Modifies expectation so that the expected method must be called exactly once. This is equivalent to calling {#times} with an argument of +1+.
78
108
  #
79
109
  # Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.
80
110
  #
@@ -136,7 +166,7 @@ module Mocha
136
166
  self
137
167
  end
138
168
 
139
- # Modifies expectation so that the expected method must be called at least once.
169
+ # Modifies expectation so that the expected method must be called at least once. This is equivalent to calling {#at_least} with an argument of +1+.
140
170
  #
141
171
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
142
172
  #
@@ -172,7 +202,7 @@ module Mocha
172
202
  self
173
203
  end
174
204
 
175
- # Modifies expectation so that the expected method must be called at most once.
205
+ # Modifies expectation so that the expected method must be called at most once. This is equivalent to calling {#at_most} with an argument of +1+.
176
206
  #
177
207
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
178
208
  #
@@ -200,9 +230,9 @@ module Mocha
200
230
  #
201
231
  # Positional arguments were separated from keyword arguments in Ruby v3 (see {https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0 this article}). In relation to this a new configuration option ({Configuration#strict_keyword_argument_matching=}) is available in Ruby >= 2.7.
202
232
  #
203
- # When {Configuration#strict_keyword_argument_matching=} is set to +false+ (which is currently the default), a positional +Hash+ and a set of keyword arguments passed to {#with} are treated the same for the purposes of parameter matching. However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa. This is because {Configuration#strict_keyword_argument_matching=} will default to +true+ in the future.
233
+ # When {Configuration#strict_keyword_argument_matching=} is set to +false+ (which is the default in Ruby v2.7), a positional +Hash+ and a set of keyword arguments passed to {#with} are treated the same for the purposes of parameter matching. However, a deprecation warning will be displayed if a positional +Hash+ matches a set of keyword arguments or vice versa.
204
234
  #
205
- # When {Configuration#strict_keyword_argument_matching=} is set to +true+, an actual positional +Hash+ will not match an expected set of keyword arguments; and vice versa, an actual set of keyword arguments will not match an expected positional +Hash+, i.e. the parameter matching is stricter.
235
+ # When {Configuration#strict_keyword_argument_matching=} is set to +true+ (which is the default in Ruby >= v3.0), an actual positional +Hash+ will not match an expected set of keyword arguments; and vice versa, an actual set of keyword arguments will not match an expected positional +Hash+, i.e. the parameter matching is stricter.
206
236
  #
207
237
  # @see ParameterMatchers
208
238
  # @see Configuration#strict_keyword_argument_matching=
@@ -235,7 +265,11 @@ module Mocha
235
265
  # object.expected_method(['string1'], 'any-old-value')
236
266
  # # => verify fails
237
267
  #
238
- # @example Loose keyword argument matching (default)
268
+ # @example Loose keyword argument matching (default in Ruby v2.7).
269
+ #
270
+ # Mocha.configure do |c|
271
+ # c.strict_keyword_argument_matching = false
272
+ # end
239
273
  #
240
274
  # class Example
241
275
  # def foo(a, bar:); end
@@ -246,7 +280,7 @@ module Mocha
246
280
  # example.foo('a', { bar: 'b' })
247
281
  # # This passes the test, but would result in an ArgumentError in practice
248
282
  #
249
- # @example Strict keyword argument matching
283
+ # @example Strict keyword argument matching (default in Ruby >= 3.0).
250
284
  #
251
285
  # Mocha.configure do |c|
252
286
  # c.strict_keyword_argument_matching = true
@@ -711,19 +745,19 @@ module Mocha
711
745
 
712
746
  # @private
713
747
  def mocha_inspect
714
- message = "#{@cardinality.anticipated_times}, #{@cardinality.invoked_times}: #{method_signature}"
715
- message << "; #{@ordering_constraints.map(&:mocha_inspect).join('; ')}" unless @ordering_constraints.empty?
748
+ strings = ["#{@cardinality.anticipated_times}, #{@cardinality.invoked_times}: #{method_signature}"]
749
+ strings << "; #{@ordering_constraints.map(&:mocha_inspect).join('; ')}" unless @ordering_constraints.empty?
716
750
  if Mocha.configuration.display_matching_invocations_on_failure?
717
- message << @cardinality.actual_invocations
751
+ strings << @cardinality.actual_invocations
718
752
  end
719
- message
753
+ strings.join
720
754
  end
721
755
 
722
756
  # @private
723
757
  def method_signature
724
- signature = "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
725
- signature << " #{@block_matcher.mocha_inspect}" if @block_matcher.mocha_inspect
726
- signature
758
+ strings = ["#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"]
759
+ strings << " #{@block_matcher.mocha_inspect}" if @block_matcher.mocha_inspect
760
+ strings.join
727
761
  end
728
762
 
729
763
  # @private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  # Default exception class raised when an unexpected invocation or an unsatisfied expectation occurs.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/backtrace_filter'
2
4
  require 'mocha/expectation_error'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  class ExpectationList
3
5
  def initialize(expectations = [])
@@ -29,7 +31,7 @@ module Mocha
29
31
  matching_expectations(invocation).detect(&:invocations_never_allowed?)
30
32
  end
31
33
 
32
- def verified?(assertion_counter = nil)
34
+ def verified?(assertion_counter)
33
35
  @expectations.all? { |expectation| expectation.verified?(assertion_counter) }
34
36
  end
35
37
 
data/lib/mocha/hooks.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/mockery'
2
4
 
3
5
  module Mocha
@@ -19,8 +21,8 @@ module Mocha
19
21
  # Prepares Mocha before a test (only for use by authors of test libraries).
20
22
  #
21
23
  # This method should be called before each individual test starts (including before any "setup" code).
22
- def mocha_setup
23
- Mockery.setup
24
+ def mocha_setup(assertion_counter)
25
+ Mockery.setup(assertion_counter)
24
26
  end
25
27
 
26
28
  # Verifies that all mock expectations have been met (only for use by authors of test libraries).
@@ -28,8 +30,8 @@ module Mocha
28
30
  # This is equivalent to a series of "assertions".
29
31
  #
30
32
  # This method should be called at the end of each individual test, before it has been determined whether or not the test has passed.
31
- def mocha_verify(assertion_counter = nil)
32
- Mockery.verify(assertion_counter)
33
+ def mocha_verify
34
+ Mockery.verify
33
35
  end
34
36
 
35
37
  # Resets Mocha after a test (only for use by authors of test libraries).
@@ -0,0 +1,20 @@
1
+ module Mocha
2
+ # @private
3
+ module IgnoringWarning
4
+ def ignoring_warning(pattern, if_: true)
5
+ return yield unless if_
6
+
7
+ begin
8
+ original_warn = Warning.method(:warn)
9
+ Warning.singleton_class.define_method(:warn) do |message|
10
+ original_warn.call(message) unless message =~ pattern
11
+ end
12
+
13
+ yield
14
+ ensure
15
+ Warning.singleton_class.undef_method(:warn)
16
+ Warning.singleton_class.define_method(:warn, original_warn)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class ImpersonatingAnyInstanceName
5
+ def initialize(klass)
6
+ @klass = klass
7
+ end
8
+
9
+ def mocha_inspect
10
+ "#<AnyInstance:#{@klass.mocha_inspect}>"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class ImpersonatingName
5
+ def initialize(object)
6
+ @object = object
7
+ end
8
+
9
+ def mocha_inspect
10
+ @object.mocha_inspect
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  class InStateOrderingConstraint
3
5
  def initialize(state_predicate)
data/lib/mocha/inspect.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module Mocha
@@ -11,7 +13,7 @@ module Mocha
11
13
  end
12
14
 
13
15
  module ArrayMethods
14
- def mocha_inspect(wrapped = true)
16
+ def mocha_inspect(wrapped: true)
15
17
  unwrapped = collect(&:mocha_inspect).join(', ')
16
18
  wrapped ? "[#{unwrapped}]" : unwrapped
17
19
  end
@@ -19,17 +21,18 @@ module Mocha
19
21
 
20
22
  module HashMethods
21
23
  def mocha_inspect
24
+ unwrapped = collect do |key, value|
25
+ case key
26
+ when Symbol
27
+ "#{key}: #{value.mocha_inspect}"
28
+ else
29
+ "#{key.mocha_inspect} => #{value.mocha_inspect}"
30
+ end
31
+ end.join(', ')
32
+
22
33
  if Hash.ruby2_keywords_hash?(self)
23
- collect do |key, value|
24
- case key
25
- when Symbol
26
- "#{key}: #{value.mocha_inspect}"
27
- else
28
- "#{key.mocha_inspect} => #{value.mocha_inspect}"
29
- end
30
- end.join(', ')
34
+ empty? ? '**{}' : unwrapped
31
35
  else
32
- unwrapped = collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')
33
36
  "{#{unwrapped}}"
34
37
  end
35
38
  end
@@ -1,19 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/stubbed_method'
2
4
 
3
5
  module Mocha
4
6
  class InstanceMethod < StubbedMethod
5
7
  private
6
8
 
7
- def mock_owner
8
- stubbee
9
+ def stubbee
10
+ stubba_object
9
11
  end
10
12
 
11
13
  def stubbee_method(method_name)
12
- stubbee._method(method_name)
14
+ stubba_object._method(method_name)
13
15
  end
14
16
 
15
17
  def original_method_owner
16
- stubbee.singleton_class
18
+ stubba_object.singleton_class
17
19
  end
18
20
  end
19
21
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module Integration
3
5
  class AssertionCounter
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/api'
2
4
  require 'mocha/integration/assertion_counter'
3
5
  require 'mocha/expectation_error_factory'
4
6
 
5
7
  module Mocha
6
8
  module Integration
9
+ # Contains {Adapter} that integrates Mocha into recent versions of Minitest.
7
10
  module Minitest
8
11
  # Integrates Mocha into recent versions of Minitest.
9
12
  #
@@ -28,15 +31,16 @@ module Mocha
28
31
 
29
32
  # @private
30
33
  def before_setup
31
- mocha_setup
34
+ assertion_counter = Integration::AssertionCounter.new(self)
35
+ mocha_setup(assertion_counter)
32
36
  super
33
37
  end
34
38
 
35
39
  # @private
36
40
  def before_teardown
37
41
  return unless passed?
38
- assertion_counter = Integration::AssertionCounter.new(self)
39
- mocha_verify(assertion_counter)
42
+
43
+ mocha_verify
40
44
  ensure
41
45
  super
42
46
  end