mongoid 7.4.3 → 8.0.7
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/Rakefile +25 -0
- 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 +33 -10
- 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 +65 -41
- 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 +28 -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 +70 -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 +26 -16
- 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.rb +7 -0
- data/lib/mongoid/attributes/dynamic.rb +3 -3
- data/lib/mongoid/attributes/nested.rb +5 -5
- data/lib/mongoid/attributes/processing.rb +37 -6
- 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 +43 -10
- 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/options.rb +3 -0
- data/lib/mongoid/config/validators/client.rb +6 -6
- data/lib/mongoid/config.rb +62 -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 +260 -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 +3 -14
- 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 -15
- 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 +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 +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 +16 -35
- data/lib/mongoid/deprecable.rb +37 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +135 -34
- data/lib/mongoid/equality.rb +8 -8
- 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 +37 -8
- 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 +55 -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 +233 -40
- 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 +185 -16
- data/lib/mongoid/matchable.rb +1 -1
- data/lib/mongoid/matcher.rb +33 -13
- 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 +1 -1
- 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 +10 -8
- data/lib/mongoid/scopable.rb +26 -22
- 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 +35 -9
- data/lib/mongoid/tasks/database.rb +0 -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/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 +4 -3
- data/spec/config/mongoid.yml +16 -0
- data/spec/integration/app_spec.rb +8 -12
- 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 +95 -1
- data/spec/integration/callbacks_spec.rb +246 -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/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 +235 -40
- data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -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 +202 -201
- 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 +160 -119
- 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/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 +551 -27
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +23 -30
- 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_spec.rb +78 -18
- 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 +1253 -247
- 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/string_spec.rb +0 -59
- 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/selectable_logical_spec.rb +50 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
- data/spec/mongoid/criteria/queryable/selector_spec.rb +89 -4
- 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 +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/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 +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 +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 +364 -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 +807 -27
- 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 +59 -2
- data/spec/mongoid/scopable_spec.rb +54 -16
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +157 -51
- 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/mongoid_spec.rb +1 -1
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/support/constraints.rb +24 -0
- data/spec/support/macros.rb +46 -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/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/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 +4 -1
- metadata +682 -635
- 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
|
|
@@ -189,6 +158,16 @@ describe Mongoid::Contextual::Mongo do
|
|
189
158
|
end
|
190
159
|
end
|
191
160
|
end
|
161
|
+
|
162
|
+
context 'when for_js is present' do
|
163
|
+
let(:context) do
|
164
|
+
Band.for_js('this.name == "Depeche Mode"')
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'counts the expected records' do
|
168
|
+
expect(context.count).to eq(1)
|
169
|
+
end
|
170
|
+
end
|
192
171
|
end
|
193
172
|
|
194
173
|
describe "#estimated_count" do
|
@@ -217,16 +196,18 @@ describe Mongoid::Contextual::Mongo do
|
|
217
196
|
end
|
218
197
|
end
|
219
198
|
|
220
|
-
context "when
|
199
|
+
context "when the query cache is enabled" do
|
200
|
+
query_cache_enabled
|
221
201
|
|
222
202
|
let(:context) do
|
223
|
-
described_class.new(criteria
|
203
|
+
described_class.new(criteria)
|
224
204
|
end
|
225
205
|
|
226
|
-
it "
|
227
|
-
|
228
|
-
|
229
|
-
|
206
|
+
it "the results are not cached" do
|
207
|
+
expect_query(2) do
|
208
|
+
2.times do
|
209
|
+
context.estimated_count
|
210
|
+
end
|
230
211
|
end
|
231
212
|
end
|
232
213
|
end
|
@@ -561,8 +542,22 @@ describe Mongoid::Contextual::Mongo do
|
|
561
542
|
context "when legacy_pluck_distinct is set" do
|
562
543
|
config_override :legacy_pluck_distinct, true
|
563
544
|
|
564
|
-
|
565
|
-
|
545
|
+
context 'when storing BigDecimal as string' do
|
546
|
+
config_override :map_big_decimal_to_decimal128, false
|
547
|
+
|
548
|
+
it "returns the non-demongoized distinct field values" do
|
549
|
+
expect(context.distinct(:sales).sort).to eq([ "1E2", "2E3" ])
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
context 'when storing BigDecimal as decimal128' do
|
554
|
+
config_override :map_big_decimal_to_decimal128, true
|
555
|
+
min_bson_version '4.15.0'
|
556
|
+
max_bson_version '4.99.99'
|
557
|
+
|
558
|
+
it "returns the non-demongoized distinct field values" do
|
559
|
+
expect(context.distinct(:sales).sort).to eq([ BSON::Decimal128.new("1E2"), BSON::Decimal128.new("2E3") ])
|
560
|
+
end
|
566
561
|
end
|
567
562
|
end
|
568
563
|
|
@@ -675,7 +670,7 @@ describe Mongoid::Contextual::Mongo do
|
|
675
670
|
end
|
676
671
|
|
677
672
|
context 'when fallbacks are enabled with a locale list' do
|
678
|
-
|
673
|
+
with_i18n_fallbacks
|
679
674
|
|
680
675
|
around(:all) do |example|
|
681
676
|
prev_fallbacks = I18n.fallbacks.dup
|
@@ -701,7 +696,7 @@ describe Mongoid::Contextual::Mongo do
|
|
701
696
|
|
702
697
|
it "correctly uses the fallback" do
|
703
698
|
I18n.locale = :en
|
704
|
-
|
699
|
+
Dictionary.create!(description: 'english-text')
|
705
700
|
I18n.locale = :he
|
706
701
|
distinct.should == "english-text"
|
707
702
|
end
|
@@ -782,9 +777,11 @@ describe Mongoid::Contextual::Mongo do
|
|
782
777
|
|
783
778
|
context "when legacy_pluck_distinct is set" do
|
784
779
|
config_override :legacy_pluck_distinct, true
|
780
|
+
config_override :map_big_decimal_to_decimal128, true
|
781
|
+
max_bson_version '4.99.99'
|
785
782
|
|
786
783
|
it "returns the distinct matching fields" do
|
787
|
-
expect(context.distinct("label.sales")).to eq([
|
784
|
+
expect(context.distinct("label.sales")).to eq([ BSON::Decimal128.new('1E+2') ])
|
788
785
|
end
|
789
786
|
end
|
790
787
|
|
@@ -797,6 +794,449 @@ describe Mongoid::Contextual::Mongo do
|
|
797
794
|
end
|
798
795
|
end
|
799
796
|
|
797
|
+
describe "#tally" do
|
798
|
+
let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
799
|
+
let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
800
|
+
let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
|
801
|
+
|
802
|
+
let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
|
803
|
+
let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
|
804
|
+
let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
|
805
|
+
|
806
|
+
let(:label1) { Label.new(name: "Atlantic") }
|
807
|
+
let(:label2) { Label.new(name: "Atlantic") }
|
808
|
+
let(:label3) { Label.new(name: "Columbia") }
|
809
|
+
|
810
|
+
before do
|
811
|
+
Band.create!(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1)
|
812
|
+
Band.create!(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2)
|
813
|
+
Band.create!(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3)
|
814
|
+
Band.create!(origin: "tally2", fanatics: fans1, genres: [1, 2])
|
815
|
+
Band.create!(origin: "tally2", fanatics: fans2, genres: [1, 2])
|
816
|
+
Band.create!(origin: "tally2", fanatics: fans3, genres: [1, 3])
|
817
|
+
end
|
818
|
+
|
819
|
+
let(:criteria) { Band.where(origin: "tally") }
|
820
|
+
|
821
|
+
context "when tallying a string" do
|
822
|
+
let(:tally) do
|
823
|
+
criteria.tally(:name)
|
824
|
+
end
|
825
|
+
|
826
|
+
it "returns the correct hash" do
|
827
|
+
expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
context "using an aliased field" do
|
832
|
+
let(:tally) do
|
833
|
+
criteria.tally(:years)
|
834
|
+
end
|
835
|
+
|
836
|
+
it "returns the correct hash" do
|
837
|
+
expect(tally).to eq(30 => 3)
|
838
|
+
end
|
839
|
+
end
|
840
|
+
|
841
|
+
context "when tallying a demongoizable field" do
|
842
|
+
let(:tally) do
|
843
|
+
criteria.tally(:sales)
|
844
|
+
end
|
845
|
+
|
846
|
+
it "returns the correct hash" do
|
847
|
+
expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
|
848
|
+
end
|
849
|
+
end
|
850
|
+
|
851
|
+
context "when tallying a localized field" do
|
852
|
+
before do
|
853
|
+
I18n.locale = :en
|
854
|
+
d1 = Dictionary.create!(description: 'en1')
|
855
|
+
d2 = Dictionary.create!(description: 'en1')
|
856
|
+
d3 = Dictionary.create!(description: 'en1')
|
857
|
+
d4 = Dictionary.create!(description: 'en2')
|
858
|
+
I18n.locale = :de
|
859
|
+
d1.description = 'de1'
|
860
|
+
d2.description = 'de1'
|
861
|
+
d3.description = 'de2'
|
862
|
+
d4.description = 'de3'
|
863
|
+
d1.save!
|
864
|
+
d2.save!
|
865
|
+
d3.save!
|
866
|
+
d4.save!
|
867
|
+
I18n.locale = :en
|
868
|
+
end
|
869
|
+
|
870
|
+
context "when getting the demongoized field" do
|
871
|
+
let(:tallied) do
|
872
|
+
Dictionary.tally(:description)
|
873
|
+
end
|
874
|
+
|
875
|
+
it "returns the translation for the current locale" do
|
876
|
+
expect(tallied).to eq("en1" => 3, "en2" => 1)
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
context "when getting a specific locale" do
|
881
|
+
let(:tallied) do
|
882
|
+
Dictionary.tally("description.de")
|
883
|
+
end
|
884
|
+
|
885
|
+
it "returns the translation for the the specific locale" do
|
886
|
+
expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
|
887
|
+
end
|
888
|
+
end
|
889
|
+
|
890
|
+
context "when getting the full hash" do
|
891
|
+
let(:tallied) do
|
892
|
+
Dictionary.tally("description_translations")
|
893
|
+
end
|
894
|
+
|
895
|
+
it "returns the correct hash" do
|
896
|
+
expect(tallied).to eq(
|
897
|
+
{"de" => "de1", "en" => "en1" } => 2,
|
898
|
+
{"de" => "de2", "en" => "en1" } => 1,
|
899
|
+
{"de" => "de3", "en" => "en2" } => 1
|
900
|
+
)
|
901
|
+
end
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
905
|
+
context "when tallying an embedded localized field" do
|
906
|
+
|
907
|
+
before do
|
908
|
+
I18n.locale = :en
|
909
|
+
address1a = Address.new(name: "en1")
|
910
|
+
address1b = Address.new(name: "en2")
|
911
|
+
address2a = Address.new(name: "en1")
|
912
|
+
address2b = Address.new(name: "en3")
|
913
|
+
I18n.locale = :de
|
914
|
+
address1a.name = "de1"
|
915
|
+
address1b.name = "de2"
|
916
|
+
address2a.name = "de1"
|
917
|
+
address2b.name = "de3"
|
918
|
+
Person.create!(addresses: [ address1a, address1b ])
|
919
|
+
Person.create!(addresses: [ address2a, address2b ])
|
920
|
+
I18n.locale = :en
|
921
|
+
end
|
922
|
+
|
923
|
+
context "when getting the demongoized field" do
|
924
|
+
let(:tallied) do
|
925
|
+
Person.tally("addresses.name")
|
926
|
+
end
|
927
|
+
|
928
|
+
it "returns the translation for the current locale" do
|
929
|
+
expect(tallied).to eq(
|
930
|
+
[ "en1", "en2" ] => 1,
|
931
|
+
[ "en1", "en3" ] => 1,
|
932
|
+
)
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
936
|
+
context "when getting a specific locale" do
|
937
|
+
let(:tallied) do
|
938
|
+
Person.tally("addresses.name.de")
|
939
|
+
end
|
940
|
+
|
941
|
+
it "returns the translation for the the specific locale" do
|
942
|
+
expect(tallied).to eq(
|
943
|
+
[ "de1", "de2" ] => 1,
|
944
|
+
[ "de1", "de3" ] => 1,
|
945
|
+
)
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
context "when getting the full hash" do
|
950
|
+
let(:tallied) do
|
951
|
+
Person.tally("addresses.name_translations")
|
952
|
+
end
|
953
|
+
|
954
|
+
it "returns the correct hash" do
|
955
|
+
expect(tallied).to eq(
|
956
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
|
957
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
|
958
|
+
)
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
end
|
963
|
+
|
964
|
+
context "when tallying an embedded field" do
|
965
|
+
let(:tally) do
|
966
|
+
criteria.tally("label.name")
|
967
|
+
end
|
968
|
+
|
969
|
+
it "returns the correct hash" do
|
970
|
+
expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
context "when tallying an element in an embeds_many field" do
|
975
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
976
|
+
|
977
|
+
let(:tally) do
|
978
|
+
criteria.tally("fanatics.age")
|
979
|
+
end
|
980
|
+
|
981
|
+
it "returns the correct hash" do
|
982
|
+
expect(tally).to eq(
|
983
|
+
[1, 2] => 2,
|
984
|
+
[1, 3] => 1
|
985
|
+
)
|
986
|
+
end
|
987
|
+
end
|
988
|
+
|
989
|
+
context "when tallying an embeds_many field" do
|
990
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
991
|
+
|
992
|
+
let(:tally) do
|
993
|
+
criteria.tally("fanatics")
|
994
|
+
end
|
995
|
+
|
996
|
+
it "returns the correct hash" do
|
997
|
+
expect(tally).to eq(
|
998
|
+
fans1.map(&:attributes) => 1,
|
999
|
+
fans2.map(&:attributes) => 1,
|
1000
|
+
fans3.map(&:attributes) => 1,
|
1001
|
+
)
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
context "when tallying a field of type array" do
|
1006
|
+
let(:criteria) { Band.where(origin: "tally2") }
|
1007
|
+
|
1008
|
+
let(:tally) do
|
1009
|
+
criteria.tally("genres")
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
it "returns the correct hash" do
|
1013
|
+
expect(tally).to eq(
|
1014
|
+
[1, 2] => 2,
|
1015
|
+
[1, 3] => 1
|
1016
|
+
)
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
context "when tallying an element from an array of hashes" do
|
1021
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1022
|
+
|
1023
|
+
let(:tally) do
|
1024
|
+
criteria.tally("genres.x")
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
it "returns the correct hash without the nil keys" do
|
1028
|
+
expect(tally).to eq(
|
1029
|
+
[1, 2] => 2,
|
1030
|
+
[1, 3] => 1
|
1031
|
+
)
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
context "when tallying an element from an array of hashes; with duplicate" do
|
1036
|
+
|
1037
|
+
before do
|
1038
|
+
Band.create!(origin: "tally", genres: [ { x: 1 }, {x: 1} ] )
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1042
|
+
|
1043
|
+
let(:tally) do
|
1044
|
+
criteria.tally("genres.x")
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
it "returns the correct hash without the nil keys" do
|
1048
|
+
expect(tally).to eq(
|
1049
|
+
[1, 2] => 2,
|
1050
|
+
[1, 3] => 1,
|
1051
|
+
[1, 1] => 1,
|
1052
|
+
)
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
context "when tallying an aliased field of type array" do
|
1057
|
+
|
1058
|
+
before do
|
1059
|
+
Person.create!(array: [ 1, 2 ])
|
1060
|
+
Person.create!(array: [ 1, 3 ])
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
let(:tally) do
|
1064
|
+
Person.tally("array")
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
it "returns the correct hash" do
|
1068
|
+
expect(tally).to eq(
|
1069
|
+
[1, 2] => 1,
|
1070
|
+
[1, 3] => 1
|
1071
|
+
)
|
1072
|
+
end
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
context "when going multiple levels deep in arrays" do
|
1076
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1077
|
+
|
1078
|
+
let(:tally) do
|
1079
|
+
criteria.tally("genres.y.z")
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
it "returns the correct hash" do
|
1083
|
+
expect(tally).to eq(
|
1084
|
+
[1, 2] => 2,
|
1085
|
+
[1, 3] => 1
|
1086
|
+
)
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
context "when going multiple levels deep in an array" do
|
1091
|
+
let(:criteria) { Band.where(origin: "tally") }
|
1092
|
+
|
1093
|
+
let(:tally) do
|
1094
|
+
criteria.tally("genres.y.z")
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
it "returns the correct hash" do
|
1098
|
+
expect(tally).to eq(
|
1099
|
+
[1, 2] => 2,
|
1100
|
+
[1, 3] => 1
|
1101
|
+
)
|
1102
|
+
end
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
1106
|
+
|
1107
|
+
before do
|
1108
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1109
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1110
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
let(:tally) do
|
1114
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
it "returns the correct hash" do
|
1118
|
+
expect(tally).to eq(
|
1119
|
+
[ [ 1, 2 ] ] => 2,
|
1120
|
+
[ [ 1, 3 ] ] => 1
|
1121
|
+
)
|
1122
|
+
end
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
1126
|
+
|
1127
|
+
before do
|
1128
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
1129
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1130
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
1131
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
1132
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
|
1133
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
let(:tally) do
|
1137
|
+
Person.tally("addresses.code.deepest.array.y.z")
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
it "returns the correct hash" do
|
1141
|
+
expect(tally).to eq(
|
1142
|
+
[ [ 1, 2 ], [ 1, 2 ] ] => 2,
|
1143
|
+
[ [ 1, 3 ], [ 1, 3 ] ] => 1
|
1144
|
+
)
|
1145
|
+
end
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
context "when some keys are missing" do
|
1149
|
+
before do
|
1150
|
+
3.times { Band.create!(origin: "tally") }
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
let(:tally) do
|
1154
|
+
criteria.tally(:name)
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
it "returns the correct hash" do
|
1158
|
+
expect(tally).to eq(
|
1159
|
+
"Depeche Mode" => 1,
|
1160
|
+
"New Order" => 1,
|
1161
|
+
"10,000 Maniacs" => 1,
|
1162
|
+
nil => 3
|
1163
|
+
)
|
1164
|
+
end
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
context "when the first element is an embeds_one" do
|
1168
|
+
before do
|
1169
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
1170
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
|
1171
|
+
Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
let(:tally) do
|
1175
|
+
Person.tally("name.translations.language")
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
it "returns the correct hash" do
|
1179
|
+
expect(tally).to eq(
|
1180
|
+
[1, 2] => 2,
|
1181
|
+
[1, 3] => 1
|
1182
|
+
)
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
context "when tallying demongoizable values from typeless fields" do
|
1187
|
+
|
1188
|
+
let!(:person1) { Person.create!(ssn: /hello/) }
|
1189
|
+
let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
|
1190
|
+
let(:tally) { Person.tally("ssn") }
|
1191
|
+
|
1192
|
+
let(:tallied_classes) do
|
1193
|
+
tally.keys.map(&:class).sort do |a, b|
|
1194
|
+
a.to_s.casecmp(b.to_s)
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
context "< BSON 5" do
|
1199
|
+
max_bson_version '4.99.99'
|
1200
|
+
|
1201
|
+
it "stores the correct types in the database" do
|
1202
|
+
expect(Person.find(person1.id).attributes["ssn"]).to be_a BSON::Regexp::Raw
|
1203
|
+
expect(Person.find(person2.id).attributes["ssn"]).to be_a BSON::Decimal128
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
it "tallies the correct type" do
|
1207
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1208
|
+
end
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
context '>= BSON 5' do
|
1212
|
+
min_bson_version "5.0"
|
1213
|
+
|
1214
|
+
it "stores the correct types in the database" do
|
1215
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1216
|
+
expect(Person.find(person2.id).ssn).to be_a BigDecimal
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
it "tallies the correct type" do
|
1220
|
+
expect(tallied_classes).to be == [ BigDecimal, BSON::Regexp::Raw ]
|
1221
|
+
end
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
context '>= BSON 5 with decimal128 allowed' do
|
1225
|
+
min_bson_version "5.0"
|
1226
|
+
config_override :allow_bson5_decimal128, true
|
1227
|
+
|
1228
|
+
it "stores the correct types in the database" do
|
1229
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1230
|
+
expect(Person.find(person2.id).ssn).to be_a BSON::Decimal128
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
it "tallies the correct type" do
|
1234
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1235
|
+
end
|
1236
|
+
end
|
1237
|
+
end
|
1238
|
+
end
|
1239
|
+
|
800
1240
|
describe "#each" do
|
801
1241
|
|
802
1242
|
before do
|
@@ -1005,63 +1445,27 @@ describe Mongoid::Contextual::Mongo do
|
|
1005
1445
|
described_class.new(criteria)
|
1006
1446
|
end
|
1007
1447
|
|
1008
|
-
context "when exists? already called" do
|
1448
|
+
context "when exists? already called and query cache is enabled" do
|
1449
|
+
query_cache_enabled
|
1009
1450
|
|
1010
1451
|
before do
|
1011
1452
|
context.exists?
|
1012
1453
|
end
|
1013
1454
|
|
1014
|
-
it "
|
1015
|
-
|
1016
|
-
|
1455
|
+
it "does not hit the database again" do
|
1456
|
+
expect_no_queries do
|
1457
|
+
expect(context).to be_exists
|
1458
|
+
end
|
1017
1459
|
end
|
1018
1460
|
end
|
1019
1461
|
end
|
1462
|
+
end
|
1020
1463
|
|
1021
|
-
|
1464
|
+
describe "#explain" do
|
1022
1465
|
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
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
|
1053
|
-
expect(context).to be_exists
|
1054
|
-
end
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
end
|
1058
|
-
end
|
1059
|
-
|
1060
|
-
describe "#explain" do
|
1061
|
-
|
1062
|
-
let(:criteria) do
|
1063
|
-
Band.where(name: "Depeche Mode")
|
1064
|
-
end
|
1466
|
+
let(:criteria) do
|
1467
|
+
Band.where(name: "Depeche Mode")
|
1468
|
+
end
|
1065
1469
|
|
1066
1470
|
let(:context) do
|
1067
1471
|
described_class.new(criteria)
|
@@ -1408,7 +1812,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1408
1812
|
it "deletes the document from the database" do
|
1409
1813
|
expect {
|
1410
1814
|
depeche.reload
|
1411
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
1815
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
1412
1816
|
end
|
1413
1817
|
|
1414
1818
|
context 'when a collation is specified on the criteria' do
|
@@ -1433,7 +1837,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1433
1837
|
it "deletes the document from the database" do
|
1434
1838
|
expect {
|
1435
1839
|
depeche.reload
|
1436
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
1840
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
|
1437
1841
|
end
|
1438
1842
|
end
|
1439
1843
|
end
|
@@ -1470,203 +1874,687 @@ describe Mongoid::Contextual::Mongo do
|
|
1470
1874
|
Band.create!(name: "New Order")
|
1471
1875
|
end
|
1472
1876
|
|
1473
|
-
|
1877
|
+
let!(:rolling_stones) do
|
1878
|
+
Band.create!(name: "The Rolling Stones")
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
context "when the context is not cached" do
|
1882
|
+
|
1883
|
+
let(:criteria) do
|
1884
|
+
Band.where(name: "Depeche Mode")
|
1885
|
+
end
|
1886
|
+
|
1887
|
+
let(:context) do
|
1888
|
+
described_class.new(criteria)
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
it "returns the first matching document" do
|
1892
|
+
expect(context.send(method)).to eq(depeche_mode)
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
context 'when the criteria has a collation' do
|
1896
|
+
min_server_version '3.4'
|
1897
|
+
|
1898
|
+
let(:criteria) do
|
1899
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
it "returns the first matching document" do
|
1903
|
+
expect(context.send(method)).to eq(depeche_mode)
|
1904
|
+
end
|
1905
|
+
end
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
context "when using .desc" do
|
1909
|
+
|
1910
|
+
let(:criteria) do
|
1911
|
+
Band.desc(:name)
|
1912
|
+
end
|
1913
|
+
|
1914
|
+
let(:context) do
|
1915
|
+
described_class.new(criteria)
|
1916
|
+
end
|
1917
|
+
|
1918
|
+
context "when there is sort on the context" do
|
1919
|
+
|
1920
|
+
it "follows the main sort" do
|
1921
|
+
expect(context.send(method)).to eq(rolling_stones)
|
1922
|
+
end
|
1923
|
+
end
|
1924
|
+
|
1925
|
+
context "when subsequently calling #last" do
|
1926
|
+
|
1927
|
+
it "returns the correct document" do
|
1928
|
+
expect(context.send(method)).to eq(rolling_stones)
|
1929
|
+
expect(context.last).to eq(depeche_mode)
|
1930
|
+
end
|
1931
|
+
end
|
1932
|
+
end
|
1933
|
+
|
1934
|
+
context 'when the criteria has no sort' do
|
1935
|
+
|
1936
|
+
let(:criteria) do
|
1937
|
+
Band.all
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
let(:context) do
|
1941
|
+
described_class.new(criteria)
|
1942
|
+
end
|
1943
|
+
|
1944
|
+
|
1945
|
+
it 'applies a sort on _id' do
|
1946
|
+
expect(context.send(method)).to eq(depeche_mode)
|
1947
|
+
end
|
1948
|
+
|
1949
|
+
context 'when calling #last' do
|
1950
|
+
|
1951
|
+
it 'returns the last document, sorted by _id' do
|
1952
|
+
expect(context.send(method)).to eq(depeche_mode)
|
1953
|
+
expect(context.last).to eq(rolling_stones)
|
1954
|
+
end
|
1955
|
+
end
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
context 'when the criteria has a sort' do
|
1959
|
+
|
1960
|
+
let(:criteria) do
|
1961
|
+
Band.desc(:name)
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
let(:context) do
|
1965
|
+
described_class.new(criteria)
|
1966
|
+
end
|
1967
|
+
|
1968
|
+
it 'applies the criteria sort' do
|
1969
|
+
expect(context.send(method)).to eq(rolling_stones)
|
1970
|
+
end
|
1971
|
+
|
1972
|
+
context 'when calling #last' do
|
1973
|
+
|
1974
|
+
it 'applies the criteria sort' do
|
1975
|
+
expect(context.send(method)).to eq(rolling_stones)
|
1976
|
+
expect(context.last).to eq(depeche_mode)
|
1977
|
+
end
|
1978
|
+
end
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
context "when using .sort" do
|
1982
|
+
|
1983
|
+
let(:criteria) do
|
1984
|
+
Band.all.sort(:name => -1).criteria
|
1985
|
+
end
|
1986
|
+
|
1987
|
+
let(:context) do
|
1988
|
+
described_class.new(criteria)
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
context "when there is sort on the context" do
|
1992
|
+
|
1993
|
+
it "follows the main sort" do
|
1994
|
+
expect(context.send(method)).to eq(rolling_stones)
|
1995
|
+
end
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
context "when subsequently calling #last" do
|
1999
|
+
|
2000
|
+
it "returns the correct document" do
|
2001
|
+
expect(context.send(method)).to eq(rolling_stones)
|
2002
|
+
expect(context.last).to eq(depeche_mode)
|
2003
|
+
end
|
2004
|
+
end
|
2005
|
+
end
|
2006
|
+
|
2007
|
+
context "when the query cache is enabled" do
|
2008
|
+
query_cache_enabled
|
2009
|
+
|
2010
|
+
let(:criteria) do
|
2011
|
+
Band.where(name: "Depeche Mode")
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
let(:context) do
|
2015
|
+
described_class.new(criteria)
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
context "when first method was called before" do
|
2019
|
+
|
2020
|
+
before do
|
2021
|
+
context.first
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
it "returns the first document without touching the database" do
|
2025
|
+
expect_no_queries do
|
2026
|
+
expect(context.send(method)).to eq(depeche_mode)
|
2027
|
+
end
|
2028
|
+
end
|
2029
|
+
end
|
2030
|
+
end
|
2031
|
+
|
2032
|
+
context "when including a limit" do
|
2033
|
+
|
2034
|
+
context "when the context is not cached" do
|
2035
|
+
|
2036
|
+
let(:context) do
|
2037
|
+
described_class.new(criteria)
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
context "when the limit is 1" do
|
2041
|
+
let(:criteria) do
|
2042
|
+
Band.criteria
|
2043
|
+
end
|
2044
|
+
|
2045
|
+
let(:docs) do
|
2046
|
+
context.send(method, 1)
|
2047
|
+
end
|
2048
|
+
|
2049
|
+
it "returns an array of documents" do
|
2050
|
+
expect(docs).to eq([ depeche_mode ])
|
2051
|
+
end
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
context "when the limit is >1" do
|
2055
|
+
let(:criteria) do
|
2056
|
+
Band.criteria
|
2057
|
+
end
|
2058
|
+
|
2059
|
+
let(:docs) do
|
2060
|
+
context.send(method, 2)
|
2061
|
+
end
|
2062
|
+
|
2063
|
+
it "returns the number of documents in order" do
|
2064
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
2065
|
+
end
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
context 'when the criteria has a collation' do
|
2069
|
+
min_server_version '3.4'
|
2070
|
+
|
2071
|
+
let(:criteria) do
|
2072
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
it "returns the first matching document" do
|
2076
|
+
expect(context.send(method, 1)).to eq([ depeche_mode ])
|
2077
|
+
end
|
2078
|
+
end
|
2079
|
+
end
|
2080
|
+
|
2081
|
+
context "when the query cache is enabled" do
|
2082
|
+
|
2083
|
+
let(:context) do
|
2084
|
+
described_class.new(criteria)
|
2085
|
+
end
|
2086
|
+
|
2087
|
+
context "when calling first beforehand" do
|
2088
|
+
query_cache_enabled
|
2089
|
+
|
2090
|
+
let(:context) do
|
2091
|
+
described_class.new(criteria)
|
2092
|
+
end
|
2093
|
+
|
2094
|
+
let(:criteria) do
|
2095
|
+
Band.all
|
2096
|
+
end
|
2097
|
+
|
2098
|
+
before do
|
2099
|
+
context.first(before_limit)
|
2100
|
+
end
|
2101
|
+
|
2102
|
+
let(:docs) do
|
2103
|
+
context.send(method, limit)
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
context "when getting all of the documents before" do
|
2107
|
+
let(:before_limit) { 3 }
|
2108
|
+
|
2109
|
+
context "when getting all of the documents" do
|
2110
|
+
let(:limit) { 3 }
|
2111
|
+
|
2112
|
+
it "returns all documents without touching the database" do
|
2113
|
+
expect_no_queries do
|
2114
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2115
|
+
end
|
2116
|
+
end
|
2117
|
+
end
|
2118
|
+
|
2119
|
+
context "when getting fewer documents" do
|
2120
|
+
let(:limit) { 2 }
|
2121
|
+
|
2122
|
+
it "returns the correct documents without touching the database" do
|
2123
|
+
expect_no_queries do
|
2124
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
2125
|
+
end
|
2126
|
+
end
|
2127
|
+
end
|
2128
|
+
end
|
2129
|
+
|
2130
|
+
context "when getting fewer documents before" do
|
2131
|
+
let(:before_limit) { 2 }
|
2132
|
+
|
2133
|
+
context "when getting the same number of documents" do
|
2134
|
+
let(:limit) { 2 }
|
2135
|
+
|
2136
|
+
it "returns the correct documents without touching the database" do
|
2137
|
+
expect_no_queries do
|
2138
|
+
expect(docs).to eq([ depeche_mode, new_order ])
|
2139
|
+
end
|
2140
|
+
end
|
2141
|
+
end
|
2142
|
+
|
2143
|
+
context "when getting more documents" do
|
2144
|
+
let(:limit) { 3 }
|
2145
|
+
|
2146
|
+
it "returns the correct documents and touches the database" do
|
2147
|
+
expect_query(1) do
|
2148
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2149
|
+
end
|
2150
|
+
end
|
2151
|
+
end
|
2152
|
+
end
|
2153
|
+
|
2154
|
+
context "when getting one document before" do
|
2155
|
+
let(:before_limit) { 1 }
|
2156
|
+
|
2157
|
+
context "when getting one document" do
|
2158
|
+
let(:limit) { 1 }
|
2159
|
+
|
2160
|
+
it "returns the correct documents without touching the database" do
|
2161
|
+
expect_no_queries do
|
2162
|
+
expect(docs).to eq([ depeche_mode ])
|
2163
|
+
end
|
2164
|
+
end
|
2165
|
+
end
|
2166
|
+
|
2167
|
+
context "when getting more than one document" do
|
2168
|
+
let(:limit) { 3 }
|
2169
|
+
|
2170
|
+
it "returns the correct documents and touches the database" do
|
2171
|
+
expect_query(1) do
|
2172
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2173
|
+
end
|
2174
|
+
end
|
2175
|
+
end
|
2176
|
+
end
|
2177
|
+
end
|
2178
|
+
end
|
2179
|
+
end
|
2180
|
+
|
2181
|
+
context "when calling #first then #last and the query cache is enabled" do
|
2182
|
+
query_cache_enabled
|
2183
|
+
|
2184
|
+
let(:context) do
|
2185
|
+
described_class.new(criteria)
|
2186
|
+
end
|
2187
|
+
|
2188
|
+
let(:criteria) do
|
2189
|
+
Band.all
|
2190
|
+
end
|
2191
|
+
|
2192
|
+
before do
|
2193
|
+
context.first(before_limit)
|
2194
|
+
end
|
2195
|
+
|
2196
|
+
let(:docs) do
|
2197
|
+
context.last(limit)
|
2198
|
+
end
|
2199
|
+
|
2200
|
+
context "when getting one from the beginning and one from the end" do
|
2201
|
+
let(:before_limit) { 2 }
|
2202
|
+
let(:limit) { 1 }
|
2203
|
+
|
2204
|
+
it "gets the correct document and hits the database" do
|
2205
|
+
expect_query(1) do
|
2206
|
+
expect(docs).to eq([rolling_stones])
|
2207
|
+
end
|
2208
|
+
end
|
2209
|
+
end
|
2210
|
+
end
|
2211
|
+
end
|
2212
|
+
end
|
2213
|
+
|
2214
|
+
describe "#last" do
|
2215
|
+
let!(:depeche_mode) do
|
2216
|
+
Band.create!(name: "Depeche Mode")
|
2217
|
+
end
|
2218
|
+
|
2219
|
+
let!(:new_order) do
|
2220
|
+
Band.create!(name: "New Order")
|
2221
|
+
end
|
2222
|
+
|
2223
|
+
let!(:rolling_stones) do
|
2224
|
+
Band.create!(name: "The Rolling Stones")
|
2225
|
+
end
|
2226
|
+
|
2227
|
+
context "when the context is not cached" do
|
2228
|
+
|
2229
|
+
let(:criteria) do
|
2230
|
+
Band.where(name: "Depeche Mode")
|
2231
|
+
end
|
2232
|
+
|
2233
|
+
let(:context) do
|
2234
|
+
described_class.new(criteria)
|
2235
|
+
end
|
2236
|
+
|
2237
|
+
it "returns the last matching document" do
|
2238
|
+
expect(context.last).to eq(depeche_mode)
|
2239
|
+
end
|
2240
|
+
|
2241
|
+
context 'when the criteria has a collation' do
|
2242
|
+
min_server_version '3.4'
|
2243
|
+
|
2244
|
+
let(:criteria) do
|
2245
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
2246
|
+
end
|
2247
|
+
|
2248
|
+
it "returns the last matching document" do
|
2249
|
+
expect(context.last).to eq(depeche_mode)
|
2250
|
+
end
|
2251
|
+
end
|
2252
|
+
end
|
2253
|
+
|
2254
|
+
context "when using .desc" do
|
2255
|
+
|
2256
|
+
let(:criteria) do
|
2257
|
+
Band.desc(:name)
|
2258
|
+
end
|
2259
|
+
|
2260
|
+
let(:context) do
|
2261
|
+
described_class.new(criteria)
|
2262
|
+
end
|
2263
|
+
|
2264
|
+
context "when there is sort on the context" do
|
2265
|
+
|
2266
|
+
it "follows the main sort" do
|
2267
|
+
expect(context.last).to eq(depeche_mode)
|
2268
|
+
end
|
2269
|
+
end
|
2270
|
+
|
2271
|
+
context "when subsequently calling #first" do
|
2272
|
+
|
2273
|
+
it "returns the correct document" do
|
2274
|
+
expect(context.last).to eq(depeche_mode)
|
2275
|
+
expect(context.first).to eq(rolling_stones)
|
2276
|
+
end
|
2277
|
+
end
|
2278
|
+
end
|
2279
|
+
|
2280
|
+
context 'when the criteria has no sort' do
|
2281
|
+
|
2282
|
+
let(:criteria) do
|
2283
|
+
Band.all
|
2284
|
+
end
|
2285
|
+
|
2286
|
+
let(:context) do
|
2287
|
+
described_class.new(criteria)
|
2288
|
+
end
|
2289
|
+
|
2290
|
+
it 'applies a sort on _id' do
|
2291
|
+
expect(context.last).to eq(rolling_stones)
|
2292
|
+
end
|
2293
|
+
|
2294
|
+
context 'when calling #first' do
|
2295
|
+
|
2296
|
+
it 'returns the first document, sorted by _id' do
|
2297
|
+
expect(context.last).to eq(rolling_stones)
|
2298
|
+
expect(context.first).to eq(depeche_mode)
|
2299
|
+
end
|
2300
|
+
end
|
2301
|
+
end
|
2302
|
+
|
2303
|
+
context 'when the criteria has a sort' do
|
2304
|
+
|
2305
|
+
let(:criteria) do
|
2306
|
+
Band.desc(:name)
|
2307
|
+
end
|
2308
|
+
|
2309
|
+
let(:context) do
|
2310
|
+
described_class.new(criteria)
|
2311
|
+
end
|
2312
|
+
|
2313
|
+
|
2314
|
+
it 'applies the criteria sort' do
|
2315
|
+
expect(context.last).to eq(depeche_mode)
|
2316
|
+
end
|
2317
|
+
|
2318
|
+
context 'when calling #first' do
|
1474
2319
|
|
1475
|
-
|
1476
|
-
|
2320
|
+
it 'applies the criteria sort' do
|
2321
|
+
expect(context.last).to eq(depeche_mode)
|
2322
|
+
expect(context.first).to eq(rolling_stones)
|
1477
2323
|
end
|
2324
|
+
end
|
2325
|
+
end
|
1478
2326
|
|
1479
|
-
|
1480
|
-
described_class.new(criteria)
|
1481
|
-
end
|
2327
|
+
context "when using .sort" do
|
1482
2328
|
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
2329
|
+
let(:criteria) do
|
2330
|
+
Band.all.sort(:name => -1).criteria
|
2331
|
+
end
|
1486
2332
|
|
1487
|
-
|
1488
|
-
|
2333
|
+
let(:context) do
|
2334
|
+
described_class.new(criteria)
|
2335
|
+
end
|
1489
2336
|
|
1490
|
-
|
1491
|
-
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1492
|
-
end
|
2337
|
+
context "when there is sort on the context" do
|
1493
2338
|
|
1494
|
-
|
1495
|
-
|
1496
|
-
end
|
2339
|
+
it "follows the main sort" do
|
2340
|
+
expect(context.last).to eq(depeche_mode)
|
1497
2341
|
end
|
1498
2342
|
end
|
1499
2343
|
|
1500
|
-
context "when
|
2344
|
+
context "when subsequently calling #first" do
|
1501
2345
|
|
1502
|
-
|
1503
|
-
|
2346
|
+
it "returns the correct document" do
|
2347
|
+
expect(context.last).to eq(depeche_mode)
|
2348
|
+
expect(context.first).to eq(rolling_stones)
|
1504
2349
|
end
|
2350
|
+
end
|
2351
|
+
end
|
1505
2352
|
|
1506
|
-
|
1507
|
-
|
1508
|
-
end
|
2353
|
+
context "when the query cache is enabled" do
|
2354
|
+
query_cache_enabled
|
1509
2355
|
|
1510
|
-
|
2356
|
+
let(:criteria) do
|
2357
|
+
Band.where(name: "Depeche Mode")
|
2358
|
+
end
|
1511
2359
|
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
end
|
2360
|
+
let(:context) do
|
2361
|
+
described_class.new(criteria)
|
2362
|
+
end
|
1516
2363
|
|
1517
|
-
|
2364
|
+
context "when last method was called before" do
|
1518
2365
|
|
1519
|
-
|
1520
|
-
|
2366
|
+
before do
|
2367
|
+
context.last
|
2368
|
+
end
|
2369
|
+
|
2370
|
+
it "returns the last document without touching the database" do
|
2371
|
+
expect_no_queries do
|
1521
2372
|
expect(context.last).to eq(depeche_mode)
|
1522
2373
|
end
|
1523
2374
|
end
|
1524
2375
|
end
|
2376
|
+
end
|
1525
2377
|
|
1526
|
-
|
2378
|
+
context "when including a limit" do
|
1527
2379
|
|
1528
|
-
|
1529
|
-
Band.all
|
1530
|
-
end
|
2380
|
+
context "when the context is not cached" do
|
1531
2381
|
|
1532
2382
|
let(:context) do
|
1533
2383
|
described_class.new(criteria)
|
1534
2384
|
end
|
1535
2385
|
|
2386
|
+
context "when the limit is 1" do
|
2387
|
+
let(:criteria) do
|
2388
|
+
Band.criteria
|
2389
|
+
end
|
1536
2390
|
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
context 'when calling #last' do
|
2391
|
+
let(:docs) do
|
2392
|
+
context.last(1)
|
2393
|
+
end
|
1542
2394
|
|
1543
|
-
it
|
1544
|
-
expect(
|
1545
|
-
expect(context.last).to eq(new_order)
|
2395
|
+
it "returns an array of documents" do
|
2396
|
+
expect(docs).to eq([ rolling_stones ])
|
1546
2397
|
end
|
1547
2398
|
end
|
1548
2399
|
|
1549
|
-
context
|
2400
|
+
context "when the limit is >1" do
|
2401
|
+
let(:criteria) do
|
2402
|
+
Band.criteria
|
2403
|
+
end
|
1550
2404
|
|
1551
|
-
let(:
|
1552
|
-
|
2405
|
+
let(:docs) do
|
2406
|
+
context.last(2)
|
1553
2407
|
end
|
1554
2408
|
|
1555
|
-
it
|
1556
|
-
expect(
|
2409
|
+
it "returns the number of documents in order" do
|
2410
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
1557
2411
|
end
|
2412
|
+
end
|
1558
2413
|
|
1559
|
-
|
2414
|
+
context 'when the criteria has a collation' do
|
2415
|
+
min_server_version '3.4'
|
1560
2416
|
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
2417
|
+
let(:criteria) do
|
2418
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
2419
|
+
end
|
2420
|
+
|
2421
|
+
it "returns the first matching document" do
|
2422
|
+
expect(context.last(1)).to eq([ depeche_mode ])
|
1565
2423
|
end
|
1566
2424
|
end
|
1567
2425
|
end
|
1568
2426
|
|
1569
|
-
context
|
1570
|
-
|
1571
|
-
let(:criteria) do
|
1572
|
-
Band.desc(:name)
|
1573
|
-
end
|
2427
|
+
context "when the context is cached" do
|
1574
2428
|
|
1575
2429
|
let(:context) do
|
1576
2430
|
described_class.new(criteria)
|
1577
2431
|
end
|
1578
2432
|
|
2433
|
+
context "when query cache is enabled" do
|
2434
|
+
query_cache_enabled
|
1579
2435
|
|
1580
|
-
|
1581
|
-
|
1582
|
-
end
|
1583
|
-
|
1584
|
-
context 'when calling #last' do
|
1585
|
-
|
1586
|
-
it 'applies the criteria sort' do
|
1587
|
-
expect(context.send(method)).to eq(new_order)
|
1588
|
-
expect(context.last).to eq(depeche_mode)
|
2436
|
+
let(:context) do
|
2437
|
+
described_class.new(criteria)
|
1589
2438
|
end
|
1590
|
-
end
|
1591
2439
|
|
1592
|
-
|
2440
|
+
let(:criteria) do
|
2441
|
+
Band.all
|
2442
|
+
end
|
1593
2443
|
|
1594
|
-
|
1595
|
-
|
2444
|
+
before do
|
2445
|
+
context.last(before_limit)
|
1596
2446
|
end
|
1597
2447
|
|
1598
|
-
|
1599
|
-
|
2448
|
+
let(:docs) do
|
2449
|
+
context.last(limit)
|
1600
2450
|
end
|
1601
2451
|
|
1602
|
-
context
|
2452
|
+
context "when getting all of the documents before" do
|
2453
|
+
let(:before_limit) { 3 }
|
1603
2454
|
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
2455
|
+
context "when getting all of the documents" do
|
2456
|
+
let(:limit) { 3 }
|
2457
|
+
|
2458
|
+
it "returns all documents without touching the db" do
|
2459
|
+
expect_no_queries do
|
2460
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2461
|
+
end
|
2462
|
+
end
|
2463
|
+
end
|
2464
|
+
|
2465
|
+
context "when getting fewer documents" do
|
2466
|
+
let(:limit) { 2 }
|
2467
|
+
|
2468
|
+
it "returns the correct documents without touching the db" do
|
2469
|
+
expect_no_queries do
|
2470
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
2471
|
+
end
|
2472
|
+
end
|
1607
2473
|
end
|
1608
2474
|
end
|
1609
|
-
end
|
1610
|
-
end
|
1611
2475
|
|
1612
|
-
|
2476
|
+
context "when getting fewer documents before" do
|
2477
|
+
let(:before_limit) { 2 }
|
1613
2478
|
|
1614
|
-
|
1615
|
-
|
1616
|
-
end
|
2479
|
+
context "when getting the same number of documents" do
|
2480
|
+
let(:limit) { 2 }
|
1617
2481
|
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
2482
|
+
it "returns the correct documents without touching the db" do
|
2483
|
+
expect_no_queries do
|
2484
|
+
expect(docs).to eq([ new_order, rolling_stones ])
|
2485
|
+
end
|
2486
|
+
end
|
2487
|
+
end
|
1621
2488
|
|
1622
|
-
|
2489
|
+
context "when getting more documents" do
|
2490
|
+
let(:limit) { 3 }
|
1623
2491
|
|
1624
|
-
|
1625
|
-
|
2492
|
+
it "returns the correct documents and touches the database" do
|
2493
|
+
expect_query(1) do
|
2494
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2495
|
+
end
|
2496
|
+
end
|
2497
|
+
end
|
1626
2498
|
end
|
1627
|
-
end
|
1628
2499
|
|
1629
|
-
|
2500
|
+
context "when getting one document before" do
|
2501
|
+
let(:before_limit) { 1 }
|
1630
2502
|
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
2503
|
+
context "when getting one document" do
|
2504
|
+
let(:limit) { 1 }
|
2505
|
+
|
2506
|
+
it "returns the correct documents without touching the database" do
|
2507
|
+
expect_no_queries do
|
2508
|
+
expect(docs).to eq([ rolling_stones ])
|
2509
|
+
end
|
2510
|
+
end
|
2511
|
+
end
|
2512
|
+
|
2513
|
+
context "when getting more than one document" do
|
2514
|
+
let(:limit) { 3 }
|
2515
|
+
|
2516
|
+
it "returns the correct documents and touches the database" do
|
2517
|
+
expect_query(1) do
|
2518
|
+
expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
|
2519
|
+
end
|
2520
|
+
end
|
2521
|
+
end
|
1634
2522
|
end
|
1635
2523
|
end
|
1636
2524
|
end
|
2525
|
+
end
|
1637
2526
|
|
1638
|
-
|
1639
|
-
|
1640
|
-
let(:criteria) do
|
1641
|
-
Band.where(name: "Depeche Mode").cache
|
1642
|
-
end
|
2527
|
+
context "when calling #last then #first and the query cache is enabled" do
|
2528
|
+
query_cache_enabled
|
1643
2529
|
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
2530
|
+
let(:context) do
|
2531
|
+
described_class.new(criteria)
|
2532
|
+
end
|
1647
2533
|
|
1648
|
-
|
2534
|
+
let(:criteria) do
|
2535
|
+
Band.all
|
2536
|
+
end
|
1649
2537
|
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
2538
|
+
before do
|
2539
|
+
context.last(before_limit)
|
2540
|
+
end
|
1653
2541
|
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
end
|
1658
|
-
end
|
2542
|
+
let(:docs) do
|
2543
|
+
context.first(limit)
|
2544
|
+
end
|
1659
2545
|
|
1660
|
-
|
2546
|
+
context "when getting one from the beginning and one from the end" do
|
2547
|
+
let(:before_limit) { 2 }
|
2548
|
+
let(:limit) { 1 }
|
1661
2549
|
|
1662
|
-
|
1663
|
-
|
2550
|
+
it "hits the database" do
|
2551
|
+
expect_query(1) do
|
2552
|
+
docs
|
1664
2553
|
end
|
2554
|
+
end
|
1665
2555
|
|
1666
|
-
|
1667
|
-
|
1668
|
-
expect(context.send(method)).to eq(depeche_mode)
|
1669
|
-
end
|
2556
|
+
it "gets the correct document" do
|
2557
|
+
expect(docs).to eq([ depeche_mode ])
|
1670
2558
|
end
|
1671
2559
|
end
|
1672
2560
|
end
|
@@ -1718,37 +2606,28 @@ describe Mongoid::Contextual::Mongo do
|
|
1718
2606
|
described_class.new(criteria)
|
1719
2607
|
end
|
1720
2608
|
|
1721
|
-
|
1722
|
-
|
1723
|
-
end
|
2609
|
+
context "when broken_view_options is false" do
|
2610
|
+
driver_config_override :broken_view_options, false
|
1724
2611
|
|
1725
|
-
|
1726
|
-
|
1727
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
1728
|
-
2.times { expect(context.send(method)).to eq(2) }
|
2612
|
+
it "returns the number of documents that match" do
|
2613
|
+
expect(context.send(method)).to eq(1)
|
1729
2614
|
end
|
1730
2615
|
end
|
1731
2616
|
|
1732
|
-
context "when
|
1733
|
-
|
1734
|
-
before do
|
1735
|
-
context.entries
|
1736
|
-
end
|
2617
|
+
context "when broken_view_options is true" do
|
2618
|
+
driver_config_override :broken_view_options, true
|
1737
2619
|
|
1738
|
-
it "returns the
|
1739
|
-
expect(context.view).to receive(:count_documents).once.and_return(2)
|
2620
|
+
it "returns the number of documents that match" do
|
1740
2621
|
expect(context.send(method)).to eq(2)
|
1741
2622
|
end
|
2623
|
+
end
|
1742
2624
|
|
1743
|
-
|
1744
|
-
|
1745
|
-
before do
|
1746
|
-
context.entries
|
1747
|
-
end
|
2625
|
+
context "when calling more than once with different limits" do
|
2626
|
+
driver_config_override :broken_view_options, false
|
1748
2627
|
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
2628
|
+
it "does not cache the value" do
|
2629
|
+
expect(context.limit(1).send(method)).to eq(1)
|
2630
|
+
expect(context.limit(2).send(method)).to eq(2)
|
1752
2631
|
end
|
1753
2632
|
end
|
1754
2633
|
end
|
@@ -1767,10 +2646,12 @@ describe Mongoid::Contextual::Mongo do
|
|
1767
2646
|
expect(context.send(method)).to eq(1)
|
1768
2647
|
end
|
1769
2648
|
|
1770
|
-
context "when calling more than once" do
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
2649
|
+
context "when calling more than once with different skips" do
|
2650
|
+
driver_config_override :broken_view_options, false
|
2651
|
+
|
2652
|
+
it "does not cache the value" do
|
2653
|
+
expect(context.skip(0).send(method)).to eq(1)
|
2654
|
+
expect(context.skip(1).send(method)).to eq(0)
|
1774
2655
|
end
|
1775
2656
|
end
|
1776
2657
|
|
@@ -1823,6 +2704,80 @@ describe Mongoid::Contextual::Mongo do
|
|
1823
2704
|
end
|
1824
2705
|
end
|
1825
2706
|
|
2707
|
+
describe "#take" do
|
2708
|
+
|
2709
|
+
let!(:depeche_mode) do
|
2710
|
+
Band.create!(name: "Depeche Mode")
|
2711
|
+
end
|
2712
|
+
|
2713
|
+
let!(:new_order) do
|
2714
|
+
Band.create!(name: "New Order")
|
2715
|
+
end
|
2716
|
+
|
2717
|
+
let!(:rolling_stones) do
|
2718
|
+
Band.create!(name: "The Rolling Stones")
|
2719
|
+
end
|
2720
|
+
|
2721
|
+
let(:criteria) do
|
2722
|
+
Band.all
|
2723
|
+
end
|
2724
|
+
|
2725
|
+
let(:context) do
|
2726
|
+
described_class.new(criteria)
|
2727
|
+
end
|
2728
|
+
|
2729
|
+
it "takes the correct number results" do
|
2730
|
+
expect(context.take(2)).to eq([ depeche_mode, new_order ])
|
2731
|
+
end
|
2732
|
+
|
2733
|
+
it "returns an array when passing 1" do
|
2734
|
+
expect(context.take(1)).to eq([ depeche_mode ])
|
2735
|
+
end
|
2736
|
+
|
2737
|
+
it "does not return an array when not passing an argument" do
|
2738
|
+
expect(context.take).to eq(depeche_mode)
|
2739
|
+
end
|
2740
|
+
|
2741
|
+
it "returns all the documents taking more than whats in the db" do
|
2742
|
+
expect(context.take(5)).to eq([ depeche_mode, new_order, rolling_stones ])
|
2743
|
+
end
|
2744
|
+
end
|
2745
|
+
|
2746
|
+
describe "#take!" do
|
2747
|
+
|
2748
|
+
let!(:depeche_mode) do
|
2749
|
+
Band.create!(name: "Depeche Mode")
|
2750
|
+
end
|
2751
|
+
|
2752
|
+
let!(:new_order) do
|
2753
|
+
Band.create!(name: "New Order")
|
2754
|
+
end
|
2755
|
+
|
2756
|
+
let!(:rolling_stones) do
|
2757
|
+
Band.create!(name: "The Rolling Stones")
|
2758
|
+
end
|
2759
|
+
|
2760
|
+
let(:criteria) do
|
2761
|
+
Band.all
|
2762
|
+
end
|
2763
|
+
|
2764
|
+
let(:context) do
|
2765
|
+
described_class.new(criteria)
|
2766
|
+
end
|
2767
|
+
|
2768
|
+
it "takes the first document" do
|
2769
|
+
expect(context.take!).to eq(depeche_mode)
|
2770
|
+
end
|
2771
|
+
|
2772
|
+
context "when there are no documents" do
|
2773
|
+
it "raises an error" do
|
2774
|
+
expect do
|
2775
|
+
Person.take!
|
2776
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Person./)
|
2777
|
+
end
|
2778
|
+
end
|
2779
|
+
end
|
2780
|
+
|
1826
2781
|
describe "#map" do
|
1827
2782
|
|
1828
2783
|
before do
|
@@ -1840,8 +2795,10 @@ describe Mongoid::Contextual::Mongo do
|
|
1840
2795
|
|
1841
2796
|
context "when passed the symbol field name" do
|
1842
2797
|
|
1843
|
-
it "
|
1844
|
-
expect
|
2798
|
+
it "raises an error" do
|
2799
|
+
expect do
|
2800
|
+
context.map(:name)
|
2801
|
+
end.to raise_error(ArgumentError)
|
1845
2802
|
end
|
1846
2803
|
end
|
1847
2804
|
|
@@ -2616,16 +3573,65 @@ describe Mongoid::Contextual::Mongo do
|
|
2616
3573
|
|
2617
3574
|
context "when the attributes are in the correct type" do
|
2618
3575
|
|
3576
|
+
context "when operation is $set" do
|
3577
|
+
|
3578
|
+
before do
|
3579
|
+
context.update_all("$set" => { name: "Smiths" })
|
3580
|
+
end
|
3581
|
+
|
3582
|
+
it "updates the first matching document" do
|
3583
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3584
|
+
end
|
3585
|
+
|
3586
|
+
it "updates the last matching document" do
|
3587
|
+
expect(new_order.reload.name).to eq("Smiths")
|
3588
|
+
end
|
3589
|
+
end
|
3590
|
+
|
3591
|
+
context "when operation is $push" do
|
3592
|
+
|
3593
|
+
before do
|
3594
|
+
depeche_mode.update_attribute(:genres, ["electronic"])
|
3595
|
+
new_order.update_attribute(:genres, ["electronic"])
|
3596
|
+
context.update_all("$push" => { genres: "pop" })
|
3597
|
+
end
|
3598
|
+
|
3599
|
+
it "updates the first matching document" do
|
3600
|
+
expect(depeche_mode.reload.genres).to eq(["electronic", "pop"])
|
3601
|
+
end
|
3602
|
+
|
3603
|
+
it "updates the last matching document" do
|
3604
|
+
expect(new_order.reload.genres).to eq(["electronic", "pop"])
|
3605
|
+
end
|
3606
|
+
end
|
3607
|
+
|
3608
|
+
context "when operation is $addToSet" do
|
3609
|
+
|
3610
|
+
before do
|
3611
|
+
context.update_all("$addToSet" => { genres: "electronic" })
|
3612
|
+
end
|
3613
|
+
|
3614
|
+
it "updates the first matching document" do
|
3615
|
+
expect(depeche_mode.reload.genres).to eq(["electronic"])
|
3616
|
+
end
|
3617
|
+
|
3618
|
+
it "updates the last matching document" do
|
3619
|
+
expect(new_order.reload.genres).to eq(["electronic"])
|
3620
|
+
end
|
3621
|
+
end
|
3622
|
+
end
|
3623
|
+
|
3624
|
+
context 'when using aliased field names' do
|
2619
3625
|
before do
|
2620
|
-
context.update_all(
|
3626
|
+
context.update_all('$set' => { years: 100 })
|
2621
3627
|
end
|
2622
3628
|
|
2623
3629
|
it "updates the first matching document" do
|
2624
|
-
expect(depeche_mode.reload.
|
3630
|
+
expect(depeche_mode.reload.years).to eq(100)
|
2625
3631
|
end
|
2626
3632
|
|
2627
3633
|
it "updates the last matching document" do
|
2628
|
-
expect(new_order.reload.
|
3634
|
+
expect(new_order.reload.years).to eq(100)
|
2629
3635
|
end
|
2630
3636
|
end
|
2631
3637
|
|