mongoid 7.5.1 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +6 -6
- data/Rakefile +25 -0
- 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 +54 -14
- 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/paths/embedded/many.rb +19 -0
- 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/cacheable.rb +2 -2
- 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 +145 -17
- 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 +521 -333
- 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 +93 -8
- data/lib/mongoid/criteria/queryable/smash.rb +40 -7
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- 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 +36 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +135 -36
- 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 +19 -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 +76 -15
- 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 +63 -10
- 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/shardable.rb +35 -11
- 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 +360 -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 +276 -65
- data/spec/mongoid/association/embedded/embeds_many_models.rb +158 -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 +215 -228
- 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 +193 -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 +554 -33
- data/spec/mongoid/cacheable_spec.rb +3 -3
- 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 +179 -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 +220 -30
- 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 +1570 -413
- 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 +90 -5
- data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
- 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 +599 -8
- 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 +57 -58
- 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_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +157 -51
- 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 -10
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
- data/spec/shared/shlib/server.sh +5 -5
- 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 +720 -638
- 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
|
|
|
@@ -217,16 +186,18 @@ describe Mongoid::Contextual::Mongo do
|
|
|
217
186
|
end
|
|
218
187
|
end
|
|
219
188
|
|
|
220
|
-
context "when
|
|
189
|
+
context "when the query cache is enabled" do
|
|
190
|
+
query_cache_enabled
|
|
221
191
|
|
|
222
192
|
let(:context) do
|
|
223
|
-
described_class.new(criteria
|
|
193
|
+
described_class.new(criteria)
|
|
224
194
|
end
|
|
225
195
|
|
|
226
|
-
it "
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
196
|
+
it "the results are not cached" do
|
|
197
|
+
expect_query(2) do
|
|
198
|
+
2.times do
|
|
199
|
+
context.estimated_count
|
|
200
|
+
end
|
|
230
201
|
end
|
|
231
202
|
end
|
|
232
203
|
end
|
|
@@ -561,8 +532,22 @@ describe Mongoid::Contextual::Mongo do
|
|
|
561
532
|
context "when legacy_pluck_distinct is set" do
|
|
562
533
|
config_override :legacy_pluck_distinct, true
|
|
563
534
|
|
|
564
|
-
|
|
565
|
-
|
|
535
|
+
context 'when storing BigDecimal as string' do
|
|
536
|
+
config_override :map_big_decimal_to_decimal128, false
|
|
537
|
+
|
|
538
|
+
it "returns the non-demongoized distinct field values" do
|
|
539
|
+
expect(context.distinct(:sales).sort).to eq([ "1E2", "2E3" ])
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
context 'when storing BigDecimal as decimal128' do
|
|
544
|
+
config_override :map_big_decimal_to_decimal128, true
|
|
545
|
+
min_bson_version '4.15.0'
|
|
546
|
+
max_bson_version '4.99.99'
|
|
547
|
+
|
|
548
|
+
it "returns the non-demongoized distinct field values" do
|
|
549
|
+
expect(context.distinct(:sales).sort).to eq([ BSON::Decimal128.new("1E2"), BSON::Decimal128.new("2E3") ])
|
|
550
|
+
end
|
|
566
551
|
end
|
|
567
552
|
end
|
|
568
553
|
|
|
@@ -576,6 +561,8 @@ describe Mongoid::Contextual::Mongo do
|
|
|
576
561
|
end
|
|
577
562
|
|
|
578
563
|
context "when getting a localized field" do
|
|
564
|
+
with_default_i18n_configs
|
|
565
|
+
|
|
579
566
|
before do
|
|
580
567
|
I18n.locale = :en
|
|
581
568
|
d = Dictionary.create!(description: 'english-text')
|
|
@@ -584,10 +571,6 @@ describe Mongoid::Contextual::Mongo do
|
|
|
584
571
|
d.save!
|
|
585
572
|
end
|
|
586
573
|
|
|
587
|
-
after do
|
|
588
|
-
I18n.locale = :en
|
|
589
|
-
end
|
|
590
|
-
|
|
591
574
|
let(:criteria) do
|
|
592
575
|
Dictionary.criteria
|
|
593
576
|
end
|
|
@@ -680,16 +663,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
680
663
|
|
|
681
664
|
context 'when fallbacks are enabled with a locale list' do
|
|
682
665
|
require_fallbacks
|
|
666
|
+
with_default_i18n_configs
|
|
683
667
|
|
|
684
|
-
|
|
685
|
-
prev_fallbacks = I18n.fallbacks.dup
|
|
668
|
+
before do
|
|
686
669
|
I18n.fallbacks[:he] = [ :en ]
|
|
687
|
-
example.run
|
|
688
|
-
I18n.fallbacks = prev_fallbacks
|
|
689
|
-
end
|
|
690
|
-
|
|
691
|
-
after do
|
|
692
|
-
I18n.locale = :en
|
|
693
670
|
end
|
|
694
671
|
|
|
695
672
|
let(:distinct) do
|
|
@@ -709,7 +686,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
709
686
|
|
|
710
687
|
it "correctly uses the fallback" do
|
|
711
688
|
I18n.locale = :en
|
|
712
|
-
|
|
689
|
+
Dictionary.create!(description: 'english-text')
|
|
713
690
|
I18n.locale = :he
|
|
714
691
|
distinct.should == "english-text"
|
|
715
692
|
end
|
|
@@ -717,6 +694,8 @@ describe Mongoid::Contextual::Mongo do
|
|
|
717
694
|
end
|
|
718
695
|
|
|
719
696
|
context "when the localized field is embedded" do
|
|
697
|
+
with_default_i18n_configs
|
|
698
|
+
|
|
720
699
|
before do
|
|
721
700
|
p = Passport.new
|
|
722
701
|
I18n.locale = :en
|
|
@@ -727,10 +706,6 @@ describe Mongoid::Contextual::Mongo do
|
|
|
727
706
|
Person.create!(passport: p, employer_id: 12345)
|
|
728
707
|
end
|
|
729
708
|
|
|
730
|
-
after do
|
|
731
|
-
I18n.locale = :en
|
|
732
|
-
end
|
|
733
|
-
|
|
734
709
|
let(:criteria) do
|
|
735
710
|
Person.where(employer_id: 12345)
|
|
736
711
|
end
|
|
@@ -794,9 +769,11 @@ describe Mongoid::Contextual::Mongo do
|
|
|
794
769
|
|
|
795
770
|
context "when legacy_pluck_distinct is set" do
|
|
796
771
|
config_override :legacy_pluck_distinct, true
|
|
772
|
+
config_override :map_big_decimal_to_decimal128, true
|
|
773
|
+
max_bson_version '4.99.99'
|
|
797
774
|
|
|
798
775
|
it "returns the distinct matching fields" do
|
|
799
|
-
expect(context.distinct("label.sales")).to eq([
|
|
776
|
+
expect(context.distinct("label.sales")).to eq([ BSON::Decimal128.new('1E+2') ])
|
|
800
777
|
end
|
|
801
778
|
end
|
|
802
779
|
|
|
@@ -809,6 +786,452 @@ describe Mongoid::Contextual::Mongo do
|
|
|
809
786
|
end
|
|
810
787
|
end
|
|
811
788
|
|
|
789
|
+
describe "#tally" do
|
|
790
|
+
let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
|
791
|
+
let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
|
792
|
+
let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
|
|
793
|
+
|
|
794
|
+
let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
|
|
795
|
+
let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
|
|
796
|
+
let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
|
|
797
|
+
|
|
798
|
+
let(:label1) { Label.new(name: "Atlantic") }
|
|
799
|
+
let(:label2) { Label.new(name: "Atlantic") }
|
|
800
|
+
let(:label3) { Label.new(name: "Columbia") }
|
|
801
|
+
|
|
802
|
+
before do
|
|
803
|
+
Band.create!(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1)
|
|
804
|
+
Band.create!(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2)
|
|
805
|
+
Band.create!(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3)
|
|
806
|
+
Band.create!(origin: "tally2", fanatics: fans1, genres: [1, 2])
|
|
807
|
+
Band.create!(origin: "tally2", fanatics: fans2, genres: [1, 2])
|
|
808
|
+
Band.create!(origin: "tally2", fanatics: fans3, genres: [1, 3])
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
812
|
+
|
|
813
|
+
context "when tallying a string" do
|
|
814
|
+
let(:tally) do
|
|
815
|
+
criteria.tally(:name)
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
it "returns the correct hash" do
|
|
819
|
+
expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
|
|
820
|
+
end
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
context "using an aliased field" do
|
|
824
|
+
let(:tally) do
|
|
825
|
+
criteria.tally(:years)
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
it "returns the correct hash" do
|
|
829
|
+
expect(tally).to eq(30 => 3)
|
|
830
|
+
end
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
context "when tallying a demongoizable field" do
|
|
834
|
+
let(:tally) do
|
|
835
|
+
criteria.tally(:sales)
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
it "returns the correct hash" do
|
|
839
|
+
expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
context "when tallying a localized field" do
|
|
844
|
+
with_default_i18n_configs
|
|
845
|
+
|
|
846
|
+
before do
|
|
847
|
+
I18n.locale = :en
|
|
848
|
+
d1 = Dictionary.create!(description: 'en1')
|
|
849
|
+
d2 = Dictionary.create!(description: 'en1')
|
|
850
|
+
d3 = Dictionary.create!(description: 'en1')
|
|
851
|
+
d4 = Dictionary.create!(description: 'en2')
|
|
852
|
+
I18n.locale = :de
|
|
853
|
+
d1.description = 'de1'
|
|
854
|
+
d2.description = 'de1'
|
|
855
|
+
d3.description = 'de2'
|
|
856
|
+
d4.description = 'de3'
|
|
857
|
+
d1.save!
|
|
858
|
+
d2.save!
|
|
859
|
+
d3.save!
|
|
860
|
+
d4.save!
|
|
861
|
+
I18n.locale = :en
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
context "when getting the demongoized field" do
|
|
865
|
+
let(:tallied) do
|
|
866
|
+
Dictionary.tally(:description)
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
it "returns the translation for the current locale" do
|
|
870
|
+
expect(tallied).to eq("en1" => 3, "en2" => 1)
|
|
871
|
+
end
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
context "when getting a specific locale" do
|
|
875
|
+
let(:tallied) do
|
|
876
|
+
Dictionary.tally("description.de")
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
it "returns the translation for the the specific locale" do
|
|
880
|
+
expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
|
|
881
|
+
end
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
context "when getting the full hash" do
|
|
885
|
+
let(:tallied) do
|
|
886
|
+
Dictionary.tally("description_translations")
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
it "returns the correct hash" do
|
|
890
|
+
expect(tallied).to eq(
|
|
891
|
+
{"de" => "de1", "en" => "en1" } => 2,
|
|
892
|
+
{"de" => "de2", "en" => "en1" } => 1,
|
|
893
|
+
{"de" => "de3", "en" => "en2" } => 1
|
|
894
|
+
)
|
|
895
|
+
end
|
|
896
|
+
end
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
context "when tallying an embedded localized field" do
|
|
900
|
+
with_default_i18n_configs
|
|
901
|
+
|
|
902
|
+
before do
|
|
903
|
+
I18n.locale = :en
|
|
904
|
+
address1a = Address.new(name: "en1")
|
|
905
|
+
address1b = Address.new(name: "en2")
|
|
906
|
+
address2a = Address.new(name: "en1")
|
|
907
|
+
address2b = Address.new(name: "en3")
|
|
908
|
+
I18n.locale = :de
|
|
909
|
+
address1a.name = "de1"
|
|
910
|
+
address1b.name = "de2"
|
|
911
|
+
address2a.name = "de1"
|
|
912
|
+
address2b.name = "de3"
|
|
913
|
+
Person.create!(addresses: [ address1a, address1b ])
|
|
914
|
+
Person.create!(addresses: [ address2a, address2b ])
|
|
915
|
+
I18n.locale = :en
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
context "when getting the demongoized field" do
|
|
919
|
+
let(:tallied) do
|
|
920
|
+
Person.tally("addresses.name")
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
it "returns the translation for the current locale" do
|
|
924
|
+
expect(tallied).to eq(
|
|
925
|
+
[ "en1", "en2" ] => 1,
|
|
926
|
+
[ "en1", "en3" ] => 1,
|
|
927
|
+
)
|
|
928
|
+
end
|
|
929
|
+
end
|
|
930
|
+
|
|
931
|
+
context "when getting a specific locale" do
|
|
932
|
+
let(:tallied) do
|
|
933
|
+
Person.tally("addresses.name.de")
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
it "returns the translation for the the specific locale" do
|
|
937
|
+
expect(tallied).to eq(
|
|
938
|
+
[ "de1", "de2" ] => 1,
|
|
939
|
+
[ "de1", "de3" ] => 1,
|
|
940
|
+
)
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
context "when getting the full hash" do
|
|
945
|
+
let(:tallied) do
|
|
946
|
+
Person.tally("addresses.name_translations")
|
|
947
|
+
end
|
|
948
|
+
|
|
949
|
+
it "returns the correct hash" do
|
|
950
|
+
expect(tallied).to eq(
|
|
951
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
|
|
952
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
|
|
953
|
+
)
|
|
954
|
+
end
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
context "when tallying an embedded field" do
|
|
960
|
+
let(:tally) do
|
|
961
|
+
criteria.tally("label.name")
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
it "returns the correct hash" do
|
|
965
|
+
expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
|
|
966
|
+
end
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
context "when tallying an element in an embeds_many field" do
|
|
970
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
971
|
+
|
|
972
|
+
let(:tally) do
|
|
973
|
+
criteria.tally("fanatics.age")
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
it "returns the correct hash" do
|
|
977
|
+
expect(tally).to eq(
|
|
978
|
+
[1, 2] => 2,
|
|
979
|
+
[1, 3] => 1
|
|
980
|
+
)
|
|
981
|
+
end
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
context "when tallying an embeds_many field" do
|
|
985
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
986
|
+
|
|
987
|
+
let(:tally) do
|
|
988
|
+
criteria.tally("fanatics")
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
it "returns the correct hash" do
|
|
992
|
+
expect(tally).to eq(
|
|
993
|
+
fans1.map(&:attributes) => 1,
|
|
994
|
+
fans2.map(&:attributes) => 1,
|
|
995
|
+
fans3.map(&:attributes) => 1,
|
|
996
|
+
)
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
context "when tallying a field of type array" do
|
|
1001
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
1002
|
+
|
|
1003
|
+
let(:tally) do
|
|
1004
|
+
criteria.tally("genres")
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
it "returns the correct hash" do
|
|
1008
|
+
expect(tally).to eq(
|
|
1009
|
+
[1, 2] => 2,
|
|
1010
|
+
[1, 3] => 1
|
|
1011
|
+
)
|
|
1012
|
+
end
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1015
|
+
context "when tallying an element from an array of hashes" do
|
|
1016
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1017
|
+
|
|
1018
|
+
let(:tally) do
|
|
1019
|
+
criteria.tally("genres.x")
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
it "returns the correct hash without the nil keys" do
|
|
1023
|
+
expect(tally).to eq(
|
|
1024
|
+
[1, 2] => 2,
|
|
1025
|
+
[1, 3] => 1
|
|
1026
|
+
)
|
|
1027
|
+
end
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
context "when tallying an element from an array of hashes; with duplicate" do
|
|
1031
|
+
|
|
1032
|
+
before do
|
|
1033
|
+
Band.create!(origin: "tally", genres: [ { x: 1 }, {x: 1} ] )
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1037
|
+
|
|
1038
|
+
let(:tally) do
|
|
1039
|
+
criteria.tally("genres.x")
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
it "returns the correct hash without the nil keys" do
|
|
1043
|
+
expect(tally).to eq(
|
|
1044
|
+
[1, 2] => 2,
|
|
1045
|
+
[1, 3] => 1,
|
|
1046
|
+
[1, 1] => 1,
|
|
1047
|
+
)
|
|
1048
|
+
end
|
|
1049
|
+
end
|
|
1050
|
+
|
|
1051
|
+
context "when tallying an aliased field of type array" do
|
|
1052
|
+
|
|
1053
|
+
before do
|
|
1054
|
+
Person.create!(array: [ 1, 2 ])
|
|
1055
|
+
Person.create!(array: [ 1, 3 ])
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
let(:tally) do
|
|
1059
|
+
Person.tally("array")
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
it "returns the correct hash" do
|
|
1063
|
+
expect(tally).to eq(
|
|
1064
|
+
[1, 2] => 1,
|
|
1065
|
+
[1, 3] => 1
|
|
1066
|
+
)
|
|
1067
|
+
end
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
context "when going multiple levels deep in arrays" do
|
|
1071
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1072
|
+
|
|
1073
|
+
let(:tally) do
|
|
1074
|
+
criteria.tally("genres.y.z")
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
it "returns the correct hash" do
|
|
1078
|
+
expect(tally).to eq(
|
|
1079
|
+
[1, 2] => 2,
|
|
1080
|
+
[1, 3] => 1
|
|
1081
|
+
)
|
|
1082
|
+
end
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
context "when going multiple levels deep in an array" do
|
|
1086
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1087
|
+
|
|
1088
|
+
let(:tally) do
|
|
1089
|
+
criteria.tally("genres.y.z")
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
it "returns the correct hash" do
|
|
1093
|
+
expect(tally).to eq(
|
|
1094
|
+
[1, 2] => 2,
|
|
1095
|
+
[1, 3] => 1
|
|
1096
|
+
)
|
|
1097
|
+
end
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
|
1101
|
+
|
|
1102
|
+
before do
|
|
1103
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1104
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1105
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
let(:tally) do
|
|
1109
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
it "returns the correct hash" do
|
|
1113
|
+
expect(tally).to eq(
|
|
1114
|
+
[ [ 1, 2 ] ] => 2,
|
|
1115
|
+
[ [ 1, 3 ] ] => 1
|
|
1116
|
+
)
|
|
1117
|
+
end
|
|
1118
|
+
end
|
|
1119
|
+
|
|
1120
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
|
1121
|
+
|
|
1122
|
+
before do
|
|
1123
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
|
1124
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1125
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
|
1126
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1127
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
|
|
1128
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
|
1129
|
+
end
|
|
1130
|
+
|
|
1131
|
+
let(:tally) do
|
|
1132
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
it "returns the correct hash" do
|
|
1136
|
+
expect(tally).to eq(
|
|
1137
|
+
[ [ 1, 2 ], [ 1, 2 ] ] => 2,
|
|
1138
|
+
[ [ 1, 3 ], [ 1, 3 ] ] => 1
|
|
1139
|
+
)
|
|
1140
|
+
end
|
|
1141
|
+
end
|
|
1142
|
+
|
|
1143
|
+
context "when some keys are missing" do
|
|
1144
|
+
before do
|
|
1145
|
+
3.times { Band.create!(origin: "tally") }
|
|
1146
|
+
end
|
|
1147
|
+
|
|
1148
|
+
let(:tally) do
|
|
1149
|
+
criteria.tally(:name)
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
it "returns the correct hash" do
|
|
1153
|
+
expect(tally).to eq(
|
|
1154
|
+
"Depeche Mode" => 1,
|
|
1155
|
+
"New Order" => 1,
|
|
1156
|
+
"10,000 Maniacs" => 1,
|
|
1157
|
+
nil => 3
|
|
1158
|
+
)
|
|
1159
|
+
end
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
context "when the first element is an embeds_one" do
|
|
1163
|
+
before do
|
|
1164
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
|
1165
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
|
1166
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
let(:tally) do
|
|
1170
|
+
Person.tally("name.translations.language")
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
it "returns the correct hash" do
|
|
1174
|
+
expect(tally).to eq(
|
|
1175
|
+
[1, 2] => 2,
|
|
1176
|
+
[1, 3] => 1
|
|
1177
|
+
)
|
|
1178
|
+
end
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
context "when tallying demongoizable values from typeless fields" do
|
|
1182
|
+
|
|
1183
|
+
let!(:person1) { Person.create!(ssn: /hello/) }
|
|
1184
|
+
let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
|
|
1185
|
+
let(:tally) { Person.tally("ssn") }
|
|
1186
|
+
|
|
1187
|
+
let(:tallied_classes) do
|
|
1188
|
+
tally.keys.map(&:class).sort do |a, b|
|
|
1189
|
+
a.to_s.casecmp(b.to_s)
|
|
1190
|
+
end
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1193
|
+
context "< BSON 5" do
|
|
1194
|
+
max_bson_version '4.99.99'
|
|
1195
|
+
|
|
1196
|
+
it "stores the correct types in the database" do
|
|
1197
|
+
expect(Person.find(person1.id).attributes["ssn"]).to be_a BSON::Regexp::Raw
|
|
1198
|
+
expect(Person.find(person2.id).attributes["ssn"]).to be_a BSON::Decimal128
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
it "tallies the correct type" do
|
|
1202
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
|
1203
|
+
end
|
|
1204
|
+
end
|
|
1205
|
+
|
|
1206
|
+
context '>= BSON 5' do
|
|
1207
|
+
min_bson_version "5.0"
|
|
1208
|
+
|
|
1209
|
+
it "stores the correct types in the database" do
|
|
1210
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
|
1211
|
+
expect(Person.find(person2.id).ssn).to be_a BigDecimal
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
it "tallies the correct type" do
|
|
1215
|
+
expect(tallied_classes).to be == [ BigDecimal, BSON::Regexp::Raw ]
|
|
1216
|
+
end
|
|
1217
|
+
end
|
|
1218
|
+
|
|
1219
|
+
context '>= BSON 5 with decimal128 allowed' do
|
|
1220
|
+
min_bson_version "5.0"
|
|
1221
|
+
config_override :allow_bson5_decimal128, true
|
|
1222
|
+
|
|
1223
|
+
it "stores the correct types in the database" do
|
|
1224
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
|
1225
|
+
expect(Person.find(person2.id).ssn).to be_a BSON::Decimal128
|
|
1226
|
+
end
|
|
1227
|
+
|
|
1228
|
+
it "tallies the correct type" do
|
|
1229
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1232
|
+
end
|
|
1233
|
+
end
|
|
1234
|
+
|
|
812
1235
|
describe "#each" do
|
|
813
1236
|
|
|
814
1237
|
before do
|
|
@@ -973,98 +1396,175 @@ describe Mongoid::Contextual::Mongo do
|
|
|
973
1396
|
|
|
974
1397
|
describe "#exists?" do
|
|
975
1398
|
|
|
976
|
-
|
|
977
|
-
Band.create!(name: "Depeche Mode")
|
|
1399
|
+
let!(:band) do
|
|
1400
|
+
Band.create!(name: "Depeche Mode", active: true)
|
|
978
1401
|
end
|
|
979
1402
|
|
|
980
|
-
context "when
|
|
1403
|
+
context "when not passing options" do
|
|
981
1404
|
|
|
982
|
-
|
|
983
|
-
Band.where(name: "New Order")
|
|
984
|
-
end
|
|
1405
|
+
context "when the count is zero" do
|
|
985
1406
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1407
|
+
let(:criteria) do
|
|
1408
|
+
Band.where(name: "New Order")
|
|
1409
|
+
end
|
|
989
1410
|
|
|
990
|
-
|
|
991
|
-
|
|
1411
|
+
let(:context) do
|
|
1412
|
+
described_class.new(criteria)
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1415
|
+
it "returns false" do
|
|
1416
|
+
expect(context).to_not be_exists
|
|
1417
|
+
end
|
|
992
1418
|
end
|
|
993
|
-
end
|
|
994
1419
|
|
|
995
|
-
|
|
1420
|
+
context "when the count is greater than zero" do
|
|
996
1421
|
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1422
|
+
let(:criteria) do
|
|
1423
|
+
Band.where(name: "Depeche Mode")
|
|
1424
|
+
end
|
|
1000
1425
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1426
|
+
let(:context) do
|
|
1427
|
+
described_class.new(criteria)
|
|
1428
|
+
end
|
|
1429
|
+
|
|
1430
|
+
it "returns true" do
|
|
1431
|
+
expect(context).to be_exists
|
|
1432
|
+
end
|
|
1003
1433
|
end
|
|
1004
1434
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1435
|
+
context "when caching is not enabled" do
|
|
1436
|
+
|
|
1437
|
+
let(:criteria) do
|
|
1438
|
+
Band.where(name: "Depeche Mode")
|
|
1439
|
+
end
|
|
1440
|
+
|
|
1441
|
+
let(:context) do
|
|
1442
|
+
described_class.new(criteria)
|
|
1443
|
+
end
|
|
1444
|
+
|
|
1445
|
+
context "when exists? already called and query cache is enabled" do
|
|
1446
|
+
query_cache_enabled
|
|
1447
|
+
|
|
1448
|
+
before do
|
|
1449
|
+
context.exists?
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
it "does not hit the database again" do
|
|
1453
|
+
expect_no_queries do
|
|
1454
|
+
expect(context).to be_exists
|
|
1455
|
+
end
|
|
1456
|
+
end
|
|
1457
|
+
end
|
|
1007
1458
|
end
|
|
1008
1459
|
end
|
|
1009
1460
|
|
|
1010
|
-
context "when
|
|
1461
|
+
context "when passing an _id" do
|
|
1011
1462
|
|
|
1012
|
-
|
|
1013
|
-
Band.where(name: "Depeche Mode")
|
|
1014
|
-
end
|
|
1463
|
+
context "when its of type BSON::ObjectId" do
|
|
1015
1464
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1465
|
+
context "when calling it on the class" do
|
|
1466
|
+
|
|
1467
|
+
it "returns true" do
|
|
1468
|
+
expect(Band.exists?(band._id)).to be true
|
|
1469
|
+
end
|
|
1470
|
+
end
|
|
1471
|
+
|
|
1472
|
+
context "when calling it on a criteria that includes the object" do
|
|
1473
|
+
|
|
1474
|
+
it "returns true" do
|
|
1475
|
+
expect(Band.where(name: band.name).exists?(band._id)).to be true
|
|
1476
|
+
end
|
|
1477
|
+
end
|
|
1478
|
+
|
|
1479
|
+
context "when calling it on a criteria that does not include the object" do
|
|
1480
|
+
|
|
1481
|
+
it "returns false" do
|
|
1482
|
+
expect(Band.where(name: "bogus").exists?(band._id)).to be false
|
|
1483
|
+
end
|
|
1484
|
+
end
|
|
1485
|
+
|
|
1486
|
+
context "when the id does not exist" do
|
|
1487
|
+
|
|
1488
|
+
it "returns false" do
|
|
1489
|
+
expect(Band.exists?(BSON::ObjectId.new)).to be false
|
|
1490
|
+
end
|
|
1491
|
+
end
|
|
1018
1492
|
end
|
|
1019
1493
|
|
|
1020
|
-
context "when
|
|
1494
|
+
context "when its of type String" do
|
|
1021
1495
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1496
|
+
context "when the id exists" do
|
|
1497
|
+
|
|
1498
|
+
it "returns true" do
|
|
1499
|
+
expect(Band.exists?(band._id.to_s)).to be true
|
|
1500
|
+
end
|
|
1024
1501
|
end
|
|
1025
1502
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1503
|
+
context "when the id does not exist" do
|
|
1504
|
+
|
|
1505
|
+
it "returns false" do
|
|
1506
|
+
expect(Band.exists?(BSON::ObjectId.new.to_s)).to be false
|
|
1507
|
+
end
|
|
1029
1508
|
end
|
|
1030
1509
|
end
|
|
1031
1510
|
end
|
|
1032
1511
|
|
|
1033
|
-
context "when
|
|
1512
|
+
context "when passing a hash" do
|
|
1034
1513
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1514
|
+
context "when calling it on the class" do
|
|
1515
|
+
|
|
1516
|
+
it "returns true" do
|
|
1517
|
+
expect(Band.exists?(name: band.name)).to be true
|
|
1518
|
+
end
|
|
1037
1519
|
end
|
|
1038
1520
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1521
|
+
context "when calling it on a criteria that includes the object" do
|
|
1522
|
+
|
|
1523
|
+
it "returns true" do
|
|
1524
|
+
expect(Band.where(active: true).exists?(name: band.name)).to be true
|
|
1525
|
+
end
|
|
1041
1526
|
end
|
|
1042
1527
|
|
|
1043
|
-
context "when
|
|
1528
|
+
context "when calling it on a criteria that does not include the object" do
|
|
1044
1529
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1530
|
+
it "returns false" do
|
|
1531
|
+
expect(Band.where(active: false).exists?(name: band.name)).to be false
|
|
1047
1532
|
end
|
|
1533
|
+
end
|
|
1048
1534
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1535
|
+
context "when the conditions don't match" do
|
|
1536
|
+
|
|
1537
|
+
it "returns false" do
|
|
1538
|
+
expect(Band.exists?(name: "bogus")).to be false
|
|
1052
1539
|
end
|
|
1053
1540
|
end
|
|
1541
|
+
end
|
|
1054
1542
|
|
|
1055
|
-
|
|
1543
|
+
context "when passing false" do
|
|
1056
1544
|
|
|
1057
|
-
|
|
1545
|
+
it "returns false" do
|
|
1546
|
+
expect(Band.exists?(false)).to be false
|
|
1547
|
+
end
|
|
1548
|
+
end
|
|
1058
1549
|
|
|
1059
|
-
|
|
1060
|
-
context.count
|
|
1061
|
-
end
|
|
1550
|
+
context "when passing nil" do
|
|
1062
1551
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1552
|
+
it "returns false" do
|
|
1553
|
+
expect(Band.exists?(nil)).to be false
|
|
1554
|
+
end
|
|
1555
|
+
end
|
|
1556
|
+
|
|
1557
|
+
context "when the limit is 0" do
|
|
1558
|
+
|
|
1559
|
+
it "returns false" do
|
|
1560
|
+
expect(Band.limit(0).exists?).to be false
|
|
1561
|
+
end
|
|
1562
|
+
end
|
|
1563
|
+
|
|
1564
|
+
context "when the criteria limit is 0" do
|
|
1565
|
+
|
|
1566
|
+
it "returns false" do
|
|
1567
|
+
expect(Band.criteria.limit(0).exists?).to be false
|
|
1068
1568
|
end
|
|
1069
1569
|
end
|
|
1070
1570
|
end
|
|
@@ -1080,7 +1580,16 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1080
1580
|
end
|
|
1081
1581
|
|
|
1082
1582
|
it "returns the criteria explain path" do
|
|
1083
|
-
|
|
1583
|
+
explain = context.explain
|
|
1584
|
+
expect(explain).to_not be_empty
|
|
1585
|
+
expect(explain.keys).to include("queryPlanner", "executionStats", "serverInfo")
|
|
1586
|
+
end
|
|
1587
|
+
|
|
1588
|
+
it "respects options passed to explain" do
|
|
1589
|
+
explain = context.explain(verbosity: :query_planner)
|
|
1590
|
+
expect(explain).to_not be_empty
|
|
1591
|
+
expect(explain.keys).to include("queryPlanner", "serverInfo")
|
|
1592
|
+
expect(explain.keys).not_to include("executionStats")
|
|
1084
1593
|
end
|
|
1085
1594
|
end
|
|
1086
1595
|
|
|
@@ -1420,7 +1929,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1420
1929
|
it "deletes the document from the database" do
|
|
1421
1930
|
expect {
|
|
1422
1931
|
depeche.reload
|
|
1423
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
1932
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
|
1424
1933
|
end
|
|
1425
1934
|
|
|
1426
1935
|
context 'when a collation is specified on the criteria' do
|
|
@@ -1445,7 +1954,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1445
1954
|
it "deletes the document from the database" do
|
|
1446
1955
|
expect {
|
|
1447
1956
|
depeche.reload
|
|
1448
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
1957
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
|
1449
1958
|
end
|
|
1450
1959
|
end
|
|
1451
1960
|
end
|
|
@@ -1561,24 +2070,6 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1561
2070
|
expect(context.last).to eq(rolling_stones)
|
|
1562
2071
|
end
|
|
1563
2072
|
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 #last' 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
2073
|
end
|
|
1583
2074
|
|
|
1584
2075
|
context 'when the criteria has a sort' do
|
|
@@ -1602,25 +2093,6 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1602
2093
|
expect(context.last).to eq(depeche_mode)
|
|
1603
2094
|
end
|
|
1604
2095
|
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
2096
|
end
|
|
1625
2097
|
|
|
1626
2098
|
context "when using .sort" do
|
|
@@ -1649,28 +2121,17 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1649
2121
|
end
|
|
1650
2122
|
end
|
|
1651
2123
|
|
|
1652
|
-
context "when the
|
|
2124
|
+
context "when the query cache is enabled" do
|
|
2125
|
+
query_cache_enabled
|
|
1653
2126
|
|
|
1654
2127
|
let(:criteria) do
|
|
1655
|
-
Band.where(name: "Depeche Mode")
|
|
2128
|
+
Band.where(name: "Depeche Mode")
|
|
1656
2129
|
end
|
|
1657
2130
|
|
|
1658
2131
|
let(:context) do
|
|
1659
2132
|
described_class.new(criteria)
|
|
1660
2133
|
end
|
|
1661
2134
|
|
|
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
2135
|
context "when first method was called before" do
|
|
1675
2136
|
|
|
1676
2137
|
before do
|
|
@@ -1678,8 +2139,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1678
2139
|
end
|
|
1679
2140
|
|
|
1680
2141
|
it "returns the first document without touching the database" do
|
|
1681
|
-
|
|
1682
|
-
|
|
2142
|
+
expect_no_queries do
|
|
2143
|
+
expect(context.send(method)).to eq(depeche_mode)
|
|
2144
|
+
end
|
|
1683
2145
|
end
|
|
1684
2146
|
end
|
|
1685
2147
|
end
|
|
@@ -1733,77 +2195,21 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1733
2195
|
end
|
|
1734
2196
|
end
|
|
1735
2197
|
|
|
1736
|
-
context "when the
|
|
2198
|
+
context "when the query cache is enabled" do
|
|
1737
2199
|
|
|
1738
2200
|
let(:context) do
|
|
1739
2201
|
described_class.new(criteria)
|
|
1740
2202
|
end
|
|
1741
2203
|
|
|
1742
|
-
context "when
|
|
1743
|
-
|
|
1744
|
-
before do
|
|
1745
|
-
context.to_a
|
|
1746
|
-
end
|
|
1747
|
-
|
|
1748
|
-
context "when all of the documents are cached" do
|
|
1749
|
-
|
|
1750
|
-
let(:criteria) do
|
|
1751
|
-
Band.all.cache
|
|
1752
|
-
end
|
|
1753
|
-
|
|
1754
|
-
context "when requesting all of the documents" do
|
|
1755
|
-
|
|
1756
|
-
let(:docs) do
|
|
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
|
|
2204
|
+
context "when calling first beforehand" do
|
|
2205
|
+
query_cache_enabled
|
|
1800
2206
|
|
|
1801
2207
|
let(:context) do
|
|
1802
2208
|
described_class.new(criteria)
|
|
1803
2209
|
end
|
|
1804
2210
|
|
|
1805
2211
|
let(:criteria) do
|
|
1806
|
-
Band.all
|
|
2212
|
+
Band.all
|
|
1807
2213
|
end
|
|
1808
2214
|
|
|
1809
2215
|
before do
|
|
@@ -1821,8 +2227,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1821
2227
|
let(:limit) { 3 }
|
|
1822
2228
|
|
|
1823
2229
|
it "returns all documents without touching the database" do
|
|
1824
|
-
|
|
1825
|
-
|
|
2230
|
+
expect_no_queries do
|
|
2231
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2232
|
+
end
|
|
1826
2233
|
end
|
|
1827
2234
|
end
|
|
1828
2235
|
|
|
@@ -1830,8 +2237,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1830
2237
|
let(:limit) { 2 }
|
|
1831
2238
|
|
|
1832
2239
|
it "returns the correct documents without touching the database" do
|
|
1833
|
-
|
|
1834
|
-
|
|
2240
|
+
expect_no_queries do
|
|
2241
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
|
2242
|
+
end
|
|
1835
2243
|
end
|
|
1836
2244
|
end
|
|
1837
2245
|
end
|
|
@@ -1843,8 +2251,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1843
2251
|
let(:limit) { 2 }
|
|
1844
2252
|
|
|
1845
2253
|
it "returns the correct documents without touching the database" do
|
|
1846
|
-
|
|
1847
|
-
|
|
2254
|
+
expect_no_queries do
|
|
2255
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
|
2256
|
+
end
|
|
1848
2257
|
end
|
|
1849
2258
|
end
|
|
1850
2259
|
|
|
@@ -1852,8 +2261,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1852
2261
|
let(:limit) { 3 }
|
|
1853
2262
|
|
|
1854
2263
|
it "returns the correct documents and touches the database" do
|
|
1855
|
-
|
|
1856
|
-
|
|
2264
|
+
expect_query(1) do
|
|
2265
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2266
|
+
end
|
|
1857
2267
|
end
|
|
1858
2268
|
end
|
|
1859
2269
|
end
|
|
@@ -1865,8 +2275,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1865
2275
|
let(:limit) { 1 }
|
|
1866
2276
|
|
|
1867
2277
|
it "returns the correct documents without touching the database" do
|
|
1868
|
-
|
|
1869
|
-
|
|
2278
|
+
expect_no_queries do
|
|
2279
|
+
expect(docs).to eq([ depeche_mode ])
|
|
2280
|
+
end
|
|
1870
2281
|
end
|
|
1871
2282
|
end
|
|
1872
2283
|
|
|
@@ -1874,8 +2285,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1874
2285
|
let(:limit) { 3 }
|
|
1875
2286
|
|
|
1876
2287
|
it "returns the correct documents and touches the database" do
|
|
1877
|
-
|
|
1878
|
-
|
|
2288
|
+
expect_query(1) do
|
|
2289
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2290
|
+
end
|
|
1879
2291
|
end
|
|
1880
2292
|
end
|
|
1881
2293
|
end
|
|
@@ -1883,14 +2295,15 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1883
2295
|
end
|
|
1884
2296
|
end
|
|
1885
2297
|
|
|
1886
|
-
context "when calling #first then #last" do
|
|
2298
|
+
context "when calling #first then #last and the query cache is enabled" do
|
|
2299
|
+
query_cache_enabled
|
|
1887
2300
|
|
|
1888
2301
|
let(:context) do
|
|
1889
2302
|
described_class.new(criteria)
|
|
1890
2303
|
end
|
|
1891
2304
|
|
|
1892
2305
|
let(:criteria) do
|
|
1893
|
-
Band.all
|
|
2306
|
+
Band.all
|
|
1894
2307
|
end
|
|
1895
2308
|
|
|
1896
2309
|
before do
|
|
@@ -1905,8 +2318,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1905
2318
|
let(:before_limit) { 2 }
|
|
1906
2319
|
let(:limit) { 1 }
|
|
1907
2320
|
|
|
1908
|
-
it "gets the correct document" do
|
|
1909
|
-
|
|
2321
|
+
it "gets the correct document and hits the database" do
|
|
2322
|
+
expect_query(1) do
|
|
2323
|
+
expect(docs).to eq([rolling_stones])
|
|
2324
|
+
end
|
|
1910
2325
|
end
|
|
1911
2326
|
end
|
|
1912
2327
|
end
|
|
@@ -1996,30 +2411,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1996
2411
|
context 'when calling #first' do
|
|
1997
2412
|
|
|
1998
2413
|
it 'returns the first document, sorted by _id' do
|
|
1999
|
-
pending "MONGOID-5416"
|
|
2000
2414
|
expect(context.last).to eq(rolling_stones)
|
|
2001
2415
|
expect(context.first).to eq(depeche_mode)
|
|
2002
2416
|
end
|
|
2003
2417
|
end
|
|
2004
|
-
|
|
2005
|
-
context 'with option { id_sort: :none }' do
|
|
2006
|
-
let(:opts) do
|
|
2007
|
-
{ id_sort: :none }
|
|
2008
|
-
end
|
|
2009
|
-
|
|
2010
|
-
it 'doesn\'t apply the sort on _id' do
|
|
2011
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
|
2012
|
-
end
|
|
2013
|
-
|
|
2014
|
-
context 'when calling #first' do
|
|
2015
|
-
|
|
2016
|
-
it 'doesn\'t apply the sort on _id' do
|
|
2017
|
-
pending "MONGOID-5416"
|
|
2018
|
-
expect(context.last(opts)).to eq(rolling_stones)
|
|
2019
|
-
expect(context.first(opts)).to eq(depeche_mode)
|
|
2020
|
-
end
|
|
2021
|
-
end
|
|
2022
|
-
end
|
|
2023
2418
|
end
|
|
2024
2419
|
|
|
2025
2420
|
context 'when the criteria has a sort' do
|
|
@@ -2044,25 +2439,6 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2044
2439
|
expect(context.first).to eq(rolling_stones)
|
|
2045
2440
|
end
|
|
2046
2441
|
end
|
|
2047
|
-
|
|
2048
|
-
context 'with option { id_sort: :none }' do
|
|
2049
|
-
|
|
2050
|
-
let(:opts) do
|
|
2051
|
-
{ id_sort: :none }
|
|
2052
|
-
end
|
|
2053
|
-
|
|
2054
|
-
it 'uses the preexisting sort' do
|
|
2055
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
|
2056
|
-
end
|
|
2057
|
-
|
|
2058
|
-
context 'when calling #first' do
|
|
2059
|
-
|
|
2060
|
-
it 'uses the preexisting sort' do
|
|
2061
|
-
expect(context.last(opts)).to eq(depeche_mode)
|
|
2062
|
-
expect(context.first(opts)).to eq(rolling_stones)
|
|
2063
|
-
end
|
|
2064
|
-
end
|
|
2065
|
-
end
|
|
2066
2442
|
end
|
|
2067
2443
|
|
|
2068
2444
|
context "when using .sort" do
|
|
@@ -2091,28 +2467,17 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2091
2467
|
end
|
|
2092
2468
|
end
|
|
2093
2469
|
|
|
2094
|
-
context "when the
|
|
2470
|
+
context "when the query cache is enabled" do
|
|
2471
|
+
query_cache_enabled
|
|
2095
2472
|
|
|
2096
2473
|
let(:criteria) do
|
|
2097
|
-
Band.where(name: "Depeche Mode")
|
|
2474
|
+
Band.where(name: "Depeche Mode")
|
|
2098
2475
|
end
|
|
2099
2476
|
|
|
2100
2477
|
let(:context) do
|
|
2101
2478
|
described_class.new(criteria)
|
|
2102
2479
|
end
|
|
2103
2480
|
|
|
2104
|
-
context "when the cache is loaded" do
|
|
2105
|
-
|
|
2106
|
-
before do
|
|
2107
|
-
context.to_a
|
|
2108
|
-
end
|
|
2109
|
-
|
|
2110
|
-
it "returns the last document without touching the database" do
|
|
2111
|
-
expect(context).to receive(:view).never
|
|
2112
|
-
expect(context.last).to eq(depeche_mode)
|
|
2113
|
-
end
|
|
2114
|
-
end
|
|
2115
|
-
|
|
2116
2481
|
context "when last method was called before" do
|
|
2117
2482
|
|
|
2118
2483
|
before do
|
|
@@ -2120,8 +2485,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2120
2485
|
end
|
|
2121
2486
|
|
|
2122
2487
|
it "returns the last document without touching the database" do
|
|
2123
|
-
|
|
2124
|
-
|
|
2488
|
+
expect_no_queries do
|
|
2489
|
+
expect(context.last).to eq(depeche_mode)
|
|
2490
|
+
end
|
|
2125
2491
|
end
|
|
2126
2492
|
end
|
|
2127
2493
|
end
|
|
@@ -2181,71 +2547,15 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2181
2547
|
described_class.new(criteria)
|
|
2182
2548
|
end
|
|
2183
2549
|
|
|
2184
|
-
context "when
|
|
2185
|
-
|
|
2186
|
-
before do
|
|
2187
|
-
context.to_a
|
|
2188
|
-
end
|
|
2189
|
-
|
|
2190
|
-
context "when all of the documents are cached" do
|
|
2191
|
-
|
|
2192
|
-
let(:criteria) do
|
|
2193
|
-
Band.all.cache
|
|
2194
|
-
end
|
|
2195
|
-
|
|
2196
|
-
context "when requesting all of the documents" do
|
|
2197
|
-
|
|
2198
|
-
let(:docs) do
|
|
2199
|
-
context.last(3)
|
|
2200
|
-
end
|
|
2201
|
-
|
|
2202
|
-
it "returns all of the documents without touching the database" do
|
|
2203
|
-
expect(context).to receive(:view).never
|
|
2204
|
-
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2205
|
-
end
|
|
2206
|
-
end
|
|
2207
|
-
|
|
2208
|
-
context "when requesting fewer than all of the documents" do
|
|
2209
|
-
|
|
2210
|
-
let(:docs) do
|
|
2211
|
-
context.last(2)
|
|
2212
|
-
end
|
|
2213
|
-
|
|
2214
|
-
it "returns all of the documents without touching the database" do
|
|
2215
|
-
expect(context).to receive(:view).never
|
|
2216
|
-
expect(docs).to eq([ new_order, rolling_stones ])
|
|
2217
|
-
end
|
|
2218
|
-
end
|
|
2219
|
-
end
|
|
2220
|
-
|
|
2221
|
-
context "when only one document is cached" do
|
|
2222
|
-
|
|
2223
|
-
let(:criteria) do
|
|
2224
|
-
Band.where(name: "Depeche Mode").cache
|
|
2225
|
-
end
|
|
2226
|
-
|
|
2227
|
-
context "when requesting one document" do
|
|
2228
|
-
|
|
2229
|
-
let(:docs) do
|
|
2230
|
-
context.last(1)
|
|
2231
|
-
end
|
|
2232
|
-
|
|
2233
|
-
it "returns one document without touching the database" do
|
|
2234
|
-
expect(context).to receive(:view).never
|
|
2235
|
-
expect(docs).to eq([ depeche_mode ])
|
|
2236
|
-
end
|
|
2237
|
-
end
|
|
2238
|
-
end
|
|
2239
|
-
end
|
|
2240
|
-
|
|
2241
|
-
context "when the last method was called before" do
|
|
2550
|
+
context "when query cache is enabled" do
|
|
2551
|
+
query_cache_enabled
|
|
2242
2552
|
|
|
2243
2553
|
let(:context) do
|
|
2244
2554
|
described_class.new(criteria)
|
|
2245
2555
|
end
|
|
2246
2556
|
|
|
2247
2557
|
let(:criteria) do
|
|
2248
|
-
Band.all
|
|
2558
|
+
Band.all
|
|
2249
2559
|
end
|
|
2250
2560
|
|
|
2251
2561
|
before do
|
|
@@ -2262,18 +2572,20 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2262
2572
|
context "when getting all of the documents" do
|
|
2263
2573
|
let(:limit) { 3 }
|
|
2264
2574
|
|
|
2265
|
-
it "returns all documents without touching the
|
|
2266
|
-
|
|
2267
|
-
|
|
2575
|
+
it "returns all documents without touching the db" do
|
|
2576
|
+
expect_no_queries do
|
|
2577
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2578
|
+
end
|
|
2268
2579
|
end
|
|
2269
2580
|
end
|
|
2270
2581
|
|
|
2271
2582
|
context "when getting fewer documents" do
|
|
2272
2583
|
let(:limit) { 2 }
|
|
2273
2584
|
|
|
2274
|
-
it "returns the correct documents without touching the
|
|
2275
|
-
|
|
2276
|
-
|
|
2585
|
+
it "returns the correct documents without touching the db" do
|
|
2586
|
+
expect_no_queries do
|
|
2587
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
|
2588
|
+
end
|
|
2277
2589
|
end
|
|
2278
2590
|
end
|
|
2279
2591
|
end
|
|
@@ -2284,9 +2596,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2284
2596
|
context "when getting the same number of documents" do
|
|
2285
2597
|
let(:limit) { 2 }
|
|
2286
2598
|
|
|
2287
|
-
it "returns the correct documents without touching the
|
|
2288
|
-
|
|
2289
|
-
|
|
2599
|
+
it "returns the correct documents without touching the db" do
|
|
2600
|
+
expect_no_queries do
|
|
2601
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
|
2602
|
+
end
|
|
2290
2603
|
end
|
|
2291
2604
|
end
|
|
2292
2605
|
|
|
@@ -2294,8 +2607,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2294
2607
|
let(:limit) { 3 }
|
|
2295
2608
|
|
|
2296
2609
|
it "returns the correct documents and touches the database" do
|
|
2297
|
-
|
|
2298
|
-
|
|
2610
|
+
expect_query(1) do
|
|
2611
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2612
|
+
end
|
|
2299
2613
|
end
|
|
2300
2614
|
end
|
|
2301
2615
|
end
|
|
@@ -2307,8 +2621,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2307
2621
|
let(:limit) { 1 }
|
|
2308
2622
|
|
|
2309
2623
|
it "returns the correct documents without touching the database" do
|
|
2310
|
-
|
|
2311
|
-
|
|
2624
|
+
expect_no_queries do
|
|
2625
|
+
expect(docs).to eq([ rolling_stones ])
|
|
2626
|
+
end
|
|
2312
2627
|
end
|
|
2313
2628
|
end
|
|
2314
2629
|
|
|
@@ -2316,8 +2631,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2316
2631
|
let(:limit) { 3 }
|
|
2317
2632
|
|
|
2318
2633
|
it "returns the correct documents and touches the database" do
|
|
2319
|
-
|
|
2320
|
-
|
|
2634
|
+
expect_query(1) do
|
|
2635
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2636
|
+
end
|
|
2321
2637
|
end
|
|
2322
2638
|
end
|
|
2323
2639
|
end
|
|
@@ -2325,14 +2641,15 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2325
2641
|
end
|
|
2326
2642
|
end
|
|
2327
2643
|
|
|
2328
|
-
context "when calling #last then #first" do
|
|
2644
|
+
context "when calling #last then #first and the query cache is enabled" do
|
|
2645
|
+
query_cache_enabled
|
|
2329
2646
|
|
|
2330
2647
|
let(:context) do
|
|
2331
2648
|
described_class.new(criteria)
|
|
2332
2649
|
end
|
|
2333
2650
|
|
|
2334
2651
|
let(:criteria) do
|
|
2335
|
-
Band.all
|
|
2652
|
+
Band.all
|
|
2336
2653
|
end
|
|
2337
2654
|
|
|
2338
2655
|
before do
|
|
@@ -2348,12 +2665,12 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2348
2665
|
let(:limit) { 1 }
|
|
2349
2666
|
|
|
2350
2667
|
it "hits the database" do
|
|
2351
|
-
|
|
2352
|
-
|
|
2668
|
+
expect_query(1) do
|
|
2669
|
+
docs
|
|
2670
|
+
end
|
|
2353
2671
|
end
|
|
2354
2672
|
|
|
2355
2673
|
it "gets the correct document" do
|
|
2356
|
-
pending "MONGOID-5416"
|
|
2357
2674
|
expect(docs).to eq([ depeche_mode ])
|
|
2358
2675
|
end
|
|
2359
2676
|
end
|
|
@@ -2406,37 +2723,28 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2406
2723
|
described_class.new(criteria)
|
|
2407
2724
|
end
|
|
2408
2725
|
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
end
|
|
2726
|
+
context "when broken_view_options is false" do
|
|
2727
|
+
driver_config_override :broken_view_options, false
|
|
2412
2728
|
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
|
2416
|
-
2.times { expect(context.send(method)).to eq(2) }
|
|
2729
|
+
it "returns the number of documents that match" do
|
|
2730
|
+
expect(context.send(method)).to eq(1)
|
|
2417
2731
|
end
|
|
2418
2732
|
end
|
|
2419
2733
|
|
|
2420
|
-
context "when
|
|
2421
|
-
|
|
2422
|
-
before do
|
|
2423
|
-
context.entries
|
|
2424
|
-
end
|
|
2734
|
+
context "when broken_view_options is true" do
|
|
2735
|
+
driver_config_override :broken_view_options, true
|
|
2425
2736
|
|
|
2426
|
-
it "returns the
|
|
2427
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
|
2737
|
+
it "returns the number of documents that match" do
|
|
2428
2738
|
expect(context.send(method)).to eq(2)
|
|
2429
2739
|
end
|
|
2740
|
+
end
|
|
2430
2741
|
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
before do
|
|
2434
|
-
context.entries
|
|
2435
|
-
end
|
|
2742
|
+
context "when calling more than once with different limits" do
|
|
2743
|
+
driver_config_override :broken_view_options, false
|
|
2436
2744
|
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2745
|
+
it "does not cache the value" do
|
|
2746
|
+
expect(context.limit(1).send(method)).to eq(1)
|
|
2747
|
+
expect(context.limit(2).send(method)).to eq(2)
|
|
2440
2748
|
end
|
|
2441
2749
|
end
|
|
2442
2750
|
end
|
|
@@ -2455,10 +2763,12 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2455
2763
|
expect(context.send(method)).to eq(1)
|
|
2456
2764
|
end
|
|
2457
2765
|
|
|
2458
|
-
context "when calling more than once" do
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2766
|
+
context "when calling more than once with different skips" do
|
|
2767
|
+
driver_config_override :broken_view_options, false
|
|
2768
|
+
|
|
2769
|
+
it "does not cache the value" do
|
|
2770
|
+
expect(context.skip(0).send(method)).to eq(1)
|
|
2771
|
+
expect(context.skip(1).send(method)).to eq(0)
|
|
2462
2772
|
end
|
|
2463
2773
|
end
|
|
2464
2774
|
|
|
@@ -2580,7 +2890,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2580
2890
|
it "raises an error" do
|
|
2581
2891
|
expect do
|
|
2582
2892
|
Person.take!
|
|
2583
|
-
end.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
2893
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Person./)
|
|
2584
2894
|
end
|
|
2585
2895
|
end
|
|
2586
2896
|
end
|
|
@@ -2602,9 +2912,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2602
2912
|
|
|
2603
2913
|
context "when passed the symbol field name" do
|
|
2604
2914
|
|
|
2605
|
-
it "
|
|
2606
|
-
expect
|
|
2607
|
-
|
|
2915
|
+
it "raises an error" do
|
|
2916
|
+
expect do
|
|
2917
|
+
context.map(:name)
|
|
2918
|
+
end.to raise_error(ArgumentError)
|
|
2608
2919
|
end
|
|
2609
2920
|
end
|
|
2610
2921
|
|
|
@@ -3392,6 +3703,20 @@ describe Mongoid::Contextual::Mongo do
|
|
|
3392
3703
|
end
|
|
3393
3704
|
end
|
|
3394
3705
|
|
|
3706
|
+
context 'when using aliased field names' do
|
|
3707
|
+
before do
|
|
3708
|
+
context.update_all('$set' => { years: 100 })
|
|
3709
|
+
end
|
|
3710
|
+
|
|
3711
|
+
it "updates the first matching document" do
|
|
3712
|
+
expect(depeche_mode.reload.years).to eq(100)
|
|
3713
|
+
end
|
|
3714
|
+
|
|
3715
|
+
it "updates the last matching document" do
|
|
3716
|
+
expect(new_order.reload.years).to eq(100)
|
|
3717
|
+
end
|
|
3718
|
+
end
|
|
3719
|
+
|
|
3395
3720
|
context "when the attributes must be mongoized" do
|
|
3396
3721
|
|
|
3397
3722
|
before do
|
|
@@ -3506,4 +3831,836 @@ describe Mongoid::Contextual::Mongo do
|
|
|
3506
3831
|
end
|
|
3507
3832
|
end
|
|
3508
3833
|
end
|
|
3834
|
+
|
|
3835
|
+
describe "#first!" do
|
|
3836
|
+
|
|
3837
|
+
let!(:depeche_mode) do
|
|
3838
|
+
Band.create!(name: "Depeche Mode")
|
|
3839
|
+
end
|
|
3840
|
+
|
|
3841
|
+
let!(:new_order) do
|
|
3842
|
+
Band.create!(name: "New Order")
|
|
3843
|
+
end
|
|
3844
|
+
|
|
3845
|
+
let!(:rolling_stones) do
|
|
3846
|
+
Band.create!(name: "The Rolling Stones")
|
|
3847
|
+
end
|
|
3848
|
+
|
|
3849
|
+
let!(:death_cab) do
|
|
3850
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
3851
|
+
end
|
|
3852
|
+
|
|
3853
|
+
let(:context) do
|
|
3854
|
+
described_class.new(criteria)
|
|
3855
|
+
end
|
|
3856
|
+
|
|
3857
|
+
context "when there's no sort" do
|
|
3858
|
+
let(:criteria) do
|
|
3859
|
+
Band.all
|
|
3860
|
+
end
|
|
3861
|
+
|
|
3862
|
+
it "gets the first document" do
|
|
3863
|
+
expect(context.first!).to eq(depeche_mode)
|
|
3864
|
+
end
|
|
3865
|
+
end
|
|
3866
|
+
|
|
3867
|
+
context "when there's a custom sort" do
|
|
3868
|
+
let(:criteria) do
|
|
3869
|
+
Band.all
|
|
3870
|
+
end
|
|
3871
|
+
|
|
3872
|
+
it "gets the first document" do
|
|
3873
|
+
expect(context.sort(name: 1).first!).to eq(death_cab)
|
|
3874
|
+
end
|
|
3875
|
+
end
|
|
3876
|
+
|
|
3877
|
+
context "when there are no documents" do
|
|
3878
|
+
let(:criteria) do
|
|
3879
|
+
Band.where(name: "bogus")
|
|
3880
|
+
end
|
|
3881
|
+
|
|
3882
|
+
it "raises an error" do
|
|
3883
|
+
expect do
|
|
3884
|
+
context.first!
|
|
3885
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
3886
|
+
end
|
|
3887
|
+
end
|
|
3888
|
+
end
|
|
3889
|
+
|
|
3890
|
+
describe "#last!" do
|
|
3891
|
+
|
|
3892
|
+
let!(:depeche_mode) do
|
|
3893
|
+
Band.create!(name: "Depeche Mode")
|
|
3894
|
+
end
|
|
3895
|
+
|
|
3896
|
+
let!(:new_order) do
|
|
3897
|
+
Band.create!(name: "New Order")
|
|
3898
|
+
end
|
|
3899
|
+
|
|
3900
|
+
let!(:rolling_stones) do
|
|
3901
|
+
Band.create!(name: "The Rolling Stones")
|
|
3902
|
+
end
|
|
3903
|
+
|
|
3904
|
+
let!(:death_cab) do
|
|
3905
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
3906
|
+
end
|
|
3907
|
+
|
|
3908
|
+
let(:context) do
|
|
3909
|
+
described_class.new(criteria)
|
|
3910
|
+
end
|
|
3911
|
+
|
|
3912
|
+
context "when there's no sort" do
|
|
3913
|
+
let(:criteria) do
|
|
3914
|
+
Band.all
|
|
3915
|
+
end
|
|
3916
|
+
|
|
3917
|
+
it "gets the last document" do
|
|
3918
|
+
expect(context.last!).to eq(death_cab)
|
|
3919
|
+
end
|
|
3920
|
+
end
|
|
3921
|
+
|
|
3922
|
+
context "when there's a custom sort" do
|
|
3923
|
+
let(:criteria) do
|
|
3924
|
+
Band.all
|
|
3925
|
+
end
|
|
3926
|
+
|
|
3927
|
+
it "gets the last document" do
|
|
3928
|
+
expect(context.sort(name: 1).last!).to eq(rolling_stones)
|
|
3929
|
+
end
|
|
3930
|
+
end
|
|
3931
|
+
|
|
3932
|
+
context "when there are no documents" do
|
|
3933
|
+
let(:criteria) do
|
|
3934
|
+
Band.where(name: "bogus")
|
|
3935
|
+
end
|
|
3936
|
+
|
|
3937
|
+
it "raises an error" do
|
|
3938
|
+
expect do
|
|
3939
|
+
context.last!
|
|
3940
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
3941
|
+
end
|
|
3942
|
+
end
|
|
3943
|
+
end
|
|
3944
|
+
|
|
3945
|
+
describe "#second" do
|
|
3946
|
+
|
|
3947
|
+
let!(:depeche_mode) do
|
|
3948
|
+
Band.create!(name: "Depeche Mode")
|
|
3949
|
+
end
|
|
3950
|
+
|
|
3951
|
+
let!(:new_order) do
|
|
3952
|
+
Band.create!(name: "New Order")
|
|
3953
|
+
end
|
|
3954
|
+
|
|
3955
|
+
let!(:rolling_stones) do
|
|
3956
|
+
Band.create!(name: "The Rolling Stones")
|
|
3957
|
+
end
|
|
3958
|
+
|
|
3959
|
+
let!(:death_cab) do
|
|
3960
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
3961
|
+
end
|
|
3962
|
+
|
|
3963
|
+
let(:context) do
|
|
3964
|
+
described_class.new(criteria)
|
|
3965
|
+
end
|
|
3966
|
+
|
|
3967
|
+
context "when there's no sort" do
|
|
3968
|
+
let(:criteria) do
|
|
3969
|
+
Band.all
|
|
3970
|
+
end
|
|
3971
|
+
|
|
3972
|
+
it "gets the second document" do
|
|
3973
|
+
expect(context.second).to eq(new_order)
|
|
3974
|
+
end
|
|
3975
|
+
end
|
|
3976
|
+
|
|
3977
|
+
context "when there's a custom sort" do
|
|
3978
|
+
let(:criteria) do
|
|
3979
|
+
Band.all
|
|
3980
|
+
end
|
|
3981
|
+
|
|
3982
|
+
it "gets the second document" do
|
|
3983
|
+
expect(context.sort(name: 1).second).to eq(depeche_mode)
|
|
3984
|
+
end
|
|
3985
|
+
end
|
|
3986
|
+
|
|
3987
|
+
context "when there are no documents" do
|
|
3988
|
+
let(:criteria) do
|
|
3989
|
+
Band.where(name: "bogus")
|
|
3990
|
+
end
|
|
3991
|
+
|
|
3992
|
+
it "returns nil" do
|
|
3993
|
+
expect(context.second).to be_nil
|
|
3994
|
+
end
|
|
3995
|
+
end
|
|
3996
|
+
end
|
|
3997
|
+
|
|
3998
|
+
describe "#second!" do
|
|
3999
|
+
|
|
4000
|
+
let!(:depeche_mode) do
|
|
4001
|
+
Band.create!(name: "Depeche Mode")
|
|
4002
|
+
end
|
|
4003
|
+
|
|
4004
|
+
let!(:new_order) do
|
|
4005
|
+
Band.create!(name: "New Order")
|
|
4006
|
+
end
|
|
4007
|
+
|
|
4008
|
+
let!(:rolling_stones) do
|
|
4009
|
+
Band.create!(name: "The Rolling Stones")
|
|
4010
|
+
end
|
|
4011
|
+
|
|
4012
|
+
let!(:death_cab) do
|
|
4013
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4014
|
+
end
|
|
4015
|
+
|
|
4016
|
+
let(:context) do
|
|
4017
|
+
described_class.new(criteria)
|
|
4018
|
+
end
|
|
4019
|
+
|
|
4020
|
+
context "when there's no sort" do
|
|
4021
|
+
let(:criteria) do
|
|
4022
|
+
Band.all
|
|
4023
|
+
end
|
|
4024
|
+
|
|
4025
|
+
it "gets the second document" do
|
|
4026
|
+
expect(context.second!).to eq(new_order)
|
|
4027
|
+
end
|
|
4028
|
+
end
|
|
4029
|
+
|
|
4030
|
+
context "when there's a custom sort" do
|
|
4031
|
+
let(:criteria) do
|
|
4032
|
+
Band.all
|
|
4033
|
+
end
|
|
4034
|
+
|
|
4035
|
+
it "gets the second document" do
|
|
4036
|
+
expect(context.sort(name: 1).second!).to eq(depeche_mode)
|
|
4037
|
+
end
|
|
4038
|
+
end
|
|
4039
|
+
|
|
4040
|
+
context "when there are no documents" do
|
|
4041
|
+
let(:criteria) do
|
|
4042
|
+
Band.where(name: "bogus")
|
|
4043
|
+
end
|
|
4044
|
+
|
|
4045
|
+
it "raises an error" do
|
|
4046
|
+
expect do
|
|
4047
|
+
context.second!
|
|
4048
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4049
|
+
end
|
|
4050
|
+
end
|
|
4051
|
+
end
|
|
4052
|
+
|
|
4053
|
+
describe "#third" do
|
|
4054
|
+
|
|
4055
|
+
let!(:depeche_mode) do
|
|
4056
|
+
Band.create!(name: "Depeche Mode")
|
|
4057
|
+
end
|
|
4058
|
+
|
|
4059
|
+
let!(:new_order) do
|
|
4060
|
+
Band.create!(name: "New Order")
|
|
4061
|
+
end
|
|
4062
|
+
|
|
4063
|
+
let!(:rolling_stones) do
|
|
4064
|
+
Band.create!(name: "The Rolling Stones")
|
|
4065
|
+
end
|
|
4066
|
+
|
|
4067
|
+
let!(:death_cab) do
|
|
4068
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4069
|
+
end
|
|
4070
|
+
|
|
4071
|
+
let(:context) do
|
|
4072
|
+
described_class.new(criteria)
|
|
4073
|
+
end
|
|
4074
|
+
|
|
4075
|
+
context "when there's no sort" do
|
|
4076
|
+
let(:criteria) do
|
|
4077
|
+
Band.all
|
|
4078
|
+
end
|
|
4079
|
+
|
|
4080
|
+
it "gets the third document" do
|
|
4081
|
+
expect(context.third).to eq(rolling_stones)
|
|
4082
|
+
end
|
|
4083
|
+
end
|
|
4084
|
+
|
|
4085
|
+
context "when there's a custom sort" do
|
|
4086
|
+
let(:criteria) do
|
|
4087
|
+
Band.all
|
|
4088
|
+
end
|
|
4089
|
+
|
|
4090
|
+
it "gets the third document" do
|
|
4091
|
+
expect(context.sort(name: 1).third).to eq(new_order)
|
|
4092
|
+
end
|
|
4093
|
+
end
|
|
4094
|
+
|
|
4095
|
+
context "when there are no documents" do
|
|
4096
|
+
let(:criteria) do
|
|
4097
|
+
Band.where(name: "bogus")
|
|
4098
|
+
end
|
|
4099
|
+
|
|
4100
|
+
it "returns nil" do
|
|
4101
|
+
expect(context.third).to be_nil
|
|
4102
|
+
end
|
|
4103
|
+
end
|
|
4104
|
+
end
|
|
4105
|
+
|
|
4106
|
+
describe "#third!" do
|
|
4107
|
+
|
|
4108
|
+
let!(:depeche_mode) do
|
|
4109
|
+
Band.create!(name: "Depeche Mode")
|
|
4110
|
+
end
|
|
4111
|
+
|
|
4112
|
+
let!(:new_order) do
|
|
4113
|
+
Band.create!(name: "New Order")
|
|
4114
|
+
end
|
|
4115
|
+
|
|
4116
|
+
let!(:rolling_stones) do
|
|
4117
|
+
Band.create!(name: "The Rolling Stones")
|
|
4118
|
+
end
|
|
4119
|
+
|
|
4120
|
+
let!(:death_cab) do
|
|
4121
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4122
|
+
end
|
|
4123
|
+
|
|
4124
|
+
let(:context) do
|
|
4125
|
+
described_class.new(criteria)
|
|
4126
|
+
end
|
|
4127
|
+
|
|
4128
|
+
context "when there's no sort" do
|
|
4129
|
+
let(:criteria) do
|
|
4130
|
+
Band.all
|
|
4131
|
+
end
|
|
4132
|
+
|
|
4133
|
+
it "gets the third document" do
|
|
4134
|
+
expect(context.third!).to eq(rolling_stones)
|
|
4135
|
+
end
|
|
4136
|
+
end
|
|
4137
|
+
|
|
4138
|
+
context "when there's a custom sort" do
|
|
4139
|
+
let(:criteria) do
|
|
4140
|
+
Band.all
|
|
4141
|
+
end
|
|
4142
|
+
|
|
4143
|
+
it "gets the third document" do
|
|
4144
|
+
expect(context.sort(name: 1).third!).to eq(new_order)
|
|
4145
|
+
end
|
|
4146
|
+
end
|
|
4147
|
+
|
|
4148
|
+
context "when there are no documents" do
|
|
4149
|
+
let(:criteria) do
|
|
4150
|
+
Band.where(name: "bogus")
|
|
4151
|
+
end
|
|
4152
|
+
|
|
4153
|
+
it "raises an error" do
|
|
4154
|
+
expect do
|
|
4155
|
+
context.third!
|
|
4156
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4157
|
+
end
|
|
4158
|
+
end
|
|
4159
|
+
end
|
|
4160
|
+
|
|
4161
|
+
describe "#fourth" do
|
|
4162
|
+
|
|
4163
|
+
let!(:depeche_mode) do
|
|
4164
|
+
Band.create!(name: "Depeche Mode")
|
|
4165
|
+
end
|
|
4166
|
+
|
|
4167
|
+
let!(:new_order) do
|
|
4168
|
+
Band.create!(name: "New Order")
|
|
4169
|
+
end
|
|
4170
|
+
|
|
4171
|
+
let!(:rolling_stones) do
|
|
4172
|
+
Band.create!(name: "The Rolling Stones")
|
|
4173
|
+
end
|
|
4174
|
+
|
|
4175
|
+
let!(:death_cab) do
|
|
4176
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4177
|
+
end
|
|
4178
|
+
|
|
4179
|
+
let(:context) do
|
|
4180
|
+
described_class.new(criteria)
|
|
4181
|
+
end
|
|
4182
|
+
|
|
4183
|
+
context "when there's no sort" do
|
|
4184
|
+
let(:criteria) do
|
|
4185
|
+
Band.all
|
|
4186
|
+
end
|
|
4187
|
+
|
|
4188
|
+
it "gets the fourth document" do
|
|
4189
|
+
expect(context.fourth).to eq(death_cab)
|
|
4190
|
+
end
|
|
4191
|
+
end
|
|
4192
|
+
|
|
4193
|
+
context "when there's a custom sort" do
|
|
4194
|
+
let(:criteria) do
|
|
4195
|
+
Band.all
|
|
4196
|
+
end
|
|
4197
|
+
|
|
4198
|
+
it "gets the fourth document" do
|
|
4199
|
+
expect(context.sort(name: 1).fourth).to eq(rolling_stones)
|
|
4200
|
+
end
|
|
4201
|
+
end
|
|
4202
|
+
|
|
4203
|
+
context "when there are no documents" do
|
|
4204
|
+
let(:criteria) do
|
|
4205
|
+
Band.where(name: "bogus")
|
|
4206
|
+
end
|
|
4207
|
+
|
|
4208
|
+
it "returns nil" do
|
|
4209
|
+
expect(context.fourth).to be_nil
|
|
4210
|
+
end
|
|
4211
|
+
end
|
|
4212
|
+
end
|
|
4213
|
+
|
|
4214
|
+
describe "#fourth!" do
|
|
4215
|
+
|
|
4216
|
+
let!(:depeche_mode) do
|
|
4217
|
+
Band.create!(name: "Depeche Mode")
|
|
4218
|
+
end
|
|
4219
|
+
|
|
4220
|
+
let!(:new_order) do
|
|
4221
|
+
Band.create!(name: "New Order")
|
|
4222
|
+
end
|
|
4223
|
+
|
|
4224
|
+
let!(:rolling_stones) do
|
|
4225
|
+
Band.create!(name: "The Rolling Stones")
|
|
4226
|
+
end
|
|
4227
|
+
|
|
4228
|
+
let!(:death_cab) do
|
|
4229
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4230
|
+
end
|
|
4231
|
+
|
|
4232
|
+
let(:context) do
|
|
4233
|
+
described_class.new(criteria)
|
|
4234
|
+
end
|
|
4235
|
+
|
|
4236
|
+
context "when there's no sort" do
|
|
4237
|
+
let(:criteria) do
|
|
4238
|
+
Band.all
|
|
4239
|
+
end
|
|
4240
|
+
|
|
4241
|
+
it "gets the fourth document" do
|
|
4242
|
+
expect(context.fourth!).to eq(death_cab)
|
|
4243
|
+
end
|
|
4244
|
+
end
|
|
4245
|
+
|
|
4246
|
+
context "when there's a custom sort" do
|
|
4247
|
+
let(:criteria) do
|
|
4248
|
+
Band.all
|
|
4249
|
+
end
|
|
4250
|
+
|
|
4251
|
+
it "gets the fourth document" do
|
|
4252
|
+
expect(context.sort(name: 1).fourth!).to eq(rolling_stones)
|
|
4253
|
+
end
|
|
4254
|
+
end
|
|
4255
|
+
|
|
4256
|
+
context "when there are no documents" do
|
|
4257
|
+
let(:criteria) do
|
|
4258
|
+
Band.where(name: "bogus")
|
|
4259
|
+
end
|
|
4260
|
+
|
|
4261
|
+
it "raises an error" do
|
|
4262
|
+
expect do
|
|
4263
|
+
context.fourth!
|
|
4264
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4265
|
+
end
|
|
4266
|
+
end
|
|
4267
|
+
end
|
|
4268
|
+
|
|
4269
|
+
describe "#fifth" do
|
|
4270
|
+
|
|
4271
|
+
let!(:depeche_mode) do
|
|
4272
|
+
Band.create!(name: "Depeche Mode")
|
|
4273
|
+
end
|
|
4274
|
+
|
|
4275
|
+
let!(:new_order) do
|
|
4276
|
+
Band.create!(name: "New Order")
|
|
4277
|
+
end
|
|
4278
|
+
|
|
4279
|
+
let!(:rolling_stones) do
|
|
4280
|
+
Band.create!(name: "The Rolling Stones")
|
|
4281
|
+
end
|
|
4282
|
+
|
|
4283
|
+
let!(:death_cab) do
|
|
4284
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4285
|
+
end
|
|
4286
|
+
|
|
4287
|
+
let!(:guns_and_roses) do
|
|
4288
|
+
Band.create!(name: "Guns and Roses")
|
|
4289
|
+
end
|
|
4290
|
+
|
|
4291
|
+
let(:context) do
|
|
4292
|
+
described_class.new(criteria)
|
|
4293
|
+
end
|
|
4294
|
+
|
|
4295
|
+
context "when there's no sort" do
|
|
4296
|
+
let(:criteria) do
|
|
4297
|
+
Band.all
|
|
4298
|
+
end
|
|
4299
|
+
|
|
4300
|
+
it "gets the fifth document" do
|
|
4301
|
+
expect(context.fifth).to eq(guns_and_roses)
|
|
4302
|
+
end
|
|
4303
|
+
end
|
|
4304
|
+
|
|
4305
|
+
context "when there's a custom sort" do
|
|
4306
|
+
let(:criteria) do
|
|
4307
|
+
Band.all
|
|
4308
|
+
end
|
|
4309
|
+
|
|
4310
|
+
it "gets the fifth document" do
|
|
4311
|
+
expect(context.sort(name: 1).fifth).to eq(rolling_stones)
|
|
4312
|
+
end
|
|
4313
|
+
end
|
|
4314
|
+
|
|
4315
|
+
context "when there are no documents" do
|
|
4316
|
+
let(:criteria) do
|
|
4317
|
+
Band.where(name: "bogus")
|
|
4318
|
+
end
|
|
4319
|
+
|
|
4320
|
+
it "returns nil" do
|
|
4321
|
+
expect(context.fifth).to be_nil
|
|
4322
|
+
end
|
|
4323
|
+
end
|
|
4324
|
+
end
|
|
4325
|
+
|
|
4326
|
+
describe "#fifth!" do
|
|
4327
|
+
|
|
4328
|
+
let!(:depeche_mode) do
|
|
4329
|
+
Band.create!(name: "Depeche Mode")
|
|
4330
|
+
end
|
|
4331
|
+
|
|
4332
|
+
let!(:new_order) do
|
|
4333
|
+
Band.create!(name: "New Order")
|
|
4334
|
+
end
|
|
4335
|
+
|
|
4336
|
+
let!(:rolling_stones) do
|
|
4337
|
+
Band.create!(name: "The Rolling Stones")
|
|
4338
|
+
end
|
|
4339
|
+
|
|
4340
|
+
let!(:death_cab) do
|
|
4341
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4342
|
+
end
|
|
4343
|
+
|
|
4344
|
+
let!(:guns_and_roses) do
|
|
4345
|
+
Band.create!(name: "Guns and Roses")
|
|
4346
|
+
end
|
|
4347
|
+
|
|
4348
|
+
let(:context) do
|
|
4349
|
+
described_class.new(criteria)
|
|
4350
|
+
end
|
|
4351
|
+
|
|
4352
|
+
context "when there's no sort" do
|
|
4353
|
+
let(:criteria) do
|
|
4354
|
+
Band.all
|
|
4355
|
+
end
|
|
4356
|
+
|
|
4357
|
+
it "gets the fifth document" do
|
|
4358
|
+
expect(context.fifth!).to eq(guns_and_roses)
|
|
4359
|
+
end
|
|
4360
|
+
end
|
|
4361
|
+
|
|
4362
|
+
context "when there's a custom sort" do
|
|
4363
|
+
let(:criteria) do
|
|
4364
|
+
Band.all
|
|
4365
|
+
end
|
|
4366
|
+
|
|
4367
|
+
it "gets the fifth document" do
|
|
4368
|
+
expect(context.sort(name: 1).fifth!).to eq(rolling_stones)
|
|
4369
|
+
end
|
|
4370
|
+
end
|
|
4371
|
+
|
|
4372
|
+
context "when there are no documents" do
|
|
4373
|
+
let(:criteria) do
|
|
4374
|
+
Band.where(name: "bogus")
|
|
4375
|
+
end
|
|
4376
|
+
|
|
4377
|
+
it "raises an error" do
|
|
4378
|
+
expect do
|
|
4379
|
+
context.fifth!
|
|
4380
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4381
|
+
end
|
|
4382
|
+
end
|
|
4383
|
+
end
|
|
4384
|
+
|
|
4385
|
+
describe "#second_to_last" do
|
|
4386
|
+
|
|
4387
|
+
let!(:depeche_mode) do
|
|
4388
|
+
Band.create!(name: "Depeche Mode")
|
|
4389
|
+
end
|
|
4390
|
+
|
|
4391
|
+
let!(:new_order) do
|
|
4392
|
+
Band.create!(name: "New Order")
|
|
4393
|
+
end
|
|
4394
|
+
|
|
4395
|
+
let!(:rolling_stones) do
|
|
4396
|
+
Band.create!(name: "The Rolling Stones")
|
|
4397
|
+
end
|
|
4398
|
+
|
|
4399
|
+
let!(:death_cab) do
|
|
4400
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4401
|
+
end
|
|
4402
|
+
|
|
4403
|
+
let(:context) do
|
|
4404
|
+
described_class.new(criteria)
|
|
4405
|
+
end
|
|
4406
|
+
|
|
4407
|
+
context "when there's no sort" do
|
|
4408
|
+
let(:criteria) do
|
|
4409
|
+
Band.all
|
|
4410
|
+
end
|
|
4411
|
+
|
|
4412
|
+
it "gets the second_to_last document" do
|
|
4413
|
+
expect(context.second_to_last).to eq(rolling_stones)
|
|
4414
|
+
end
|
|
4415
|
+
end
|
|
4416
|
+
|
|
4417
|
+
context "when there's a custom sort" do
|
|
4418
|
+
let(:criteria) do
|
|
4419
|
+
Band.all
|
|
4420
|
+
end
|
|
4421
|
+
|
|
4422
|
+
it "gets the second_to_last document" do
|
|
4423
|
+
expect(context.sort(name: 1).second_to_last).to eq(new_order)
|
|
4424
|
+
end
|
|
4425
|
+
end
|
|
4426
|
+
|
|
4427
|
+
context "when there are no documents" do
|
|
4428
|
+
let(:criteria) do
|
|
4429
|
+
Band.where(name: "bogus")
|
|
4430
|
+
end
|
|
4431
|
+
|
|
4432
|
+
it "returns nil" do
|
|
4433
|
+
expect(context.second_to_last).to be_nil
|
|
4434
|
+
end
|
|
4435
|
+
end
|
|
4436
|
+
end
|
|
4437
|
+
|
|
4438
|
+
describe "#second_to_last!" do
|
|
4439
|
+
|
|
4440
|
+
let!(:depeche_mode) do
|
|
4441
|
+
Band.create!(name: "Depeche Mode")
|
|
4442
|
+
end
|
|
4443
|
+
|
|
4444
|
+
let!(:new_order) do
|
|
4445
|
+
Band.create!(name: "New Order")
|
|
4446
|
+
end
|
|
4447
|
+
|
|
4448
|
+
let!(:rolling_stones) do
|
|
4449
|
+
Band.create!(name: "The Rolling Stones")
|
|
4450
|
+
end
|
|
4451
|
+
|
|
4452
|
+
let!(:death_cab) do
|
|
4453
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4454
|
+
end
|
|
4455
|
+
|
|
4456
|
+
let(:context) do
|
|
4457
|
+
described_class.new(criteria)
|
|
4458
|
+
end
|
|
4459
|
+
|
|
4460
|
+
context "when there's no sort" do
|
|
4461
|
+
let(:criteria) do
|
|
4462
|
+
Band.all
|
|
4463
|
+
end
|
|
4464
|
+
|
|
4465
|
+
it "gets the second_to_last document" do
|
|
4466
|
+
expect(context.second_to_last!).to eq(rolling_stones)
|
|
4467
|
+
end
|
|
4468
|
+
end
|
|
4469
|
+
|
|
4470
|
+
context "when there's a custom sort" do
|
|
4471
|
+
let(:criteria) do
|
|
4472
|
+
Band.all
|
|
4473
|
+
end
|
|
4474
|
+
|
|
4475
|
+
it "gets the second_to_last document" do
|
|
4476
|
+
expect(context.sort(name: 1).second_to_last!).to eq(new_order)
|
|
4477
|
+
end
|
|
4478
|
+
end
|
|
4479
|
+
|
|
4480
|
+
context "when there are no documents" do
|
|
4481
|
+
let(:criteria) do
|
|
4482
|
+
Band.where(name: "bogus")
|
|
4483
|
+
end
|
|
4484
|
+
|
|
4485
|
+
it "raises an error" do
|
|
4486
|
+
expect do
|
|
4487
|
+
context.second_to_last!
|
|
4488
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4489
|
+
end
|
|
4490
|
+
end
|
|
4491
|
+
end
|
|
4492
|
+
|
|
4493
|
+
describe "#third_to_last" do
|
|
4494
|
+
|
|
4495
|
+
let!(:depeche_mode) do
|
|
4496
|
+
Band.create!(name: "Depeche Mode")
|
|
4497
|
+
end
|
|
4498
|
+
|
|
4499
|
+
let!(:new_order) do
|
|
4500
|
+
Band.create!(name: "New Order")
|
|
4501
|
+
end
|
|
4502
|
+
|
|
4503
|
+
let!(:rolling_stones) do
|
|
4504
|
+
Band.create!(name: "The Rolling Stones")
|
|
4505
|
+
end
|
|
4506
|
+
|
|
4507
|
+
let!(:death_cab) do
|
|
4508
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4509
|
+
end
|
|
4510
|
+
|
|
4511
|
+
let(:context) do
|
|
4512
|
+
described_class.new(criteria)
|
|
4513
|
+
end
|
|
4514
|
+
|
|
4515
|
+
context "when there's no sort" do
|
|
4516
|
+
let(:criteria) do
|
|
4517
|
+
Band.all
|
|
4518
|
+
end
|
|
4519
|
+
|
|
4520
|
+
it "gets the third_to_last document" do
|
|
4521
|
+
expect(context.third_to_last).to eq(new_order)
|
|
4522
|
+
end
|
|
4523
|
+
end
|
|
4524
|
+
|
|
4525
|
+
context "when there's a custom sort" do
|
|
4526
|
+
let(:criteria) do
|
|
4527
|
+
Band.all
|
|
4528
|
+
end
|
|
4529
|
+
|
|
4530
|
+
it "gets the third_to_last document" do
|
|
4531
|
+
expect(context.sort(name: 1).third_to_last).to eq(depeche_mode)
|
|
4532
|
+
end
|
|
4533
|
+
end
|
|
4534
|
+
|
|
4535
|
+
context "when there are no documents" do
|
|
4536
|
+
let(:criteria) do
|
|
4537
|
+
Band.where(name: "bogus")
|
|
4538
|
+
end
|
|
4539
|
+
|
|
4540
|
+
it "returns nil" do
|
|
4541
|
+
expect(context.third_to_last).to be_nil
|
|
4542
|
+
end
|
|
4543
|
+
end
|
|
4544
|
+
end
|
|
4545
|
+
|
|
4546
|
+
describe "#third_to_last!" do
|
|
4547
|
+
|
|
4548
|
+
let!(:depeche_mode) do
|
|
4549
|
+
Band.create!(name: "Depeche Mode")
|
|
4550
|
+
end
|
|
4551
|
+
|
|
4552
|
+
let!(:new_order) do
|
|
4553
|
+
Band.create!(name: "New Order")
|
|
4554
|
+
end
|
|
4555
|
+
|
|
4556
|
+
let!(:rolling_stones) do
|
|
4557
|
+
Band.create!(name: "The Rolling Stones")
|
|
4558
|
+
end
|
|
4559
|
+
|
|
4560
|
+
let!(:death_cab) do
|
|
4561
|
+
Band.create!(name: "Death Cab For Cutie")
|
|
4562
|
+
end
|
|
4563
|
+
|
|
4564
|
+
let(:context) do
|
|
4565
|
+
described_class.new(criteria)
|
|
4566
|
+
end
|
|
4567
|
+
|
|
4568
|
+
context "when there's no sort" do
|
|
4569
|
+
let(:criteria) do
|
|
4570
|
+
Band.all
|
|
4571
|
+
end
|
|
4572
|
+
|
|
4573
|
+
it "gets the third_to_last document" do
|
|
4574
|
+
expect(context.third_to_last!).to eq(new_order)
|
|
4575
|
+
end
|
|
4576
|
+
end
|
|
4577
|
+
|
|
4578
|
+
context "when there's a custom sort" do
|
|
4579
|
+
let(:criteria) do
|
|
4580
|
+
Band.all
|
|
4581
|
+
end
|
|
4582
|
+
|
|
4583
|
+
it "gets the third_to_last document" do
|
|
4584
|
+
expect(context.sort(name: 1).third_to_last!).to eq(depeche_mode)
|
|
4585
|
+
end
|
|
4586
|
+
end
|
|
4587
|
+
|
|
4588
|
+
context "when there are no documents" do
|
|
4589
|
+
let(:criteria) do
|
|
4590
|
+
Band.where(name: "bogus")
|
|
4591
|
+
end
|
|
4592
|
+
|
|
4593
|
+
it "raises an error" do
|
|
4594
|
+
expect do
|
|
4595
|
+
context.third_to_last!
|
|
4596
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
|
|
4597
|
+
end
|
|
4598
|
+
end
|
|
4599
|
+
end
|
|
4600
|
+
|
|
4601
|
+
describe '#load_async' do
|
|
4602
|
+
let!(:band) do
|
|
4603
|
+
Band.create!(name: "Depeche Mode")
|
|
4604
|
+
end
|
|
4605
|
+
|
|
4606
|
+
let(:criteria) do
|
|
4607
|
+
Band.where(name: "Depeche Mode")
|
|
4608
|
+
end
|
|
4609
|
+
|
|
4610
|
+
let(:context) do
|
|
4611
|
+
described_class.new(criteria)
|
|
4612
|
+
end
|
|
4613
|
+
|
|
4614
|
+
context 'with global thread pool async query executor' do
|
|
4615
|
+
config_override :async_query_executor, :global_thread_pool
|
|
4616
|
+
|
|
4617
|
+
it 'preloads the documents' do
|
|
4618
|
+
context.load_async
|
|
4619
|
+
context.documents_loader.wait
|
|
4620
|
+
|
|
4621
|
+
expect(context.view).not_to receive(:map)
|
|
4622
|
+
expect(context.to_a).to eq([band])
|
|
4623
|
+
end
|
|
4624
|
+
|
|
4625
|
+
it 're-raises exception during preload' do
|
|
4626
|
+
expect_any_instance_of(Mongoid::Contextual::Mongo::DocumentsLoader)
|
|
4627
|
+
.to receive(:execute)
|
|
4628
|
+
.at_least(:once)
|
|
4629
|
+
.and_raise(Mongo::Error::OperationFailure)
|
|
4630
|
+
|
|
4631
|
+
context.load_async
|
|
4632
|
+
context.documents_loader.wait
|
|
4633
|
+
|
|
4634
|
+
expect do
|
|
4635
|
+
context.to_a
|
|
4636
|
+
end.to raise_error(Mongo::Error::OperationFailure)
|
|
4637
|
+
end
|
|
4638
|
+
end
|
|
4639
|
+
|
|
4640
|
+
context 'with immediate thread pool async query executor' do
|
|
4641
|
+
config_override :async_query_executor, :immediate
|
|
4642
|
+
|
|
4643
|
+
it 'preloads the documents' do
|
|
4644
|
+
context.load_async
|
|
4645
|
+
context.documents_loader.wait
|
|
4646
|
+
|
|
4647
|
+
expect(context.view).not_to receive(:map)
|
|
4648
|
+
expect(context.to_a).to eq([band])
|
|
4649
|
+
end
|
|
4650
|
+
|
|
4651
|
+
it 're-raises exception during preload' do
|
|
4652
|
+
expect_any_instance_of(Mongoid::Contextual::Mongo::DocumentsLoader)
|
|
4653
|
+
.to receive(:execute)
|
|
4654
|
+
.at_least(:once)
|
|
4655
|
+
.and_raise(Mongo::Error::OperationFailure)
|
|
4656
|
+
|
|
4657
|
+
context.load_async
|
|
4658
|
+
context.documents_loader.wait
|
|
4659
|
+
|
|
4660
|
+
expect do
|
|
4661
|
+
context.to_a
|
|
4662
|
+
end.to raise_error(Mongo::Error::OperationFailure)
|
|
4663
|
+
end
|
|
4664
|
+
end
|
|
4665
|
+
end
|
|
3509
4666
|
end
|