Skip to content

Instantly share code, notes, and snippets.

@senny
Created December 30, 2013 10:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save senny/8180368 to your computer and use it in GitHub Desktop.
Save senny/8180368 to your computer and use it in GitHub Desktop.
class KeyExtractor
def self.extract(key_spec, source)
new(key_spec.split("."), source).extract
end
def self.extract_array(key_spec, source)
extract(key_spec, source) || []
end
def initialize(key_parts, source)
@key_parts = key_parts
@source = source
end
def extract
while key = @key_parts.shift
extraction_method = "extract_#{@source.class}"
@source = if respond_to?(extraction_method)
send extraction_method, key, @source
else
extract_Unknown key, @source
end
end
@source
end
def extract_Hash(key, source)
source[key]
end
def extract_Array(key, source)
rest_key = ([key] + @key_parts).join(".")
source.map { |e| KeyExtractor.extract(rest_key, e)}.compact
end
def extract_NilClass(key, source)
nil
end
def extract_Unknown(key, source)
nil
end
end
require "unit/test_helper"
require "key_extractor"
class KeyExtractorTest < ActiveSupport::TestCase
setup do
@extractor = KeyExtractor
end
test "extracts a top level key" do
assert_equal 3, @extractor.extract("a", {"a" => 3, "b" => 4})
end
test "extracts a nested key hash" do
assert_equal "yay", @extractor.extract("a.b", {"a" => { "b" => "yay" }})
end
test "extracts a nested key" do
assert_equal ["1", "4"], @extractor.extract("a.b", {"a" => [{"b" => "1", "c" => "2"},
{"c" => "3"},
{"b" => "4"}]})
end
test "extract from array" do
assert_equal ["5", "7"], @extractor.extract("c", [{"c" => "5"},
{"d" => 1},
{"c" => "7", "d" => 3}])
end
test "nil when the key does not exist" do
assert_equal nil, @extractor.extract("a.b", {})
end
test "nil when key is too long" do
assert_equal nil, @extractor.extract("a.b.c", {"a" => {"b" => "the end"}})
end
test "blank array when there is nothing to extract" do
assert_equal [], @extractor.extract("a.b", {"a" => []})
assert_equal [], @extractor.extract("a.b", {"a" => [{"c" => "1"}]})
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment