spec/document_spec.rb in mongodoc-0.2.1 vs spec/document_spec.rb in mongodoc-0.2.2

- old
+ new

@@ -16,12 +16,12 @@ it "#id returns the _id" do @doc.id.should == @doc._id end - it "#to_param returns the _id" do - @doc.to_param.should == @doc._id + it "#to_param returns the string of the _id" do + @doc.to_param.should == @doc._id.to_s end context "#new_record?" do it "is true when the object does not have an _id" do @doc._id = nil @@ -217,293 +217,277 @@ key :data validates_presence_of :data end + let(:data) { 'data' } + let(:instance) { CreateTest.new(:data => data) } + before do - @value = 'value' - CreateTest.stub(:_create).and_return(true) + instance.stub(:save) + instance.stub(:save!) end context ".create" do - it "creates a new document" do - obj = CreateTest.new - CreateTest.should_receive(:new).and_return(obj) - CreateTest.create + it "creates a new document with the attributes" do + CreateTest.should_receive(:new).with(:data => data).and_return(instance) + CreateTest.create(:data => data) end - it "delegates to _create with safe => false" do - obj = CreateTest.new(:data => @value) - CreateTest.stub(:new).and_return(obj) - CreateTest.should_receive(:_create).with(obj, false).and_return(true) - CreateTest.create(:data => @value) - end + context "with the new document" do + before do + CreateTest.stub(:new).and_return(instance) + end - it "sets the passed attributes" do - CreateTest.create(:data => @value).data.should == @value - end + it "calls save on the instance with safe => false" do + instance.should_receive(:save).with(false) + CreateTest.create(:data => data) + end - it "returns a valid document" do - CreateTest.should === CreateTest.create(:data => @value) + it "returns the new object" do + CreateTest.create(:data => data).should == instance + end end - - it "validates" do - CreateTest.create.errors.should_not be_empty - end - - it "returns an invalid document" do - CreateTest.should === CreateTest.create - end end context ".create!" do - it "creates a new document" do - obj = CreateTest.new - CreateTest.should_receive(:new).and_return(obj) - CreateTest.create! rescue nil + it "creates a new document with the attributes" do + CreateTest.should_receive(:new).with(:data => data).and_return(instance) + CreateTest.create!(:data => data) end - it "delegates to _create with safe => true" do - obj = CreateTest.new(:data => @value) - CreateTest.stub(:new).and_return(obj) - CreateTest.should_receive(:_create).with(obj, true).and_return(true) - CreateTest.create!(:data => @value) - end + context "with the new document" do + before do + CreateTest.stub(:new).and_return(instance) + end - it "sets the passed attributes" do - CreateTest.create!(:data => @value).data.should == @value - end + it "calls save! on the instance" do + instance.should_receive(:save!) + CreateTest.create!(:data => data) + end - it "returns a valid document" do - CreateTest.should === CreateTest.create!(:data => @value) + it "returns the new object" do + CreateTest.create!(:data => data).should == instance + end end - - it "raises when invalid" do - expect do - CreateTest.create! - end.should raise_error(MongoDoc::DocumentInvalidError) - end end end - context "#_create" do - class CreateTest - include MongoDoc::Document - end - - before do - @collection = stub('collection') - @collection.stub(:insert) - @doc = CreateTest.new - CreateTest.stub(:collection).and_return(@collection) - end - - it "delegates to the collection insert with safe" do - safe = true - @collection.should_receive(:insert).with(@doc, hash_including(:safe => safe)) - CreateTest.send(:_create, @doc, safe) - end - - it "sets the _id of the document" do - id = 'id' - @collection.stub(:insert).and_return(id) - CreateTest.send(:_create, @doc, false) - @doc._id.should == id - end - - it "returns the _id" do - id = 'id' - @collection.stub(:insert).and_return(id) - CreateTest.send(:_create, @doc, false).should == id - end - end - context "updating attributes" do class UpdateAttributesRoot include MongoDoc::Document - has_one :update_attribute_child + has_one :update_attributes_child end class UpdateAttributesChild include MongoDoc::Document key :data end + let(:data) {'data'} + + let(:attrs) {{:data => data}} + + let(:path_attrs) {{'update_attributes_child.data' => data}} + + let(:doc) do + doc = UpdateAttributesChild.new + doc._id = 'id' + doc.stub(:_naive_update_attributes) + doc + end + before do - @data = 'data' - @doc = UpdateAttributesChild.new - UpdateAttributesRoot.new.update_attribute_child = @doc - @attrs = {:data => @data} - @path_attrs = {'update_attribute_child.data' => @data} - @doc.stub(:_naive_update_attributes) + root = UpdateAttributesRoot.new + root.update_attributes_child = doc + root._id = 'id' end context "#update_attributes" do + it "delegates to save if the object is a new record" do + check = 'check' + doc.stub(:new_record?).and_return(true) + doc.should_receive(:save).and_return(check) + doc.update_attributes(attrs).should == check + end it "sets the attributes" do - @doc.update_attributes(@attrs) - @doc.data.should == @data + doc.update_attributes(attrs) + doc.data.should == data end it "normalizes the attributes to the parent" do - @doc.should_receive(:_path_to_root) - @doc.update_attributes(@attrs) + doc.should_receive(:_path_to_root) + doc.update_attributes(attrs) end it "validates" do - @doc.should_receive(:valid?) - @doc.update_attributes(@attrs) + doc.should_receive(:valid?) + doc.update_attributes(attrs) end it "returns false if the object is not valid" do - @doc.stub(:valid?).and_return(false) - @doc.update_attributes(@attrs).should be_false + doc.stub(:valid?).and_return(false) + doc.update_attributes(attrs).should be_false end context "if valid" do context "and strict" do it "delegates to _strict_update_attributes" do - strict_attrs = @attrs.merge(:__strict__ => true) - @doc.should_receive(:_strict_update_attributes).with(@path_attrs, false) - @doc.update_attributes(strict_attrs) + strict_attrs = attrs.merge(:__strict__ => true) + doc.should_receive(:_strict_update_attributes).with(path_attrs, false) + doc.update_attributes(strict_attrs) end end context "and naive" do it "delegates to _naive_update_attributes" do - @doc.should_receive(:_naive_update_attributes).with(@path_attrs, false) - @doc.update_attributes(@attrs) + doc.should_receive(:_naive_update_attributes).with(path_attrs, false) + doc.update_attributes(attrs) end end it "returns the result of _naive_update_attributes" do result = 'check' - @doc.stub(:_naive_update_attributes).and_return(result) - @doc.update_attributes(@attrs).should == result + doc.stub(:_naive_update_attributes).and_return(result) + doc.update_attributes(attrs).should == result end end end context "#update_attributes!" do + it "delegates to save! if the object is a new record" do + check = 'check' + doc.stub(:new_record?).and_return(true) + doc.should_receive(:save!).and_return(check) + doc.update_attributes!(attrs).should == check + end + it "sets the attributes" do - @doc.update_attributes!(@attrs) - @doc.data.should == @data + doc.update_attributes!(attrs) + doc.data.should == data end it "normalizes the attributes to the parent" do - @doc.should_receive(:_path_to_root) - @doc.update_attributes!(@attrs) + doc.should_receive(:_path_to_root) + doc.update_attributes!(attrs) end it "validates" do - @doc.should_receive(:valid?).and_return(true) - @doc.update_attributes!(@attrs) + doc.should_receive(:valid?).and_return(true) + doc.update_attributes!(attrs) end it "raises if not valid" do - @doc.stub(:valid?).and_return(false) + doc.stub(:valid?).and_return(false) expect do - @doc.update_attributes!(@attrs) + doc.update_attributes!(attrs) end.should raise_error(MongoDoc::DocumentInvalidError) end context "if valid" do context "and strict" do it "delegates to _strict_update_attributes with safe == true" do - strict_attrs = @attrs.merge(:__strict__ => true) - @doc.should_receive(:_strict_update_attributes).with(@path_attrs, true) - @doc.update_attributes!(strict_attrs) + strict_attrs = attrs.merge(:__strict__ => true) + doc.should_receive(:_strict_update_attributes).with(path_attrs, true) + doc.update_attributes!(strict_attrs) end end context "and naive" do it "delegates to _naive_update_attributes with safe == true" do - @doc.should_receive(:_naive_update_attributes).with(@path_attrs, true) - @doc.update_attributes!(@attrs) + doc.should_receive(:_naive_update_attributes).with(path_attrs, true) + doc.update_attributes!(attrs) end end it "returns the result of _naive_update_attributes" do result = 'check' - @doc.stub(:_naive_update_attributes).and_return(result) - @doc.update_attributes!(@attrs).should == result + doc.stub(:_naive_update_attributes).and_return(result) + doc.update_attributes!(attrs).should == result end end end end context "#_naive_update_attributes" do class NaiveUpdateAttributes include MongoDoc::Document end - before do - @id = 'id' - @attrs = {:data => 'data'} - @safe = false - @doc = NaiveUpdateAttributes.new - @doc.stub(:_id).and_return(@id) - @collection = stub('collection') - @collection.stub(:update) - @doc.stub(:_collection).and_return(@collection) + + let(:id) { 'id' } + + let(:attrs) { {:data => 'data'} } + + let(:safe) { false } + + let(:doc) do + doc = NaiveUpdateAttributes.new + doc.stub(:_id).and_return(id) + doc end - it "calls update on the collection without a root" do - @collection.should_receive(:update).with({'_id' => @id}, MongoDoc::Query.set_modifier(@attrs), {:safe => @safe}) - @doc.send(:_naive_update_attributes, @attrs, @safe) + it "without a root delegates to _update" do + doc.should_receive(:_update).with({}, attrs, safe) + doc.send(:_naive_update_attributes, attrs, safe) end it "with a root, calls _naive_update_attributes on the root" do root = NaiveUpdateAttributes.new - @doc.stub(:_root).and_return(root) - root.should_receive(:_naive_update_attributes).with(@attrs, @safe) - @doc.send(:_naive_update_attributes, @attrs, @safe) + doc.stub(:_root).and_return(root) + root.should_receive(:_naive_update_attributes).with(attrs, safe) + doc.send(:_naive_update_attributes, attrs, safe) end end context "#_strict_update_attributes" do class StrictUpdateAttributes include MongoDoc::Document end - before do - @id = 'id' - @attrs = {:data => 'data'} - @selector = {'selector' => 'selector'} - @safe = false - @doc = StrictUpdateAttributes.new - @doc.stub(:_id).and_return(@id) - @collection = stub('collection') - @collection.stub(:update) - @doc.stub(:_collection).and_return(@collection) + let(:id) { 'id' } + + let(:attrs) { {:data => 'data'} } + + let(:selector) { {:selector => 'selector'} } + + let(:safe) { false } + + let(:doc) do + doc = StrictUpdateAttributes.new + doc.stub(:_id).and_return(id) + doc end context "without a root" do - it "calls update on the collection" do - @collection.should_receive(:update).with({'_id' => @id}.merge(@selector), MongoDoc::Query.set_modifier(@attrs), :safe => @safe) - @doc.send(:_strict_update_attributes, @attrs, @safe, @selector) + it "without a root delegates to _update" do + doc.should_receive(:_update).with(selector, attrs, safe) + doc.send(:_strict_update_attributes, attrs, safe, selector) end end context "with a root" do + let(:root) { StrictUpdateAttributes.new } + before do - @root = StrictUpdateAttributes.new - @root.stub(:_collection).and_return(@collection) - @doc.stub(:_root).and_return(@root) - @doc.stub(:_selector_path_to_root).and_return({'path._id' => @id}) + doc.stub(:_root).and_return(root) end - it "calls _selector_path_to_root on our id" do - @doc.should_receive(:_selector_path_to_root).with('_id' => @id).and_return({'path._id' => @id}) - @doc.send(:_strict_update_attributes, @attrs, @safe) + it "calls _path_to_root on our id" do + root.stub(:_strict_update_attributes) + doc.should_receive(:_path_to_root).with(doc, '_id' => id) + doc.send(:_strict_update_attributes, attrs, safe) end it "calls _strict_update_attributes on the root with our selector" do - @root.should_receive(:_strict_update_attributes).with(@attrs, @safe, 'path._id' => @id) - @doc.send(:_strict_update_attributes, @attrs, @safe) + selector = {'path._id' => id} + doc.stub(:_path_to_root).with(doc, '_id' => id).and_return(selector) + root.should_receive(:_strict_update_attributes).with(attrs, safe, selector) + doc.send(:_strict_update_attributes, attrs, safe) end end end describe "bson" do @@ -620,16 +604,49 @@ MongoDoc::BSON.decode(doc.to_bson).should == doc end it "roundtrips the proxy" do doc = TestHasManyBsonDoc.new(:subdoc => SubHasManyBsonDoc.new(:attr => "value")) - MongoDoc::Proxy.should === MongoDoc::BSON.decode(doc.to_bson).subdoc + MongoDoc::Associations::CollectionProxy.should === MongoDoc::BSON.decode(doc.to_bson).subdoc end end end end + context "removing documents" do + class RemoveDocument + include MongoDoc::Document + end + + let(:doc) { RemoveDocument.new } + + context "#remove" do + it "when called on a embedded document with a _root raises UnsupportedOperation" do + doc._root = RemoveDocument.new + expect { doc.remove }.to raise_error(MongoDoc::UnsupportedOperation) + end + + it "delegates to remove document" do + doc.should_receive(:remove_document) + doc.remove + end + end + + context "#remove_document" do + it "when the document is the root, removes the document" do + doc.should_receive(:_remove) + doc.remove_document + end + + it "when the document is not the root, calls remove_document on the root" do + doc._root = root = RemoveDocument.new + root.should_receive(:remove_document) + doc.remove_document + end + end + end + context "misc class methods" do class ClassMethods include MongoDoc::Document end @@ -638,10 +655,10 @@ end it ".collection returns a wrapped MongoDoc::Collection" do db = stub('db') db.should_receive(:collection).with(ClassMethods.to_s.tableize.gsub('/', '.')) - MongoDoc.should_receive(:database).and_return(db) + MongoDoc::Connection.should_receive(:database).and_return(db) MongoDoc::Collection.should === ClassMethods.collection end end end