Skip to content

Instantly share code, notes, and snippets.

@dgraham
Created September 19, 2012 16:37
Show Gist options
  • Save dgraham/3750660 to your computer and use it in GitHub Desktop.
Save dgraham/3750660 to your computer and use it in GitHub Desktop.
Hash -> Schema
require 'minitest/spec'
require 'minitest/autorun'
require 'set'
class Schemas
def initialize
@schemas = Set.new
end
def <<(hash)
@schemas << hash
end
def to_a
@schemas.to_a
end
end
class HashSchema
def schema(hash)
{}.tap do |result|
hash.keys.sort.each do |key|
result[key] = classify(hash, key)
end
end
end
private
def classify(hash, key)
case hash[key]
when Hash
schema(hash[key])
else
hash[key].class.name.downcase
end
end
end
describe HashSchema do
subject { HashSchema.new }
describe 'when given unsorted hash keys' do
let(:hash) { {'z' => 42, 'y' => 43, 'x' => '44'} }
let(:expected) { {'x' => 'string', 'y' => 'fixnum', 'z' => 'fixnum'} }
it 'sorts and classifies value types' do
subject.schema(hash).must_equal expected
end
end
describe 'when given unsorted nested hashes' do
let(:hash) { {'z' => 42, 'y' => {'c' => true, 'b' => 12.1}} }
let(:expected) { {'y' => {'b' => 'float', 'c' => 'trueclass'}, 'z' => 'fixnum'} }
it 'recursively sorts and classifies value types' do
subject.schema(hash).must_equal expected
end
end
end
describe Schemas do
subject { Schemas.new }
describe 'when given duplicate hashes' do
let(:expected) { [{'a' => 42}, {'b' => 12}] }
it 'only tracks distinct entries' do
subject << {'a' => 42}
subject << {'b' => 12}
subject << {'a' => 42}
subject.to_a.size.must_equal 2
subject.to_a.must_equal expected
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment