Rspec Candies and Cookies

[ruby]
it "include_hash tests nested hashes" do
{ foo: ‘a’, bar: {nested_hash: {fi: ‘c’, baz:’b’} }}.should include_nested_hash(nested_hash: {fi: ‘c’, baz:’b’})
end
[/ruby]

Combining Mandraka’s  Rspec Candy with this little find from CookiesHQ, led me to a nested hash matcher

Very useful for testing API responses.

[ruby toolbar=”true”]

def find_first_value_for(hsh, key)
return hsh[key] if hsh[key]
hsh.values.each do |hash_value|
values = [hash_value] unless hash_value.is_a? Array
values.each{ |value| return find_first_value_for(value, key) if value.is_a? Hash }
end
end

RSpec::Matchers.define :include_nested_hash do |expected|
match do |actual|
if !actual.nil? and expected.is_a? Hash
if expected.keys.count > 1
keys.map do |key|
value = find_first_value_for actual(actual, key)
!value.nil? ? {key.to_sym => value} : {}
end
elsif expected.keys.count == 1
{expected.keys.first => find_first_value_for(actual, expected.keys.first)}
else
{}
end
!actual.nil? && result == expected
else
false
end
end
end
[/ruby]

Just include it in your spec_helper.rb or custom matcher module then test with something like this:

[ruby toolbar=”true”]
context "when testing with rspec candy" do
it "include_hash is available" do
{ foo: ‘a’, bar: ‘b’ }.should include_hash(foo: ‘a’)
end
it "include_hash tests nested hashes" do
{ foo: ‘a’, bar: {nested_hash: {fi: ‘c’, baz:’b’} }}.should include_nested_hash(nested_hash: {fi: ‘c’, baz:’b’})
end
end
[/ruby]