mongoid 7.0.6 → 7.1.2
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/CHANGELOG.md +13 -13
- data/README.md +23 -17
- data/Rakefile +2 -0
- data/lib/config/locales/en.yml +60 -51
- data/lib/mongoid.rb +10 -2
- data/lib/mongoid/association.rb +9 -6
- data/lib/mongoid/association/accessors.rb +95 -52
- data/lib/mongoid/association/bindable.rb +7 -5
- data/lib/mongoid/association/builders.rb +4 -3
- data/lib/mongoid/association/constrainable.rb +4 -2
- data/lib/mongoid/association/depending.rb +5 -2
- data/lib/mongoid/association/eager_loadable.rb +2 -0
- data/lib/mongoid/association/embedded.rb +3 -0
- data/lib/mongoid/association/embedded/batchable.rb +4 -2
- data/lib/mongoid/association/embedded/cyclic.rb +8 -6
- data/lib/mongoid/association/embedded/embedded_in.rb +6 -3
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +4 -1
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +8 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +15 -12
- data/lib/mongoid/association/embedded/embeds_many.rb +9 -5
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +5 -2
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +9 -3
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -47
- data/lib/mongoid/association/embedded/embeds_one.rb +9 -5
- data/lib/mongoid/association/embedded/embeds_one/binding.rb +5 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +10 -4
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +17 -14
- data/lib/mongoid/association/macros.rb +38 -36
- data/lib/mongoid/association/many.rb +14 -11
- data/lib/mongoid/association/marshalable.rb +3 -1
- data/lib/mongoid/association/nested.rb +4 -1
- data/lib/mongoid/association/nested/many.rb +17 -15
- data/lib/mongoid/association/nested/nested_buildable.rb +6 -3
- data/lib/mongoid/association/nested/one.rb +11 -9
- data/lib/mongoid/association/one.rb +3 -1
- data/lib/mongoid/association/options.rb +9 -6
- data/lib/mongoid/association/proxy.rb +31 -14
- data/lib/mongoid/association/referenced.rb +3 -0
- data/lib/mongoid/association/referenced/auto_save.rb +4 -1
- data/lib/mongoid/association/referenced/belongs_to.rb +6 -3
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +3 -1
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +6 -3
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +40 -2
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +16 -14
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -0
- data/lib/mongoid/association/referenced/eager.rb +37 -15
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +13 -6
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +12 -6
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +5 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +25 -18
- data/lib/mongoid/association/referenced/has_many.rb +7 -4
- data/lib/mongoid/association/referenced/has_many/binding.rb +3 -1
- data/lib/mongoid/association/referenced/has_many/buildable.rb +5 -2
- data/lib/mongoid/association/referenced/has_many/eager.rb +2 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +11 -4
- data/lib/mongoid/association/referenced/has_many/proxy.rb +46 -43
- data/lib/mongoid/association/referenced/has_one.rb +5 -2
- data/lib/mongoid/association/referenced/has_one/binding.rb +4 -2
- data/lib/mongoid/association/referenced/has_one/buildable.rb +8 -1
- data/lib/mongoid/association/referenced/has_one/eager.rb +2 -0
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +11 -9
- data/lib/mongoid/association/referenced/has_one/proxy.rb +17 -15
- data/lib/mongoid/association/referenced/syncable.rb +7 -5
- data/lib/mongoid/association/reflections.rb +7 -5
- data/lib/mongoid/association/relatable.rb +17 -14
- data/lib/mongoid/atomic.rb +15 -3
- data/lib/mongoid/atomic/modifiers.rb +24 -1
- data/lib/mongoid/atomic/paths.rb +2 -0
- data/lib/mongoid/atomic/paths/embedded.rb +2 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +4 -2
- data/lib/mongoid/atomic/paths/embedded/one.rb +4 -2
- data/lib/mongoid/atomic/paths/root.rb +4 -2
- data/lib/mongoid/attributes.rb +14 -13
- data/lib/mongoid/attributes/dynamic.rb +2 -0
- data/lib/mongoid/attributes/nested.rb +7 -5
- data/lib/mongoid/attributes/processing.rb +8 -6
- data/lib/mongoid/attributes/readonly.rb +3 -1
- data/lib/mongoid/cacheable.rb +3 -1
- data/lib/mongoid/changeable.rb +3 -1
- data/lib/mongoid/clients.rb +2 -0
- data/lib/mongoid/clients/factory.rb +1 -0
- data/lib/mongoid/clients/options.rb +2 -0
- data/lib/mongoid/clients/sessions.rb +3 -0
- data/lib/mongoid/clients/storage_options.rb +2 -0
- data/lib/mongoid/clients/validators.rb +2 -0
- data/lib/mongoid/clients/validators/storage.rb +2 -0
- data/lib/mongoid/composable.rb +4 -2
- data/lib/mongoid/config.rb +53 -10
- data/lib/mongoid/config/environment.rb +2 -0
- data/lib/mongoid/config/options.rb +20 -12
- data/lib/mongoid/config/validators.rb +2 -0
- data/lib/mongoid/config/validators/client.rb +2 -0
- data/lib/mongoid/config/validators/option.rb +2 -0
- data/lib/mongoid/contextual.rb +7 -4
- data/lib/mongoid/contextual/aggregable/memory.rb +3 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +3 -1
- data/lib/mongoid/contextual/atomic.rb +24 -6
- data/lib/mongoid/contextual/command.rb +2 -0
- data/lib/mongoid/contextual/geo_near.rb +5 -3
- data/lib/mongoid/contextual/map_reduce.rb +5 -2
- data/lib/mongoid/contextual/memory.rb +4 -2
- data/lib/mongoid/contextual/mongo.rb +6 -1
- data/lib/mongoid/contextual/none.rb +2 -0
- data/lib/mongoid/contextual/queryable.rb +2 -0
- data/lib/mongoid/copyable.rb +3 -1
- data/lib/mongoid/criteria.rb +25 -4
- data/lib/mongoid/criteria/findable.rb +11 -1
- data/lib/mongoid/criteria/includable.rb +8 -6
- data/lib/mongoid/criteria/inspectable.rb +2 -0
- data/lib/mongoid/criteria/marshalable.rb +2 -0
- data/lib/mongoid/criteria/modifiable.rb +4 -1
- data/lib/mongoid/criteria/options.rb +2 -0
- data/lib/mongoid/criteria/permission.rb +2 -0
- data/lib/mongoid/criteria/queryable.rb +7 -2
- data/lib/mongoid/criteria/queryable/aggregable.rb +2 -0
- data/lib/mongoid/criteria/queryable/expandable.rb +93 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +2 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +5 -6
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -2
- data/lib/mongoid/criteria/queryable/extensions/object.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +7 -5
- data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/time.rb +4 -2
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +3 -1
- data/lib/mongoid/criteria/queryable/key.rb +34 -6
- data/lib/mongoid/criteria/queryable/macroable.rb +3 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +153 -11
- data/lib/mongoid/criteria/queryable/optional.rb +5 -3
- data/lib/mongoid/criteria/queryable/options.rb +2 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +5 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +374 -90
- data/lib/mongoid/criteria/queryable/selector.rb +38 -5
- data/lib/mongoid/criteria/queryable/smash.rb +2 -0
- data/lib/mongoid/criteria/queryable/storable.rb +233 -0
- data/lib/mongoid/criteria/scopable.rb +2 -0
- data/lib/mongoid/document.rb +2 -0
- data/lib/mongoid/equality.rb +3 -2
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/errors/ambiguous_relationship.rb +4 -2
- data/lib/mongoid/errors/callback.rb +2 -0
- data/lib/mongoid/errors/criteria_argument_required.rb +19 -0
- data/lib/mongoid/errors/delete_restriction.rb +3 -2
- data/lib/mongoid/errors/document_not_destroyed.rb +2 -0
- data/lib/mongoid/errors/document_not_found.rb +2 -0
- data/lib/mongoid/errors/eager_load.rb +6 -2
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -0
- data/lib/mongoid/errors/invalid_collection.rb +2 -0
- data/lib/mongoid/errors/invalid_config_option.rb +2 -0
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +2 -0
- data/lib/mongoid/errors/invalid_field.rb +2 -0
- data/lib/mongoid/errors/invalid_field_option.rb +2 -0
- data/lib/mongoid/errors/invalid_find.rb +2 -0
- data/lib/mongoid/errors/invalid_includes.rb +2 -0
- data/lib/mongoid/errors/invalid_index.rb +2 -0
- data/lib/mongoid/errors/invalid_options.rb +4 -2
- data/lib/mongoid/errors/invalid_path.rb +2 -0
- data/lib/mongoid/errors/invalid_persistence_option.rb +2 -0
- data/lib/mongoid/errors/invalid_relation.rb +4 -2
- data/lib/mongoid/errors/invalid_relation_option.rb +4 -2
- data/lib/mongoid/errors/invalid_scope.rb +2 -0
- data/lib/mongoid/errors/invalid_session_use.rb +2 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -4
- data/lib/mongoid/errors/invalid_storage_options.rb +2 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors/invalid_time.rb +2 -0
- data/lib/mongoid/errors/invalid_value.rb +2 -0
- data/lib/mongoid/errors/inverse_not_found.rb +3 -1
- data/lib/mongoid/errors/mixed_client_configuration.rb +2 -0
- data/lib/mongoid/errors/mixed_relations.rb +2 -0
- data/lib/mongoid/errors/mongoid_error.rb +2 -0
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -1
- data/lib/mongoid/errors/no_client_config.rb +2 -0
- data/lib/mongoid/errors/no_client_database.rb +2 -0
- data/lib/mongoid/errors/no_client_hosts.rb +2 -0
- data/lib/mongoid/errors/no_clients_config.rb +2 -0
- data/lib/mongoid/errors/no_default_client.rb +2 -0
- data/lib/mongoid/errors/no_environment.rb +2 -0
- data/lib/mongoid/errors/no_map_reduce_output.rb +2 -0
- data/lib/mongoid/errors/no_metadata.rb +2 -0
- data/lib/mongoid/errors/no_parent.rb +2 -0
- data/lib/mongoid/errors/readonly_attribute.rb +2 -0
- data/lib/mongoid/errors/readonly_document.rb +2 -0
- data/lib/mongoid/errors/scope_overwrite.rb +2 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -0
- data/lib/mongoid/errors/unknown_attribute.rb +2 -0
- data/lib/mongoid/errors/unknown_model.rb +2 -0
- data/lib/mongoid/errors/unsaved_document.rb +2 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +2 -0
- data/lib/mongoid/errors/validations.rb +2 -0
- data/lib/mongoid/evolvable.rb +3 -1
- data/lib/mongoid/extensions.rb +2 -0
- data/lib/mongoid/extensions/array.rb +23 -6
- data/lib/mongoid/extensions/big_decimal.rb +2 -0
- data/lib/mongoid/extensions/boolean.rb +2 -0
- data/lib/mongoid/extensions/date.rb +13 -3
- data/lib/mongoid/extensions/date_time.rb +4 -3
- data/lib/mongoid/extensions/decimal128.rb +2 -0
- data/lib/mongoid/extensions/false_class.rb +2 -0
- data/lib/mongoid/extensions/float.rb +5 -3
- data/lib/mongoid/extensions/hash.rb +51 -9
- data/lib/mongoid/extensions/integer.rb +5 -3
- data/lib/mongoid/extensions/module.rb +2 -0
- data/lib/mongoid/extensions/nil_class.rb +2 -0
- data/lib/mongoid/extensions/object.rb +16 -4
- data/lib/mongoid/extensions/object_id.rb +2 -0
- data/lib/mongoid/extensions/range.rb +2 -0
- data/lib/mongoid/extensions/regexp.rb +3 -1
- data/lib/mongoid/extensions/set.rb +2 -0
- data/lib/mongoid/extensions/string.rb +18 -9
- data/lib/mongoid/extensions/symbol.rb +2 -0
- data/lib/mongoid/extensions/time.rb +14 -0
- data/lib/mongoid/extensions/time_with_zone.rb +14 -0
- data/lib/mongoid/extensions/true_class.rb +2 -0
- data/lib/mongoid/factory.rb +28 -5
- data/lib/mongoid/fields.rb +5 -2
- data/lib/mongoid/fields/foreign_key.rb +3 -1
- data/lib/mongoid/fields/localized.rb +2 -0
- data/lib/mongoid/fields/standard.rb +6 -3
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields/validators/macro.rb +13 -2
- data/lib/mongoid/findable.rb +9 -4
- data/lib/mongoid/indexable.rb +3 -1
- data/lib/mongoid/indexable/specification.rb +3 -1
- data/lib/mongoid/indexable/validators/options.rb +2 -0
- data/lib/mongoid/inspectable.rb +3 -1
- data/lib/mongoid/interceptable.rb +9 -3
- data/lib/mongoid/loggable.rb +13 -7
- data/lib/mongoid/matchable.rb +2 -0
- data/lib/mongoid/matchable/all.rb +2 -0
- data/lib/mongoid/matchable/and.rb +2 -0
- data/lib/mongoid/matchable/default.rb +2 -0
- data/lib/mongoid/matchable/elem_match.rb +2 -0
- data/lib/mongoid/matchable/eq.rb +1 -0
- data/lib/mongoid/matchable/exists.rb +2 -0
- data/lib/mongoid/matchable/gt.rb +2 -0
- data/lib/mongoid/matchable/gte.rb +2 -0
- data/lib/mongoid/matchable/in.rb +2 -0
- data/lib/mongoid/matchable/lt.rb +2 -0
- data/lib/mongoid/matchable/lte.rb +2 -0
- data/lib/mongoid/matchable/ne.rb +2 -0
- data/lib/mongoid/matchable/nin.rb +2 -0
- data/lib/mongoid/matchable/nor.rb +2 -1
- data/lib/mongoid/matchable/or.rb +2 -0
- data/lib/mongoid/matchable/regexp.rb +5 -2
- data/lib/mongoid/matchable/size.rb +2 -0
- data/lib/mongoid/persistable.rb +133 -15
- data/lib/mongoid/persistable/creatable.rb +3 -1
- data/lib/mongoid/persistable/deletable.rb +3 -1
- data/lib/mongoid/persistable/destroyable.rb +3 -1
- data/lib/mongoid/persistable/incrementable.rb +6 -2
- data/lib/mongoid/persistable/logical.rb +4 -1
- data/lib/mongoid/persistable/poppable.rb +3 -1
- data/lib/mongoid/persistable/pullable.rb +3 -1
- data/lib/mongoid/persistable/pushable.rb +14 -3
- data/lib/mongoid/persistable/renamable.rb +10 -3
- data/lib/mongoid/persistable/savable.rb +3 -1
- data/lib/mongoid/persistable/settable.rb +3 -1
- data/lib/mongoid/persistable/unsettable.rb +8 -3
- data/lib/mongoid/persistable/updatable.rb +3 -1
- data/lib/mongoid/persistable/upsertable.rb +3 -1
- data/lib/mongoid/persistence_context.rb +27 -15
- data/lib/mongoid/positional.rb +2 -0
- data/lib/mongoid/query_cache.rb +10 -9
- data/lib/mongoid/railtie.rb +3 -1
- data/lib/mongoid/railties/controller_runtime.rb +4 -1
- data/lib/mongoid/railties/database.rake +9 -0
- data/lib/mongoid/reloadable.rb +4 -2
- data/lib/mongoid/scopable.rb +2 -1
- data/lib/mongoid/selectable.rb +3 -1
- data/lib/mongoid/serializable.rb +23 -13
- data/lib/mongoid/shardable.rb +59 -5
- data/lib/mongoid/stateful.rb +3 -1
- data/lib/mongoid/tasks/database.rake +12 -5
- data/lib/mongoid/tasks/database.rb +50 -0
- data/lib/mongoid/threaded.rb +2 -0
- data/lib/mongoid/threaded/lifecycle.rb +2 -0
- data/lib/mongoid/timestamps.rb +3 -1
- data/lib/mongoid/timestamps/created.rb +3 -1
- data/lib/mongoid/timestamps/created/short.rb +2 -0
- data/lib/mongoid/timestamps/short.rb +2 -0
- data/lib/mongoid/timestamps/timeless.rb +6 -2
- data/lib/mongoid/timestamps/updated.rb +3 -1
- data/lib/mongoid/timestamps/updated/short.rb +2 -0
- data/lib/mongoid/touchable.rb +20 -12
- data/lib/mongoid/traversable.rb +4 -2
- data/lib/mongoid/validatable.rb +7 -5
- data/lib/mongoid/validatable/associated.rb +4 -2
- data/lib/mongoid/validatable/format.rb +2 -0
- data/lib/mongoid/validatable/length.rb +2 -0
- data/lib/mongoid/validatable/localizable.rb +2 -0
- data/lib/mongoid/validatable/macros.rb +2 -0
- data/lib/mongoid/validatable/presence.rb +4 -2
- data/lib/mongoid/validatable/queryable.rb +2 -0
- data/lib/mongoid/validatable/uniqueness.rb +5 -3
- data/lib/mongoid/version.rb +2 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +2 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +44 -29
- data/lib/rails/generators/mongoid/model/model_generator.rb +3 -1
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/mongoid_generator.rb +2 -0
- data/lib/rails/mongoid.rb +4 -2
- data/lib/support/ruby_version.rb +3 -0
- data/spec/app/models/account.rb +3 -0
- data/spec/app/models/acolyte.rb +3 -0
- data/spec/app/models/actor.rb +3 -0
- data/spec/app/models/actress.rb +3 -0
- data/spec/app/models/address.rb +3 -0
- data/spec/app/models/address_component.rb +3 -0
- data/spec/app/models/address_number.rb +3 -0
- data/spec/app/models/agency.rb +3 -0
- data/spec/app/models/agent.rb +3 -0
- data/spec/app/models/album.rb +3 -0
- data/spec/app/models/alert.rb +3 -0
- data/spec/app/models/animal.rb +3 -0
- data/spec/app/models/answer.rb +3 -0
- data/spec/app/models/appointment.rb +3 -0
- data/spec/app/models/array_field.rb +1 -0
- data/spec/app/models/article.rb +3 -0
- data/spec/app/models/artist.rb +3 -0
- data/spec/app/models/artwork.rb +3 -0
- data/spec/app/models/audio.rb +3 -0
- data/spec/app/models/augmentation.rb +3 -0
- data/spec/app/models/author.rb +3 -0
- data/spec/app/models/baby.rb +3 -0
- data/spec/app/models/band.rb +3 -0
- data/spec/app/models/bar.rb +3 -0
- data/spec/app/models/basic.rb +3 -0
- data/spec/app/models/bed.rb +3 -0
- data/spec/app/models/big_palette.rb +3 -0
- data/spec/app/models/birthday.rb +3 -0
- data/spec/app/models/bomb.rb +3 -0
- data/spec/app/models/book.rb +3 -0
- data/spec/app/models/breed.rb +3 -0
- data/spec/app/models/browser.rb +3 -0
- data/spec/app/models/building.rb +3 -0
- data/spec/app/models/building_address.rb +3 -0
- data/spec/app/models/bus.rb +3 -0
- data/spec/app/models/business.rb +3 -0
- data/spec/app/models/callback_test.rb +3 -0
- data/spec/app/models/canvas.rb +3 -0
- data/spec/app/models/car.rb +3 -0
- data/spec/app/models/cat.rb +3 -0
- data/spec/app/models/category.rb +3 -0
- data/spec/app/models/child.rb +3 -0
- data/spec/app/models/child_doc.rb +3 -0
- data/spec/app/models/church.rb +3 -0
- data/spec/app/models/circle.rb +3 -0
- data/spec/app/models/circuit.rb +3 -0
- data/spec/app/models/circus.rb +3 -0
- data/spec/app/models/code.rb +3 -0
- data/spec/app/models/coding.rb +4 -0
- data/spec/app/models/coding/pull_request.rb +12 -0
- data/spec/app/models/comment.rb +3 -0
- data/spec/app/models/company.rb +3 -0
- data/spec/app/models/consumption_period.rb +3 -0
- data/spec/app/models/contextable_item.rb +3 -0
- data/spec/app/models/contractor.rb +3 -0
- data/spec/app/models/cookie.rb +3 -0
- data/spec/app/models/country_code.rb +3 -0
- data/spec/app/models/courier_job.rb +3 -0
- data/spec/app/models/definition.rb +3 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/description.rb +3 -0
- data/spec/app/models/dictionary.rb +3 -0
- data/spec/app/models/division.rb +3 -0
- data/spec/app/models/doctor.rb +3 -0
- data/spec/app/models/dog.rb +3 -0
- data/spec/app/models/dokument.rb +3 -0
- data/spec/app/models/draft.rb +3 -0
- data/spec/app/models/dragon.rb +3 -0
- data/spec/app/models/driver.rb +3 -0
- data/spec/app/models/drug.rb +3 -0
- data/spec/app/models/dungeon.rb +3 -0
- data/spec/app/models/edit.rb +3 -0
- data/spec/app/models/email.rb +3 -0
- data/spec/app/models/employer.rb +3 -0
- data/spec/app/models/entry.rb +3 -0
- data/spec/app/models/eraser.rb +3 -0
- data/spec/app/models/even.rb +3 -0
- data/spec/app/models/event.rb +3 -0
- data/spec/app/models/exhibition.rb +3 -0
- data/spec/app/models/exhibitor.rb +3 -0
- data/spec/app/models/explosion.rb +3 -0
- data/spec/app/models/eye.rb +3 -0
- data/spec/app/models/eye_bowl.rb +3 -0
- data/spec/app/models/face.rb +3 -0
- data/spec/app/models/favorite.rb +3 -0
- data/spec/app/models/filesystem.rb +3 -0
- data/spec/app/models/fire_hydrant.rb +3 -0
- data/spec/app/models/firefox.rb +3 -0
- data/spec/app/models/fish.rb +3 -0
- data/spec/app/models/folder.rb +3 -0
- data/spec/app/models/folder_item.rb +3 -0
- data/spec/app/models/fruits.rb +3 -0
- data/spec/app/models/game.rb +3 -0
- data/spec/app/models/ghost.rb +3 -0
- data/spec/app/models/home.rb +3 -0
- data/spec/app/models/house.rb +3 -0
- data/spec/app/models/html_writer.rb +3 -0
- data/spec/app/models/id_key.rb +3 -0
- data/spec/app/models/image.rb +3 -0
- data/spec/app/models/implant.rb +3 -0
- data/spec/app/models/item.rb +3 -0
- data/spec/app/models/jar.rb +3 -0
- data/spec/app/models/kaleidoscope.rb +3 -0
- data/spec/app/models/kangaroo.rb +4 -1
- data/spec/app/models/label.rb +3 -0
- data/spec/app/models/language.rb +3 -0
- data/spec/app/models/lat_lng.rb +3 -0
- data/spec/app/models/league.rb +3 -0
- data/spec/app/models/learner.rb +3 -0
- data/spec/app/models/line_item.rb +3 -0
- data/spec/app/models/location.rb +3 -0
- data/spec/app/models/login.rb +3 -0
- data/spec/app/models/manufacturer.rb +3 -0
- data/spec/app/models/meat.rb +3 -0
- data/spec/app/models/membership.rb +3 -0
- data/spec/app/models/message.rb +3 -0
- data/spec/app/models/minim.rb +1 -1
- data/spec/app/models/mixed_drink.rb +3 -0
- data/spec/app/models/movie.rb +3 -0
- data/spec/app/models/my_hash.rb +3 -0
- data/spec/app/models/name.rb +3 -0
- data/spec/app/models/name_only.rb +9 -0
- data/spec/app/models/node.rb +3 -0
- data/spec/app/models/note.rb +3 -0
- data/spec/app/models/odd.rb +3 -0
- data/spec/app/models/ordered_post.rb +3 -0
- data/spec/app/models/ordered_preference.rb +3 -0
- data/spec/app/models/oscar.rb +3 -0
- data/spec/app/models/other_owner_object.rb +3 -0
- data/spec/app/models/override.rb +3 -0
- data/spec/app/models/ownable.rb +3 -0
- data/spec/app/models/owner.rb +3 -0
- data/spec/app/models/pack.rb +3 -0
- data/spec/app/models/page.rb +3 -0
- data/spec/app/models/page_question.rb +3 -0
- data/spec/app/models/palette.rb +3 -0
- data/spec/app/models/parent.rb +3 -0
- data/spec/app/models/parent_doc.rb +3 -0
- data/spec/app/models/passport.rb +3 -0
- data/spec/app/models/patient.rb +3 -0
- data/spec/app/models/pdf_writer.rb +3 -0
- data/spec/app/models/pencil.rb +3 -0
- data/spec/app/models/person.rb +3 -0
- data/spec/app/models/pet.rb +3 -0
- data/spec/app/models/pet_owner.rb +3 -0
- data/spec/app/models/phone.rb +3 -0
- data/spec/app/models/pizza.rb +3 -0
- data/spec/app/models/player.rb +3 -0
- data/spec/app/models/post.rb +3 -0
- data/spec/app/models/post_genre.rb +3 -0
- data/spec/app/models/powerup.rb +3 -0
- data/spec/app/models/preference.rb +3 -0
- data/spec/app/models/princess.rb +3 -0
- data/spec/app/models/product.rb +3 -0
- data/spec/app/models/profile.rb +3 -0
- data/spec/app/models/pronunciation.rb +3 -0
- data/spec/app/models/pub.rb +3 -0
- data/spec/app/models/publication.rb +5 -0
- data/spec/app/models/publication/encyclopedia.rb +12 -0
- data/spec/app/models/publication/review.rb +14 -0
- data/spec/app/models/purchase.rb +3 -0
- data/spec/app/models/question.rb +3 -0
- data/spec/app/models/quiz.rb +3 -0
- data/spec/app/models/rating.rb +3 -0
- data/spec/app/models/record.rb +3 -0
- data/spec/app/models/registry.rb +3 -0
- data/spec/app/models/role.rb +3 -0
- data/spec/app/models/root_category.rb +3 -0
- data/spec/app/models/sandwich.rb +3 -0
- data/spec/app/models/scheduler.rb +3 -0
- data/spec/app/models/seo.rb +3 -0
- data/spec/app/models/series.rb +3 -0
- data/spec/app/models/server.rb +3 -0
- data/spec/app/models/service.rb +3 -0
- data/spec/app/models/shape.rb +3 -0
- data/spec/app/models/shelf.rb +3 -0
- data/spec/app/models/shipment_address.rb +3 -0
- data/spec/app/models/shipping_container.rb +3 -0
- data/spec/app/models/shipping_pack.rb +3 -0
- data/spec/app/models/shop.rb +3 -0
- data/spec/app/models/short_agent.rb +3 -0
- data/spec/app/models/short_quiz.rb +3 -0
- data/spec/app/models/simple.rb +3 -0
- data/spec/app/models/slave.rb +3 -0
- data/spec/app/models/song.rb +3 -0
- data/spec/app/models/sound.rb +3 -0
- data/spec/app/models/square.rb +3 -0
- data/spec/app/models/staff.rb +3 -0
- data/spec/app/models/store_as_dup_test1.rb +3 -0
- data/spec/app/models/store_as_dup_test2.rb +3 -0
- data/spec/app/models/store_as_dup_test3.rb +1 -0
- data/spec/app/models/store_as_dup_test4.rb +1 -0
- data/spec/app/models/strategy.rb +3 -0
- data/spec/app/models/sub_item.rb +3 -0
- data/spec/app/models/subscription.rb +3 -0
- data/spec/app/models/survey.rb +3 -0
- data/spec/app/models/symptom.rb +3 -0
- data/spec/app/models/tag.rb +3 -0
- data/spec/app/models/target.rb +3 -0
- data/spec/app/models/template.rb +3 -0
- data/spec/app/models/thing.rb +3 -0
- data/spec/app/models/title.rb +3 -0
- data/spec/app/models/tool.rb +3 -0
- data/spec/app/models/topping.rb +3 -0
- data/spec/app/models/track.rb +3 -0
- data/spec/app/models/translation.rb +3 -0
- data/spec/app/models/tree.rb +3 -0
- data/spec/app/models/truck.rb +3 -0
- data/spec/app/models/updatable.rb +1 -0
- data/spec/app/models/user.rb +3 -0
- data/spec/app/models/user_account.rb +3 -0
- data/spec/app/models/validation_callback.rb +3 -0
- data/spec/app/models/vehicle.rb +3 -0
- data/spec/app/models/version.rb +3 -0
- data/spec/app/models/vertex.rb +4 -1
- data/spec/app/models/vet_visit.rb +3 -0
- data/spec/app/models/video.rb +3 -0
- data/spec/app/models/video_game.rb +3 -0
- data/spec/app/models/weapon.rb +3 -0
- data/spec/app/models/wiki_page.rb +3 -0
- data/spec/app/models/word.rb +3 -0
- data/spec/app/models/word_origin.rb +3 -0
- data/spec/app/models/writer.rb +3 -0
- data/spec/config/mongoid.yml +1 -0
- data/spec/integration/app_spec.rb +192 -0
- data/spec/integration/associations/belongs_to_spec.rb +3 -0
- data/spec/integration/associations/embedded_spec.rb +175 -0
- data/spec/integration/associations/foreign_key_spec.rb +99 -0
- data/spec/integration/associations/foreign_key_spec_models.rb +65 -0
- data/spec/integration/associations/reverse_population_spec.rb +35 -0
- data/spec/integration/associations/reverse_population_spec_models.rb +37 -0
- data/spec/integration/criteria/default_scope_spec.rb +21 -0
- data/spec/integration/criteria/logical_spec.rb +94 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/integration/i18n_fallbacks_spec.rb +90 -0
- data/spec/integration/shardable_spec.rb +133 -0
- data/spec/lite_spec_helper.rb +20 -5
- data/spec/mongoid/association/accessors_spec.rb +3 -0
- data/spec/mongoid/association/auto_save_spec.rb +3 -0
- data/spec/mongoid/association/builders_spec.rb +3 -0
- data/spec/mongoid/association/constrainable_spec.rb +3 -0
- data/spec/mongoid/association/counter_cache_spec.rb +3 -0
- data/spec/mongoid/association/depending_spec.rb +3 -0
- data/spec/mongoid/association/eager_spec.rb +3 -0
- data/spec/mongoid/association/embedded/cyclic_spec.rb +3 -0
- data/spec/mongoid/association/embedded/dirty_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embedded_in_spec.rb +4 -1
- data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +52 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +14 -1
- data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +3 -0
- data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +29 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +4 -3
- data/spec/mongoid/association/macros_spec.rb +3 -0
- data/spec/mongoid/association/nested/many_spec.rb +3 -0
- data/spec/mongoid/association/nested/one_spec.rb +3 -0
- data/spec/mongoid/association/options_spec.rb +3 -0
- data/spec/mongoid/association/polymorphic_spec.rb +3 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +3 -0
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +3 -0
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +205 -10
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +3 -0
- data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +38 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +16 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +26 -5
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +39 -15
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +40 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +26 -2
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_many/eager_spec.rb +18 -3
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +5 -1
- data/spec/mongoid/association/referenced/has_many_models.rb +3 -0
- data/spec/mongoid/association/referenced/has_many_query_spec.rb +38 -0
- data/spec/mongoid/association/referenced/has_many_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_one/binding_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_one/eager_spec.rb +18 -3
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +3 -0
- data/spec/mongoid/association/referenced/has_one_models.rb +3 -0
- data/spec/mongoid/association/referenced/has_one_query_spec.rb +38 -0
- data/spec/mongoid/association/referenced/has_one_spec.rb +3 -0
- data/spec/mongoid/association/reflections_spec.rb +3 -0
- data/spec/mongoid/association/syncable_spec.rb +3 -0
- data/spec/mongoid/association_spec.rb +3 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +3 -0
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +3 -0
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +3 -0
- data/spec/mongoid/atomic/paths/root_spec.rb +3 -0
- data/spec/mongoid/atomic/paths_spec.rb +3 -0
- data/spec/mongoid/atomic_spec.rb +3 -0
- data/spec/mongoid/attributes/nested_spec.rb +3 -0
- data/spec/mongoid/attributes/readonly_spec.rb +3 -0
- data/spec/mongoid/attributes_spec.rb +3 -0
- data/spec/mongoid/cacheable_spec.rb +3 -0
- data/spec/mongoid/changeable_spec.rb +26 -0
- data/spec/mongoid/clients/factory_spec.rb +38 -20
- data/spec/mongoid/clients/options_spec.rb +26 -15
- data/spec/mongoid/clients/sessions_spec.rb +11 -4
- data/spec/mongoid/clients/transactions_spec.rb +26 -11
- data/spec/mongoid/clients_spec.rb +5 -2
- data/spec/mongoid/composable_spec.rb +3 -0
- data/spec/mongoid/config/environment_spec.rb +3 -0
- data/spec/mongoid/config/options_spec.rb +23 -3
- data/spec/mongoid/config_spec.rb +39 -0
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +3 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +3 -0
- data/spec/mongoid/contextual/atomic_spec.rb +120 -10
- data/spec/mongoid/contextual/geo_near_spec.rb +3 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +23 -5
- data/spec/mongoid/contextual/memory_spec.rb +3 -0
- data/spec/mongoid/contextual/mongo_spec.rb +81 -53
- data/spec/mongoid/contextual/none_spec.rb +3 -0
- data/spec/mongoid/copyable_spec.rb +3 -0
- data/spec/mongoid/copyable_spec_models.rb +3 -0
- data/spec/mongoid/criteria/findable_spec.rb +58 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +3 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +3 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +7 -3
- data/spec/mongoid/criteria/options_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +135 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +36 -17
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +10 -7
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -1
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +24 -16
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +48 -12
- data/spec/mongoid/criteria/queryable/optional_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1348 -281
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +996 -2159
- data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +3 -0
- data/spec/mongoid/criteria/queryable/storable_spec.rb +190 -0
- data/spec/mongoid/criteria/scopable_spec.rb +3 -0
- data/spec/mongoid/criteria_spec.rb +73 -2
- data/spec/mongoid/document_persistence_context_spec.rb +33 -0
- data/spec/mongoid/document_query_spec.rb +39 -0
- data/spec/mongoid/document_spec.rb +3 -0
- data/spec/mongoid/equality_spec.rb +3 -0
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +6 -3
- data/spec/mongoid/errors/callback_spec.rb +3 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +3 -0
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +3 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +3 -0
- data/spec/mongoid/errors/eager_load_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_collection_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_includes_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_index_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_options_spec.rb +5 -2
- data/spec/mongoid/errors/invalid_path_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_relation_spec.rb +5 -2
- data/spec/mongoid/errors/invalid_scope_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -0
- data/spec/mongoid/errors/invalid_time_spec.rb +3 -0
- data/spec/mongoid/errors/inverse_not_found_spec.rb +4 -1
- data/spec/mongoid/errors/mixed_client_configuration_spec.rb +3 -0
- data/spec/mongoid/errors/mixed_relations_spec.rb +3 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +3 -0
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -3
- data/spec/mongoid/errors/no_client_config_spec.rb +3 -0
- data/spec/mongoid/errors/no_client_database_spec.rb +3 -0
- data/spec/mongoid/errors/no_client_hosts_spec.rb +3 -0
- data/spec/mongoid/errors/no_clients_config_spec.rb +3 -0
- data/spec/mongoid/errors/no_environment_spec.rb +3 -0
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -0
- data/spec/mongoid/errors/no_metadata_spec.rb +5 -2
- data/spec/mongoid/errors/no_parent_spec.rb +4 -1
- data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -0
- data/spec/mongoid/errors/readonly_document_spec.rb +3 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -0
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -0
- data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -0
- data/spec/mongoid/errors/unsaved_document_spec.rb +4 -1
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -0
- data/spec/mongoid/errors/validations_spec.rb +3 -0
- data/spec/mongoid/extensions/array_spec.rb +26 -43
- data/spec/mongoid/extensions/big_decimal_spec.rb +3 -0
- data/spec/mongoid/extensions/binary_spec.rb +3 -0
- data/spec/mongoid/extensions/boolean_spec.rb +3 -0
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +336 -0
- data/spec/mongoid/extensions/date_spec.rb +9 -160
- data/spec/mongoid/extensions/date_time_spec.rb +18 -60
- data/spec/mongoid/extensions/decimal128_spec.rb +3 -0
- data/spec/mongoid/extensions/false_class_spec.rb +3 -0
- data/spec/mongoid/extensions/float_spec.rb +18 -3
- data/spec/mongoid/extensions/hash_spec.rb +106 -0
- data/spec/mongoid/extensions/integer_spec.rb +15 -2
- data/spec/mongoid/extensions/module_spec.rb +3 -0
- data/spec/mongoid/extensions/nil_class_spec.rb +3 -0
- data/spec/mongoid/extensions/object_id_spec.rb +3 -0
- data/spec/mongoid/extensions/object_spec.rb +14 -24
- data/spec/mongoid/extensions/range_spec.rb +3 -0
- data/spec/mongoid/extensions/regexp_spec.rb +3 -0
- data/spec/mongoid/extensions/set_spec.rb +3 -0
- data/spec/mongoid/extensions/string_spec.rb +60 -26
- data/spec/mongoid/extensions/symbol_spec.rb +3 -0
- data/spec/mongoid/extensions/time_spec.rb +30 -0
- data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -0
- data/spec/mongoid/extensions/true_class_spec.rb +3 -0
- data/spec/mongoid/extensions_spec.rb +3 -0
- data/spec/mongoid/factory_spec.rb +27 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +3 -0
- data/spec/mongoid/fields/localized_spec.rb +3 -0
- data/spec/mongoid/fields/standard_spec.rb +3 -0
- data/spec/mongoid/fields_spec.rb +18 -0
- data/spec/mongoid/findable_spec.rb +3 -0
- data/spec/mongoid/indexable/specification_spec.rb +3 -0
- data/spec/mongoid/indexable_spec.rb +9 -4
- data/spec/mongoid/inspectable_spec.rb +3 -0
- data/spec/mongoid/interceptable_spec.rb +65 -0
- data/spec/mongoid/interceptable_spec_models.rb +76 -0
- data/spec/mongoid/loggable_spec.rb +3 -0
- data/spec/mongoid/matchable/all_spec.rb +3 -0
- data/spec/mongoid/matchable/and_spec.rb +3 -0
- data/spec/mongoid/matchable/default_spec.rb +4 -1
- data/spec/mongoid/matchable/elem_match_spec.rb +3 -0
- data/spec/mongoid/matchable/eq_spec.rb +1 -0
- data/spec/mongoid/matchable/exists_spec.rb +3 -0
- data/spec/mongoid/matchable/gt_spec.rb +3 -0
- data/spec/mongoid/matchable/gte_spec.rb +3 -0
- data/spec/mongoid/matchable/in_spec.rb +3 -0
- data/spec/mongoid/matchable/lt_spec.rb +3 -0
- data/spec/mongoid/matchable/lte_spec.rb +3 -0
- data/spec/mongoid/matchable/ne_spec.rb +3 -0
- data/spec/mongoid/matchable/nin_spec.rb +3 -0
- data/spec/mongoid/matchable/nor_spec.rb +1 -0
- data/spec/mongoid/matchable/or_spec.rb +3 -0
- data/spec/mongoid/matchable/regexp_spec.rb +5 -2
- data/spec/mongoid/matchable/size_spec.rb +3 -0
- data/spec/mongoid/matchable_spec.rb +5 -2
- data/spec/mongoid/persistable/creatable_spec.rb +3 -0
- data/spec/mongoid/persistable/deletable_spec.rb +3 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +3 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +17 -0
- data/spec/mongoid/persistable/logical_spec.rb +17 -0
- data/spec/mongoid/persistable/poppable_spec.rb +17 -0
- data/spec/mongoid/persistable/pullable_spec.rb +31 -0
- data/spec/mongoid/persistable/pushable_spec.rb +86 -1
- data/spec/mongoid/persistable/renamable_spec.rb +17 -0
- data/spec/mongoid/persistable/savable_spec.rb +3 -0
- data/spec/mongoid/persistable/settable_spec.rb +17 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +17 -0
- data/spec/mongoid/persistable/updatable_spec.rb +3 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +3 -0
- data/spec/mongoid/persistable_spec.rb +85 -8
- data/spec/mongoid/persistence_context_spec.rb +3 -0
- data/spec/mongoid/positional_spec.rb +3 -0
- data/spec/mongoid/query_cache_middleware_spec.rb +48 -0
- data/spec/mongoid/query_cache_spec.rb +5 -45
- data/spec/mongoid/relations/proxy_spec.rb +4 -1
- data/spec/mongoid/reloadable_spec.rb +3 -0
- data/spec/mongoid/scopable_spec.rb +5 -1
- data/spec/mongoid/selectable_spec.rb +3 -0
- data/spec/mongoid/serializable_spec.rb +132 -18
- data/spec/mongoid/shardable_models.rb +61 -0
- data/spec/mongoid/shardable_spec.rb +72 -16
- data/spec/mongoid/stateful_spec.rb +3 -0
- data/spec/mongoid/tasks/database_rake_spec.rb +16 -13
- data/spec/mongoid/tasks/database_spec.rb +4 -1
- data/spec/mongoid/threaded_spec.rb +3 -0
- data/spec/mongoid/timestamps/created/short_spec.rb +3 -0
- data/spec/mongoid/timestamps/created_spec.rb +3 -0
- data/spec/mongoid/timestamps/timeless_spec.rb +3 -0
- data/spec/mongoid/timestamps/updated/short_spec.rb +3 -0
- data/spec/mongoid/timestamps/updated_spec.rb +3 -0
- data/spec/mongoid/timestamps_spec.rb +3 -0
- data/spec/mongoid/touchable_spec.rb +49 -3
- data/spec/mongoid/traversable_spec.rb +3 -0
- data/spec/mongoid/validatable/associated_spec.rb +3 -0
- data/spec/mongoid/validatable/format_spec.rb +3 -0
- data/spec/mongoid/validatable/length_spec.rb +3 -0
- data/spec/mongoid/validatable/numericality_spec.rb +3 -0
- data/spec/mongoid/validatable/presence_spec.rb +3 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +3 -0
- data/spec/mongoid/validatable_spec.rb +3 -0
- data/spec/mongoid_spec.rb +3 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +4 -1
- data/spec/rails/mongoid_spec.rb +5 -2
- data/spec/spec_helper.rb +21 -44
- data/spec/support/authorization.rb +3 -0
- data/spec/support/child_process_helper.rb +76 -0
- data/spec/support/cluster_config.rb +3 -3
- data/spec/support/constraints.rb +185 -30
- data/spec/support/expectations.rb +6 -1
- data/spec/support/helpers.rb +11 -0
- data/spec/support/lite_constraints.rb +22 -0
- data/spec/support/macros.rb +1 -0
- data/spec/support/shared/time.rb +54 -0
- data/spec/support/spec_config.rb +15 -4
- metadata +544 -472
- metadata.gz.sig +0 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
1
4
|
require "spec_helper"
|
|
2
5
|
|
|
3
6
|
describe String do
|
|
@@ -315,7 +318,7 @@ describe String do
|
|
|
315
318
|
context "when provided a regex" do
|
|
316
319
|
|
|
317
320
|
let(:regex) do
|
|
318
|
-
|
|
321
|
+
/\A[123]/.freeze
|
|
319
322
|
end
|
|
320
323
|
|
|
321
324
|
let(:evolved) do
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "lite_spec_helper"
|
|
2
5
|
|
|
3
6
|
describe Time do
|
|
4
7
|
|
|
@@ -8,22 +11,27 @@ describe Time do
|
|
|
8
11
|
|
|
9
12
|
context "when the time is not in utc" do
|
|
10
13
|
|
|
11
|
-
let(:
|
|
12
|
-
Time.new(2010, 1, 1,
|
|
14
|
+
let(:time) do
|
|
15
|
+
Time.new(2010, 1, 1, 14, 0, 0, '+02:00')
|
|
13
16
|
end
|
|
14
17
|
|
|
15
18
|
let(:evolved) do
|
|
16
|
-
described_class.evolve(
|
|
19
|
+
described_class.evolve(time)
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
let(:expected) do
|
|
20
|
-
Time.new(2010, 1, 1, 12, 0, 0)
|
|
23
|
+
Time.new(2010, 1, 1, 12, 0, 0, '+00:00')
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
it "returns the same time" do
|
|
24
27
|
expect(evolved).to eq(expected)
|
|
25
28
|
end
|
|
26
29
|
|
|
30
|
+
it 'does not mutate original time' do
|
|
31
|
+
described_class.evolve(time)
|
|
32
|
+
expect(time.utc_offset).to eq(7200)
|
|
33
|
+
end
|
|
34
|
+
|
|
27
35
|
it "returns the time in utc" do
|
|
28
36
|
expect(evolved.utc_offset).to eq(0)
|
|
29
37
|
end
|
|
@@ -31,12 +39,12 @@ describe Time do
|
|
|
31
39
|
|
|
32
40
|
context "when the time is already utc" do
|
|
33
41
|
|
|
34
|
-
let(:
|
|
42
|
+
let(:time) do
|
|
35
43
|
Time.new(2010, 1, 1, 12, 0, 0).utc
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
let(:evolved) do
|
|
39
|
-
described_class.evolve(
|
|
47
|
+
described_class.evolve(time)
|
|
40
48
|
end
|
|
41
49
|
|
|
42
50
|
let(:expected) do
|
|
@@ -57,12 +65,12 @@ describe Time do
|
|
|
57
65
|
|
|
58
66
|
context "when the array is composed of times" do
|
|
59
67
|
|
|
60
|
-
let(:
|
|
68
|
+
let(:time) do
|
|
61
69
|
Time.new(2010, 1, 1, 12, 0, 0)
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
let(:evolved) do
|
|
65
|
-
described_class.evolve([
|
|
73
|
+
described_class.evolve([ time ])
|
|
66
74
|
end
|
|
67
75
|
|
|
68
76
|
let(:expected) do
|
|
@@ -80,16 +88,16 @@ describe Time do
|
|
|
80
88
|
|
|
81
89
|
context "when the array is composed of strings" do
|
|
82
90
|
|
|
83
|
-
let(:
|
|
91
|
+
let(:time) do
|
|
84
92
|
Time.parse("1st Jan 2010 12:00:00+01:00")
|
|
85
93
|
end
|
|
86
94
|
|
|
87
95
|
let(:evolved) do
|
|
88
|
-
described_class.evolve([
|
|
96
|
+
described_class.evolve([ time.to_s ])
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
it "returns the strings as a times" do
|
|
92
|
-
expect(evolved).to eq([
|
|
100
|
+
expect(evolved).to eq([ time.to_time ])
|
|
93
101
|
end
|
|
94
102
|
|
|
95
103
|
it "returns the times in utc" do
|
|
@@ -146,7 +154,7 @@ describe Time do
|
|
|
146
154
|
|
|
147
155
|
context "when provided a range" do
|
|
148
156
|
|
|
149
|
-
context "when the range are
|
|
157
|
+
context "when the range are times" do
|
|
150
158
|
|
|
151
159
|
let(:min) do
|
|
152
160
|
Time.new(2010, 1, 1, 12, 0, 0)
|
|
@@ -273,16 +281,16 @@ describe Time do
|
|
|
273
281
|
|
|
274
282
|
context "when provided a string" do
|
|
275
283
|
|
|
276
|
-
let(:
|
|
284
|
+
let(:time) do
|
|
277
285
|
Time.parse("1st Jan 2010 12:00:00+01:00")
|
|
278
286
|
end
|
|
279
287
|
|
|
280
288
|
let(:evolved) do
|
|
281
|
-
described_class.evolve(
|
|
289
|
+
described_class.evolve(time.to_s)
|
|
282
290
|
end
|
|
283
291
|
|
|
284
292
|
it "returns the string as a time" do
|
|
285
|
-
expect(evolved).to eq(
|
|
293
|
+
expect(evolved).to eq(time.to_time)
|
|
286
294
|
end
|
|
287
295
|
|
|
288
296
|
it "returns the time in utc" do
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
1
4
|
require "spec_helper"
|
|
2
5
|
|
|
3
6
|
describe Mongoid::Criteria::Queryable::Mergeable do
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
let(:query) do
|
|
9
|
+
Mongoid::Query.new
|
|
10
|
+
end
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
Mongoid::Query.new
|
|
9
|
-
end
|
|
12
|
+
describe "#intersect" do
|
|
10
13
|
|
|
11
14
|
before do
|
|
12
15
|
query.intersect
|
|
@@ -19,10 +22,6 @@ describe Mongoid::Criteria::Queryable::Mergeable do
|
|
|
19
22
|
|
|
20
23
|
describe "#override" do
|
|
21
24
|
|
|
22
|
-
let(:query) do
|
|
23
|
-
Mongoid::Query.new
|
|
24
|
-
end
|
|
25
|
-
|
|
26
25
|
before do
|
|
27
26
|
query.override
|
|
28
27
|
end
|
|
@@ -34,10 +33,6 @@ describe Mongoid::Criteria::Queryable::Mergeable do
|
|
|
34
33
|
|
|
35
34
|
describe "#union" do
|
|
36
35
|
|
|
37
|
-
let(:query) do
|
|
38
|
-
Mongoid::Query.new
|
|
39
|
-
end
|
|
40
|
-
|
|
41
36
|
before do
|
|
42
37
|
query.union
|
|
43
38
|
end
|
|
@@ -46,4 +41,45 @@ describe Mongoid::Criteria::Queryable::Mergeable do
|
|
|
46
41
|
expect(query.strategy).to eq(:__union__)
|
|
47
42
|
end
|
|
48
43
|
end
|
|
44
|
+
|
|
45
|
+
describe '#_mongoid_expand_keys' do
|
|
46
|
+
it 'expands simple keys' do
|
|
47
|
+
query.send(:_mongoid_expand_keys, {a: 1}).should == {a: 1}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
let(:gt) do
|
|
51
|
+
Mongoid::Criteria::Queryable::Key.new("age", :__override__, "$gt")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
let(:gtp) do
|
|
55
|
+
Mongoid::Criteria::Queryable::Key.new("age", :__override__, "$gt")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
let(:lt) do
|
|
59
|
+
Mongoid::Criteria::Queryable::Key.new("age", :__override__, "$lt")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'expands Key instances' do
|
|
63
|
+
query.send(:_mongoid_expand_keys, {gt => 42}).should == {'age' => {'$gt' => 42}}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'expands multiple Key instances on the same field' do
|
|
67
|
+
query.send(:_mongoid_expand_keys, {gt => 42, lt => 50}).should == {
|
|
68
|
+
'age' => {'$gt' => 42, '$lt' => 50}}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'expands simple and Key instances on the same field' do
|
|
72
|
+
query.send(:_mongoid_expand_keys, {'age' => 42, lt => 50}).should == {
|
|
73
|
+
'age' => {'$eq' => 42, '$lt' => 50}}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'expands Key and simple instances on the same field' do
|
|
77
|
+
query.send(:_mongoid_expand_keys, {gt => 42, 'age' => 50}).should == {
|
|
78
|
+
'age' => {'$gt' => 42, '$eq' => 50}}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'Ruby does not allow same symbol operator with different values' do
|
|
82
|
+
{gt => 42, gtp => 50}.should == {gtp => 50}
|
|
83
|
+
end
|
|
84
|
+
end
|
|
49
85
|
end
|
|
@@ -9,8 +9,292 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
9
9
|
Mongoid::Query.new("id" => "_id")
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
shared_examples_for 'returns a cloned query' do
|
|
13
|
+
|
|
14
|
+
it "returns a cloned query" do
|
|
15
|
+
expect(selection).to_not equal(query)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Hoisting means the operator can be elided, for example
|
|
20
|
+
# Foo.and(a: 1) produces simply {'a' => 1}.
|
|
21
|
+
shared_examples_for 'a hoisting logical operation' do
|
|
22
|
+
|
|
23
|
+
let(:query) do
|
|
24
|
+
Mongoid::Query.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "when provided a single criterion" do
|
|
28
|
+
|
|
29
|
+
shared_examples_for 'adds the conditions to top level' do
|
|
30
|
+
|
|
31
|
+
it "adds the conditions to top level" do
|
|
32
|
+
expect(selection.selector).to eq(
|
|
33
|
+
"field" => [ 1, 2 ]
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it_behaves_like 'returns a cloned query'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
let(:selection) do
|
|
41
|
+
query.send(tested_method, field: [ 1, 2 ])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it_behaves_like 'adds the conditions to top level'
|
|
45
|
+
|
|
46
|
+
context 'when the criterion is wrapped in an array' do
|
|
47
|
+
let(:selection) do
|
|
48
|
+
query.send(tested_method, [{field: [ 1, 2 ] }])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it_behaves_like 'adds the conditions to top level'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when the criterion is wrapped in a deep array with nil elements' do
|
|
55
|
+
let(:selection) do
|
|
56
|
+
query.send(tested_method, [[[{field: [ 1, 2 ] }]], [nil]])
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it_behaves_like 'adds the conditions to top level'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'when argument is a Criteria' do
|
|
64
|
+
let(:base) do
|
|
65
|
+
query.where(hello: 'world')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
let(:other) do
|
|
69
|
+
query.where(foo: 'bar')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
let(:result) { base.send(tested_method, other) }
|
|
73
|
+
|
|
74
|
+
it 'combines' do
|
|
75
|
+
expect(result.selector).to eq(
|
|
76
|
+
'hello' => 'world',
|
|
77
|
+
'foo' => 'bar',
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "when provided a single criterion that is handled via Key" do
|
|
83
|
+
|
|
84
|
+
shared_examples_for 'adds the conditions to top level' do
|
|
85
|
+
|
|
86
|
+
it "adds the conditions to top level" do
|
|
87
|
+
expect(selection.selector).to eq({
|
|
88
|
+
"field" => {'$gt' => 3},
|
|
89
|
+
})
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it_behaves_like 'returns a cloned query'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
let(:selection) do
|
|
96
|
+
query.send(tested_method, :field.gt => 3)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it_behaves_like 'adds the conditions to top level'
|
|
100
|
+
|
|
101
|
+
context 'when the criterion is wrapped in an array' do
|
|
102
|
+
let(:selection) do
|
|
103
|
+
query.send(tested_method, [{ :field.gt => 3 }])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it_behaves_like 'adds the conditions to top level'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context 'when the criterion is wrapped in a deep array with nil elements' do
|
|
110
|
+
let(:selection) do
|
|
111
|
+
query.send(tested_method, [[[{ :field.gt => 3 }]], [nil]])
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it_behaves_like 'adds the conditions to top level'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context 'when the criterion is a time' do
|
|
118
|
+
let(:selection) do
|
|
119
|
+
query.send(tested_method, :field.gte => Time.new(2020, 1, 1))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'adds the conditions' do
|
|
123
|
+
expect(selection.selector).to eq({
|
|
124
|
+
"field" => {'$gte' => Time.new(2020, 1, 1)},
|
|
125
|
+
})
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'keeps argument type' do
|
|
129
|
+
selection.selector['field']['$gte'].should be_a(Time)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context 'when the criterion is a datetime' do
|
|
134
|
+
let(:selection) do
|
|
135
|
+
query.send(tested_method, :field.gte => DateTime.new(2020, 1, 1))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'adds the conditions' do
|
|
139
|
+
expect(selection.selector).to eq({
|
|
140
|
+
"field" => {'$gte' => Time.utc(2020, 1, 1)},
|
|
141
|
+
})
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'converts argument to a time' do
|
|
145
|
+
selection.selector['field']['$gte'].should be_a(Time)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context 'when the criterion is a date' do
|
|
150
|
+
let(:selection) do
|
|
151
|
+
query.send(tested_method, :field.gte => Date.new(2020, 1, 1))
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'adds the conditions' do
|
|
155
|
+
expect(selection.selector).to eq({
|
|
156
|
+
"field" => {'$gte' => Time.utc(2020, 1, 1)},
|
|
157
|
+
})
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it 'converts argument to a time' do
|
|
161
|
+
selection.selector['field']['$gte'].should be_a(Time)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
context "when provided a nested criterion" do
|
|
167
|
+
|
|
168
|
+
let(:selection) do
|
|
169
|
+
query.send(tested_method, :test.elem_match => { :field.in => [ 1, 2 ] })
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "builds the correct selector" do
|
|
173
|
+
expect(selection.selector).to eq({
|
|
174
|
+
"test" => { "$elemMatch" => { "field" => { "$in" => [ 1, 2 ] }}}
|
|
175
|
+
})
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it_behaves_like 'returns a cloned query'
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context "when chaining the criteria" do
|
|
182
|
+
|
|
183
|
+
context "when the criteria are for different fields" do
|
|
184
|
+
|
|
185
|
+
let(:selection) do
|
|
186
|
+
query.and(first: [ 1, 2 ]).send(tested_method, second: [ 3, 4 ])
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "adds the conditions to top level" do
|
|
190
|
+
expect(selection.selector).to eq({
|
|
191
|
+
"first" => [ 1, 2 ],
|
|
192
|
+
"second" => [ 3, 4 ],
|
|
193
|
+
})
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it_behaves_like 'returns a cloned query'
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context "when the criteria are on the same field" do
|
|
200
|
+
|
|
201
|
+
let(:selection) do
|
|
202
|
+
query.and(first: [ 1, 2 ]).send(tested_method, first: [ 3, 4 ])
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "combines via $and operator" do
|
|
206
|
+
expect(selection.selector).to eq({
|
|
207
|
+
"first" => [ 1, 2 ],
|
|
208
|
+
"$and" => [
|
|
209
|
+
{ "first" => [ 3, 4 ] }
|
|
210
|
+
]
|
|
211
|
+
})
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it_behaves_like 'returns a cloned query'
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Non-hoisting means the operator is always present, for example
|
|
220
|
+
# Foo.or(a: 1) produces {'$or' => [{'a' => 1}]}.
|
|
221
|
+
shared_examples_for 'a non-hoisting logical operation' do
|
|
222
|
+
|
|
223
|
+
context 'when there is a single predicate' do
|
|
224
|
+
let(:query) do
|
|
225
|
+
Mongoid::Query.new.send(tested_method, hello: 'world')
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it 'adds the predicate' do
|
|
229
|
+
expect(query.selector).to eq(expected_operator => [{'hello' => 'world'}])
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context 'when the single predicate is wrapped in an array' do
|
|
234
|
+
let(:query) do
|
|
235
|
+
Mongoid::Query.new.send(tested_method, [{hello: 'world'}])
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it 'adds the predicate' do
|
|
239
|
+
expect(query.selector).to eq(expected_operator => [{'hello' => 'world'}])
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
context 'when argument is a Criteria' do
|
|
244
|
+
let(:query) do
|
|
245
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
let(:other) do
|
|
249
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
let(:result) { query.send(tested_method, other) }
|
|
253
|
+
|
|
254
|
+
it 'combines' do
|
|
255
|
+
# This is used for $or / $nor, the two conditions should remain
|
|
256
|
+
# as separate hashes
|
|
257
|
+
expect(result.selector).to eq(expected_operator => [{'hello' => 'world'}, {'foo' => 'bar'}])
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
context 'when argument is a mix of Criteria and hashes' do
|
|
262
|
+
let(:query) do
|
|
263
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
let(:other1) do
|
|
267
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
let(:other2) do
|
|
271
|
+
{bar: 42}
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
let(:other3) do
|
|
275
|
+
Mongoid::Query.new.where(a: 2)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
let(:result) { query.send(tested_method, other1, other2, other3) }
|
|
279
|
+
|
|
280
|
+
it 'combines' do
|
|
281
|
+
expect(result.selector).to eq(expected_operator => [
|
|
282
|
+
{'hello' => 'world'},
|
|
283
|
+
{'foo' => 'bar'},
|
|
284
|
+
{'bar' => 42},
|
|
285
|
+
{'a' => 2},
|
|
286
|
+
])
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
12
291
|
describe "#and" do
|
|
13
292
|
|
|
293
|
+
let(:tested_method) { :and }
|
|
294
|
+
let(:expected_operator) { '$and' }
|
|
295
|
+
|
|
296
|
+
it_behaves_like 'a hoisting logical operation'
|
|
297
|
+
|
|
14
298
|
context "when provided no criterion" do
|
|
15
299
|
|
|
16
300
|
let(:selection) do
|
|
@@ -25,9 +309,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
25
309
|
expect(selection).to eq(query)
|
|
26
310
|
end
|
|
27
311
|
|
|
28
|
-
|
|
29
|
-
expect(selection).to_not equal(query)
|
|
30
|
-
end
|
|
312
|
+
it_behaves_like 'returns a cloned query'
|
|
31
313
|
end
|
|
32
314
|
|
|
33
315
|
context "when provided nil" do
|
|
@@ -44,103 +326,669 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
44
326
|
expect(selection).to eq(query)
|
|
45
327
|
end
|
|
46
328
|
|
|
47
|
-
|
|
48
|
-
|
|
329
|
+
it_behaves_like 'returns a cloned query'
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
context "when provided multiple criteria" do
|
|
333
|
+
|
|
334
|
+
context "when the criterion is already included" do
|
|
335
|
+
|
|
336
|
+
context 'simple criterion' do
|
|
337
|
+
let(:selection) do
|
|
338
|
+
query.and({ first: [ 1, 2 ] }).and({ first: [ 1, 2 ] })
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it "adds all conditions" do
|
|
342
|
+
expect(selection.selector).to eq({
|
|
343
|
+
'first' => [1, 2],
|
|
344
|
+
"$and" => [
|
|
345
|
+
{ "first" => [ 1, 2 ] }
|
|
346
|
+
]
|
|
347
|
+
})
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it_behaves_like 'returns a cloned query'
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
context 'Key criterion' do
|
|
354
|
+
let(:selection) do
|
|
355
|
+
query.and({ first: [ 1, 2 ] }).and(:first.gt => 3)
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
it "adds all conditions" do
|
|
359
|
+
expect(selection.selector).to eq({
|
|
360
|
+
'first' => [1, 2],
|
|
361
|
+
"$and" => [
|
|
362
|
+
{ "first" => {'$gt' => 3} }
|
|
363
|
+
]
|
|
364
|
+
})
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it_behaves_like 'returns a cloned query'
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
context 'Key criterion when existing criterion is an operator' do
|
|
371
|
+
let(:selection) do
|
|
372
|
+
query.and(:first.lt => 5).and(:first.gt => 3)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
it "adds all conditions" do
|
|
376
|
+
expect(selection.selector).to eq({
|
|
377
|
+
'first' => {'$lt' => 5, '$gt' => 3},
|
|
378
|
+
})
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it_behaves_like 'returns a cloned query'
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
context "when the new criteria are for different fields" do
|
|
386
|
+
|
|
387
|
+
let(:selection) do
|
|
388
|
+
query.and({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "adds all conditions to top level" do
|
|
392
|
+
expect(selection.selector).to eq({
|
|
393
|
+
"first" => [ 1, 2 ],
|
|
394
|
+
"second" => [ 3, 4 ],
|
|
395
|
+
})
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it_behaves_like 'returns a cloned query'
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
context "when the new criteria are for the same field" do
|
|
402
|
+
|
|
403
|
+
context 'when criteria are simple' do
|
|
404
|
+
let(:selection) do
|
|
405
|
+
query.and({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
it "combines via $and operator" do
|
|
409
|
+
expect(selection.selector).to eq({
|
|
410
|
+
"first" => [ 1, 2 ],
|
|
411
|
+
"$and" => [
|
|
412
|
+
{ "first" => [ 3, 4 ] }
|
|
413
|
+
]
|
|
414
|
+
})
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
it_behaves_like 'returns a cloned query'
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
context 'when criteria are handled via Key' do
|
|
421
|
+
shared_examples_for 'adds the conditions to top level' do
|
|
422
|
+
|
|
423
|
+
it "adds the conditions to top level" do
|
|
424
|
+
expect(selection.selector).to eq({
|
|
425
|
+
"field" => {'$gt' => 3, '$lt' => 5},
|
|
426
|
+
})
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
it_behaves_like 'returns a cloned query'
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
context 'criteria are provided in the same hash' do
|
|
433
|
+
let(:selection) do
|
|
434
|
+
query.send(tested_method, :field.gt => 3, :field.lt => 5)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it_behaves_like 'adds the conditions to top level'
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
context 'criteria are provided in separate hashes' do
|
|
441
|
+
let(:selection) do
|
|
442
|
+
query.send(tested_method, {:field.gt => 3}, {:field.lt => 5})
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
it_behaves_like 'adds the conditions to top level'
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
context 'when the criterion is wrapped in an array' do
|
|
449
|
+
let(:selection) do
|
|
450
|
+
query.send(tested_method, [:field.gt => 3], [:field.lt => 5])
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
it_behaves_like 'adds the conditions to top level'
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
context 'when criteria are simple and handled via Key' do
|
|
458
|
+
shared_examples_for 'combines conditions with $and' do
|
|
459
|
+
|
|
460
|
+
it "combines conditions with $and" do
|
|
461
|
+
expect(selection.selector).to eq({
|
|
462
|
+
"field" => 3,
|
|
463
|
+
'$and' => ['field' => {'$lt' => 5}],
|
|
464
|
+
})
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it_behaves_like 'returns a cloned query'
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
context 'criteria are provided in the same hash' do
|
|
471
|
+
let(:selection) do
|
|
472
|
+
query.send(tested_method, :field => 3, :field.lt => 5)
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it_behaves_like 'combines conditions with $and'
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
context 'criteria are provided in separate hashes' do
|
|
479
|
+
let(:selection) do
|
|
480
|
+
query.send(tested_method, {:field => 3}, {:field.lt => 5})
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it_behaves_like 'combines conditions with $and'
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
context 'when the criterion is wrapped in an array' do
|
|
487
|
+
let(:selection) do
|
|
488
|
+
query.send(tested_method, [:field => 3], [:field.lt => 5])
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it_behaves_like 'combines conditions with $and'
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
context 'when criteria are handled via Key and simple' do
|
|
496
|
+
shared_examples_for 'combines conditions with $and' do
|
|
497
|
+
|
|
498
|
+
it "combines conditions with $and" do
|
|
499
|
+
expect(selection.selector).to eq({
|
|
500
|
+
"field" => {'$gt' => 3},
|
|
501
|
+
'$and' => ['field' => 5],
|
|
502
|
+
})
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it_behaves_like 'returns a cloned query'
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
context 'criteria are provided in the same hash' do
|
|
509
|
+
let(:selection) do
|
|
510
|
+
query.send(tested_method, :field.gt => 3, :field => 5)
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
it_behaves_like 'combines conditions with $and'
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
context 'criteria are provided in separate hashes' do
|
|
517
|
+
let(:selection) do
|
|
518
|
+
query.send(tested_method, {:field.gt => 3}, {:field => 5})
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
it_behaves_like 'combines conditions with $and'
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
context 'when the criterion is wrapped in an array' do
|
|
525
|
+
let(:selection) do
|
|
526
|
+
query.send(tested_method, [:field.gt => 3], [:field => 5])
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it_behaves_like 'combines conditions with $and'
|
|
530
|
+
end
|
|
531
|
+
end
|
|
49
532
|
end
|
|
50
533
|
end
|
|
51
534
|
|
|
52
|
-
context
|
|
535
|
+
context 'when argument is a Criteria' do
|
|
536
|
+
let(:query) do
|
|
537
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
let(:result) { query.and(other) }
|
|
541
|
+
|
|
542
|
+
context 'different fields' do
|
|
543
|
+
|
|
544
|
+
let(:other) do
|
|
545
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
it 'combines both fields at top level' do
|
|
549
|
+
expect(result.selector).to eq('hello' => 'world', 'foo' => 'bar')
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
context 'same field' do
|
|
554
|
+
|
|
555
|
+
let(:other) do
|
|
556
|
+
Mongoid::Query.new.where(hello: /bar/)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it 'combines fields with $and' do
|
|
560
|
+
expect(result.selector).to eq('hello' => 'world', '$and' => [{'hello' => /bar/}])
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
context 'when argument is a mix of Criteria and hashes' do
|
|
566
|
+
let(:query) do
|
|
567
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
let(:other1) do
|
|
571
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
let(:other2) do
|
|
575
|
+
{bar: 42}
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
let(:other3) do
|
|
579
|
+
Mongoid::Query.new.where(a: 2)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
let(:result) { query.and(other1, other2, other3) }
|
|
583
|
+
|
|
584
|
+
it 'combines' do
|
|
585
|
+
expect(result.selector).to eq('hello' => 'world',
|
|
586
|
+
'foo' => 'bar',
|
|
587
|
+
'bar' => 42,
|
|
588
|
+
'a' => 2,
|
|
589
|
+
)
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
context 'when Key instances are used and types involved have serializers' do
|
|
594
|
+
let(:time) { Time.now }
|
|
595
|
+
|
|
596
|
+
let(:query) do
|
|
597
|
+
Band.all.and(:created_at.gt => time)
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
let(:expected) do
|
|
601
|
+
{'created_at' => {'$gt' => time.utc}}
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
it 'combines and evolves' do
|
|
605
|
+
expect(query.selector).to eq(expected)
|
|
606
|
+
end
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
describe 'query shape' do
|
|
610
|
+
shared_examples_for 'adds most recent criterion as $and' do
|
|
611
|
+
let(:selector) { scope.selector }
|
|
612
|
+
|
|
613
|
+
it 'adds most recent criterion as $and' do
|
|
614
|
+
expect(selector).to eq('foo' => 1, '$and' => [{'foo' => 2}])
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
context 'and/and' do
|
|
619
|
+
let(:scope) do
|
|
620
|
+
Band.and(foo: 1).and(foo: 2)
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
it_behaves_like 'adds most recent criterion as $and'
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
context 'and/and' do
|
|
627
|
+
let(:scope) do
|
|
628
|
+
Band.and(foo: 1).and(foo: 2)
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
it_behaves_like 'adds most recent criterion as $and'
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
context 'and/where' do
|
|
635
|
+
let(:scope) do
|
|
636
|
+
Band.and(foo: 1).where(foo: 2)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
it_behaves_like 'adds most recent criterion as $and'
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
context 'where/and' do
|
|
643
|
+
let(:scope) do
|
|
644
|
+
Band.where(foo: 1).and(foo: 2)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
it_behaves_like 'adds most recent criterion as $and'
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
context 'where/where' do
|
|
651
|
+
let(:scope) do
|
|
652
|
+
Band.where(foo: 1).where(foo: 2)
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
it_behaves_like 'adds most recent criterion as $and'
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
context 'when conditions already exist in criteria' do
|
|
660
|
+
let(:base_selection) do
|
|
661
|
+
query.where(foo: 'bar')
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
context 'when hash conditions are given' do
|
|
665
|
+
let(:selection) do
|
|
666
|
+
base_selection.and(hello: 'world')
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
it 'adds new conditions to top level' do
|
|
670
|
+
selection.selector.should == {
|
|
671
|
+
'foo' => 'bar',
|
|
672
|
+
'hello' => 'world',
|
|
673
|
+
}
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
context 'when criteria conditions are given' do
|
|
678
|
+
let(:selection) do
|
|
679
|
+
base_selection.and(query.where(hello: 'world'))
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
it 'adds new conditions to top level' do
|
|
683
|
+
selection.selector.should == {
|
|
684
|
+
'foo' => 'bar',
|
|
685
|
+
'hello' => 'world',
|
|
686
|
+
}
|
|
687
|
+
end
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
context 'when complex criteria conditions are given' do
|
|
691
|
+
let(:selection) do
|
|
692
|
+
base_selection.and(query.or([one: 'one'], [two: 'two']))
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
it 'adds new conditions to top level' do
|
|
696
|
+
selection.selector.should == {
|
|
697
|
+
'foo' => 'bar',
|
|
698
|
+
'$or' => [
|
|
699
|
+
{'one' => 'one'},
|
|
700
|
+
{'two' => 'two'},
|
|
701
|
+
],
|
|
702
|
+
}
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
shared_examples '$or/$nor' do
|
|
709
|
+
|
|
710
|
+
it_behaves_like 'a non-hoisting logical operation'
|
|
711
|
+
|
|
712
|
+
context "when provided no arguments" do
|
|
53
713
|
|
|
54
714
|
let(:selection) do
|
|
55
|
-
query.
|
|
715
|
+
query.send(tested_method)
|
|
56
716
|
end
|
|
57
717
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
})
|
|
718
|
+
it_behaves_like 'returns a cloned query'
|
|
719
|
+
|
|
720
|
+
it "does not add any criteria" do
|
|
721
|
+
expect(selection.selector).to eq({})
|
|
62
722
|
end
|
|
63
723
|
|
|
64
|
-
it "returns
|
|
65
|
-
expect(selection).
|
|
724
|
+
it "returns the query" do
|
|
725
|
+
expect(selection).to eq(query)
|
|
66
726
|
end
|
|
67
727
|
end
|
|
68
728
|
|
|
69
|
-
context "when provided
|
|
729
|
+
context "when provided nil" do
|
|
70
730
|
|
|
71
731
|
let(:selection) do
|
|
72
|
-
query.
|
|
732
|
+
query.send(tested_method, nil)
|
|
73
733
|
end
|
|
74
734
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
})
|
|
735
|
+
it_behaves_like 'returns a cloned query'
|
|
736
|
+
|
|
737
|
+
it "does not add any criteria" do
|
|
738
|
+
expect(selection.selector).to eq({})
|
|
79
739
|
end
|
|
80
740
|
|
|
81
|
-
it "returns
|
|
82
|
-
expect(selection).
|
|
741
|
+
it "returns the query" do
|
|
742
|
+
expect(selection).to eq(query)
|
|
83
743
|
end
|
|
84
744
|
end
|
|
85
745
|
|
|
86
|
-
context "when provided
|
|
746
|
+
context "when provided a single criterion" do
|
|
87
747
|
|
|
88
|
-
|
|
748
|
+
let(:selection) do
|
|
749
|
+
query.send(tested_method, field: [ 1, 2 ])
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
it_behaves_like 'returns a cloned query'
|
|
753
|
+
|
|
754
|
+
it "adds the $or/$nor selector" do
|
|
755
|
+
expect(selection.selector).to eq({
|
|
756
|
+
expected_operator => [{ "field" => [ 1, 2 ] }]
|
|
757
|
+
})
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
context 'when the criterion is wrapped in array' do
|
|
89
761
|
|
|
90
762
|
let(:selection) do
|
|
91
|
-
query.
|
|
763
|
+
query.send(tested_method, [{ field: [ 1, 2 ] }])
|
|
92
764
|
end
|
|
93
765
|
|
|
94
|
-
|
|
766
|
+
it_behaves_like 'returns a cloned query'
|
|
767
|
+
|
|
768
|
+
it "adds the $or/$nor selector" do
|
|
95
769
|
expect(selection.selector).to eq({
|
|
96
|
-
"
|
|
97
|
-
{ "first" => [ 1, 2 ] }
|
|
98
|
-
]
|
|
770
|
+
expected_operator => [{ "field" => [ 1, 2 ] }]
|
|
99
771
|
})
|
|
100
772
|
end
|
|
101
773
|
|
|
102
|
-
|
|
103
|
-
|
|
774
|
+
context 'when the array has nil as one of the elements' do
|
|
775
|
+
|
|
776
|
+
let(:selection) do
|
|
777
|
+
query.send(tested_method, [{ field: [ 1, 2 ] }, nil])
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
it_behaves_like 'returns a cloned query'
|
|
781
|
+
|
|
782
|
+
it "adds the $or/$nor selector ignoring the nil element" do
|
|
783
|
+
expect(selection.selector).to eq({
|
|
784
|
+
expected_operator => [{ "field" => [ 1, 2 ] }]
|
|
785
|
+
})
|
|
786
|
+
end
|
|
104
787
|
end
|
|
105
788
|
end
|
|
106
789
|
|
|
107
|
-
context
|
|
790
|
+
context 'when query already has a condition on another field' do
|
|
108
791
|
|
|
109
792
|
let(:selection) do
|
|
110
|
-
query.
|
|
793
|
+
query.where(foo: 'bar').send(tested_method, field: [ 1, 2 ])
|
|
111
794
|
end
|
|
112
795
|
|
|
113
|
-
it
|
|
796
|
+
it 'moves original conditions under $or/$nor' do
|
|
114
797
|
expect(selection.selector).to eq({
|
|
115
|
-
"
|
|
798
|
+
expected_operator => [{'foo' => 'bar'}, { "field" => [ 1, 2 ] }]
|
|
799
|
+
})
|
|
800
|
+
end
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
context 'when query already has an $or/$nor condition and another condition' do
|
|
804
|
+
|
|
805
|
+
let(:selection) do
|
|
806
|
+
query.send(tested_method, field: [ 1, 2 ]).where(foo: 'bar').send(tested_method, test: 1)
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it 'unions existing conditions' do
|
|
810
|
+
expect(selection.selector).to eq(
|
|
811
|
+
expected_operator => [
|
|
812
|
+
{
|
|
813
|
+
expected_operator => [{ "field" => [ 1, 2 ] }],
|
|
814
|
+
'foo' => 'bar',
|
|
815
|
+
},
|
|
816
|
+
{'test' => 1},
|
|
817
|
+
]
|
|
818
|
+
)
|
|
819
|
+
end
|
|
820
|
+
end
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
context "when provided multiple criteria" do
|
|
824
|
+
|
|
825
|
+
context "when the criteria are for different fields" do
|
|
826
|
+
|
|
827
|
+
let(:selection) do
|
|
828
|
+
query.send(tested_method, { first: [ 1, 2 ] }, { second: [ 3, 4 ] })
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
it_behaves_like 'returns a cloned query'
|
|
832
|
+
|
|
833
|
+
it "adds the $or/$nor selector" do
|
|
834
|
+
expect(selection.selector).to eq({
|
|
835
|
+
expected_operator => [
|
|
116
836
|
{ "first" => [ 1, 2 ] },
|
|
117
837
|
{ "second" => [ 3, 4 ] }
|
|
118
838
|
]
|
|
119
839
|
})
|
|
120
840
|
end
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
context "when the criteria uses a Key instance" do
|
|
844
|
+
|
|
845
|
+
let(:selection) do
|
|
846
|
+
query.send(tested_method, { first: [ 1, 2 ] }, { :second.gt => 3 })
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
it "adds the $or/$nor selector" do
|
|
850
|
+
expect(selection.selector).to eq({
|
|
851
|
+
expected_operator => [
|
|
852
|
+
{ "first" => [ 1, 2 ] },
|
|
853
|
+
{ "second" => { "$gt" => 3 }}
|
|
854
|
+
]
|
|
855
|
+
})
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
it_behaves_like 'returns a cloned query'
|
|
859
|
+
|
|
860
|
+
context 'when the criterion is a time' do
|
|
861
|
+
let(:selection) do
|
|
862
|
+
query.send(tested_method, :field.gte => Time.new(2020, 1, 1))
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
it 'adds the conditions' do
|
|
866
|
+
expect(selection.selector).to eq(expected_operator => [
|
|
867
|
+
"field" => {'$gte' => Time.new(2020, 1, 1)},
|
|
868
|
+
])
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
it 'keeps the type' do
|
|
872
|
+
selection.selector[expected_operator].first['field']['$gte'].should be_a(Time)
|
|
873
|
+
end
|
|
874
|
+
end
|
|
121
875
|
|
|
122
|
-
|
|
123
|
-
|
|
876
|
+
context 'when the criterion is a datetime' do
|
|
877
|
+
let(:selection) do
|
|
878
|
+
query.send(tested_method, :field.gte => DateTime.new(2020, 1, 1))
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
it 'adds the conditions' do
|
|
882
|
+
expect(selection.selector).to eq(expected_operator => [
|
|
883
|
+
"field" => {'$gte' => Time.utc(2020, 1, 1)},
|
|
884
|
+
])
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
it 'converts argument to a time' do
|
|
888
|
+
selection.selector[expected_operator].first['field']['$gte'].should be_a(Time)
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
context 'when the criterion is a date' do
|
|
893
|
+
let(:selection) do
|
|
894
|
+
query.send(tested_method, :field.gte => Date.new(2020, 1, 1))
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
it 'adds the conditions' do
|
|
898
|
+
expect(selection.selector).to eq(expected_operator => [
|
|
899
|
+
"field" => {'$gte' => Time.utc(2020, 1, 1)},
|
|
900
|
+
])
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
it 'converts argument to a time' do
|
|
904
|
+
selection.selector[expected_operator].first['field']['$gte'].should be_a(Time)
|
|
905
|
+
end
|
|
124
906
|
end
|
|
125
907
|
end
|
|
126
908
|
|
|
127
|
-
context "when
|
|
909
|
+
context "when a criterion has an aliased field" do
|
|
128
910
|
|
|
129
911
|
let(:selection) do
|
|
130
|
-
query.
|
|
912
|
+
query.send(tested_method, { id: 1 })
|
|
131
913
|
end
|
|
132
914
|
|
|
133
|
-
it "
|
|
915
|
+
it "adds the $or/$nor selector and aliases the field" do
|
|
134
916
|
expect(selection.selector).to eq({
|
|
135
|
-
"
|
|
917
|
+
expected_operator => [ { "_id" => 1 } ]
|
|
918
|
+
})
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
it_behaves_like 'returns a cloned query'
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
context "when a criterion is wrapped in an array" do
|
|
925
|
+
|
|
926
|
+
let(:selection) do
|
|
927
|
+
query.send(tested_method, [{ first: [ 1, 2 ] }, { :second.gt => 3 }])
|
|
928
|
+
end
|
|
929
|
+
|
|
930
|
+
it_behaves_like 'returns a cloned query'
|
|
931
|
+
|
|
932
|
+
it "adds the $or/$nor selector" do
|
|
933
|
+
expect(selection.selector).to eq({
|
|
934
|
+
expected_operator => [
|
|
136
935
|
{ "first" => [ 1, 2 ] },
|
|
137
|
-
{ "
|
|
936
|
+
{ "second" => { "$gt" => 3 }}
|
|
138
937
|
]
|
|
139
938
|
})
|
|
140
939
|
end
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
context "when the criteria are on the same field" do
|
|
943
|
+
|
|
944
|
+
context 'simple criteria' do
|
|
945
|
+
let(:selection) do
|
|
946
|
+
query.send(tested_method, { first: [ 1, 2 ] }, { first: [ 3, 4 ] })
|
|
947
|
+
end
|
|
948
|
+
|
|
949
|
+
it_behaves_like 'returns a cloned query'
|
|
950
|
+
|
|
951
|
+
it "appends both $or/$nor expressions" do
|
|
952
|
+
expect(selection.selector).to eq({
|
|
953
|
+
expected_operator => [
|
|
954
|
+
{ "first" => [ 1, 2 ] },
|
|
955
|
+
{ "first" => [ 3, 4 ] }
|
|
956
|
+
]
|
|
957
|
+
})
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
|
|
961
|
+
context 'Key criteria as one argument' do
|
|
962
|
+
let(:selection) do
|
|
963
|
+
query.send(tested_method, :first.gt => 3, :first.lt => 5)
|
|
964
|
+
end
|
|
965
|
+
|
|
966
|
+
it_behaves_like 'returns a cloned query'
|
|
141
967
|
|
|
142
|
-
|
|
143
|
-
|
|
968
|
+
it "adds all criteria" do
|
|
969
|
+
expect(selection.selector).to eq({
|
|
970
|
+
expected_operator => [
|
|
971
|
+
{ "first" => {'$gt' => 3, '$lt' => 5} },
|
|
972
|
+
]
|
|
973
|
+
})
|
|
974
|
+
end
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
context 'Key criteria as multiple arguments' do
|
|
978
|
+
let(:selection) do
|
|
979
|
+
query.send(tested_method, {:first.gt => 3}, {:first.lt => 5})
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
it_behaves_like 'returns a cloned query'
|
|
983
|
+
|
|
984
|
+
it "adds all criteria" do
|
|
985
|
+
expect(selection.selector).to eq({
|
|
986
|
+
expected_operator => [
|
|
987
|
+
{ "first" => {'$gt' => 3} },
|
|
988
|
+
{ "first" => {'$lt' => 5} },
|
|
989
|
+
]
|
|
990
|
+
})
|
|
991
|
+
end
|
|
144
992
|
end
|
|
145
993
|
end
|
|
146
994
|
end
|
|
@@ -150,385 +998,452 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
150
998
|
context "when the criterion are for different fields" do
|
|
151
999
|
|
|
152
1000
|
let(:selection) do
|
|
153
|
-
query.
|
|
1001
|
+
query.send(tested_method, first: [ 1, 2 ]).send(tested_method, second: [ 3, 4 ])
|
|
154
1002
|
end
|
|
155
1003
|
|
|
156
|
-
|
|
1004
|
+
it_behaves_like 'returns a cloned query'
|
|
1005
|
+
|
|
1006
|
+
it "adds the $or/$nor selectors" do
|
|
157
1007
|
expect(selection.selector).to eq({
|
|
158
|
-
|
|
1008
|
+
expected_operator => [
|
|
159
1009
|
{ "first" => [ 1, 2 ] },
|
|
160
1010
|
{ "second" => [ 3, 4 ] }
|
|
161
1011
|
]
|
|
162
1012
|
})
|
|
163
1013
|
end
|
|
164
|
-
|
|
165
|
-
it "returns a cloned query" do
|
|
166
|
-
expect(selection).to_not equal(query)
|
|
167
|
-
end
|
|
168
1014
|
end
|
|
169
1015
|
|
|
170
1016
|
context "when the criterion are on the same field" do
|
|
171
1017
|
|
|
172
1018
|
let(:selection) do
|
|
173
|
-
query.
|
|
1019
|
+
query.send(tested_method, first: [ 1, 2 ]).send(tested_method, first: [ 3, 4 ])
|
|
174
1020
|
end
|
|
175
1021
|
|
|
176
|
-
|
|
1022
|
+
it_behaves_like 'returns a cloned query'
|
|
1023
|
+
|
|
1024
|
+
it "appends both $or/$nor expressions" do
|
|
177
1025
|
expect(selection.selector).to eq({
|
|
178
|
-
|
|
1026
|
+
expected_operator => [
|
|
179
1027
|
{ "first" => [ 1, 2 ] },
|
|
180
1028
|
{ "first" => [ 3, 4 ] }
|
|
181
1029
|
]
|
|
182
1030
|
})
|
|
183
1031
|
end
|
|
184
|
-
|
|
185
|
-
it "returns a cloned query" do
|
|
186
|
-
expect(selection).to_not equal(query)
|
|
187
|
-
end
|
|
188
1032
|
end
|
|
189
1033
|
end
|
|
190
1034
|
end
|
|
191
1035
|
|
|
192
1036
|
describe "#or" do
|
|
193
1037
|
|
|
194
|
-
|
|
1038
|
+
let(:tested_method) { :or }
|
|
1039
|
+
let(:expected_operator) { '$or' }
|
|
1040
|
+
|
|
1041
|
+
it_behaves_like '$or/$nor'
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
describe "#nor" do
|
|
1045
|
+
|
|
1046
|
+
let(:tested_method) { :nor }
|
|
1047
|
+
let(:expected_operator) { '$nor' }
|
|
1048
|
+
|
|
1049
|
+
it_behaves_like '$or/$nor'
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
describe "#any_of" do
|
|
1053
|
+
|
|
1054
|
+
let(:tested_method) { :any_of }
|
|
1055
|
+
let(:expected_operator) { '$or' }
|
|
1056
|
+
|
|
1057
|
+
it_behaves_like 'a hoisting logical operation'
|
|
1058
|
+
|
|
1059
|
+
# When multiple arguments are given to any_of, it behaves differently
|
|
1060
|
+
# from and.
|
|
1061
|
+
context 'when argument is a mix of Criteria and hashes' do
|
|
1062
|
+
let(:query) do
|
|
1063
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
1064
|
+
end
|
|
1065
|
+
|
|
1066
|
+
let(:other1) do
|
|
1067
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
let(:other2) do
|
|
1071
|
+
{bar: 42}
|
|
1072
|
+
end
|
|
1073
|
+
|
|
1074
|
+
let(:other3) do
|
|
1075
|
+
Mongoid::Query.new.where(a: 2)
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
let(:result) { query.send(tested_method, other1, other2, other3) }
|
|
1079
|
+
|
|
1080
|
+
it 'combines' do
|
|
1081
|
+
expect(result.selector).to eq(
|
|
1082
|
+
'hello' => 'world',
|
|
1083
|
+
expected_operator => [
|
|
1084
|
+
{'foo' => 'bar'},
|
|
1085
|
+
{'bar' => 42},
|
|
1086
|
+
{'a' => 2},
|
|
1087
|
+
],
|
|
1088
|
+
)
|
|
1089
|
+
end
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
context "when provided no arguments" do
|
|
195
1093
|
|
|
196
1094
|
let(:selection) do
|
|
197
|
-
query.
|
|
1095
|
+
query.any_of
|
|
198
1096
|
end
|
|
199
1097
|
|
|
200
|
-
|
|
1098
|
+
it_behaves_like 'returns a cloned query'
|
|
1099
|
+
|
|
1100
|
+
it "does not add any criteria" do
|
|
201
1101
|
expect(selection.selector).to eq({})
|
|
202
1102
|
end
|
|
203
1103
|
|
|
204
1104
|
it "returns the query" do
|
|
205
1105
|
expect(selection).to eq(query)
|
|
206
1106
|
end
|
|
207
|
-
|
|
208
|
-
it "returns a cloned query" do
|
|
209
|
-
expect(selection).to_not equal(query)
|
|
210
|
-
end
|
|
211
1107
|
end
|
|
212
1108
|
|
|
213
1109
|
context "when provided nil" do
|
|
214
1110
|
|
|
215
1111
|
let(:selection) do
|
|
216
|
-
query.
|
|
1112
|
+
query.any_of(nil)
|
|
217
1113
|
end
|
|
218
1114
|
|
|
219
|
-
|
|
1115
|
+
it_behaves_like 'returns a cloned query'
|
|
1116
|
+
|
|
1117
|
+
it "does not add any criteria" do
|
|
220
1118
|
expect(selection.selector).to eq({})
|
|
221
1119
|
end
|
|
222
1120
|
|
|
223
1121
|
it "returns the query" do
|
|
224
1122
|
expect(selection).to eq(query)
|
|
225
1123
|
end
|
|
226
|
-
|
|
227
|
-
it "returns a cloned query" do
|
|
228
|
-
expect(selection).to_not equal(query)
|
|
229
|
-
end
|
|
230
1124
|
end
|
|
231
1125
|
|
|
232
1126
|
context "when provided a single criterion" do
|
|
233
1127
|
|
|
234
1128
|
let(:selection) do
|
|
235
|
-
query.
|
|
1129
|
+
query.any_of(field: [ 1, 2 ])
|
|
236
1130
|
end
|
|
237
1131
|
|
|
1132
|
+
it_behaves_like 'returns a cloned query'
|
|
1133
|
+
|
|
238
1134
|
it "adds the $or selector" do
|
|
239
|
-
expect(selection.selector).to eq(
|
|
240
|
-
"
|
|
241
|
-
|
|
1135
|
+
expect(selection.selector).to eq(
|
|
1136
|
+
"field" => [ 1, 2 ],
|
|
1137
|
+
)
|
|
242
1138
|
end
|
|
243
1139
|
|
|
244
|
-
|
|
245
|
-
expect(selection).to_not equal(query)
|
|
246
|
-
end
|
|
247
|
-
end
|
|
1140
|
+
context 'when the criterion is wrapped in array' do
|
|
248
1141
|
|
|
249
|
-
|
|
1142
|
+
let(:selection) do
|
|
1143
|
+
query.any_of([{ field: [ 1, 2 ] }])
|
|
1144
|
+
end
|
|
1145
|
+
|
|
1146
|
+
it_behaves_like 'returns a cloned query'
|
|
1147
|
+
|
|
1148
|
+
it "adds the condition" do
|
|
1149
|
+
expect(selection.selector).to eq(
|
|
1150
|
+
"field" => [ 1, 2 ],
|
|
1151
|
+
)
|
|
1152
|
+
end
|
|
250
1153
|
|
|
251
|
-
|
|
1154
|
+
context 'when the array has nil as one of the elements' do
|
|
252
1155
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
1156
|
+
let(:selection) do
|
|
1157
|
+
query.any_of([{ field: [ 1, 2 ] }, nil])
|
|
1158
|
+
end
|
|
256
1159
|
|
|
257
|
-
|
|
258
|
-
expect(selection.selector).to eq({
|
|
259
|
-
"$or" => [
|
|
260
|
-
{ "first" => [ 1, 2 ] },
|
|
261
|
-
{ "second" => [ 3, 4 ] }
|
|
262
|
-
]
|
|
263
|
-
})
|
|
264
|
-
end
|
|
1160
|
+
it_behaves_like 'returns a cloned query'
|
|
265
1161
|
|
|
266
|
-
|
|
267
|
-
|
|
1162
|
+
it "adds the $or selector ignoring the nil element" do
|
|
1163
|
+
expect(selection.selector).to eq(
|
|
1164
|
+
"field" => [ 1, 2 ],
|
|
1165
|
+
)
|
|
1166
|
+
end
|
|
268
1167
|
end
|
|
269
1168
|
end
|
|
270
1169
|
|
|
271
|
-
context
|
|
1170
|
+
context 'when query already has a condition on another field' do
|
|
272
1171
|
|
|
273
|
-
|
|
274
|
-
query.or({ first: [ 1, 2 ] }, { :second.gt => 3 })
|
|
275
|
-
end
|
|
1172
|
+
context 'when there is one argument' do
|
|
276
1173
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
1174
|
+
let(:selection) do
|
|
1175
|
+
query.where(foo: 'bar').any_of(field: [ 1, 2 ])
|
|
1176
|
+
end
|
|
1177
|
+
|
|
1178
|
+
it 'adds the new condition' do
|
|
1179
|
+
expect(selection.selector).to eq(
|
|
1180
|
+
'foo' => 'bar',
|
|
1181
|
+
'field' => [1, 2],
|
|
1182
|
+
)
|
|
1183
|
+
end
|
|
284
1184
|
end
|
|
285
1185
|
|
|
286
|
-
|
|
287
|
-
|
|
1186
|
+
context 'when there are multiple arguments' do
|
|
1187
|
+
|
|
1188
|
+
let(:selection) do
|
|
1189
|
+
query.where(foo: 'bar').any_of({field: [ 1, 2 ]}, {hello: 'world'})
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
it 'adds the new condition' do
|
|
1193
|
+
expect(selection.selector).to eq(
|
|
1194
|
+
'foo' => 'bar',
|
|
1195
|
+
'$or' => [
|
|
1196
|
+
{'field' => [1, 2]},
|
|
1197
|
+
{'hello' => 'world'},
|
|
1198
|
+
],
|
|
1199
|
+
)
|
|
1200
|
+
end
|
|
288
1201
|
end
|
|
289
1202
|
end
|
|
290
1203
|
|
|
291
|
-
context
|
|
1204
|
+
context 'when query already has an $or condition and another condition' do
|
|
292
1205
|
|
|
293
1206
|
let(:selection) do
|
|
294
|
-
query.or(
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "adds the $or selector and aliases the field" do
|
|
298
|
-
expect(selection.selector).to eq({
|
|
299
|
-
"$or" => [ { "_id" => 1 } ]
|
|
300
|
-
})
|
|
1207
|
+
query.or(field: [ 1, 2 ]).where(foo: 'bar').any_of(test: 1)
|
|
301
1208
|
end
|
|
302
1209
|
|
|
303
|
-
it
|
|
304
|
-
expect(selection).
|
|
1210
|
+
it 'adds the new condition' do
|
|
1211
|
+
expect(selection.selector).to eq(
|
|
1212
|
+
'$or' => [{'field' => [1, 2]}],
|
|
1213
|
+
'foo' => 'bar',
|
|
1214
|
+
'test' => 1,
|
|
1215
|
+
)
|
|
305
1216
|
end
|
|
306
1217
|
end
|
|
1218
|
+
end
|
|
307
1219
|
|
|
308
|
-
|
|
1220
|
+
context "when provided multiple criteria" do
|
|
1221
|
+
|
|
1222
|
+
context "when the criteria are for different fields" do
|
|
309
1223
|
|
|
310
1224
|
let(:selection) do
|
|
311
|
-
query.
|
|
1225
|
+
query.any_of({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
|
|
312
1226
|
end
|
|
313
1227
|
|
|
1228
|
+
it_behaves_like 'returns a cloned query'
|
|
1229
|
+
|
|
314
1230
|
it "adds the $or selector" do
|
|
315
1231
|
expect(selection.selector).to eq({
|
|
316
1232
|
"$or" => [
|
|
317
1233
|
{ "first" => [ 1, 2 ] },
|
|
318
|
-
{ "second" =>
|
|
1234
|
+
{ "second" => [ 3, 4 ] }
|
|
319
1235
|
]
|
|
320
1236
|
})
|
|
321
1237
|
end
|
|
322
|
-
|
|
323
|
-
it "returns a cloned query" do
|
|
324
|
-
expect(selection).to_not equal(query)
|
|
325
|
-
end
|
|
326
1238
|
end
|
|
327
1239
|
|
|
328
|
-
context "when the
|
|
1240
|
+
context "when the criteria uses a Key instance" do
|
|
329
1241
|
|
|
330
1242
|
let(:selection) do
|
|
331
|
-
query.
|
|
1243
|
+
query.any_of({ first: [ 1, 2 ] }, { :second.gt => 3 })
|
|
332
1244
|
end
|
|
333
1245
|
|
|
334
|
-
it "
|
|
1246
|
+
it "adds the $or selector" do
|
|
335
1247
|
expect(selection.selector).to eq({
|
|
336
1248
|
"$or" => [
|
|
337
1249
|
{ "first" => [ 1, 2 ] },
|
|
338
|
-
{ "
|
|
1250
|
+
{ "second" => { "$gt" => 3 }}
|
|
339
1251
|
]
|
|
340
1252
|
})
|
|
341
1253
|
end
|
|
342
1254
|
|
|
343
|
-
|
|
344
|
-
expect(selection).to_not equal(query)
|
|
345
|
-
end
|
|
1255
|
+
it_behaves_like 'returns a cloned query'
|
|
346
1256
|
end
|
|
347
|
-
end
|
|
348
1257
|
|
|
349
|
-
|
|
1258
|
+
context 'when criteria are simple and handled via Key' do
|
|
1259
|
+
shared_examples_for 'adds conditions with $or' do
|
|
350
1260
|
|
|
351
|
-
|
|
1261
|
+
it "adds conditions with $or" do
|
|
1262
|
+
expect(selection.selector).to eq({
|
|
1263
|
+
'$or' => [
|
|
1264
|
+
{'field' => 3},
|
|
1265
|
+
{'field' => {'$lt' => 5}},
|
|
1266
|
+
],
|
|
1267
|
+
})
|
|
1268
|
+
end
|
|
352
1269
|
|
|
353
|
-
|
|
354
|
-
query.or(first: [ 1, 2 ]).or(second: [ 3, 4 ])
|
|
1270
|
+
it_behaves_like 'returns a cloned query'
|
|
355
1271
|
end
|
|
356
1272
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
1273
|
+
shared_examples_for 'adds one condition' do
|
|
1274
|
+
|
|
1275
|
+
it "adds one condition" do
|
|
1276
|
+
expect(selection.selector).to eq({
|
|
1277
|
+
'field' => 3,
|
|
1278
|
+
'$and' => [
|
|
1279
|
+
{'field' => {'$lt' => 5}},
|
|
1280
|
+
],
|
|
1281
|
+
})
|
|
1282
|
+
end
|
|
365
1283
|
|
|
366
|
-
|
|
367
|
-
expect(selection).to_not equal(query)
|
|
1284
|
+
it_behaves_like 'returns a cloned query'
|
|
368
1285
|
end
|
|
369
|
-
end
|
|
370
1286
|
|
|
371
|
-
|
|
1287
|
+
context 'criteria are provided in the same hash' do
|
|
1288
|
+
let(:selection) do
|
|
1289
|
+
query.send(tested_method, :field => 3, :field.lt => 5)
|
|
1290
|
+
end
|
|
372
1291
|
|
|
373
|
-
|
|
374
|
-
query.or(first: [ 1, 2 ]).or(first: [ 3, 4 ])
|
|
1292
|
+
it_behaves_like 'adds one condition'
|
|
375
1293
|
end
|
|
376
1294
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
})
|
|
1295
|
+
context 'criteria are provided in separate hashes' do
|
|
1296
|
+
let(:selection) do
|
|
1297
|
+
query.send(tested_method, {:field => 3}, {:field.lt => 5})
|
|
1298
|
+
end
|
|
1299
|
+
|
|
1300
|
+
it_behaves_like 'adds conditions with $or'
|
|
384
1301
|
end
|
|
385
1302
|
|
|
386
|
-
|
|
387
|
-
|
|
1303
|
+
context 'when the criterion is wrapped in an array' do
|
|
1304
|
+
let(:selection) do
|
|
1305
|
+
query.send(tested_method, [:field => 3], [:field.lt => 5])
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
it_behaves_like 'adds conditions with $or'
|
|
388
1309
|
end
|
|
389
1310
|
end
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
1311
|
|
|
393
|
-
|
|
1312
|
+
context 'when criteria are handled via Key and simple' do
|
|
1313
|
+
shared_examples_for 'adds conditions with $or' do
|
|
394
1314
|
|
|
395
|
-
|
|
1315
|
+
it "adds conditions with $or" do
|
|
1316
|
+
expect(selection.selector).to eq({
|
|
1317
|
+
'$or' => [
|
|
1318
|
+
{'field' => {'$gt' => 3}},
|
|
1319
|
+
{'field' => 5},
|
|
1320
|
+
],
|
|
1321
|
+
})
|
|
1322
|
+
end
|
|
396
1323
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
end
|
|
1324
|
+
it_behaves_like 'returns a cloned query'
|
|
1325
|
+
end
|
|
400
1326
|
|
|
401
|
-
|
|
402
|
-
expect(selection.selector).to eq({})
|
|
403
|
-
end
|
|
1327
|
+
shared_examples_for 'adds one condition' do
|
|
404
1328
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
1329
|
+
it "adds one condition" do
|
|
1330
|
+
expect(selection.selector).to eq({
|
|
1331
|
+
'field' => {'$gt' => 3},
|
|
1332
|
+
'$and' => ['field' => 5],
|
|
1333
|
+
})
|
|
1334
|
+
end
|
|
408
1335
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
end
|
|
412
|
-
end
|
|
1336
|
+
it_behaves_like 'returns a cloned query'
|
|
1337
|
+
end
|
|
413
1338
|
|
|
414
|
-
|
|
1339
|
+
context 'criteria are provided in the same hash' do
|
|
1340
|
+
let(:selection) do
|
|
1341
|
+
query.send(tested_method, :field.gt => 3, :field => 5)
|
|
1342
|
+
end
|
|
415
1343
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
end
|
|
1344
|
+
it_behaves_like 'adds one condition'
|
|
1345
|
+
end
|
|
419
1346
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
1347
|
+
context 'criteria are provided in separate hashes' do
|
|
1348
|
+
let(:selection) do
|
|
1349
|
+
query.send(tested_method, {:field.gt => 3}, {:field => 5})
|
|
1350
|
+
end
|
|
423
1351
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
end
|
|
1352
|
+
it_behaves_like 'adds conditions with $or'
|
|
1353
|
+
end
|
|
427
1354
|
|
|
428
|
-
|
|
429
|
-
|
|
1355
|
+
context 'when the criterion is wrapped in an array' do
|
|
1356
|
+
let(:selection) do
|
|
1357
|
+
query.send(tested_method, [:field.gt => 3], [:field => 5])
|
|
1358
|
+
end
|
|
1359
|
+
|
|
1360
|
+
it_behaves_like 'adds conditions with $or'
|
|
1361
|
+
end
|
|
430
1362
|
end
|
|
431
|
-
end
|
|
432
1363
|
|
|
433
|
-
|
|
1364
|
+
context "when a criterion has an aliased field" do
|
|
434
1365
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
1366
|
+
let(:selection) do
|
|
1367
|
+
query.any_of({ id: 1 })
|
|
1368
|
+
end
|
|
438
1369
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
1370
|
+
it "adds the $or selector and aliases the field" do
|
|
1371
|
+
expect(selection.selector).to eq(
|
|
1372
|
+
"_id" => 1,
|
|
1373
|
+
)
|
|
1374
|
+
end
|
|
444
1375
|
|
|
445
|
-
|
|
446
|
-
expect(selection).to_not equal(query)
|
|
1376
|
+
it_behaves_like 'returns a cloned query'
|
|
447
1377
|
end
|
|
448
|
-
end
|
|
449
1378
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
context "when the criterion are fnor different fields" do
|
|
1379
|
+
context "when a criterion is wrapped in an array" do
|
|
453
1380
|
|
|
454
1381
|
let(:selection) do
|
|
455
|
-
query.
|
|
1382
|
+
query.any_of([{ first: [ 1, 2 ] }, { :second.gt => 3 }])
|
|
456
1383
|
end
|
|
457
1384
|
|
|
458
|
-
|
|
1385
|
+
it_behaves_like 'returns a cloned query'
|
|
1386
|
+
|
|
1387
|
+
it "adds the $or selector" do
|
|
459
1388
|
expect(selection.selector).to eq({
|
|
460
|
-
"$
|
|
1389
|
+
"$or" => [
|
|
461
1390
|
{ "first" => [ 1, 2 ] },
|
|
462
|
-
{ "second" =>
|
|
1391
|
+
{ "second" => { "$gt" => 3 }}
|
|
463
1392
|
]
|
|
464
1393
|
})
|
|
465
1394
|
end
|
|
466
|
-
|
|
467
|
-
it "returns a cloned query" do
|
|
468
|
-
expect(selection).to_not equal(query)
|
|
469
|
-
end
|
|
470
1395
|
end
|
|
471
1396
|
|
|
472
|
-
context "when the
|
|
1397
|
+
context "when the criteria are on the same field" do
|
|
473
1398
|
|
|
474
1399
|
let(:selection) do
|
|
475
|
-
query.
|
|
1400
|
+
query.any_of({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
|
|
476
1401
|
end
|
|
477
1402
|
|
|
478
|
-
|
|
1403
|
+
it_behaves_like 'returns a cloned query'
|
|
1404
|
+
|
|
1405
|
+
it "appends both $or expressions" do
|
|
479
1406
|
expect(selection.selector).to eq({
|
|
480
|
-
"$
|
|
1407
|
+
"$or" => [
|
|
481
1408
|
{ "first" => [ 1, 2 ] },
|
|
482
1409
|
{ "first" => [ 3, 4 ] }
|
|
483
1410
|
]
|
|
484
1411
|
})
|
|
485
1412
|
end
|
|
486
|
-
|
|
487
|
-
it "returns a cloned query" do
|
|
488
|
-
expect(selection).to_not equal(query)
|
|
489
|
-
end
|
|
490
1413
|
end
|
|
491
1414
|
end
|
|
492
1415
|
|
|
493
|
-
context "when chaining the
|
|
1416
|
+
context "when chaining the criteria" do
|
|
494
1417
|
|
|
495
|
-
context "when the
|
|
1418
|
+
context "when the criteria are for different fields" do
|
|
496
1419
|
|
|
497
1420
|
let(:selection) do
|
|
498
|
-
query.
|
|
1421
|
+
query.any_of(first: [ 1, 2 ]).any_of(second: [ 3, 4 ])
|
|
499
1422
|
end
|
|
500
1423
|
|
|
501
|
-
|
|
502
|
-
expect(selection.selector).to eq({
|
|
503
|
-
"$nor" => [
|
|
504
|
-
{ "first" => [ 1, 2 ] },
|
|
505
|
-
{ "second" => [ 3, 4 ] }
|
|
506
|
-
]
|
|
507
|
-
})
|
|
508
|
-
end
|
|
1424
|
+
it_behaves_like 'returns a cloned query'
|
|
509
1425
|
|
|
510
|
-
it "
|
|
511
|
-
expect(selection).
|
|
1426
|
+
it "adds the conditions separately" do
|
|
1427
|
+
expect(selection.selector).to eq(
|
|
1428
|
+
"first" => [ 1, 2 ],
|
|
1429
|
+
"second" => [ 3, 4 ],
|
|
1430
|
+
)
|
|
512
1431
|
end
|
|
513
1432
|
end
|
|
514
1433
|
|
|
515
|
-
context "when the
|
|
1434
|
+
context "when the criteria are on the same field" do
|
|
516
1435
|
|
|
517
1436
|
let(:selection) do
|
|
518
|
-
query.
|
|
1437
|
+
query.any_of(first: [ 1, 2 ]).any_of(first: [ 3, 4 ])
|
|
519
1438
|
end
|
|
520
1439
|
|
|
521
|
-
|
|
522
|
-
expect(selection.selector).to eq({
|
|
523
|
-
"$nor" => [
|
|
524
|
-
{ "first" => [ 1, 2 ] },
|
|
525
|
-
{ "first" => [ 3, 4 ] }
|
|
526
|
-
]
|
|
527
|
-
})
|
|
528
|
-
end
|
|
1440
|
+
it_behaves_like 'returns a cloned query'
|
|
529
1441
|
|
|
530
|
-
it "
|
|
531
|
-
expect(selection).
|
|
1442
|
+
it "adds the conditions separately" do
|
|
1443
|
+
expect(selection.selector).to eq(
|
|
1444
|
+
"first" => [ 1, 2 ],
|
|
1445
|
+
'$and' => [{"first" => [ 3, 4 ]}],
|
|
1446
|
+
)
|
|
532
1447
|
end
|
|
533
1448
|
end
|
|
534
1449
|
end
|
|
@@ -561,27 +1476,45 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
561
1476
|
expect(query.negating).to be nil
|
|
562
1477
|
end
|
|
563
1478
|
|
|
564
|
-
|
|
565
|
-
|
|
1479
|
+
shared_examples_for 'negates the next condition' do
|
|
566
1480
|
let(:selection) do
|
|
567
|
-
query.not.
|
|
1481
|
+
query.not.send(query_method, field: [ 1, 2 ])
|
|
568
1482
|
end
|
|
569
1483
|
|
|
570
|
-
it "negates the
|
|
1484
|
+
it "negates the next condition" do
|
|
571
1485
|
expect(selection.selector).to eq(
|
|
572
|
-
{ "field" => { "$not" => {
|
|
1486
|
+
{ "field" => { "$not" => { operator => [ 1, 2 ] }}}
|
|
573
1487
|
)
|
|
574
1488
|
end
|
|
575
1489
|
|
|
576
|
-
|
|
577
|
-
expect(selection).to_not equal(query)
|
|
578
|
-
end
|
|
1490
|
+
it_behaves_like 'returns a cloned query'
|
|
579
1491
|
|
|
580
1492
|
it "removes the negation on the clone" do
|
|
581
1493
|
expect(selection).to_not be_negating
|
|
582
1494
|
end
|
|
583
1495
|
end
|
|
584
1496
|
|
|
1497
|
+
context "when the next condition is #all" do
|
|
1498
|
+
let(:query_method) { :all }
|
|
1499
|
+
let(:operator) { '$all' }
|
|
1500
|
+
|
|
1501
|
+
it_behaves_like 'negates the next condition'
|
|
1502
|
+
end
|
|
1503
|
+
|
|
1504
|
+
context "when the next condition is #in" do
|
|
1505
|
+
let(:query_method) { :in }
|
|
1506
|
+
let(:operator) { '$in' }
|
|
1507
|
+
|
|
1508
|
+
it_behaves_like 'negates the next condition'
|
|
1509
|
+
end
|
|
1510
|
+
|
|
1511
|
+
context "when the next condition is #nin" do
|
|
1512
|
+
let(:query_method) { :nin }
|
|
1513
|
+
let(:operator) { '$nin' }
|
|
1514
|
+
|
|
1515
|
+
it_behaves_like 'negates the next condition'
|
|
1516
|
+
end
|
|
1517
|
+
|
|
585
1518
|
context "when the following criteria is a gt method" do
|
|
586
1519
|
|
|
587
1520
|
let(:selection) do
|
|
@@ -594,10 +1527,27 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
594
1527
|
)
|
|
595
1528
|
end
|
|
596
1529
|
|
|
597
|
-
|
|
598
|
-
|
|
1530
|
+
it_behaves_like 'returns a cloned query'
|
|
1531
|
+
|
|
1532
|
+
it "removes the negation on the clone" do
|
|
1533
|
+
expect(selection).to_not be_negating
|
|
1534
|
+
end
|
|
1535
|
+
end
|
|
1536
|
+
|
|
1537
|
+
context "when the criteria uses Key" do
|
|
1538
|
+
|
|
1539
|
+
let(:selection) do
|
|
1540
|
+
query.not(:age.gt => 50)
|
|
1541
|
+
end
|
|
1542
|
+
|
|
1543
|
+
it "negates the gt selection" do
|
|
1544
|
+
expect(selection.selector).to eq(
|
|
1545
|
+
'$and' => ['$nor' => ['age' => {'$gt' => 50}]]
|
|
1546
|
+
)
|
|
599
1547
|
end
|
|
600
1548
|
|
|
1549
|
+
it_behaves_like 'returns a cloned query'
|
|
1550
|
+
|
|
601
1551
|
it "removes the negation on the clone" do
|
|
602
1552
|
expect(selection).to_not be_negating
|
|
603
1553
|
end
|
|
@@ -615,9 +1565,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
615
1565
|
)
|
|
616
1566
|
end
|
|
617
1567
|
|
|
618
|
-
|
|
619
|
-
expect(selection).to_not equal(query)
|
|
620
|
-
end
|
|
1568
|
+
it_behaves_like 'returns a cloned query'
|
|
621
1569
|
|
|
622
1570
|
it "removes the negation on the clone" do
|
|
623
1571
|
expect(selection).to_not be_negating
|
|
@@ -636,10 +1584,27 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
636
1584
|
)
|
|
637
1585
|
end
|
|
638
1586
|
|
|
639
|
-
|
|
640
|
-
|
|
1587
|
+
it_behaves_like 'returns a cloned query'
|
|
1588
|
+
|
|
1589
|
+
it "removes the negation on the clone" do
|
|
1590
|
+
expect(selection).to_not be_negating
|
|
1591
|
+
end
|
|
1592
|
+
end
|
|
1593
|
+
|
|
1594
|
+
context 'when the following criteria uses string were form' do
|
|
1595
|
+
|
|
1596
|
+
let(:selection) do
|
|
1597
|
+
query.not.where('hello world')
|
|
1598
|
+
end
|
|
1599
|
+
|
|
1600
|
+
it "negates the selection with an operator" do
|
|
1601
|
+
expect(selection.selector).to eq(
|
|
1602
|
+
'$and' => [{'$nor' => [{'$where' => 'hello world'}]}]
|
|
1603
|
+
)
|
|
641
1604
|
end
|
|
642
1605
|
|
|
1606
|
+
it_behaves_like 'returns a cloned query'
|
|
1607
|
+
|
|
643
1608
|
it "removes the negation on the clone" do
|
|
644
1609
|
expect(selection).to_not be_negating
|
|
645
1610
|
end
|
|
@@ -661,9 +1626,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
661
1626
|
expect(selection).to eq(query)
|
|
662
1627
|
end
|
|
663
1628
|
|
|
664
|
-
|
|
665
|
-
expect(selection).to_not equal(query)
|
|
666
|
-
end
|
|
1629
|
+
it_behaves_like 'returns a cloned query'
|
|
667
1630
|
end
|
|
668
1631
|
|
|
669
1632
|
context "when provided a single criterion" do
|
|
@@ -678,14 +1641,31 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
678
1641
|
})
|
|
679
1642
|
end
|
|
680
1643
|
|
|
681
|
-
|
|
682
|
-
|
|
1644
|
+
it_behaves_like 'returns a cloned query'
|
|
1645
|
+
end
|
|
1646
|
+
|
|
1647
|
+
context "when negating a field in the original selector" do
|
|
1648
|
+
let(:query) do
|
|
1649
|
+
Mongoid::Query.new("id" => "_id").where(field: 'foo')
|
|
683
1650
|
end
|
|
1651
|
+
|
|
1652
|
+
let(:selection) do
|
|
1653
|
+
query.not(field: 'bar')
|
|
1654
|
+
end
|
|
1655
|
+
|
|
1656
|
+
it "combines the conditions" do
|
|
1657
|
+
expect(selection.selector).to eq({
|
|
1658
|
+
"field" => 'foo',
|
|
1659
|
+
'$and' => [{'$nor' => [{ "field" => 'bar' }]}],
|
|
1660
|
+
})
|
|
1661
|
+
end
|
|
1662
|
+
|
|
1663
|
+
it_behaves_like 'returns a cloned query'
|
|
684
1664
|
end
|
|
685
1665
|
|
|
686
|
-
context "when provided multiple
|
|
1666
|
+
context "when provided multiple criteria" do
|
|
687
1667
|
|
|
688
|
-
context "when the
|
|
1668
|
+
context "when the criteria are for different fields" do
|
|
689
1669
|
|
|
690
1670
|
let(:selection) do
|
|
691
1671
|
query.not(first: /1/, second: /2/)
|
|
@@ -698,9 +1678,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
698
1678
|
})
|
|
699
1679
|
end
|
|
700
1680
|
|
|
701
|
-
|
|
702
|
-
|
|
1681
|
+
it_behaves_like 'returns a cloned query'
|
|
1682
|
+
end
|
|
1683
|
+
|
|
1684
|
+
context "when the criteria are given in separate arguments" do
|
|
1685
|
+
|
|
1686
|
+
let(:selection) do
|
|
1687
|
+
query.not({first: /1/}, {second: /2/})
|
|
1688
|
+
end
|
|
1689
|
+
|
|
1690
|
+
it "adds the $not selectors" do
|
|
1691
|
+
expect(selection.selector).to eq({
|
|
1692
|
+
"first" => { "$not" => /1/ },
|
|
1693
|
+
"second" => { "$not" => /2/ }
|
|
1694
|
+
})
|
|
703
1695
|
end
|
|
1696
|
+
|
|
1697
|
+
it_behaves_like 'returns a cloned query'
|
|
704
1698
|
end
|
|
705
1699
|
end
|
|
706
1700
|
|
|
@@ -719,9 +1713,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
719
1713
|
})
|
|
720
1714
|
end
|
|
721
1715
|
|
|
722
|
-
|
|
723
|
-
expect(selection).to_not equal(query)
|
|
724
|
-
end
|
|
1716
|
+
it_behaves_like 'returns a cloned query'
|
|
725
1717
|
end
|
|
726
1718
|
|
|
727
1719
|
context "when the criterion are on the same field" do
|
|
@@ -730,15 +1722,14 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
730
1722
|
query.not(first: /1/).not(first: /2/)
|
|
731
1723
|
end
|
|
732
1724
|
|
|
733
|
-
it "
|
|
734
|
-
expect(selection.selector).to eq(
|
|
735
|
-
"first" => { "$not" => /
|
|
736
|
-
|
|
1725
|
+
it "combines conditions" do
|
|
1726
|
+
expect(selection.selector).to eq(
|
|
1727
|
+
"first" => { "$not" => /1/ },
|
|
1728
|
+
'$and' => [{'$nor' => [{'first' => /2/}]}],
|
|
1729
|
+
)
|
|
737
1730
|
end
|
|
738
1731
|
|
|
739
|
-
|
|
740
|
-
expect(selection).to_not equal(query)
|
|
741
|
-
end
|
|
1732
|
+
it_behaves_like 'returns a cloned query'
|
|
742
1733
|
end
|
|
743
1734
|
|
|
744
1735
|
context "when the criterion are a double negative" do
|
|
@@ -753,9 +1744,85 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
|
753
1744
|
})
|
|
754
1745
|
end
|
|
755
1746
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
1747
|
+
it_behaves_like 'returns a cloned query'
|
|
1748
|
+
end
|
|
1749
|
+
end
|
|
1750
|
+
|
|
1751
|
+
context 'when argument is a Criteria' do
|
|
1752
|
+
let(:query) do
|
|
1753
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
let(:other) do
|
|
1757
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
1758
|
+
end
|
|
1759
|
+
|
|
1760
|
+
let(:result) { query.not(other) }
|
|
1761
|
+
|
|
1762
|
+
it 'combines' do
|
|
1763
|
+
expect(result.selector).to eq('hello' => 'world', 'foo' => {'$ne' => 'bar'})
|
|
1764
|
+
end
|
|
1765
|
+
end
|
|
1766
|
+
|
|
1767
|
+
context 'when argument is a simple Criteria with multiple fields' do
|
|
1768
|
+
let(:query) do
|
|
1769
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
1770
|
+
end
|
|
1771
|
+
|
|
1772
|
+
let(:other) do
|
|
1773
|
+
Mongoid::Query.new.where(a: 1, b: 2)
|
|
1774
|
+
end
|
|
1775
|
+
|
|
1776
|
+
let(:result) { query.not(other) }
|
|
1777
|
+
|
|
1778
|
+
it 'combines fields into top level criteria' do
|
|
1779
|
+
expect(result.selector).to eq('hello' => 'world',
|
|
1780
|
+
'a' => {'$ne' => 1}, 'b' => {'$ne' => 2})
|
|
1781
|
+
end
|
|
1782
|
+
end
|
|
1783
|
+
|
|
1784
|
+
context 'when argument is a complex Criteria' do
|
|
1785
|
+
let(:query) do
|
|
1786
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
1787
|
+
end
|
|
1788
|
+
|
|
1789
|
+
let(:other) do
|
|
1790
|
+
Mongoid::Query.new.where('$nor' => [{a: 1, b: 2}])
|
|
1791
|
+
end
|
|
1792
|
+
|
|
1793
|
+
let(:result) { query.not(other) }
|
|
1794
|
+
|
|
1795
|
+
it 'combines with $and of $nor' do
|
|
1796
|
+
expect(result.selector).to eq('hello' => 'world', '$and' => [{'$nor' => [{
|
|
1797
|
+
'$nor' => [{'a' => 1, 'b' => 2}]}]}])
|
|
1798
|
+
end
|
|
1799
|
+
end
|
|
1800
|
+
|
|
1801
|
+
context 'when argument is a mix of Criteria and hashes' do
|
|
1802
|
+
let(:query) do
|
|
1803
|
+
Mongoid::Query.new.where(hello: 'world')
|
|
1804
|
+
end
|
|
1805
|
+
|
|
1806
|
+
let(:other1) do
|
|
1807
|
+
Mongoid::Query.new.where(foo: 'bar')
|
|
1808
|
+
end
|
|
1809
|
+
|
|
1810
|
+
let(:other2) do
|
|
1811
|
+
{bar: 42}
|
|
1812
|
+
end
|
|
1813
|
+
|
|
1814
|
+
let(:other3) do
|
|
1815
|
+
Mongoid::Query.new.where(a: 2)
|
|
1816
|
+
end
|
|
1817
|
+
|
|
1818
|
+
let(:result) { query.not(other1, other2, other3) }
|
|
1819
|
+
|
|
1820
|
+
it 'combines' do
|
|
1821
|
+
expect(result.selector).to eq('hello' => 'world',
|
|
1822
|
+
'foo' => {'$ne' => 'bar'},
|
|
1823
|
+
'bar' => {'$ne' => 42},
|
|
1824
|
+
'a' => {'$ne' => 2},
|
|
1825
|
+
)
|
|
759
1826
|
end
|
|
760
1827
|
end
|
|
761
1828
|
end
|