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