Skip to content

Commit

Permalink
Collection Hash class for giving collection attributes more intelligence
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethan Rowe committed May 4, 2010
1 parent 57e27db commit e576056
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/simple_mapper.rb
@@ -1,4 +1,5 @@
module SimpleMapper
require 'simple_mapper/collection'
require 'simple_mapper/attribute'
require 'simple_mapper/attribute/pattern'
require 'simple_mapper/attributes'
Expand Down
8 changes: 7 additions & 1 deletion lib/simple_mapper/attribute/pattern.rb
Expand Up @@ -26,12 +26,18 @@ def transformed_source_value(object)

def apply_type(value)
converter = self.converter
value.inject({}) do |hash, keyval|
value.inject(new_collection) do |hash, keyval|
hash[keyval[0]] = converter.decode(keyval[1])
hash
end
end

def new_collection
h = SimpleMapper::Collection::Hash.new
h.attribute = self
h
end

def to_simple(object, container, options = {})
val = value(object)
mapper = self.mapper
Expand Down
16 changes: 16 additions & 0 deletions lib/simple_mapper/collection.rb
@@ -0,0 +1,16 @@
require 'delegate'
module SimpleMapper
module Collection
class Hash < DelegateClass(::Hash)
attr_accessor :attribute

def initialize(hash = {})
super(hash)
end

def build(*args)
attribute.mapper.new(*args)
end
end
end
end
14 changes: 12 additions & 2 deletions test/unit/attribute_pattern_test.rb
Expand Up @@ -150,11 +150,21 @@ class SimpleMapperAttributePatternTest < Test::Unit::TestCase
@instance.apply_type(@input)
end

should 'return new hash of keys mapped to decoded values' do
should 'return new collection hash of keys mapped to decoded values' do
@expected.each do |key, value|
@type.stubs(:decode).with(@input[key]).returns(value)
end
assert_equal @expected, @instance.apply_type(@input)
result = @instance.apply_type(@input)
assert_equal @expected, result
assert_equal SimpleMapper::Collection::Hash, result.class
end

should 'initialize collection hash with the attribute instance' do
@expected.each do |key, value|
@type.stubs(:decode).with(@input[key]).returns(value)
end
result = @instance.apply_type(@input)
assert_equal @instance, result.attribute
end
end
end
Expand Down
52 changes: 52 additions & 0 deletions test/unit/collection_hash_test.rb
@@ -0,0 +1,52 @@
require 'test_helper'

class CollectionHashTest < Test::Unit::TestCase
context 'A SimpleMapper::Collection::Hash' do
setup do
@class = SimpleMapper::Collection::Hash
end

should 'be equivalent to a hash passed to the constructor' do
hash = {:a => 'A', :b => 'B'}
instance = @class.new(hash)
assert_equal hash, instance
assert_equal @class, instance.class
end

should 'allow hash-style lookups, assignments, etc.' do
instance = @class.new
assert_equal nil, instance[:foo]
assert_equal :bar, instance[:foo] = :bar
assert_equal :bar, instance[:foo]
assert_equal true, instance.has_key?(:foo)
assert_equal false, instance.has_key?(:blah)
assert_equal :blee, instance[:boo] = :blee
assert_equal :blee, instance[:boo]
assert_equal([:boo, :foo], instance.keys.sort_by {|k| k.to_s})
end

should 'have an :attribute attribute' do
instance = @class.new
assert_equal nil, instance.attribute
attrib = stub('attribute_object')
assert_equal attrib, instance.attribute = attrib
assert_equal attrib, instance.attribute
end

should 'allow construction of new mapper instances through :build' do
mapper = stub('mapper')
attrib = stub('attribute_object', :mapper => mapper)
seq = sequence('build invocations')
mapper.expects(:new).with.in_sequence(seq).returns(:one)
mapper.expects(:new).with(:a => 'A').in_sequence(seq).returns(:two)
mapper.expects(:new).with(:foo, :bar, :a => 'A', :b => 'B').in_sequence(seq).returns(:three)
instance = @class.new
instance.attribute = attrib
result = []
result << instance.build
result << instance.build(:a => 'A')
result << instance.build(:foo, :bar, :a => 'A', :b => 'B')
assert_equal [:one, :two, :three], result
end
end
end

0 comments on commit e576056

Please sign in to comment.