diff --git a/lib/flexmock/argument_matchers.rb b/lib/flexmock/argument_matchers.rb index c5b3da0..9bf76d8 100644 --- a/lib/flexmock/argument_matchers.rb +++ b/lib/flexmock/argument_matchers.rb @@ -67,6 +67,23 @@ def inspect end end + #################################################################### + # Match hashes that match all the fields of +hash+. + class KwArgsMatcher + def initialize(expected) + @expected = expected + end + def ===(target) + return false unless target.kind_of?(Hash) + return false unless @expected.all? { |k, v| v === target[k] } + + @expected.size == target.size + end + def inspect + "kw(#{@expected.inspect})" + end + end + #################################################################### # Match objects that implement all the methods in +methods+. class DuckMatcher diff --git a/lib/flexmock/expectation.rb b/lib/flexmock/expectation.rb index b8058c3..1b514d1 100644 --- a/lib/flexmock/expectation.rb +++ b/lib/flexmock/expectation.rb @@ -241,7 +241,12 @@ def with_any_args # Declare that the method can be called with any number of # arguments of any type. def with_kw_args(matcher) - @expected_kw_args = matcher + @expected_kw_args = + if matcher.kind_of?(Hash) + KwArgsMatcher.new(matcher) + else + matcher + end self end diff --git a/test/should_receive_test.rb b/test/should_receive_test.rb index f2ec04d..54fa51d 100644 --- a/test/should_receive_test.rb +++ b/test/should_receive_test.rb @@ -446,6 +446,32 @@ def test_with_kw_args_matching end end + def test_with_kw_args_matches_values_separately + FlexMock.use('greeter') do |m| + m.should_receive(:hi).with_kw_args(a: on { |v| v == 1 }, b: 2).once + m.hi(a: 1, b: 2) + end + end + + def test_with_kw_args_raises_if_an_expected_key_is_missing + assert_raises(FlexMock::CheckFailedError) do + FlexMock.use('greeter') do |m| + m.should_receive(:hi).with_kw_args(a: on { |v| v == 1 }, b: 2).once + m.hi(a: 1) + end + end + end + + def test_with_kw_args_raises_if_there_is_an_actual_key_too_much + assert_raises(FlexMock::CheckFailedError) do + FlexMock.use('greeter') do |m| + m.should_receive(:hi).with_kw_args(a: on { |v| v == 1 }, b: 2).once + m.hi(a: 1, b: 2, c: 3) + end + end + end + + def test_with_kw_args_non_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(20).with_kw_args(some: 10)