mongoid 7.4.0 → 8.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +52 -28
- data/lib/mongoid/association/accessors.rb +38 -9
- data/lib/mongoid/association/bindable.rb +50 -2
- data/lib/mongoid/association/builders.rb +4 -2
- data/lib/mongoid/association/constrainable.rb +0 -1
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +53 -13
- 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/proxy.rb +2 -2
- 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 +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -28
- data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
- data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
- data/lib/mongoid/association/macros.rb +22 -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 +5 -5
- data/lib/mongoid/association/one.rb +2 -2
- data/lib/mongoid/association/options.rb +9 -9
- data/lib/mongoid/association/proxy.rb +14 -3
- 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 +66 -13
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
- data/lib/mongoid/association/referenced/has_many/proxy.rb +24 -18
- 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 +2 -2
- 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/attributes/dynamic.rb +3 -3
- data/lib/mongoid/attributes/nested.rb +5 -5
- data/lib/mongoid/attributes/processing.rb +10 -3
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +2 -2
- data/lib/mongoid/attributes.rb +43 -40
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/changeable.rb +42 -7
- data/lib/mongoid/clients/options.rb +5 -1
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/clients/validators/storage.rb +3 -3
- data/lib/mongoid/config/environment.rb +20 -4
- data/lib/mongoid/config/validators/client.rb +6 -6
- data/lib/mongoid/config.rb +32 -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 +180 -21
- data/lib/mongoid/contextual/mongo.rb +237 -217
- data/lib/mongoid/contextual/none.rb +67 -5
- data/lib/mongoid/contextual/queryable.rb +1 -1
- data/lib/mongoid/contextual.rb +2 -2
- data/lib/mongoid/copyable.rb +32 -8
- data/lib/mongoid/criteria/findable.rb +7 -4
- data/lib/mongoid/criteria/includable.rb +24 -20
- 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 +2 -13
- 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 +0 -14
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- 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 +3 -3
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
- 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 +3 -3
- data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
- data/lib/mongoid/criteria/queryable/optional.rb +5 -11
- 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 +31 -37
- data/lib/mongoid/criteria/queryable/selector.rb +92 -7
- data/lib/mongoid/criteria/queryable/smash.rb +40 -7
- data/lib/mongoid/criteria/queryable.rb +12 -7
- data/lib/mongoid/criteria/scopable.rb +2 -2
- data/lib/mongoid/criteria.rb +15 -35
- data/lib/mongoid/deprecable.rb +36 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +98 -34
- data/lib/mongoid/equality.rb +12 -12
- data/lib/mongoid/errors/document_not_found.rb +33 -12
- 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_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/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 +2 -2
- 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 +13 -6
- data/lib/mongoid/extensions/integer.rb +7 -4
- data/lib/mongoid/extensions/module.rb +1 -1
- data/lib/mongoid/extensions/object.rb +8 -6
- 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 +27 -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 +42 -7
- data/lib/mongoid/fields/foreign_key.rb +11 -4
- data/lib/mongoid/fields/localized.rb +9 -4
- data/lib/mongoid/fields/standard.rb +7 -7
- data/lib/mongoid/fields/validators/macro.rb +3 -9
- data/lib/mongoid/fields.rb +201 -35
- data/lib/mongoid/findable.rb +34 -13
- data/lib/mongoid/indexable/specification.rb +2 -2
- data/lib/mongoid/indexable/validators/options.rb +6 -2
- data/lib/mongoid/interceptable.rb +73 -13
- data/lib/mongoid/matchable.rb +1 -1
- data/lib/mongoid/matcher.rb +12 -7
- data/lib/mongoid/persistable/creatable.rb +18 -9
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/destroyable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +2 -2
- data/lib/mongoid/persistable/unsettable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +19 -12
- data/lib/mongoid/persistable/upsertable.rb +2 -2
- data/lib/mongoid/persistable.rb +3 -3
- data/lib/mongoid/persistence_context.rb +63 -10
- data/lib/mongoid/query_cache.rb +8 -260
- data/lib/mongoid/railties/controller_runtime.rb +1 -1
- data/lib/mongoid/reloadable.rb +7 -3
- data/lib/mongoid/scopable.rb +26 -22
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/serializable.rb +10 -6
- data/lib/mongoid/stateful.rb +35 -9
- data/lib/mongoid/tasks/database.rb +0 -2
- data/lib/mongoid/threaded/lifecycle.rb +5 -5
- data/lib/mongoid/threaded.rb +12 -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 +8 -4
- data/lib/mongoid/validatable/localizable.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +0 -2
- data/lib/mongoid/validatable/presence.rb +2 -2
- data/lib/mongoid/validatable/uniqueness.rb +9 -8
- data/lib/mongoid/validatable.rb +6 -6
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +28 -0
- data/lib/mongoid.rb +2 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
- data/spec/config/mongoid.yml +16 -0
- data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
- data/spec/integration/app_spec.rb +28 -26
- data/spec/integration/associations/belongs_to_spec.rb +18 -0
- data/spec/integration/associations/embedded_dirty_spec.rb +28 -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 +95 -1
- data/spec/integration/callbacks_spec.rb +226 -4
- data/spec/integration/criteria/range_spec.rb +95 -1
- data/spec/integration/discriminator_key_spec.rb +115 -76
- data/spec/integration/dots_and_dollars_spec.rb +277 -0
- data/spec/integration/i18n_fallbacks_spec.rb +1 -17
- 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/lite_spec_helper.rb +1 -1
- 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 +69 -9
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
- data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -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_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 +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
- 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 +8 -8
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
- 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 +14 -0
- data/spec/mongoid/atomic/paths_spec.rb +0 -14
- data/spec/mongoid/atomic_spec.rb +22 -0
- 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 +524 -27
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +34 -42
- data/spec/mongoid/clients/options_spec.rb +1 -0
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +57 -2
- data/spec/mongoid/config/environment_spec.rb +39 -1
- data/spec/mongoid/config_spec.rb +104 -13
- 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 +1336 -69
- data/spec/mongoid/contextual/mongo_spec.rb +1105 -174
- data/spec/mongoid/contextual/none_spec.rb +38 -0
- data/spec/mongoid/copyable_spec.rb +451 -1
- 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/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 +0 -484
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
- data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
- data/spec/mongoid/criteria_projection_spec.rb +0 -1
- data/spec/mongoid/criteria_spec.rb +475 -1199
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/equality_spec.rb +12 -12
- data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
- 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/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 +30 -0
- 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 +634 -66
- data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
- data/spec/mongoid/factory_spec.rb +61 -1
- data/spec/mongoid/fields/localized_spec.rb +37 -12
- data/spec/mongoid/fields_spec.rb +321 -50
- data/spec/mongoid/findable_spec.rb +80 -15
- data/spec/mongoid/indexable/specification_spec.rb +2 -2
- data/spec/mongoid/indexable_spec.rb +39 -20
- data/spec/mongoid/interceptable_spec.rb +584 -5
- 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 +2 -2
- data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
- data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
- data/spec/mongoid/persistence_context_spec.rb +50 -1
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +0 -154
- data/spec/mongoid/reloadable_spec.rb +35 -2
- data/spec/mongoid/scopable_spec.rb +54 -16
- data/spec/mongoid/shardable_spec.rb +14 -0
- data/spec/mongoid/stateful_spec.rb +28 -0
- data/spec/mongoid/timestamps_spec.rb +390 -0
- data/spec/mongoid/timestamps_spec_models.rb +67 -0
- data/spec/mongoid/touchable_spec.rb +116 -0
- data/spec/mongoid/touchable_spec_models.rb +12 -8
- data/spec/mongoid/traversable_spec.rb +4 -11
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
- data/spec/mongoid/warnings_spec.rb +35 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/constraints.rb +8 -16
- data/spec/shared/lib/mrss/docker_runner.rb +23 -3
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
- data/spec/shared/share/Dockerfile.erb +34 -48
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/server.sh +32 -19
- data/spec/shared/shlib/set_env.sh +37 -0
- data/spec/support/constraints.rb +24 -0
- data/spec/support/macros.rb +55 -0
- data/spec/support/models/augmentation.rb +12 -0
- data/spec/support/models/band.rb +3 -0
- data/spec/support/models/catalog.rb +24 -0
- data/spec/support/models/circus.rb +3 -0
- data/spec/support/models/code.rb +2 -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/membership.rb +1 -0
- data/spec/support/models/passport.rb +9 -0
- data/spec/support/models/person.rb +1 -0
- data/spec/support/models/player.rb +2 -0
- data/spec/support/models/powerup.rb +12 -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/spec/support/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_azure.json +17 -0
- data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_gcp.json +17 -0
- data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_kmip.json +17 -0
- data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_local.json +18 -0
- data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/spec_config.rb +4 -0
- data.tar.gz.sig +0 -0
- metadata +682 -619
- 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/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
|
|
|
@@ -675,7 +660,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
675
660
|
end
|
|
676
661
|
|
|
677
662
|
context 'when fallbacks are enabled with a locale list' do
|
|
678
|
-
|
|
663
|
+
with_i18n_fallbacks
|
|
679
664
|
|
|
680
665
|
around(:all) do |example|
|
|
681
666
|
prev_fallbacks = I18n.fallbacks.dup
|
|
@@ -701,7 +686,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
701
686
|
|
|
702
687
|
it "correctly uses the fallback" do
|
|
703
688
|
I18n.locale = :en
|
|
704
|
-
|
|
689
|
+
Dictionary.create!(description: 'english-text')
|
|
705
690
|
I18n.locale = :he
|
|
706
691
|
distinct.should == "english-text"
|
|
707
692
|
end
|
|
@@ -782,9 +767,11 @@ describe Mongoid::Contextual::Mongo do
|
|
|
782
767
|
|
|
783
768
|
context "when legacy_pluck_distinct is set" do
|
|
784
769
|
config_override :legacy_pluck_distinct, true
|
|
770
|
+
config_override :map_big_decimal_to_decimal128, true
|
|
771
|
+
max_bson_version '4.99.99'
|
|
785
772
|
|
|
786
773
|
it "returns the distinct matching fields" do
|
|
787
|
-
expect(context.distinct("label.sales")).to eq([
|
|
774
|
+
expect(context.distinct("label.sales")).to eq([ BSON::Decimal128.new('1E+2') ])
|
|
788
775
|
end
|
|
789
776
|
end
|
|
790
777
|
|
|
@@ -797,6 +784,433 @@ describe Mongoid::Contextual::Mongo do
|
|
|
797
784
|
end
|
|
798
785
|
end
|
|
799
786
|
|
|
787
|
+
describe "#tally" do
|
|
788
|
+
let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
|
789
|
+
let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
|
790
|
+
let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
|
|
791
|
+
|
|
792
|
+
let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
|
|
793
|
+
let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
|
|
794
|
+
let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
|
|
795
|
+
|
|
796
|
+
let(:label1) { Label.new(name: "Atlantic") }
|
|
797
|
+
let(:label2) { Label.new(name: "Atlantic") }
|
|
798
|
+
let(:label3) { Label.new(name: "Columbia") }
|
|
799
|
+
|
|
800
|
+
before do
|
|
801
|
+
Band.create!(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1)
|
|
802
|
+
Band.create!(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2)
|
|
803
|
+
Band.create!(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3)
|
|
804
|
+
Band.create!(origin: "tally2", fanatics: fans1, genres: [1, 2])
|
|
805
|
+
Band.create!(origin: "tally2", fanatics: fans2, genres: [1, 2])
|
|
806
|
+
Band.create!(origin: "tally2", fanatics: fans3, genres: [1, 3])
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
810
|
+
|
|
811
|
+
context "when tallying a string" do
|
|
812
|
+
let(:tally) do
|
|
813
|
+
criteria.tally(:name)
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
it "returns the correct hash" do
|
|
817
|
+
expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
|
|
818
|
+
end
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
context "using an aliased field" do
|
|
822
|
+
let(:tally) do
|
|
823
|
+
criteria.tally(:years)
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
it "returns the correct hash" do
|
|
827
|
+
expect(tally).to eq(30 => 3)
|
|
828
|
+
end
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
context "when tallying a demongoizable field" do
|
|
832
|
+
let(:tally) do
|
|
833
|
+
criteria.tally(:sales)
|
|
834
|
+
end
|
|
835
|
+
|
|
836
|
+
it "returns the correct hash" do
|
|
837
|
+
expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
context "when tallying a localized field" do
|
|
842
|
+
before do
|
|
843
|
+
I18n.locale = :en
|
|
844
|
+
d1 = Dictionary.create!(description: 'en1')
|
|
845
|
+
d2 = Dictionary.create!(description: 'en1')
|
|
846
|
+
d3 = Dictionary.create!(description: 'en1')
|
|
847
|
+
d4 = Dictionary.create!(description: 'en2')
|
|
848
|
+
I18n.locale = :de
|
|
849
|
+
d1.description = 'de1'
|
|
850
|
+
d2.description = 'de1'
|
|
851
|
+
d3.description = 'de2'
|
|
852
|
+
d4.description = 'de3'
|
|
853
|
+
d1.save!
|
|
854
|
+
d2.save!
|
|
855
|
+
d3.save!
|
|
856
|
+
d4.save!
|
|
857
|
+
I18n.locale = :en
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
context "when getting the demongoized field" do
|
|
861
|
+
let(:tallied) do
|
|
862
|
+
Dictionary.tally(:description)
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
it "returns the translation for the current locale" do
|
|
866
|
+
expect(tallied).to eq("en1" => 3, "en2" => 1)
|
|
867
|
+
end
|
|
868
|
+
end
|
|
869
|
+
|
|
870
|
+
context "when getting a specific locale" do
|
|
871
|
+
let(:tallied) do
|
|
872
|
+
Dictionary.tally("description.de")
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
it "returns the translation for the the specific locale" do
|
|
876
|
+
expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
|
|
877
|
+
end
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
context "when getting the full hash" do
|
|
881
|
+
let(:tallied) do
|
|
882
|
+
Dictionary.tally("description_translations")
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
it "returns the correct hash" do
|
|
886
|
+
expect(tallied).to eq(
|
|
887
|
+
{"de" => "de1", "en" => "en1" } => 2,
|
|
888
|
+
{"de" => "de2", "en" => "en1" } => 1,
|
|
889
|
+
{"de" => "de3", "en" => "en2" } => 1
|
|
890
|
+
)
|
|
891
|
+
end
|
|
892
|
+
end
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
context "when tallying an embedded localized field" do
|
|
896
|
+
|
|
897
|
+
before do
|
|
898
|
+
I18n.locale = :en
|
|
899
|
+
address1a = Address.new(name: "en1")
|
|
900
|
+
address1b = Address.new(name: "en2")
|
|
901
|
+
address2a = Address.new(name: "en1")
|
|
902
|
+
address2b = Address.new(name: "en3")
|
|
903
|
+
I18n.locale = :de
|
|
904
|
+
address1a.name = "de1"
|
|
905
|
+
address1b.name = "de2"
|
|
906
|
+
address2a.name = "de1"
|
|
907
|
+
address2b.name = "de3"
|
|
908
|
+
Person.create!(addresses: [ address1a, address1b ])
|
|
909
|
+
Person.create!(addresses: [ address2a, address2b ])
|
|
910
|
+
I18n.locale = :en
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
context "when getting the demongoized field" do
|
|
914
|
+
let(:tallied) do
|
|
915
|
+
Person.tally("addresses.name")
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
it "returns the translation for the current locale" do
|
|
919
|
+
expect(tallied).to eq(
|
|
920
|
+
[ "en1", "en2" ] => 1,
|
|
921
|
+
[ "en1", "en3" ] => 1,
|
|
922
|
+
)
|
|
923
|
+
end
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
context "when getting a specific locale" do
|
|
927
|
+
let(:tallied) do
|
|
928
|
+
Person.tally("addresses.name.de")
|
|
929
|
+
end
|
|
930
|
+
|
|
931
|
+
it "returns the translation for the the specific locale" do
|
|
932
|
+
expect(tallied).to eq(
|
|
933
|
+
[ "de1", "de2" ] => 1,
|
|
934
|
+
[ "de1", "de3" ] => 1,
|
|
935
|
+
)
|
|
936
|
+
end
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
context "when getting the full hash" do
|
|
940
|
+
let(:tallied) do
|
|
941
|
+
Person.tally("addresses.name_translations")
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
it "returns the correct hash" do
|
|
945
|
+
expect(tallied).to eq(
|
|
946
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
|
|
947
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
|
|
948
|
+
)
|
|
949
|
+
end
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
context "when tallying an embedded field" do
|
|
955
|
+
let(:tally) do
|
|
956
|
+
criteria.tally("label.name")
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
it "returns the correct hash" do
|
|
960
|
+
expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
context "when tallying an element in an embeds_many field" do
|
|
965
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
966
|
+
|
|
967
|
+
let(:tally) do
|
|
968
|
+
criteria.tally("fanatics.age")
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
it "returns the correct hash" do
|
|
972
|
+
expect(tally).to eq(
|
|
973
|
+
[1, 2] => 2,
|
|
974
|
+
[1, 3] => 1
|
|
975
|
+
)
|
|
976
|
+
end
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
context "when tallying an embeds_many field" do
|
|
980
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
981
|
+
|
|
982
|
+
let(:tally) do
|
|
983
|
+
criteria.tally("fanatics")
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
it "returns the correct hash" do
|
|
987
|
+
expect(tally).to eq(
|
|
988
|
+
fans1.map(&:attributes) => 1,
|
|
989
|
+
fans2.map(&:attributes) => 1,
|
|
990
|
+
fans3.map(&:attributes) => 1,
|
|
991
|
+
)
|
|
992
|
+
end
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
context "when tallying a field of type array" do
|
|
996
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
|
997
|
+
|
|
998
|
+
let(:tally) do
|
|
999
|
+
criteria.tally("genres")
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
it "returns the correct hash" do
|
|
1003
|
+
expect(tally).to eq(
|
|
1004
|
+
[1, 2] => 2,
|
|
1005
|
+
[1, 3] => 1
|
|
1006
|
+
)
|
|
1007
|
+
end
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
context "when tallying an element from an array of hashes" do
|
|
1011
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1012
|
+
|
|
1013
|
+
let(:tally) do
|
|
1014
|
+
criteria.tally("genres.x")
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
it "returns the correct hash without the nil keys" do
|
|
1018
|
+
expect(tally).to eq(
|
|
1019
|
+
[1, 2] => 2,
|
|
1020
|
+
[1, 3] => 1
|
|
1021
|
+
)
|
|
1022
|
+
end
|
|
1023
|
+
end
|
|
1024
|
+
|
|
1025
|
+
context "when tallying an element from an array of hashes; with duplicate" do
|
|
1026
|
+
|
|
1027
|
+
before do
|
|
1028
|
+
Band.create!(origin: "tally", genres: [ { x: 1 }, {x: 1} ] )
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1032
|
+
|
|
1033
|
+
let(:tally) do
|
|
1034
|
+
criteria.tally("genres.x")
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
it "returns the correct hash without the nil keys" do
|
|
1038
|
+
expect(tally).to eq(
|
|
1039
|
+
[1, 2] => 2,
|
|
1040
|
+
[1, 3] => 1,
|
|
1041
|
+
[1, 1] => 1,
|
|
1042
|
+
)
|
|
1043
|
+
end
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
context "when tallying an aliased field of type array" do
|
|
1047
|
+
|
|
1048
|
+
before do
|
|
1049
|
+
Person.create!(array: [ 1, 2 ])
|
|
1050
|
+
Person.create!(array: [ 1, 3 ])
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
let(:tally) do
|
|
1054
|
+
Person.tally("array")
|
|
1055
|
+
end
|
|
1056
|
+
|
|
1057
|
+
it "returns the correct hash" do
|
|
1058
|
+
expect(tally).to eq(
|
|
1059
|
+
[1, 2] => 1,
|
|
1060
|
+
[1, 3] => 1
|
|
1061
|
+
)
|
|
1062
|
+
end
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
context "when going multiple levels deep in arrays" do
|
|
1066
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1067
|
+
|
|
1068
|
+
let(:tally) do
|
|
1069
|
+
criteria.tally("genres.y.z")
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
it "returns the correct hash" do
|
|
1073
|
+
expect(tally).to eq(
|
|
1074
|
+
[1, 2] => 2,
|
|
1075
|
+
[1, 3] => 1
|
|
1076
|
+
)
|
|
1077
|
+
end
|
|
1078
|
+
end
|
|
1079
|
+
|
|
1080
|
+
context "when going multiple levels deep in an array" do
|
|
1081
|
+
let(:criteria) { Band.where(origin: "tally") }
|
|
1082
|
+
|
|
1083
|
+
let(:tally) do
|
|
1084
|
+
criteria.tally("genres.y.z")
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
it "returns the correct hash" do
|
|
1088
|
+
expect(tally).to eq(
|
|
1089
|
+
[1, 2] => 2,
|
|
1090
|
+
[1, 3] => 1
|
|
1091
|
+
)
|
|
1092
|
+
end
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
|
1096
|
+
|
|
1097
|
+
before do
|
|
1098
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1099
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1100
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
let(:tally) do
|
|
1104
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
it "returns the correct hash" do
|
|
1108
|
+
expect(tally).to eq(
|
|
1109
|
+
[ [ 1, 2 ] ] => 2,
|
|
1110
|
+
[ [ 1, 3 ] ] => 1
|
|
1111
|
+
)
|
|
1112
|
+
end
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
|
1116
|
+
|
|
1117
|
+
before do
|
|
1118
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
|
1119
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1120
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
|
1121
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
|
1122
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
|
|
1123
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1126
|
+
let(:tally) do
|
|
1127
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
|
1128
|
+
end
|
|
1129
|
+
|
|
1130
|
+
it "returns the correct hash" do
|
|
1131
|
+
expect(tally).to eq(
|
|
1132
|
+
[ [ 1, 2 ], [ 1, 2 ] ] => 2,
|
|
1133
|
+
[ [ 1, 3 ], [ 1, 3 ] ] => 1
|
|
1134
|
+
)
|
|
1135
|
+
end
|
|
1136
|
+
end
|
|
1137
|
+
|
|
1138
|
+
context "when some keys are missing" do
|
|
1139
|
+
before do
|
|
1140
|
+
3.times { Band.create!(origin: "tally") }
|
|
1141
|
+
end
|
|
1142
|
+
|
|
1143
|
+
let(:tally) do
|
|
1144
|
+
criteria.tally(:name)
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
it "returns the correct hash" do
|
|
1148
|
+
expect(tally).to eq(
|
|
1149
|
+
"Depeche Mode" => 1,
|
|
1150
|
+
"New Order" => 1,
|
|
1151
|
+
"10,000 Maniacs" => 1,
|
|
1152
|
+
nil => 3
|
|
1153
|
+
)
|
|
1154
|
+
end
|
|
1155
|
+
end
|
|
1156
|
+
|
|
1157
|
+
context "when the first element is an embeds_one" do
|
|
1158
|
+
before do
|
|
1159
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
|
1160
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
|
1161
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
let(:tally) do
|
|
1165
|
+
Person.tally("name.translations.language")
|
|
1166
|
+
end
|
|
1167
|
+
|
|
1168
|
+
it "returns the correct hash" do
|
|
1169
|
+
expect(tally).to eq(
|
|
1170
|
+
[1, 2] => 2,
|
|
1171
|
+
[1, 3] => 1
|
|
1172
|
+
)
|
|
1173
|
+
end
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1176
|
+
context "when tallying demongoizable values from typeless fields" do
|
|
1177
|
+
|
|
1178
|
+
let!(:person1) { Person.create!(ssn: /hello/) }
|
|
1179
|
+
let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
|
|
1180
|
+
let(:tally) { Person.tally("ssn") }
|
|
1181
|
+
|
|
1182
|
+
context "< BSON 5" do
|
|
1183
|
+
max_bson_version '4.99.99'
|
|
1184
|
+
|
|
1185
|
+
it "stores the correct types in the database" do
|
|
1186
|
+
Person.find(person1.id).attributes["ssn"].should be_a BSON::Regexp::Raw
|
|
1187
|
+
Person.find(person2.id).attributes["ssn"].should be_a BSON::Decimal128
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1190
|
+
it "tallies the correct type" do
|
|
1191
|
+
tally.keys.map(&:class).sort do |a,b|
|
|
1192
|
+
a.to_s <=> b.to_s
|
|
1193
|
+
end.should == [BSON::Decimal128, BSON::Regexp::Raw]
|
|
1194
|
+
end
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
context ">= BSON 5" do
|
|
1198
|
+
min_bson_version "5.0"
|
|
1199
|
+
|
|
1200
|
+
it "stores the correct types in the database" do
|
|
1201
|
+
Person.find(person1.id).ssn.should be_a BSON::Regexp::Raw
|
|
1202
|
+
Person.find(person2.id).ssn.should be_a BigDeimal
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
it "tallies the correct type" do
|
|
1206
|
+
tally.keys.map(&:class).sort do |a,b|
|
|
1207
|
+
a.to_s <=> b.to_s
|
|
1208
|
+
end.should == [BigDecimal, BSON::Regexp::Raw]
|
|
1209
|
+
end
|
|
1210
|
+
end
|
|
1211
|
+
end
|
|
1212
|
+
end
|
|
1213
|
+
|
|
800
1214
|
describe "#each" do
|
|
801
1215
|
|
|
802
1216
|
before do
|
|
@@ -1005,51 +1419,15 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1005
1419
|
described_class.new(criteria)
|
|
1006
1420
|
end
|
|
1007
1421
|
|
|
1008
|
-
context "when exists? already called" do
|
|
1422
|
+
context "when exists? already called and query cache is enabled" do
|
|
1423
|
+
query_cache_enabled
|
|
1009
1424
|
|
|
1010
1425
|
before do
|
|
1011
1426
|
context.exists?
|
|
1012
1427
|
end
|
|
1013
1428
|
|
|
1014
|
-
it "
|
|
1015
|
-
|
|
1016
|
-
expect(context).to be_exists
|
|
1017
|
-
end
|
|
1018
|
-
end
|
|
1019
|
-
end
|
|
1020
|
-
|
|
1021
|
-
context "when caching is enabled" do
|
|
1022
|
-
|
|
1023
|
-
let(:criteria) do
|
|
1024
|
-
Band.where(name: "Depeche Mode").cache
|
|
1025
|
-
end
|
|
1026
|
-
|
|
1027
|
-
let(:context) do
|
|
1028
|
-
described_class.new(criteria)
|
|
1029
|
-
end
|
|
1030
|
-
|
|
1031
|
-
context "when the cache is loaded" do
|
|
1032
|
-
|
|
1033
|
-
before do
|
|
1034
|
-
context.to_a
|
|
1035
|
-
end
|
|
1036
|
-
|
|
1037
|
-
it "does not hit the database" do
|
|
1038
|
-
expect(context).to receive(:view).never
|
|
1039
|
-
expect(context).to be_exists
|
|
1040
|
-
end
|
|
1041
|
-
end
|
|
1042
|
-
|
|
1043
|
-
context "when the cache is not loaded" do
|
|
1044
|
-
|
|
1045
|
-
context "when a count has been executed" do
|
|
1046
|
-
|
|
1047
|
-
before do
|
|
1048
|
-
context.count
|
|
1049
|
-
end
|
|
1050
|
-
|
|
1051
|
-
it "does not hit the database" do
|
|
1052
|
-
expect(context).to receive(:view).never
|
|
1429
|
+
it "does not hit the database again" do
|
|
1430
|
+
expect_no_queries do
|
|
1053
1431
|
expect(context).to be_exists
|
|
1054
1432
|
end
|
|
1055
1433
|
end
|
|
@@ -1408,7 +1786,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1408
1786
|
it "deletes the document from the database" do
|
|
1409
1787
|
expect {
|
|
1410
1788
|
depeche.reload
|
|
1411
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
1789
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
|
1412
1790
|
end
|
|
1413
1791
|
|
|
1414
1792
|
context 'when a collation is specified on the criteria' do
|
|
@@ -1433,7 +1811,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1433
1811
|
it "deletes the document from the database" do
|
|
1434
1812
|
expect {
|
|
1435
1813
|
depeche.reload
|
|
1436
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
1814
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
|
1437
1815
|
end
|
|
1438
1816
|
end
|
|
1439
1817
|
end
|
|
@@ -1470,6 +1848,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1470
1848
|
Band.create!(name: "New Order")
|
|
1471
1849
|
end
|
|
1472
1850
|
|
|
1851
|
+
let!(:rolling_stones) do
|
|
1852
|
+
Band.create!(name: "The Rolling Stones")
|
|
1853
|
+
end
|
|
1854
|
+
|
|
1473
1855
|
context "when the context is not cached" do
|
|
1474
1856
|
|
|
1475
1857
|
let(:criteria) do
|
|
@@ -1510,14 +1892,14 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1510
1892
|
context "when there is sort on the context" do
|
|
1511
1893
|
|
|
1512
1894
|
it "follows the main sort" do
|
|
1513
|
-
expect(context.send(method)).to eq(
|
|
1895
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1514
1896
|
end
|
|
1515
1897
|
end
|
|
1516
1898
|
|
|
1517
1899
|
context "when subsequently calling #last" do
|
|
1518
1900
|
|
|
1519
1901
|
it "returns the correct document" do
|
|
1520
|
-
expect(context.send(method)).to eq(
|
|
1902
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1521
1903
|
expect(context.last).to eq(depeche_mode)
|
|
1522
1904
|
end
|
|
1523
1905
|
end
|
|
@@ -1542,134 +1924,614 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1542
1924
|
|
|
1543
1925
|
it 'returns the last document, sorted by _id' do
|
|
1544
1926
|
expect(context.send(method)).to eq(depeche_mode)
|
|
1545
|
-
expect(context.last).to eq(
|
|
1927
|
+
expect(context.last).to eq(rolling_stones)
|
|
1546
1928
|
end
|
|
1547
1929
|
end
|
|
1930
|
+
end
|
|
1548
1931
|
|
|
1549
|
-
|
|
1932
|
+
context 'when the criteria has a sort' do
|
|
1550
1933
|
|
|
1551
|
-
|
|
1552
|
-
|
|
1934
|
+
let(:criteria) do
|
|
1935
|
+
Band.desc(:name)
|
|
1936
|
+
end
|
|
1937
|
+
|
|
1938
|
+
let(:context) do
|
|
1939
|
+
described_class.new(criteria)
|
|
1940
|
+
end
|
|
1941
|
+
|
|
1942
|
+
it 'applies the criteria sort' do
|
|
1943
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1944
|
+
end
|
|
1945
|
+
|
|
1946
|
+
context 'when calling #last' do
|
|
1947
|
+
|
|
1948
|
+
it 'applies the criteria sort' do
|
|
1949
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1950
|
+
expect(context.last).to eq(depeche_mode)
|
|
1553
1951
|
end
|
|
1952
|
+
end
|
|
1953
|
+
end
|
|
1954
|
+
|
|
1955
|
+
context "when using .sort" do
|
|
1956
|
+
|
|
1957
|
+
let(:criteria) do
|
|
1958
|
+
Band.all.sort(:name => -1).criteria
|
|
1959
|
+
end
|
|
1960
|
+
|
|
1961
|
+
let(:context) do
|
|
1962
|
+
described_class.new(criteria)
|
|
1963
|
+
end
|
|
1964
|
+
|
|
1965
|
+
context "when there is sort on the context" do
|
|
1554
1966
|
|
|
1555
|
-
it
|
|
1556
|
-
expect(context.send(method
|
|
1967
|
+
it "follows the main sort" do
|
|
1968
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1557
1969
|
end
|
|
1970
|
+
end
|
|
1558
1971
|
|
|
1559
|
-
|
|
1972
|
+
context "when subsequently calling #last" do
|
|
1560
1973
|
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
end
|
|
1974
|
+
it "returns the correct document" do
|
|
1975
|
+
expect(context.send(method)).to eq(rolling_stones)
|
|
1976
|
+
expect(context.last).to eq(depeche_mode)
|
|
1565
1977
|
end
|
|
1566
1978
|
end
|
|
1567
1979
|
end
|
|
1568
1980
|
|
|
1569
|
-
context
|
|
1981
|
+
context "when the query cache is enabled" do
|
|
1982
|
+
query_cache_enabled
|
|
1570
1983
|
|
|
1571
1984
|
let(:criteria) do
|
|
1572
|
-
Band.
|
|
1985
|
+
Band.where(name: "Depeche Mode")
|
|
1573
1986
|
end
|
|
1574
1987
|
|
|
1575
1988
|
let(:context) do
|
|
1576
1989
|
described_class.new(criteria)
|
|
1577
1990
|
end
|
|
1578
1991
|
|
|
1992
|
+
context "when first method was called before" do
|
|
1579
1993
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1994
|
+
before do
|
|
1995
|
+
context.first
|
|
1996
|
+
end
|
|
1997
|
+
|
|
1998
|
+
it "returns the first document without touching the database" do
|
|
1999
|
+
expect_no_queries do
|
|
2000
|
+
expect(context.send(method)).to eq(depeche_mode)
|
|
2001
|
+
end
|
|
2002
|
+
end
|
|
1582
2003
|
end
|
|
2004
|
+
end
|
|
1583
2005
|
|
|
1584
|
-
|
|
2006
|
+
context "when including a limit" do
|
|
1585
2007
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
2008
|
+
context "when the context is not cached" do
|
|
2009
|
+
|
|
2010
|
+
let(:context) do
|
|
2011
|
+
described_class.new(criteria)
|
|
2012
|
+
end
|
|
2013
|
+
|
|
2014
|
+
context "when the limit is 1" do
|
|
2015
|
+
let(:criteria) do
|
|
2016
|
+
Band.criteria
|
|
2017
|
+
end
|
|
2018
|
+
|
|
2019
|
+
let(:docs) do
|
|
2020
|
+
context.send(method, 1)
|
|
2021
|
+
end
|
|
2022
|
+
|
|
2023
|
+
it "returns an array of documents" do
|
|
2024
|
+
expect(docs).to eq([ depeche_mode ])
|
|
2025
|
+
end
|
|
2026
|
+
end
|
|
2027
|
+
|
|
2028
|
+
context "when the limit is >1" do
|
|
2029
|
+
let(:criteria) do
|
|
2030
|
+
Band.criteria
|
|
2031
|
+
end
|
|
2032
|
+
|
|
2033
|
+
let(:docs) do
|
|
2034
|
+
context.send(method, 2)
|
|
2035
|
+
end
|
|
2036
|
+
|
|
2037
|
+
it "returns the number of documents in order" do
|
|
2038
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
|
2039
|
+
end
|
|
2040
|
+
end
|
|
2041
|
+
|
|
2042
|
+
context 'when the criteria has a collation' do
|
|
2043
|
+
min_server_version '3.4'
|
|
2044
|
+
|
|
2045
|
+
let(:criteria) do
|
|
2046
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
|
2047
|
+
end
|
|
2048
|
+
|
|
2049
|
+
it "returns the first matching document" do
|
|
2050
|
+
expect(context.send(method, 1)).to eq([ depeche_mode ])
|
|
2051
|
+
end
|
|
1589
2052
|
end
|
|
1590
2053
|
end
|
|
1591
2054
|
|
|
1592
|
-
context
|
|
2055
|
+
context "when the query cache is enabled" do
|
|
1593
2056
|
|
|
1594
|
-
let(:
|
|
1595
|
-
|
|
2057
|
+
let(:context) do
|
|
2058
|
+
described_class.new(criteria)
|
|
1596
2059
|
end
|
|
1597
2060
|
|
|
1598
|
-
|
|
1599
|
-
|
|
2061
|
+
context "when calling first beforehand" do
|
|
2062
|
+
query_cache_enabled
|
|
2063
|
+
|
|
2064
|
+
let(:context) do
|
|
2065
|
+
described_class.new(criteria)
|
|
2066
|
+
end
|
|
2067
|
+
|
|
2068
|
+
let(:criteria) do
|
|
2069
|
+
Band.all
|
|
2070
|
+
end
|
|
2071
|
+
|
|
2072
|
+
before do
|
|
2073
|
+
context.first(before_limit)
|
|
2074
|
+
end
|
|
2075
|
+
|
|
2076
|
+
let(:docs) do
|
|
2077
|
+
context.send(method, limit)
|
|
2078
|
+
end
|
|
2079
|
+
|
|
2080
|
+
context "when getting all of the documents before" do
|
|
2081
|
+
let(:before_limit) { 3 }
|
|
2082
|
+
|
|
2083
|
+
context "when getting all of the documents" do
|
|
2084
|
+
let(:limit) { 3 }
|
|
2085
|
+
|
|
2086
|
+
it "returns all documents without touching the database" do
|
|
2087
|
+
expect_no_queries do
|
|
2088
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2089
|
+
end
|
|
2090
|
+
end
|
|
2091
|
+
end
|
|
2092
|
+
|
|
2093
|
+
context "when getting fewer documents" do
|
|
2094
|
+
let(:limit) { 2 }
|
|
2095
|
+
|
|
2096
|
+
it "returns the correct documents without touching the database" do
|
|
2097
|
+
expect_no_queries do
|
|
2098
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
|
2099
|
+
end
|
|
2100
|
+
end
|
|
2101
|
+
end
|
|
2102
|
+
end
|
|
2103
|
+
|
|
2104
|
+
context "when getting fewer documents before" do
|
|
2105
|
+
let(:before_limit) { 2 }
|
|
2106
|
+
|
|
2107
|
+
context "when getting the same number of documents" do
|
|
2108
|
+
let(:limit) { 2 }
|
|
2109
|
+
|
|
2110
|
+
it "returns the correct documents without touching the database" do
|
|
2111
|
+
expect_no_queries do
|
|
2112
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
|
2113
|
+
end
|
|
2114
|
+
end
|
|
2115
|
+
end
|
|
2116
|
+
|
|
2117
|
+
context "when getting more documents" do
|
|
2118
|
+
let(:limit) { 3 }
|
|
2119
|
+
|
|
2120
|
+
it "returns the correct documents and touches the database" do
|
|
2121
|
+
expect_query(1) do
|
|
2122
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2123
|
+
end
|
|
2124
|
+
end
|
|
2125
|
+
end
|
|
2126
|
+
end
|
|
2127
|
+
|
|
2128
|
+
context "when getting one document before" do
|
|
2129
|
+
let(:before_limit) { 1 }
|
|
2130
|
+
|
|
2131
|
+
context "when getting one document" do
|
|
2132
|
+
let(:limit) { 1 }
|
|
2133
|
+
|
|
2134
|
+
it "returns the correct documents without touching the database" do
|
|
2135
|
+
expect_no_queries do
|
|
2136
|
+
expect(docs).to eq([ depeche_mode ])
|
|
2137
|
+
end
|
|
2138
|
+
end
|
|
2139
|
+
end
|
|
2140
|
+
|
|
2141
|
+
context "when getting more than one document" do
|
|
2142
|
+
let(:limit) { 3 }
|
|
2143
|
+
|
|
2144
|
+
it "returns the correct documents and touches the database" do
|
|
2145
|
+
expect_query(1) do
|
|
2146
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2147
|
+
end
|
|
2148
|
+
end
|
|
2149
|
+
end
|
|
2150
|
+
end
|
|
1600
2151
|
end
|
|
2152
|
+
end
|
|
2153
|
+
end
|
|
1601
2154
|
|
|
1602
|
-
|
|
2155
|
+
context "when calling #first then #last and the query cache is enabled" do
|
|
2156
|
+
query_cache_enabled
|
|
1603
2157
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
2158
|
+
let(:context) do
|
|
2159
|
+
described_class.new(criteria)
|
|
2160
|
+
end
|
|
2161
|
+
|
|
2162
|
+
let(:criteria) do
|
|
2163
|
+
Band.all
|
|
2164
|
+
end
|
|
2165
|
+
|
|
2166
|
+
before do
|
|
2167
|
+
context.first(before_limit)
|
|
2168
|
+
end
|
|
2169
|
+
|
|
2170
|
+
let(:docs) do
|
|
2171
|
+
context.last(limit)
|
|
2172
|
+
end
|
|
2173
|
+
|
|
2174
|
+
context "when getting one from the beginning and one from the end" do
|
|
2175
|
+
let(:before_limit) { 2 }
|
|
2176
|
+
let(:limit) { 1 }
|
|
2177
|
+
|
|
2178
|
+
it "gets the correct document and hits the database" do
|
|
2179
|
+
expect_query(1) do
|
|
2180
|
+
expect(docs).to eq([rolling_stones])
|
|
1607
2181
|
end
|
|
1608
2182
|
end
|
|
1609
2183
|
end
|
|
1610
2184
|
end
|
|
2185
|
+
end
|
|
2186
|
+
end
|
|
1611
2187
|
|
|
1612
|
-
|
|
2188
|
+
describe "#last" do
|
|
2189
|
+
let!(:depeche_mode) do
|
|
2190
|
+
Band.create!(name: "Depeche Mode")
|
|
2191
|
+
end
|
|
2192
|
+
|
|
2193
|
+
let!(:new_order) do
|
|
2194
|
+
Band.create!(name: "New Order")
|
|
2195
|
+
end
|
|
2196
|
+
|
|
2197
|
+
let!(:rolling_stones) do
|
|
2198
|
+
Band.create!(name: "The Rolling Stones")
|
|
2199
|
+
end
|
|
2200
|
+
|
|
2201
|
+
context "when the context is not cached" do
|
|
2202
|
+
|
|
2203
|
+
let(:criteria) do
|
|
2204
|
+
Band.where(name: "Depeche Mode")
|
|
2205
|
+
end
|
|
2206
|
+
|
|
2207
|
+
let(:context) do
|
|
2208
|
+
described_class.new(criteria)
|
|
2209
|
+
end
|
|
2210
|
+
|
|
2211
|
+
it "returns the last matching document" do
|
|
2212
|
+
expect(context.last).to eq(depeche_mode)
|
|
2213
|
+
end
|
|
2214
|
+
|
|
2215
|
+
context 'when the criteria has a collation' do
|
|
2216
|
+
min_server_version '3.4'
|
|
1613
2217
|
|
|
1614
2218
|
let(:criteria) do
|
|
1615
|
-
Band.
|
|
2219
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
|
2220
|
+
end
|
|
2221
|
+
|
|
2222
|
+
it "returns the last matching document" do
|
|
2223
|
+
expect(context.last).to eq(depeche_mode)
|
|
2224
|
+
end
|
|
2225
|
+
end
|
|
2226
|
+
end
|
|
2227
|
+
|
|
2228
|
+
context "when using .desc" do
|
|
2229
|
+
|
|
2230
|
+
let(:criteria) do
|
|
2231
|
+
Band.desc(:name)
|
|
2232
|
+
end
|
|
2233
|
+
|
|
2234
|
+
let(:context) do
|
|
2235
|
+
described_class.new(criteria)
|
|
2236
|
+
end
|
|
2237
|
+
|
|
2238
|
+
context "when there is sort on the context" do
|
|
2239
|
+
|
|
2240
|
+
it "follows the main sort" do
|
|
2241
|
+
expect(context.last).to eq(depeche_mode)
|
|
2242
|
+
end
|
|
2243
|
+
end
|
|
2244
|
+
|
|
2245
|
+
context "when subsequently calling #first" do
|
|
2246
|
+
|
|
2247
|
+
it "returns the correct document" do
|
|
2248
|
+
expect(context.last).to eq(depeche_mode)
|
|
2249
|
+
expect(context.first).to eq(rolling_stones)
|
|
2250
|
+
end
|
|
2251
|
+
end
|
|
2252
|
+
end
|
|
2253
|
+
|
|
2254
|
+
context 'when the criteria has no sort' do
|
|
2255
|
+
|
|
2256
|
+
let(:criteria) do
|
|
2257
|
+
Band.all
|
|
2258
|
+
end
|
|
2259
|
+
|
|
2260
|
+
let(:context) do
|
|
2261
|
+
described_class.new(criteria)
|
|
2262
|
+
end
|
|
2263
|
+
|
|
2264
|
+
it 'applies a sort on _id' do
|
|
2265
|
+
expect(context.last).to eq(rolling_stones)
|
|
2266
|
+
end
|
|
2267
|
+
|
|
2268
|
+
context 'when calling #first' do
|
|
2269
|
+
|
|
2270
|
+
it 'returns the first document, sorted by _id' do
|
|
2271
|
+
expect(context.last).to eq(rolling_stones)
|
|
2272
|
+
expect(context.first).to eq(depeche_mode)
|
|
2273
|
+
end
|
|
2274
|
+
end
|
|
2275
|
+
end
|
|
2276
|
+
|
|
2277
|
+
context 'when the criteria has a sort' do
|
|
2278
|
+
|
|
2279
|
+
let(:criteria) do
|
|
2280
|
+
Band.desc(:name)
|
|
2281
|
+
end
|
|
2282
|
+
|
|
2283
|
+
let(:context) do
|
|
2284
|
+
described_class.new(criteria)
|
|
2285
|
+
end
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
it 'applies the criteria sort' do
|
|
2289
|
+
expect(context.last).to eq(depeche_mode)
|
|
2290
|
+
end
|
|
2291
|
+
|
|
2292
|
+
context 'when calling #first' do
|
|
2293
|
+
|
|
2294
|
+
it 'applies the criteria sort' do
|
|
2295
|
+
expect(context.last).to eq(depeche_mode)
|
|
2296
|
+
expect(context.first).to eq(rolling_stones)
|
|
2297
|
+
end
|
|
2298
|
+
end
|
|
2299
|
+
end
|
|
2300
|
+
|
|
2301
|
+
context "when using .sort" do
|
|
2302
|
+
|
|
2303
|
+
let(:criteria) do
|
|
2304
|
+
Band.all.sort(:name => -1).criteria
|
|
2305
|
+
end
|
|
2306
|
+
|
|
2307
|
+
let(:context) do
|
|
2308
|
+
described_class.new(criteria)
|
|
2309
|
+
end
|
|
2310
|
+
|
|
2311
|
+
context "when there is sort on the context" do
|
|
2312
|
+
|
|
2313
|
+
it "follows the main sort" do
|
|
2314
|
+
expect(context.last).to eq(depeche_mode)
|
|
2315
|
+
end
|
|
2316
|
+
end
|
|
2317
|
+
|
|
2318
|
+
context "when subsequently calling #first" do
|
|
2319
|
+
|
|
2320
|
+
it "returns the correct document" do
|
|
2321
|
+
expect(context.last).to eq(depeche_mode)
|
|
2322
|
+
expect(context.first).to eq(rolling_stones)
|
|
2323
|
+
end
|
|
2324
|
+
end
|
|
2325
|
+
end
|
|
2326
|
+
|
|
2327
|
+
context "when the query cache is enabled" do
|
|
2328
|
+
query_cache_enabled
|
|
2329
|
+
|
|
2330
|
+
let(:criteria) do
|
|
2331
|
+
Band.where(name: "Depeche Mode")
|
|
2332
|
+
end
|
|
2333
|
+
|
|
2334
|
+
let(:context) do
|
|
2335
|
+
described_class.new(criteria)
|
|
2336
|
+
end
|
|
2337
|
+
|
|
2338
|
+
context "when last method was called before" do
|
|
2339
|
+
|
|
2340
|
+
before do
|
|
2341
|
+
context.last
|
|
1616
2342
|
end
|
|
1617
2343
|
|
|
2344
|
+
it "returns the last document without touching the database" do
|
|
2345
|
+
expect_no_queries do
|
|
2346
|
+
expect(context.last).to eq(depeche_mode)
|
|
2347
|
+
end
|
|
2348
|
+
end
|
|
2349
|
+
end
|
|
2350
|
+
end
|
|
2351
|
+
|
|
2352
|
+
context "when including a limit" do
|
|
2353
|
+
|
|
2354
|
+
context "when the context is not cached" do
|
|
2355
|
+
|
|
1618
2356
|
let(:context) do
|
|
1619
2357
|
described_class.new(criteria)
|
|
1620
2358
|
end
|
|
1621
2359
|
|
|
1622
|
-
context "when
|
|
2360
|
+
context "when the limit is 1" do
|
|
2361
|
+
let(:criteria) do
|
|
2362
|
+
Band.criteria
|
|
2363
|
+
end
|
|
1623
2364
|
|
|
1624
|
-
|
|
1625
|
-
|
|
2365
|
+
let(:docs) do
|
|
2366
|
+
context.last(1)
|
|
2367
|
+
end
|
|
2368
|
+
|
|
2369
|
+
it "returns an array of documents" do
|
|
2370
|
+
expect(docs).to eq([ rolling_stones ])
|
|
1626
2371
|
end
|
|
1627
2372
|
end
|
|
1628
2373
|
|
|
1629
|
-
context "when
|
|
2374
|
+
context "when the limit is >1" do
|
|
2375
|
+
let(:criteria) do
|
|
2376
|
+
Band.criteria
|
|
2377
|
+
end
|
|
1630
2378
|
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
2379
|
+
let(:docs) do
|
|
2380
|
+
context.last(2)
|
|
2381
|
+
end
|
|
2382
|
+
|
|
2383
|
+
it "returns the number of documents in order" do
|
|
2384
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
|
1634
2385
|
end
|
|
1635
2386
|
end
|
|
1636
|
-
end
|
|
1637
2387
|
|
|
1638
|
-
|
|
2388
|
+
context 'when the criteria has a collation' do
|
|
2389
|
+
min_server_version '3.4'
|
|
1639
2390
|
|
|
1640
|
-
|
|
1641
|
-
|
|
2391
|
+
let(:criteria) do
|
|
2392
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
|
2393
|
+
end
|
|
2394
|
+
|
|
2395
|
+
it "returns the first matching document" do
|
|
2396
|
+
expect(context.last(1)).to eq([ depeche_mode ])
|
|
2397
|
+
end
|
|
1642
2398
|
end
|
|
2399
|
+
end
|
|
2400
|
+
|
|
2401
|
+
context "when the context is cached" do
|
|
1643
2402
|
|
|
1644
2403
|
let(:context) do
|
|
1645
2404
|
described_class.new(criteria)
|
|
1646
2405
|
end
|
|
1647
2406
|
|
|
1648
|
-
context "when
|
|
2407
|
+
context "when query cache is enabled" do
|
|
2408
|
+
query_cache_enabled
|
|
2409
|
+
|
|
2410
|
+
let(:context) do
|
|
2411
|
+
described_class.new(criteria)
|
|
2412
|
+
end
|
|
2413
|
+
|
|
2414
|
+
let(:criteria) do
|
|
2415
|
+
Band.all
|
|
2416
|
+
end
|
|
1649
2417
|
|
|
1650
2418
|
before do
|
|
1651
|
-
context.
|
|
2419
|
+
context.last(before_limit)
|
|
1652
2420
|
end
|
|
1653
2421
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
expect(context.send(method)).to eq(depeche_mode)
|
|
2422
|
+
let(:docs) do
|
|
2423
|
+
context.last(limit)
|
|
1657
2424
|
end
|
|
1658
|
-
end
|
|
1659
2425
|
|
|
1660
|
-
|
|
2426
|
+
context "when getting all of the documents before" do
|
|
2427
|
+
let(:before_limit) { 3 }
|
|
1661
2428
|
|
|
1662
|
-
|
|
1663
|
-
|
|
2429
|
+
context "when getting all of the documents" do
|
|
2430
|
+
let(:limit) { 3 }
|
|
2431
|
+
|
|
2432
|
+
it "returns all documents without touching the db" do
|
|
2433
|
+
expect_no_queries do
|
|
2434
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2435
|
+
end
|
|
2436
|
+
end
|
|
2437
|
+
end
|
|
2438
|
+
|
|
2439
|
+
context "when getting fewer documents" do
|
|
2440
|
+
let(:limit) { 2 }
|
|
2441
|
+
|
|
2442
|
+
it "returns the correct documents without touching the db" do
|
|
2443
|
+
expect_no_queries do
|
|
2444
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
|
2445
|
+
end
|
|
2446
|
+
end
|
|
2447
|
+
end
|
|
1664
2448
|
end
|
|
1665
2449
|
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
2450
|
+
context "when getting fewer documents before" do
|
|
2451
|
+
let(:before_limit) { 2 }
|
|
2452
|
+
|
|
2453
|
+
context "when getting the same number of documents" do
|
|
2454
|
+
let(:limit) { 2 }
|
|
2455
|
+
|
|
2456
|
+
it "returns the correct documents without touching the db" do
|
|
2457
|
+
expect_no_queries do
|
|
2458
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
|
2459
|
+
end
|
|
2460
|
+
end
|
|
2461
|
+
end
|
|
2462
|
+
|
|
2463
|
+
context "when getting more documents" do
|
|
2464
|
+
let(:limit) { 3 }
|
|
2465
|
+
|
|
2466
|
+
it "returns the correct documents and touches the database" do
|
|
2467
|
+
expect_query(1) do
|
|
2468
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2469
|
+
end
|
|
2470
|
+
end
|
|
2471
|
+
end
|
|
2472
|
+
end
|
|
2473
|
+
|
|
2474
|
+
context "when getting one document before" do
|
|
2475
|
+
let(:before_limit) { 1 }
|
|
2476
|
+
|
|
2477
|
+
context "when getting one document" do
|
|
2478
|
+
let(:limit) { 1 }
|
|
2479
|
+
|
|
2480
|
+
it "returns the correct documents without touching the database" do
|
|
2481
|
+
expect_no_queries do
|
|
2482
|
+
expect(docs).to eq([ rolling_stones ])
|
|
2483
|
+
end
|
|
2484
|
+
end
|
|
2485
|
+
end
|
|
2486
|
+
|
|
2487
|
+
context "when getting more than one document" do
|
|
2488
|
+
let(:limit) { 3 }
|
|
2489
|
+
|
|
2490
|
+
it "returns the correct documents and touches the database" do
|
|
2491
|
+
expect_query(1) do
|
|
2492
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2493
|
+
end
|
|
2494
|
+
end
|
|
2495
|
+
end
|
|
1669
2496
|
end
|
|
1670
2497
|
end
|
|
1671
2498
|
end
|
|
1672
2499
|
end
|
|
2500
|
+
|
|
2501
|
+
context "when calling #last then #first and the query cache is enabled" do
|
|
2502
|
+
query_cache_enabled
|
|
2503
|
+
|
|
2504
|
+
let(:context) do
|
|
2505
|
+
described_class.new(criteria)
|
|
2506
|
+
end
|
|
2507
|
+
|
|
2508
|
+
let(:criteria) do
|
|
2509
|
+
Band.all
|
|
2510
|
+
end
|
|
2511
|
+
|
|
2512
|
+
before do
|
|
2513
|
+
context.last(before_limit)
|
|
2514
|
+
end
|
|
2515
|
+
|
|
2516
|
+
let(:docs) do
|
|
2517
|
+
context.first(limit)
|
|
2518
|
+
end
|
|
2519
|
+
|
|
2520
|
+
context "when getting one from the beginning and one from the end" do
|
|
2521
|
+
let(:before_limit) { 2 }
|
|
2522
|
+
let(:limit) { 1 }
|
|
2523
|
+
|
|
2524
|
+
it "hits the database" do
|
|
2525
|
+
expect_query(1) do
|
|
2526
|
+
docs
|
|
2527
|
+
end
|
|
2528
|
+
end
|
|
2529
|
+
|
|
2530
|
+
it "gets the correct document" do
|
|
2531
|
+
expect(docs).to eq([ depeche_mode ])
|
|
2532
|
+
end
|
|
2533
|
+
end
|
|
2534
|
+
end
|
|
1673
2535
|
end
|
|
1674
2536
|
|
|
1675
2537
|
describe "#initialize" do
|
|
@@ -1718,37 +2580,28 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1718
2580
|
described_class.new(criteria)
|
|
1719
2581
|
end
|
|
1720
2582
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
end
|
|
2583
|
+
context "when broken_view_options is false" do
|
|
2584
|
+
driver_config_override :broken_view_options, false
|
|
1724
2585
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
|
1728
|
-
2.times { expect(context.send(method)).to eq(2) }
|
|
2586
|
+
it "returns the number of documents that match" do
|
|
2587
|
+
expect(context.send(method)).to eq(1)
|
|
1729
2588
|
end
|
|
1730
2589
|
end
|
|
1731
2590
|
|
|
1732
|
-
context "when
|
|
2591
|
+
context "when broken_view_options is true" do
|
|
2592
|
+
driver_config_override :broken_view_options, true
|
|
1733
2593
|
|
|
1734
|
-
|
|
1735
|
-
context.entries
|
|
1736
|
-
end
|
|
1737
|
-
|
|
1738
|
-
it "returns the cached value for all calls" do
|
|
1739
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
|
2594
|
+
it "returns the number of documents that match" do
|
|
1740
2595
|
expect(context.send(method)).to eq(2)
|
|
1741
2596
|
end
|
|
2597
|
+
end
|
|
1742
2598
|
|
|
1743
|
-
|
|
2599
|
+
context "when calling more than once with different limits" do
|
|
2600
|
+
driver_config_override :broken_view_options, false
|
|
1744
2601
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
it "resets the length on each full iteration" do
|
|
1750
|
-
expect(context.size).to eq(2)
|
|
1751
|
-
end
|
|
2602
|
+
it "does not cache the value" do
|
|
2603
|
+
expect(context.limit(1).send(method)).to eq(1)
|
|
2604
|
+
expect(context.limit(2).send(method)).to eq(2)
|
|
1752
2605
|
end
|
|
1753
2606
|
end
|
|
1754
2607
|
end
|
|
@@ -1767,10 +2620,12 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1767
2620
|
expect(context.send(method)).to eq(1)
|
|
1768
2621
|
end
|
|
1769
2622
|
|
|
1770
|
-
context "when calling more than once" do
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
2623
|
+
context "when calling more than once with different skips" do
|
|
2624
|
+
driver_config_override :broken_view_options, false
|
|
2625
|
+
|
|
2626
|
+
it "does not cache the value" do
|
|
2627
|
+
expect(context.skip(0).send(method)).to eq(1)
|
|
2628
|
+
expect(context.skip(1).send(method)).to eq(0)
|
|
1774
2629
|
end
|
|
1775
2630
|
end
|
|
1776
2631
|
|
|
@@ -1823,6 +2678,80 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1823
2678
|
end
|
|
1824
2679
|
end
|
|
1825
2680
|
|
|
2681
|
+
describe "#take" do
|
|
2682
|
+
|
|
2683
|
+
let!(:depeche_mode) do
|
|
2684
|
+
Band.create!(name: "Depeche Mode")
|
|
2685
|
+
end
|
|
2686
|
+
|
|
2687
|
+
let!(:new_order) do
|
|
2688
|
+
Band.create!(name: "New Order")
|
|
2689
|
+
end
|
|
2690
|
+
|
|
2691
|
+
let!(:rolling_stones) do
|
|
2692
|
+
Band.create!(name: "The Rolling Stones")
|
|
2693
|
+
end
|
|
2694
|
+
|
|
2695
|
+
let(:criteria) do
|
|
2696
|
+
Band.all
|
|
2697
|
+
end
|
|
2698
|
+
|
|
2699
|
+
let(:context) do
|
|
2700
|
+
described_class.new(criteria)
|
|
2701
|
+
end
|
|
2702
|
+
|
|
2703
|
+
it "takes the correct number results" do
|
|
2704
|
+
expect(context.take(2)).to eq([ depeche_mode, new_order ])
|
|
2705
|
+
end
|
|
2706
|
+
|
|
2707
|
+
it "returns an array when passing 1" do
|
|
2708
|
+
expect(context.take(1)).to eq([ depeche_mode ])
|
|
2709
|
+
end
|
|
2710
|
+
|
|
2711
|
+
it "does not return an array when not passing an argument" do
|
|
2712
|
+
expect(context.take).to eq(depeche_mode)
|
|
2713
|
+
end
|
|
2714
|
+
|
|
2715
|
+
it "returns all the documents taking more than whats in the db" do
|
|
2716
|
+
expect(context.take(5)).to eq([ depeche_mode, new_order, rolling_stones ])
|
|
2717
|
+
end
|
|
2718
|
+
end
|
|
2719
|
+
|
|
2720
|
+
describe "#take!" do
|
|
2721
|
+
|
|
2722
|
+
let!(:depeche_mode) do
|
|
2723
|
+
Band.create!(name: "Depeche Mode")
|
|
2724
|
+
end
|
|
2725
|
+
|
|
2726
|
+
let!(:new_order) do
|
|
2727
|
+
Band.create!(name: "New Order")
|
|
2728
|
+
end
|
|
2729
|
+
|
|
2730
|
+
let!(:rolling_stones) do
|
|
2731
|
+
Band.create!(name: "The Rolling Stones")
|
|
2732
|
+
end
|
|
2733
|
+
|
|
2734
|
+
let(:criteria) do
|
|
2735
|
+
Band.all
|
|
2736
|
+
end
|
|
2737
|
+
|
|
2738
|
+
let(:context) do
|
|
2739
|
+
described_class.new(criteria)
|
|
2740
|
+
end
|
|
2741
|
+
|
|
2742
|
+
it "takes the first document" do
|
|
2743
|
+
expect(context.take!).to eq(depeche_mode)
|
|
2744
|
+
end
|
|
2745
|
+
|
|
2746
|
+
context "when there are no documents" do
|
|
2747
|
+
it "raises an error" do
|
|
2748
|
+
expect do
|
|
2749
|
+
Person.take!
|
|
2750
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Person./)
|
|
2751
|
+
end
|
|
2752
|
+
end
|
|
2753
|
+
end
|
|
2754
|
+
|
|
1826
2755
|
describe "#map" do
|
|
1827
2756
|
|
|
1828
2757
|
before do
|
|
@@ -1840,8 +2769,10 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1840
2769
|
|
|
1841
2770
|
context "when passed the symbol field name" do
|
|
1842
2771
|
|
|
1843
|
-
it "
|
|
1844
|
-
expect
|
|
2772
|
+
it "raises an error" do
|
|
2773
|
+
expect do
|
|
2774
|
+
context.map(:name)
|
|
2775
|
+
end.to raise_error(ArgumentError)
|
|
1845
2776
|
end
|
|
1846
2777
|
end
|
|
1847
2778
|
|