mocha 2.8.2 → 3.0.0.pre.rc.1

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +67 -3
  3. data/.rubocop_todo.yml +25 -13
  4. data/Gemfile +11 -27
  5. data/README.md +3 -4
  6. data/RELEASE.md +30 -25
  7. data/Rakefile +6 -5
  8. data/gemfiles/Gemfile.minitest.latest +3 -3
  9. data/gemfiles/Gemfile.rubocop +9 -0
  10. data/gemfiles/Gemfile.test-unit.latest +3 -3
  11. data/lib/mocha/any_instance_method.rb +2 -0
  12. data/lib/mocha/any_instance_receiver.rb +20 -0
  13. data/lib/mocha/api.rb +5 -3
  14. data/lib/mocha/argument_iterator.rb +5 -5
  15. data/lib/mocha/backtrace_filter.rb +2 -0
  16. data/lib/mocha/{block_matcher.rb → block_matchers.rb} +2 -0
  17. data/lib/mocha/cardinality.rb +2 -2
  18. data/lib/mocha/central.rb +4 -0
  19. data/lib/mocha/change_state_side_effect.rb +2 -0
  20. data/lib/mocha/class_methods.rb +5 -4
  21. data/lib/mocha/configuration.rb +19 -42
  22. data/lib/mocha/default_name.rb +15 -0
  23. data/lib/mocha/default_receiver.rb +13 -0
  24. data/lib/mocha/deprecation.rb +15 -9
  25. data/lib/mocha/detection/minitest.rb +2 -0
  26. data/lib/mocha/detection/test_unit.rb +4 -1
  27. data/lib/mocha/error_with_filtered_backtrace.rb +2 -0
  28. data/lib/mocha/exception_raiser.rb +3 -0
  29. data/lib/mocha/expectation.rb +59 -25
  30. data/lib/mocha/expectation_error.rb +2 -0
  31. data/lib/mocha/expectation_error_factory.rb +2 -0
  32. data/lib/mocha/expectation_list.rb +2 -0
  33. data/lib/mocha/hooks.rb +2 -0
  34. data/lib/mocha/impersonating_any_instance_name.rb +13 -0
  35. data/lib/mocha/impersonating_name.rb +13 -0
  36. data/lib/mocha/in_state_ordering_constraint.rb +2 -0
  37. data/lib/mocha/inspect.rb +13 -10
  38. data/lib/mocha/instance_method.rb +2 -0
  39. data/lib/mocha/integration/assertion_counter.rb +2 -0
  40. data/lib/mocha/integration/minitest/adapter.rb +4 -3
  41. data/lib/mocha/integration/minitest.rb +4 -3
  42. data/lib/mocha/integration/monkey_patcher.rb +4 -2
  43. data/lib/mocha/integration/test_unit/adapter.rb +3 -0
  44. data/lib/mocha/integration/test_unit.rb +4 -3
  45. data/lib/mocha/invocation.rb +9 -6
  46. data/lib/mocha/logger.rb +2 -0
  47. data/lib/mocha/macos_version.rb +2 -0
  48. data/lib/mocha/method_matcher.rb +2 -0
  49. data/lib/mocha/minitest.rb +2 -1
  50. data/lib/mocha/mock.rb +8 -8
  51. data/lib/mocha/mockery.rb +16 -6
  52. data/lib/mocha/name.rb +13 -0
  53. data/lib/mocha/not_initialized_error.rb +2 -0
  54. data/lib/mocha/object_methods.rb +7 -5
  55. data/lib/mocha/object_receiver.rb +20 -0
  56. data/lib/mocha/parameter_matchers/all_of.rb +23 -28
  57. data/lib/mocha/parameter_matchers/any_of.rb +29 -34
  58. data/lib/mocha/parameter_matchers/any_parameters.rb +21 -26
  59. data/lib/mocha/parameter_matchers/anything.rb +18 -23
  60. data/lib/mocha/parameter_matchers/base.rb +5 -23
  61. data/lib/mocha/parameter_matchers/equals.rb +24 -29
  62. data/lib/mocha/parameter_matchers/equivalent_uri.rb +23 -28
  63. data/lib/mocha/parameter_matchers/has_entries.rb +24 -29
  64. data/lib/mocha/parameter_matchers/has_entry.rb +68 -70
  65. data/lib/mocha/parameter_matchers/has_key.rb +25 -29
  66. data/lib/mocha/parameter_matchers/has_keys.rb +25 -30
  67. data/lib/mocha/parameter_matchers/has_value.rb +25 -29
  68. data/lib/mocha/parameter_matchers/includes.rb +65 -73
  69. data/lib/mocha/parameter_matchers/instance_methods.rb +5 -3
  70. data/lib/mocha/parameter_matchers/instance_of.rb +24 -29
  71. data/lib/mocha/parameter_matchers/is_a.rb +25 -30
  72. data/lib/mocha/parameter_matchers/kind_of.rb +24 -29
  73. data/lib/mocha/parameter_matchers/not.rb +24 -29
  74. data/lib/mocha/parameter_matchers/optionally.rb +35 -40
  75. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +39 -19
  76. data/lib/mocha/parameter_matchers/regexp_matches.rb +25 -29
  77. data/lib/mocha/parameter_matchers/responds_with.rb +48 -53
  78. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +23 -28
  79. data/lib/mocha/parameter_matchers.rb +4 -6
  80. data/lib/mocha/parameters_matcher.rb +9 -1
  81. data/lib/mocha/raised_exception.rb +2 -0
  82. data/lib/mocha/return_values.rb +2 -0
  83. data/lib/mocha/ruby_version.rb +3 -0
  84. data/lib/mocha/sequence.rb +2 -0
  85. data/lib/mocha/single_return_value.rb +1 -1
  86. data/lib/mocha/state_machine.rb +2 -0
  87. data/lib/mocha/stubbed_method.rb +9 -2
  88. data/lib/mocha/stubbing_error.rb +2 -0
  89. data/lib/mocha/test_unit.rb +2 -1
  90. data/lib/mocha/thrower.rb +2 -0
  91. data/lib/mocha/thrown_object.rb +2 -0
  92. data/lib/mocha/version.rb +3 -1
  93. data/lib/mocha/yield_parameters.rb +2 -0
  94. data/lib/mocha.rb +5 -0
  95. data/mocha.gemspec +10 -4
  96. metadata +17 -16
  97. data/lib/mocha/debug.rb +0 -9
  98. data/lib/mocha/integration/minitest/exception_translation.rb +0 -14
  99. data/lib/mocha/is_a.rb +0 -7
  100. data/lib/mocha/names.rb +0 -43
  101. data/lib/mocha/parameter_matchers/deprecations.rb +0 -44
  102. 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
- # 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.
238
+ # Note that +Hash+-related matchers such as {ParameterMatchers#has_value} or {ParameterMatchers#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
  #
@@ -191,7 +221,7 @@ module Mocha
191
221
 
192
222
  # Modifies expectation so that the expected method must be called with +expected_parameters_or_matchers+.
193
223
  #
194
- # May be used with Ruby literals or variables for exact matching or with parameter matchers for less-specific matching, e.g. {ParameterMatchers::Methods#includes}, {ParameterMatchers::Methods#has_key}, etc. See {ParameterMatchers} for a list of all available parameter matchers.
224
+ # May be used with Ruby literals or variables for exact matching or with parameter matchers for less-specific matching, e.g. {ParameterMatchers#includes}, {ParameterMatchers#has_key}, etc. See {ParameterMatchers} for a list of all available parameter matchers.
195
225
  #
196
226
  # Alternatively a block argument can be passed to {#with} to implement custom parameter matching. The block receives the +*actual_parameters+ as its arguments and should return +true+ if they are acceptable or +false+ otherwise. See the example below where a method is expected to be called with a value divisible by 4.
197
227
  # The block argument takes precedence over +expected_parameters_or_matchers+. The block may be called multiple times per invocation of the expected method and so it should be idempotent.
@@ -200,14 +230,14 @@ 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=
209
239
  #
210
- # @param [Array<Object,ParameterMatchers::BaseMethods>] expected_parameters_or_matchers expected parameter values or parameter matchers.
240
+ # @param [Array<Object,ParameterMatchers::Base>] expected_parameters_or_matchers expected parameter values or parameter matchers.
211
241
  # @yield optional block specifying custom matching.
212
242
  # @yieldparam [Array<Object>] actual_parameters parameters with which expected method was invoked.
213
243
  # @yieldreturn [Boolean] +true+ if +actual_parameters+ are acceptable; +false+ otherwise.
@@ -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 = [])
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
@@ -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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/stubbed_method'
2
4
 
3
5
  module Mocha
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module Integration
3
5
  class AssertionCounter
@@ -1,7 +1,8 @@
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
- require 'mocha/parameter_matchers/deprecations'
5
6
 
6
7
  module Mocha
7
8
  module Integration
@@ -23,8 +24,7 @@ module Mocha
23
24
  end
24
25
 
25
26
  # @private
26
- def self.included(mod)
27
- mod.extend(Mocha::ParameterMatchers::Deprecations)
27
+ def self.included(_mod)
28
28
  Mocha::ExpectationErrorFactory.exception_class = ::Minitest::Assertion
29
29
  end
30
30
 
@@ -37,6 +37,7 @@ module Mocha
37
37
  # @private
38
38
  def before_teardown
39
39
  return unless passed?
40
+
40
41
  assertion_counter = Integration::AssertionCounter.new(self)
41
42
  mocha_verify(assertion_counter)
42
43
  ensure
@@ -1,4 +1,5 @@
1
- require 'mocha/debug'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'mocha/detection/minitest'
3
4
  require 'mocha/integration/minitest/adapter'
4
5
 
@@ -10,14 +11,14 @@ module Mocha
10
11
  return false unless target
11
12
 
12
13
  minitest_version = Gem::Version.new(Detection::Minitest.version)
13
- Debug.puts "Detected Minitest version: #{minitest_version}"
14
+ warn "Detected Minitest version: #{minitest_version}" if $DEBUG
14
15
 
15
16
  unless Minitest::Adapter.applicable_to?(minitest_version)
16
17
  raise 'Versions of minitest earlier than v3.3.0 are not supported.'
17
18
  end
18
19
 
19
20
  unless target < Minitest::Adapter
20
- Debug.puts "Applying #{Minitest::Adapter.description}"
21
+ warn "Applying #{Minitest::Adapter.description}" if $DEBUG
21
22
  target.send(:include, Minitest::Adapter)
22
23
  end
23
24
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/api'
2
4
 
3
5
  module Mocha
@@ -5,12 +7,12 @@ module Mocha
5
7
  module MonkeyPatcher
6
8
  def self.apply(mod, run_method_patch)
7
9
  if mod < Mocha::API
8
- Debug.puts "Mocha::API already included in #{mod}"
10
+ warn "Mocha::API already included in #{mod}" if $DEBUG
9
11
  else
10
12
  mod.send(:include, Mocha::API)
11
13
  end
12
14
  if mod.method_defined?(:run_before_mocha)
13
- Debug.puts "#{mod}#run_before_mocha method already defined"
15
+ warn "#{mod}#run_before_mocha method already defined" if $DEBUG
14
16
  elsif mod.method_defined?(:run)
15
17
  mod.send(:alias_method, :run_before_mocha, :run)
16
18
  mod.send(:remove_method, :run)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/api'
2
4
  require 'mocha/integration/assertion_counter'
3
5
  require 'mocha/expectation_error'
@@ -45,6 +47,7 @@ module Mocha
45
47
  # @private
46
48
  def handle_mocha_expectation_error(exception)
47
49
  return false unless exception.is_a?(Mocha::ExpectationError)
50
+
48
51
  problem_occurred
49
52
  add_failure(exception.message, exception.backtrace)
50
53
  true