require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "Dynamoid::Fields" do before do @address = Address.new end it 'declares read attributes' do @address.city.should be_nil end it 'declares write attributes' do @address.city = 'Chicago' @address.city.should == 'Chicago' end it 'declares a query attribute' do @address.city?.should be_false @address.city = 'Chicago' @address.city?.should be_true end it 'automatically declares id' do lambda {@address.id}.should_not raise_error end it 'automatically declares and fills in created_at and updated_at' do @address.save @address = @address.reload @address.created_at.should_not be_nil @address.created_at.class.should == DateTime @address.updated_at.should_not be_nil @address.updated_at.class.should == DateTime end context 'with a saved address' do before do @address = Address.create(:deliverable => true) @original_id = @address.id end it 'should write an attribute correctly' do @address.write_attribute(:city, 'Chicago') end it 'should write an attribute with an alias' do @address[:city] = 'Chicago' end it 'should read a written attribute' do @address.write_attribute(:city, 'Chicago') @address.read_attribute(:city).should == 'Chicago' end it 'should read a written attribute with the alias' do @address.write_attribute(:city, 'Chicago') @address[:city].should == 'Chicago' end it 'should update all attributes' do @address.expects(:save).once.returns(true) @address.update_attributes(:city => 'Chicago') @address[:city].should == 'Chicago' @address.id.should == @original_id end it 'should update one attribute' do @address.expects(:save).once.returns(true) @address.update_attribute(:city, 'Chicago') @address[:city].should == 'Chicago' @address.id.should == @original_id end it 'should update only created_at when no params are passed' do @initial_updated_at = @address.updated_at @address.update_attributes([]) @address.updated_at.should_not == @initial_updated_at end it 'adds in dirty methods for attributes' do @address.city = 'Chicago' @address.save @address.city = 'San Francisco' @address.city_was.should == 'Chicago' end it 'returns all attributes' do Address.attributes.should == {:id=>{:type=>:string}, :created_at=>{:type=>:datetime}, :updated_at=>{:type=>:datetime}, :city=>{:type=>:string}, :options=>{:type=>:serialized}, :deliverable => {:type => :boolean}, :lock_version => {:type => :integer}} end end it "gives a warning when setting a single value larger than the maximum item size" do Dynamoid.logger.expects(:warn).with(regexp_matches(/city field has a length of 66000/)) Address.new city: ("Ten chars " * 6_600) end context '.remove_attribute' do subject { @address } before(:each) do Address.field :foobar Address.remove_field :foobar end it('should not be in the attributes hash') { Address.attributes.should_not have_key(:foobar) } it('removes the accessor') { should_not respond_to(:foobar) } it('removes the writer') { should_not respond_to(:foobar=) } it('removes the interrogative') { should_not respond_to(:foobar?) } end context 'default values for fields' do before do @clazz = Class.new do include Dynamoid::Document field :name, :string, :default => 'x' field :uid, :integer, :default => lambda { 42 } def self.name 'Document' end end @doc = @clazz.new end it 'returns default value' do @doc.name.should eq('x') @doc.uid.should eq(42) end it 'should save default value' do @doc.save! @doc.reload.name.should eq('x') @doc.uid.should eq(42) end end context 'single table inheritance' do it "has only base class fields on the base class" do Vehicle.attributes.keys.to_set.should == Set.new([:type, :description, :created_at, :updated_at, :id]) end it "has only the base and derived fields on a sub-class" do #Only NuclearSubmarines have torpedoes Car.attributes.should_not have_key(:torpedoes) end end end