dostu
dostu

Reputation: 1518

Confusing RSpec hash match diff

I'm using RSpec match matcher to check if a hash contains expected values. When a key of the hash doesn't match, all the dynamic (a_string_starting_with, etc) values are shown as not matching. It's especially distracting when you try to match a bigger hash. I'm wondering if there's another way check the hash, so only the values which really do not match would show up in the diff.

Here's an example, where a is marked in red, although the value is correct.

it 'matches' do
  actual = {
    a: 'test test',
    b: 1,
    c: 2,
  }

  expect(actual).to match(
    a: a_string_starting_with('test'),
    b: 0,
    c: 2,
  )
end

Match diff

I'm wondering if there's another matcher I should use. Or if there are any custom matchers or gems for this?

Upvotes: 3

Views: 1642

Answers (2)

Xiaohui Zhang
Xiaohui Zhang

Reputation: 1125

I got the same problem, this works to me:

# spec/supports/hash_diff_patcher.rb
module HashDiffPatcher
  def diff_as_object(actual, expected)
    if kind_of_hash?(actual) && kind_of_hash?(expected)
      super(actual.sort.to_h, expected.sort.to_h)
    else
      super
    end
  end

  private

  def kind_of_hash?(obj)
    # compact grape entity
    obj.instance_of?(Hash) || obj.instance_of?(Grape::Entity::Exposure::NestingExposure::OutputBuilder)
  end
end

RSpec::Support::Differ.prepend HashDiffPatcher

Upvotes: 0

Aleksis Zalitis
Aleksis Zalitis

Reputation: 121

The problem with this is the current differ gem used by RSpec and they are already aware of the issue, though currently no fix exists, as can be seen by these tickets:

One of the solutions in proposed for now in the ticket is similar to what Mosaaleb is suggesting.

Upvotes: 5

Related Questions