You can override the expected and actual methods, which will then be used to create the diff. In this example, we store the expected and actual values as instance variables and define methods that return instance variables:
RSpec::Matchers.define :be_matching_content do |expected_raw| match do |actual_raw| @actual = actual_raw.gsub(/\s/,'') @expected = expected_raw.gsub(/\s/,'') expect(expected).to eq(@actual) end diffable attr_reader :actual, :expected end
Another example is matching specific attributes in two different types of objects. (The expected object in this case is the Client model.)
RSpec::Matchers.define :have_attributes_of_v1_client do |expected_client| match do |actual_object| @expected = client_attributes(expected_client) @actual = actual_object.attributes expect(actual_object).to have_attributes(@expected) end diffable attr_reader :actual, :expected def failure_message "expected attributes of a V1 Client view row, but they do not match" end def client_attributes(client) { "id" => client.id, "client_type" => client.client_type.name, "username" => client.username, "active" => client.active?, } end end
An example error is as follows:
Failure/Error: is_expected.to have_attributes_of_v1_client(client_active_partner) expected attributes of a V1 Client view row, but they do not match Diff: @@ -1,6 +1,6 @@ "active" => true, -"client_type" => #<ClientType id: 2, name: "ContentPartner">, +"client_type" => "ContentPartner", "id" => 11,
source share