Skip to content

Commit

Permalink
Change behavior of Attribute#== method
Browse files Browse the repository at this point in the history
By changing Coercer#== and DefaultValue#== methods, we allow
Attribute#== to actually compare objects now (before, every comparison
would return `false` because of different instances of DefaultValue
model in options[:default_value] key.
  • Loading branch information
novikserg committed Jul 19, 2015
1 parent 3748f6e commit ef57af3
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 19 deletions.
2 changes: 2 additions & 0 deletions lib/virtus/attribute/default_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Attribute
class DefaultValue
extend DescendantsTracker

include Equalizer.new(inspect) << :value

# Builds a default value instance
#
# @return [Virtus::Attribute::DefaultValue]
Expand Down
1 change: 1 addition & 0 deletions lib/virtus/coercer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Virtus
# Abstract coercer class
#
class Coercer
include Equalizer.new(inspect) << :primitive << :type

# @api private
attr_reader :primitive, :type
Expand Down
7 changes: 2 additions & 5 deletions spec/unit/virtus/attribute/comparison_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
describe Virtus::Attribute, '#== (defined by including Virtus::Equalizer)' do
let(:attribute) { described_class.build(String, :name => :name) }

# Currently that's the way it works and it happens because default_value objects
# don't have equalizer, resulting in attributes object mismatch.
# This behavior (and a spec) will need a change in future.
it 'returns false when attributes have same type and options' do
it 'returns true when attributes have same type and options' do
equal_attribute = described_class.build(String, :name => :name)
expect(attribute == equal_attribute).to be_falsey
expect(attribute == equal_attribute).to be_truthy
end

it 'returns false when attributes have different type' do
Expand Down
8 changes: 4 additions & 4 deletions spec/unit/virtus/attribute_set/append_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@

it { is_expected.to equal(object) }

it 'replaces the original attribute' do
expect { subject }.to change { object.to_a }.
from(attributes).
to([ attribute ])
it "replaces the original attribute object" do
expect { subject }.to change { object.to_a.map(&:__id__) }.
from(attributes.map(&:__id__)).
to([attribute.__id__])
end
end
end
22 changes: 15 additions & 7 deletions spec/unit/virtus/attribute_set/element_set_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,28 @@

it { is_expected.to equal(attribute) }

it 'replaces the original attribute' do
expect { subject }.to change { object.to_a }.from(attributes).to([ attribute ])
it "replaces the original attribute object" do
expect { subject }.to change { object.to_a.map(&:__id__) }.
from(attributes.map(&:__id__)).
to([attribute.__id__])
end

it 'allows #[] to access the attribute with a symbol' do
expect { subject }.to change { object['name'] }.from(original).to(attribute)
it 'allows #[] to access the attribute with a string' do
expect { subject }.to change { object['name'].__id__ }.
from(original.__id__).
to(attribute.__id__)
end

it 'allows #[] to access the attribute with a string' do
expect { subject }.to change { object[:name] }.from(original).to(attribute)
it 'allows #[] to access the attribute with a symbol' do
expect { subject }.to change { object[:name].__id__ }.
from(original.__id__).
to(attribute.__id__)
end

it 'allows #reset to track overridden attributes' do
expect { subject }.to change { object.reset.to_a }.from(attributes).to([ attribute ])
expect { subject }.to change { object.reset.to_a.map(&:__id__) }.
from(attributes.map(&:__id__)).
to([attribute.__id__])
end
end
end
8 changes: 5 additions & 3 deletions spec/unit/virtus/attribute_set/merge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@

context 'with a duplicate attribute' do
let(:attributes) { [Virtus::Attribute.build(String, :name => name)] }
let(:attribute) { Virtus::Attribute.build(String, :name => name) }
let(:attribute) { Virtus::Attribute.build(String, :name => name) }

it { is_expected.to equal(object) }

it 'replaces the original attribute' do
expect { subject }.to change { object.to_a }.from(attributes).to([attribute])
it "replaces the original attribute object" do
expect { subject }.to change { object.to_a.map(&:__id__) }.
from(attributes.map(&:__id__)).
to([attribute.__id__])
end
end
end

0 comments on commit ef57af3

Please sign in to comment.