spec/woyo/world/attributes_spec.rb in woyo-world-0.0.6 vs spec/woyo/world/attributes_spec.rb in woyo-world-0.0.7

- old
+ new

@@ -1,499 +1,417 @@ +require 'spec_helper' require 'woyo/world/attributes' describe Woyo::Attributes do before :all do class AttrTest include Woyo::Attributes - attributes :attr1, :attr2, :attr3 end end - - it 'names can be listed for class' do - attrs = AttrTest.attributes - attrs.should be_instance_of Array - 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 - 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) + context '#attributes' do + + it 'returns empty AttributesHash for instance with no attributes' do + attr_test = AttrTest.new + expect(attr_test.attributes).to be_instance_of Woyo::Attributes::AttributesHash + expect(attr_test.attributes.count).to eq 0 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 'returns AttributesHash with names and nil values for instance with unpopulated attributes' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + expect(attr_test.attributes).to be_instance_of Woyo::Attributes::AttributesHash + expect(attr_test.attributes.keys).to eq [ :attr1, :attr2, :attr3 ] + expect(attr_test.attributes.values).to 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 } + it 'returns AttributesHash with names and values for instance with populated attributes' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + expect(attr_test.attributes).to be_instance_of Woyo::Attributes::AttributesHash + expect(attr_test.attributes.keys).to eq [ :attr1, :attr2, :attr3 ] + attr_test.attributes.keys.each do |attr| + attr_test.send(attr, attr.to_s.upcase) 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) + expect(attr_test.attributes.values).to eq [ 'ATTR1', 'ATTR2', 'ATTR3' ] 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 - end - it 'can be written via method without =' do - attr_test = AttrTest.new - AttrTest.attributes.each do |attr| - attr_test.send(attr, attr.to_s.upcase) + it 'returns AttributesHash with names and default values for instance with unpopulated attributes' do + attr_test = AttrTest.new + attr_test.attributes one: 1, two: 2, three: 3 + expect(attr_test.attributes).to be_instance_of Woyo::Attributes::AttributesHash + expect(attr_test.attributes.keys).to eq [ :one, :two, :three ] + expect(attr_test.attributes.values).to eq [ 1, 2, 3 ] 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 - end - it 'can be read via method' do - attr_test = AttrTest.new - AttrTest.attributes.each do |attr| - attr_test.send(attr, attr.to_s.upcase) + it 'provides convenience accessor :names for :keys' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + expect(attr_test.attributes.names).to eq [ :attr1, :attr2, :attr3 ] end - attr_test.attributes.count.should eq AttrTest.attributes.count - attr_test.attributes.each do |name,value| - eval("attr_test.#{name}").should eq value - end + end - it 'list can be added to' do - expect { - class AttrTest - attributes :attr4, :attr5, :attr6 + context 'can be accessed' do + + it 'to write via method with =' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + attr_test.attributes.names.each do |attr| + attr_test.send("#{attr}=", attr.to_s.upcase) end - }.to_not raise_error - AttrTest.attributes.count.should eq 6 - attr_test = AttrTest.new - AttrTest.attributes.each do |attr| - attr_test.send(attr, attr.to_s.upcase) + attr_test.attributes.each do |name,value| + expect(value).to eq name.to_s.upcase + end end - attr_test.attributes.count.should eq 6 - end - it 'can be defined with "attribute"' do - expect { - class AttrTest - attribute :open + it 'to write via method without =' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + attr_test.attributes.names.each do |attr| + attr_test.send(attr, attr.to_s.upcase) 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 } - attributes attr_with_number__default: 12345 - attributes attr_with_string__default: "abcde" - attributes attr_with_boolean_default: true + attr_test.attributes.each do |name,value| + expect(value).to eq name.to_s.upcase end - }.to_not raise_error - attr_test = AttrTest.new - attr_test.attr_with_array___default.should eq [ 1, 2, 3 ] - attr_test.attr_with_array___default = :array - attr_test.attr_with_array___default.should eq :array - attr_test.attr_with_hash____default.should eq ( { a: 1, b: 2, c: 3 } ) - attr_test.attr_with_hash____default = :hash - attr_test.attr_with_hash____default.should eq :hash - attr_test.attr_with_number__default.should eq 12345 - attr_test.attr_with_number__default = :number - attr_test.attr_with_number__default.should eq :number - attr_test.attr_with_string__default.should eq "abcde" - attr_test.attr_with_string__default = :string - attr_test.attr_with_string__default.should eq :string - attr_test.attr_with_boolean_default.should eq true - attr_test.attr_with_boolean_default = :boolean - attr_test.attr_with_boolean_default.should eq :boolean - end + end - it 'can have a default proc' do - expect { - class AttrTest - attributes attr_with_proc_default: proc { Time.now } + it 'to read via method' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + attr_test.attributes.names.each do |attr| + attr_test.send(attr, attr.to_s.upcase) end - }.to_not raise_error - attr_test = AttrTest.new - attr_test.attr_with_proc_default.should be < Time.now + attr_test.attributes.each do |name,value| + expect(eval("attr_test.#{name}")).to eq value + end + end + end - it 'default proc runs in instance scope' do - expect { - class AttrTest - attributes attr_with_proc_default: proc { |this| this.my_method } - def my_method - "okay" + context 'can be defined' do + + it 'via "attribute"' do + attr_test = AttrTest.new + attr_test.attribute :open + expect(attr_test.open).to be_nil + attr_test.open = true + expect(attr_test.open).to be true + end + + it 'attribute list can be added to' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + attr_test.attributes :attr4, :attr5, :attr6 + expect(attr_test.attributes.count).to eq 6 + expect(attr_test.attributes.names).to eq [ :attr1, :attr2, :attr3, :attr4, :attr5, :attr6 ] + end + + it 'attribute list can be added to without duplication' do + attr_test = AttrTest.new + attr_test.attributes :attr1, :attr2, :attr3 + attr_test.attributes :attr2, :attr3, :attr4 + expect(attr_test.attributes.count).to eq 4 + expect(attr_test.attributes.names).to eq [ :attr1, :attr2, :attr3, :attr4 ] + end + + it 'with a default value' do + attr_test = AttrTest.new + attr_test.attributes attr_with_array___default: [ 1, 2, 3 ] + attr_test.attributes attr_with_hash____default: { a: 1, b: 2, c: 3 } + attr_test.attributes attr_with_number__default: 12345 + attr_test.attributes attr_with_string__default: "abcde" + attr_test.attributes attr_with_boolean_default: true + expect(attr_test.attr_with_array___default).to eq [ 1, 2, 3 ] + expect(attr_test.attr_with_hash____default).to eq ( { a: 1, b: 2, c: 3 } ) + expect(attr_test.attr_with_number__default).to eq 12345 + expect(attr_test.attr_with_string__default).to eq "abcde" + expect(attr_test.attr_with_boolean_default).to eq true + end + + context 'wth a dynamic value' do + + context 'a proc' do + + it 'runs' do + attr_test = AttrTest.new + attr_test.attributes attr_with_proc_default: proc { Time.now } + expect(attr_test.attr_with_proc_default).to be < Time.now end - end - }.to_not raise_error - attr_test = AttrTest.new - attr_test.attr_with_proc_default.should eq "okay" - end - it 'can have a default lambda' do - expect { - class AttrTest - attributes attr_with_lambda_default: lambda { Time.now } - end - }.to_not raise_error - attr_test = AttrTest.new - attr_test.attr_with_lambda_default.should be < Time.now - end + it 'runs in instance scope' do + attr_test = AttrTest.new + attr_test.define_singleton_method(:my_method) { "okay" } + attr_test.attributes attr_with_proc_default: proc { |this| this.my_method } + expect(attr_test.attr_with_proc_default).to eq "okay" + end - it 'default lambda runs in instance scope' do - expect { - class AttrTest - attributes attr_with_lambda_default: lambda { |this| this.my_method } - def my_method - "okay" + it 'runs on each access via method' do + attr_test = AttrTest.new + attr_test.attributes time_proc: proc { Time.now } + old_time = attr_test.time_proc + expect(attr_test.time_proc).to be > old_time end + + it 'is returned on direct access to attribute' do + attr_test = AttrTest.new + attr_test.attributes time_proc: proc { Time.now } + expect(attr_test.attributes[:time_proc]).to respond_to :call + 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 'a lambda' do + + it 'runs' do + attr_test = AttrTest.new + attr_test.attributes attr_with_lambda_default: lambda { Time.now } + expect(attr_test.attr_with_lambda_default).to be < Time.now + end - context 'have convenient instance accessors' do + it 'runs in instance scope' do + attr_test = AttrTest.new + attr_test.define_singleton_method(:my_method) { "okay" } + attr_test.attributes attr_with_lambda_default: lambda { |this| this.my_method } + expect(attr_test.attr_with_lambda_default).to eq "okay" + end - before :all do - expect { - class BooleanAttrTest - include Woyo::Attributes - attribute open: true - attribute light: false - end - }.to_not raise_error - end + it 'runs on each access via method' do + attr_test = AttrTest.new + attr_test.attributes time_lambda: lambda { Time.now } + old_time = attr_test.time_lambda + expect(attr_test.time_lambda).to be > old_time + end - it '#attr?' do - attr_test = BooleanAttrTest.new - attr_test.open.should eq true - attr_test.open?.should eq true - end + it 'is returned on direct access to attribute' do + attr_test = AttrTest.new + attr_test.attributes time_lambda: lambda { Time.now } + expect(attr_test.attributes[:time_lambda]).to respond_to :call + 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 + + context 'a block' do - 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 'runs' do + attr_test = AttrTest.new + attr_test.attribute( :attr_with_block_default ) { Time.now } + expect(attr_test.attr_with_block_default).to be < Time.now + 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 + it 'runs in instance scope' do + attr_test = AttrTest.new + attr_test.define_singleton_method(:my_method) { "okay" } + attr_test.attribute( :attr_with_block_default ) { |this| this.my_method } + expect(attr_test.attr_with_block_default).to eq "okay" + end + + it 'runs on each access via method' do + attr_test = AttrTest.new + attr_test.attribute( :time_block ) { Time.now } + old_time = attr_test.time_block + expect(attr_test.time_block).to be > old_time + end + + it 'is returned on direct access to attribute' do + attr_test = AttrTest.new + attr_test.attribute( :time_block ) { Time.now } + expect(attr_test.attributes[:time_block]).to respond_to :call + end + end + end - context 'have class accessor ::is' do + end - # 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 + context 'that are boolean have convenient instance accessors' do - 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 + let(:bat) { class BooleanAttrTest; include Woyo::Attributes; end.new } - 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 + before :each do + bat.attribute open: 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 + it '#attr?' do + expect(bat.open).to eq true + expect(bat.open?).to eq true + end + it '#attr!' do + bat.open = false + expect(bat.open).to eq false + expect(bat.open!).to eq true + expect(bat.open).to eq true end + it '#is? :attr' do + expect(bat.is?(:open)).to eq true + bat.open = false + expect(bat.is?(:open)).to eq false + end + + it '#is :attr' do + bat.open = false + expect(bat.open).to eq false + bat.is(:open) + expect(bat.open).to eq true + end + end context 'can be re-defined' do + let(:ard) { AttrTest.new } + 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 + ard.attribute :attr + ard.attribute :attr + expect(ard.attributes.count).to eq 1 + expect(ard.attributes.names).to eq [:attr] + expect(ard.attr).to eq 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' + ard.attribute :attr + ard.attribute :attr => 'default' + expect(ard.attributes.count).to eq 1 + expect(ard.attributes.names).to eq [:attr] + expect(ard.attr).to eq 'default' 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' + ard.attribute :attr => 'old_default' + ard.attribute :attr => 'new_default' + expect(ard.attributes.count).to eq 1 + expect(ard.attributes.names).to eq [:attr] + expect(ard.attr).to eq 'new_default' 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 + let(:gat) { AttrTest.new } - 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 ] + before :each do + gat.group :stooges, :larry, :curly, :moe end - it 'have convenience accessor :names for :keys' do - @at.stooges.names.should eq [ :larry, :curly, :moe ] + it 'can be accessed by named instance methods' do + expect(gat.stooges).to be_instance_of Woyo::Attributes::Group 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 ] + it 'names and nil values can be retrieved' do + expect(gat.stooges).to be_instance_of Woyo::Attributes::Group + expect(gat.stooges.count).to eq 3 + expect(gat.stooges.names).to eq [ :larry, :curly, :moe ] + expect(gat.stooges.values).to 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 ] + it 'names and default values can be retrieved' do + gat.group :numbers, one: 1, two: 2, three: 3 + expect(gat.numbers).to be_instance_of Woyo::Attributes::Group + expect(gat.numbers.count).to eq 3 + expect(gat.numbers.names).to eq [ :one, :two, :three ] + expect(gat.numbers.values).to 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' + expect(gat.stooges[:curly]).to eq nil + gat.stooges[:curly] = 'bald' + expect(gat.stooges[:curly]).to 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' + expect(gat.attributes.keys).to eq [ :larry, :curly, :moe ] + gat.stooges[:larry] = 'knucklehead' + expect(gat.larry).to eq 'knucklehead' end it 'attributes are members' do - @at.ferarri = 'fast' - @at.ferarri.should eq 'fast' - @at.cars[:ferarri].should eq 'fast' + gat.moe = 'smart' + expect(gat.stooges[:moe]).to eq 'smart' end + it '#groups returns hash with names and groups' do + gat.group :numbers, one: 1, two: 2, three: proc { 3 } + expect(gat.groups).to eq( { stooges: gat.stooges, numbers: gat.numbers } ) + end + end - context 'boolean groups' do + context 'exclusions' do - before :all do - class ExGroupTest - include Woyo::Attributes - group! :temp, :hot, :warm, :cool, :cold - group! :light, :dark, :dim, :bright - end - end + let(:xat) { AttrTest.new } - 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 ] + before :each do + xat.exclusion :temp, :warm, :cool, :cold end - it 'accessor returns BooleanGroup instance' do - egt = ExGroupTest.new - egt.temp.should be_instance_of Woyo::Attributes::BooleanGroup + it 'can be accessed by named instance methods' do + expect(xat.temp).to be_instance_of Woyo::Attributes::Exclusion 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 + expect(xat.temp[:warm]).to eq true + expect(xat.temp[:cool]).to eq false + expect(xat.temp[:cold]).to eq false end + it '#value returns true member' do + expect(xat.temp.value).to eq :warm + xat.temp[:cold] = true + expect(xat.temp.value).to eq :cold + 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 + xat.temp[:cold] = true + expect(xat.cold).to be true + expect(xat.cool).to be false + expect(xat.warm).to 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 + xat.cool = true + expect(xat.temp[:cold]).to be false + expect(xat.temp[:cool]).to be true + expect(xat.temp[:warm]).to be false end + it '#exclusions returns hash with names and exlcusions' do + xat.exclusion :light, :dark, :dim, :bright + expect(xat.exclusions).to eq( { temp: xat.temp, light: xat.light } ) + end + end - context 'assigned a Hash as a value' do + context 'with Hash value' do - before :all do - class AttrHashTest - include Woyo::Attributes - attributes :reaction, :hot, :cold - end - @aht = AttrHashTest.new + let(:hat) { AttrTest.new } + + before :each do + hat.attributes :reaction, :hot, :cold end - it 'accepts the hash as a value' do - expect { @aht.reaction hot: 'Sweat', cold: 'Shiver' }.to_not raise_error + it 'accept a hash as value' do + expect { hat.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' + it 'return the value of the first key that evaluates as a true attribute' do + hat.reaction hot: 'Sweat', cold: 'Shiver' + hat.cold = true + expect(hat.reaction).to eq 'Shiver' + hat.hot = true + expect(hat.reaction).to 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 + it 'otherwise return the hash' do + hat.reaction hot: 'Sweat', cold: 'Shiver' + hat.cold = false + hat.hot = false + expect(hat.reaction).to eq ( { :hot => 'Sweat', :cold => 'Shiver' } ) end end end