Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec: comparing a hash with string keys against a hash with symbol keys?

Consider the following RSpec snippet:

it "should match" do
  {:a => 1, :b => 2}.should =~ {"a" => 1, "b" => 2}
end

This test fails because one hash uses symbols for keys and the other uses strings for keys. In my case, one hash is a parsed JSON object, the other is the hash that created the object. I'd like them to compare as equal.

Before I go writing my own matcher or coercing both hashes to have string keys, is there a matcher or technique that handles this (common) case?

like image 782
fearless_fool Avatar asked Aug 06 '12 17:08

fearless_fool


People also ask

Why are symbols faster than strings?

Main differences between Strings and SymbolsSymbols are immutable; Strings aren't. Being immutable means that the values won't change. Therefore, Symbols are faster than Strings. In fact, Strings are about 1.7 times slower than Symbols!

Can you iterate through a hash Ruby?

Iterating over a HashYou can use the each method to iterate over all the elements in a Hash. However unlike Array#each , when you iterate over a Hash using each , it passes two values to the block: the key and the value of each element.

What is a hash pair?

Entries in a hash are often referred to as key-value pairs. This creates an associative representation of data. Most commonly, a hash is created using symbols as keys and any data types as values. All key-value pairs in a hash are surrounded by curly braces {} and comma separated.

What is hash in Ruby?

In Ruby, Hash is a collection of unique keys and their values. Hash is like an Array, except the indexing is done with the help of arbitrary keys of any object type. In Hash, the order of returning keys and their value by various iterators is arbitrary and will generally not be in the insertion order.


2 Answers

You could do:

it "should match" do
    {:a => 1, :b => 2}.stringify_keys.should =~ {"a" => 1, "b" => 2}
end
like image 137
Shailen Tuli Avatar answered Oct 21 '22 12:10

Shailen Tuli


Assuming you have access to Rails's ActiveSupport. You can leverage with_indifferent_access to match both hashes. Below is an example with the hashrocket Ruby syntax and the Rspec expect syntax:

it 'matches two hashes' do
  hash_1 = {a: 1, b: 2}.with_indifferent_access
  hash_2 = {'a' => 1, 'b' => 2}
  expect(hash_1).to match(hash_2)
end

Note: make sure to use with_indifferent_access on the hash with the symbol keys

like image 35
yacc Avatar answered Oct 21 '22 12:10

yacc