require 'spec_helper' require 'support/models' describe "Document" do before do @document = Doc do key :first_name, String key :last_name, String key :age, Integer key :date, Date end end context "array key" do before do @document.key :tags, Array end it "should give correct default" do doc = @document.new doc.tags.should == [] end it "should work with assignment" do doc = @document.new doc.tags = %w(foo bar) doc.tags.should == %w(foo bar) end it "should work with assignment after saving" do doc = @document.new doc.tags = %w(foo bar) doc.save doc.tags.should == %w(foo bar) doc.reload.tags.should == %w(foo bar) end it "should work with assignment then <<" do doc = @document.new doc.tags = [] doc.tags << "foo" doc.tags.should == ["foo"] end it "should work with <<" do doc = @document.new doc.tags << "foo" doc.tags.should == ["foo"] end it "should work with << then save" do doc = @document.new doc.tags << "foo" doc.tags << "bar" doc.save doc.tags.should == %w(foo bar) doc.reload.tags.should == %w(foo bar) end end context "hash key" do before do @document.key :foo, Hash end it "should give correct default" do doc = @document.new doc.foo.should == {} end it "should work with []=" do doc = @document.new doc.foo["quux"] = "bar" doc.foo["quux"].should == "bar" doc.foo.should == { "quux" => "bar" } end it "should work with indifferent access" do doc = @document.new doc.foo = {:baz => 'bar'} doc.foo[:baz].should == 'bar' doc.foo['baz'].should == 'bar' end it "should work with indifferent access after save" do doc = @document.new doc.foo = {:baz => 'bar'} doc.save doc = doc.reload doc.foo[:baz].should == 'bar' doc.foo['baz'].should == 'bar' end end context "custom type key with default" do before do @document.key :window, WindowSize, :default => WindowSize.new(600, 480) end it "should default to default" do doc = @document.new doc.window.should == WindowSize.new(600, 480) end it "should save and load from mongo" do doc = @document.new doc.save doc = doc.reload doc.window.should == WindowSize.new(600, 480) end end context "key with proc default value" do before do @document.key :proc_default, String, :default => lambda { return 'string' } end it "should detect and run proc default" do doc = @document.new doc.proc_default.should == 'string' end it "should save and load from mongo" do doc = @document.create doc = doc.reload doc.proc_default.should == 'string' end end context "symbol key" do before do @document.key :foo, Symbol, :default => lambda { 123 } end it "should return default value" do doc = @document.new doc.foo.should == :'123' end it "should return symbol value" do doc = @document.create :foo => 'qwerty' doc.foo.should == :qwerty doc.set :foo => 'poiuyt' doc.reload doc.foo.should == :poiuyt doc.foo = 'asdf' doc.foo.should == :asdf end it "should return typecasted value" do doc = @document.new (doc.foo = 'qwerty').should == 'qwerty' end end it "should have instance method for collection" do @document.new.collection.name.should == @document.collection.name end it "should have instance method for database" do @document.new.database.should == @document.database end context "#destroyed?" do before do @doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27') end it "should be true if deleted" do @doc1.delete @doc1.should be_destroyed end it "should be true if destroyed" do @doc1.destroy @doc1.should be_destroyed end it "should be false if not deleted or destroyed" do @doc1.should_not be_destroyed end end context "#persisted?" do before do @doc = @document.new(:first_name => 'John', :last_name => 'Nunemaker', :age => '27') end it "should be false if new" do @doc.should_not be_persisted end it "should be false if destroyed" do @doc.save @doc.destroy @doc.should be_destroyed @doc.should_not be_persisted end it "should be true if not new or destroyed" do @doc.save @doc.should be_persisted end end context "#reload" do before do @foo_class = Doc do key :name end @bar_class = EDoc do key :name end @document.many :foos, :class => @foo_class @document.many :bars, :class => @bar_class @document.belongs_to :foo, :class => @foo_class @document.one :bar, :class => @bar_class @instance = @document.create({ :age => 39, :foos => [@foo_class.new(:name => '1')], :bars => [@bar_class.new(:name => '1')], :foo => @foo_class.new(:name => '2'), :bar => @bar_class.new(:name => '2') }) end it "should reload keys from the database" do @instance.age = 37 @instance.age.should == 37 @instance.reload @instance.age.should == 39 end it "should reset many associations" do @instance.foos.should_receive(:reset).at_least(1).times @instance.bars.should_receive(:reset).at_least(1).times @instance.reload end it "should reset belongs_to association" do @instance.foo = nil @instance.reload @instance.foo.should_not be_nil end it "should reset one association" do @instance.bar = nil @instance.reload @instance.bar.should_not be_nil end it "should reinstantiate embedded associations" do @instance.reload @instance.bars.first.name.should == '1' end it "should return self" do @instance.reload.object_id.should == @instance.object_id end it "should raise DocumentNotFound if not found" do @instance.destroy lambda { @instance.reload }.should raise_error(MongoMapper::DocumentNotFound) end it "should clear keys that were removed from the database" do @instance.unset(:age) @instance.reload.age.should be_nil end end context "database has keys not defined in model" do before do @id = BSON::ObjectId.new @document.collection.insert_one({ :_id => @id, :first_name => 'John', :last_name => 'Nunemaker', :age => 27, :favorite_color => 'red', :skills => ['ruby', 'rails', 'javascript', 'xhtml', 'css'] }) end it "should assign all keys from database" do doc = @document.find(@id) doc.first_name.should == 'John' doc.last_name.should == 'Nunemaker' doc.age.should == 27 doc.favorite_color.should == 'red' doc.skills.should == ['ruby', 'rails', 'javascript', 'xhtml', 'css'] end end it "should not walk ObjectSpace when creating a model" do ObjectSpace.should_receive(:each_object).never Doc() end end