Skip to content

Commit

Permalink
Merge pull request #18 from stitchfix/bugfix/fix-eql
Browse files Browse the repository at this point in the history
Make immutable_struct set-friendly
  • Loading branch information
billeisenhauer committed Feb 22, 2016
2 parents fc06e98 + 0755c45 commit 2c3b19d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/immutable-struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,18 @@ def self.new(*attributes,&block)
end

alias_method :eql?, :==

define_method(:hash) do
attribute_values = attributes.map { |attr| self.send(attr) }
(attribute_values + [self.class]).hash
end
end
klass.class_exec(&block) unless block.nil?
imethods = klass.instance_methods(include_super=false)
klass.class_exec(imethods) do |imethods|
define_method(:to_h) do
imethods.inject({}) do |hash, method|
next hash if [:==, :eql?, :merge].include?(method)
next hash if [:==, :eql?, :merge, :hash].include?(method)
hash.merge(method.to_sym => self.send(method))
end
end
Expand Down
40 changes: 40 additions & 0 deletions spec/immutable_struct_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,45 @@ def lawsuit

end

describe "hash" do

it "should have same hash value as itself" do
@k1_a.hash.eql?(@k1_a.hash).should be true
end

it "should have same hash value as same class with identical attribute values" do
@k1_a.hash.eql?(@k1_c.hash).should be true
end

it 'should not have hash value as same class with different attribute values' do
@k1_a.hash.eql?(@k1_b.hash).should be false
end

it 'should not have hash value equal to different class with identical attribute values' do
@k1_a.hash.eql?(@k3_a.hash).should be false
end

it 'should reject set addition if same instance is already a member' do
set = Set.new([@k1_a])
set.add?(@k1_a).should be nil
end

it 'should reject set addition if different instance, but attributes are the same' do
set = Set.new([@k1_a])
set.add?(@k1_c).should be nil
end

it 'should allow set addition if different instance and attribute values' do
set = Set.new([@k1_a])
set.add?(@k1_b).should_not be nil
end

it 'should allow set addition if different class' do
set = Set.new([@k1_a])
set.add?(@k2_a).should_not be nil
end

end

end
end

0 comments on commit 2c3b19d

Please sign in to comment.