mongoid 7.5.4 → 8.1.3
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/CHANGELOG.md +3 -3
- data/README.md +6 -6
- data/lib/config/locales/en.yml +92 -43
- data/lib/mongoid/association/accessors.rb +40 -11
- data/lib/mongoid/association/bindable.rb +50 -2
- data/lib/mongoid/association/builders.rb +5 -3
- data/lib/mongoid/association/constrainable.rb +0 -1
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +34 -11
- data/lib/mongoid/association/embedded/cyclic.rb +1 -1
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
- data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
- data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
- data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
- data/lib/mongoid/association/macros.rb +8 -1
- data/lib/mongoid/association/many.rb +11 -7
- data/lib/mongoid/association/nested/many.rb +5 -4
- data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
- data/lib/mongoid/association/nested/one.rb +45 -7
- data/lib/mongoid/association/one.rb +2 -2
- data/lib/mongoid/association/options.rb +9 -9
- data/lib/mongoid/association/proxy.rb +15 -4
- data/lib/mongoid/association/referenced/auto_save.rb +4 -3
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
- data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
- data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
- data/lib/mongoid/association/referenced/eager.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
- data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
- data/lib/mongoid/association/referenced/has_many.rb +3 -3
- data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
- data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
- data/lib/mongoid/association/referenced/has_one.rb +3 -3
- data/lib/mongoid/association/referenced/syncable.rb +4 -4
- data/lib/mongoid/association/reflections.rb +4 -4
- data/lib/mongoid/association/relatable.rb +44 -10
- data/lib/mongoid/association.rb +5 -5
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +7 -0
- data/lib/mongoid/attributes/dynamic.rb +4 -4
- data/lib/mongoid/attributes/nested.rb +6 -6
- data/lib/mongoid/attributes/processing.rb +37 -6
- data/lib/mongoid/attributes/projector.rb +2 -2
- data/lib/mongoid/attributes/readonly.rb +3 -3
- data/lib/mongoid/attributes.rb +51 -42
- data/lib/mongoid/changeable.rb +147 -14
- data/lib/mongoid/clients/options.rb +5 -1
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +3 -15
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/options.rb +3 -0
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators/client.rb +6 -6
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +153 -18
- data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
- data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
- data/lib/mongoid/contextual/aggregable/none.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/geo_near.rb +7 -7
- data/lib/mongoid/contextual/map_reduce.rb +2 -2
- data/lib/mongoid/contextual/memory.rb +285 -58
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +540 -346
- data/lib/mongoid/contextual/none.rb +193 -20
- data/lib/mongoid/contextual/queryable.rb +1 -1
- data/lib/mongoid/contextual.rb +14 -2
- data/lib/mongoid/copyable.rb +32 -8
- data/lib/mongoid/criteria/findable.rb +8 -5
- data/lib/mongoid/criteria/includable.rb +27 -22
- data/lib/mongoid/criteria/marshalable.rb +10 -2
- data/lib/mongoid/criteria/permission.rb +1 -1
- data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
- data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
- data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
- data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
- data/lib/mongoid/criteria/queryable/key.rb +4 -4
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
- data/lib/mongoid/criteria/queryable/optional.rb +11 -17
- data/lib/mongoid/criteria/queryable/options.rb +2 -2
- data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
- data/lib/mongoid/criteria/queryable/selector.rb +92 -7
- data/lib/mongoid/criteria/queryable/smash.rb +40 -7
- data/lib/mongoid/criteria/queryable.rb +12 -7
- data/lib/mongoid/criteria/scopable.rb +2 -2
- data/lib/mongoid/criteria/translator.rb +45 -0
- data/lib/mongoid/criteria.rb +20 -40
- data/lib/mongoid/deprecable.rb +37 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +127 -35
- data/lib/mongoid/equality.rb +8 -8
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/document_not_found.rb +10 -6
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_config_option.rb +1 -1
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
- data/lib/mongoid/errors/invalid_field.rb +6 -2
- data/lib/mongoid/errors/invalid_field_type.rb +26 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_relation.rb +1 -1
- data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
- data/lib/mongoid/errors/invalid_session_use.rb +1 -1
- data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors/mongoid_error.rb +3 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
- data/lib/mongoid/errors/no_client_database.rb +1 -1
- data/lib/mongoid/errors/no_client_hosts.rb +1 -1
- data/lib/mongoid/errors/readonly_attribute.rb +1 -1
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
- data/lib/mongoid/errors/unknown_attribute.rb +1 -1
- data/lib/mongoid/errors.rb +6 -3
- data/lib/mongoid/extensions/array.rb +9 -7
- data/lib/mongoid/extensions/big_decimal.rb +33 -10
- data/lib/mongoid/extensions/binary.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +8 -2
- data/lib/mongoid/extensions/date.rb +26 -20
- data/lib/mongoid/extensions/date_time.rb +1 -1
- data/lib/mongoid/extensions/false_class.rb +1 -1
- data/lib/mongoid/extensions/float.rb +7 -4
- data/lib/mongoid/extensions/hash.rb +37 -8
- data/lib/mongoid/extensions/integer.rb +7 -4
- data/lib/mongoid/extensions/module.rb +1 -1
- data/lib/mongoid/extensions/object.rb +10 -8
- data/lib/mongoid/extensions/range.rb +41 -10
- data/lib/mongoid/extensions/regexp.rb +11 -4
- data/lib/mongoid/extensions/set.rb +11 -4
- data/lib/mongoid/extensions/string.rb +11 -22
- data/lib/mongoid/extensions/symbol.rb +4 -15
- data/lib/mongoid/extensions/time.rb +29 -16
- data/lib/mongoid/extensions/time_with_zone.rb +1 -2
- data/lib/mongoid/extensions/true_class.rb +1 -1
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/factory.rb +55 -7
- data/lib/mongoid/fields/foreign_key.rb +11 -4
- data/lib/mongoid/fields/localized.rb +19 -4
- data/lib/mongoid/fields/standard.rb +17 -7
- data/lib/mongoid/fields/validators/macro.rb +3 -9
- data/lib/mongoid/fields.rb +129 -20
- data/lib/mongoid/findable.rb +54 -24
- data/lib/mongoid/indexable/specification.rb +2 -2
- data/lib/mongoid/indexable/validators/options.rb +6 -2
- data/lib/mongoid/interceptable.rb +188 -16
- data/lib/mongoid/matchable.rb +1 -1
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +33 -13
- data/lib/mongoid/persistable/creatable.rb +19 -9
- data/lib/mongoid/persistable/deletable.rb +2 -2
- data/lib/mongoid/persistable/destroyable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +14 -2
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +69 -12
- data/lib/mongoid/persistable/upsertable.rb +21 -2
- data/lib/mongoid/persistable.rb +6 -3
- data/lib/mongoid/persistence_context.rb +6 -4
- data/lib/mongoid/query_cache.rb +13 -261
- data/lib/mongoid/railties/controller_runtime.rb +1 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/reloadable.rb +10 -8
- data/lib/mongoid/scopable.rb +15 -13
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/serializable.rb +10 -6
- data/lib/mongoid/stateful.rb +57 -10
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -2
- data/lib/mongoid/threaded/lifecycle.rb +5 -5
- data/lib/mongoid/threaded.rb +42 -12
- data/lib/mongoid/timestamps/created.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +2 -2
- data/lib/mongoid/touchable.rb +2 -3
- data/lib/mongoid/traversable.rb +5 -4
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/localizable.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +5 -7
- data/lib/mongoid/validatable/presence.rb +2 -2
- data/lib/mongoid/validatable/uniqueness.rb +9 -8
- data/lib/mongoid/validatable.rb +9 -6
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +19 -4
- data/lib/mongoid.rb +17 -3
- data/spec/config/mongoid.yml +16 -0
- data/spec/integration/app_spec.rb +10 -14
- data/spec/integration/associations/belongs_to_spec.rb +18 -0
- data/spec/integration/associations/embedded_spec.rb +15 -0
- data/spec/integration/associations/embeds_many_spec.rb +15 -2
- data/spec/integration/associations/embeds_one_spec.rb +18 -0
- data/spec/integration/associations/foreign_key_spec.rb +9 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
- data/spec/integration/associations/has_one_spec.rb +97 -1
- data/spec/integration/associations/scope_option_spec.rb +1 -1
- data/spec/integration/callbacks_models.rb +132 -1
- data/spec/integration/callbacks_spec.rb +381 -4
- data/spec/integration/criteria/range_spec.rb +95 -1
- data/spec/integration/discriminator_key_spec.rb +118 -80
- data/spec/integration/dots_and_dollars_spec.rb +277 -0
- data/spec/integration/i18n_fallbacks_spec.rb +3 -32
- data/spec/integration/matcher_examples_spec.rb +20 -13
- data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
- data/spec/integration/matcher_operator_spec.rb +3 -5
- data/spec/integration/persistence/range_field_spec.rb +350 -0
- data/spec/mongoid/association/counter_cache_spec.rb +1 -1
- data/spec/mongoid/association/depending_spec.rb +9 -9
- data/spec/mongoid/association/eager_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +255 -65
- data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
- data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -177
- data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
- data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
- data/spec/mongoid/association/syncable_spec.rb +15 -1
- data/spec/mongoid/atomic/paths_spec.rb +0 -14
- data/spec/mongoid/attributes/nested_spec.rb +80 -11
- data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
- data/spec/mongoid/attributes/projector_spec.rb +1 -5
- data/spec/mongoid/attributes_spec.rb +510 -33
- data/spec/mongoid/changeable_spec.rb +429 -37
- data/spec/mongoid/clients/factory_spec.rb +23 -30
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +149 -15
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +214 -31
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
- data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
- data/spec/mongoid/contextual/memory_spec.rb +850 -88
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +2309 -1127
- data/spec/mongoid/contextual/none_spec.rb +60 -21
- data/spec/mongoid/copyable_spec.rb +453 -11
- data/spec/mongoid/criteria/findable_spec.rb +86 -210
- data/spec/mongoid/criteria/includable_spec.rb +1492 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
- data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
- data/spec/mongoid/criteria/translator_spec.rb +132 -0
- data/spec/mongoid/criteria_projection_spec.rb +1 -5
- data/spec/mongoid/criteria_spec.rb +469 -1205
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
- data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
- data/spec/mongoid/errors/no_environment_spec.rb +3 -3
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
- data/spec/mongoid/extensions/array_spec.rb +16 -2
- data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
- data/spec/mongoid/extensions/binary_spec.rb +44 -9
- data/spec/mongoid/extensions/boolean_spec.rb +68 -82
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
- data/spec/mongoid/extensions/date_spec.rb +71 -1
- data/spec/mongoid/extensions/date_time_spec.rb +15 -9
- data/spec/mongoid/extensions/float_spec.rb +53 -74
- data/spec/mongoid/extensions/hash_spec.rb +33 -3
- data/spec/mongoid/extensions/integer_spec.rb +50 -64
- data/spec/mongoid/extensions/range_spec.rb +255 -54
- data/spec/mongoid/extensions/regexp_spec.rb +58 -33
- data/spec/mongoid/extensions/set_spec.rb +106 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -25
- data/spec/mongoid/extensions/symbol_spec.rb +18 -25
- data/spec/mongoid/extensions/time_spec.rb +639 -106
- data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
- data/spec/mongoid/factory_spec.rb +61 -1
- data/spec/mongoid/fields/localized_spec.rb +80 -37
- data/spec/mongoid/fields_spec.rb +500 -84
- data/spec/mongoid/findable_spec.rb +450 -58
- data/spec/mongoid/indexable/specification_spec.rb +2 -2
- data/spec/mongoid/indexable_spec.rb +55 -30
- data/spec/mongoid/interceptable_spec.rb +824 -22
- data/spec/mongoid/interceptable_spec_models.rb +235 -4
- data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
- data/spec/mongoid/mongoizable_spec.rb +285 -0
- data/spec/mongoid/persistable/creatable_spec.rb +2 -2
- data/spec/mongoid/persistable/deletable_spec.rb +28 -8
- data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
- data/spec/mongoid/persistence_context_spec.rb +31 -57
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +56 -215
- data/spec/mongoid/reloadable_spec.rb +83 -6
- data/spec/mongoid/scopable_spec.rb +91 -1
- data/spec/mongoid/serializable_spec.rb +9 -30
- data/spec/mongoid/shardable_spec.rb +4 -4
- data/spec/mongoid/stateful_spec.rb +150 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps_spec.rb +392 -4
- data/spec/mongoid/timestamps_spec_models.rb +67 -0
- data/spec/mongoid/touchable_spec.rb +390 -2
- data/spec/mongoid/touchable_spec_models.rb +14 -8
- data/spec/mongoid/traversable_spec.rb +13 -35
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
- data/spec/mongoid/warnings_spec.rb +35 -0
- data/spec/mongoid_spec.rb +34 -16
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/docker_runner.rb +8 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +2 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +28 -4
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/spec_helper.rb +5 -0
- data/spec/support/constraints.rb +24 -0
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +78 -0
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/augmentation.rb +12 -0
- data/spec/support/models/band.rb +4 -0
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/catalog.rb +24 -0
- data/spec/support/models/circus.rb +3 -0
- data/spec/support/models/cover.rb +10 -0
- data/spec/support/models/fanatic.rb +8 -0
- data/spec/support/models/implant.rb +9 -0
- data/spec/support/models/label.rb +2 -0
- data/spec/support/models/passport.rb +9 -0
- data/spec/support/models/person.rb +2 -0
- data/spec/support/models/player.rb +2 -0
- data/spec/support/models/powerup.rb +12 -0
- data/spec/support/models/product.rb +1 -0
- data/spec/support/models/purse.rb +9 -0
- data/spec/support/models/registry.rb +1 -0
- data/spec/support/models/school.rb +14 -0
- data/spec/support/models/shield.rb +18 -0
- data/spec/support/models/student.rb +14 -0
- data/spec/support/models/weapon.rb +12 -0
- data.tar.gz.sig +0 -0
- metadata +100 -22
- metadata.gz.sig +0 -0
- data/lib/mongoid/errors/eager_load.rb +0 -23
- data/lib/mongoid/errors/invalid_value.rb +0 -17
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
- data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -44,39 +44,6 @@ describe Mongoid::Contextual::Mongo do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe "#cached?" do
|
48
|
-
|
49
|
-
context "when the criteria is cached" do
|
50
|
-
|
51
|
-
let(:criteria) do
|
52
|
-
Band.all.cache
|
53
|
-
end
|
54
|
-
|
55
|
-
let(:context) do
|
56
|
-
described_class.new(criteria)
|
57
|
-
end
|
58
|
-
|
59
|
-
it "returns true" do
|
60
|
-
expect(context).to be_cached
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context "when the criteria is not cached" do
|
65
|
-
|
66
|
-
let(:criteria) do
|
67
|
-
Band.all
|
68
|
-
end
|
69
|
-
|
70
|
-
let(:context) do
|
71
|
-
described_class.new(criteria)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "returns false" do
|
75
|
-
expect(context).to_not be_cached
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
47
|
describe "#count" do
|
81
48
|
|
82
49
|
let!(:depeche) do
|
@@ -102,15 +69,17 @@ describe Mongoid::Contextual::Mongo do
|
|
102
69
|
end
|
103
70
|
end
|
104
71
|
|
105
|
-
context "when
|
72
|
+
context "when the query cache is enabled" do
|
73
|
+
query_cache_enabled
|
106
74
|
|
107
75
|
let(:context) do
|
108
|
-
described_class.new(criteria
|
76
|
+
described_class.new(criteria)
|
109
77
|
end
|
110
78
|
|
111
|
-
it "
|
112
|
-
|
113
|
-
|
79
|
+
it "only executes the count query once" do
|
80
|
+
expect_query(1) do
|
81
|
+
2.times { expect(context.count).to eq(1) }
|
82
|
+
end
|
114
83
|
end
|
115
84
|
end
|
116
85
|
|
@@ -189,6 +158,16 @@ describe Mongoid::Contextual::Mongo do
|
|
189
158
|
end
|
190
159
|
end
|
191
160
|
end
|
161
|
+
|
162
|
+
context 'when for_js is present' do
|
163
|
+
let(:context) do
|
164
|
+
Band.for_js('this.name == "Depeche Mode"')
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'counts the expected records' do
|
168
|
+
expect(context.count).to eq(1)
|
169
|
+
end
|
170
|
+
end
|
192
171
|
end
|
193
172
|
|
194
173
|
describe "#estimated_count" do
|
@@ -217,16 +196,18 @@ describe Mongoid::Contextual::Mongo do
|
|
217
196
|
end
|
218
197
|
end
|
219
198
|
|
220
|
-
context "when
|
199
|
+
context "when the query cache is enabled" do
|
200
|
+
query_cache_enabled
|
221
201
|
|
222
202
|
let(:context) do
|
223
|
-
described_class.new(criteria
|
203
|
+
described_class.new(criteria)
|
224
204
|
end
|
225
205
|
|
226
|
-
it "
|
227
|
-
|
228
|
-
|
229
|
-
|
206
|
+
it "the results are not cached" do
|
207
|
+
expect_query(2) do
|
208
|
+
2.times do
|
209
|
+
context.estimated_count
|
210
|
+
end
|
230
211
|
end
|
231
212
|
end
|
232
213
|
end
|
@@ -561,8 +542,22 @@ describe Mongoid::Contextual::Mongo do
|
|
561
542
|
context "when legacy_pluck_distinct is set" do
|
562
543
|
config_override :legacy_pluck_distinct, true
|
563
544
|
|
564
|
-
|
565
|
-
|
545
|
+
context 'when storing BigDecimal as string' do
|
546
|
+
config_override :map_big_decimal_to_decimal128, false
|
547
|
+
|
548
|
+
it "returns the non-demongoized distinct field values" do
|
549
|
+
expect(context.distinct(:sales).sort).to eq([ "1E2", "2E3" ])
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
context 'when storing BigDecimal as decimal128' do
|
554
|
+
config_override :map_big_decimal_to_decimal128, true
|
555
|
+
min_bson_version '4.15.0'
|
556
|
+
max_bson_version '4.99.99'
|
557
|
+
|
558
|
+
it "returns the non-demongoized distinct field values" do
|
559
|
+
expect(context.distinct(:sales).sort).to eq([ BSON::Decimal128.new("1E2"), BSON::Decimal128.new("2E3") ])
|
560
|
+
end
|
566
561
|
end
|
567
562
|
end
|
568
563
|
|
@@ -576,6 +571,8 @@ describe Mongoid::Contextual::Mongo do
|
|
576
571
|
end
|
577
572
|
|
578
573
|
context "when getting a localized field" do
|
574
|
+
with_default_i18n_configs
|
575
|
+
|
579
576
|
before do
|
580
577
|
I18n.locale = :en
|
581
578
|
d = Dictionary.create!(description: 'english-text')
|
@@ -584,10 +581,6 @@ describe Mongoid::Contextual::Mongo do
|
|
584
581
|
d.save!
|
585
582
|
end
|
586
583
|
|
587
|
-
after do
|
588
|
-
I18n.locale = :en
|
589
|
-
end
|
590
|
-
|
591
584
|
let(:criteria) do
|
592
585
|
Dictionary.criteria
|
593
586
|
end
|
@@ -680,16 +673,10 @@ describe Mongoid::Contextual::Mongo do
|
|
680
673
|
|
681
674
|
context 'when fallbacks are enabled with a locale list' do
|
682
675
|
require_fallbacks
|
676
|
+
with_default_i18n_configs
|
683
677
|
|
684
|
-
|
685
|
-
prev_fallbacks = I18n.fallbacks.dup
|
678
|
+
before do
|
686
679
|
I18n.fallbacks[:he] = [ :en ]
|
687
|
-
example.run
|
688
|
-
I18n.fallbacks = prev_fallbacks
|
689
|
-
end
|
690
|
-
|
691
|
-
after do
|
692
|
-
I18n.locale = :en
|
693
680
|
end
|
694
681
|
|
695
682
|
let(:distinct) do
|
@@ -709,7 +696,7 @@ describe Mongoid::Contextual::Mongo do
|
|
709
696
|
|
710
697
|
it "correctly uses the fallback" do
|
711
698
|
I18n.locale = :en
|
712
|
-
|
699
|
+
Dictionary.create!(description: 'english-text')
|
713
700
|
I18n.locale = :he
|
714
701
|
distinct.should == "english-text"
|
715
702
|
end
|
@@ -717,6 +704,8 @@ describe Mongoid::Contextual::Mongo do
|
|
717
704
|
end
|
718
705
|
|
719
706
|
context "when the localized field is embedded" do
|
707
|
+
with_default_i18n_configs
|
708
|
+
|
720
709
|
before do
|
721
710
|
p = Passport.new
|
722
711
|
I18n.locale = :en
|
@@ -727,10 +716,6 @@ describe Mongoid::Contextual::Mongo do
|
|
727
716
|
Person.create!(passport: p, employer_id: 12345)
|
728
717
|
end
|
729
718
|
|
730
|
-
after do
|
731
|
-
I18n.locale = :en
|
732
|
-
end
|
733
|
-
|
734
719
|
let(:criteria) do
|
735
720
|
Person.where(employer_id: 12345)
|
736
721
|
end
|
@@ -794,9 +779,11 @@ describe Mongoid::Contextual::Mongo do
|
|
794
779
|
|
795
780
|
context "when legacy_pluck_distinct is set" do
|
796
781
|
config_override :legacy_pluck_distinct, true
|
782
|
+
config_override :map_big_decimal_to_decimal128, true
|
783
|
+
max_bson_version '4.99.99'
|
797
784
|
|
798
785
|
it "returns the distinct matching fields" do
|
799
|
-
expect(context.distinct("label.sales")).to eq([
|
786
|
+
expect(context.distinct("label.sales")).to eq([ BSON::Decimal128.new('1E+2') ])
|
800
787
|
end
|
801
788
|
end
|
802
789
|
|
@@ -809,484 +796,860 @@ describe Mongoid::Contextual::Mongo do
|
|
809
796
|
end
|
810
797
|
end
|
811
798
|
|
812
|
-
describe "#
|
799
|
+
describe "#tally" do
|
800
|
+
let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
801
|
+
let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
802
|
+
let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
|
813
803
|
|
814
|
-
|
815
|
-
|
816
|
-
|
804
|
+
let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
|
805
|
+
let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
|
806
|
+
let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
|
817
807
|
|
818
|
-
let(:
|
819
|
-
|
820
|
-
|
808
|
+
let(:label1) { Label.new(name: "Atlantic") }
|
809
|
+
let(:label2) { Label.new(name: "Atlantic") }
|
810
|
+
let(:label3) { Label.new(name: "Columbia") }
|
821
811
|
|
822
|
-
|
823
|
-
|
812
|
+
before do
|
813
|
+
Band.create!(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1)
|
814
|
+
Band.create!(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2)
|
815
|
+
Band.create!(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3)
|
816
|
+
Band.create!(origin: "tally2", fanatics: fans1, genres: [1, 2])
|
817
|
+
Band.create!(origin: "tally2", fanatics: fans2, genres: [1, 2])
|
818
|
+
Band.create!(origin: "tally2", fanatics: fans3, genres: [1, 3])
|
824
819
|
end
|
825
820
|
|
826
|
-
|
827
|
-
min_server_version '3.4'
|
821
|
+
let(:criteria) { Band.where(origin: "tally") }
|
828
822
|
|
829
|
-
|
830
|
-
|
823
|
+
context "when tallying a string" do
|
824
|
+
let(:tally) do
|
825
|
+
criteria.tally(:name)
|
831
826
|
end
|
832
827
|
|
833
|
-
it "
|
834
|
-
|
835
|
-
expect(doc).to be_a(Mongoid::Document)
|
836
|
-
end
|
828
|
+
it "returns the correct hash" do
|
829
|
+
expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
|
837
830
|
end
|
831
|
+
end
|
838
832
|
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
end
|
833
|
+
context "using an aliased field" do
|
834
|
+
let(:tally) do
|
835
|
+
criteria.tally(:years)
|
843
836
|
end
|
844
837
|
|
845
|
-
it "returns
|
846
|
-
expect(
|
838
|
+
it "returns the correct hash" do
|
839
|
+
expect(tally).to eq(30 => 3)
|
847
840
|
end
|
848
841
|
end
|
849
842
|
|
850
|
-
context "when
|
851
|
-
|
852
|
-
|
853
|
-
context.each do |doc|
|
854
|
-
expect(doc).to be_a(Mongoid::Document)
|
855
|
-
end
|
856
|
-
end
|
857
|
-
|
858
|
-
it "iterates over the matching documents" do
|
859
|
-
context.each do |doc|
|
860
|
-
expect(doc.name).to eq("Depeche Mode")
|
861
|
-
end
|
843
|
+
context "when tallying a demongoizable field" do
|
844
|
+
let(:tally) do
|
845
|
+
criteria.tally(:sales)
|
862
846
|
end
|
863
847
|
|
864
|
-
it "returns
|
865
|
-
expect(
|
848
|
+
it "returns the correct hash" do
|
849
|
+
expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
|
866
850
|
end
|
867
851
|
end
|
868
852
|
|
869
|
-
context "when
|
853
|
+
context "when tallying a localized field" do
|
854
|
+
with_default_i18n_configs
|
870
855
|
|
871
|
-
|
872
|
-
|
856
|
+
before do
|
857
|
+
I18n.locale = :en
|
858
|
+
d1 = Dictionary.create!(description: 'en1')
|
859
|
+
d2 = Dictionary.create!(description: 'en1')
|
860
|
+
d3 = Dictionary.create!(description: 'en1')
|
861
|
+
d4 = Dictionary.create!(description: 'en2')
|
862
|
+
I18n.locale = :de
|
863
|
+
d1.description = 'de1'
|
864
|
+
d2.description = 'de1'
|
865
|
+
d3.description = 'de2'
|
866
|
+
d4.description = 'de3'
|
867
|
+
d1.save!
|
868
|
+
d2.save!
|
869
|
+
d3.save!
|
870
|
+
d4.save!
|
871
|
+
I18n.locale = :en
|
873
872
|
end
|
874
873
|
|
875
|
-
|
876
|
-
|
874
|
+
context "when getting the demongoized field" do
|
875
|
+
let(:tallied) do
|
876
|
+
Dictionary.tally(:description)
|
877
|
+
end
|
878
|
+
|
879
|
+
it "returns the translation for the current locale" do
|
880
|
+
expect(tallied).to eq("en1" => 3, "en2" => 1)
|
881
|
+
end
|
877
882
|
end
|
878
883
|
|
879
|
-
context "when
|
884
|
+
context "when getting a specific locale" do
|
885
|
+
let(:tallied) do
|
886
|
+
Dictionary.tally("description.de")
|
887
|
+
end
|
880
888
|
|
881
|
-
|
889
|
+
it "returns the translation for the the specific locale" do
|
890
|
+
expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
|
891
|
+
end
|
892
|
+
end
|
882
893
|
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
end
|
887
|
-
end
|
894
|
+
context "when getting the full hash" do
|
895
|
+
let(:tallied) do
|
896
|
+
Dictionary.tally("description_translations")
|
888
897
|
end
|
889
898
|
|
890
|
-
|
899
|
+
it "returns the correct hash" do
|
900
|
+
expect(tallied).to eq(
|
901
|
+
{"de" => "de1", "en" => "en1" } => 2,
|
902
|
+
{"de" => "de2", "en" => "en1" } => 1,
|
903
|
+
{"de" => "de3", "en" => "en2" } => 1
|
904
|
+
)
|
905
|
+
end
|
906
|
+
end
|
907
|
+
end
|
891
908
|
|
892
|
-
|
893
|
-
|
894
|
-
end
|
909
|
+
context "when tallying an embedded localized field" do
|
910
|
+
with_default_i18n_configs
|
895
911
|
|
896
|
-
|
897
|
-
|
898
|
-
|
912
|
+
before do
|
913
|
+
I18n.locale = :en
|
914
|
+
address1a = Address.new(name: "en1")
|
915
|
+
address1b = Address.new(name: "en2")
|
916
|
+
address2a = Address.new(name: "en1")
|
917
|
+
address2b = Address.new(name: "en3")
|
918
|
+
I18n.locale = :de
|
919
|
+
address1a.name = "de1"
|
920
|
+
address1b.name = "de2"
|
921
|
+
address2a.name = "de1"
|
922
|
+
address2b.name = "de3"
|
923
|
+
Person.create!(addresses: [ address1a, address1b ])
|
924
|
+
Person.create!(addresses: [ address2a, address2b ])
|
925
|
+
I18n.locale = :en
|
926
|
+
end
|
899
927
|
|
900
|
-
|
901
|
-
|
902
|
-
|
928
|
+
context "when getting the demongoized field" do
|
929
|
+
let(:tallied) do
|
930
|
+
Person.tally("addresses.name")
|
931
|
+
end
|
903
932
|
|
904
|
-
|
905
|
-
|
906
|
-
|
933
|
+
it "returns the translation for the current locale" do
|
934
|
+
expect(tallied).to eq(
|
935
|
+
[ "en1", "en2" ] => 1,
|
936
|
+
[ "en1", "en3" ] => 1,
|
937
|
+
)
|
938
|
+
end
|
939
|
+
end
|
907
940
|
|
908
|
-
|
941
|
+
context "when getting a specific locale" do
|
942
|
+
let(:tallied) do
|
943
|
+
Person.tally("addresses.name.de")
|
944
|
+
end
|
909
945
|
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
evt.command_name == 'getMore'
|
916
|
-
end
|
917
|
-
expect(get_more_events.length).to be(0)
|
918
|
-
ensure
|
919
|
-
context.view.client.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
|
920
|
-
end
|
946
|
+
it "returns the translation for the the specific locale" do
|
947
|
+
expect(tallied).to eq(
|
948
|
+
[ "de1", "de2" ] => 1,
|
949
|
+
[ "de1", "de3" ] => 1,
|
950
|
+
)
|
921
951
|
end
|
922
952
|
end
|
923
|
-
end
|
924
953
|
|
925
|
-
|
954
|
+
context "when getting the full hash" do
|
955
|
+
let(:tallied) do
|
956
|
+
Person.tally("addresses.name_translations")
|
957
|
+
end
|
926
958
|
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
959
|
+
it "returns the correct hash" do
|
960
|
+
expect(tallied).to eq(
|
961
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
|
962
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
|
963
|
+
)
|
964
|
+
end
|
931
965
|
end
|
932
966
|
|
933
|
-
|
934
|
-
|
967
|
+
end
|
968
|
+
|
969
|
+
context "when tallying an embedded field" do
|
970
|
+
let(:tally) do
|
971
|
+
criteria.tally("label.name")
|
935
972
|
end
|
936
973
|
|
937
|
-
|
938
|
-
|
974
|
+
it "returns the correct hash" do
|
975
|
+
expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
|
939
976
|
end
|
977
|
+
end
|
940
978
|
|
941
|
-
|
942
|
-
|
979
|
+
context "when tallying an element in an embeds_many field" do
|
980
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
981
|
+
|
982
|
+
let(:tally) do
|
983
|
+
criteria.tally("fanatics.age")
|
943
984
|
end
|
944
985
|
|
945
|
-
it
|
946
|
-
expect(
|
986
|
+
it "returns the correct hash" do
|
987
|
+
expect(tally).to eq(
|
988
|
+
[1, 2] => 2,
|
989
|
+
[1, 3] => 1
|
990
|
+
)
|
947
991
|
end
|
948
992
|
end
|
949
|
-
end
|
950
993
|
|
951
|
-
|
994
|
+
context "when tallying an embeds_many field" do
|
995
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
952
996
|
|
953
|
-
|
954
|
-
|
955
|
-
|
997
|
+
let(:tally) do
|
998
|
+
criteria.tally("fanatics")
|
999
|
+
end
|
956
1000
|
|
957
|
-
|
958
|
-
|
1001
|
+
it "returns the correct hash" do
|
1002
|
+
expect(tally).to eq(
|
1003
|
+
fans1.map(&:attributes) => 1,
|
1004
|
+
fans2.map(&:attributes) => 1,
|
1005
|
+
fans3.map(&:attributes) => 1,
|
1006
|
+
)
|
1007
|
+
end
|
959
1008
|
end
|
960
1009
|
|
961
|
-
context "when
|
1010
|
+
context "when tallying a field of type array" do
|
1011
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
962
1012
|
|
963
|
-
let(:
|
964
|
-
|
1013
|
+
let(:tally) do
|
1014
|
+
criteria.tally("genres")
|
965
1015
|
end
|
966
1016
|
|
967
|
-
it "
|
968
|
-
expect(
|
969
|
-
|
1017
|
+
it "returns the correct hash" do
|
1018
|
+
expect(tally).to eq(
|
1019
|
+
[1, 2] => 2,
|
1020
|
+
[1, 3] => 1
|
1021
|
+
)
|
970
1022
|
end
|
971
1023
|
end
|
972
|
-
end
|
973
1024
|
|
974
|
-
|
1025
|
+
context "when tallying an element from an array of hashes" do
|
1026
|
+
let(:criteria) { Band.where(origin: "tally") }
|
975
1027
|
|
976
|
-
|
977
|
-
|
1028
|
+
let(:tally) do
|
1029
|
+
criteria.tally("genres.x")
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "returns the correct hash without the nil keys" do
|
1033
|
+
expect(tally).to eq(
|
1034
|
+
[1, 2] => 2,
|
1035
|
+
[1, 3] => 1
|
1036
|
+
)
|
1037
|
+
end
|
978
1038
|
end
|
979
1039
|
|
980
|
-
context "when
|
1040
|
+
context "when tallying an element from an array of hashes; with duplicate" do
|
981
1041
|
|
982
|
-
|
983
|
-
Band.
|
1042
|
+
before do
|
1043
|
+
Band.create!(origin: "tally", genres: [ { x: 1 }, {x: 1} ] )
|
984
1044
|
end
|
985
1045
|
|
986
|
-
let(:
|
987
|
-
|
1046
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1047
|
+
|
1048
|
+
let(:tally) do
|
1049
|
+
criteria.tally("genres.x")
|
988
1050
|
end
|
989
1051
|
|
990
|
-
it "returns
|
991
|
-
expect(
|
1052
|
+
it "returns the correct hash without the nil keys" do
|
1053
|
+
expect(tally).to eq(
|
1054
|
+
[1, 2] => 2,
|
1055
|
+
[1, 3] => 1,
|
1056
|
+
[1, 1] => 1,
|
1057
|
+
)
|
992
1058
|
end
|
993
1059
|
end
|
994
1060
|
|
995
|
-
context "when
|
1061
|
+
context "when tallying an aliased field of type array" do
|
996
1062
|
|
997
|
-
|
998
|
-
|
1063
|
+
before do
|
1064
|
+
Person.create!(array: [ 1, 2 ])
|
1065
|
+
Person.create!(array: [ 1, 3 ])
|
999
1066
|
end
|
1000
1067
|
|
1001
|
-
let(:
|
1002
|
-
|
1068
|
+
let(:tally) do
|
1069
|
+
Person.tally("array")
|
1003
1070
|
end
|
1004
1071
|
|
1005
|
-
it "returns
|
1006
|
-
expect(
|
1072
|
+
it "returns the correct hash" do
|
1073
|
+
expect(tally).to eq(
|
1074
|
+
[1, 2] => 1,
|
1075
|
+
[1, 3] => 1
|
1076
|
+
)
|
1007
1077
|
end
|
1008
1078
|
end
|
1009
1079
|
|
1010
|
-
context "when
|
1080
|
+
context "when going multiple levels deep in arrays" do
|
1081
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1011
1082
|
|
1012
|
-
let(:
|
1013
|
-
|
1083
|
+
let(:tally) do
|
1084
|
+
criteria.tally("genres.y.z")
|
1014
1085
|
end
|
1015
1086
|
|
1016
|
-
|
1017
|
-
|
1087
|
+
it "returns the correct hash" do
|
1088
|
+
expect(tally).to eq(
|
1089
|
+
[1, 2] => 2,
|
1090
|
+
[1, 3] => 1
|
1091
|
+
)
|
1018
1092
|
end
|
1093
|
+
end
|
1019
1094
|
|
1020
|
-
|
1095
|
+
context "when going multiple levels deep in an array" do
|
1096
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1021
1097
|
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1098
|
+
let(:tally) do
|
1099
|
+
criteria.tally("genres.y.z")
|
1100
|
+
end
|
1025
1101
|
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1102
|
+
it "returns the correct hash" do
|
1103
|
+
expect(tally).to eq(
|
1104
|
+
[1, 2] => 2,
|
1105
|
+
[1, 3] => 1
|
1106
|
+
)
|
1030
1107
|
end
|
1031
1108
|
end
|
1032
1109
|
|
1033
|
-
context "when
|
1110
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
1034
1111
|
|
1035
|
-
|
1036
|
-
|
1112
|
+
before do
|
1113
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1114
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1115
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
1037
1116
|
end
|
1038
1117
|
|
1039
|
-
let(:
|
1040
|
-
|
1118
|
+
let(:tally) do
|
1119
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
1041
1120
|
end
|
1042
1121
|
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
it "does not hit the database" do
|
1050
|
-
expect(context).to receive(:view).never
|
1051
|
-
expect(context).to be_exists
|
1052
|
-
end
|
1122
|
+
it "returns the correct hash" do
|
1123
|
+
expect(tally).to eq(
|
1124
|
+
[ [ 1, 2 ] ] => 2,
|
1125
|
+
[ [ 1, 3 ] ] => 1
|
1126
|
+
)
|
1053
1127
|
end
|
1128
|
+
end
|
1054
1129
|
|
1055
|
-
|
1130
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
1056
1131
|
|
1057
|
-
|
1132
|
+
before do
|
1133
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
1134
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1135
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
1136
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1137
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
|
1138
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
1139
|
+
end
|
1058
1140
|
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1141
|
+
let(:tally) do
|
1142
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
1143
|
+
end
|
1062
1144
|
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1145
|
+
it "returns the correct hash" do
|
1146
|
+
expect(tally).to eq(
|
1147
|
+
[ [ 1, 2 ], [ 1, 2 ] ] => 2,
|
1148
|
+
[ [ 1, 3 ], [ 1, 3 ] ] => 1
|
1149
|
+
)
|
1068
1150
|
end
|
1069
1151
|
end
|
1070
|
-
end
|
1071
1152
|
|
1072
|
-
|
1153
|
+
context "when some keys are missing" do
|
1154
|
+
before do
|
1155
|
+
3.times { Band.create!(origin: "tally") }
|
1156
|
+
end
|
1073
1157
|
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1158
|
+
let(:tally) do
|
1159
|
+
criteria.tally(:name)
|
1160
|
+
end
|
1077
1161
|
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1162
|
+
it "returns the correct hash" do
|
1163
|
+
expect(tally).to eq(
|
1164
|
+
"Depeche Mode" => 1,
|
1165
|
+
"New Order" => 1,
|
1166
|
+
"10,000 Maniacs" => 1,
|
1167
|
+
nil => 3
|
1168
|
+
)
|
1169
|
+
end
|
1084
1170
|
end
|
1085
|
-
end
|
1086
1171
|
|
1087
|
-
|
1172
|
+
context "when the first element is an embeds_one" do
|
1173
|
+
before do
|
1174
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
1175
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
1176
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
|
1177
|
+
end
|
1088
1178
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1179
|
+
let(:tally) do
|
1180
|
+
Person.tally("name.translations.language")
|
1181
|
+
end
|
1092
1182
|
|
1093
|
-
|
1094
|
-
|
1183
|
+
it "returns the correct hash" do
|
1184
|
+
expect(tally).to eq(
|
1185
|
+
[1, 2] => 2,
|
1186
|
+
[1, 3] => 1
|
1187
|
+
)
|
1188
|
+
end
|
1095
1189
|
end
|
1096
1190
|
|
1097
|
-
context "when
|
1098
|
-
|
1099
|
-
context "when not providing options" do
|
1191
|
+
context "when tallying demongoizable values from typeless fields" do
|
1100
1192
|
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1193
|
+
let!(:person1) { Person.create!(ssn: /hello/) }
|
1194
|
+
let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
|
1195
|
+
let(:tally) { Person.tally("ssn") }
|
1104
1196
|
|
1105
|
-
|
1106
|
-
|
1197
|
+
let(:tallied_classes) do
|
1198
|
+
tally.keys.map(&:class).sort do |a, b|
|
1199
|
+
a.to_s.casecmp(b.to_s)
|
1107
1200
|
end
|
1201
|
+
end
|
1108
1202
|
|
1109
|
-
|
1110
|
-
|
1111
|
-
end
|
1203
|
+
context "< BSON 5" do
|
1204
|
+
max_bson_version '4.99.99'
|
1112
1205
|
|
1113
|
-
it "
|
1114
|
-
expect(
|
1206
|
+
it "stores the correct types in the database" do
|
1207
|
+
expect(Person.find(person1.id).attributes["ssn"]).to be_a BSON::Regexp::Raw
|
1208
|
+
expect(Person.find(person2.id).attributes["ssn"]).to be_a BSON::Decimal128
|
1115
1209
|
end
|
1116
1210
|
|
1117
|
-
it "
|
1118
|
-
expect(
|
1211
|
+
it "tallies the correct type" do
|
1212
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1119
1213
|
end
|
1120
1214
|
end
|
1121
1215
|
|
1122
|
-
context
|
1216
|
+
context '>= BSON 5' do
|
1217
|
+
min_bson_version "5.0"
|
1123
1218
|
|
1124
|
-
|
1125
|
-
|
1219
|
+
it "stores the correct types in the database" do
|
1220
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1221
|
+
expect(Person.find(person2.id).ssn).to be_a BigDecimal
|
1126
1222
|
end
|
1127
1223
|
|
1128
|
-
|
1129
|
-
|
1224
|
+
it "tallies the correct type" do
|
1225
|
+
expect(tallied_classes).to be == [ BigDecimal, BSON::Regexp::Raw ]
|
1130
1226
|
end
|
1227
|
+
end
|
1131
1228
|
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1229
|
+
context '>= BSON 5 with decimal128 allowed' do
|
1230
|
+
min_bson_version "5.0"
|
1231
|
+
config_override :allow_bson5_decimal128, true
|
1135
1232
|
|
1136
|
-
it "
|
1137
|
-
expect(
|
1233
|
+
it "stores the correct types in the database" do
|
1234
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1235
|
+
expect(Person.find(person2.id).ssn).to be_a BSON::Decimal128
|
1138
1236
|
end
|
1139
1237
|
|
1140
|
-
it "
|
1141
|
-
expect(
|
1142
|
-
expect(tool.reload.name).to be_nil
|
1238
|
+
it "tallies the correct type" do
|
1239
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1143
1240
|
end
|
1144
1241
|
end
|
1242
|
+
end
|
1243
|
+
end
|
1145
1244
|
|
1146
|
-
|
1245
|
+
describe "#each" do
|
1147
1246
|
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1247
|
+
before do
|
1248
|
+
Band.create!(name: "Depeche Mode")
|
1249
|
+
end
|
1151
1250
|
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1251
|
+
let(:criteria) do
|
1252
|
+
Band.where(name: "Depeche Mode")
|
1253
|
+
end
|
1155
1254
|
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1255
|
+
let(:context) do
|
1256
|
+
described_class.new(criteria)
|
1257
|
+
end
|
1159
1258
|
|
1160
|
-
|
1161
|
-
|
1162
|
-
end
|
1259
|
+
context 'when the criteria has a collation' do
|
1260
|
+
min_server_version '3.4'
|
1163
1261
|
|
1164
|
-
|
1165
|
-
|
1262
|
+
let(:criteria) do
|
1263
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
it "yields mongoid documents to the block" do
|
1267
|
+
context.each do |doc|
|
1268
|
+
expect(doc).to be_a(Mongoid::Document)
|
1166
1269
|
end
|
1270
|
+
end
|
1167
1271
|
|
1168
|
-
|
1169
|
-
|
1272
|
+
it "iterates over the matching documents" do
|
1273
|
+
context.each do |doc|
|
1274
|
+
expect(doc.name).to eq("Depeche Mode")
|
1170
1275
|
end
|
1171
1276
|
end
|
1172
1277
|
|
1173
|
-
|
1278
|
+
it "returns self" do
|
1279
|
+
expect(context.each{}).to be(context)
|
1280
|
+
end
|
1281
|
+
end
|
1174
1282
|
|
1175
|
-
|
1176
|
-
Band.where(name: "Depeche Mode")
|
1177
|
-
end
|
1283
|
+
context "when providing a block" do
|
1178
1284
|
|
1179
|
-
|
1180
|
-
|
1285
|
+
it "yields mongoid documents to the block" do
|
1286
|
+
context.each do |doc|
|
1287
|
+
expect(doc).to be_a(Mongoid::Document)
|
1181
1288
|
end
|
1289
|
+
end
|
1182
1290
|
|
1183
|
-
|
1184
|
-
|
1291
|
+
it "iterates over the matching documents" do
|
1292
|
+
context.each do |doc|
|
1293
|
+
expect(doc.name).to eq("Depeche Mode")
|
1185
1294
|
end
|
1295
|
+
end
|
1186
1296
|
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1297
|
+
it "returns self" do
|
1298
|
+
expect(context.each{}).to be(context)
|
1299
|
+
end
|
1300
|
+
end
|
1190
1301
|
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1302
|
+
context "when no block is provided" do
|
1303
|
+
|
1304
|
+
let(:enum) do
|
1305
|
+
context.each
|
1195
1306
|
end
|
1196
1307
|
|
1197
|
-
|
1198
|
-
|
1308
|
+
it "returns an enumerator" do
|
1309
|
+
expect(enum).to be_a(Enumerator)
|
1310
|
+
end
|
1199
1311
|
|
1200
|
-
|
1201
|
-
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1202
|
-
end
|
1312
|
+
context "when iterating over the enumerator" do
|
1203
1313
|
|
1204
|
-
|
1205
|
-
described_class.new(criteria)
|
1206
|
-
end
|
1314
|
+
context "when iterating with each" do
|
1207
1315
|
|
1208
|
-
|
1209
|
-
|
1316
|
+
it "yields mongoid documents to the block" do
|
1317
|
+
enum.each do |doc|
|
1318
|
+
expect(doc).to be_a(Mongoid::Document)
|
1319
|
+
end
|
1320
|
+
end
|
1210
1321
|
end
|
1211
1322
|
|
1212
|
-
|
1213
|
-
expect(result).to eq(depeche)
|
1214
|
-
end
|
1323
|
+
context "when iterating with next" do
|
1215
1324
|
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1325
|
+
before do
|
1326
|
+
10.times { |i| Band.create!(name: "Test #{i}") }
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
let(:criteria) do
|
1330
|
+
Band.batch_size(5)
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
it "yields mongoid documents" do
|
1334
|
+
expect(enum.next).to be_a(Mongoid::Document)
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
it "does not load all documents" do
|
1338
|
+
subscriber = Mrss::EventSubscriber.new
|
1339
|
+
context.view.client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
1340
|
+
|
1341
|
+
enum.next
|
1342
|
+
|
1343
|
+
find_events = subscriber.all_events.select do |evt|
|
1344
|
+
evt.command_name == 'find'
|
1345
|
+
end
|
1346
|
+
expect(find_events.length).to be(2)
|
1347
|
+
get_more_events = subscriber.all_events.select do |evt|
|
1348
|
+
evt.command_name == 'getMore'
|
1349
|
+
end
|
1350
|
+
expect(get_more_events.length).to be(0)
|
1351
|
+
ensure
|
1352
|
+
context.view.client.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
|
1353
|
+
end
|
1219
1354
|
end
|
1220
1355
|
end
|
1221
1356
|
end
|
1222
1357
|
|
1223
|
-
context
|
1358
|
+
context 'when the criteria has a parent document' do
|
1224
1359
|
|
1225
|
-
|
1226
|
-
|
1360
|
+
before do
|
1361
|
+
Post.create!(person: person)
|
1362
|
+
Post.create!(person: person)
|
1363
|
+
Post.create!(person: person)
|
1227
1364
|
end
|
1228
1365
|
|
1229
|
-
let(:
|
1230
|
-
|
1366
|
+
let(:person) do
|
1367
|
+
Person.new
|
1231
1368
|
end
|
1232
1369
|
|
1233
|
-
let(:
|
1234
|
-
|
1370
|
+
let(:criteria) do
|
1371
|
+
person.posts.all
|
1235
1372
|
end
|
1236
1373
|
|
1237
|
-
|
1238
|
-
|
1374
|
+
let(:persons) do
|
1375
|
+
criteria.collect(&:person)
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
it 'sets the same parent object on each related object' do
|
1379
|
+
expect(persons.uniq.size).to eq(1)
|
1239
1380
|
end
|
1240
1381
|
end
|
1241
1382
|
end
|
1242
1383
|
|
1243
|
-
describe "#
|
1384
|
+
describe "#eager_load" do
|
1244
1385
|
|
1245
|
-
let
|
1246
|
-
|
1386
|
+
let(:criteria) do
|
1387
|
+
Person.includes(:game)
|
1247
1388
|
end
|
1248
1389
|
|
1249
|
-
let
|
1250
|
-
|
1390
|
+
let(:context) do
|
1391
|
+
described_class.new(criteria)
|
1251
1392
|
end
|
1252
1393
|
|
1253
|
-
context "when
|
1394
|
+
context "when no documents are returned" do
|
1254
1395
|
|
1255
|
-
|
1396
|
+
let(:game_association) do
|
1397
|
+
Person.reflect_on_association(:game)
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
it "does not make any additional database queries" do
|
1401
|
+
expect(game_association).to receive(:eager_load).never
|
1402
|
+
context.send(:eager_load, [])
|
1403
|
+
end
|
1404
|
+
end
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
describe "#exists?" do
|
1408
|
+
|
1409
|
+
let!(:band) do
|
1410
|
+
Band.create!(name: "Depeche Mode", active: true)
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
context "when not passing options" do
|
1414
|
+
|
1415
|
+
context "when the count is zero" do
|
1256
1416
|
|
1257
1417
|
let(:criteria) do
|
1258
|
-
Band.where(name: "
|
1418
|
+
Band.where(name: "New Order")
|
1259
1419
|
end
|
1260
1420
|
|
1261
1421
|
let(:context) do
|
1262
1422
|
described_class.new(criteria)
|
1263
1423
|
end
|
1264
1424
|
|
1265
|
-
|
1266
|
-
context.
|
1267
|
-
end
|
1268
|
-
|
1269
|
-
it "returns the first matching document" do
|
1270
|
-
expect(result).to eq(depeche)
|
1271
|
-
end
|
1272
|
-
|
1273
|
-
it "updates the document in the database" do
|
1274
|
-
expect(depeche.reload.likes).to eq(1)
|
1425
|
+
it "returns false" do
|
1426
|
+
expect(context).to_not be_exists
|
1275
1427
|
end
|
1276
1428
|
end
|
1277
1429
|
|
1278
|
-
context "when
|
1430
|
+
context "when the count is greater than zero" do
|
1279
1431
|
|
1280
1432
|
let(:criteria) do
|
1281
|
-
Band.
|
1433
|
+
Band.where(name: "Depeche Mode")
|
1282
1434
|
end
|
1283
1435
|
|
1284
1436
|
let(:context) do
|
1285
1437
|
described_class.new(criteria)
|
1286
1438
|
end
|
1287
1439
|
|
1288
|
-
|
1289
|
-
context.
|
1440
|
+
it "returns true" do
|
1441
|
+
expect(context).to be_exists
|
1442
|
+
end
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
context "when caching is not enabled" do
|
1446
|
+
|
1447
|
+
let(:criteria) do
|
1448
|
+
Band.where(name: "Depeche Mode")
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
let(:context) do
|
1452
|
+
described_class.new(criteria)
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
context "when exists? already called and query cache is enabled" do
|
1456
|
+
query_cache_enabled
|
1457
|
+
|
1458
|
+
before do
|
1459
|
+
context.exists?
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
it "does not hit the database again" do
|
1463
|
+
expect_no_queries do
|
1464
|
+
expect(context).to be_exists
|
1465
|
+
end
|
1466
|
+
end
|
1467
|
+
end
|
1468
|
+
end
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
context "when passing an _id" do
|
1472
|
+
|
1473
|
+
context "when its of type BSON::ObjectId" do
|
1474
|
+
|
1475
|
+
context "when calling it on the class" do
|
1476
|
+
|
1477
|
+
it "returns true" do
|
1478
|
+
expect(Band.exists?(band._id)).to be true
|
1479
|
+
end
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
context "when calling it on a criteria that includes the object" do
|
1483
|
+
|
1484
|
+
it "returns true" do
|
1485
|
+
expect(Band.where(name: band.name).exists?(band._id)).to be true
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
context "when calling it on a criteria that does not include the object" do
|
1490
|
+
|
1491
|
+
it "returns false" do
|
1492
|
+
expect(Band.where(name: "bogus").exists?(band._id)).to be false
|
1493
|
+
end
|
1494
|
+
end
|
1495
|
+
|
1496
|
+
context "when the id does not exist" do
|
1497
|
+
|
1498
|
+
it "returns false" do
|
1499
|
+
expect(Band.exists?(BSON::ObjectId.new)).to be false
|
1500
|
+
end
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
context "when its of type String" do
|
1505
|
+
|
1506
|
+
context "when the id exists" do
|
1507
|
+
|
1508
|
+
it "returns true" do
|
1509
|
+
expect(Band.exists?(band._id.to_s)).to be true
|
1510
|
+
end
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
context "when the id does not exist" do
|
1514
|
+
|
1515
|
+
it "returns false" do
|
1516
|
+
expect(Band.exists?(BSON::ObjectId.new.to_s)).to be false
|
1517
|
+
end
|
1518
|
+
end
|
1519
|
+
end
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
context "when passing a hash" do
|
1523
|
+
|
1524
|
+
context "when calling it on the class" do
|
1525
|
+
|
1526
|
+
it "returns true" do
|
1527
|
+
expect(Band.exists?(name: band.name)).to be true
|
1528
|
+
end
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
context "when calling it on a criteria that includes the object" do
|
1532
|
+
|
1533
|
+
it "returns true" do
|
1534
|
+
expect(Band.where(active: true).exists?(name: band.name)).to be true
|
1535
|
+
end
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
context "when calling it on a criteria that does not include the object" do
|
1539
|
+
|
1540
|
+
it "returns false" do
|
1541
|
+
expect(Band.where(active: false).exists?(name: band.name)).to be false
|
1542
|
+
end
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
context "when the conditions don't match" do
|
1546
|
+
|
1547
|
+
it "returns false" do
|
1548
|
+
expect(Band.exists?(name: "bogus")).to be false
|
1549
|
+
end
|
1550
|
+
end
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
context "when passing false" do
|
1554
|
+
|
1555
|
+
it "returns false" do
|
1556
|
+
expect(Band.exists?(false)).to be false
|
1557
|
+
end
|
1558
|
+
end
|
1559
|
+
|
1560
|
+
context "when passing nil" do
|
1561
|
+
|
1562
|
+
it "returns false" do
|
1563
|
+
expect(Band.exists?(nil)).to be false
|
1564
|
+
end
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
context "when the limit is 0" do
|
1568
|
+
|
1569
|
+
it "returns false" do
|
1570
|
+
expect(Band.limit(0).exists?).to be false
|
1571
|
+
end
|
1572
|
+
end
|
1573
|
+
|
1574
|
+
context "when the criteria limit is 0" do
|
1575
|
+
|
1576
|
+
it "returns false" do
|
1577
|
+
expect(Band.criteria.limit(0).exists?).to be false
|
1578
|
+
end
|
1579
|
+
end
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
describe "#explain" do
|
1583
|
+
|
1584
|
+
let(:criteria) do
|
1585
|
+
Band.where(name: "Depeche Mode")
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
let(:context) do
|
1589
|
+
described_class.new(criteria)
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
it "returns the criteria explain path" do
|
1593
|
+
explain = context.explain
|
1594
|
+
expect(explain).to_not be_empty
|
1595
|
+
expect(explain.keys).to include("queryPlanner", "executionStats", "serverInfo")
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
it "respects options passed to explain" do
|
1599
|
+
explain = context.explain(verbosity: :query_planner)
|
1600
|
+
expect(explain).to_not be_empty
|
1601
|
+
expect(explain.keys).to include("queryPlanner", "serverInfo")
|
1602
|
+
expect(explain.keys).not_to include("executionStats")
|
1603
|
+
end
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
describe "#find_one_and_replace" do
|
1607
|
+
|
1608
|
+
let!(:depeche) do
|
1609
|
+
Band.create!(name: "Depeche Mode")
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
let!(:tool) do
|
1613
|
+
Band.create!(name: "Tool")
|
1614
|
+
end
|
1615
|
+
|
1616
|
+
context "when the selector matches" do
|
1617
|
+
|
1618
|
+
context "when not providing options" do
|
1619
|
+
|
1620
|
+
let(:criteria) do
|
1621
|
+
Band.where(name: "Depeche Mode")
|
1622
|
+
end
|
1623
|
+
|
1624
|
+
let(:context) do
|
1625
|
+
described_class.new(criteria)
|
1626
|
+
end
|
1627
|
+
|
1628
|
+
let!(:result) do
|
1629
|
+
context.find_one_and_replace(name: 'FKA Twigs')
|
1630
|
+
end
|
1631
|
+
|
1632
|
+
it "returns the first matching document" do
|
1633
|
+
expect(result).to eq(depeche)
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
it "updates the document in the database" do
|
1637
|
+
expect(depeche.reload.name).to eq('FKA Twigs')
|
1638
|
+
end
|
1639
|
+
end
|
1640
|
+
|
1641
|
+
context "when sorting" do
|
1642
|
+
|
1643
|
+
let(:criteria) do
|
1644
|
+
Band.desc(:name)
|
1645
|
+
end
|
1646
|
+
|
1647
|
+
let(:context) do
|
1648
|
+
described_class.new(criteria)
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
let!(:result) do
|
1652
|
+
context.find_one_and_replace(likes: 1)
|
1290
1653
|
end
|
1291
1654
|
|
1292
1655
|
it "returns the first matching document" do
|
@@ -1295,6 +1658,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1295
1658
|
|
1296
1659
|
it "updates the document in the database" do
|
1297
1660
|
expect(tool.reload.likes).to eq(1)
|
1661
|
+
expect(tool.reload.name).to be_nil
|
1298
1662
|
end
|
1299
1663
|
end
|
1300
1664
|
|
@@ -1309,7 +1673,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1309
1673
|
end
|
1310
1674
|
|
1311
1675
|
let!(:result) do
|
1312
|
-
context.
|
1676
|
+
context.find_one_and_replace(name: 'FKA Twigs', likes: 1)
|
1313
1677
|
end
|
1314
1678
|
|
1315
1679
|
it "returns the first matching document" do
|
@@ -1336,7 +1700,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1336
1700
|
end
|
1337
1701
|
|
1338
1702
|
let!(:result) do
|
1339
|
-
context.
|
1703
|
+
context.find_one_and_replace({ likes: 1 }, return_document: :after)
|
1340
1704
|
end
|
1341
1705
|
|
1342
1706
|
it "returns the first matching document" do
|
@@ -1344,6 +1708,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1344
1708
|
end
|
1345
1709
|
|
1346
1710
|
it "returns the updated document" do
|
1711
|
+
expect(result.name).to be_nil
|
1347
1712
|
expect(result.likes).to eq(1)
|
1348
1713
|
end
|
1349
1714
|
end
|
@@ -1360,7 +1725,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1360
1725
|
end
|
1361
1726
|
|
1362
1727
|
let!(:result) do
|
1363
|
-
context.
|
1728
|
+
context.find_one_and_replace({ likes: 1 }, return_document: :after)
|
1364
1729
|
end
|
1365
1730
|
|
1366
1731
|
it "returns the first matching document" do
|
@@ -1369,6 +1734,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1369
1734
|
|
1370
1735
|
it "returns the updated document" do
|
1371
1736
|
expect(result.likes).to eq(1)
|
1737
|
+
expect(result.name).to be_nil
|
1372
1738
|
end
|
1373
1739
|
end
|
1374
1740
|
end
|
@@ -1376,7 +1742,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1376
1742
|
context "when the selector does not match" do
|
1377
1743
|
|
1378
1744
|
let(:criteria) do
|
1379
|
-
Band.where(name: "
|
1745
|
+
Band.where(name: "DEPECHE MODE")
|
1380
1746
|
end
|
1381
1747
|
|
1382
1748
|
let(:context) do
|
@@ -1384,7 +1750,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1384
1750
|
end
|
1385
1751
|
|
1386
1752
|
let(:result) do
|
1387
|
-
context.
|
1753
|
+
context.find_one_and_replace(name: 'FKA Twigs')
|
1388
1754
|
end
|
1389
1755
|
|
1390
1756
|
it "returns nil" do
|
@@ -1393,41 +1759,22 @@ describe Mongoid::Contextual::Mongo do
|
|
1393
1759
|
end
|
1394
1760
|
end
|
1395
1761
|
|
1396
|
-
describe "#
|
1762
|
+
describe "#find_one_and_update" do
|
1397
1763
|
|
1398
1764
|
let!(:depeche) do
|
1399
1765
|
Band.create!(name: "Depeche Mode")
|
1400
1766
|
end
|
1401
1767
|
|
1402
|
-
let(:
|
1403
|
-
Band.
|
1404
|
-
end
|
1405
|
-
|
1406
|
-
let(:context) do
|
1407
|
-
described_class.new(criteria)
|
1408
|
-
end
|
1409
|
-
|
1410
|
-
let!(:result) do
|
1411
|
-
context.find_one_and_delete
|
1768
|
+
let!(:tool) do
|
1769
|
+
Band.create!(name: "Tool")
|
1412
1770
|
end
|
1413
1771
|
|
1414
|
-
context
|
1415
|
-
|
1416
|
-
it "returns the first matching document" do
|
1417
|
-
expect(result).to eq(depeche)
|
1418
|
-
end
|
1419
|
-
|
1420
|
-
it "deletes the document from the database" do
|
1421
|
-
expect {
|
1422
|
-
depeche.reload
|
1423
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
1424
|
-
end
|
1772
|
+
context "when the selector matches" do
|
1425
1773
|
|
1426
|
-
context
|
1427
|
-
min_server_version '3.4'
|
1774
|
+
context "when not providing options" do
|
1428
1775
|
|
1429
1776
|
let(:criteria) do
|
1430
|
-
Band.where(name: "
|
1777
|
+
Band.where(name: "Depeche Mode")
|
1431
1778
|
end
|
1432
1779
|
|
1433
1780
|
let(:context) do
|
@@ -1435,72 +1782,244 @@ describe Mongoid::Contextual::Mongo do
|
|
1435
1782
|
end
|
1436
1783
|
|
1437
1784
|
let!(:result) do
|
1438
|
-
context.
|
1785
|
+
context.find_one_and_update("$inc" => { likes: 1 })
|
1439
1786
|
end
|
1440
1787
|
|
1441
1788
|
it "returns the first matching document" do
|
1442
1789
|
expect(result).to eq(depeche)
|
1443
1790
|
end
|
1444
1791
|
|
1445
|
-
it "
|
1446
|
-
expect
|
1447
|
-
depeche.reload
|
1448
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
1792
|
+
it "updates the document in the database" do
|
1793
|
+
expect(depeche.reload.likes).to eq(1)
|
1449
1794
|
end
|
1450
1795
|
end
|
1451
|
-
end
|
1452
|
-
|
1453
|
-
context 'when the selector does not match a document' do
|
1454
|
-
|
1455
|
-
let(:criteria) do
|
1456
|
-
Band.where(name: "Placebo")
|
1457
|
-
end
|
1458
|
-
|
1459
|
-
let(:context) do
|
1460
|
-
described_class.new(criteria)
|
1461
|
-
end
|
1462
|
-
|
1463
|
-
let(:result) do
|
1464
|
-
context.find_one_and_delete
|
1465
|
-
end
|
1466
|
-
|
1467
|
-
it "returns nil" do
|
1468
|
-
expect(result).to be_nil
|
1469
|
-
end
|
1470
|
-
end
|
1471
|
-
end
|
1472
|
-
|
1473
|
-
[ :first, :one ].each do |method|
|
1474
|
-
|
1475
|
-
describe "##{method}" do
|
1476
|
-
|
1477
|
-
let!(:depeche_mode) do
|
1478
|
-
Band.create!(name: "Depeche Mode")
|
1479
|
-
end
|
1480
|
-
|
1481
|
-
let!(:new_order) do
|
1482
|
-
Band.create!(name: "New Order")
|
1483
|
-
end
|
1484
|
-
|
1485
|
-
let!(:rolling_stones) do
|
1486
|
-
Band.create!(name: "The Rolling Stones")
|
1487
|
-
end
|
1488
1796
|
|
1489
|
-
context "when
|
1797
|
+
context "when sorting" do
|
1490
1798
|
|
1491
1799
|
let(:criteria) do
|
1492
|
-
Band.
|
1800
|
+
Band.desc(:name)
|
1493
1801
|
end
|
1494
1802
|
|
1495
1803
|
let(:context) do
|
1496
1804
|
described_class.new(criteria)
|
1497
1805
|
end
|
1498
1806
|
|
1499
|
-
|
1500
|
-
|
1807
|
+
let!(:result) do
|
1808
|
+
context.find_one_and_update("$inc" => { likes: 1 })
|
1501
1809
|
end
|
1502
1810
|
|
1503
|
-
|
1811
|
+
it "returns the first matching document" do
|
1812
|
+
expect(result).to eq(tool)
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
it "updates the document in the database" do
|
1816
|
+
expect(tool.reload.likes).to eq(1)
|
1817
|
+
end
|
1818
|
+
end
|
1819
|
+
|
1820
|
+
context "when limiting fields" do
|
1821
|
+
|
1822
|
+
let(:criteria) do
|
1823
|
+
Band.only(:_id)
|
1824
|
+
end
|
1825
|
+
|
1826
|
+
let(:context) do
|
1827
|
+
described_class.new(criteria)
|
1828
|
+
end
|
1829
|
+
|
1830
|
+
let!(:result) do
|
1831
|
+
context.find_one_and_update("$inc" => { likes: 1 })
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
it "returns the first matching document" do
|
1835
|
+
expect(result).to eq(depeche)
|
1836
|
+
end
|
1837
|
+
|
1838
|
+
it "limits the returned fields" do
|
1839
|
+
expect(result.name).to be_nil
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
it "updates the document in the database" do
|
1843
|
+
expect(depeche.reload.likes).to eq(1)
|
1844
|
+
end
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
context "when returning new" do
|
1848
|
+
|
1849
|
+
let(:criteria) do
|
1850
|
+
Band.where(name: "Depeche Mode")
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
let(:context) do
|
1854
|
+
described_class.new(criteria)
|
1855
|
+
end
|
1856
|
+
|
1857
|
+
let!(:result) do
|
1858
|
+
context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
|
1859
|
+
end
|
1860
|
+
|
1861
|
+
it "returns the first matching document" do
|
1862
|
+
expect(result).to eq(depeche)
|
1863
|
+
end
|
1864
|
+
|
1865
|
+
it "returns the updated document" do
|
1866
|
+
expect(result.likes).to eq(1)
|
1867
|
+
end
|
1868
|
+
end
|
1869
|
+
|
1870
|
+
context 'when a collation is specified on the criteria' do
|
1871
|
+
min_server_version '3.4'
|
1872
|
+
|
1873
|
+
let(:criteria) do
|
1874
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1875
|
+
end
|
1876
|
+
|
1877
|
+
let(:context) do
|
1878
|
+
described_class.new(criteria)
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
let!(:result) do
|
1882
|
+
context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
it "returns the first matching document" do
|
1886
|
+
expect(result).to eq(depeche)
|
1887
|
+
end
|
1888
|
+
|
1889
|
+
it "returns the updated document" do
|
1890
|
+
expect(result.likes).to eq(1)
|
1891
|
+
end
|
1892
|
+
end
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
context "when the selector does not match" do
|
1896
|
+
|
1897
|
+
let(:criteria) do
|
1898
|
+
Band.where(name: "Placebo")
|
1899
|
+
end
|
1900
|
+
|
1901
|
+
let(:context) do
|
1902
|
+
described_class.new(criteria)
|
1903
|
+
end
|
1904
|
+
|
1905
|
+
let(:result) do
|
1906
|
+
context.find_one_and_update("$inc" => { likes: 1 })
|
1907
|
+
end
|
1908
|
+
|
1909
|
+
it "returns nil" do
|
1910
|
+
expect(result).to be_nil
|
1911
|
+
end
|
1912
|
+
end
|
1913
|
+
end
|
1914
|
+
|
1915
|
+
describe "#find_one_and_delete" do
|
1916
|
+
|
1917
|
+
let!(:depeche) do
|
1918
|
+
Band.create!(name: "Depeche Mode")
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
let(:criteria) do
|
1922
|
+
Band.where(name: "Depeche Mode")
|
1923
|
+
end
|
1924
|
+
|
1925
|
+
let(:context) do
|
1926
|
+
described_class.new(criteria)
|
1927
|
+
end
|
1928
|
+
|
1929
|
+
let!(:result) do
|
1930
|
+
context.find_one_and_delete
|
1931
|
+
end
|
1932
|
+
|
1933
|
+
context 'when the selector matches a document' do
|
1934
|
+
|
1935
|
+
it "returns the first matching document" do
|
1936
|
+
expect(result).to eq(depeche)
|
1937
|
+
end
|
1938
|
+
|
1939
|
+
it "deletes the document from the database" do
|
1940
|
+
expect {
|
1941
|
+
depeche.reload
|
1942
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
1943
|
+
end
|
1944
|
+
|
1945
|
+
context 'when a collation is specified on the criteria' do
|
1946
|
+
min_server_version '3.4'
|
1947
|
+
|
1948
|
+
let(:criteria) do
|
1949
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1950
|
+
end
|
1951
|
+
|
1952
|
+
let(:context) do
|
1953
|
+
described_class.new(criteria)
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
let!(:result) do
|
1957
|
+
context.find_one_and_delete
|
1958
|
+
end
|
1959
|
+
|
1960
|
+
it "returns the first matching document" do
|
1961
|
+
expect(result).to eq(depeche)
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
it "deletes the document from the database" do
|
1965
|
+
expect {
|
1966
|
+
depeche.reload
|
1967
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
1968
|
+
end
|
1969
|
+
end
|
1970
|
+
end
|
1971
|
+
|
1972
|
+
context 'when the selector does not match a document' do
|
1973
|
+
|
1974
|
+
let(:criteria) do
|
1975
|
+
Band.where(name: "Placebo")
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
let(:context) do
|
1979
|
+
described_class.new(criteria)
|
1980
|
+
end
|
1981
|
+
|
1982
|
+
let(:result) do
|
1983
|
+
context.find_one_and_delete
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
it "returns nil" do
|
1987
|
+
expect(result).to be_nil
|
1988
|
+
end
|
1989
|
+
end
|
1990
|
+
end
|
1991
|
+
|
1992
|
+
[ :first, :one ].each do |method|
|
1993
|
+
|
1994
|
+
describe "##{method}" do
|
1995
|
+
|
1996
|
+
let!(:depeche_mode) do
|
1997
|
+
Band.create!(name: "Depeche Mode")
|
1998
|
+
end
|
1999
|
+
|
2000
|
+
let!(:new_order) do
|
2001
|
+
Band.create!(name: "New Order")
|
2002
|
+
end
|
2003
|
+
|
2004
|
+
let!(:rolling_stones) do
|
2005
|
+
Band.create!(name: "The Rolling Stones")
|
2006
|
+
end
|
2007
|
+
|
2008
|
+
context "when the context is not cached" do
|
2009
|
+
|
2010
|
+
let(:criteria) do
|
2011
|
+
Band.where(name: "Depeche Mode")
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
let(:context) do
|
2015
|
+
described_class.new(criteria)
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
it "returns the first matching document" do
|
2019
|
+
expect(context.send(method)).to eq(depeche_mode)
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
context 'when the criteria has a collation' do
|
1504
2023
|
min_server_version '3.4'
|
1505
2024
|
|
1506
2025
|
let(:criteria) do
|
@@ -1554,31 +2073,13 @@ describe Mongoid::Contextual::Mongo do
|
|
1554
2073
|
expect(context.send(method)).to eq(depeche_mode)
|
1555
2074
|
end
|
1556
2075
|
|
1557
|
-
context
|
2076
|
+
context 'when calling #last' do
|
1558
2077
|
|
1559
|
-
it 'returns the
|
2078
|
+
it 'returns the last document, sorted by _id' do
|
1560
2079
|
expect(context.send(method)).to eq(depeche_mode)
|
1561
2080
|
expect(context.last).to eq(rolling_stones)
|
1562
2081
|
end
|
1563
2082
|
end
|
1564
|
-
|
1565
|
-
context 'with option { id_sort: :none }' do
|
1566
|
-
let(:opts) do
|
1567
|
-
{ id_sort: :none }
|
1568
|
-
end
|
1569
|
-
|
1570
|
-
it 'applies the sort on _id' do
|
1571
|
-
expect(context.send(method, opts)).to eq(depeche_mode)
|
1572
|
-
end
|
1573
|
-
|
1574
|
-
context "when calling ##{method}" do
|
1575
|
-
|
1576
|
-
it 'doesn\'t apply a sort on _id' do
|
1577
|
-
expect(context.send(method, opts)).to eq(depeche_mode)
|
1578
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
1579
|
-
end
|
1580
|
-
end
|
1581
|
-
end
|
1582
2083
|
end
|
1583
2084
|
|
1584
2085
|
context 'when the criteria has a sort' do
|
@@ -1602,25 +2103,6 @@ describe Mongoid::Contextual::Mongo do
|
|
1602
2103
|
expect(context.last).to eq(depeche_mode)
|
1603
2104
|
end
|
1604
2105
|
end
|
1605
|
-
|
1606
|
-
context 'with option { id_sort: :none }' do
|
1607
|
-
|
1608
|
-
let(:opts) do
|
1609
|
-
{ id_sort: :none }
|
1610
|
-
end
|
1611
|
-
|
1612
|
-
it 'uses the preexisting sort' do
|
1613
|
-
expect(context.send(method, opts)).to eq(rolling_stones)
|
1614
|
-
end
|
1615
|
-
|
1616
|
-
context 'when calling #last' do
|
1617
|
-
|
1618
|
-
it 'uses the preexisting sort' do
|
1619
|
-
expect(context.send(method, opts)).to eq(rolling_stones)
|
1620
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
1621
|
-
end
|
1622
|
-
end
|
1623
|
-
end
|
1624
2106
|
end
|
1625
2107
|
|
1626
2108
|
context "when using .sort" do
|
@@ -1649,28 +2131,17 @@ describe Mongoid::Contextual::Mongo do
|
|
1649
2131
|
end
|
1650
2132
|
end
|
1651
2133
|
|
1652
|
-
context "when the
|
2134
|
+
context "when the query cache is enabled" do
|
2135
|
+
query_cache_enabled
|
1653
2136
|
|
1654
2137
|
let(:criteria) do
|
1655
|
-
Band.where(name: "Depeche Mode")
|
2138
|
+
Band.where(name: "Depeche Mode")
|
1656
2139
|
end
|
1657
2140
|
|
1658
2141
|
let(:context) do
|
1659
2142
|
described_class.new(criteria)
|
1660
2143
|
end
|
1661
2144
|
|
1662
|
-
context "when the cache is loaded" do
|
1663
|
-
|
1664
|
-
before do
|
1665
|
-
context.to_a
|
1666
|
-
end
|
1667
|
-
|
1668
|
-
it "returns the first document without touching the database" do
|
1669
|
-
expect(context).to receive(:view).never
|
1670
|
-
expect(context.send(method)).to eq(depeche_mode)
|
1671
|
-
end
|
1672
|
-
end
|
1673
|
-
|
1674
2145
|
context "when first method was called before" do
|
1675
2146
|
|
1676
2147
|
before do
|
@@ -1678,8 +2149,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1678
2149
|
end
|
1679
2150
|
|
1680
2151
|
it "returns the first document without touching the database" do
|
1681
|
-
|
1682
|
-
|
2152
|
+
expect_no_queries do
|
2153
|
+
expect(context.send(method)).to eq(depeche_mode)
|
2154
|
+
end
|
1683
2155
|
end
|
1684
2156
|
end
|
1685
2157
|
end
|
@@ -1733,86 +2205,30 @@ describe Mongoid::Contextual::Mongo do
|
|
1733
2205
|
end
|
1734
2206
|
end
|
1735
2207
|
|
1736
|
-
context "when the
|
2208
|
+
context "when the query cache is enabled" do
|
1737
2209
|
|
1738
2210
|
let(:context) do
|
1739
2211
|
described_class.new(criteria)
|
1740
2212
|
end
|
1741
2213
|
|
1742
|
-
context "when
|
2214
|
+
context "when calling first beforehand" do
|
2215
|
+
query_cache_enabled
|
1743
2216
|
|
1744
|
-
|
1745
|
-
|
2217
|
+
let(:context) do
|
2218
|
+
described_class.new(criteria)
|
1746
2219
|
end
|
1747
2220
|
|
1748
|
-
|
2221
|
+
let(:criteria) do
|
2222
|
+
Band.all
|
2223
|
+
end
|
1749
2224
|
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
2225
|
+
before do
|
2226
|
+
context.first(before_limit)
|
2227
|
+
end
|
1753
2228
|
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
context.send(method, 3)
|
1758
|
-
end
|
1759
|
-
|
1760
|
-
it "returns all of the documents without touching the database" do
|
1761
|
-
expect(context).to receive(:view).never
|
1762
|
-
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
1763
|
-
end
|
1764
|
-
end
|
1765
|
-
|
1766
|
-
context "when requesting fewer than all of the documents" do
|
1767
|
-
|
1768
|
-
let(:docs) do
|
1769
|
-
context.send(method, 2)
|
1770
|
-
end
|
1771
|
-
|
1772
|
-
it "returns all of the documents without touching the database" do
|
1773
|
-
expect(context).to receive(:view).never
|
1774
|
-
expect(docs).to eq([ depeche_mode, new_order ])
|
1775
|
-
end
|
1776
|
-
end
|
1777
|
-
end
|
1778
|
-
|
1779
|
-
context "when only one document is cached" do
|
1780
|
-
|
1781
|
-
let(:criteria) do
|
1782
|
-
Band.where(name: "Depeche Mode").cache
|
1783
|
-
end
|
1784
|
-
|
1785
|
-
context "when requesting one document" do
|
1786
|
-
|
1787
|
-
let(:docs) do
|
1788
|
-
context.send(method, 1)
|
1789
|
-
end
|
1790
|
-
|
1791
|
-
it "returns one document without touching the database" do
|
1792
|
-
expect(context).to receive(:view).never
|
1793
|
-
expect(docs).to eq([ depeche_mode ])
|
1794
|
-
end
|
1795
|
-
end
|
1796
|
-
end
|
1797
|
-
end
|
1798
|
-
|
1799
|
-
context "when the first method was called before" do
|
1800
|
-
|
1801
|
-
let(:context) do
|
1802
|
-
described_class.new(criteria)
|
1803
|
-
end
|
1804
|
-
|
1805
|
-
let(:criteria) do
|
1806
|
-
Band.all.cache
|
1807
|
-
end
|
1808
|
-
|
1809
|
-
before do
|
1810
|
-
context.first(before_limit)
|
1811
|
-
end
|
1812
|
-
|
1813
|
-
let(:docs) do
|
1814
|
-
context.send(method, limit)
|
1815
|
-
end
|
2229
|
+
let(:docs) do
|
2230
|
+
context.send(method, limit)
|
2231
|
+
end
|
1816
2232
|
|
1817
2233
|
context "when getting all of the documents before" do
|
1818
2234
|
let(:before_limit) { 3 }
|
@@ -1821,8 +2237,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1821
2237
|
let(:limit) { 3 }
|
1822
2238
|
|
1823
2239
|
it "returns all documents without touching the database" do
|
1824
|
-
|
1825
|
-
|
2240
|
+
expect_no_queries do
|
2241
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2242
|
+
end
|
1826
2243
|
end
|
1827
2244
|
end
|
1828
2245
|
|
@@ -1830,8 +2247,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1830
2247
|
let(:limit) { 2 }
|
1831
2248
|
|
1832
2249
|
it "returns the correct documents without touching the database" do
|
1833
|
-
|
1834
|
-
|
2250
|
+
expect_no_queries do
|
2251
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
2252
|
+
end
|
1835
2253
|
end
|
1836
2254
|
end
|
1837
2255
|
end
|
@@ -1843,8 +2261,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1843
2261
|
let(:limit) { 2 }
|
1844
2262
|
|
1845
2263
|
it "returns the correct documents without touching the database" do
|
1846
|
-
|
1847
|
-
|
2264
|
+
expect_no_queries do
|
2265
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
2266
|
+
end
|
1848
2267
|
end
|
1849
2268
|
end
|
1850
2269
|
|
@@ -1852,8 +2271,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1852
2271
|
let(:limit) { 3 }
|
1853
2272
|
|
1854
2273
|
it "returns the correct documents and touches the database" do
|
1855
|
-
|
1856
|
-
|
2274
|
+
expect_query(1) do
|
2275
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2276
|
+
end
|
1857
2277
|
end
|
1858
2278
|
end
|
1859
2279
|
end
|
@@ -1865,8 +2285,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1865
2285
|
let(:limit) { 1 }
|
1866
2286
|
|
1867
2287
|
it "returns the correct documents without touching the database" do
|
1868
|
-
|
1869
|
-
|
2288
|
+
expect_no_queries do
|
2289
|
+
expect(docs).to eq([ depeche_mode ])
|
2290
|
+
end
|
1870
2291
|
end
|
1871
2292
|
end
|
1872
2293
|
|
@@ -1874,8 +2295,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1874
2295
|
let(:limit) { 3 }
|
1875
2296
|
|
1876
2297
|
it "returns the correct documents and touches the database" do
|
1877
|
-
|
1878
|
-
|
2298
|
+
expect_query(1) do
|
2299
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2300
|
+
end
|
1879
2301
|
end
|
1880
2302
|
end
|
1881
2303
|
end
|
@@ -1883,24 +2305,15 @@ describe Mongoid::Contextual::Mongo do
|
|
1883
2305
|
end
|
1884
2306
|
end
|
1885
2307
|
|
1886
|
-
context "when
|
1887
|
-
|
1888
|
-
let(:criteria) { Band.criteria }
|
1889
|
-
let(:docs) { context.send(method, {}) }
|
1890
|
-
|
1891
|
-
it "behaves as if limit is nil" do
|
1892
|
-
expect(docs).to eq(depeche_mode)
|
1893
|
-
end
|
1894
|
-
end
|
1895
|
-
|
1896
|
-
context "when calling #first then #last" do
|
2308
|
+
context "when calling #first then #last and the query cache is enabled" do
|
2309
|
+
query_cache_enabled
|
1897
2310
|
|
1898
2311
|
let(:context) do
|
1899
2312
|
described_class.new(criteria)
|
1900
2313
|
end
|
1901
2314
|
|
1902
2315
|
let(:criteria) do
|
1903
|
-
Band.all
|
2316
|
+
Band.all
|
1904
2317
|
end
|
1905
2318
|
|
1906
2319
|
before do
|
@@ -1915,8 +2328,10 @@ describe Mongoid::Contextual::Mongo do
|
|
1915
2328
|
let(:before_limit) { 2 }
|
1916
2329
|
let(:limit) { 1 }
|
1917
2330
|
|
1918
|
-
it "gets the correct document" do
|
1919
|
-
|
2331
|
+
it "gets the correct document and hits the database" do
|
2332
|
+
expect_query(1) do
|
2333
|
+
expect(docs).to eq([rolling_stones])
|
2334
|
+
end
|
1920
2335
|
end
|
1921
2336
|
end
|
1922
2337
|
end
|
@@ -2006,30 +2421,10 @@ describe Mongoid::Contextual::Mongo do
|
|
2006
2421
|
context 'when calling #first' do
|
2007
2422
|
|
2008
2423
|
it 'returns the first document, sorted by _id' do
|
2009
|
-
pending "MONGOID-5416"
|
2010
2424
|
expect(context.last).to eq(rolling_stones)
|
2011
2425
|
expect(context.first).to eq(depeche_mode)
|
2012
2426
|
end
|
2013
2427
|
end
|
2014
|
-
|
2015
|
-
context 'with option { id_sort: :none }' do
|
2016
|
-
let(:opts) do
|
2017
|
-
{ id_sort: :none }
|
2018
|
-
end
|
2019
|
-
|
2020
|
-
it 'doesn\'t apply the sort on _id' do
|
2021
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
2022
|
-
end
|
2023
|
-
|
2024
|
-
context 'when calling #first' do
|
2025
|
-
|
2026
|
-
it 'doesn\'t apply the sort on _id' do
|
2027
|
-
pending "MONGOID-5416"
|
2028
|
-
expect(context.last(opts)).to eq(rolling_stones)
|
2029
|
-
expect(context.first(opts)).to eq(depeche_mode)
|
2030
|
-
end
|
2031
|
-
end
|
2032
|
-
end
|
2033
2428
|
end
|
2034
2429
|
|
2035
2430
|
context 'when the criteria has a sort' do
|
@@ -2054,25 +2449,6 @@ describe Mongoid::Contextual::Mongo do
|
|
2054
2449
|
expect(context.first).to eq(rolling_stones)
|
2055
2450
|
end
|
2056
2451
|
end
|
2057
|
-
|
2058
|
-
context 'with option { id_sort: :none }' do
|
2059
|
-
|
2060
|
-
let(:opts) do
|
2061
|
-
{ id_sort: :none }
|
2062
|
-
end
|
2063
|
-
|
2064
|
-
it 'uses the preexisting sort' do
|
2065
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
2066
|
-
end
|
2067
|
-
|
2068
|
-
context 'when calling #first' do
|
2069
|
-
|
2070
|
-
it 'uses the preexisting sort' do
|
2071
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
2072
|
-
expect(context.first(opts)).to eq(rolling_stones)
|
2073
|
-
end
|
2074
|
-
end
|
2075
|
-
end
|
2076
2452
|
end
|
2077
2453
|
|
2078
2454
|
context "when using .sort" do
|
@@ -2101,28 +2477,17 @@ describe Mongoid::Contextual::Mongo do
|
|
2101
2477
|
end
|
2102
2478
|
end
|
2103
2479
|
|
2104
|
-
context "when the
|
2480
|
+
context "when the query cache is enabled" do
|
2481
|
+
query_cache_enabled
|
2105
2482
|
|
2106
2483
|
let(:criteria) do
|
2107
|
-
Band.where(name: "Depeche Mode")
|
2484
|
+
Band.where(name: "Depeche Mode")
|
2108
2485
|
end
|
2109
2486
|
|
2110
2487
|
let(:context) do
|
2111
2488
|
described_class.new(criteria)
|
2112
2489
|
end
|
2113
2490
|
|
2114
|
-
context "when the cache is loaded" do
|
2115
|
-
|
2116
|
-
before do
|
2117
|
-
context.to_a
|
2118
|
-
end
|
2119
|
-
|
2120
|
-
it "returns the last document without touching the database" do
|
2121
|
-
expect(context).to receive(:view).never
|
2122
|
-
expect(context.last).to eq(depeche_mode)
|
2123
|
-
end
|
2124
|
-
end
|
2125
|
-
|
2126
2491
|
context "when last method was called before" do
|
2127
2492
|
|
2128
2493
|
before do
|
@@ -2130,8 +2495,9 @@ describe Mongoid::Contextual::Mongo do
|
|
2130
2495
|
end
|
2131
2496
|
|
2132
2497
|
it "returns the last document without touching the database" do
|
2133
|
-
|
2134
|
-
|
2498
|
+
expect_no_queries do
|
2499
|
+
expect(context.last).to eq(depeche_mode)
|
2500
|
+
end
|
2135
2501
|
end
|
2136
2502
|
end
|
2137
2503
|
end
|
@@ -2191,71 +2557,15 @@ describe Mongoid::Contextual::Mongo do
|
|
2191
2557
|
described_class.new(criteria)
|
2192
2558
|
end
|
2193
2559
|
|
2194
|
-
context "when
|
2195
|
-
|
2196
|
-
before do
|
2197
|
-
context.to_a
|
2198
|
-
end
|
2199
|
-
|
2200
|
-
context "when all of the documents are cached" do
|
2201
|
-
|
2202
|
-
let(:criteria) do
|
2203
|
-
Band.all.cache
|
2204
|
-
end
|
2205
|
-
|
2206
|
-
context "when requesting all of the documents" do
|
2207
|
-
|
2208
|
-
let(:docs) do
|
2209
|
-
context.last(3)
|
2210
|
-
end
|
2211
|
-
|
2212
|
-
it "returns all of the documents without touching the database" do
|
2213
|
-
expect(context).to receive(:view).never
|
2214
|
-
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2215
|
-
end
|
2216
|
-
end
|
2217
|
-
|
2218
|
-
context "when requesting fewer than all of the documents" do
|
2219
|
-
|
2220
|
-
let(:docs) do
|
2221
|
-
context.last(2)
|
2222
|
-
end
|
2223
|
-
|
2224
|
-
it "returns all of the documents without touching the database" do
|
2225
|
-
expect(context).to receive(:view).never
|
2226
|
-
expect(docs).to eq([ new_order, rolling_stones ])
|
2227
|
-
end
|
2228
|
-
end
|
2229
|
-
end
|
2230
|
-
|
2231
|
-
context "when only one document is cached" do
|
2232
|
-
|
2233
|
-
let(:criteria) do
|
2234
|
-
Band.where(name: "Depeche Mode").cache
|
2235
|
-
end
|
2236
|
-
|
2237
|
-
context "when requesting one document" do
|
2238
|
-
|
2239
|
-
let(:docs) do
|
2240
|
-
context.last(1)
|
2241
|
-
end
|
2242
|
-
|
2243
|
-
it "returns one document without touching the database" do
|
2244
|
-
expect(context).to receive(:view).never
|
2245
|
-
expect(docs).to eq([ depeche_mode ])
|
2246
|
-
end
|
2247
|
-
end
|
2248
|
-
end
|
2249
|
-
end
|
2250
|
-
|
2251
|
-
context "when the last method was called before" do
|
2560
|
+
context "when query cache is enabled" do
|
2561
|
+
query_cache_enabled
|
2252
2562
|
|
2253
2563
|
let(:context) do
|
2254
2564
|
described_class.new(criteria)
|
2255
2565
|
end
|
2256
2566
|
|
2257
2567
|
let(:criteria) do
|
2258
|
-
Band.all
|
2568
|
+
Band.all
|
2259
2569
|
end
|
2260
2570
|
|
2261
2571
|
before do
|
@@ -2272,18 +2582,20 @@ describe Mongoid::Contextual::Mongo do
|
|
2272
2582
|
context "when getting all of the documents" do
|
2273
2583
|
let(:limit) { 3 }
|
2274
2584
|
|
2275
|
-
it "returns all documents without touching the
|
2276
|
-
|
2277
|
-
|
2585
|
+
it "returns all documents without touching the db" do
|
2586
|
+
expect_no_queries do
|
2587
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2588
|
+
end
|
2278
2589
|
end
|
2279
2590
|
end
|
2280
2591
|
|
2281
2592
|
context "when getting fewer documents" do
|
2282
2593
|
let(:limit) { 2 }
|
2283
2594
|
|
2284
|
-
it "returns the correct documents without touching the
|
2285
|
-
|
2286
|
-
|
2595
|
+
it "returns the correct documents without touching the db" do
|
2596
|
+
expect_no_queries do
|
2597
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
2598
|
+
end
|
2287
2599
|
end
|
2288
2600
|
end
|
2289
2601
|
end
|
@@ -2294,9 +2606,10 @@ describe Mongoid::Contextual::Mongo do
|
|
2294
2606
|
context "when getting the same number of documents" do
|
2295
2607
|
let(:limit) { 2 }
|
2296
2608
|
|
2297
|
-
it "returns the correct documents without touching the
|
2298
|
-
|
2299
|
-
|
2609
|
+
it "returns the correct documents without touching the db" do
|
2610
|
+
expect_no_queries do
|
2611
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
2612
|
+
end
|
2300
2613
|
end
|
2301
2614
|
end
|
2302
2615
|
|
@@ -2304,8 +2617,9 @@ describe Mongoid::Contextual::Mongo do
|
|
2304
2617
|
let(:limit) { 3 }
|
2305
2618
|
|
2306
2619
|
it "returns the correct documents and touches the database" do
|
2307
|
-
|
2308
|
-
|
2620
|
+
expect_query(1) do
|
2621
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2622
|
+
end
|
2309
2623
|
end
|
2310
2624
|
end
|
2311
2625
|
end
|
@@ -2317,8 +2631,9 @@ describe Mongoid::Contextual::Mongo do
|
|
2317
2631
|
let(:limit) { 1 }
|
2318
2632
|
|
2319
2633
|
it "returns the correct documents without touching the database" do
|
2320
|
-
|
2321
|
-
|
2634
|
+
expect_no_queries do
|
2635
|
+
expect(docs).to eq([ rolling_stones ])
|
2636
|
+
end
|
2322
2637
|
end
|
2323
2638
|
end
|
2324
2639
|
|
@@ -2326,8 +2641,9 @@ describe Mongoid::Contextual::Mongo do
|
|
2326
2641
|
let(:limit) { 3 }
|
2327
2642
|
|
2328
2643
|
it "returns the correct documents and touches the database" do
|
2329
|
-
|
2330
|
-
|
2644
|
+
expect_query(1) do
|
2645
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2646
|
+
end
|
2331
2647
|
end
|
2332
2648
|
end
|
2333
2649
|
end
|
@@ -2335,14 +2651,15 @@ describe Mongoid::Contextual::Mongo do
|
|
2335
2651
|
end
|
2336
2652
|
end
|
2337
2653
|
|
2338
|
-
context "when calling #last then #first" do
|
2654
|
+
context "when calling #last then #first and the query cache is enabled" do
|
2655
|
+
query_cache_enabled
|
2339
2656
|
|
2340
2657
|
let(:context) do
|
2341
2658
|
described_class.new(criteria)
|
2342
2659
|
end
|
2343
2660
|
|
2344
2661
|
let(:criteria) do
|
2345
|
-
Band.all
|
2662
|
+
Band.all
|
2346
2663
|
end
|
2347
2664
|
|
2348
2665
|
before do
|
@@ -2358,26 +2675,16 @@ describe Mongoid::Contextual::Mongo do
|
|
2358
2675
|
let(:limit) { 1 }
|
2359
2676
|
|
2360
2677
|
it "hits the database" do
|
2361
|
-
|
2362
|
-
|
2678
|
+
expect_query(1) do
|
2679
|
+
docs
|
2680
|
+
end
|
2363
2681
|
end
|
2364
2682
|
|
2365
2683
|
it "gets the correct document" do
|
2366
|
-
pending "MONGOID-5416"
|
2367
2684
|
expect(docs).to eq([ depeche_mode ])
|
2368
2685
|
end
|
2369
2686
|
end
|
2370
2687
|
end
|
2371
|
-
|
2372
|
-
context "when given an empty hash" do
|
2373
|
-
let(:context) { described_class.new(criteria) }
|
2374
|
-
let(:criteria) { Band.criteria }
|
2375
|
-
let(:docs) { context.last({}) }
|
2376
|
-
|
2377
|
-
it "behaves as if limit is nil" do
|
2378
|
-
expect(docs).to eq(rolling_stones)
|
2379
|
-
end
|
2380
|
-
end
|
2381
2688
|
end
|
2382
2689
|
|
2383
2690
|
describe "#initialize" do
|
@@ -2426,37 +2733,28 @@ describe Mongoid::Contextual::Mongo do
|
|
2426
2733
|
described_class.new(criteria)
|
2427
2734
|
end
|
2428
2735
|
|
2429
|
-
|
2430
|
-
|
2431
|
-
end
|
2736
|
+
context "when broken_view_options is false" do
|
2737
|
+
driver_config_override :broken_view_options, false
|
2432
2738
|
|
2433
|
-
|
2434
|
-
|
2435
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
2436
|
-
2.times { expect(context.send(method)).to eq(2) }
|
2739
|
+
it "returns the number of documents that match" do
|
2740
|
+
expect(context.send(method)).to eq(1)
|
2437
2741
|
end
|
2438
2742
|
end
|
2439
2743
|
|
2440
|
-
context "when
|
2441
|
-
|
2442
|
-
before do
|
2443
|
-
context.entries
|
2444
|
-
end
|
2744
|
+
context "when broken_view_options is true" do
|
2745
|
+
driver_config_override :broken_view_options, true
|
2445
2746
|
|
2446
|
-
it "returns the
|
2447
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
2747
|
+
it "returns the number of documents that match" do
|
2448
2748
|
expect(context.send(method)).to eq(2)
|
2449
2749
|
end
|
2750
|
+
end
|
2450
2751
|
|
2451
|
-
|
2452
|
-
|
2453
|
-
before do
|
2454
|
-
context.entries
|
2455
|
-
end
|
2752
|
+
context "when calling more than once with different limits" do
|
2753
|
+
driver_config_override :broken_view_options, false
|
2456
2754
|
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2755
|
+
it "does not cache the value" do
|
2756
|
+
expect(context.limit(1).send(method)).to eq(1)
|
2757
|
+
expect(context.limit(2).send(method)).to eq(2)
|
2460
2758
|
end
|
2461
2759
|
end
|
2462
2760
|
end
|
@@ -2475,10 +2773,12 @@ describe Mongoid::Contextual::Mongo do
|
|
2475
2773
|
expect(context.send(method)).to eq(1)
|
2476
2774
|
end
|
2477
2775
|
|
2478
|
-
context "when calling more than once" do
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2776
|
+
context "when calling more than once with different skips" do
|
2777
|
+
driver_config_override :broken_view_options, false
|
2778
|
+
|
2779
|
+
it "does not cache the value" do
|
2780
|
+
expect(context.skip(0).send(method)).to eq(1)
|
2781
|
+
expect(context.skip(1).send(method)).to eq(0)
|
2482
2782
|
end
|
2483
2783
|
end
|
2484
2784
|
|
@@ -2600,7 +2900,7 @@ describe Mongoid::Contextual::Mongo do
|
|
2600
2900
|
it "raises an error" do
|
2601
2901
|
expect do
|
2602
2902
|
Person.take!
|
2603
|
-
end.to raise_error(Mongoid::Errors::DocumentNotFound)
|
2903
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Person./)
|
2604
2904
|
end
|
2605
2905
|
end
|
2606
2906
|
end
|
@@ -2622,9 +2922,10 @@ describe Mongoid::Contextual::Mongo do
|
|
2622
2922
|
|
2623
2923
|
context "when passed the symbol field name" do
|
2624
2924
|
|
2625
|
-
it "
|
2626
|
-
expect
|
2627
|
-
|
2925
|
+
it "raises an error" do
|
2926
|
+
expect do
|
2927
|
+
context.map(:name)
|
2928
|
+
end.to raise_error(ArgumentError)
|
2628
2929
|
end
|
2629
2930
|
end
|
2630
2931
|
|
@@ -2853,219 +3154,948 @@ describe Mongoid::Contextual::Mongo do
|
|
2853
3154
|
described_class.new(criteria)
|
2854
3155
|
end
|
2855
3156
|
|
2856
|
-
let(:results) do
|
2857
|
-
context.map_reduce(map, reduce).out(inline: 1)
|
3157
|
+
let(:results) do
|
3158
|
+
context.map_reduce(map, reduce).out(inline: 1)
|
3159
|
+
end
|
3160
|
+
|
3161
|
+
it "returns the first aggregate result" do
|
3162
|
+
expect(results).to include(
|
3163
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3164
|
+
)
|
3165
|
+
end
|
3166
|
+
|
3167
|
+
it "returns the correct number of documents" do
|
3168
|
+
expect(results.count).to eq(1)
|
3169
|
+
end
|
3170
|
+
|
3171
|
+
it "contains the entire raw results" do
|
3172
|
+
expect(results["results"]).to eq([
|
3173
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3174
|
+
])
|
3175
|
+
end
|
3176
|
+
end
|
3177
|
+
|
3178
|
+
context "when the output is replace" do
|
3179
|
+
|
3180
|
+
let(:criteria) do
|
3181
|
+
Band.limit(1)
|
3182
|
+
end
|
3183
|
+
|
3184
|
+
let(:context) do
|
3185
|
+
described_class.new(criteria)
|
3186
|
+
end
|
3187
|
+
|
3188
|
+
let(:results) do
|
3189
|
+
context.map_reduce(map, reduce).out(replace: "mr-output")
|
3190
|
+
end
|
3191
|
+
|
3192
|
+
it "returns the correct number of documents" do
|
3193
|
+
expect(results.count).to eq(1)
|
3194
|
+
end
|
3195
|
+
|
3196
|
+
it "contains the entire results" do
|
3197
|
+
expect(results).to eq([
|
3198
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3199
|
+
])
|
3200
|
+
end
|
3201
|
+
end
|
3202
|
+
|
3203
|
+
context "when the output is reduce" do
|
3204
|
+
|
3205
|
+
let(:criteria) do
|
3206
|
+
Band.limit(1)
|
3207
|
+
end
|
3208
|
+
|
3209
|
+
let(:context) do
|
3210
|
+
described_class.new(criteria)
|
3211
|
+
end
|
3212
|
+
|
3213
|
+
let(:results) do
|
3214
|
+
context.map_reduce(map, reduce).out(reduce: :mr_output)
|
3215
|
+
end
|
3216
|
+
|
3217
|
+
it "returns the correct number of documents" do
|
3218
|
+
expect(results.count).to eq(1)
|
3219
|
+
end
|
3220
|
+
|
3221
|
+
it "contains the entire results" do
|
3222
|
+
expect(results).to eq([
|
3223
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3224
|
+
])
|
3225
|
+
end
|
3226
|
+
end
|
3227
|
+
|
3228
|
+
context "when the output is merge" do
|
3229
|
+
|
3230
|
+
let(:criteria) do
|
3231
|
+
Band.limit(1)
|
3232
|
+
end
|
3233
|
+
|
3234
|
+
let(:context) do
|
3235
|
+
described_class.new(criteria)
|
3236
|
+
end
|
3237
|
+
|
3238
|
+
let(:results) do
|
3239
|
+
context.map_reduce(map, reduce).out(merge: :mr_output)
|
3240
|
+
end
|
3241
|
+
|
3242
|
+
it "returns the correct number of documents" do
|
3243
|
+
expect(results.count).to eq(1)
|
3244
|
+
end
|
3245
|
+
|
3246
|
+
it "contains the entire results" do
|
3247
|
+
expect(results).to eq([
|
3248
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3249
|
+
])
|
3250
|
+
end
|
3251
|
+
end
|
3252
|
+
|
3253
|
+
context "when the output specifies a different db" do
|
3254
|
+
# Limit is not supported in sharded clusters
|
3255
|
+
require_topology :single, :replica_set
|
3256
|
+
|
3257
|
+
let(:criteria) do
|
3258
|
+
Band.limit(1)
|
3259
|
+
end
|
3260
|
+
|
3261
|
+
let(:context) do
|
3262
|
+
described_class.new(criteria)
|
3263
|
+
end
|
3264
|
+
|
3265
|
+
after do
|
3266
|
+
Band.with(database: 'another-db') do |b|
|
3267
|
+
b.all.delete
|
3268
|
+
end
|
3269
|
+
end
|
3270
|
+
|
3271
|
+
context 'when db is a string' do
|
3272
|
+
|
3273
|
+
let(:results) do
|
3274
|
+
context.map_reduce(map, reduce).out(merge: :mr_output, db: 'another-db')
|
3275
|
+
end
|
3276
|
+
|
3277
|
+
it "returns the correct number of documents" do
|
3278
|
+
expect(results.count).to eq(1)
|
3279
|
+
end
|
3280
|
+
|
3281
|
+
it "contains the entire results" do
|
3282
|
+
expect(results).to eq([
|
3283
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3284
|
+
])
|
3285
|
+
end
|
3286
|
+
|
3287
|
+
it 'writes to the specified db' do
|
3288
|
+
expect(Band.mongo_client.with(database: 'another-db')[:mr_output].find.count).to eq(1)
|
3289
|
+
end
|
3290
|
+
end
|
3291
|
+
|
3292
|
+
context 'when db is a symbol' do
|
3293
|
+
|
3294
|
+
let(:results) do
|
3295
|
+
context.map_reduce(map, reduce).out(merge: :mr_output, 'db' => 'another-db')
|
3296
|
+
end
|
3297
|
+
|
3298
|
+
it "returns the correct number of documents" do
|
3299
|
+
expect(results.count).to eq(1)
|
3300
|
+
end
|
3301
|
+
|
3302
|
+
it "contains the entire results" do
|
3303
|
+
expect(results).to eq([
|
3304
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
3305
|
+
])
|
3306
|
+
end
|
3307
|
+
|
3308
|
+
it 'writes to the specified db' do
|
3309
|
+
expect(Band.mongo_client.with(database: 'another-db')[:mr_output].find.count).to eq(1)
|
3310
|
+
end
|
3311
|
+
end
|
3312
|
+
end
|
3313
|
+
|
3314
|
+
context "when providing no output" do
|
3315
|
+
|
3316
|
+
let(:criteria) do
|
3317
|
+
Band.limit(1)
|
3318
|
+
end
|
3319
|
+
|
3320
|
+
let(:context) do
|
3321
|
+
described_class.new(criteria)
|
3322
|
+
end
|
3323
|
+
|
3324
|
+
let(:results) do
|
3325
|
+
context.map_reduce(map, reduce)
|
3326
|
+
end
|
3327
|
+
|
3328
|
+
it "raises an error" do
|
3329
|
+
expect {
|
3330
|
+
results.entries
|
3331
|
+
}.to raise_error(Mongoid::Errors::NoMapReduceOutput)
|
3332
|
+
end
|
3333
|
+
end
|
3334
|
+
|
3335
|
+
context "when providing a finalize" do
|
3336
|
+
|
3337
|
+
let(:criteria) do
|
3338
|
+
Band.limit(1)
|
3339
|
+
end
|
3340
|
+
|
3341
|
+
let(:context) do
|
3342
|
+
described_class.new(criteria)
|
3343
|
+
end
|
3344
|
+
|
3345
|
+
let(:finalize) do
|
3346
|
+
%Q{
|
3347
|
+
function(key, value) {
|
3348
|
+
value.extra = true;
|
3349
|
+
return value;
|
3350
|
+
}}
|
3351
|
+
end
|
3352
|
+
|
3353
|
+
let(:results) do
|
3354
|
+
context.map_reduce(map, reduce).out(inline: 1).finalize(finalize)
|
3355
|
+
end
|
3356
|
+
|
3357
|
+
it "returns the correct number of documents" do
|
3358
|
+
expect(results.count).to eq(1)
|
3359
|
+
end
|
3360
|
+
|
3361
|
+
it "contains the entire results" do
|
3362
|
+
expect(results).to eq([
|
3363
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200, "extra" => true }}
|
3364
|
+
])
|
3365
|
+
end
|
3366
|
+
end
|
3367
|
+
end
|
3368
|
+
|
3369
|
+
describe "#skip" do
|
3370
|
+
|
3371
|
+
let!(:depeche_mode) do
|
3372
|
+
Band.create!(name: "Depeche Mode")
|
3373
|
+
end
|
3374
|
+
|
3375
|
+
let!(:new_order) do
|
3376
|
+
Band.create!(name: "New Order")
|
3377
|
+
end
|
3378
|
+
|
3379
|
+
let(:criteria) do
|
3380
|
+
Band.all
|
3381
|
+
end
|
3382
|
+
|
3383
|
+
let(:context) do
|
3384
|
+
described_class.new(criteria)
|
3385
|
+
end
|
3386
|
+
|
3387
|
+
it "limits the results" do
|
3388
|
+
expect(context.skip(1).entries).to eq([ new_order ])
|
3389
|
+
end
|
3390
|
+
end
|
3391
|
+
|
3392
|
+
describe "#sort" do
|
3393
|
+
|
3394
|
+
let!(:depeche_mode) do
|
3395
|
+
Band.create!(name: "Depeche Mode")
|
3396
|
+
end
|
3397
|
+
|
3398
|
+
let!(:new_order) do
|
3399
|
+
Band.create!(name: "New Order")
|
3400
|
+
end
|
3401
|
+
|
3402
|
+
let(:criteria) do
|
3403
|
+
Band.all
|
3404
|
+
end
|
3405
|
+
|
3406
|
+
let(:context) do
|
3407
|
+
described_class.new(criteria)
|
3408
|
+
end
|
3409
|
+
|
3410
|
+
context "when providing a spec" do
|
3411
|
+
|
3412
|
+
it "sorts the results" do
|
3413
|
+
expect(context.sort(name: -1).entries).to eq([ new_order, depeche_mode ])
|
3414
|
+
end
|
3415
|
+
|
3416
|
+
it "returns the context" do
|
3417
|
+
expect(context.sort(name: 1)).to eq(context)
|
3418
|
+
end
|
3419
|
+
end
|
3420
|
+
|
3421
|
+
context "when providing a block" do
|
3422
|
+
|
3423
|
+
let(:sorted) do
|
3424
|
+
context.sort do |a, b|
|
3425
|
+
b.name <=> a.name
|
3426
|
+
end
|
3427
|
+
end
|
3428
|
+
|
3429
|
+
it "sorts the results in memory" do
|
3430
|
+
expect(sorted).to eq([ new_order, depeche_mode ])
|
3431
|
+
end
|
3432
|
+
end
|
3433
|
+
end
|
3434
|
+
|
3435
|
+
describe "#update" do
|
3436
|
+
|
3437
|
+
let!(:depeche_mode) do
|
3438
|
+
Band.create!(name: "Depeche Mode")
|
3439
|
+
end
|
3440
|
+
|
3441
|
+
let!(:new_order) do
|
3442
|
+
Band.create!(name: "New Order")
|
3443
|
+
end
|
3444
|
+
|
3445
|
+
let(:criteria) do
|
3446
|
+
Band.all
|
3447
|
+
end
|
3448
|
+
|
3449
|
+
let(:context) do
|
3450
|
+
described_class.new(criteria)
|
3451
|
+
end
|
3452
|
+
|
3453
|
+
context "when adding an element to a HABTM set" do
|
3454
|
+
|
3455
|
+
let(:person) do
|
3456
|
+
Person.create!
|
3457
|
+
end
|
3458
|
+
|
3459
|
+
let(:preference) do
|
3460
|
+
Preference.create!
|
3461
|
+
end
|
3462
|
+
|
3463
|
+
before do
|
3464
|
+
Person.where(id: person.id).
|
3465
|
+
update("$addToSet" => { preference_ids: preference.id })
|
3466
|
+
end
|
3467
|
+
|
3468
|
+
it "adds a single element to the array" do
|
3469
|
+
expect(person.reload.preference_ids).to eq([ preference.id ])
|
3470
|
+
end
|
3471
|
+
end
|
3472
|
+
|
3473
|
+
context "when providing attributes" do
|
3474
|
+
|
3475
|
+
context "when the attributes are of the correct type" do
|
3476
|
+
|
3477
|
+
before do
|
3478
|
+
context.update(name: "Smiths")
|
3479
|
+
end
|
3480
|
+
|
3481
|
+
it "updates only the first matching document" do
|
3482
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3483
|
+
end
|
3484
|
+
|
3485
|
+
it "does not update the last matching document" do
|
3486
|
+
expect(new_order.reload.name).to eq("New Order")
|
3487
|
+
end
|
3488
|
+
end
|
3489
|
+
|
3490
|
+
context "when the attributes must be mongoized" do
|
3491
|
+
|
3492
|
+
context "when coercing a string to integer" do
|
3493
|
+
|
3494
|
+
before do
|
3495
|
+
context.update(member_count: "1")
|
3496
|
+
end
|
3497
|
+
|
3498
|
+
it "updates the first matching document" do
|
3499
|
+
expect(depeche_mode.reload.member_count).to eq(1)
|
3500
|
+
end
|
3501
|
+
|
3502
|
+
it "does not update the last matching document" do
|
3503
|
+
expect(new_order.reload.member_count).to be_nil
|
3504
|
+
end
|
3505
|
+
end
|
3506
|
+
|
3507
|
+
context "when coercing a string to date" do
|
3508
|
+
|
3509
|
+
before do
|
3510
|
+
context.update(founded: "1979/1/1")
|
3511
|
+
end
|
3512
|
+
|
3513
|
+
it "updates the first matching document" do
|
3514
|
+
expect(depeche_mode.reload.founded).to eq(Date.new(1979, 1, 1))
|
3515
|
+
end
|
3516
|
+
|
3517
|
+
it "does not update the last matching document" do
|
3518
|
+
expect(new_order.reload.founded).to be_nil
|
3519
|
+
end
|
3520
|
+
end
|
3521
|
+
end
|
3522
|
+
end
|
3523
|
+
|
3524
|
+
context "when providing atomic operations" do
|
3525
|
+
|
3526
|
+
context "when only atomic operations are provided" do
|
3527
|
+
|
3528
|
+
context "when the attributes are in the correct type" do
|
3529
|
+
|
3530
|
+
before do
|
3531
|
+
context.update("$set" => { name: "Smiths" })
|
3532
|
+
end
|
3533
|
+
|
3534
|
+
it "updates the first matching document" do
|
3535
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3536
|
+
end
|
3537
|
+
|
3538
|
+
it "does not update the last matching document" do
|
3539
|
+
expect(new_order.reload.name).to eq("New Order")
|
3540
|
+
end
|
3541
|
+
end
|
3542
|
+
|
3543
|
+
context "when the attributes must be mongoized" do
|
3544
|
+
|
3545
|
+
before do
|
3546
|
+
context.update("$set" => { member_count: "1" })
|
3547
|
+
end
|
3548
|
+
|
3549
|
+
it "updates the first matching document" do
|
3550
|
+
expect(depeche_mode.reload.member_count).to eq(1)
|
3551
|
+
end
|
3552
|
+
|
3553
|
+
it "does not update the last matching document" do
|
3554
|
+
expect(new_order.reload.member_count).to be_nil
|
3555
|
+
end
|
3556
|
+
end
|
3557
|
+
end
|
3558
|
+
|
3559
|
+
context "when a mix are provided" do
|
3560
|
+
|
3561
|
+
before do
|
3562
|
+
context.update("$set" => { name: "Smiths" }, likes: 100)
|
3563
|
+
end
|
3564
|
+
|
3565
|
+
it "updates the first matching document's set" do
|
3566
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3567
|
+
end
|
3568
|
+
|
3569
|
+
it "updates the first matching document's updates" do
|
3570
|
+
expect(depeche_mode.reload.likes).to eq(100)
|
3571
|
+
end
|
3572
|
+
|
3573
|
+
it "does not update the last matching document's set" do
|
3574
|
+
expect(new_order.reload.name).to eq("New Order")
|
3575
|
+
end
|
3576
|
+
|
3577
|
+
it "does not update the last matching document's updates" do
|
3578
|
+
expect(new_order.reload.likes).to be_nil
|
3579
|
+
end
|
3580
|
+
end
|
3581
|
+
end
|
3582
|
+
|
3583
|
+
context "when providing no attributes" do
|
3584
|
+
|
3585
|
+
it "returns false" do
|
3586
|
+
expect(context.update).to be false
|
3587
|
+
end
|
3588
|
+
end
|
3589
|
+
|
3590
|
+
context 'when provided array filters' do
|
3591
|
+
min_server_version '3.6'
|
3592
|
+
|
3593
|
+
before do
|
3594
|
+
Band.delete_all
|
3595
|
+
b = Band.new(name: 'Depeche Mode')
|
3596
|
+
b.labels << Label.new(name: 'Warner')
|
3597
|
+
b.labels << Label.new(name: 'Sony')
|
3598
|
+
b.labels << Label.new(name: 'Cbs')
|
3599
|
+
b.save!
|
3600
|
+
|
3601
|
+
b = Band.new(name: 'FKA Twigs')
|
3602
|
+
b.labels << Label.new(name: 'Warner')
|
3603
|
+
b.labels << Label.new(name: 'Cbs')
|
3604
|
+
b.save!
|
3605
|
+
end
|
3606
|
+
|
3607
|
+
|
3608
|
+
let(:criteria) do
|
3609
|
+
Band.where(name: 'Depeche Mode')
|
3610
|
+
end
|
3611
|
+
|
3612
|
+
let!(:update) do
|
3613
|
+
context.update({ '$set' => { 'labels.$[i].name' => 'Sony' } },
|
3614
|
+
array_filters: [{ 'i.name' => 'Cbs' }])
|
3615
|
+
end
|
3616
|
+
|
3617
|
+
it 'applies the array filters' do
|
3618
|
+
expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
|
3619
|
+
end
|
3620
|
+
|
3621
|
+
it 'does not affect other documents' do
|
3622
|
+
expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Cbs'])
|
3623
|
+
end
|
3624
|
+
end
|
3625
|
+
end
|
3626
|
+
|
3627
|
+
describe "#update_all" do
|
3628
|
+
|
3629
|
+
let!(:depeche_mode) do
|
3630
|
+
Band.create!(name: "Depeche Mode", origin: "Essex")
|
3631
|
+
end
|
3632
|
+
|
3633
|
+
let!(:new_order) do
|
3634
|
+
Band.create!(name: "New Order")
|
3635
|
+
end
|
3636
|
+
|
3637
|
+
let(:criteria) do
|
3638
|
+
Band.all
|
3639
|
+
end
|
3640
|
+
|
3641
|
+
let(:context) do
|
3642
|
+
described_class.new(criteria)
|
3643
|
+
end
|
3644
|
+
|
3645
|
+
context "when providing attributes" do
|
3646
|
+
|
3647
|
+
context "when the attributes are of the correct type" do
|
3648
|
+
|
3649
|
+
before do
|
3650
|
+
context.update_all(name: "Smiths")
|
3651
|
+
end
|
3652
|
+
|
3653
|
+
it "updates the first matching document" do
|
3654
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3655
|
+
end
|
3656
|
+
|
3657
|
+
it "does not clear out other attributes" do
|
3658
|
+
expect(depeche_mode.reload.origin).to eq("Essex")
|
3659
|
+
end
|
3660
|
+
|
3661
|
+
it "updates the last matching document" do
|
3662
|
+
expect(new_order.reload.name).to eq("Smiths")
|
3663
|
+
end
|
3664
|
+
end
|
3665
|
+
|
3666
|
+
context "when the attributes must be mongoized" do
|
3667
|
+
|
3668
|
+
before do
|
3669
|
+
context.update_all(member_count: "1")
|
3670
|
+
end
|
3671
|
+
|
3672
|
+
it "updates the first matching document" do
|
3673
|
+
expect(depeche_mode.reload.member_count).to eq(1)
|
3674
|
+
end
|
3675
|
+
|
3676
|
+
it "updates the last matching document" do
|
3677
|
+
expect(new_order.reload.member_count).to eq(1)
|
3678
|
+
end
|
3679
|
+
end
|
3680
|
+
|
3681
|
+
context "when using aliased field names" do
|
3682
|
+
|
3683
|
+
before do
|
3684
|
+
context.update_all(years: 100)
|
3685
|
+
end
|
3686
|
+
|
3687
|
+
it "updates the first matching document" do
|
3688
|
+
expect(depeche_mode.reload.years).to eq(100)
|
3689
|
+
end
|
3690
|
+
|
3691
|
+
it "updates the last matching document" do
|
3692
|
+
expect(new_order.reload.years).to eq(100)
|
3693
|
+
end
|
3694
|
+
end
|
3695
|
+
end
|
3696
|
+
|
3697
|
+
context "when providing atomic operations" do
|
3698
|
+
|
3699
|
+
context "when only atomic operations are provided" do
|
3700
|
+
|
3701
|
+
context "when the attributes are in the correct type" do
|
3702
|
+
|
3703
|
+
context "when operation is $set" do
|
3704
|
+
|
3705
|
+
before do
|
3706
|
+
context.update_all("$set" => { name: "Smiths" })
|
3707
|
+
end
|
3708
|
+
|
3709
|
+
it "updates the first matching document" do
|
3710
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3711
|
+
end
|
3712
|
+
|
3713
|
+
it "updates the last matching document" do
|
3714
|
+
expect(new_order.reload.name).to eq("Smiths")
|
3715
|
+
end
|
3716
|
+
end
|
3717
|
+
|
3718
|
+
context "when operation is $push" do
|
3719
|
+
|
3720
|
+
before do
|
3721
|
+
depeche_mode.update_attribute(:genres, ["electronic"])
|
3722
|
+
new_order.update_attribute(:genres, ["electronic"])
|
3723
|
+
context.update_all("$push" => { genres: "pop" })
|
3724
|
+
end
|
3725
|
+
|
3726
|
+
it "updates the first matching document" do
|
3727
|
+
expect(depeche_mode.reload.genres).to eq(["electronic", "pop"])
|
3728
|
+
end
|
3729
|
+
|
3730
|
+
it "updates the last matching document" do
|
3731
|
+
expect(new_order.reload.genres).to eq(["electronic", "pop"])
|
3732
|
+
end
|
3733
|
+
end
|
3734
|
+
|
3735
|
+
context "when operation is $addToSet" do
|
3736
|
+
|
3737
|
+
before do
|
3738
|
+
context.update_all("$addToSet" => { genres: "electronic" })
|
3739
|
+
end
|
3740
|
+
|
3741
|
+
it "updates the first matching document" do
|
3742
|
+
expect(depeche_mode.reload.genres).to eq(["electronic"])
|
3743
|
+
end
|
3744
|
+
|
3745
|
+
it "updates the last matching document" do
|
3746
|
+
expect(new_order.reload.genres).to eq(["electronic"])
|
3747
|
+
end
|
3748
|
+
end
|
3749
|
+
end
|
3750
|
+
|
3751
|
+
context 'when using aliased field names' do
|
3752
|
+
before do
|
3753
|
+
context.update_all('$set' => { years: 100 })
|
3754
|
+
end
|
3755
|
+
|
3756
|
+
it "updates the first matching document" do
|
3757
|
+
expect(depeche_mode.reload.years).to eq(100)
|
3758
|
+
end
|
3759
|
+
|
3760
|
+
it "updates the last matching document" do
|
3761
|
+
expect(new_order.reload.years).to eq(100)
|
3762
|
+
end
|
3763
|
+
end
|
3764
|
+
|
3765
|
+
context "when the attributes must be mongoized" do
|
3766
|
+
|
3767
|
+
before do
|
3768
|
+
context.update_all("$set" => { member_count: "1" })
|
3769
|
+
end
|
3770
|
+
|
3771
|
+
it "updates the first matching document" do
|
3772
|
+
expect(depeche_mode.reload.member_count).to eq(1)
|
3773
|
+
end
|
3774
|
+
|
3775
|
+
it "updates the last matching document" do
|
3776
|
+
expect(new_order.reload.member_count).to eq(1)
|
3777
|
+
end
|
3778
|
+
end
|
3779
|
+
end
|
3780
|
+
|
3781
|
+
context "when a mix are provided" do
|
3782
|
+
|
3783
|
+
before do
|
3784
|
+
context.update_all("$set" => { name: "Smiths" }, likes: 100)
|
3785
|
+
end
|
3786
|
+
|
3787
|
+
it "updates the first matching document's set" do
|
3788
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3789
|
+
end
|
3790
|
+
|
3791
|
+
it "updates the first matching document's updates" do
|
3792
|
+
expect(depeche_mode.reload.likes).to eq(100)
|
3793
|
+
end
|
3794
|
+
|
3795
|
+
it "updates the last matching document's set" do
|
3796
|
+
expect(new_order.reload.name).to eq("Smiths")
|
3797
|
+
end
|
3798
|
+
|
3799
|
+
it "updates the last matching document's updates" do
|
3800
|
+
expect(new_order.reload.likes).to eq(100)
|
3801
|
+
end
|
3802
|
+
end
|
3803
|
+
end
|
3804
|
+
|
3805
|
+
context "when providing no attributes" do
|
3806
|
+
|
3807
|
+
it "returns false" do
|
3808
|
+
expect(context.update_all).to be false
|
3809
|
+
end
|
3810
|
+
end
|
3811
|
+
|
3812
|
+
context 'when provided array filters' do
|
3813
|
+
min_server_version '3.6'
|
3814
|
+
|
3815
|
+
before do
|
3816
|
+
Band.delete_all
|
3817
|
+
b = Band.new(name: 'Depeche Mode')
|
3818
|
+
b.labels << Label.new(name: 'Warner')
|
3819
|
+
b.labels << Label.new(name: 'Sony')
|
3820
|
+
b.labels << Label.new(name: 'Cbs')
|
3821
|
+
b.save!
|
3822
|
+
|
3823
|
+
b = Band.new(name: 'FKA Twigs')
|
3824
|
+
b.labels << Label.new(name: 'Warner')
|
3825
|
+
b.labels << Label.new(name: 'Cbs')
|
3826
|
+
b.save!
|
3827
|
+
end
|
3828
|
+
|
3829
|
+
|
3830
|
+
let(:criteria) do
|
3831
|
+
Band.all
|
2858
3832
|
end
|
2859
3833
|
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
)
|
3834
|
+
let!(:update) do
|
3835
|
+
context.update_all({ '$set' => { 'labels.$[i].name' => 'Sony' } },
|
3836
|
+
array_filters: [{ 'i.name' => 'Cbs' }])
|
2864
3837
|
end
|
2865
3838
|
|
2866
|
-
it
|
2867
|
-
expect(
|
3839
|
+
it 'applies the array filters' do
|
3840
|
+
expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
|
2868
3841
|
end
|
2869
3842
|
|
2870
|
-
it
|
2871
|
-
expect(
|
2872
|
-
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
2873
|
-
])
|
3843
|
+
it 'updates all documents' do
|
3844
|
+
expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Sony'])
|
2874
3845
|
end
|
2875
3846
|
end
|
3847
|
+
end
|
2876
3848
|
|
2877
|
-
|
3849
|
+
describe '#pipeline' do
|
3850
|
+
|
3851
|
+
context 'when the criteria has a selector' do
|
3852
|
+
|
3853
|
+
before do
|
3854
|
+
Artist.index(name: "text")
|
3855
|
+
Artist.create_indexes
|
3856
|
+
end
|
2878
3857
|
|
2879
3858
|
let(:criteria) do
|
2880
|
-
|
3859
|
+
Artist.text_search("New Order")
|
2881
3860
|
end
|
2882
3861
|
|
2883
3862
|
let(:context) do
|
2884
3863
|
described_class.new(criteria)
|
2885
3864
|
end
|
2886
3865
|
|
2887
|
-
let(:
|
2888
|
-
context.
|
3866
|
+
let(:pipeline_match) do
|
3867
|
+
context.send(:pipeline, :some_field).first['$match']
|
2889
3868
|
end
|
2890
3869
|
|
2891
|
-
it
|
2892
|
-
expect(
|
3870
|
+
it 'creates a pipeline with the selector as one of the $match criteria' do
|
3871
|
+
expect(pipeline_match).to include({ '$text' => { '$search' => "New Order" } })
|
2893
3872
|
end
|
2894
3873
|
|
2895
|
-
it
|
2896
|
-
expect(
|
2897
|
-
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
2898
|
-
])
|
3874
|
+
it 'creates a pipeline with the $exists operator as one of the $match criteria' do
|
3875
|
+
expect(pipeline_match).to include({ 'some_field' => { '$exists' => true } })
|
2899
3876
|
end
|
2900
3877
|
end
|
3878
|
+
end
|
2901
3879
|
|
2902
|
-
|
3880
|
+
describe "#first!" do
|
2903
3881
|
|
2904
|
-
|
2905
|
-
|
2906
|
-
|
3882
|
+
let!(:depeche_mode) do
|
3883
|
+
Band.create!(name: "Depeche Mode")
|
3884
|
+
end
|
2907
3885
|
|
2908
|
-
|
2909
|
-
|
2910
|
-
|
3886
|
+
let!(:new_order) do
|
3887
|
+
Band.create!(name: "New Order")
|
3888
|
+
end
|
2911
3889
|
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
3890
|
+
let!(:rolling_stones) do
|
3891
|
+
Band.create!(name: "The Rolling Stones")
|
3892
|
+
end
|
2915
3893
|
|
2916
|
-
|
2917
|
-
|
3894
|
+
let!(:death_cab) do
|
3895
|
+
Band.create!(name: "Death Cab For Cutie")
|
3896
|
+
end
|
3897
|
+
|
3898
|
+
let(:context) do
|
3899
|
+
described_class.new(criteria)
|
3900
|
+
end
|
3901
|
+
|
3902
|
+
context "when there's no sort" do
|
3903
|
+
let(:criteria) do
|
3904
|
+
Band.all
|
2918
3905
|
end
|
2919
3906
|
|
2920
|
-
it "
|
2921
|
-
expect(
|
2922
|
-
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
2923
|
-
])
|
3907
|
+
it "gets the first document" do
|
3908
|
+
expect(context.first!).to eq(depeche_mode)
|
2924
3909
|
end
|
2925
3910
|
end
|
2926
3911
|
|
2927
|
-
context "when
|
2928
|
-
|
3912
|
+
context "when there's a custom sort" do
|
2929
3913
|
let(:criteria) do
|
2930
|
-
Band.
|
3914
|
+
Band.all
|
2931
3915
|
end
|
2932
3916
|
|
2933
|
-
|
2934
|
-
|
3917
|
+
it "gets the first document" do
|
3918
|
+
expect(context.sort(name: 1).first!).to eq(death_cab)
|
2935
3919
|
end
|
3920
|
+
end
|
2936
3921
|
|
2937
|
-
|
2938
|
-
|
3922
|
+
context "when there are no documents" do
|
3923
|
+
let(:criteria) do
|
3924
|
+
Band.where(name: "bogus")
|
2939
3925
|
end
|
2940
3926
|
|
2941
|
-
it "
|
2942
|
-
expect
|
3927
|
+
it "raises an error" do
|
3928
|
+
expect do
|
3929
|
+
context.first!
|
3930
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
2943
3931
|
end
|
3932
|
+
end
|
3933
|
+
end
|
2944
3934
|
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
end
|
3935
|
+
describe "#last!" do
|
3936
|
+
|
3937
|
+
let!(:depeche_mode) do
|
3938
|
+
Band.create!(name: "Depeche Mode")
|
2950
3939
|
end
|
2951
3940
|
|
2952
|
-
|
2953
|
-
|
2954
|
-
|
3941
|
+
let!(:new_order) do
|
3942
|
+
Band.create!(name: "New Order")
|
3943
|
+
end
|
3944
|
+
|
3945
|
+
let!(:rolling_stones) do
|
3946
|
+
Band.create!(name: "The Rolling Stones")
|
3947
|
+
end
|
3948
|
+
|
3949
|
+
let!(:death_cab) do
|
3950
|
+
Band.create!(name: "Death Cab For Cutie")
|
3951
|
+
end
|
2955
3952
|
|
3953
|
+
let(:context) do
|
3954
|
+
described_class.new(criteria)
|
3955
|
+
end
|
3956
|
+
|
3957
|
+
context "when there's no sort" do
|
2956
3958
|
let(:criteria) do
|
2957
|
-
Band.
|
3959
|
+
Band.all
|
2958
3960
|
end
|
2959
3961
|
|
2960
|
-
|
2961
|
-
|
3962
|
+
it "gets the last document" do
|
3963
|
+
expect(context.last!).to eq(death_cab)
|
2962
3964
|
end
|
3965
|
+
end
|
2963
3966
|
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
end
|
3967
|
+
context "when there's a custom sort" do
|
3968
|
+
let(:criteria) do
|
3969
|
+
Band.all
|
2968
3970
|
end
|
2969
3971
|
|
2970
|
-
|
3972
|
+
it "gets the last document" do
|
3973
|
+
expect(context.sort(name: 1).last!).to eq(rolling_stones)
|
3974
|
+
end
|
3975
|
+
end
|
2971
3976
|
|
2972
|
-
|
2973
|
-
|
2974
|
-
|
3977
|
+
context "when there are no documents" do
|
3978
|
+
let(:criteria) do
|
3979
|
+
Band.where(name: "bogus")
|
3980
|
+
end
|
2975
3981
|
|
2976
|
-
|
2977
|
-
|
2978
|
-
|
3982
|
+
it "raises an error" do
|
3983
|
+
expect do
|
3984
|
+
context.last!
|
3985
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3986
|
+
end
|
3987
|
+
end
|
3988
|
+
end
|
2979
3989
|
|
2980
|
-
|
2981
|
-
expect(results).to eq([
|
2982
|
-
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
|
2983
|
-
])
|
2984
|
-
end
|
3990
|
+
describe "#second" do
|
2985
3991
|
|
2986
|
-
|
2987
|
-
|
2988
|
-
|
2989
|
-
end
|
3992
|
+
let!(:depeche_mode) do
|
3993
|
+
Band.create!(name: "Depeche Mode")
|
3994
|
+
end
|
2990
3995
|
|
2991
|
-
|
3996
|
+
let!(:new_order) do
|
3997
|
+
Band.create!(name: "New Order")
|
3998
|
+
end
|
2992
3999
|
|
2993
|
-
|
2994
|
-
|
2995
|
-
|
4000
|
+
let!(:rolling_stones) do
|
4001
|
+
Band.create!(name: "The Rolling Stones")
|
4002
|
+
end
|
2996
4003
|
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
4004
|
+
let!(:death_cab) do
|
4005
|
+
Band.create!(name: "Death Cab For Cutie")
|
4006
|
+
end
|
3000
4007
|
|
3001
|
-
|
3002
|
-
|
3003
|
-
|
3004
|
-
])
|
3005
|
-
end
|
4008
|
+
let(:context) do
|
4009
|
+
described_class.new(criteria)
|
4010
|
+
end
|
3006
4011
|
|
3007
|
-
|
3008
|
-
|
3009
|
-
|
4012
|
+
context "when there's no sort" do
|
4013
|
+
let(:criteria) do
|
4014
|
+
Band.all
|
3010
4015
|
end
|
3011
|
-
end
|
3012
4016
|
|
3013
|
-
|
4017
|
+
it "gets the second document" do
|
4018
|
+
expect(context.second).to eq(new_order)
|
4019
|
+
end
|
4020
|
+
end
|
3014
4021
|
|
4022
|
+
context "when there's a custom sort" do
|
3015
4023
|
let(:criteria) do
|
3016
|
-
Band.
|
4024
|
+
Band.all
|
3017
4025
|
end
|
3018
4026
|
|
3019
|
-
|
3020
|
-
|
4027
|
+
it "gets the second document" do
|
4028
|
+
expect(context.sort(name: 1).second).to eq(depeche_mode)
|
3021
4029
|
end
|
4030
|
+
end
|
3022
4031
|
|
3023
|
-
|
3024
|
-
|
4032
|
+
context "when there are no documents" do
|
4033
|
+
let(:criteria) do
|
4034
|
+
Band.where(name: "bogus")
|
3025
4035
|
end
|
3026
4036
|
|
3027
|
-
it "
|
3028
|
-
expect
|
3029
|
-
results.entries
|
3030
|
-
}.to raise_error(Mongoid::Errors::NoMapReduceOutput)
|
4037
|
+
it "returns nil" do
|
4038
|
+
expect(context.second).to be_nil
|
3031
4039
|
end
|
3032
4040
|
end
|
4041
|
+
end
|
3033
4042
|
|
3034
|
-
|
4043
|
+
describe "#second!" do
|
4044
|
+
|
4045
|
+
let!(:depeche_mode) do
|
4046
|
+
Band.create!(name: "Depeche Mode")
|
4047
|
+
end
|
4048
|
+
|
4049
|
+
let!(:new_order) do
|
4050
|
+
Band.create!(name: "New Order")
|
4051
|
+
end
|
4052
|
+
|
4053
|
+
let!(:rolling_stones) do
|
4054
|
+
Band.create!(name: "The Rolling Stones")
|
4055
|
+
end
|
4056
|
+
|
4057
|
+
let!(:death_cab) do
|
4058
|
+
Band.create!(name: "Death Cab For Cutie")
|
4059
|
+
end
|
4060
|
+
|
4061
|
+
let(:context) do
|
4062
|
+
described_class.new(criteria)
|
4063
|
+
end
|
3035
4064
|
|
4065
|
+
context "when there's no sort" do
|
3036
4066
|
let(:criteria) do
|
3037
|
-
Band.
|
4067
|
+
Band.all
|
3038
4068
|
end
|
3039
4069
|
|
3040
|
-
|
3041
|
-
|
4070
|
+
it "gets the second document" do
|
4071
|
+
expect(context.second!).to eq(new_order)
|
3042
4072
|
end
|
4073
|
+
end
|
3043
4074
|
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
value.extra = true;
|
3048
|
-
return value;
|
3049
|
-
}}
|
4075
|
+
context "when there's a custom sort" do
|
4076
|
+
let(:criteria) do
|
4077
|
+
Band.all
|
3050
4078
|
end
|
3051
4079
|
|
3052
|
-
|
3053
|
-
context.
|
4080
|
+
it "gets the second document" do
|
4081
|
+
expect(context.sort(name: 1).second!).to eq(depeche_mode)
|
3054
4082
|
end
|
4083
|
+
end
|
3055
4084
|
|
3056
|
-
|
3057
|
-
|
4085
|
+
context "when there are no documents" do
|
4086
|
+
let(:criteria) do
|
4087
|
+
Band.where(name: "bogus")
|
3058
4088
|
end
|
3059
4089
|
|
3060
|
-
it "
|
3061
|
-
expect
|
3062
|
-
|
3063
|
-
|
4090
|
+
it "raises an error" do
|
4091
|
+
expect do
|
4092
|
+
context.second!
|
4093
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3064
4094
|
end
|
3065
4095
|
end
|
3066
4096
|
end
|
3067
4097
|
|
3068
|
-
describe "#
|
4098
|
+
describe "#third" do
|
3069
4099
|
|
3070
4100
|
let!(:depeche_mode) do
|
3071
4101
|
Band.create!(name: "Depeche Mode")
|
@@ -3075,20 +4105,50 @@ describe Mongoid::Contextual::Mongo do
|
|
3075
4105
|
Band.create!(name: "New Order")
|
3076
4106
|
end
|
3077
4107
|
|
3078
|
-
let(:
|
3079
|
-
Band.
|
4108
|
+
let!(:rolling_stones) do
|
4109
|
+
Band.create!(name: "The Rolling Stones")
|
4110
|
+
end
|
4111
|
+
|
4112
|
+
let!(:death_cab) do
|
4113
|
+
Band.create!(name: "Death Cab For Cutie")
|
3080
4114
|
end
|
3081
4115
|
|
3082
4116
|
let(:context) do
|
3083
4117
|
described_class.new(criteria)
|
3084
4118
|
end
|
3085
4119
|
|
3086
|
-
|
3087
|
-
|
4120
|
+
context "when there's no sort" do
|
4121
|
+
let(:criteria) do
|
4122
|
+
Band.all
|
4123
|
+
end
|
4124
|
+
|
4125
|
+
it "gets the third document" do
|
4126
|
+
expect(context.third).to eq(rolling_stones)
|
4127
|
+
end
|
4128
|
+
end
|
4129
|
+
|
4130
|
+
context "when there's a custom sort" do
|
4131
|
+
let(:criteria) do
|
4132
|
+
Band.all
|
4133
|
+
end
|
4134
|
+
|
4135
|
+
it "gets the third document" do
|
4136
|
+
expect(context.sort(name: 1).third).to eq(new_order)
|
4137
|
+
end
|
4138
|
+
end
|
4139
|
+
|
4140
|
+
context "when there are no documents" do
|
4141
|
+
let(:criteria) do
|
4142
|
+
Band.where(name: "bogus")
|
4143
|
+
end
|
4144
|
+
|
4145
|
+
it "returns nil" do
|
4146
|
+
expect(context.third).to be_nil
|
4147
|
+
end
|
3088
4148
|
end
|
3089
4149
|
end
|
3090
4150
|
|
3091
|
-
describe "#
|
4151
|
+
describe "#third!" do
|
3092
4152
|
|
3093
4153
|
let!(:depeche_mode) do
|
3094
4154
|
Band.create!(name: "Depeche Mode")
|
@@ -3098,40 +4158,52 @@ describe Mongoid::Contextual::Mongo do
|
|
3098
4158
|
Band.create!(name: "New Order")
|
3099
4159
|
end
|
3100
4160
|
|
3101
|
-
let(:
|
3102
|
-
Band.
|
4161
|
+
let!(:rolling_stones) do
|
4162
|
+
Band.create!(name: "The Rolling Stones")
|
4163
|
+
end
|
4164
|
+
|
4165
|
+
let!(:death_cab) do
|
4166
|
+
Band.create!(name: "Death Cab For Cutie")
|
3103
4167
|
end
|
3104
4168
|
|
3105
4169
|
let(:context) do
|
3106
4170
|
described_class.new(criteria)
|
3107
4171
|
end
|
3108
4172
|
|
3109
|
-
context "when
|
3110
|
-
|
3111
|
-
|
3112
|
-
expect(context.sort(name: -1).entries).to eq([ new_order, depeche_mode ])
|
4173
|
+
context "when there's no sort" do
|
4174
|
+
let(:criteria) do
|
4175
|
+
Band.all
|
3113
4176
|
end
|
3114
4177
|
|
3115
|
-
it "
|
3116
|
-
expect(context.
|
4178
|
+
it "gets the third document" do
|
4179
|
+
expect(context.third!).to eq(rolling_stones)
|
3117
4180
|
end
|
3118
4181
|
end
|
3119
4182
|
|
3120
|
-
context "when
|
4183
|
+
context "when there's a custom sort" do
|
4184
|
+
let(:criteria) do
|
4185
|
+
Band.all
|
4186
|
+
end
|
3121
4187
|
|
3122
|
-
|
3123
|
-
context.sort
|
3124
|
-
b.name <=> a.name
|
3125
|
-
end
|
4188
|
+
it "gets the third document" do
|
4189
|
+
expect(context.sort(name: 1).third!).to eq(new_order)
|
3126
4190
|
end
|
4191
|
+
end
|
3127
4192
|
|
3128
|
-
|
3129
|
-
|
4193
|
+
context "when there are no documents" do
|
4194
|
+
let(:criteria) do
|
4195
|
+
Band.where(name: "bogus")
|
4196
|
+
end
|
4197
|
+
|
4198
|
+
it "raises an error" do
|
4199
|
+
expect do
|
4200
|
+
context.third!
|
4201
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3130
4202
|
end
|
3131
4203
|
end
|
3132
4204
|
end
|
3133
4205
|
|
3134
|
-
describe "#
|
4206
|
+
describe "#fourth" do
|
3135
4207
|
|
3136
4208
|
let!(:depeche_mode) do
|
3137
4209
|
Band.create!(name: "Depeche Mode")
|
@@ -3141,388 +4213,498 @@ describe Mongoid::Contextual::Mongo do
|
|
3141
4213
|
Band.create!(name: "New Order")
|
3142
4214
|
end
|
3143
4215
|
|
3144
|
-
let(:
|
3145
|
-
Band.
|
4216
|
+
let!(:rolling_stones) do
|
4217
|
+
Band.create!(name: "The Rolling Stones")
|
4218
|
+
end
|
4219
|
+
|
4220
|
+
let!(:death_cab) do
|
4221
|
+
Band.create!(name: "Death Cab For Cutie")
|
3146
4222
|
end
|
3147
4223
|
|
3148
4224
|
let(:context) do
|
3149
4225
|
described_class.new(criteria)
|
3150
4226
|
end
|
3151
4227
|
|
3152
|
-
context "when
|
3153
|
-
|
3154
|
-
|
3155
|
-
Person.create!
|
4228
|
+
context "when there's no sort" do
|
4229
|
+
let(:criteria) do
|
4230
|
+
Band.all
|
3156
4231
|
end
|
3157
4232
|
|
3158
|
-
|
3159
|
-
|
4233
|
+
it "gets the fourth document" do
|
4234
|
+
expect(context.fourth).to eq(death_cab)
|
3160
4235
|
end
|
4236
|
+
end
|
3161
4237
|
|
3162
|
-
|
3163
|
-
|
3164
|
-
|
4238
|
+
context "when there's a custom sort" do
|
4239
|
+
let(:criteria) do
|
4240
|
+
Band.all
|
3165
4241
|
end
|
3166
4242
|
|
3167
|
-
it "
|
3168
|
-
expect(
|
4243
|
+
it "gets the fourth document" do
|
4244
|
+
expect(context.sort(name: 1).fourth).to eq(rolling_stones)
|
3169
4245
|
end
|
3170
4246
|
end
|
3171
4247
|
|
3172
|
-
context "when
|
4248
|
+
context "when there are no documents" do
|
4249
|
+
let(:criteria) do
|
4250
|
+
Band.where(name: "bogus")
|
4251
|
+
end
|
3173
4252
|
|
3174
|
-
|
4253
|
+
it "returns nil" do
|
4254
|
+
expect(context.fourth).to be_nil
|
4255
|
+
end
|
4256
|
+
end
|
4257
|
+
end
|
3175
4258
|
|
3176
|
-
|
3177
|
-
context.update(name: "Smiths")
|
3178
|
-
end
|
4259
|
+
describe "#fourth!" do
|
3179
4260
|
|
3180
|
-
|
3181
|
-
|
3182
|
-
|
4261
|
+
let!(:depeche_mode) do
|
4262
|
+
Band.create!(name: "Depeche Mode")
|
4263
|
+
end
|
3183
4264
|
|
3184
|
-
|
3185
|
-
|
3186
|
-
|
3187
|
-
end
|
4265
|
+
let!(:new_order) do
|
4266
|
+
Band.create!(name: "New Order")
|
4267
|
+
end
|
3188
4268
|
|
3189
|
-
|
4269
|
+
let!(:rolling_stones) do
|
4270
|
+
Band.create!(name: "The Rolling Stones")
|
4271
|
+
end
|
3190
4272
|
|
3191
|
-
|
4273
|
+
let!(:death_cab) do
|
4274
|
+
Band.create!(name: "Death Cab For Cutie")
|
4275
|
+
end
|
3192
4276
|
|
3193
|
-
|
3194
|
-
|
3195
|
-
|
4277
|
+
let(:context) do
|
4278
|
+
described_class.new(criteria)
|
4279
|
+
end
|
3196
4280
|
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
4281
|
+
context "when there's no sort" do
|
4282
|
+
let(:criteria) do
|
4283
|
+
Band.all
|
4284
|
+
end
|
3200
4285
|
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
4286
|
+
it "gets the fourth document" do
|
4287
|
+
expect(context.fourth!).to eq(death_cab)
|
4288
|
+
end
|
4289
|
+
end
|
3205
4290
|
|
3206
|
-
|
4291
|
+
context "when there's a custom sort" do
|
4292
|
+
let(:criteria) do
|
4293
|
+
Band.all
|
4294
|
+
end
|
3207
4295
|
|
3208
|
-
|
3209
|
-
|
3210
|
-
|
4296
|
+
it "gets the fourth document" do
|
4297
|
+
expect(context.sort(name: 1).fourth!).to eq(rolling_stones)
|
4298
|
+
end
|
4299
|
+
end
|
3211
4300
|
|
3212
|
-
|
3213
|
-
|
3214
|
-
|
4301
|
+
context "when there are no documents" do
|
4302
|
+
let(:criteria) do
|
4303
|
+
Band.where(name: "bogus")
|
4304
|
+
end
|
3215
4305
|
|
3216
|
-
|
3217
|
-
|
3218
|
-
|
3219
|
-
end
|
4306
|
+
it "raises an error" do
|
4307
|
+
expect do
|
4308
|
+
context.fourth!
|
4309
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3220
4310
|
end
|
3221
4311
|
end
|
4312
|
+
end
|
3222
4313
|
|
3223
|
-
|
4314
|
+
describe "#fifth" do
|
3224
4315
|
|
3225
|
-
|
4316
|
+
let!(:depeche_mode) do
|
4317
|
+
Band.create!(name: "Depeche Mode")
|
4318
|
+
end
|
3226
4319
|
|
3227
|
-
|
4320
|
+
let!(:new_order) do
|
4321
|
+
Band.create!(name: "New Order")
|
4322
|
+
end
|
3228
4323
|
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
4324
|
+
let!(:rolling_stones) do
|
4325
|
+
Band.create!(name: "The Rolling Stones")
|
4326
|
+
end
|
3232
4327
|
|
3233
|
-
|
3234
|
-
|
3235
|
-
|
4328
|
+
let!(:death_cab) do
|
4329
|
+
Band.create!(name: "Death Cab For Cutie")
|
4330
|
+
end
|
3236
4331
|
|
3237
|
-
|
3238
|
-
|
3239
|
-
|
3240
|
-
end
|
4332
|
+
let!(:guns_and_roses) do
|
4333
|
+
Band.create!(name: "Guns and Roses")
|
4334
|
+
end
|
3241
4335
|
|
3242
|
-
|
4336
|
+
let(:context) do
|
4337
|
+
described_class.new(criteria)
|
4338
|
+
end
|
3243
4339
|
|
3244
|
-
|
3245
|
-
|
3246
|
-
|
4340
|
+
context "when there's no sort" do
|
4341
|
+
let(:criteria) do
|
4342
|
+
Band.all
|
4343
|
+
end
|
3247
4344
|
|
3248
|
-
|
3249
|
-
|
3250
|
-
|
4345
|
+
it "gets the fifth document" do
|
4346
|
+
expect(context.fifth).to eq(guns_and_roses)
|
4347
|
+
end
|
4348
|
+
end
|
3251
4349
|
|
3252
|
-
|
3253
|
-
|
3254
|
-
|
3255
|
-
end
|
4350
|
+
context "when there's a custom sort" do
|
4351
|
+
let(:criteria) do
|
4352
|
+
Band.all
|
3256
4353
|
end
|
3257
4354
|
|
3258
|
-
|
4355
|
+
it "gets the fifth document" do
|
4356
|
+
expect(context.sort(name: 1).fifth).to eq(rolling_stones)
|
4357
|
+
end
|
4358
|
+
end
|
3259
4359
|
|
3260
|
-
|
3261
|
-
|
3262
|
-
|
4360
|
+
context "when there are no documents" do
|
4361
|
+
let(:criteria) do
|
4362
|
+
Band.where(name: "bogus")
|
4363
|
+
end
|
3263
4364
|
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
4365
|
+
it "returns nil" do
|
4366
|
+
expect(context.fifth).to be_nil
|
4367
|
+
end
|
4368
|
+
end
|
4369
|
+
end
|
3267
4370
|
|
3268
|
-
|
3269
|
-
expect(depeche_mode.reload.likes).to eq(100)
|
3270
|
-
end
|
4371
|
+
describe "#fifth!" do
|
3271
4372
|
|
3272
|
-
|
3273
|
-
|
3274
|
-
|
4373
|
+
let!(:depeche_mode) do
|
4374
|
+
Band.create!(name: "Depeche Mode")
|
4375
|
+
end
|
3275
4376
|
|
3276
|
-
|
3277
|
-
|
3278
|
-
end
|
3279
|
-
end
|
4377
|
+
let!(:new_order) do
|
4378
|
+
Band.create!(name: "New Order")
|
3280
4379
|
end
|
3281
4380
|
|
3282
|
-
|
4381
|
+
let!(:rolling_stones) do
|
4382
|
+
Band.create!(name: "The Rolling Stones")
|
4383
|
+
end
|
3283
4384
|
|
3284
|
-
|
3285
|
-
|
3286
|
-
end
|
4385
|
+
let!(:death_cab) do
|
4386
|
+
Band.create!(name: "Death Cab For Cutie")
|
3287
4387
|
end
|
3288
4388
|
|
3289
|
-
|
3290
|
-
|
4389
|
+
let!(:guns_and_roses) do
|
4390
|
+
Band.create!(name: "Guns and Roses")
|
4391
|
+
end
|
3291
4392
|
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
b.labels << Label.new(name: 'Warner')
|
3296
|
-
b.labels << Label.new(name: 'Sony')
|
3297
|
-
b.labels << Label.new(name: 'Cbs')
|
3298
|
-
b.save!
|
4393
|
+
let(:context) do
|
4394
|
+
described_class.new(criteria)
|
4395
|
+
end
|
3299
4396
|
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
b.save!
|
4397
|
+
context "when there's no sort" do
|
4398
|
+
let(:criteria) do
|
4399
|
+
Band.all
|
3304
4400
|
end
|
3305
4401
|
|
4402
|
+
it "gets the fifth document" do
|
4403
|
+
expect(context.fifth!).to eq(guns_and_roses)
|
4404
|
+
end
|
4405
|
+
end
|
3306
4406
|
|
4407
|
+
context "when there's a custom sort" do
|
3307
4408
|
let(:criteria) do
|
3308
|
-
Band.
|
4409
|
+
Band.all
|
3309
4410
|
end
|
3310
4411
|
|
3311
|
-
|
3312
|
-
context.
|
3313
|
-
array_filters: [{ 'i.name' => 'Cbs' }])
|
4412
|
+
it "gets the fifth document" do
|
4413
|
+
expect(context.sort(name: 1).fifth!).to eq(rolling_stones)
|
3314
4414
|
end
|
4415
|
+
end
|
3315
4416
|
|
3316
|
-
|
3317
|
-
|
4417
|
+
context "when there are no documents" do
|
4418
|
+
let(:criteria) do
|
4419
|
+
Band.where(name: "bogus")
|
3318
4420
|
end
|
3319
4421
|
|
3320
|
-
it
|
3321
|
-
expect
|
4422
|
+
it "raises an error" do
|
4423
|
+
expect do
|
4424
|
+
context.fifth!
|
4425
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3322
4426
|
end
|
3323
4427
|
end
|
3324
4428
|
end
|
3325
4429
|
|
3326
|
-
describe "#
|
4430
|
+
describe "#second_to_last" do
|
3327
4431
|
|
3328
4432
|
let!(:depeche_mode) do
|
3329
|
-
Band.create!(name: "Depeche Mode"
|
4433
|
+
Band.create!(name: "Depeche Mode")
|
3330
4434
|
end
|
3331
4435
|
|
3332
4436
|
let!(:new_order) do
|
3333
4437
|
Band.create!(name: "New Order")
|
3334
4438
|
end
|
3335
4439
|
|
3336
|
-
let(:
|
3337
|
-
Band.
|
4440
|
+
let!(:rolling_stones) do
|
4441
|
+
Band.create!(name: "The Rolling Stones")
|
4442
|
+
end
|
4443
|
+
|
4444
|
+
let!(:death_cab) do
|
4445
|
+
Band.create!(name: "Death Cab For Cutie")
|
3338
4446
|
end
|
3339
4447
|
|
3340
4448
|
let(:context) do
|
3341
4449
|
described_class.new(criteria)
|
3342
4450
|
end
|
3343
4451
|
|
3344
|
-
context "when
|
4452
|
+
context "when there's no sort" do
|
4453
|
+
let(:criteria) do
|
4454
|
+
Band.all
|
4455
|
+
end
|
3345
4456
|
|
3346
|
-
|
4457
|
+
it "gets the second_to_last document" do
|
4458
|
+
expect(context.second_to_last).to eq(rolling_stones)
|
4459
|
+
end
|
4460
|
+
end
|
3347
4461
|
|
3348
|
-
|
3349
|
-
|
3350
|
-
|
4462
|
+
context "when there's a custom sort" do
|
4463
|
+
let(:criteria) do
|
4464
|
+
Band.all
|
4465
|
+
end
|
3351
4466
|
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
4467
|
+
it "gets the second_to_last document" do
|
4468
|
+
expect(context.sort(name: 1).second_to_last).to eq(new_order)
|
4469
|
+
end
|
4470
|
+
end
|
3355
4471
|
|
3356
|
-
|
3357
|
-
|
3358
|
-
|
4472
|
+
context "when there are no documents" do
|
4473
|
+
let(:criteria) do
|
4474
|
+
Band.where(name: "bogus")
|
4475
|
+
end
|
3359
4476
|
|
3360
|
-
|
3361
|
-
|
3362
|
-
end
|
4477
|
+
it "returns nil" do
|
4478
|
+
expect(context.second_to_last).to be_nil
|
3363
4479
|
end
|
4480
|
+
end
|
4481
|
+
end
|
3364
4482
|
|
3365
|
-
|
4483
|
+
describe "#second_to_last!" do
|
3366
4484
|
|
3367
|
-
|
3368
|
-
|
3369
|
-
|
4485
|
+
let!(:depeche_mode) do
|
4486
|
+
Band.create!(name: "Depeche Mode")
|
4487
|
+
end
|
3370
4488
|
|
3371
|
-
|
3372
|
-
|
3373
|
-
|
4489
|
+
let!(:new_order) do
|
4490
|
+
Band.create!(name: "New Order")
|
4491
|
+
end
|
3374
4492
|
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
end
|
4493
|
+
let!(:rolling_stones) do
|
4494
|
+
Band.create!(name: "The Rolling Stones")
|
4495
|
+
end
|
3379
4496
|
|
3380
|
-
|
4497
|
+
let!(:death_cab) do
|
4498
|
+
Band.create!(name: "Death Cab For Cutie")
|
4499
|
+
end
|
3381
4500
|
|
3382
|
-
|
3383
|
-
|
3384
|
-
|
4501
|
+
let(:context) do
|
4502
|
+
described_class.new(criteria)
|
4503
|
+
end
|
3385
4504
|
|
3386
|
-
|
3387
|
-
|
3388
|
-
|
4505
|
+
context "when there's no sort" do
|
4506
|
+
let(:criteria) do
|
4507
|
+
Band.all
|
4508
|
+
end
|
3389
4509
|
|
3390
|
-
|
3391
|
-
|
3392
|
-
end
|
4510
|
+
it "gets the second_to_last document" do
|
4511
|
+
expect(context.second_to_last!).to eq(rolling_stones)
|
3393
4512
|
end
|
3394
4513
|
end
|
3395
4514
|
|
3396
|
-
context "when
|
4515
|
+
context "when there's a custom sort" do
|
4516
|
+
let(:criteria) do
|
4517
|
+
Band.all
|
4518
|
+
end
|
3397
4519
|
|
3398
|
-
|
4520
|
+
it "gets the second_to_last document" do
|
4521
|
+
expect(context.sort(name: 1).second_to_last!).to eq(new_order)
|
4522
|
+
end
|
4523
|
+
end
|
3399
4524
|
|
3400
|
-
|
4525
|
+
context "when there are no documents" do
|
4526
|
+
let(:criteria) do
|
4527
|
+
Band.where(name: "bogus")
|
4528
|
+
end
|
3401
4529
|
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
4530
|
+
it "raises an error" do
|
4531
|
+
expect do
|
4532
|
+
context.second_to_last!
|
4533
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
4534
|
+
end
|
4535
|
+
end
|
4536
|
+
end
|
3405
4537
|
|
3406
|
-
|
3407
|
-
expect(depeche_mode.reload.name).to eq("Smiths")
|
3408
|
-
end
|
4538
|
+
describe "#third_to_last" do
|
3409
4539
|
|
3410
|
-
|
3411
|
-
|
3412
|
-
|
3413
|
-
end
|
4540
|
+
let!(:depeche_mode) do
|
4541
|
+
Band.create!(name: "Depeche Mode")
|
4542
|
+
end
|
3414
4543
|
|
3415
|
-
|
4544
|
+
let!(:new_order) do
|
4545
|
+
Band.create!(name: "New Order")
|
4546
|
+
end
|
3416
4547
|
|
3417
|
-
|
3418
|
-
|
3419
|
-
|
4548
|
+
let!(:rolling_stones) do
|
4549
|
+
Band.create!(name: "The Rolling Stones")
|
4550
|
+
end
|
3420
4551
|
|
3421
|
-
|
3422
|
-
|
3423
|
-
|
4552
|
+
let!(:death_cab) do
|
4553
|
+
Band.create!(name: "Death Cab For Cutie")
|
4554
|
+
end
|
3424
4555
|
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
end
|
3429
|
-
end
|
4556
|
+
let(:context) do
|
4557
|
+
described_class.new(criteria)
|
4558
|
+
end
|
3430
4559
|
|
3431
|
-
|
4560
|
+
context "when there's no sort" do
|
4561
|
+
let(:criteria) do
|
4562
|
+
Band.all
|
4563
|
+
end
|
3432
4564
|
|
3433
|
-
|
3434
|
-
|
3435
|
-
|
4565
|
+
it "gets the third_to_last document" do
|
4566
|
+
expect(context.third_to_last).to eq(new_order)
|
4567
|
+
end
|
4568
|
+
end
|
3436
4569
|
|
3437
|
-
|
3438
|
-
|
3439
|
-
|
4570
|
+
context "when there's a custom sort" do
|
4571
|
+
let(:criteria) do
|
4572
|
+
Band.all
|
4573
|
+
end
|
3440
4574
|
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
4575
|
+
it "gets the third_to_last document" do
|
4576
|
+
expect(context.sort(name: 1).third_to_last).to eq(depeche_mode)
|
4577
|
+
end
|
4578
|
+
end
|
3444
4579
|
|
3445
|
-
|
3446
|
-
|
3447
|
-
|
4580
|
+
context "when there are no documents" do
|
4581
|
+
let(:criteria) do
|
4582
|
+
Band.where(name: "bogus")
|
4583
|
+
end
|
3448
4584
|
|
3449
|
-
|
3450
|
-
|
3451
|
-
end
|
4585
|
+
it "returns nil" do
|
4586
|
+
expect(context.third_to_last).to be_nil
|
3452
4587
|
end
|
3453
4588
|
end
|
4589
|
+
end
|
3454
4590
|
|
3455
|
-
|
4591
|
+
describe "#third_to_last!" do
|
3456
4592
|
|
3457
|
-
|
3458
|
-
|
3459
|
-
end
|
4593
|
+
let!(:depeche_mode) do
|
4594
|
+
Band.create!(name: "Depeche Mode")
|
3460
4595
|
end
|
3461
4596
|
|
3462
|
-
|
3463
|
-
|
4597
|
+
let!(:new_order) do
|
4598
|
+
Band.create!(name: "New Order")
|
4599
|
+
end
|
3464
4600
|
|
3465
|
-
|
3466
|
-
|
3467
|
-
|
3468
|
-
b.labels << Label.new(name: 'Warner')
|
3469
|
-
b.labels << Label.new(name: 'Sony')
|
3470
|
-
b.labels << Label.new(name: 'Cbs')
|
3471
|
-
b.save!
|
4601
|
+
let!(:rolling_stones) do
|
4602
|
+
Band.create!(name: "The Rolling Stones")
|
4603
|
+
end
|
3472
4604
|
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3476
|
-
|
4605
|
+
let!(:death_cab) do
|
4606
|
+
Band.create!(name: "Death Cab For Cutie")
|
4607
|
+
end
|
4608
|
+
|
4609
|
+
let(:context) do
|
4610
|
+
described_class.new(criteria)
|
4611
|
+
end
|
4612
|
+
|
4613
|
+
context "when there's no sort" do
|
4614
|
+
let(:criteria) do
|
4615
|
+
Band.all
|
3477
4616
|
end
|
3478
4617
|
|
4618
|
+
it "gets the third_to_last document" do
|
4619
|
+
expect(context.third_to_last!).to eq(new_order)
|
4620
|
+
end
|
4621
|
+
end
|
3479
4622
|
|
4623
|
+
context "when there's a custom sort" do
|
3480
4624
|
let(:criteria) do
|
3481
4625
|
Band.all
|
3482
4626
|
end
|
3483
4627
|
|
3484
|
-
|
3485
|
-
context.
|
3486
|
-
array_filters: [{ 'i.name' => 'Cbs' }])
|
4628
|
+
it "gets the third_to_last document" do
|
4629
|
+
expect(context.sort(name: 1).third_to_last!).to eq(depeche_mode)
|
3487
4630
|
end
|
4631
|
+
end
|
3488
4632
|
|
3489
|
-
|
3490
|
-
|
4633
|
+
context "when there are no documents" do
|
4634
|
+
let(:criteria) do
|
4635
|
+
Band.where(name: "bogus")
|
3491
4636
|
end
|
3492
4637
|
|
3493
|
-
it
|
3494
|
-
expect
|
4638
|
+
it "raises an error" do
|
4639
|
+
expect do
|
4640
|
+
context.third_to_last!
|
4641
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
3495
4642
|
end
|
3496
4643
|
end
|
3497
4644
|
end
|
3498
4645
|
|
3499
|
-
describe '#
|
4646
|
+
describe '#load_async' do
|
4647
|
+
let!(:band) do
|
4648
|
+
Band.create!(name: "Depeche Mode")
|
4649
|
+
end
|
3500
4650
|
|
3501
|
-
|
4651
|
+
let(:criteria) do
|
4652
|
+
Band.where(name: "Depeche Mode")
|
4653
|
+
end
|
3502
4654
|
|
3503
|
-
|
3504
|
-
|
3505
|
-
|
3506
|
-
end
|
4655
|
+
let(:context) do
|
4656
|
+
described_class.new(criteria)
|
4657
|
+
end
|
3507
4658
|
|
3508
|
-
|
3509
|
-
|
3510
|
-
end
|
4659
|
+
context 'with global thread pool async query executor' do
|
4660
|
+
config_override :async_query_executor, :global_thread_pool
|
3511
4661
|
|
3512
|
-
|
3513
|
-
|
4662
|
+
it 'preloads the documents' do
|
4663
|
+
context.load_async
|
4664
|
+
context.documents_loader.wait
|
4665
|
+
|
4666
|
+
expect(context.view).not_to receive(:map)
|
4667
|
+
expect(context.to_a).to eq([band])
|
3514
4668
|
end
|
3515
4669
|
|
3516
|
-
|
3517
|
-
|
4670
|
+
it 're-raises exception during preload' do
|
4671
|
+
expect_any_instance_of(Mongoid::Contextual::Mongo::DocumentsLoader)
|
4672
|
+
.to receive(:execute)
|
4673
|
+
.at_least(:once)
|
4674
|
+
.and_raise(Mongo::Error::OperationFailure)
|
4675
|
+
|
4676
|
+
context.load_async
|
4677
|
+
context.documents_loader.wait
|
4678
|
+
|
4679
|
+
expect do
|
4680
|
+
context.to_a
|
4681
|
+
end.to raise_error(Mongo::Error::OperationFailure)
|
3518
4682
|
end
|
4683
|
+
end
|
3519
4684
|
|
3520
|
-
|
3521
|
-
|
4685
|
+
context 'with immediate thread pool async query executor' do
|
4686
|
+
config_override :async_query_executor, :immediate
|
4687
|
+
|
4688
|
+
it 'preloads the documents' do
|
4689
|
+
context.load_async
|
4690
|
+
context.documents_loader.wait
|
4691
|
+
|
4692
|
+
expect(context.view).not_to receive(:map)
|
4693
|
+
expect(context.to_a).to eq([band])
|
3522
4694
|
end
|
3523
4695
|
|
3524
|
-
it '
|
3525
|
-
|
4696
|
+
it 're-raises exception during preload' do
|
4697
|
+
expect_any_instance_of(Mongoid::Contextual::Mongo::DocumentsLoader)
|
4698
|
+
.to receive(:execute)
|
4699
|
+
.at_least(:once)
|
4700
|
+
.and_raise(Mongo::Error::OperationFailure)
|
4701
|
+
|
4702
|
+
context.load_async
|
4703
|
+
context.documents_loader.wait
|
4704
|
+
|
4705
|
+
expect do
|
4706
|
+
context.to_a
|
4707
|
+
end.to raise_error(Mongo::Error::OperationFailure)
|
3526
4708
|
end
|
3527
4709
|
end
|
3528
4710
|
end
|