mocha 2.7.1 → 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 (101) 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 +37 -0
  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 +4 -2
  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 +18 -41
  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 +57 -23
  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 +3 -0
  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 +5 -1
  57. data/lib/mocha/parameter_matchers/any_of.rb +5 -1
  58. data/lib/mocha/parameter_matchers/any_parameters.rb +5 -1
  59. data/lib/mocha/parameter_matchers/anything.rb +5 -1
  60. data/lib/mocha/parameter_matchers/base.rb +4 -2
  61. data/lib/mocha/parameter_matchers/equals.rb +5 -1
  62. data/lib/mocha/parameter_matchers/equivalent_uri.rb +5 -1
  63. data/lib/mocha/parameter_matchers/has_entries.rb +5 -1
  64. data/lib/mocha/parameter_matchers/has_entry.rb +6 -1
  65. data/lib/mocha/parameter_matchers/has_key.rb +6 -1
  66. data/lib/mocha/parameter_matchers/has_keys.rb +6 -2
  67. data/lib/mocha/parameter_matchers/has_value.rb +6 -1
  68. data/lib/mocha/parameter_matchers/includes.rb +8 -7
  69. data/lib/mocha/parameter_matchers/instance_methods.rb +4 -2
  70. data/lib/mocha/parameter_matchers/instance_of.rb +5 -1
  71. data/lib/mocha/parameter_matchers/is_a.rb +5 -1
  72. data/lib/mocha/parameter_matchers/kind_of.rb +5 -1
  73. data/lib/mocha/parameter_matchers/not.rb +5 -1
  74. data/lib/mocha/parameter_matchers/optionally.rb +6 -1
  75. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +41 -16
  76. data/lib/mocha/parameter_matchers/regexp_matches.rb +6 -1
  77. data/lib/mocha/parameter_matchers/responds_with.rb +5 -1
  78. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +5 -1
  79. data/lib/mocha/parameter_matchers.rb +2 -0
  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 -15
  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/receivers.rb +0 -45
data/lib/mocha/name.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class Name
5
+ def initialize(name)
6
+ @name = name.to_s
7
+ end
8
+
9
+ def mocha_inspect
10
+ "#<Mock:#{@name}>"
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/error_with_filtered_backtrace'
2
4
 
3
5
  module Mocha
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/mockery'
2
4
  require 'mocha/instance_method'
3
5
  require 'mocha/argument_iterator'
@@ -12,7 +14,7 @@ module Mocha
12
14
  alias_method :_method, :method
13
15
 
14
16
  # @private
15
- def mocha(instantiate = true)
17
+ def mocha(instantiate: true)
16
18
  if instantiate
17
19
  @mocha ||= Mocha::Mockery.instance.mock_impersonating(self)
18
20
  else
@@ -75,11 +77,11 @@ module Mocha
75
77
  if frozen?
76
78
  raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
77
79
  end
80
+
78
81
  expectation = nil
79
82
  mockery = Mocha::Mockery.instance
80
83
  iterator = ArgumentIterator.new(expected_methods_vs_return_values)
81
- iterator.each do |*args|
82
- method_name = args.shift
84
+ iterator.each do |method_name, *args|
83
85
  mockery.on_stubbing(self, method_name)
84
86
  method = stubba_method.new(stubba_object, method_name)
85
87
  mockery.stubba.stub(method)
@@ -121,11 +123,11 @@ module Mocha
121
123
  if frozen?
122
124
  raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
123
125
  end
126
+
124
127
  expectation = nil
125
128
  mockery = Mocha::Mockery.instance
126
129
  iterator = ArgumentIterator.new(stubbed_methods_vs_return_values)
127
- iterator.each do |*args|
128
- method_name = args.shift
130
+ iterator.each do |method_name, *args|
129
131
  mockery.on_stubbing(self, method_name)
130
132
  method = stubba_method.new(stubba_object, method_name)
131
133
  mockery.stubba.stub(method)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mocha
4
+ class ObjectReceiver
5
+ def initialize(object)
6
+ @object = object
7
+ end
8
+
9
+ def mocks
10
+ object = @object
11
+ mocks = []
12
+ while object
13
+ mocha = object.mocha(instantiate: false)
14
+ mocks << mocha if mocha
15
+ object = object.is_a?(Class) ? object.superclass : nil
16
+ end
17
+ mocks
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -25,7 +27,9 @@ module Mocha
25
27
  end
26
28
 
27
29
  # Parameter matcher which combines a number of other matchers using a logical AND.
28
- class AllOf < Base
30
+ class AllOf
31
+ include Base
32
+
29
33
  # @private
30
34
  def initialize(*matchers)
31
35
  @matchers = matchers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -31,7 +33,9 @@ module Mocha
31
33
  end
32
34
 
33
35
  # Parameter matcher which combines a number of other matchers using a logical OR.
34
- class AnyOf < Base
36
+ class AnyOf
37
+ include Base
38
+
35
39
  # @private
36
40
  def initialize(*matchers)
37
41
  @matchers = matchers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -23,7 +25,9 @@ module Mocha
23
25
  end
24
26
 
25
27
  # Parameter matcher which always matches whatever the parameters.
26
- class AnyParameters < Base
28
+ class AnyParameters
29
+ include Base
30
+
27
31
  # @private
28
32
  def matches?(available_parameters)
29
33
  until available_parameters.empty?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -20,7 +22,9 @@ module Mocha
20
22
  end
21
23
 
22
24
  # Parameter matcher which always matches a single parameter.
23
- class Anything < Base
25
+ class Anything
26
+ include Base
27
+
24
28
  # @private
25
29
  def matches?(available_parameters)
26
30
  available_parameters.shift
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module ParameterMatchers
3
- # @abstract Subclass and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}.
4
- class Base
5
+ # @abstract Include and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}.
6
+ module Base
5
7
  # A shorthand way of combining two matchers when both must match.
6
8
  #
7
9
  # Returns a new {AllOf} parameter matcher combining two matchers using a logical AND.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter equals expected value.
29
- class Equals < Base
31
+ class Equals
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(value)
32
36
  @value = value
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
  require 'uri'
3
5
  require 'cgi'
@@ -27,7 +29,9 @@ module Mocha
27
29
  end
28
30
 
29
31
  # Parameter matcher which matches URIs with equivalent query strings.
30
- class EquivalentUri < Base
32
+ class EquivalentUri
33
+ include Base
34
+
31
35
  # @private
32
36
  def initialize(uri)
33
37
  @uri = URI.parse(uri)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
  require 'mocha/parameter_matchers/all_of'
3
5
  require 'mocha/parameter_matchers/has_entry'
@@ -28,7 +30,9 @@ module Mocha
28
30
  end
29
31
 
30
32
  # Parameter matcher which matches when actual parameter contains all expected +Hash+ entries.
31
- class HasEntries < Base
33
+ class HasEntries
34
+ include Base
35
+
32
36
  # @private
33
37
  def initialize(entries, exact: false)
34
38
  @entries = entries
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -55,7 +57,9 @@ module Mocha
55
57
  end
56
58
 
57
59
  # Parameter matcher which matches when actual parameter contains expected +Hash+ entry.
58
- class HasEntry < Base
60
+ class HasEntry
61
+ include Base
62
+
59
63
  # @private
60
64
  def initialize(key, value)
61
65
  @key = key
@@ -66,6 +70,7 @@ module Mocha
66
70
  def matches?(available_parameters)
67
71
  parameter = available_parameters.shift
68
72
  return false unless parameter.respond_to?(:keys) && parameter.respond_to?(:[])
73
+
69
74
  matching_keys = parameter.keys.select { |key| @key.to_matcher.matches?([key]) }
70
75
  matching_keys.any? { |key| @value.to_matcher.matches?([parameter[key]]) }
71
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected key.
29
- class HasKey < Base
31
+ class HasKey
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(key)
32
36
  @key = key
@@ -36,6 +40,7 @@ module Mocha
36
40
  def matches?(available_parameters)
37
41
  parameter = available_parameters.shift
38
42
  return false unless parameter.respond_to?(:keys)
43
+
39
44
  parameter.keys.any? { |key| @key.to_matcher.matches?([key]) }
40
45
  end
41
46
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter contains +Hash+ with all expected keys.
29
- class HasKeys < Base
31
+ class HasKeys
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(*keys)
32
36
  raise ArgumentError, 'No arguments. Expecting at least one.' if keys.empty?
@@ -46,7 +50,7 @@ module Mocha
46
50
 
47
51
  # @private
48
52
  def mocha_inspect
49
- "has_keys(#{@keys.mocha_inspect(false)})"
53
+ "has_keys(#{@keys.mocha_inspect(wrapped: false)})"
50
54
  end
51
55
  end
52
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected value.
29
- class HasValue < Base
31
+ class HasValue
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(value)
32
36
  @value = value
@@ -36,6 +40,7 @@ module Mocha
36
40
  def matches?(available_parameters)
37
41
  parameter = available_parameters.shift
38
42
  return false unless parameter.respond_to?(:values)
43
+
39
44
  parameter.values.any? { |value| @value.to_matcher.matches?([value]) }
40
45
  end
41
46
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/all_of'
2
4
  require 'mocha/parameter_matchers/base'
3
5
 
@@ -65,32 +67,31 @@ module Mocha
65
67
  end
66
68
 
67
69
  # Parameter matcher which matches when actual parameter includes expected values.
68
- class Includes < Base
70
+ class Includes
71
+ include Base
72
+
69
73
  # @private
70
74
  def initialize(*items)
71
75
  @items = items
72
76
  end
73
77
 
74
78
  # @private
75
- # rubocop:disable Metrics/PerceivedComplexity
76
79
  def matches?(available_parameters)
77
80
  parameter = available_parameters.shift
78
81
  return false unless parameter.respond_to?(:include?)
82
+
79
83
  if @items.size == 1
80
- # rubocop:disable Style/GuardClause
81
84
  if parameter.respond_to?(:any?) && !parameter.is_a?(String)
82
85
  parameter = parameter.keys if parameter.is_a?(Hash)
83
- return parameter.any? { |p| @items.first.to_matcher.matches?([p]) }
86
+ parameter.any? { |p| @items.first.to_matcher.matches?([p]) }
84
87
  else
85
- return parameter.include?(@items.first)
88
+ parameter.include?(@items.first)
86
89
  end
87
- # rubocop:enable Style/GuardClause
88
90
  else
89
91
  includes_matchers = @items.map { |item| Includes.new(item) }
90
92
  AllOf.new(*includes_matchers).matches?([parameter])
91
93
  end
92
94
  end
93
- # rubocop:enable Metrics/PerceivedComplexity
94
95
 
95
96
  # @private
96
97
  def mocha_inspect
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
  require 'mocha/parameter_matchers/equals'
3
5
  require 'mocha/parameter_matchers/positional_or_keyword_hash'
@@ -7,11 +9,11 @@ module Mocha
7
9
  # @private
8
10
  module InstanceMethods
9
11
  # @private
10
- def to_matcher(expectation: nil, top_level: false)
12
+ def to_matcher(expectation: nil, top_level: false, last: false)
11
13
  if Base === self
12
14
  self
13
15
  elsif Hash === self && top_level
14
- Mocha::ParameterMatchers::PositionalOrKeywordHash.new(self, expectation)
16
+ Mocha::ParameterMatchers::PositionalOrKeywordHash.new(self, expectation, last)
15
17
  else
16
18
  Mocha::ParameterMatchers::Equals.new(self)
17
19
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter is an instance of the specified class.
29
- class InstanceOf < Base
31
+ class InstanceOf
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(klass)
32
36
  @klass = klass
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -27,7 +29,9 @@ module Mocha
27
29
  end
28
30
 
29
31
  # Parameter matcher which matches when actual parameter is a specific class.
30
- class IsA < Base
32
+ class IsA
33
+ include Base
34
+
31
35
  # @private
32
36
  def initialize(klass)
33
37
  @klass = klass
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches when actual parameter is a kind of specified class.
29
- class KindOf < Base
31
+ class KindOf
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(klass)
32
36
  @klass = klass
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which inverts the logic of the specified matcher using a logical NOT operation.
29
- class Not < Base
31
+ class Not
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(matcher)
32
36
  @matcher = matcher
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  module ParameterMatchers
3
5
  # Matches optional parameters if available.
@@ -35,7 +37,9 @@ module Mocha
35
37
  end
36
38
 
37
39
  # Parameter matcher which allows optional parameters to be specified.
38
- class Optionally < Base
40
+ class Optionally
41
+ include Base
42
+
39
43
  # @private
40
44
  def initialize(*parameters)
41
45
  @matchers = parameters.map(&:to_matcher)
@@ -47,6 +51,7 @@ module Mocha
47
51
  while !available_parameters.empty? && (index < @matchers.length)
48
52
  matcher = @matchers[index]
49
53
  return false unless matcher.matches?(available_parameters)
54
+
50
55
  index += 1
51
56
  end
52
57
  true
@@ -1,39 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/configuration'
2
4
  require 'mocha/deprecation'
5
+ require 'mocha/ruby_version'
3
6
  require 'mocha/parameter_matchers/base'
4
7
  require 'mocha/parameter_matchers/has_entries'
5
8
 
6
9
  module Mocha
7
10
  module ParameterMatchers
8
11
  # @private
9
- class PositionalOrKeywordHash < Base
10
- def initialize(value, expectation)
11
- @value = value
12
+ class PositionalOrKeywordHash
13
+ include Base
14
+
15
+ def initialize(expected_value, expectation, last_expected_value)
16
+ @expected_value = expected_value
12
17
  @expectation = expectation
18
+ @last_expected_value = last_expected_value
13
19
  end
14
20
 
15
- def matches?(available_parameters)
16
- parameter, is_last_parameter = extract_parameter(available_parameters)
17
-
18
- return false unless HasEntries.new(@value, exact: true).matches?([parameter])
21
+ def matches?(actual_values)
22
+ actual_value, is_last_actual_value = extract_actual_value(actual_values)
19
23
 
20
- if is_last_parameter && !same_type_of_hash?(parameter, @value)
21
- return false if Mocha.configuration.strict_keyword_argument_matching?
22
-
23
- deprecation_warning(parameter, @value) if Mocha::RUBY_V27_PLUS
24
+ if !matches_entries_exactly?(actual_value)
25
+ false
26
+ elsif is_last_actual_value
27
+ matches_last_actual_value?(actual_value)
28
+ else
29
+ true
24
30
  end
25
-
26
- true
27
31
  end
28
32
 
29
33
  def mocha_inspect
30
- @value.mocha_inspect
34
+ @expected_value.mocha_inspect
31
35
  end
32
36
 
33
37
  private
34
38
 
35
- def extract_parameter(available_parameters)
36
- [available_parameters.shift, available_parameters.empty?]
39
+ def matches_entries_exactly?(actual_value)
40
+ HasEntries.new(@expected_value, exact: true).matches?([actual_value])
41
+ end
42
+
43
+ def matches_last_actual_value?(actual_value)
44
+ if same_type_of_hash?(actual_value, @expected_value)
45
+ true
46
+ elsif last_expected_value_is_positional_hash? # rubocop:disable Lint/DuplicateBranch
47
+ true
48
+ elsif Mocha.configuration.strict_keyword_argument_matching?
49
+ false
50
+ else
51
+ deprecation_warning(actual_value, @expected_value) if Mocha::RUBY_V27_PLUS
52
+ true
53
+ end
54
+ end
55
+
56
+ def last_expected_value_is_positional_hash?
57
+ @last_expected_value && !ruby2_keywords_hash?(@expected_value)
58
+ end
59
+
60
+ def extract_actual_value(actual_values)
61
+ [actual_values.shift, actual_values.empty?]
37
62
  end
38
63
 
39
64
  def same_type_of_hash?(actual, expected)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
 
3
5
  module Mocha
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches if specified regular expression matches actual paramter.
29
- class RegexpMatches < Base
31
+ class RegexpMatches
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(regexp)
32
36
  @regexp = regexp
@@ -36,6 +40,7 @@ module Mocha
36
40
  def matches?(available_parameters)
37
41
  parameter = available_parameters.shift
38
42
  return false unless parameter.respond_to?(:=~)
43
+
39
44
  parameter =~ @regexp
40
45
  end
41
46
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
  require 'mocha/parameter_matchers/all_of'
3
5
  require 'yaml'
@@ -54,7 +56,9 @@ module Mocha
54
56
  end
55
57
 
56
58
  # Parameter matcher which matches if actual parameter returns expected result when specified method is invoked.
57
- class RespondsWith < Base
59
+ class RespondsWith
60
+ include Base
61
+
58
62
  # @private
59
63
  def initialize(message, result)
60
64
  @message = message
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/parameter_matchers/base'
2
4
  require 'yaml'
3
5
 
@@ -26,7 +28,9 @@ module Mocha
26
28
  end
27
29
 
28
30
  # Parameter matcher which matches if actual parameter is YAML equivalent of specified object.
29
- class YamlEquivalent < Base
31
+ class YamlEquivalent
32
+ include Base
33
+
30
34
  # @private
31
35
  def initialize(object)
32
36
  @object = object
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  # Used as parameters for {Expectation#with} to restrict the parameter values which will match the expectation. Can be nested.
3
5
  module ParameterMatchers; end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/inspect'
2
4
  require 'mocha/parameter_matchers'
3
5
 
@@ -32,7 +34,13 @@ module Mocha
32
34
  end
33
35
 
34
36
  def matchers
35
- @expected_parameters.map { |p| p.to_matcher(expectation: @expectation, top_level: true) }
37
+ @expected_parameters.map.with_index do |parameter, index|
38
+ parameter.to_matcher(
39
+ expectation: @expectation,
40
+ top_level: true,
41
+ last: index == @expected_parameters.length - 1
42
+ )
43
+ end
36
44
  end
37
45
  end
38
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  class RaisedException
3
5
  def initialize(exception)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mocha/single_return_value'
2
4
 
3
5
  module Mocha
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mocha
2
4
  RUBY_V27_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.7')
5
+ RUBY_V30_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('3.0')
3
6
  RUBY_V34_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('3.4')
4
7
  end