spec/woyo/world/attributes_spec.rb in woyo-world-0.0.5 vs spec/woyo/world/attributes_spec.rb in woyo-world-0.0.6
- old
+ new
@@ -15,18 +15,47 @@
attrs.count.should eq 3
attrs.all? { |a| a.is_a? Symbol }.should be_true
end
it 'hash of names and values can be retrieved for instance' do
- attrs = AttrTest.new.attributes
- attrs.should be_instance_of Hash
+ attr_test = AttrTest.new
+ attr_test.attributes.should be_instance_of Woyo::Attributes::AttributesHash
+ AttrTest.attributes.each do |attr|
+ attr_test.send(attr, attr.to_s.upcase)
+ end
+ attr_test.attributes.keys.should eq [ :attr1, :attr2, :attr3 ]
+ attr_test.attributes.values.should eq [ 'ATTR1', 'ATTR2', 'ATTR3' ]
end
+ it 'hash of names and nil values can be retrieved for instance before populating' do
+ attr_test = AttrTest.new
+ attr_test.attributes.should be_instance_of Woyo::Attributes::AttributesHash
+ attr_test.attributes.keys.should eq [ :attr1, :attr2, :attr3 ]
+ attr_test.attributes.values.should eq [ nil, nil, nil ]
+ end
+
+ it 'hash of names and default values can be retrieved for instance before populating' do
+ expect {
+ class DefTest
+ include Woyo::Attributes
+ attributes one: 1, two: 2, three: proc { 3 }
+ end
+ }.to_not raise_error
+ def_test = DefTest.new
+ def_test.attributes.keys.should eq [ :one, :two, :three ]
+ def_test.attributes.values.should eq [ 1, 2, 3 ]
+ end
+
+ it 'have convenience accessor :names for :keys' do
+ attr_test = AttrTest.new
+ attr_test.attributes.names.should eq [ :attr1, :attr2, :attr3 ]
+ end
+
it 'can be written via method with =' do
attr_test = AttrTest.new
AttrTest.attributes.each do |attr|
- attr_test.send(attr, attr.to_s.upcase)
+ attr_test.send("#{attr}=", attr.to_s.upcase)
end
attr_test.attributes.count.should eq AttrTest.attributes.count
attr_test.attributes.each do |name,value|
value.should eq name.to_s.upcase
end
@@ -60,17 +89,28 @@
attributes :attr4, :attr5, :attr6
end
}.to_not raise_error
AttrTest.attributes.count.should eq 6
attr_test = AttrTest.new
- # populate attributes
AttrTest.attributes.each do |attr|
attr_test.send(attr, attr.to_s.upcase)
end
attr_test.attributes.count.should eq 6
end
+ it 'can be defined with "attribute"' do
+ expect {
+ class AttrTest
+ attribute :open
+ end
+ }.to_not raise_error
+ attr_test = AttrTest.new
+ attr_test.open.should be_nil
+ attr_test.open = true
+ attr_test.open.should be_true
+ end
+
it 'can have a default value' do
expect {
class AttrTest
attributes attr_with_array___default: [ 1, 2, 3 ]
attributes attr_with_hash____default: { a: 1, b: 2, c: 3 }
@@ -139,9 +179,323 @@
end
end
}.to_not raise_error
attr_test = AttrTest.new
attr_test.attr_with_lambda_default.should eq "okay"
+ end
+
+ context 'that are boolean' do
+
+ context 'have convenient instance accessors' do
+
+ before :all do
+ expect {
+ class BooleanAttrTest
+ include Woyo::Attributes
+ attribute open: true
+ attribute light: false
+ end
+ }.to_not raise_error
+ end
+
+ it '#attr?' do
+ attr_test = BooleanAttrTest.new
+ attr_test.open.should eq true
+ attr_test.open?.should eq true
+ end
+
+ it '#attr!' do
+ attr_test = BooleanAttrTest.new
+ attr_test.open = false
+ attr_test.open.should eq false
+ attr_test.open!.should eq true
+ attr_test.open.should eq true
+ end
+
+ it '#is? :attr' do
+ attr_test = BooleanAttrTest.new
+ attr_test.is?(:open).should eq true
+ attr_test.open = false
+ attr_test.is?(:open).should eq false
+ end
+
+ it '#is :attr' do
+ attr_test = BooleanAttrTest.new
+ attr_test.light.should eq false
+ attr_test.is(:light)
+ attr_test.light.should eq true
+ end
+ end
+
+ context 'have class accessor ::is' do
+
+ # I was confused here, this may not be needed as a class method at all!!!
+
+ it 'that defines new attribute with true default' do
+ expect {
+ class BooleanIsTest1
+ include Woyo::Attributes
+ is :attr1
+ end
+ }.to_not raise_error
+ attr_test = BooleanIsTest1.new
+ attr_test.attr1.should eq true
+ end
+
+ it 'that sets true default for existing attribute' do
+ expect {
+ class BooleanIsTest2
+ include Woyo::Attributes
+ attribute :attr2
+ is :attr2
+ end
+ }.to_not raise_error
+ attr_test = BooleanIsTest2.new
+ attr_test.attr2.should eq true
+ end
+
+ it 'that changes default to true for existing attribute' do
+ expect {
+ class BooleanIsTest3
+ include Woyo::Attributes
+ attribute :attr3 => false
+ is :attr3
+ end
+ }.to_not raise_error
+ attr_test = BooleanIsTest3.new
+ attr_test.attr3.should eq true
+ end
+
+ it 'that works for attribute in BooleanGroup' do
+ expect {
+ class BooleanIsTest4
+ include Woyo::Attributes
+ group! :temp, :hot, :warm, :cool, :cold
+ # :hot is true by default
+ is :cold
+ # :cold is now true
+ end
+ }.to_not raise_error
+ attr_test = BooleanIsTest4.new
+ attr_test.hot.should eq false
+ attr_test.warm.should eq false
+ attr_test.cool.should eq false
+ attr_test.cold.should eq true
+ end
+
+ end
+
+ end
+
+ context 'can be re-defined' do
+
+ it 'without duplication' do
+ expect {
+ class AttrReDef1
+ include Woyo::Attributes
+ attribute :attr1
+ end
+ class AttrReDef1
+ attribute :attr1
+ end
+ }.to_not raise_error
+ AttrReDef1.attributes.count.should eq 1
+ AttrReDef1.attributes.should eq [:attr1]
+ attr_rd1 = AttrReDef1.new
+ attr_rd1.attr1.should be_nil
+ end
+
+ it 'to set default' do
+ expect {
+ class AttrReDef2
+ include Woyo::Attributes
+ attribute :attr2
+ end
+ class AttrReDef2
+ attribute attr2: 'two'
+ end
+ }.to_not raise_error
+ AttrReDef2.attributes.count.should eq 1
+ AttrReDef2.attributes.should eq [:attr2]
+ attr_rd2 = AttrReDef2.new
+ attr_rd2.attr2.should eq 'two'
+ end
+
+ it 'to change default' do
+ expect {
+ class AttrReDef3
+ include Woyo::Attributes
+ attribute attr3: '333'
+ end
+ class AttrReDef3
+ attribute attr3: 'three'
+ end
+ }.to_not raise_error
+ AttrReDef3.attributes.count.should eq 1
+ AttrReDef3.attributes.should eq [:attr3]
+ attr_rd3 = AttrReDef3.new
+ attr_rd3.attr3.should eq 'three'
+ end
+
+ end
+
+ context 'groups' do
+
+ before :all do
+ class AT
+ include Woyo::Attributes
+ group :stooges, :larry, :curly, :moe
+ group :cars, :mustang, :ferarri, :mini
+ end
+ @at = AT.new
+ end
+
+ it 'can be listed for class' do
+ groups = AT.groups
+ groups.should be_instance_of Hash
+ groups.count.should eq 2
+ groups.keys.should eq [ :stooges, :cars ]
+ groups[:stooges].should eq [ :larry, :curly, :moe ]
+ groups[:cars].should eq [ :mustang, :ferarri, :mini ]
+ end
+
+ it 'have convenience accessor :names for :keys' do
+ @at.stooges.names.should eq [ :larry, :curly, :moe ]
+ end
+
+ it 'names and nil values can be retrieved from instance without populating' do
+ @at.stooges.should be_instance_of Woyo::Attributes::Group
+ @at.stooges.count.should eq 3
+ @at.stooges.names.should eq [ :larry, :curly, :moe ]
+ @at.stooges.values.should eq [ nil, nil, nil ]
+ end
+
+ it 'names and default values can be retrieved from instance without populating' do
+ expect {
+ class GroupDefTest
+ include Woyo::Attributes
+ group :numbers, one: 1, two: 2, three: proc { 3 }
+ end
+ }.to_not raise_error
+ def_test = GroupDefTest.new
+ groups = def_test.groups
+ groups.should be_instance_of Hash
+ groups.count.should eq 1
+ groups.names.should eq [ :numbers ]
+ groups[:numbers].should be_instance_of Woyo::Attributes::Group
+ groups[:numbers].names.should eq [ :one, :two, :three ]
+ groups[:numbers].values.should eq [ 1, 2, 3 ]
+ def_test.numbers.names.should eq [ :one, :two, :three ]
+ def_test.numbers.values.should eq [ 1, 2, 3 ]
+ end
+
+ it 'members can be accessed via group' do
+ @at.stooges[:curly].should eq nil
+ @at.stooges[:curly] = 'bald'
+ @at.stooges[:curly].should eq 'bald'
+ end
+
+ it 'members are also attributes' do
+ all_attrs = [ :larry, :curly, :moe, :mustang, :ferarri, :mini ]
+ @at.attributes.keys.should eq all_attrs
+ all_attrs.each do |attr|
+ @at.should respond_to attr
+ end
+ end
+
+ it 'members are attributes' do
+ @at.stooges[:moe] = 'knucklehead'
+ @at.stooges[:moe].should eq 'knucklehead'
+ @at.moe.should eq 'knucklehead'
+ end
+
+ it 'attributes are members' do
+ @at.ferarri = 'fast'
+ @at.ferarri.should eq 'fast'
+ @at.cars[:ferarri].should eq 'fast'
+ end
+
+ end
+
+ context 'boolean groups' do
+
+ before :all do
+ class ExGroupTest
+ include Woyo::Attributes
+ group! :temp, :hot, :warm, :cool, :cold
+ group! :light, :dark, :dim, :bright
+ end
+ end
+
+ it 'are listed for a class' do
+ groups = ExGroupTest.boolean_groups
+ groups.should be_instance_of Hash
+ groups.count.should eq 2
+ groups.keys.should eq [ :temp, :light ]
+ groups[:temp].should eq [ :hot, :warm, :cool, :cold ]
+ groups[:light].should eq [ :dark, :dim, :bright ]
+ end
+
+ it 'accessor returns BooleanGroup instance' do
+ egt = ExGroupTest.new
+ egt.temp.should be_instance_of Woyo::Attributes::BooleanGroup
+ end
+
+ it 'first member is true, rest are false' do
+ egt = ExGroupTest.new
+ egt.light[:dark].should eq true
+ egt.light[:dim].should eq false
+ egt.light[:bright].should eq false
+ end
+
+ it 'making group member true affects member attributes' do
+ egt = ExGroupTest.new
+ egt.temp[:cold] = true
+ egt.cold.should be true
+ egt.cool.should be false
+ egt.warm.should be false
+ egt.hot.should be false
+ end
+
+ it 'making attribute true affects group members' do
+ egt = ExGroupTest.new
+ egt.cold = true
+ egt.light[:cold].should be true
+ egt.light[:cool].should be false
+ egt.light[:warm].should be false
+ egt.light[:hot].should be false
+ end
+
+ end
+
+ context 'assigned a Hash as a value' do
+
+ before :all do
+ class AttrHashTest
+ include Woyo::Attributes
+ attributes :reaction, :hot, :cold
+ end
+ @aht = AttrHashTest.new
+ end
+
+ it 'accepts the hash as a value' do
+ expect { @aht.reaction hot: 'Sweat', cold: 'Shiver' }.to_not raise_error
+ end
+
+ it 'returns the value of the first key that evaluates as a true attribute' do
+ @aht.cold = true
+ @aht.reaction.should eq 'Shiver'
+ @aht.hot = true
+ @aht.reaction.should eq 'Sweat'
+ end
+
+ it 'otherwise it returns the hash' do
+ reactions = { :hot => 'Sweat', :cold => 'Shiver' }
+ @aht.cold = false
+ @aht.hot = false
+ @aht.reaction.should eq reactions
+ end
+
end
end