Message expectation doesn't leverage passed matcher capabilities when reporting error.
Created by: rfronczyk
Subject of the issue
Calling expect(...).to receive(...).with(...)
with a composed matcher doesn't use the full capabilities of the passed matcher in order to provide a more precise error message to the user.
You can argue that the diff produced in the attached example is correct ( the passed array doesn't match the expected one so the diff include the whole array), that said the other example shows that it could be done better.
Your environment
- Ruby version: ruby-2.4.6
- rspec-mocks version: 3.8.2
Steps to reproduce
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "rspec", "3.8.2" # Activate the gem and version you are reporting the issue against.
end
puts "Ruby version is: #{RUBY_VERSION}"
require 'rspec/autorun'
class A
def test(params)
end
end
B = Struct.new(:a, :b)
RSpec.describe 'additions' do
let(:test_double) { instance_double(A) }
let(:passed_attributes) do
[
B.new(1, 2),
B.new(3, 4),
B.new(5, 6),
B.new(7, 8)
]
end
let(:attribute_matcher) do
[
have_attributes(a: 1, b: 2),
have_attributes(a: 3, b: 4),
have_attributes(a: 5, b: 10),
have_attributes(a: 7, b: 8)
]
end
it 'shows the whole array instead of elements which dont match' do
expect(test_double).to receive(:test).with(a_collection_containing_exactly(*attribute_matcher))
test_double.test(passed_attributes)
end
it 'shows only not matching elements' do
expect(passed_attributes).to contain_exactly(*attribute_matcher)
end
end
Expected behavior
I would expect that error message shows only elements of the array which don't match the expectation.
Actual behavior
Error message lists the whole array.