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
@@ -379,36 +379,77 @@ describe Mongoid::Contextual::Memory do
|
|
379
379
|
|
380
380
|
describe "#distinct" do
|
381
381
|
|
382
|
-
|
383
|
-
|
384
|
-
end
|
382
|
+
context "when legacy_pluck_distinct is true" do
|
383
|
+
config_override :legacy_pluck_distinct, true
|
385
384
|
|
386
|
-
|
387
|
-
|
388
|
-
|
385
|
+
let(:hobrecht) do
|
386
|
+
Address.new(street: "hobrecht")
|
387
|
+
end
|
388
|
+
|
389
|
+
let(:friedel) do
|
390
|
+
Address.new(street: "friedel")
|
391
|
+
end
|
389
392
|
|
390
|
-
|
393
|
+
context "when limiting the result set" do
|
391
394
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
+
let(:criteria) do
|
396
|
+
Address.where(street: "hobrecht").tap do |crit|
|
397
|
+
crit.documents = [ hobrecht, hobrecht, friedel ]
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
let(:context) do
|
402
|
+
described_class.new(criteria)
|
403
|
+
end
|
404
|
+
|
405
|
+
it "returns the distinct field values" do
|
406
|
+
expect(context.distinct(:street)).to eq([ "hobrecht" ])
|
395
407
|
end
|
396
408
|
end
|
397
409
|
|
398
|
-
|
399
|
-
|
410
|
+
context "when not limiting the result set" do
|
411
|
+
|
412
|
+
let(:criteria) do
|
413
|
+
Address.all.tap do |crit|
|
414
|
+
crit.documents = [ hobrecht, friedel, friedel ]
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
let(:context) do
|
419
|
+
described_class.new(criteria)
|
420
|
+
end
|
421
|
+
|
422
|
+
it "returns the distinct field values" do
|
423
|
+
expect(context.distinct(:street)).to eq([ "hobrecht", "friedel" ])
|
424
|
+
end
|
400
425
|
end
|
401
426
|
|
402
|
-
|
403
|
-
|
427
|
+
context 'when there is a collation on the criteria' do
|
428
|
+
|
429
|
+
let(:criteria) do
|
430
|
+
Address.where(street: "hobrecht").tap do |crit|
|
431
|
+
crit.documents = [ hobrecht, hobrecht, friedel ]
|
432
|
+
end.collation(locale: 'en_US', strength: 2)
|
433
|
+
end
|
434
|
+
|
435
|
+
it "raises an exception" do
|
436
|
+
expect {
|
437
|
+
context.distinct(:street)
|
438
|
+
}.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
|
439
|
+
end
|
404
440
|
end
|
405
441
|
end
|
406
442
|
|
407
|
-
context "when
|
443
|
+
context "when legacy_pluck_distinct is false" do
|
444
|
+
config_override :legacy_pluck_distinct, false
|
445
|
+
|
446
|
+
let(:depeche) { Band.create!(name: "Depeche Mode", years: 30, sales: "1E2") }
|
447
|
+
let(:new_order) { Band.create!(name: "New Order", years: 25, sales: "2E3") }
|
448
|
+
let(:maniacs) { Band.create!(name: "10,000 Maniacs", years: 20, sales: "1E2") }
|
408
449
|
|
409
450
|
let(:criteria) do
|
410
|
-
|
411
|
-
crit.documents = [
|
451
|
+
Band.all.tap do |crit|
|
452
|
+
crit.documents = [ depeche, new_order, maniacs ]
|
412
453
|
end
|
413
454
|
end
|
414
455
|
|
@@ -416,23 +457,180 @@ describe Mongoid::Contextual::Memory do
|
|
416
457
|
described_class.new(criteria)
|
417
458
|
end
|
418
459
|
|
419
|
-
|
420
|
-
|
460
|
+
context "when limiting the result set" do
|
461
|
+
|
462
|
+
let(:criteria) do
|
463
|
+
Band.where(name: "Depeche Mode").tap do |crit|
|
464
|
+
crit.documents = [ depeche ]
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
it "returns the distinct matching fields" do
|
469
|
+
expect(context.distinct(:name)).to eq([ "Depeche Mode" ])
|
470
|
+
end
|
421
471
|
end
|
422
|
-
end
|
423
472
|
|
424
|
-
|
473
|
+
context "when not limiting the result set" do
|
425
474
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
end.collation(locale: 'en_US', strength: 2)
|
475
|
+
it "returns the distinct field values" do
|
476
|
+
expect(context.distinct(:name).sort).to eq([ "10,000 Maniacs", "Depeche Mode", "New Order" ].sort)
|
477
|
+
end
|
430
478
|
end
|
431
479
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
480
|
+
context "when providing an aliased field" do
|
481
|
+
|
482
|
+
it "returns the distinct field values" do
|
483
|
+
expect(context.distinct(:years).sort).to eq([ 20, 25, 30 ])
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
context "when providing a demongoizable field" do
|
488
|
+
|
489
|
+
it "returns the non-demongoized distinct field values" do
|
490
|
+
expect(context.distinct(:sales).sort).to eq([ BigDecimal("1E2"), BigDecimal("2E3") ])
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
context "when getting a localized field" do
|
495
|
+
before do
|
496
|
+
I18n.locale = :en
|
497
|
+
d = Dictionary.create!(description: 'english-text')
|
498
|
+
I18n.locale = :de
|
499
|
+
d.description = 'deutsch-text'
|
500
|
+
d.save!
|
501
|
+
end
|
502
|
+
|
503
|
+
after do
|
504
|
+
I18n.locale = :en
|
505
|
+
end
|
506
|
+
|
507
|
+
let(:criteria) do
|
508
|
+
Dictionary.all.tap do |crit|
|
509
|
+
crit.documents = [ Dictionary.first ]
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
context "when getting the field without _translations" do
|
514
|
+
it "gets the demongoized localized field" do
|
515
|
+
expect(context.distinct(:description)).to eq([ 'deutsch-text' ])
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
context "when getting the field with _translations" do
|
520
|
+
|
521
|
+
it "gets the full hash" do
|
522
|
+
expect(context.distinct(:description_translations)).to eq([ { "de" => "deutsch-text", "en" => "english-text" } ])
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
context 'when plucking a specific locale' do
|
527
|
+
|
528
|
+
let(:distinct) do
|
529
|
+
context.distinct(:'description.de')
|
530
|
+
end
|
531
|
+
|
532
|
+
it 'returns the specific translation' do
|
533
|
+
expect(distinct).to eq([ "deutsch-text" ])
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
context 'when plucking a specific locale from _translations field' do
|
538
|
+
|
539
|
+
let(:distinct) do
|
540
|
+
context.distinct(:'description_translations.de')
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'returns the specific translations' do
|
544
|
+
expect(distinct).to eq(['deutsch-text'])
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
context 'when fallbacks are enabled with a locale list' do
|
549
|
+
with_i18n_fallbacks
|
550
|
+
|
551
|
+
around(:all) do |example|
|
552
|
+
prev_fallbacks = I18n.fallbacks.dup
|
553
|
+
I18n.fallbacks[:he] = [ :en ]
|
554
|
+
example.run
|
555
|
+
I18n.fallbacks = prev_fallbacks
|
556
|
+
end
|
557
|
+
|
558
|
+
after do
|
559
|
+
I18n.locale = :en
|
560
|
+
end
|
561
|
+
|
562
|
+
let(:distinct) do
|
563
|
+
context.distinct(:description).first
|
564
|
+
end
|
565
|
+
|
566
|
+
it "correctly uses the fallback" do
|
567
|
+
I18n.locale = :en
|
568
|
+
Dictionary.create!(description: 'english-text')
|
569
|
+
I18n.locale = :he
|
570
|
+
distinct.should == "english-text"
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
context "when the localized field is embedded" do
|
575
|
+
let(:person) do
|
576
|
+
p = Passport.new
|
577
|
+
I18n.locale = :en
|
578
|
+
p.name = "Neil"
|
579
|
+
I18n.locale = :he
|
580
|
+
p.name = "Nissim"
|
581
|
+
|
582
|
+
Person.create!(passport: p, employer_id: 12345)
|
583
|
+
end
|
584
|
+
|
585
|
+
after do
|
586
|
+
I18n.locale = :en
|
587
|
+
end
|
588
|
+
|
589
|
+
let(:criteria) do
|
590
|
+
Person.where(employer_id: 12345).tap do |crit|
|
591
|
+
crit.documents = [ person ]
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
let(:distinct) do
|
596
|
+
context.distinct("pass.name").first
|
597
|
+
end
|
598
|
+
|
599
|
+
let(:distinct_translations) do
|
600
|
+
context.distinct("pass.name_translations").first
|
601
|
+
end
|
602
|
+
|
603
|
+
let(:distinct_translations_field) do
|
604
|
+
context.distinct("pass.name_translations.en").first
|
605
|
+
end
|
606
|
+
|
607
|
+
it "returns the translation for the current locale" do
|
608
|
+
expect(distinct).to eq("Nissim")
|
609
|
+
end
|
610
|
+
|
611
|
+
it "returns the full _translation hash" do
|
612
|
+
expect(distinct_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
|
613
|
+
end
|
614
|
+
|
615
|
+
it "returns the translation for the requested locale" do
|
616
|
+
expect(distinct_translations_field).to eq("Neil")
|
617
|
+
end
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
context "when getting an embedded field" do
|
622
|
+
|
623
|
+
let(:label) { Label.new(sales: "1E2") }
|
624
|
+
let!(:band) { Band.create!(label: label) }
|
625
|
+
let(:criteria) do
|
626
|
+
Band.where(_id: band.id).tap do |crit|
|
627
|
+
crit.documents = [ band ]
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
it "returns the distinct matching fields" do
|
632
|
+
expect(context.distinct("label.sales")).to eq([ BigDecimal("1E2") ])
|
633
|
+
end
|
436
634
|
end
|
437
635
|
end
|
438
636
|
end
|
@@ -624,6 +822,14 @@ describe Mongoid::Contextual::Memory do
|
|
624
822
|
expect(context.send(method)).to eq(hobrecht)
|
625
823
|
end
|
626
824
|
|
825
|
+
it "returns a list when passing a limit" do
|
826
|
+
expect(context.send(method, 2)).to eq([ hobrecht, friedel ])
|
827
|
+
end
|
828
|
+
|
829
|
+
it "returns a list when passing 1" do
|
830
|
+
expect(context.send(method, 1)).to eq([ hobrecht ])
|
831
|
+
end
|
832
|
+
|
627
833
|
context 'when there is a collation on the criteria' do
|
628
834
|
|
629
835
|
let(:criteria) do
|
@@ -641,6 +847,108 @@ describe Mongoid::Contextual::Memory do
|
|
641
847
|
end
|
642
848
|
end
|
643
849
|
|
850
|
+
describe "#take" do
|
851
|
+
|
852
|
+
let(:hobrecht) do
|
853
|
+
Address.new(street: "hobrecht")
|
854
|
+
end
|
855
|
+
|
856
|
+
let(:friedel) do
|
857
|
+
Address.new(street: "friedel")
|
858
|
+
end
|
859
|
+
|
860
|
+
let(:criteria) do
|
861
|
+
Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
|
862
|
+
crit.documents = [ hobrecht, friedel ]
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
let(:context) do
|
867
|
+
described_class.new(criteria)
|
868
|
+
end
|
869
|
+
|
870
|
+
it "returns the first matching document" do
|
871
|
+
expect(context.take).to eq(hobrecht)
|
872
|
+
end
|
873
|
+
|
874
|
+
it "returns an array when passing a limit" do
|
875
|
+
expect(context.take(2)).to eq([ hobrecht, friedel ])
|
876
|
+
end
|
877
|
+
|
878
|
+
it "returns an array when passing a limit as 1" do
|
879
|
+
expect(context.take(1)).to eq([ hobrecht ])
|
880
|
+
end
|
881
|
+
|
882
|
+
context 'when there is a collation on the criteria' do
|
883
|
+
|
884
|
+
let(:criteria) do
|
885
|
+
Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
|
886
|
+
crit.documents = [ hobrecht, friedel ]
|
887
|
+
end.collation(locale: 'en_US', strength: 2)
|
888
|
+
end
|
889
|
+
|
890
|
+
it "raises an exception" do
|
891
|
+
expect {
|
892
|
+
context.take
|
893
|
+
}.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
897
|
+
|
898
|
+
describe "#take!" do
|
899
|
+
|
900
|
+
let(:hobrecht) do
|
901
|
+
Address.new(street: "hobrecht")
|
902
|
+
end
|
903
|
+
|
904
|
+
let(:friedel) do
|
905
|
+
Address.new(street: "friedel")
|
906
|
+
end
|
907
|
+
|
908
|
+
let(:criteria) do
|
909
|
+
Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
|
910
|
+
crit.documents = [ hobrecht, friedel ]
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
let(:context) do
|
915
|
+
described_class.new(criteria)
|
916
|
+
end
|
917
|
+
|
918
|
+
it "returns the first matching document" do
|
919
|
+
expect(context.take!).to eq(hobrecht)
|
920
|
+
end
|
921
|
+
|
922
|
+
context "when the criteria is empty" do
|
923
|
+
let(:criteria) do
|
924
|
+
Address.where(street: "bogus").tap do |crit|
|
925
|
+
crit.documents = []
|
926
|
+
end
|
927
|
+
end
|
928
|
+
|
929
|
+
it "raise an error" do
|
930
|
+
expect do
|
931
|
+
context.take!
|
932
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Address./)
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
936
|
+
context 'when there is a collation on the criteria' do
|
937
|
+
|
938
|
+
let(:criteria) do
|
939
|
+
Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
|
940
|
+
crit.documents = [ hobrecht, friedel ]
|
941
|
+
end.collation(locale: 'en_US', strength: 2)
|
942
|
+
end
|
943
|
+
|
944
|
+
it "raises an exception" do
|
945
|
+
expect {
|
946
|
+
context.take
|
947
|
+
}.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
|
948
|
+
end
|
949
|
+
end
|
950
|
+
end
|
951
|
+
|
644
952
|
describe "#initialize" do
|
645
953
|
|
646
954
|
context "when the criteria has no options" do
|
@@ -766,6 +1074,14 @@ describe Mongoid::Contextual::Memory do
|
|
766
1074
|
expect(context.last).to eq(friedel)
|
767
1075
|
end
|
768
1076
|
|
1077
|
+
it "returns a list when a limit is passed" do
|
1078
|
+
expect(context.last(2)).to eq([ hobrecht, friedel ])
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
it "returns a list when the limit is 1" do
|
1082
|
+
expect(context.last(1)).to eq([ friedel ])
|
1083
|
+
end
|
1084
|
+
|
769
1085
|
context 'when there is a collation on the criteria' do
|
770
1086
|
|
771
1087
|
let(:criteria) do
|
@@ -919,72 +1235,1023 @@ describe Mongoid::Contextual::Memory do
|
|
919
1235
|
|
920
1236
|
describe "#pluck" do
|
921
1237
|
|
922
|
-
let(:hobrecht) do
|
923
|
-
Address.new(street: "hobrecht")
|
924
|
-
end
|
925
|
-
|
926
|
-
let(:friedel) do
|
927
|
-
Address.new(street: "friedel")
|
928
|
-
end
|
929
|
-
|
930
|
-
let(:criteria) do
|
931
|
-
Address.all.tap do |crit|
|
932
|
-
crit.documents = [ hobrecht, friedel ]
|
933
|
-
end
|
934
|
-
end
|
935
|
-
|
936
1238
|
let(:context) do
|
937
1239
|
described_class.new(criteria)
|
938
1240
|
end
|
939
1241
|
|
940
|
-
context "when
|
1242
|
+
context "when legacy_pluck_distinct is true" do
|
1243
|
+
config_override :legacy_pluck_distinct, true
|
941
1244
|
|
942
|
-
let
|
943
|
-
|
1245
|
+
let(:hobrecht) do
|
1246
|
+
Address.new(street: "hobrecht")
|
944
1247
|
end
|
945
1248
|
|
946
|
-
|
947
|
-
|
1249
|
+
let(:friedel) do
|
1250
|
+
Address.new(street: "friedel")
|
948
1251
|
end
|
949
|
-
end
|
950
1252
|
|
951
|
-
|
1253
|
+
let(:criteria) do
|
1254
|
+
Address.all.tap do |crit|
|
1255
|
+
crit.documents = [ hobrecht, friedel ]
|
1256
|
+
end
|
1257
|
+
end
|
952
1258
|
|
953
|
-
context "when
|
1259
|
+
context "when plucking" do
|
954
1260
|
|
955
|
-
let(:plucked) do
|
956
|
-
context.pluck(:
|
1261
|
+
let!(:plucked) do
|
1262
|
+
context.pluck(:street)
|
957
1263
|
end
|
958
1264
|
|
959
|
-
it "returns
|
960
|
-
expect(plucked).to eq([])
|
1265
|
+
it "returns the values" do
|
1266
|
+
expect(plucked).to eq([ "hobrecht", "friedel" ])
|
961
1267
|
end
|
962
1268
|
end
|
963
1269
|
|
964
|
-
context "when
|
1270
|
+
context "when plucking a mix of empty and non-empty values" do
|
965
1271
|
|
966
|
-
let(:
|
967
|
-
|
1272
|
+
let(:empty_doc) do
|
1273
|
+
Address.new(street: nil)
|
968
1274
|
end
|
969
1275
|
|
970
|
-
|
971
|
-
|
972
|
-
|
1276
|
+
let(:criteria) do
|
1277
|
+
Address.all.tap do |crit|
|
1278
|
+
crit.documents = [ hobrecht, friedel, empty_doc ]
|
1279
|
+
end
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
let!(:plucked) do
|
1283
|
+
context.pluck(:street)
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
it "returns the values" do
|
1287
|
+
expect(plucked).to eq([ "hobrecht", "friedel", nil ])
|
1288
|
+
end
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
context "when plucking a field that doesnt exist" do
|
1292
|
+
|
1293
|
+
context "when pluck one field" do
|
1294
|
+
|
1295
|
+
let(:plucked) do
|
1296
|
+
context.pluck(:foo)
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
it "returns a empty array" do
|
1300
|
+
expect(plucked).to eq([nil, nil])
|
1301
|
+
end
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
context "when pluck multiple fields" do
|
1305
|
+
|
1306
|
+
let(:plucked) do
|
1307
|
+
context.pluck(:foo, :bar)
|
1308
|
+
end
|
1309
|
+
|
1310
|
+
it "returns a empty array" do
|
1311
|
+
expect(plucked).to eq([[nil, nil], [nil, nil]])
|
1312
|
+
end
|
1313
|
+
end
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
context 'when there is a collation on the criteria' do
|
1317
|
+
|
1318
|
+
let(:criteria) do
|
1319
|
+
Address.all.tap do |crit|
|
1320
|
+
crit.documents = [ hobrecht, friedel ]
|
1321
|
+
end.collation(locale: 'en_US', strength: 2)
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
it "raises an exception" do
|
1325
|
+
expect {
|
1326
|
+
context.pluck(:foo, :bar)
|
1327
|
+
}.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
|
1328
|
+
end
|
973
1329
|
end
|
974
1330
|
end
|
975
1331
|
|
976
|
-
context
|
1332
|
+
context "when legacy_pluck_distinct is false" do
|
1333
|
+
config_override :legacy_pluck_distinct, false
|
1334
|
+
|
1335
|
+
let!(:depeche) do
|
1336
|
+
Band.create!(name: "Depeche Mode", likes: 3)
|
1337
|
+
end
|
1338
|
+
|
1339
|
+
let!(:tool) do
|
1340
|
+
Band.create!(name: "Tool", likes: 3)
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
let!(:photek) do
|
1344
|
+
Band.create!(name: "Photek", likes: 1)
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
let!(:maniacs) do
|
1348
|
+
Band.create!(name: "10,000 Maniacs", likes: 1, sales: "1E2")
|
1349
|
+
end
|
977
1350
|
|
978
1351
|
let(:criteria) do
|
979
|
-
|
980
|
-
crit.documents = [
|
981
|
-
end
|
1352
|
+
Band.all.tap do |crit|
|
1353
|
+
crit.documents = [ depeche, tool, photek, maniacs ]
|
1354
|
+
end
|
982
1355
|
end
|
983
1356
|
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
1357
|
+
context "when the field is aliased" do
|
1358
|
+
|
1359
|
+
let!(:expensive) do
|
1360
|
+
Product.create!(price: 100000)
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
let!(:cheap) do
|
1364
|
+
Product.create!(price: 1)
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
let(:criteria) do
|
1368
|
+
Product.all.tap do |crit|
|
1369
|
+
crit.documents = [ expensive, cheap ]
|
1370
|
+
end
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
context "when using alias_attribute" do
|
1374
|
+
|
1375
|
+
let(:plucked) do
|
1376
|
+
context.pluck(:price)
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
it "uses the aliases" do
|
1380
|
+
expect(plucked).to eq([ 100000, 1 ])
|
1381
|
+
end
|
1382
|
+
end
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
context "when the criteria matches" do
|
1386
|
+
|
1387
|
+
context "when there are no duplicate values" do
|
1388
|
+
|
1389
|
+
let!(:plucked) do
|
1390
|
+
context.pluck(:name)
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
it "returns the values" do
|
1394
|
+
expect(plucked).to contain_exactly("10,000 Maniacs", "Depeche Mode", "Tool", "Photek")
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
context "when subsequently executing the criteria without a pluck" do
|
1398
|
+
|
1399
|
+
it "does not limit the fields" do
|
1400
|
+
expect(context.first.likes).to eq(3)
|
1401
|
+
end
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
context 'when the field is a subdocument' do
|
1405
|
+
|
1406
|
+
context 'when a top-level field and a subdocument field are plucked' do
|
1407
|
+
let(:criteria) do
|
1408
|
+
Band.where(name: 'FKA Twigs').tap do |crit|
|
1409
|
+
crit.documents = [
|
1410
|
+
Band.create!(name: 'FKA Twigs'),
|
1411
|
+
Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
|
1412
|
+
]
|
1413
|
+
end
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
let(:embedded_pluck) do
|
1417
|
+
context.pluck(:name, 'records.name')
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
let(:expected) do
|
1421
|
+
[
|
1422
|
+
["FKA Twigs", []],
|
1423
|
+
['FKA Twigs', ["LP1"]]
|
1424
|
+
]
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
it 'returns the list of top-level field and subdocument values' do
|
1428
|
+
expect(embedded_pluck).to eq(expected)
|
1429
|
+
end
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
context 'when only a subdocument field is plucked' do
|
1433
|
+
|
1434
|
+
let(:criteria) do
|
1435
|
+
Band.where(name: 'FKA Twigs').tap do |crit|
|
1436
|
+
crit.documents = [
|
1437
|
+
Band.create!(name: 'FKA Twigs'),
|
1438
|
+
Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
|
1439
|
+
]
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
let(:embedded_pluck) do
|
1444
|
+
context.pluck('records.name')
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
let(:expected) do
|
1448
|
+
[
|
1449
|
+
[],
|
1450
|
+
["LP1"]
|
1451
|
+
]
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
it 'returns the list of subdocument values' do
|
1455
|
+
expect(embedded_pluck).to eq(expected)
|
1456
|
+
end
|
1457
|
+
end
|
1458
|
+
end
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
context "when plucking multi-fields" do
|
1462
|
+
|
1463
|
+
let(:plucked) do
|
1464
|
+
context.pluck(:name, :likes)
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
it "returns the values" do
|
1468
|
+
expect(plucked).to contain_exactly(["10,000 Maniacs", 1], ["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
|
1469
|
+
end
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
context "when there are duplicate values" do
|
1473
|
+
|
1474
|
+
let(:plucked) do
|
1475
|
+
context.pluck(:likes)
|
1476
|
+
end
|
1477
|
+
|
1478
|
+
it "returns the duplicates" do
|
1479
|
+
expect(plucked).to contain_exactly(1, 3, 3, 1)
|
1480
|
+
end
|
1481
|
+
end
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
context "when plucking an aliased field" do
|
1485
|
+
|
1486
|
+
let(:plucked) do
|
1487
|
+
context.pluck(:id)
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
it "returns the field values" do
|
1491
|
+
expect(plucked).to eq([ depeche.id, tool.id, photek.id, maniacs.id ])
|
1492
|
+
end
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
context "when plucking existent and non-existent fields" do
|
1496
|
+
|
1497
|
+
let(:plucked) do
|
1498
|
+
context.pluck(:id, :fooz)
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
it "returns nil for the field that doesnt exist" do
|
1502
|
+
expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil], [maniacs.id, nil] ])
|
1503
|
+
end
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
context "when plucking a field that doesnt exist" do
|
1507
|
+
|
1508
|
+
context "when pluck one field" do
|
1509
|
+
|
1510
|
+
let(:plucked) do
|
1511
|
+
context.pluck(:foo)
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
it "returns an array with nil values" do
|
1515
|
+
expect(plucked).to eq([nil, nil, nil, nil])
|
1516
|
+
end
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
context "when pluck multiple fields" do
|
1520
|
+
|
1521
|
+
let(:plucked) do
|
1522
|
+
context.pluck(:foo, :bar)
|
1523
|
+
end
|
1524
|
+
|
1525
|
+
it "returns an array of arrays with nil values" do
|
1526
|
+
expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil], [nil, nil]])
|
1527
|
+
end
|
1528
|
+
end
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
context 'when plucking a localized field' do
|
1532
|
+
|
1533
|
+
before do
|
1534
|
+
I18n.locale = :en
|
1535
|
+
d = Dictionary.create!(description: 'english-text')
|
1536
|
+
I18n.locale = :de
|
1537
|
+
d.description = 'deutsch-text'
|
1538
|
+
d.save!
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
after do
|
1542
|
+
I18n.locale = :en
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
let(:criteria) do
|
1546
|
+
Dictionary.all.tap do |crit|
|
1547
|
+
crit.documents = [ Dictionary.first ]
|
1548
|
+
end
|
1549
|
+
end
|
1550
|
+
|
1551
|
+
context 'when plucking the entire field' do
|
1552
|
+
|
1553
|
+
let(:plucked) do
|
1554
|
+
context.pluck(:description)
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
let(:plucked_translations) do
|
1558
|
+
context.pluck(:description_translations)
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
let(:plucked_translations_both) do
|
1562
|
+
context.pluck(:description_translations, :description)
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
it 'returns the demongoized translations' do
|
1566
|
+
expect(plucked.first).to eq('deutsch-text')
|
1567
|
+
end
|
1568
|
+
|
1569
|
+
it 'returns the full translations hash to _translations' do
|
1570
|
+
expect(plucked_translations.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
|
1571
|
+
end
|
1572
|
+
|
1573
|
+
it 'returns both' do
|
1574
|
+
expect(plucked_translations_both.first).to eq([{"de"=>"deutsch-text", "en"=>"english-text"}, "deutsch-text"])
|
1575
|
+
end
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
context 'when plucking a specific locale' do
|
1579
|
+
|
1580
|
+
let(:plucked) do
|
1581
|
+
context.pluck(:'description.de')
|
1582
|
+
end
|
1583
|
+
|
1584
|
+
it 'returns the specific translations' do
|
1585
|
+
expect(plucked.first).to eq('deutsch-text')
|
1586
|
+
end
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
context 'when plucking a specific locale from _translations field' do
|
1590
|
+
|
1591
|
+
let(:plucked) do
|
1592
|
+
context.pluck(:'description_translations.de')
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it 'returns the specific translations' do
|
1596
|
+
expect(plucked.first).to eq('deutsch-text')
|
1597
|
+
end
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
context 'when fallbacks are enabled with a locale list' do
|
1601
|
+
with_i18n_fallbacks
|
1602
|
+
|
1603
|
+
around(:all) do |example|
|
1604
|
+
prev_fallbacks = I18n.fallbacks.dup
|
1605
|
+
I18n.fallbacks[:he] = [ :en ]
|
1606
|
+
example.run
|
1607
|
+
I18n.fallbacks = prev_fallbacks
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
after do
|
1611
|
+
I18n.locale = :en
|
1612
|
+
end
|
1613
|
+
|
1614
|
+
let(:plucked) do
|
1615
|
+
context.pluck(:description).first
|
1616
|
+
end
|
1617
|
+
|
1618
|
+
it "correctly uses the fallback" do
|
1619
|
+
I18n.locale = :en
|
1620
|
+
Dictionary.create!(description: 'english-text')
|
1621
|
+
I18n.locale = :he
|
1622
|
+
plucked.should == "english-text"
|
1623
|
+
end
|
1624
|
+
end
|
1625
|
+
|
1626
|
+
context "when the localized field is embedded" do
|
1627
|
+
before do
|
1628
|
+
p = Passport.new
|
1629
|
+
I18n.locale = :en
|
1630
|
+
p.name = "Neil"
|
1631
|
+
I18n.locale = :he
|
1632
|
+
p.name = "Nissim"
|
1633
|
+
|
1634
|
+
Person.create!(passport: p, employer_id: 12345)
|
1635
|
+
end
|
1636
|
+
|
1637
|
+
after do
|
1638
|
+
I18n.locale = :en
|
1639
|
+
end
|
1640
|
+
|
1641
|
+
let(:plucked) do
|
1642
|
+
Person.where(employer_id: 12345).pluck("pass.name").first
|
1643
|
+
end
|
1644
|
+
|
1645
|
+
let(:plucked_translations) do
|
1646
|
+
Person.where(employer_id: 12345).pluck("pass.name_translations").first
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
let(:plucked_translations_field) do
|
1650
|
+
Person.where(employer_id: 12345).pluck("pass.name_translations.en").first
|
1651
|
+
end
|
1652
|
+
|
1653
|
+
it "returns the translation for the current locale" do
|
1654
|
+
expect(plucked).to eq("Nissim")
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
it "returns the full _translation hash" do
|
1658
|
+
expect(plucked_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
it "returns the translation for the requested locale" do
|
1662
|
+
expect(plucked_translations_field).to eq("Neil")
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
end
|
1666
|
+
|
1667
|
+
context 'when plucking a field to be demongoized' do
|
1668
|
+
|
1669
|
+
let(:plucked) do
|
1670
|
+
Band.where(name: maniacs.name).pluck(:sales)
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
with_config_values :map_big_decimal_to_decimal128, true, false do
|
1674
|
+
|
1675
|
+
it "demongoizes the field" do
|
1676
|
+
expect(plucked.first).to be_a(BigDecimal)
|
1677
|
+
expect(plucked.first).to eq(BigDecimal("1E2"))
|
1678
|
+
end
|
1679
|
+
end
|
1680
|
+
end
|
1681
|
+
|
1682
|
+
context "when plucking an embedded field" do
|
1683
|
+
let(:label) { Label.new(sales: "1E2") }
|
1684
|
+
let!(:band) { Band.create!(label: label) }
|
1685
|
+
|
1686
|
+
let(:plucked) do
|
1687
|
+
Band.where(_id: band.id).tap do |crit|
|
1688
|
+
crit.documents = [ band ]
|
1689
|
+
end.pluck("label.sales")
|
1690
|
+
end
|
1691
|
+
|
1692
|
+
it "demongoizes the field" do
|
1693
|
+
expect(plucked).to eq([ BigDecimal("1E2") ])
|
1694
|
+
end
|
1695
|
+
end
|
1696
|
+
|
1697
|
+
context "when plucking an embeds_many field" do
|
1698
|
+
let(:label) { Label.new(sales: "1E2") }
|
1699
|
+
let!(:band) { Band.create!(labels: [label]) }
|
1700
|
+
|
1701
|
+
let(:plucked) { Band.where(_id: band.id).pluck("labels.sales") }
|
1702
|
+
|
1703
|
+
it "demongoizes the field" do
|
1704
|
+
expect(plucked.first).to eq([ BigDecimal("1E2") ])
|
1705
|
+
end
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
context "when plucking a nonexistent embedded field" do
|
1709
|
+
let(:label) { Label.new(sales: "1E2") }
|
1710
|
+
let!(:band) { Band.create!(label: label) }
|
1711
|
+
|
1712
|
+
let(:plucked) do
|
1713
|
+
Band.where(_id: band.id).tap do |crit|
|
1714
|
+
crit.documents = [ band ]
|
1715
|
+
end.pluck("label.qwerty")
|
1716
|
+
end
|
1717
|
+
|
1718
|
+
it "returns nil" do
|
1719
|
+
expect(plucked.first).to eq(nil)
|
1720
|
+
end
|
1721
|
+
end
|
1722
|
+
|
1723
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
1724
|
+
|
1725
|
+
let(:criteria) do
|
1726
|
+
Person.all.tap do |crit|
|
1727
|
+
crit.documents = [
|
1728
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
|
1729
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
|
1730
|
+
Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]),
|
1731
|
+
]
|
1732
|
+
end
|
1733
|
+
end
|
1734
|
+
|
1735
|
+
let(:plucked) do
|
1736
|
+
context.pluck("addresses.code.deepest.array.y.z")
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
it "returns the correct hash" do
|
1740
|
+
expect(plucked).to eq([
|
1741
|
+
[ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
|
1742
|
+
])
|
1743
|
+
end
|
1744
|
+
end
|
1745
|
+
end
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
describe "#pick" do
|
1749
|
+
|
1750
|
+
let(:depeche) do
|
1751
|
+
Band.create!(name: "Depeche Mode", likes: 3)
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
let(:tool) do
|
1755
|
+
Band.create!(name: "Tool", likes: 3)
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
let(:criteria) do
|
1759
|
+
Band.all.tap do |crit|
|
1760
|
+
crit.documents = [ depeche, tool ]
|
1761
|
+
end
|
1762
|
+
end
|
1763
|
+
|
1764
|
+
let(:context) do
|
1765
|
+
described_class.new(criteria)
|
1766
|
+
end
|
1767
|
+
|
1768
|
+
context "when picking a field" do
|
1769
|
+
|
1770
|
+
let(:picked) do
|
1771
|
+
context.pick(:name)
|
1772
|
+
end
|
1773
|
+
|
1774
|
+
it "returns one element" do
|
1775
|
+
expect(picked).to eq("Depeche Mode")
|
1776
|
+
end
|
1777
|
+
end
|
1778
|
+
|
1779
|
+
context "when picking multiple fields" do
|
1780
|
+
|
1781
|
+
let(:picked) do
|
1782
|
+
context.pick(:name, :likes)
|
1783
|
+
end
|
1784
|
+
|
1785
|
+
it "returns an array" do
|
1786
|
+
expect(picked).to eq([ "Depeche Mode", 3 ])
|
1787
|
+
end
|
1788
|
+
end
|
1789
|
+
|
1790
|
+
context "when no documents to pick" do
|
1791
|
+
|
1792
|
+
let(:criteria) do
|
1793
|
+
Band.all.tap do |crit|
|
1794
|
+
crit.documents = []
|
1795
|
+
end
|
1796
|
+
end
|
1797
|
+
|
1798
|
+
let(:picked) do
|
1799
|
+
context.pick(:name)
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
it "returns nil" do
|
1803
|
+
expect(picked).to be_nil
|
1804
|
+
end
|
1805
|
+
end
|
1806
|
+
end
|
1807
|
+
|
1808
|
+
describe "#tally" do
|
1809
|
+
let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
1810
|
+
let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
|
1811
|
+
let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
|
1812
|
+
|
1813
|
+
let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
|
1814
|
+
let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
|
1815
|
+
let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
|
1816
|
+
|
1817
|
+
let(:label1) { Label.new(name: "Atlantic") }
|
1818
|
+
let(:label2) { Label.new(name: "Atlantic") }
|
1819
|
+
let(:label3) { Label.new(name: "Columbia") }
|
1820
|
+
|
1821
|
+
|
1822
|
+
let(:band1) { Band.new(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1) }
|
1823
|
+
let(:band2) { Band.new(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2) }
|
1824
|
+
let(:band3) { Band.new(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3) }
|
1825
|
+
let(:band4) { Band.new(origin: "tally2", fanatics: fans1, genres: [1, 2]) }
|
1826
|
+
let(:band5) { Band.new(origin: "tally2", fanatics: fans2, genres: [1, 2]) }
|
1827
|
+
let(:band6) { Band.new(origin: "tally2", fanatics: fans3, genres: [1, 3]) }
|
1828
|
+
|
1829
|
+
let(:criteria) do
|
1830
|
+
Band.where(origin: "tally").all.tap do |crit|
|
1831
|
+
crit.documents = [ band1, band2, band3 ]
|
1832
|
+
end
|
1833
|
+
end
|
1834
|
+
|
1835
|
+
let(:criteria2) do
|
1836
|
+
Band.where(origin: "tally2").tap do |crit|
|
1837
|
+
crit.documents = [ band4, band5, band6 ]
|
1838
|
+
end
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
let(:context) do
|
1842
|
+
described_class.new(criteria)
|
1843
|
+
end
|
1844
|
+
|
1845
|
+
let(:context2) do
|
1846
|
+
described_class.new(criteria2)
|
1847
|
+
end
|
1848
|
+
|
1849
|
+
context "when tallying a string" do
|
1850
|
+
let(:tally) do
|
1851
|
+
context.tally(:name)
|
1852
|
+
end
|
1853
|
+
|
1854
|
+
it "returns the correct hash" do
|
1855
|
+
expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
|
1856
|
+
end
|
1857
|
+
end
|
1858
|
+
|
1859
|
+
context "using an aliased field" do
|
1860
|
+
let(:tally) do
|
1861
|
+
context.tally(:years)
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
it "returns the correct hash" do
|
1865
|
+
expect(tally).to eq(30 => 3)
|
1866
|
+
end
|
1867
|
+
end
|
1868
|
+
|
1869
|
+
context "when tallying a demongoizable field" do
|
1870
|
+
let(:tally) do
|
1871
|
+
context.tally(:sales)
|
1872
|
+
end
|
1873
|
+
|
1874
|
+
it "returns the correct hash" do
|
1875
|
+
expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
|
1876
|
+
end
|
1877
|
+
end
|
1878
|
+
|
1879
|
+
context "when tallying a localized field" do
|
1880
|
+
let(:d1) { Dictionary.new(description: 'en1') }
|
1881
|
+
let(:d2) { Dictionary.new(description: 'en1') }
|
1882
|
+
let(:d3) { Dictionary.new(description: 'en1') }
|
1883
|
+
let(:d4) { Dictionary.new(description: 'en2') }
|
1884
|
+
|
1885
|
+
before do
|
1886
|
+
I18n.locale = :en
|
1887
|
+
d1
|
1888
|
+
d2
|
1889
|
+
d3
|
1890
|
+
d4
|
1891
|
+
I18n.locale = :de
|
1892
|
+
d1.description = 'de1'
|
1893
|
+
d2.description = 'de1'
|
1894
|
+
d3.description = 'de2'
|
1895
|
+
d4.description = 'de3'
|
1896
|
+
I18n.locale = :en
|
1897
|
+
end
|
1898
|
+
|
1899
|
+
let(:criteria) do
|
1900
|
+
Dictionary.all.tap do |crit|
|
1901
|
+
crit.documents = [ d1, d2, d3, d4 ]
|
1902
|
+
end
|
1903
|
+
end
|
1904
|
+
|
1905
|
+
context "when getting the demongoized field" do
|
1906
|
+
let(:tallied) do
|
1907
|
+
context.tally(:description)
|
1908
|
+
end
|
1909
|
+
|
1910
|
+
it "returns the translation for the current locale" do
|
1911
|
+
expect(tallied).to eq("en1" => 3, "en2" => 1)
|
1912
|
+
end
|
1913
|
+
end
|
1914
|
+
|
1915
|
+
context "when getting a specific locale" do
|
1916
|
+
let(:tallied) do
|
1917
|
+
context.tally("description.de")
|
1918
|
+
end
|
1919
|
+
|
1920
|
+
it "returns the translation for the the specific locale" do
|
1921
|
+
expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
|
1922
|
+
end
|
1923
|
+
end
|
1924
|
+
|
1925
|
+
context "when getting the full hash" do
|
1926
|
+
let(:tallied) do
|
1927
|
+
context.tally("description_translations")
|
1928
|
+
end
|
1929
|
+
|
1930
|
+
it "returns the correct hash" do
|
1931
|
+
expect(tallied).to eq(
|
1932
|
+
{"de" => "de1", "en" => "en1" } => 2,
|
1933
|
+
{"de" => "de2", "en" => "en1" } => 1,
|
1934
|
+
{"de" => "de3", "en" => "en2" } => 1
|
1935
|
+
)
|
1936
|
+
end
|
1937
|
+
end
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
context "when tallying an embedded localized field" do
|
1941
|
+
|
1942
|
+
let(:person1) { Person.create!(addresses: [ address1a, address1b ]) }
|
1943
|
+
let(:person2) { Person.create!(addresses: [ address2a, address2b ]) }
|
1944
|
+
|
1945
|
+
let(:address1a) { Address.new(name: "en1") }
|
1946
|
+
let(:address1b) { Address.new(name: "en2") }
|
1947
|
+
let(:address2a) { Address.new(name: "en1") }
|
1948
|
+
let(:address2b) { Address.new(name: "en3") }
|
1949
|
+
|
1950
|
+
before do
|
1951
|
+
I18n.locale = :en
|
1952
|
+
address1a
|
1953
|
+
address1b
|
1954
|
+
address2a
|
1955
|
+
address2b
|
1956
|
+
I18n.locale = :de
|
1957
|
+
address1a.name = "de1"
|
1958
|
+
address1b.name = "de2"
|
1959
|
+
address2a.name = "de1"
|
1960
|
+
address2b.name = "de3"
|
1961
|
+
person1
|
1962
|
+
person2
|
1963
|
+
I18n.locale = :en
|
1964
|
+
end
|
1965
|
+
|
1966
|
+
let(:criteria) do
|
1967
|
+
Person.all.tap do |crit|
|
1968
|
+
crit.documents = [ person1, person2 ]
|
1969
|
+
end
|
1970
|
+
end
|
1971
|
+
|
1972
|
+
context "when getting the demongoized field" do
|
1973
|
+
let(:tallied) do
|
1974
|
+
context.tally("addresses.name")
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
it "returns the translation for the current locale" do
|
1978
|
+
expect(tallied).to eq(
|
1979
|
+
[ "en1", "en2" ] => 1,
|
1980
|
+
[ "en1", "en3" ] => 1,
|
1981
|
+
)
|
1982
|
+
end
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
context "when getting a specific locale" do
|
1986
|
+
let(:tallied) do
|
1987
|
+
context.tally("addresses.name.de")
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
it "returns the translation for the the specific locale" do
|
1991
|
+
expect(tallied).to eq(
|
1992
|
+
[ "de1", "de2" ] => 1,
|
1993
|
+
[ "de1", "de3" ] => 1,
|
1994
|
+
)
|
1995
|
+
end
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
context "when getting the full hash" do
|
1999
|
+
let(:tallied) do
|
2000
|
+
context.tally("addresses.name_translations")
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
it "returns the correct hash" do
|
2004
|
+
expect(tallied).to eq(
|
2005
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
|
2006
|
+
[{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
|
2007
|
+
)
|
2008
|
+
end
|
2009
|
+
end
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
context "when tallying an embedded field" do
|
2013
|
+
let(:tally) do
|
2014
|
+
context.tally("label.name")
|
2015
|
+
end
|
2016
|
+
|
2017
|
+
it "returns the correct hash" do
|
2018
|
+
expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
|
2019
|
+
end
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
context "when tallying an element in an embeds_many field" do
|
2023
|
+
|
2024
|
+
let(:tally) do
|
2025
|
+
context2.tally("fanatics.age")
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
it "returns the correct hash" do
|
2029
|
+
expect(tally).to eq(
|
2030
|
+
[1, 2] => 2,
|
2031
|
+
[1, 3] => 1
|
2032
|
+
)
|
2033
|
+
end
|
2034
|
+
end
|
2035
|
+
|
2036
|
+
context "when tallying an embeds_many field" do
|
2037
|
+
|
2038
|
+
let(:tally) do
|
2039
|
+
context2.tally("fanatics")
|
2040
|
+
end
|
2041
|
+
|
2042
|
+
it "returns the correct hash" do
|
2043
|
+
expect(tally).to eq(
|
2044
|
+
fans1 => 1,
|
2045
|
+
fans2 => 1,
|
2046
|
+
fans3 => 1,
|
2047
|
+
)
|
2048
|
+
end
|
2049
|
+
end
|
2050
|
+
|
2051
|
+
context "when tallying a field of type array" do
|
2052
|
+
|
2053
|
+
let(:tally) do
|
2054
|
+
context2.tally("genres")
|
2055
|
+
end
|
2056
|
+
|
2057
|
+
it "returns the correct hash" do
|
2058
|
+
expect(tally).to eq(
|
2059
|
+
[1, 2] => 2,
|
2060
|
+
[1, 3] => 1
|
2061
|
+
)
|
2062
|
+
end
|
2063
|
+
end
|
2064
|
+
|
2065
|
+
context "when tallying an element from an array of hashes" do
|
2066
|
+
|
2067
|
+
let(:tally) do
|
2068
|
+
context.tally("genres.x")
|
2069
|
+
end
|
2070
|
+
|
2071
|
+
it "returns the correct hash without the nil keys" do
|
2072
|
+
expect(tally).to eq(
|
2073
|
+
[1, 2] => 2,
|
2074
|
+
[1, 3] => 1
|
2075
|
+
)
|
2076
|
+
end
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
context "when tallying an element from an array of hashes; with duplicate" do
|
2080
|
+
|
2081
|
+
let(:band4) { Band.new(origin: "tally", genres: [ { x: 1 }, {x: 1} ] ) }
|
2082
|
+
|
2083
|
+
let(:criteria) do
|
2084
|
+
Band.where(origin: "tally").all.tap do |crit|
|
2085
|
+
crit.documents = [ band1, band2, band3, band4 ]
|
2086
|
+
end
|
2087
|
+
end
|
2088
|
+
|
2089
|
+
let(:tally) do
|
2090
|
+
context.tally("genres.x")
|
2091
|
+
end
|
2092
|
+
|
2093
|
+
it "returns the correct hash without the nil keys" do
|
2094
|
+
expect(tally).to eq(
|
2095
|
+
[1, 2] => 2,
|
2096
|
+
[1, 3] => 1,
|
2097
|
+
[1, 1] => 1,
|
2098
|
+
)
|
2099
|
+
end
|
2100
|
+
end
|
2101
|
+
|
2102
|
+
context "when tallying an aliased field of type array" do
|
2103
|
+
|
2104
|
+
let(:person1) { Person.new(array: [ 1, 2 ]) }
|
2105
|
+
let(:person2) { Person.new(array: [ 1, 3 ]) }
|
2106
|
+
|
2107
|
+
let(:criteria) do
|
2108
|
+
Person.all.tap do |crit|
|
2109
|
+
crit.documents = [ person1, person2 ]
|
2110
|
+
end
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
let(:tally) do
|
2114
|
+
context.tally("array")
|
2115
|
+
end
|
2116
|
+
|
2117
|
+
it "returns the correct hash" do
|
2118
|
+
expect(tally).to eq(
|
2119
|
+
[1, 2] => 1,
|
2120
|
+
[1, 3] => 1
|
2121
|
+
)
|
2122
|
+
end
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
context "when going multiple levels deep in arrays" do
|
2126
|
+
|
2127
|
+
let(:tally) do
|
2128
|
+
context.tally("genres.y.z")
|
2129
|
+
end
|
2130
|
+
|
2131
|
+
it "returns the correct hash" do
|
2132
|
+
expect(tally).to eq(
|
2133
|
+
[1, 2] => 2,
|
2134
|
+
[1, 3] => 1
|
2135
|
+
)
|
2136
|
+
end
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
context "when going multiple levels deep in an array" do
|
2140
|
+
|
2141
|
+
let(:tally) do
|
2142
|
+
context.tally("genres.y.z")
|
2143
|
+
end
|
2144
|
+
|
2145
|
+
it "returns the correct hash" do
|
2146
|
+
expect(tally).to eq(
|
2147
|
+
[1, 2] => 2,
|
2148
|
+
[1, 3] => 1
|
2149
|
+
)
|
2150
|
+
end
|
2151
|
+
end
|
2152
|
+
|
2153
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
2154
|
+
|
2155
|
+
let(:person1) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
|
2156
|
+
let(:person2) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
|
2157
|
+
let(:person3) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]) }
|
2158
|
+
|
2159
|
+
let(:criteria) do
|
2160
|
+
Person.all.tap do |crit|
|
2161
|
+
crit.documents = [ person1, person2, person3 ]
|
2162
|
+
end
|
2163
|
+
end
|
2164
|
+
|
2165
|
+
let(:tally) do
|
2166
|
+
context.tally("addresses.code.deepest.array.y.z")
|
2167
|
+
end
|
2168
|
+
|
2169
|
+
it "returns the correct hash" do
|
2170
|
+
expect(tally).to eq(
|
2171
|
+
[ [ 1, 2 ] ] => 2,
|
2172
|
+
[ [ 1, 3 ] ] => 1
|
2173
|
+
)
|
2174
|
+
end
|
2175
|
+
end
|
2176
|
+
|
2177
|
+
context "when tallying deeply nested arrays/embedded associations" do
|
2178
|
+
|
2179
|
+
let(:person1) do
|
2180
|
+
Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
2181
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
2182
|
+
end
|
2183
|
+
|
2184
|
+
let(:person2) do
|
2185
|
+
Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
|
2186
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
|
2187
|
+
end
|
2188
|
+
|
2189
|
+
let(:person3) do
|
2190
|
+
Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
|
2191
|
+
Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
|
2192
|
+
end
|
2193
|
+
|
2194
|
+
let(:criteria) do
|
2195
|
+
Person.all.tap do |crit|
|
2196
|
+
crit.documents = [ person1, person2, person3 ]
|
2197
|
+
end
|
2198
|
+
end
|
2199
|
+
|
2200
|
+
let(:tally) do
|
2201
|
+
context.tally("addresses.code.deepest.array.y.z")
|
2202
|
+
end
|
2203
|
+
|
2204
|
+
it "returns the correct hash" do
|
2205
|
+
expect(tally).to eq(
|
2206
|
+
[ [ 1, 2 ], [ 1, 2 ] ] => 2,
|
2207
|
+
[ [ 1, 3 ], [ 1, 3 ] ] => 1
|
2208
|
+
)
|
2209
|
+
end
|
2210
|
+
end
|
2211
|
+
|
2212
|
+
context "when some keys are missing" do
|
2213
|
+
|
2214
|
+
let(:criteria) do
|
2215
|
+
Band.where(origin: "tally").all.tap do |crit|
|
2216
|
+
crit.documents = [ band1, band2, band3 ]
|
2217
|
+
3.times{ crit.documents << Band.new(origin: "tally") }
|
2218
|
+
end
|
2219
|
+
end
|
2220
|
+
|
2221
|
+
let(:tally) do
|
2222
|
+
context.tally(:name)
|
2223
|
+
end
|
2224
|
+
|
2225
|
+
it "returns the correct hash" do
|
2226
|
+
expect(tally).to eq(
|
2227
|
+
"Depeche Mode" => 1,
|
2228
|
+
"New Order" => 1,
|
2229
|
+
"10,000 Maniacs" => 1,
|
2230
|
+
nil => 3
|
2231
|
+
)
|
2232
|
+
end
|
2233
|
+
end
|
2234
|
+
|
2235
|
+
context "when the first element is an embeds_one" do
|
2236
|
+
let(:person1) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
|
2237
|
+
let(:person2) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
|
2238
|
+
let(:person3) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ])) }
|
2239
|
+
|
2240
|
+
let(:criteria) do
|
2241
|
+
Person.all.tap do |crit|
|
2242
|
+
crit.documents = [ person1, person2, person3 ]
|
2243
|
+
end
|
2244
|
+
end
|
2245
|
+
|
2246
|
+
let(:tally) do
|
2247
|
+
context.tally("name.translations.language")
|
2248
|
+
end
|
2249
|
+
|
2250
|
+
it "returns the correct hash" do
|
2251
|
+
expect(tally).to eq(
|
2252
|
+
[1, 2] => 2,
|
2253
|
+
[1, 3] => 1
|
2254
|
+
)
|
988
2255
|
end
|
989
2256
|
end
|
990
2257
|
end
|