-
-
Save ke4roh/348afe4a793d7d281071 to your computer and use it in GitHub Desktop.
declare module_function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
gem 'json' | |
group :test do | |
gem 'minitest' | |
gem 'test-unit' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module JsonUtilities | |
module_function | |
# compares two json objects (Array, Hash, or String to be parsed) for equality. | |
# Returns true if the objects are equivalent, false otherwise | |
def compare_json(json1, json2) | |
# return false if classes mismatch or don't match our allowed types | |
unless((json1.class == json2.class) && (json1.is_a?(String) || json1.is_a?(Hash) || json1.is_a?(Array))) | |
return false | |
end | |
# Parse objects to JSON if Strings | |
json1,json2 = [json1,json2].map! do |json| | |
json.is_a?(String) ? JSON.parse(json) : json | |
end | |
return compare_json0(json1, json2) | |
end | |
def compare_json0(json1, json2) | |
# initializing result var in the desired scope | |
result = false | |
# If an array, loop through each subarray/hash within the array and recursively call self with these objects for traversal | |
if(json1.is_a?(Array)) | |
# Lengths must match | |
return false unless (json1.length==json2.length) | |
result = true # Zero length is also valid | |
json1.each_with_index do |obj, index| | |
json1_obj, json2_obj = obj, json2[index] | |
result = compare_json0(json1_obj, json2_obj) | |
# End loop once a false match has been found | |
break unless result | |
end | |
elsif(json1.is_a?(Hash)) | |
# If a hash, check object1's keys and their values object2's keys and values | |
# first check that there are the same number of keys | |
return false unless (json1.keys.length==json2.keys.length) | |
# created_at and updated_at can create false mismatches due to occasional millisecond differences in tests | |
[json1,json2].each { |json| json.delete_if {|key,value| ["created_at", "updated_at"].include?(key)} } | |
json1.each do |key,value| | |
# both objects must have a matching key to pass | |
return false unless json2.has_key?(key) | |
json1_val, json2_val = value, json2[key] | |
result = compare_json0(json1_val, json2_val) | |
# End loop once a false match has been found | |
break unless result | |
end | |
end | |
return result ? true : (json1 == json2) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'json_utilities' | |
require "minitest/autorun" | |
require 'json' | |
class TestJsonUtilities < MiniTest::Unit::TestCase | |
def test_same | |
initial=JSON.parse(<<eos) | |
{ | |
"firstName": "John", | |
"lastName": "Smith", | |
"isAlive": true, | |
"age": 25, | |
"height_cm": 167.6, | |
"address": { | |
"streetAddress": ["Big Street|6,5"], | |
"city": "New York", | |
"state": "NY", | |
"postalCode": "10021-3100" | |
}, | |
"phoneNumbers": [ | |
{ | |
"type": "home", | |
"number": "212 555-1234" | |
}, | |
{ | |
"type": "office", | |
"number": "646 555-4567" | |
} | |
], | |
"children": [], | |
"spouse": null | |
} | |
eos | |
test=JSON.parse(<<eos) | |
{"firstName": "John", "lastName": "Smith", "height_cm": 167.6, "age": 25, "address": {"streetAddress": ["Big Street|6,5"], "state": "NY", "postalCode": "10021-3100", "city": "New York"}, "isAlive": true, "spouse": null, "children": [], "phoneNumbers": [{"number": "212 555-1234", "type": "home"}, {"number": "646 555-4567", "type": "office"}]} | |
eos | |
puts JSON.pretty_generate(test) | |
assert(JsonUtilities.compare_json(initial,test),"Big comparison fails") | |
end | |
def test_empty_array_in_hash | |
assert(JsonUtilities.compare_json('{"foo": []}','{"foo": []}')) | |
end | |
def test_string_in_array | |
assert(JsonUtilities.compare_json('["foo"]','["foo"]'),"String in array fails") | |
end | |
def test_empty_array | |
assert(JsonUtilities.compare_json('[]','[]')) | |
end | |
def test_json2_hash_with_extra_key | |
a='{"foo":"bar"}' | |
b='{"foo":"bar", "bar":"baz"}' | |
assert(JsonUtilities.compare_json(a,b)==false,"fails with an extra key in jsonb") | |
assert(JsonUtilities.compare_json(b,a)==false,"fails with an extra key in jsona") | |
end | |
def test_null_hash_value_equality | |
a='{"foo": null}' | |
assert(JsonUtilities.compare_json(a,a)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment