Skip to content

Commit

Permalink
- Had to patch up mock and stub to deal with <=2.7 kwargs oddities
Browse files Browse the repository at this point in the history
+ Extended #stub to handle kwargs for both block and call args. (SampsonCrowley)

[git-p4: depot-paths = "//src/minitest/dev/": change = 13436]
  • Loading branch information
zenspider committed Jun 13, 2022
1 parent 6fecff9 commit 25b60ae
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
36 changes: 26 additions & 10 deletions lib/minitest/mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ class Mock
overridden_methods.map(&:to_sym).each do |method_id|
define_method method_id do |*args, **kwargs, &b|
if @expected_calls.key? method_id then
method_missing(method_id, *args, **kwargs, &b)
if kwargs.empty? then # FIX: drop this after 2.7 dead
method_missing(method_id, *args, &b)
else
method_missing(method_id, *args, **kwargs, &b)
end
else
super(*args, **kwargs, &b)
if kwargs.empty? then # FIX: drop this after 2.7 dead
super(*args, &b)
else
super(*args, **kwargs, &b)
end
end
end
end
Expand Down Expand Up @@ -242,30 +250,38 @@ class Object
# NOTE: keyword args in callables are NOT checked for correctness
# against the existing method. Too many edge cases to be worth it.

def stub name, val_or_callable, *block_args
def stub name, val_or_callable, *block_args, **block_kwargs
new_name = "__minitest_stub__#{name}"

metaclass = class << self; self; end

if respond_to? name and not methods.map(&:to_s).include? name.to_s then
metaclass.send :define_method, name do |*args|
super(*args)
metaclass.send :define_method, name do |*args, **kwargs|
super(*args, **kwargs)
end
end

metaclass.send :alias_method, new_name, name

metaclass.send :define_method, name do |*args, &blk|
metaclass.send :define_method, name do |*args, **kwargs, &blk|
if val_or_callable.respond_to? :call then
val_or_callable.call(*args, &blk)
if kwargs.empty? then # FIX: drop this after 2.7 dead
val_or_callable.call(*args, &blk)
else
val_or_callable.call(*args, **kwargs, &blk)
end
else
blk.call(*block_args) if blk
if blk then
if block_kwargs.empty? then # FIX: drop this after 2.7 dead
blk.call(*block_args)
else
blk.call(*block_args, **block_kwargs)
end
end
val_or_callable
end
end

metaclass.send(:ruby2_keywords, name) if metaclass.respond_to?(:ruby2_keywords, true)

yield self
ensure
metaclass.send :undef_method, name
Expand Down
19 changes: 17 additions & 2 deletions test/minitest/test_minitest_mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ def test_mock_block_is_passed_keyword_args__block_bad_missing
mock.foo(k1: arg1, k2: arg2)
end

assert_equal "missing keyword: :k3", e.message # basically testing ruby
# basically testing ruby ... need ? for ruby < 2.7 :(
assert_match(/missing keyword: :?k3/, e.message)
end

def test_mock_block_is_passed_keyword_args__block_bad_extra
Expand All @@ -333,7 +334,8 @@ def test_mock_block_is_passed_keyword_args__block_bad_extra
mock.foo(k1: arg1, k2: arg2, k3: arg3)
end

assert_equal "unknown keyword: :k3", e.message # basically testing ruby
# basically testing ruby ... need ? for ruby < 2.7 :(
assert_match(/unknown keyword: :?k3/, e.message)
end

def test_mock_block_is_passed_keyword_args__block_bad_value
Expand Down Expand Up @@ -661,6 +663,19 @@ def test_mock_with_yield
@tc.assert_equal true, rs
end

def test_mock_with_yield_kwargs
mock = Minitest::Mock.new
rs = nil

File.stub :open, true, mock, kw:42 do
File.open "foo.txt", "r" do |f, kw:|
rs = kw
end
end

@tc.assert_equal 42, rs
end

alias test_stub_value__old test_stub_value # TODO: remove/rename

## Permutation Sets:
Expand Down

0 comments on commit 25b60ae

Please sign in to comment.