mongoid 7.1.5 → 7.1.9
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +1 -1
- data/Rakefile +33 -7
- data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
- data/lib/mongoid/attributes.rb +8 -1
- data/lib/mongoid/criteria/queryable/selector.rb +0 -4
- data/lib/mongoid/document.rb +3 -2
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/interceptable.rb +3 -1
- data/lib/mongoid/reloadable.rb +5 -0
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/validatable/presence.rb +3 -3
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
- data/spec/app/models/customer.rb +11 -0
- data/spec/app/models/customer_address.rb +12 -0
- data/spec/app/models/dictionary.rb +6 -0
- data/spec/app/models/person.rb +2 -0
- data/spec/app/models/series.rb +1 -0
- data/spec/app/models/wiki_page.rb +1 -0
- data/spec/integration/app_spec.rb +178 -88
- data/spec/integration/associations/embeds_many_spec.rb +24 -0
- data/spec/integration/associations/embeds_one_spec.rb +24 -0
- data/spec/integration/associations/has_many_spec.rb +42 -0
- data/spec/integration/associations/has_one_spec.rb +42 -0
- data/spec/integration/callbacks_models.rb +49 -0
- data/spec/integration/callbacks_spec.rb +216 -0
- data/spec/integration/document_spec.rb +21 -0
- data/spec/lite_spec_helper.rb +6 -6
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
- data/spec/mongoid/atomic/paths_spec.rb +41 -0
- data/spec/mongoid/attributes_spec.rb +241 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +36 -0
- data/spec/mongoid/document_query_spec.rb +51 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
- data/spec/mongoid/factory_spec.rb +2 -2
- data/spec/mongoid/persistable/savable_spec.rb +4 -4
- data/spec/mongoid/persistable/settable_spec.rb +30 -0
- data/spec/mongoid/persistable_spec.rb +2 -2
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +226 -0
- data/spec/shared/lib/mrss/constraints.rb +368 -0
- data/spec/shared/lib/mrss/docker_runner.rb +271 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +322 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/distro.sh +73 -0
- data/spec/shared/shlib/server.sh +317 -0
- data/spec/shared/shlib/set_env.sh +131 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/constraints.rb +0 -226
- data/spec/support/spec_config.rb +8 -0
- metadata +538 -493
- metadata.gz.sig +0 -0
- data/spec/support/child_process_helper.rb +0 -76
- data/spec/support/lite_constraints.rb +0 -22
| @@ -507,4 +507,54 @@ describe Mongoid::Association::Embedded::EmbeddedIn::Proxy do | |
| 507 507 | 
             
                  end
         | 
| 508 508 | 
             
                end
         | 
| 509 509 | 
             
              end
         | 
| 510 | 
            +
             | 
| 511 | 
            +
              context "when the same class is embedded multiple times" do
         | 
| 512 | 
            +
             | 
| 513 | 
            +
                let(:customer) do
         | 
| 514 | 
            +
                  Customer.new
         | 
| 515 | 
            +
                end
         | 
| 516 | 
            +
             | 
| 517 | 
            +
                context "assignment after saving" do
         | 
| 518 | 
            +
             | 
| 519 | 
            +
                  it "correctly sets the association for the embedded class" do
         | 
| 520 | 
            +
                    pending 'MONGOID-5039'
         | 
| 521 | 
            +
             | 
| 522 | 
            +
                    customer.home_address = CustomerAddress.new
         | 
| 523 | 
            +
                    customer.work_address = CustomerAddress.new
         | 
| 524 | 
            +
             | 
| 525 | 
            +
                    expect(customer.home_address._association.store_as).to eq("home_address")
         | 
| 526 | 
            +
                    expect(customer.work_address._association.store_as).to eq("work_address")
         | 
| 527 | 
            +
             | 
| 528 | 
            +
                    expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
         | 
| 529 | 
            +
                    expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
         | 
| 530 | 
            +
             | 
| 531 | 
            +
                    customer.save!
         | 
| 532 | 
            +
             | 
| 533 | 
            +
                    customer.home_address = CustomerAddress.new
         | 
| 534 | 
            +
                    customer.work_address = CustomerAddress.new
         | 
| 535 | 
            +
             | 
| 536 | 
            +
                    expect(customer.home_address._association.store_as).to eq("home_address")
         | 
| 537 | 
            +
                    expect(customer.work_address._association.store_as).to eq("work_address")
         | 
| 538 | 
            +
             | 
| 539 | 
            +
                    expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
         | 
| 540 | 
            +
                    expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
         | 
| 541 | 
            +
                  end
         | 
| 542 | 
            +
                end
         | 
| 543 | 
            +
             | 
| 544 | 
            +
                context "inverse assignment" do
         | 
| 545 | 
            +
             | 
| 546 | 
            +
                  it "correctly sets the association for the embedded class" do
         | 
| 547 | 
            +
                    pending 'MONGOID-5039'
         | 
| 548 | 
            +
             | 
| 549 | 
            +
                    customer.work_address = CustomerAddress.new
         | 
| 550 | 
            +
                    customer.work_address.addressable = customer
         | 
| 551 | 
            +
             | 
| 552 | 
            +
                    expect(customer.home_address._association.store_as).to eq("home_address")
         | 
| 553 | 
            +
                    expect(customer.work_address._association.store_as).to eq("work_address")
         | 
| 554 | 
            +
             | 
| 555 | 
            +
                    expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
         | 
| 556 | 
            +
                    expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
         | 
| 557 | 
            +
                  end
         | 
| 558 | 
            +
                end
         | 
| 559 | 
            +
              end
         | 
| 510 560 | 
             
            end
         | 
| @@ -268,5 +268,46 @@ describe Mongoid::Atomic::Paths do | |
| 268 268 | 
             
                    end
         | 
| 269 269 | 
             
                  end
         | 
| 270 270 | 
             
                end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                context "when the same class is embedded in multiple associations" do
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                  let(:customer) do
         | 
| 275 | 
            +
                    Customer.new
         | 
| 276 | 
            +
                  end
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                  context "assignment after saving" do
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    it "correctly sets the association for the embedded class" do
         | 
| 281 | 
            +
                      pending 'MONGOID-5039'
         | 
| 282 | 
            +
             | 
| 283 | 
            +
                      customer.home_address = CustomerAddress.new
         | 
| 284 | 
            +
                      customer.work_address = CustomerAddress.new
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                      expect(customer.home_address.atomic_path).to eq("home_address")
         | 
| 287 | 
            +
                      expect(customer.work_address.atomic_path).to eq("work_address")
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                      customer.save!
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                      customer.home_address = CustomerAddress.new
         | 
| 292 | 
            +
                      customer.work_address = CustomerAddress.new
         | 
| 293 | 
            +
             | 
| 294 | 
            +
                      expect(customer.home_address.atomic_path).to eq("home_address")
         | 
| 295 | 
            +
                      expect(customer.work_address.atomic_path).to eq("work_address")
         | 
| 296 | 
            +
                    end
         | 
| 297 | 
            +
                  end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                  context "inverse assignment" do
         | 
| 300 | 
            +
             | 
| 301 | 
            +
                    it "correctly returns the path for each embedded class" do
         | 
| 302 | 
            +
                      pending 'MONGOID-5039'
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                      customer.work_address = CustomerAddress.new
         | 
| 305 | 
            +
                      customer.work_address.addressable = customer
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                      expect(customer.home_address.atomic_path).to eq("home_address")
         | 
| 308 | 
            +
                      expect(customer.work_address.atomic_path).to eq("work_address")
         | 
| 309 | 
            +
                    end
         | 
| 310 | 
            +
                  end
         | 
| 311 | 
            +
                end
         | 
| 271 312 | 
             
              end
         | 
| 272 313 | 
             
            end
         | 
| @@ -245,6 +245,97 @@ describe Mongoid::Attributes do | |
| 245 245 | 
             
                    end
         | 
| 246 246 | 
             
                  end
         | 
| 247 247 |  | 
| 248 | 
            +
                  context "when the field was not explicitly defined" do
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                    context "when excluding with only and the field was not excluded" do
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                      let(:from_db) do
         | 
| 253 | 
            +
                        Person.only(:_id).first
         | 
| 254 | 
            +
                      end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                      it "raises an error" do
         | 
| 257 | 
            +
                        expect {
         | 
| 258 | 
            +
                          from_db[:undefined_field]
         | 
| 259 | 
            +
                        }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 260 | 
            +
                      end
         | 
| 261 | 
            +
                    end
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                    context "when excluding with without and the field was excluded" do
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                      let(:from_db) do
         | 
| 266 | 
            +
                        Person.without(:title).first
         | 
| 267 | 
            +
                      end
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                      it "raises an error" do
         | 
| 270 | 
            +
                        expect {
         | 
| 271 | 
            +
                          from_db[:title]
         | 
| 272 | 
            +
                        }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 273 | 
            +
                      end
         | 
| 274 | 
            +
                    end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                    context "when excluding with without and the field was not excluded" do
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                      let(:from_db) do
         | 
| 279 | 
            +
                        Person.without(:title).first
         | 
| 280 | 
            +
                      end
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                      it "returns nil" do
         | 
| 283 | 
            +
                        from_db[:undefined_field].should be nil
         | 
| 284 | 
            +
                      end
         | 
| 285 | 
            +
                    end
         | 
| 286 | 
            +
                  end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
                  context 'when projecting with #only' do
         | 
| 289 | 
            +
                    let!(:person) do
         | 
| 290 | 
            +
                      Person.create(title: 'sir', name: { first_name: 'Jose', language: { name: 'es' } })
         | 
| 291 | 
            +
                    end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                    context 'when projecting an embedded association' do
         | 
| 294 | 
            +
                      let(:from_db) do
         | 
| 295 | 
            +
                        Person.only(:name).first
         | 
| 296 | 
            +
                      end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                      context 'when retrieving a field of the association using the dot notation' do
         | 
| 299 | 
            +
             | 
| 300 | 
            +
                        it 'retrieves the field' do
         | 
| 301 | 
            +
                          pending 'MONGOID-5032, fixed in 7.3'
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                          expect(from_db['name.first_name']).to eq 'Jose'
         | 
| 304 | 
            +
                        end
         | 
| 305 | 
            +
                      end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                      context 'when retrieving a field of a nested association using the dot notation' do
         | 
| 308 | 
            +
                        it 'retrieves the field' do
         | 
| 309 | 
            +
                          pending 'MONGOID-5032, fixed in 7.3'
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                          expect(from_db['name.language.name']).to eq 'es'
         | 
| 312 | 
            +
                        end
         | 
| 313 | 
            +
                      end
         | 
| 314 | 
            +
                    end
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                    context 'when projecting a sub-association of an embedded association' do
         | 
| 317 | 
            +
                      let(:from_db) do
         | 
| 318 | 
            +
                        Person.only('name.language').first
         | 
| 319 | 
            +
                      end
         | 
| 320 | 
            +
             | 
| 321 | 
            +
                      context 'when retrieving a field under the projected sub-association' do
         | 
| 322 | 
            +
                        it 'retrieves the field' do
         | 
| 323 | 
            +
                          pending 'MONGOID-5032, fixed in 7.3'
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                          expect(from_db['name.language.name']).to eq 'es'
         | 
| 326 | 
            +
                        end
         | 
| 327 | 
            +
                      end
         | 
| 328 | 
            +
             | 
| 329 | 
            +
                      context 'when retrieving a non-projected field' do
         | 
| 330 | 
            +
                        it 'raises MissingAttributeError' do
         | 
| 331 | 
            +
                          expect do
         | 
| 332 | 
            +
                            from_db['name.first_name']
         | 
| 333 | 
            +
                          end.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 334 | 
            +
                        end
         | 
| 335 | 
            +
                      end
         | 
| 336 | 
            +
                    end
         | 
| 337 | 
            +
                  end
         | 
| 338 | 
            +
             | 
| 248 339 | 
             
                  context "when the attribute does not exist" do
         | 
| 249 340 |  | 
| 250 341 | 
             
                    before do
         | 
| @@ -329,6 +420,67 @@ describe Mongoid::Attributes do | |
| 329 420 | 
             
                    expect(terms).to eq(true)
         | 
| 330 421 | 
             
                  end
         | 
| 331 422 | 
             
                end
         | 
| 423 | 
            +
             | 
| 424 | 
            +
                context 'when the field is not explicitly defined' do
         | 
| 425 | 
            +
                  let(:bar) { Bar.new }
         | 
| 426 | 
            +
             | 
| 427 | 
            +
                  before do
         | 
| 428 | 
            +
                    bar['missing_field'] = 42
         | 
| 429 | 
            +
                  end
         | 
| 430 | 
            +
             | 
| 431 | 
            +
                  it 'writes the value into attributes' do
         | 
| 432 | 
            +
                    bar.attributes.should == {'_id' => bar.id, 'missing_field' => 42}
         | 
| 433 | 
            +
                  end
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                  it 'makes the attribute accessible via []' do
         | 
| 436 | 
            +
                    bar['missing_field'].should == 42
         | 
| 437 | 
            +
                  end
         | 
| 438 | 
            +
             | 
| 439 | 
            +
                  context 'when writing fields on a document with projection' do
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                    let!(:person) do
         | 
| 442 | 
            +
                      Person.create(title: "sir")
         | 
| 443 | 
            +
                    end
         | 
| 444 | 
            +
             | 
| 445 | 
            +
                    context "when excluding with only and the field was not excluded" do
         | 
| 446 | 
            +
             | 
| 447 | 
            +
                      let(:from_db) do
         | 
| 448 | 
            +
                        Person.only(:_id).first
         | 
| 449 | 
            +
                      end
         | 
| 450 | 
            +
             | 
| 451 | 
            +
                      it "raises an error" do
         | 
| 452 | 
            +
                        expect {
         | 
| 453 | 
            +
                          from_db[:undefined_field] = 'x'
         | 
| 454 | 
            +
                        }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 455 | 
            +
                      end
         | 
| 456 | 
            +
                    end
         | 
| 457 | 
            +
             | 
| 458 | 
            +
                    context "when excluding with without and the field was excluded" do
         | 
| 459 | 
            +
             | 
| 460 | 
            +
                      let(:from_db) do
         | 
| 461 | 
            +
                        Person.without(:title).first
         | 
| 462 | 
            +
                      end
         | 
| 463 | 
            +
             | 
| 464 | 
            +
                      it "raises an error" do
         | 
| 465 | 
            +
                        expect {
         | 
| 466 | 
            +
                          from_db[:title] = 'x'
         | 
| 467 | 
            +
                        }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 468 | 
            +
                      end
         | 
| 469 | 
            +
                    end
         | 
| 470 | 
            +
             | 
| 471 | 
            +
                    context "when excluding with without and the field was not excluded" do
         | 
| 472 | 
            +
             | 
| 473 | 
            +
                      let(:from_db) do
         | 
| 474 | 
            +
                        Person.without(:title).first
         | 
| 475 | 
            +
                      end
         | 
| 476 | 
            +
             | 
| 477 | 
            +
                      it "writes the value" do
         | 
| 478 | 
            +
                        from_db[:undefined_field] = 'x'
         | 
| 479 | 
            +
                        from_db[:undefined_field].should == 'x'
         | 
| 480 | 
            +
                      end
         | 
| 481 | 
            +
                    end
         | 
| 482 | 
            +
                  end
         | 
| 483 | 
            +
                end
         | 
| 332 484 | 
             
              end
         | 
| 333 485 |  | 
| 334 486 | 
             
              describe "#_id" do
         | 
| @@ -893,6 +1045,50 @@ describe Mongoid::Attributes do | |
| 893 1045 | 
             
                    expect(person.age_before_type_cast).to eq("old")
         | 
| 894 1046 | 
             
                  end
         | 
| 895 1047 | 
             
                end
         | 
| 1048 | 
            +
             | 
| 1049 | 
            +
                context 'when reading fields on a document with projection' do
         | 
| 1050 | 
            +
             | 
| 1051 | 
            +
                  let!(:person) do
         | 
| 1052 | 
            +
                    Person.create(title: "sir")
         | 
| 1053 | 
            +
                  end
         | 
| 1054 | 
            +
             | 
| 1055 | 
            +
                  context "when excluding with only and the field was not excluded" do
         | 
| 1056 | 
            +
             | 
| 1057 | 
            +
                    let(:from_db) do
         | 
| 1058 | 
            +
                      Person.only(:_id).first
         | 
| 1059 | 
            +
                    end
         | 
| 1060 | 
            +
             | 
| 1061 | 
            +
                    it "raises an error" do
         | 
| 1062 | 
            +
                      expect {
         | 
| 1063 | 
            +
                        from_db.read_attribute(:undefined_field)
         | 
| 1064 | 
            +
                      }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 1065 | 
            +
                    end
         | 
| 1066 | 
            +
                  end
         | 
| 1067 | 
            +
             | 
| 1068 | 
            +
                  context "when excluding with without and the field was excluded" do
         | 
| 1069 | 
            +
             | 
| 1070 | 
            +
                    let(:from_db) do
         | 
| 1071 | 
            +
                      Person.without(:title).first
         | 
| 1072 | 
            +
                    end
         | 
| 1073 | 
            +
             | 
| 1074 | 
            +
                    it "raises an error" do
         | 
| 1075 | 
            +
                      expect {
         | 
| 1076 | 
            +
                        from_db.read_attribute(:title)
         | 
| 1077 | 
            +
                      }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 1078 | 
            +
                    end
         | 
| 1079 | 
            +
                  end
         | 
| 1080 | 
            +
             | 
| 1081 | 
            +
                  context "when excluding with without and the field was not excluded" do
         | 
| 1082 | 
            +
             | 
| 1083 | 
            +
                    let(:from_db) do
         | 
| 1084 | 
            +
                      Person.without(:title).first
         | 
| 1085 | 
            +
                    end
         | 
| 1086 | 
            +
             | 
| 1087 | 
            +
                    it "returns nil" do
         | 
| 1088 | 
            +
                      from_db.read_attribute(:undefined_field).should be nil
         | 
| 1089 | 
            +
                    end
         | 
| 1090 | 
            +
                  end
         | 
| 1091 | 
            +
                end
         | 
| 896 1092 | 
             
              end
         | 
| 897 1093 |  | 
| 898 1094 | 
             
              describe "#attribute_present?" do
         | 
| @@ -1398,6 +1594,51 @@ describe Mongoid::Attributes do | |
| 1398 1594 | 
             
                    expect(dictionary.description).to eq('foo')
         | 
| 1399 1595 | 
             
                  end
         | 
| 1400 1596 | 
             
                end
         | 
| 1597 | 
            +
             | 
| 1598 | 
            +
                context 'when writing fields on a document with projection' do
         | 
| 1599 | 
            +
             | 
| 1600 | 
            +
                  let!(:person) do
         | 
| 1601 | 
            +
                    Person.create(title: "sir")
         | 
| 1602 | 
            +
                  end
         | 
| 1603 | 
            +
             | 
| 1604 | 
            +
                  context "when excluding with only and the field was not excluded" do
         | 
| 1605 | 
            +
             | 
| 1606 | 
            +
                    let(:from_db) do
         | 
| 1607 | 
            +
                      Person.only(:_id).first
         | 
| 1608 | 
            +
                    end
         | 
| 1609 | 
            +
             | 
| 1610 | 
            +
                    it "raises an error" do
         | 
| 1611 | 
            +
                      expect {
         | 
| 1612 | 
            +
                        from_db.write_attribute(:undefined_field, 'x')
         | 
| 1613 | 
            +
                      }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 1614 | 
            +
                    end
         | 
| 1615 | 
            +
                  end
         | 
| 1616 | 
            +
             | 
| 1617 | 
            +
                  context "when excluding with without and the field was excluded" do
         | 
| 1618 | 
            +
             | 
| 1619 | 
            +
                    let(:from_db) do
         | 
| 1620 | 
            +
                      Person.without(:title).first
         | 
| 1621 | 
            +
                    end
         | 
| 1622 | 
            +
             | 
| 1623 | 
            +
                    it "raises an error" do
         | 
| 1624 | 
            +
                      expect {
         | 
| 1625 | 
            +
                        from_db.write_attribute(:title, 'x')
         | 
| 1626 | 
            +
                      }.to raise_error(ActiveModel::MissingAttributeError)
         | 
| 1627 | 
            +
                    end
         | 
| 1628 | 
            +
                  end
         | 
| 1629 | 
            +
             | 
| 1630 | 
            +
                  context "when excluding with without and the field was not excluded" do
         | 
| 1631 | 
            +
             | 
| 1632 | 
            +
                    let(:from_db) do
         | 
| 1633 | 
            +
                      Person.without(:title).first
         | 
| 1634 | 
            +
                    end
         | 
| 1635 | 
            +
             | 
| 1636 | 
            +
                    it "writes the value" do
         | 
| 1637 | 
            +
                      from_db.write_attribute(:undefined_field, 'x')
         | 
| 1638 | 
            +
                      from_db.read_attribute(:undefined_field).should == 'x'
         | 
| 1639 | 
            +
                    end
         | 
| 1640 | 
            +
                  end
         | 
| 1641 | 
            +
                end
         | 
| 1401 1642 | 
             
              end
         | 
| 1402 1643 |  | 
| 1403 1644 | 
             
              describe "#typed_value_for" do
         | 
| @@ -753,12 +753,25 @@ describe Mongoid::Contextual::Atomic do | |
| 753 753 | 
             
                  context.set(name: "Recoil")
         | 
| 754 754 | 
             
                end
         | 
| 755 755 |  | 
| 756 | 
            -
                 | 
| 757 | 
            -
                   | 
| 756 | 
            +
                shared_examples 'writes as expected' do
         | 
| 757 | 
            +
                  it "sets existing fields" do
         | 
| 758 | 
            +
                    expect(depeche_mode.reload.name).to eq("Recoil")
         | 
| 759 | 
            +
                  end
         | 
| 760 | 
            +
             | 
| 761 | 
            +
                  it "sets non existent fields" do
         | 
| 762 | 
            +
                    expect(smiths.reload.name).to eq("Recoil")
         | 
| 763 | 
            +
                  end
         | 
| 758 764 | 
             
                end
         | 
| 759 765 |  | 
| 760 | 
            -
                 | 
| 761 | 
            -
             | 
| 766 | 
            +
                include_examples 'writes as expected'
         | 
| 767 | 
            +
             | 
| 768 | 
            +
                context 'when fields being set have been projected out' do
         | 
| 769 | 
            +
             | 
| 770 | 
            +
                  let(:criteria) do
         | 
| 771 | 
            +
                    Band.only(:genres)
         | 
| 772 | 
            +
                  end
         | 
| 773 | 
            +
             | 
| 774 | 
            +
                  include_examples 'writes as expected'
         | 
| 762 775 | 
             
                end
         | 
| 763 776 | 
             
              end
         | 
| 764 777 |  | 
| @@ -1447,6 +1447,42 @@ describe Mongoid::Criteria::Queryable::Selectable do | |
| 1447 1447 | 
             
                    end
         | 
| 1448 1448 | 
             
                  end
         | 
| 1449 1449 | 
             
                end
         | 
| 1450 | 
            +
             | 
| 1451 | 
            +
                context 'when using multiple criteria and symbol operators' do
         | 
| 1452 | 
            +
                  context 'when using fields that meaningfully evolve values' do
         | 
| 1453 | 
            +
             | 
| 1454 | 
            +
                    let(:query) do
         | 
| 1455 | 
            +
                      Dictionary.any_of({a: 1}, :published.gt => Date.new(2020, 2, 3))
         | 
| 1456 | 
            +
                    end
         | 
| 1457 | 
            +
             | 
| 1458 | 
            +
                    it 'generates the expected query' do
         | 
| 1459 | 
            +
                      query.selector.should == {'$or' => [
         | 
| 1460 | 
            +
                        {'a' => 1},
         | 
| 1461 | 
            +
                        # Date instance is converted to a Time instance in local time,
         | 
| 1462 | 
            +
                        # because we are querying on a Time field and dates are interpreted
         | 
| 1463 | 
            +
                        # in local time when assigning to Time fields
         | 
| 1464 | 
            +
                        {'published' => {'$gt' => Time.local(2020, 2, 3)}},
         | 
| 1465 | 
            +
                      ]}
         | 
| 1466 | 
            +
                    end
         | 
| 1467 | 
            +
                  end
         | 
| 1468 | 
            +
             | 
| 1469 | 
            +
                  context 'when using fields that do not meaningfully evolve values' do
         | 
| 1470 | 
            +
             | 
| 1471 | 
            +
                    let(:query) do
         | 
| 1472 | 
            +
                      Dictionary.any_of({a: 1}, :submitted_on.gt => Date.new(2020, 2, 3))
         | 
| 1473 | 
            +
                    end
         | 
| 1474 | 
            +
             | 
| 1475 | 
            +
                    it 'generates the expected query' do
         | 
| 1476 | 
            +
                      query.selector.should == {'$or' => [
         | 
| 1477 | 
            +
                        {'a' => 1},
         | 
| 1478 | 
            +
                        # Date instance is converted to a Time instance in UTC,
         | 
| 1479 | 
            +
                        # because we are querying on a Date field and dates are interpreted
         | 
| 1480 | 
            +
                        # in UTC when persisted as dates by Mongoid
         | 
| 1481 | 
            +
                        {'submitted_on' => {'$gt' => Time.utc(2020, 2, 3)}},
         | 
| 1482 | 
            +
                      ]}
         | 
| 1483 | 
            +
                    end
         | 
| 1484 | 
            +
                  end
         | 
| 1485 | 
            +
                end
         | 
| 1450 1486 | 
             
              end
         | 
| 1451 1487 |  | 
| 1452 1488 | 
             
              describe "#not" do
         | 
| @@ -36,4 +36,55 @@ describe Mongoid::Document do | |
| 36 36 | 
             
                  expect(_person.age).to be 42
         | 
| 37 37 | 
             
                end
         | 
| 38 38 | 
             
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              context 'when projecting with #without' do
         | 
| 41 | 
            +
                before do
         | 
| 42 | 
            +
                  duck = Pet.new(name: 'Duck')
         | 
| 43 | 
            +
                  Person.create!(username: 'Dev', title: 'CEO', pet: duck)
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                let(:person) { Person.where(username: 'Dev').without(:title).first }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  it 'allows access to attribute of embedded document' do
         | 
| 49 | 
            +
                  expect(person.pet.name).to eq 'Duck'
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                context 'when exclusion starts with association name but is not the association' do
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  let(:person) { Person.where(username: 'Dev').without(:pet_).first }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  it 'allows access to attribute of embedded document' do
         | 
| 57 | 
            +
                    expect(person.pet.name).to eq 'Duck'
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                context 'when exclusion starts with prefix of association name' do
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  let(:person) { Person.where(username: 'Dev').without(:pe).first }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  it 'allows access to attribute of embedded document' do
         | 
| 66 | 
            +
                    expect(person.pet.name).to eq 'Duck'
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                context 'when another attribute of the association is excluded' do
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  let(:person) { Person.where(username: 'Dev').without('pet.weight').first }
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  it 'allows access to non-excluded attribute of embedded document' do
         | 
| 75 | 
            +
                    expect(person.pet.name).to eq 'Duck'
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                context 'when the excluded attribute of the association is retrieved' do
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  let(:person) { Person.where(username: 'Dev').without('pet.name').first }
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  it 'prohibits the retrieval' do
         | 
| 84 | 
            +
                    lambda do
         | 
| 85 | 
            +
                      person.pet.name
         | 
| 86 | 
            +
                    end.should raise_error(ActiveModel::MissingAttributeError)
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
              end
         | 
| 39 90 | 
             
            end
         |