mocha 2.7.1 → 3.0.0.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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