mongomodel 0.4.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +30 -0
- data/Gemfile +1 -1
- data/README.md +7 -1
- data/Rakefile +0 -2
- data/gemfiles/mongo_mapper.gemfile +6 -7
- data/gemfiles/mongoid.gemfile +6 -7
- data/gemfiles/rails-3.1.gemfile +5 -6
- data/gemfiles/rails-3.2.gemfile +5 -6
- data/gemfiles/rails-4-observers.gemfile +6 -8
- data/gemfiles/rails-4-protected-attributes.gemfile +6 -8
- data/gemfiles/rails-4.gemfile +5 -7
- data/lib/mongomodel.rb +1 -0
- data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +6 -1
- data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +17 -0
- data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +1 -1
- data/lib/mongomodel/concerns/attributes.rb +5 -0
- data/lib/mongomodel/concerns/properties.rb +2 -2
- data/lib/mongomodel/concerns/serialization.rb +15 -6
- data/lib/mongomodel/embedded_document.rb +1 -0
- data/lib/mongomodel/railtie.rb +7 -5
- data/lib/mongomodel/support/scope.rb +2 -9
- data/lib/mongomodel/support/scope/array_methods.rb +21 -0
- data/lib/mongomodel/support/types/date_time.rb +18 -5
- data/lib/mongomodel/version.rb +1 -1
- data/spec/mongomodel/attributes/store_spec.rb +9 -5
- data/spec/mongomodel/concerns/activemodel_spec.rb +13 -13
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +65 -65
- data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +128 -121
- data/spec/mongomodel/concerns/attributes_spec.rb +11 -2
- data/spec/mongomodel/concerns/logging_spec.rb +1 -1
- data/spec/mongomodel/concerns/observing_spec.rb +1 -1
- data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +26 -10
- data/spec/mongomodel/concerns/timestamps_spec.rb +5 -5
- data/spec/mongomodel/document/indexes_spec.rb +1 -1
- data/spec/mongomodel/document/validations/uniqueness_spec.rb +1 -1
- data/spec/mongomodel/document/validations_spec.rb +1 -1
- data/spec/mongomodel/document_spec.rb +1 -1
- data/spec/mongomodel/mongomodel_spec.rb +1 -1
- data/spec/mongomodel/support/mongo_order_spec.rb +2 -2
- data/spec/mongomodel/support/paginator_spec.rb +3 -3
- data/spec/mongomodel/support/property_spec.rb +12 -6
- data/spec/mongomodel/support/scope_spec.rb +24 -14
- data/spec/support/helpers/document_finder_stubs.rb +5 -5
- data/spec/support/matchers/find_with.rb +2 -2
- metadata +6 -4
- data/Appraisals +0 -46
    
        data/lib/mongomodel/version.rb
    CHANGED
    
    
| @@ -27,7 +27,7 @@ module MongoModel | |
| 27 27 | 
             
                  properties[:as]      = MongoModel::Properties::Property.new(:as, String, :as => '_custom_as')
         | 
| 28 28 | 
             
                  properties
         | 
| 29 29 | 
             
                end
         | 
| 30 | 
            -
                let(:instance) {  | 
| 30 | 
            +
                let(:instance) { double('instance', :properties => properties) }
         | 
| 31 31 |  | 
| 32 32 | 
             
                subject { Attributes::Store.new(instance) }
         | 
| 33 33 |  | 
| @@ -143,9 +143,9 @@ module MongoModel | |
| 143 143 | 
             
                      },
         | 
| 144 144 | 
             
                    :datetime =>
         | 
| 145 145 | 
             
                      {
         | 
| 146 | 
            -
                        Time.local(2008, 5, 14, 1, 2, 3, 123456) => Time.local(2008, 5, 14, 1, 2, 3,  | 
| 146 | 
            +
                        Time.local(2008, 5, 14, 1, 2, 3, 123456) => Time.local(2008, 5, 14, 1, 2, 3, 123000).to_datetime,
         | 
| 147 147 | 
             
                        Date.civil(2009, 11, 15)                 => DateTime.civil(2009, 11, 15, 0, 0, 0, 0),
         | 
| 148 | 
            -
                        "Sat Jan 01 20:15:01.123456 UTC 2000"    => DateTime.civil(2000, 1, 1, 20, 15,  | 
| 148 | 
            +
                        "Sat Jan 01 20:15:01.123456 UTC 2000"    => DateTime.civil(2000, 1, 1, 20, 15, Rational(1123, 1000), 0),
         | 
| 149 149 | 
             
                        "2009/3/4"                               => DateTime.civil(2009, 3, 4, 0, 0, 0, 0),
         | 
| 150 150 | 
             
                        "09:34"                                  => lambda { |t| t.hour == 9 && t.min == 34 },
         | 
| 151 151 | 
             
                        "5:21pm"                                 => lambda { |t| t.hour == 17 && t.min == 21 },
         | 
| @@ -291,13 +291,14 @@ module MongoModel | |
| 291 291 | 
             
                    subject[:array] = [ 123, 'abc', 45.67, true, :bar, CustomClass.new('custom in array') ]
         | 
| 292 292 | 
             
                    subject[:date] = Date.civil(2009, 11, 15)
         | 
| 293 293 | 
             
                    subject[:time] = Time.local(2008, 5, 14, 1, 2, 3, 4, 0.5)
         | 
| 294 | 
            +
                    subject[:datetime] = DateTime.civil(2000, 1, 1, 20, 15, Rational(1123456, 1000000), 0)
         | 
| 294 295 | 
             
                    subject[:rational] = Rational(2, 3)
         | 
| 295 296 | 
             
                    subject[:openstruct] = OpenStruct.new(:abc => 123)
         | 
| 296 297 | 
             
                    subject[:custom] = CustomClass.new('custom')
         | 
| 297 298 | 
             
                    subject[:as] = "As property"
         | 
| 298 299 | 
             
                    subject[:non_property] = "Hello World"
         | 
| 299 300 | 
             
                    subject[:custom_non_property] = CustomClass.new('custom non property')
         | 
| 300 | 
            -
             | 
| 301 | 
            +
                    
         | 
| 301 302 | 
             
                    subject.to_mongo.should include({
         | 
| 302 303 | 
             
                      'string' => 'string',
         | 
| 303 304 | 
             
                      'integer' => 42,
         | 
| @@ -307,7 +308,8 @@ module MongoModel | |
| 307 308 | 
             
                      'hash' => { :foo => 'bar', :custom => { :name => 'custom in hash' } },
         | 
| 308 309 | 
             
                      'array' => [ 123, 'abc', 45.67, true, :bar, { :name => 'custom in array' } ],
         | 
| 309 310 | 
             
                      'date' => "2009/11/15",
         | 
| 310 | 
            -
                      'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0),
         | 
| 311 | 
            +
                      'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0).utc,
         | 
| 312 | 
            +
                      'datetime' => Time.utc(2000, 1, 1, 20, 15, 1, 123000),
         | 
| 311 313 | 
             
                      'rational' => "2/3",
         | 
| 312 314 | 
             
                      'openstruct' => { :abc => 123 },
         | 
| 313 315 | 
             
                      'custom' => { :name => 'custom' },
         | 
| @@ -328,6 +330,7 @@ module MongoModel | |
| 328 330 | 
             
                      'array' => [ 123, 'abc', 45.67, true, :bar ],
         | 
| 329 331 | 
             
                      'date' => Time.utc(2009, 11, 15),
         | 
| 330 332 | 
             
                      'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0.5),
         | 
| 333 | 
            +
                      'datetime' => Time.utc(2000, 1, 1, 20, 15, 1, 123000),
         | 
| 331 334 | 
             
                      'rational' => "2/3",
         | 
| 332 335 | 
             
                      'openstruct' => { "foo" => "bar" },
         | 
| 333 336 | 
             
                      'custom' => { :name => 'custom' },
         | 
| @@ -344,6 +347,7 @@ module MongoModel | |
| 344 347 | 
             
                    subject[:array].should == [ 123, 'abc', 45.67, true, :bar ]
         | 
| 345 348 | 
             
                    subject[:date].should == Date.civil(2009, 11, 15)
         | 
| 346 349 | 
             
                    subject[:time].should == Time.local(2008, 5, 14, 1, 2, 3, 4, 0)
         | 
| 350 | 
            +
                    subject[:datetime].should == DateTime.civil(2000, 1, 1, 20, 15, Rational(1123, 1000), 0)
         | 
| 347 351 | 
             
                    subject[:rational].should == Rational(2, 3)
         | 
| 348 352 | 
             
                    subject[:openstruct].should == OpenStruct.new(:foo => "bar")
         | 
| 349 353 | 
             
                    subject[:custom].should == CustomClass.new('custom')
         | 
| @@ -1,22 +1,22 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module MongoModel
         | 
| 4 | 
            -
               | 
| 5 | 
            -
                 | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
                   | 
| 12 | 
            -
                     | 
| 4 | 
            +
              specs_for(Document, EmbeddedDocument) do
         | 
| 5 | 
            +
                shared_examples_for "ActiveModel" do
         | 
| 6 | 
            +
                  require 'test/unit/assertions'
         | 
| 7 | 
            +
                  include Test::Unit::Assertions
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  include ActiveModel::Lint::Tests
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
         | 
| 12 | 
            +
                    example m.gsub('_',' ') do
         | 
| 13 | 
            +
                      send m
         | 
| 14 | 
            +
                    end
         | 
| 13 15 | 
             
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  let(:model) { subject }
         | 
| 14 18 | 
             
                end
         | 
| 15 19 |  | 
| 16 | 
            -
                let(:model) { subject }
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
              
         | 
| 19 | 
            -
              specs_for(Document, EmbeddedDocument) do
         | 
| 20 20 | 
             
                define_class(:TestModel, described_class)
         | 
| 21 21 | 
             
                subject { TestModel.new }
         | 
| 22 22 |  | 
| @@ -1,77 +1,77 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 | 
            -
            module MongoModel
         | 
| 4 | 
            -
               | 
| 5 | 
            -
                 | 
| 6 | 
            -
             | 
| 3 | 
            +
            module MongoModel  
         | 
| 4 | 
            +
              specs_for(Document, EmbeddedDocument) do
         | 
| 5 | 
            +
                shared_examples_for "assigning correct class to belongs_to association" do
         | 
| 6 | 
            +
                  define_class(:User, Document)
         | 
| 7 | 
            +
                  define_class(:SpecialUser, :User)
         | 
| 7 8 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                  
         | 
| 16 | 
            -
                  it "is settable" do
         | 
| 17 | 
            -
                    subject.user = user
         | 
| 18 | 
            -
                    subject.user.should == user
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                  
         | 
| 21 | 
            -
                  it "is not truthy" do
         | 
| 22 | 
            -
                    subject.user.should_not be_truthy
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
                  
         | 
| 25 | 
            -
                  describe "setting a subclass type" do
         | 
| 26 | 
            -
                    it "sets successfully" do
         | 
| 27 | 
            -
                      subject.user = special_user
         | 
| 28 | 
            -
                      subject.user.should == special_user
         | 
| 9 | 
            +
                  let(:user) { User.create! }
         | 
| 10 | 
            +
                  let(:special_user) { SpecialUser.create! }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  context "when uninitialized" do
         | 
| 13 | 
            +
                    it "is nil" do
         | 
| 14 | 
            +
                      subject.user.should be_nil
         | 
| 29 15 | 
             
                    end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 16 | 
            +
             | 
| 17 | 
            +
                    it "is settable" do
         | 
| 18 | 
            +
                      subject.user = user
         | 
| 19 | 
            +
                      subject.user.should == user
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    it "is not truthy" do
         | 
| 23 | 
            +
                      subject.user.should_not be_truthy
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    describe "setting a subclass type" do
         | 
| 27 | 
            +
                      it "sets successfully" do
         | 
| 28 | 
            +
                        subject.user = special_user
         | 
| 29 | 
            +
                        subject.user.should == special_user
         | 
| 30 | 
            +
                      end
         | 
| 39 31 | 
             
                    end
         | 
| 40 | 
            -
                    
         | 
| 41 | 
            -
                    let(:parent) { ArticleParent.create!(:article => subject) }
         | 
| 42 | 
            -
                    let(:reloaded) { ArticleParent.find(parent.id).article }
         | 
| 43 | 
            -
                  else
         | 
| 44 | 
            -
                    before(:each) { subject.save! }
         | 
| 45 | 
            -
                    let(:reloaded) { Article.find(subject.id) }
         | 
| 46 | 
            -
                  end
         | 
| 47 | 
            -
                  
         | 
| 48 | 
            -
                  it "accesses the user through the association" do
         | 
| 49 | 
            -
                    reloaded.user.should == user
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                  
         | 
| 52 | 
            -
                  it "is truthy" do
         | 
| 53 | 
            -
                    subject.user.should be_truthy
         | 
| 54 | 
            -
                  end
         | 
| 55 | 
            -
                  
         | 
| 56 | 
            -
                  it "allows the user to be reloaded" do
         | 
| 57 | 
            -
                    user = reloaded.user.target
         | 
| 58 | 
            -
                    
         | 
| 59 | 
            -
                    user.should equal(reloaded.user.target)
         | 
| 60 | 
            -
                    user.should equal(reloaded.user.target)
         | 
| 61 | 
            -
                    user.should_not equal(reloaded.user(true).target)
         | 
| 62 32 | 
             
                  end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                   | 
| 65 | 
            -
                    subject { Article.new(:user =>  | 
| 66 | 
            -
             | 
| 67 | 
            -
                     | 
| 68 | 
            -
                       | 
| 33 | 
            +
             | 
| 34 | 
            +
                  context "when loading from database" do
         | 
| 35 | 
            +
                    subject { Article.new(:user => user) }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    if specing?(EmbeddedDocument)
         | 
| 38 | 
            +
                      define_class(:ArticleParent, Document) do
         | 
| 39 | 
            +
                        property :article, Article
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      let(:parent) { ArticleParent.create!(:article => subject) }
         | 
| 43 | 
            +
                      let(:reloaded) { ArticleParent.find(parent.id).article }
         | 
| 44 | 
            +
                    else
         | 
| 45 | 
            +
                      before(:each) { subject.save! }
         | 
| 46 | 
            +
                      let(:reloaded) { Article.find(subject.id) }
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    it "accesses the user through the association" do
         | 
| 50 | 
            +
                      reloaded.user.should == user
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    it "is truthy" do
         | 
| 54 | 
            +
                      subject.user.should be_truthy
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    it "allows the user to be reloaded" do
         | 
| 58 | 
            +
                      user = reloaded.user.target
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      user.should equal(reloaded.user.target)
         | 
| 61 | 
            +
                      user.should equal(reloaded.user.target)
         | 
| 62 | 
            +
                      user.should_not equal(reloaded.user(true).target)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    describe "setting a subclass type" do
         | 
| 66 | 
            +
                      subject { Article.new(:user => special_user) }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      it "loads successfully" do
         | 
| 69 | 
            +
                        reloaded.user.should == special_user
         | 
| 70 | 
            +
                      end
         | 
| 69 71 | 
             
                    end
         | 
| 70 72 | 
             
                  end
         | 
| 71 73 | 
             
                end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
              
         | 
| 74 | 
            -
              specs_for(Document, EmbeddedDocument) do
         | 
| 74 | 
            +
                
         | 
| 75 75 | 
             
                describe "belongs_to association" do
         | 
| 76 76 | 
             
                  define_class(:Article, described_class) do
         | 
| 77 77 | 
             
                    belongs_to :user
         | 
| @@ -13,130 +13,130 @@ module MongoModel | |
| 13 13 | 
             
                end
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            -
               | 
| 17 | 
            -
                 | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
                   | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                   | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
                   | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
                   | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
                   | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                   | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
                   | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
                   | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
                   | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
                   | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
                   | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                   | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
                   | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
                   | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
                   | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
                   | 
| 124 | 
            -
                     | 
| 125 | 
            -
                       | 
| 16 | 
            +
              specs_for(Document, EmbeddedDocument) do
         | 
| 17 | 
            +
                shared_examples_for "accessing and manipulating a has_many :by => :ids association" do
         | 
| 18 | 
            +
                  it "accesses chapters" do
         | 
| 19 | 
            +
                    subject.chapters.should == [chapter1, chapter2]
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  it "accesses chapter ids through association" do
         | 
| 23 | 
            +
                    subject.chapters.ids.should == [chapter1.id, chapter2.id]
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  it "has chapter ids" do
         | 
| 27 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id]
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  it "adds chapters with <<" do
         | 
| 31 | 
            +
                    subject.chapters << chapter3
         | 
| 32 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter3]
         | 
| 33 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  it "adds/change chapters with []=" do
         | 
| 37 | 
            +
                    subject.chapters[2] = chapter3
         | 
| 38 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter3]
         | 
| 39 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  it "adds chapters with concat" do
         | 
| 43 | 
            +
                    subject.chapters.concat([chapter3])
         | 
| 44 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter3]
         | 
| 45 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  it "inserts chapters" do
         | 
| 49 | 
            +
                    subject.chapters.insert(1, chapter3)
         | 
| 50 | 
            +
                    subject.chapters.should == [chapter1, chapter3, chapter2]
         | 
| 51 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter3.id, chapter2.id]
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  it "replaces chapters" do
         | 
| 55 | 
            +
                    subject.chapters.replace([chapter2, chapter3])
         | 
| 56 | 
            +
                    subject.chapters.should == [chapter2, chapter3]
         | 
| 57 | 
            +
                    subject.chapter_ids.should == [chapter2.id, chapter3.id]
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  it "adds chapters with push" do
         | 
| 61 | 
            +
                    subject.chapters.push(chapter3)
         | 
| 62 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter3]
         | 
| 63 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  it "adds chapters with unshift" do
         | 
| 67 | 
            +
                    subject.chapters.unshift(chapter3)
         | 
| 68 | 
            +
                    subject.chapters.should == [chapter3, chapter1, chapter2]
         | 
| 69 | 
            +
                    subject.chapter_ids.should == [chapter3.id, chapter1.id, chapter2.id]
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  it "clears chapters" do
         | 
| 73 | 
            +
                    subject.chapters.clear
         | 
| 74 | 
            +
                    subject.chapters.should be_empty
         | 
| 75 | 
            +
                    subject.chapter_ids.should be_empty
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  it "removes chapters with delete" do
         | 
| 79 | 
            +
                    subject.chapters.delete(chapter1)
         | 
| 80 | 
            +
                    subject.chapters.should == [chapter2]
         | 
| 81 | 
            +
                    subject.chapter_ids.should == [chapter2.id]
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  it "removes chapters with delete_at" do
         | 
| 85 | 
            +
                    subject.chapters.delete_at(0)
         | 
| 86 | 
            +
                    subject.chapters.should == [chapter2]
         | 
| 87 | 
            +
                    subject.chapter_ids.should == [chapter2.id]
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  it "removes chapters with delete_if" do
         | 
| 91 | 
            +
                    subject.chapters.delete_if { |c| c.id == chapter1.id }
         | 
| 92 | 
            +
                    subject.chapters.should == [chapter2]
         | 
| 93 | 
            +
                    subject.chapter_ids.should == [chapter2.id]
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  it "builds a chapter" do
         | 
| 97 | 
            +
                    chapter4 = subject.chapters.build(:id => '4')
         | 
| 98 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter4]
         | 
| 99 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    chapter4.should be_a_new_record
         | 
| 102 | 
            +
                    chapter4.id.should == '4'
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  it "creates a chapter" do
         | 
| 106 | 
            +
                    chapter4 = subject.chapters.create(:id => '4')
         | 
| 107 | 
            +
                    subject.chapters.should == [chapter1, chapter2, chapter4]
         | 
| 108 | 
            +
                    subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                    chapter4.should_not be_a_new_record
         | 
| 111 | 
            +
                    chapter4.id.should == '4'
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  it "finds chapters" do
         | 
| 115 | 
            +
                    # Create bogus chapters
         | 
| 116 | 
            +
                    Chapter.create!(:id => '999')
         | 
| 117 | 
            +
                    Chapter.create!(:id => '998')
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                    result = subject.chapters.order(:id.desc)
         | 
| 120 | 
            +
                    result.should == [chapter2, chapter1]
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  describe "adding a non-chapter" do
         | 
| 124 | 
            +
                    def self.should_raise(message, &block)
         | 
| 125 | 
            +
                      it "raises an AsssociationTypeMismatch error when #{message}" do
         | 
| 126 | 
            +
                        lambda { instance_eval(&block) }.should raise_error(AssociationTypeMismatch, "expected instance of Chapter but got NonChapter")
         | 
| 127 | 
            +
                      end
         | 
| 126 128 | 
             
                    end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
         | 
| 131 | 
            +
                    should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
         | 
| 132 | 
            +
                    should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
         | 
| 133 | 
            +
                    should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
         | 
| 134 | 
            +
                    should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
         | 
| 135 | 
            +
                    should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
         | 
| 136 | 
            +
                    should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
         | 
| 127 137 | 
             
                  end
         | 
| 128 | 
            -
                  
         | 
| 129 | 
            -
                  should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
         | 
| 130 | 
            -
                  should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
         | 
| 131 | 
            -
                  should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
         | 
| 132 | 
            -
                  should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
         | 
| 133 | 
            -
                  should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
         | 
| 134 | 
            -
                  should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
         | 
| 135 | 
            -
                  should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
         | 
| 136 138 | 
             
                end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
              
         | 
| 139 | 
            -
              specs_for(Document, EmbeddedDocument) do
         | 
| 139 | 
            +
                
         | 
| 140 140 | 
             
                describe "has_many :by => :ids association" do
         | 
| 141 141 | 
             
                  define_class(:Chapter, Document)
         | 
| 142 142 | 
             
                  define_class(:IllustratedChapter, :Chapter)
         | 
| @@ -186,6 +186,13 @@ module MongoModel | |
| 186 186 | 
             
                    end
         | 
| 187 187 |  | 
| 188 188 | 
             
                    it_should_behave_like "accessing and manipulating a has_many :by => :ids association"
         | 
| 189 | 
            +
                    
         | 
| 190 | 
            +
                    context "when child objects are destroyed" do
         | 
| 191 | 
            +
                      it "does not load the deleted child objects" do
         | 
| 192 | 
            +
                        chapter1.destroy
         | 
| 193 | 
            +
                        subject.chapters.should === [chapter2]
         | 
| 194 | 
            +
                      end
         | 
| 195 | 
            +
                    end
         | 
| 189 196 | 
             
                  end
         | 
| 190 197 |  | 
| 191 198 | 
             
                  describe "with :dependent => :destroy option" do
         |