Created
January 6, 2022 15:38
-
-
Save wasabigeek/74c048d87ac1f80edfff13cdab9883b0 to your computer and use it in GitHub Desktop.
Mocha kwarg matching patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Mocha | |
class Mock | |
# change to *args, **kwargs | |
def method_missing(symbol, *args, **kwargs, &block) | |
check_expiry | |
check_responder_responds_to(symbol) | |
# change to *arg, **kwargs | |
invocation = Invocation.new(self, symbol, *args, **kwargs, &block) | |
if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(invocation)) | |
matching_expectation_allowing_invocation.invoke(invocation) | |
elsif (matching_expectation = all_expectations.match(invocation)) || (!matching_expectation && !@everything_stubbed) | |
raise_unexpected_invocation_error(invocation, matching_expectation) | |
end | |
end | |
end | |
class Invocation | |
attr_reader :args, :kwargs | |
# change *arguments to *args, **kwargs | |
def initialize(mock, method_name, *args, **kwargs, &block) | |
@args = args | |
@kwargs = kwargs | |
@mock = mock | |
@method_name = method_name | |
@arguments = [*args, kwargs] | |
@block = block | |
@yields = [] | |
@result = nil | |
end | |
end | |
class Expectation | |
# change *expected_parameters to *expected_args, **expected_kwargs | |
def with(*expected_args, **expected_kwargs, &matching_block) | |
@parameters_matcher = ParametersMatcher.new(*expected_args, **expected_kwargs, &matching_block) | |
self | |
end | |
def match?(invocation) | |
# change invocation.arguments to *invocation.args, **invocation.kwargs | |
@method_matcher.match?(invocation.method_name) \ | |
&& @parameters_matcher.match?(*invocation.args, **invocation.kwargs) && @block_matcher.match?(invocation.block) && in_correct_order? | |
end | |
end | |
class ParametersMatcher | |
# change to *expected_args, **expected_kwargs | |
def initialize(*expected_args, **expected_kwargs, &matching_block) | |
@expected_args = expected_args.empty? ? [ParameterMatchers::AnyParameters.new] : expected_args | |
@expected_kwargs = expected_kwargs.empty? ? ParameterMatchers::AnyParameters.new : ParameterMatchers::HasEntries.new(expected_kwargs) # warning: HasEntries is more permissive than checking hash equality | |
@expected_parameters = [*expected_args, expected_kwargs] # temporary | |
@matching_block = matching_block | |
end | |
# change to *actual_args, **actual_kwargs | |
def match?(*actual_args, **actual_kwargs) | |
if @matching_block | |
@matching_block.call(*actual_args, **actual_kwargs) | |
else | |
parameters_match?(*actual_args, **actual_kwargs) | |
end | |
end | |
# change to *actual_args, **actual_kwargs | |
def parameters_match?(*actual_args, **actual_kwargs) | |
arg_matchers.all? { |matcher| matcher.matches?(actual_args) } \ | |
&& kwarg_matcher.matches?([actual_kwargs]) \ | |
&& actual_args.empty? | |
end | |
def arg_matchers | |
@expected_args.map(&:to_matcher) | |
end | |
def kwarg_matcher | |
@expected_kwargs | |
end | |
end | |
class StubbedMethod | |
def define_new_method | |
self_in_scope = self | |
method_name_in_scope = method_name | |
# change *args to *args, **kwargs | |
stub_method_owner.send(:define_method, method_name) do |*args, **kwargs, &block| | |
self_in_scope.mock.method_missing(method_name_in_scope, *args, **kwargs, &block) | |
end | |
retain_original_visibility(stub_method_owner) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment