mongoid 9.0.11 → 9.1.1

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.
Files changed (1033) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -8
  3. data/README.md +5 -11
  4. data/Rakefile +35 -38
  5. data/lib/config/locales/en.yml +60 -0
  6. data/lib/mongoid/association/accessors.rb +27 -26
  7. data/lib/mongoid/association/bindable.rb +43 -45
  8. data/lib/mongoid/association/builders.rb +18 -15
  9. data/lib/mongoid/association/constrainable.rb +3 -5
  10. data/lib/mongoid/association/depending.rb +43 -43
  11. data/lib/mongoid/association/eager.rb +56 -13
  12. data/lib/mongoid/association/eager_load/discriminated_inclusion.rb +88 -0
  13. data/lib/mongoid/association/eager_load/embedded_distributor.rb +151 -0
  14. data/lib/mongoid/association/eager_load/inclusion.rb +173 -0
  15. data/lib/mongoid/association/eager_load/inclusion_tree.rb +96 -0
  16. data/lib/mongoid/association/eager_load/lookup_pipeline.rb +121 -0
  17. data/lib/mongoid/association/eager_load/polymorphic_preloader.rb +61 -0
  18. data/lib/mongoid/association/eager_load/polymorphic_targets.rb +151 -0
  19. data/lib/mongoid/association/eager_loadable.rb +108 -23
  20. data/lib/mongoid/association/embedded/batchable.rb +28 -30
  21. data/lib/mongoid/association/embedded/cyclic.rb +8 -11
  22. data/lib/mongoid/association/embedded/eager.rb +1 -6
  23. data/lib/mongoid/association/embedded/embedded_in/binding.rb +6 -9
  24. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -3
  25. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -0
  26. data/lib/mongoid/association/embedded/embedded_in.rb +25 -22
  27. data/lib/mongoid/association/embedded/embeds_many/binding.rb +0 -2
  28. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +2 -3
  29. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +7 -2
  30. data/lib/mongoid/association/embedded/embeds_many.rb +24 -21
  31. data/lib/mongoid/association/embedded/embeds_one/binding.rb +0 -2
  32. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +2 -6
  33. data/lib/mongoid/association/embedded/embeds_one.rb +21 -18
  34. data/lib/mongoid/association/embedded.rb +0 -1
  35. data/lib/mongoid/association/macros.rb +16 -8
  36. data/lib/mongoid/association/many.rb +75 -3
  37. data/lib/mongoid/association/marshalable.rb +0 -3
  38. data/lib/mongoid/association/nested/many.rb +52 -18
  39. data/lib/mongoid/association/nested/nested_buildable.rb +20 -9
  40. data/lib/mongoid/association/nested/one.rb +10 -8
  41. data/lib/mongoid/association/nested.rb +1 -3
  42. data/lib/mongoid/association/one.rb +0 -3
  43. data/lib/mongoid/association/options.rb +25 -7
  44. data/lib/mongoid/association/referenced/auto_save.rb +0 -2
  45. data/lib/mongoid/association/referenced/belongs_to/binding.rb +11 -15
  46. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +23 -5
  47. data/lib/mongoid/association/referenced/belongs_to/eager.rb +7 -4
  48. data/lib/mongoid/association/referenced/belongs_to.rb +49 -43
  49. data/lib/mongoid/association/referenced/counter_cache.rb +7 -12
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +0 -2
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +8 -4
  52. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +0 -3
  53. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +57 -47
  54. data/lib/mongoid/association/referenced/has_many/binding.rb +0 -2
  55. data/lib/mongoid/association/referenced/has_many/buildable.rb +11 -5
  56. data/lib/mongoid/association/referenced/has_many/eager.rb +0 -3
  57. data/lib/mongoid/association/referenced/has_many/enumerable.rb +109 -38
  58. data/lib/mongoid/association/referenced/has_many/proxy.rb +110 -7
  59. data/lib/mongoid/association/referenced/has_many.rb +30 -24
  60. data/lib/mongoid/association/referenced/has_many_through/eager.rb +99 -0
  61. data/lib/mongoid/association/referenced/has_many_through/proxy.rb +68 -0
  62. data/lib/mongoid/association/referenced/has_many_through.rb +201 -0
  63. data/lib/mongoid/association/referenced/has_one/binding.rb +0 -2
  64. data/lib/mongoid/association/referenced/has_one/buildable.rb +11 -9
  65. data/lib/mongoid/association/referenced/has_one/eager.rb +0 -3
  66. data/lib/mongoid/association/referenced/has_one.rb +27 -21
  67. data/lib/mongoid/association/referenced/has_one_through/eager.rb +65 -0
  68. data/lib/mongoid/association/referenced/has_one_through/proxy.rb +30 -0
  69. data/lib/mongoid/association/referenced/has_one_through.rb +167 -0
  70. data/lib/mongoid/association/referenced/syncable.rb +30 -34
  71. data/lib/mongoid/association/referenced.rb +2 -1
  72. data/lib/mongoid/association/reflections.rb +0 -3
  73. data/lib/mongoid/association/relatable.rb +108 -65
  74. data/lib/mongoid/association.rb +19 -15
  75. data/lib/mongoid/atomic/modifiers.rb +65 -25
  76. data/lib/mongoid/atomic/paths/embedded/many.rb +4 -7
  77. data/lib/mongoid/atomic/paths/embedded/one.rb +2 -4
  78. data/lib/mongoid/atomic/paths/embedded.rb +3 -6
  79. data/lib/mongoid/atomic/paths/root.rb +1 -4
  80. data/lib/mongoid/atomic/paths.rb +2 -3
  81. data/lib/mongoid/atomic.rb +0 -3
  82. data/lib/mongoid/attributes/dynamic.rb +6 -7
  83. data/lib/mongoid/attributes/nested.rb +8 -10
  84. data/lib/mongoid/attributes/projector.rb +7 -20
  85. data/lib/mongoid/attributes/readonly.rb +6 -11
  86. data/lib/mongoid/attributes.rb +18 -34
  87. data/lib/mongoid/cacheable.rb +24 -6
  88. data/lib/mongoid/clients/factory.rb +13 -22
  89. data/lib/mongoid/clients/options.rb +2 -5
  90. data/lib/mongoid/clients/sessions.rb +50 -60
  91. data/lib/mongoid/clients/storage_options.rb +1 -4
  92. data/lib/mongoid/clients/validators/storage.rb +2 -3
  93. data/lib/mongoid/clients/validators.rb +1 -2
  94. data/lib/mongoid/clients.rb +8 -11
  95. data/lib/mongoid/collection_configurable.rb +18 -14
  96. data/lib/mongoid/composable.rb +30 -34
  97. data/lib/mongoid/config/defaults.rb +6 -4
  98. data/lib/mongoid/config/encryption.rb +36 -21
  99. data/lib/mongoid/config/environment.rb +7 -16
  100. data/lib/mongoid/config/introspection.rb +14 -16
  101. data/lib/mongoid/config/options.rb +16 -10
  102. data/lib/mongoid/config/validators/async_query_executor.rb +3 -6
  103. data/lib/mongoid/config/validators/client.rb +12 -15
  104. data/lib/mongoid/config/validators/option.rb +3 -5
  105. data/lib/mongoid/config/validators.rb +3 -4
  106. data/lib/mongoid/config.rb +188 -47
  107. data/lib/mongoid/contextual/aggregable/memory.rb +7 -5
  108. data/lib/mongoid/contextual/aggregable/mongo.rb +20 -22
  109. data/lib/mongoid/contextual/aggregable/none.rb +2 -4
  110. data/lib/mongoid/contextual/aggregable.rb +5 -7
  111. data/lib/mongoid/contextual/atomic.rb +20 -24
  112. data/lib/mongoid/contextual/command.rb +0 -3
  113. data/lib/mongoid/contextual/map_reduce.rb +12 -16
  114. data/lib/mongoid/contextual/memory.rb +87 -69
  115. data/lib/mongoid/contextual/mongo/documents_loader.rb +2 -3
  116. data/lib/mongoid/contextual/mongo.rb +169 -85
  117. data/lib/mongoid/contextual/none.rb +9 -9
  118. data/lib/mongoid/contextual/queryable.rb +1 -4
  119. data/lib/mongoid/contextual.rb +18 -7
  120. data/lib/mongoid/copyable.rb +7 -9
  121. data/lib/mongoid/criteria/findable.rb +5 -7
  122. data/lib/mongoid/criteria/includable.rb +67 -14
  123. data/lib/mongoid/criteria/inspectable.rb +2 -5
  124. data/lib/mongoid/criteria/marshalable.rb +4 -8
  125. data/lib/mongoid/criteria/modifiable.rb +3 -11
  126. data/lib/mongoid/criteria/options.rb +0 -3
  127. data/lib/mongoid/criteria/permission.rb +34 -37
  128. data/lib/mongoid/criteria/queryable/aggregable.rb +9 -10
  129. data/lib/mongoid/criteria/queryable/expandable.rb +4 -9
  130. data/lib/mongoid/criteria/queryable/extensions/array.rb +7 -10
  131. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -5
  132. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -4
  133. data/lib/mongoid/criteria/queryable/extensions/date.rb +2 -6
  134. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +3 -7
  135. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -4
  136. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +20 -11
  137. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -11
  138. data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -8
  139. data/lib/mongoid/criteria/queryable/extensions/range.rb +6 -9
  140. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -12
  141. data/lib/mongoid/criteria/queryable/extensions/set.rb +4 -6
  142. data/lib/mongoid/criteria/queryable/extensions/string.rb +5 -9
  143. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -7
  144. data/lib/mongoid/criteria/queryable/extensions/time.rb +2 -6
  145. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +2 -12
  146. data/lib/mongoid/criteria/queryable/extensions.rb +18 -21
  147. data/lib/mongoid/criteria/queryable/key.rb +12 -18
  148. data/lib/mongoid/criteria/queryable/macroable.rb +0 -3
  149. data/lib/mongoid/criteria/queryable/mergeable.rb +35 -39
  150. data/lib/mongoid/criteria/queryable/optional.rb +17 -18
  151. data/lib/mongoid/criteria/queryable/options.rb +20 -9
  152. data/lib/mongoid/criteria/queryable/pipeline.rb +6 -9
  153. data/lib/mongoid/criteria/queryable/selectable.rb +253 -199
  154. data/lib/mongoid/criteria/queryable/selector.rb +20 -29
  155. data/lib/mongoid/criteria/queryable/smash.rb +1 -6
  156. data/lib/mongoid/criteria/queryable/storable.rb +20 -39
  157. data/lib/mongoid/criteria/queryable.rb +25 -15
  158. data/lib/mongoid/criteria/scopable.rb +5 -11
  159. data/lib/mongoid/criteria/translator.rb +5 -8
  160. data/lib/mongoid/criteria.rb +109 -54
  161. data/lib/mongoid/deprecable.rb +45 -5
  162. data/lib/mongoid/deprecation.rb +2 -6
  163. data/lib/mongoid/document.rb +1 -1
  164. data/lib/mongoid/encryptable.rb +47 -2
  165. data/lib/mongoid/equality.rb +4 -5
  166. data/lib/mongoid/errors/ambiguous_relationship.rb +2 -5
  167. data/lib/mongoid/errors/attribute_not_loaded.rb +1 -4
  168. data/lib/mongoid/errors/callback.rb +1 -4
  169. data/lib/mongoid/errors/config_redactor.rb +43 -0
  170. data/lib/mongoid/errors/create_collection_failure.rb +8 -11
  171. data/lib/mongoid/errors/criteria_argument_required.rb +2 -5
  172. data/lib/mongoid/errors/delete_restriction.rb +1 -4
  173. data/lib/mongoid/errors/document_not_destroyed.rb +1 -4
  174. data/lib/mongoid/errors/document_not_found.rb +16 -21
  175. data/lib/mongoid/errors/drop_collection_failure.rb +7 -10
  176. data/lib/mongoid/errors/empty_config_file.rb +1 -4
  177. data/lib/mongoid/errors/immutable_attribute.rb +1 -4
  178. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -4
  179. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +26 -0
  180. data/lib/mongoid/errors/invalid_async_query_executor.rb +2 -5
  181. data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +2 -5
  182. data/lib/mongoid/errors/invalid_collection.rb +1 -3
  183. data/lib/mongoid/errors/invalid_config_file.rb +1 -4
  184. data/lib/mongoid/errors/invalid_config_option.rb +2 -5
  185. data/lib/mongoid/errors/invalid_dependent_strategy.rb +6 -10
  186. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +2 -4
  187. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +1 -4
  188. data/lib/mongoid/errors/invalid_elem_match_operator.rb +5 -9
  189. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +1 -4
  190. data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +1 -4
  191. data/lib/mongoid/errors/invalid_expression_operator.rb +3 -7
  192. data/lib/mongoid/errors/invalid_field.rb +2 -5
  193. data/lib/mongoid/errors/invalid_field_operator.rb +5 -9
  194. data/lib/mongoid/errors/invalid_field_option.rb +2 -5
  195. data/lib/mongoid/errors/invalid_field_type.rb +1 -4
  196. data/lib/mongoid/errors/invalid_find.rb +1 -4
  197. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +1 -4
  198. data/lib/mongoid/errors/invalid_includes.rb +3 -6
  199. data/lib/mongoid/errors/invalid_index.rb +1 -4
  200. data/lib/mongoid/errors/invalid_options.rb +1 -4
  201. data/lib/mongoid/errors/invalid_path.rb +1 -4
  202. data/lib/mongoid/errors/invalid_persistence_option.rb +4 -7
  203. data/lib/mongoid/errors/invalid_query.rb +6 -11
  204. data/lib/mongoid/errors/invalid_relation.rb +10 -13
  205. data/lib/mongoid/errors/invalid_relation_option.rb +4 -7
  206. data/lib/mongoid/errors/invalid_scope.rb +1 -4
  207. data/lib/mongoid/errors/invalid_session_nesting.rb +0 -3
  208. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +2 -4
  209. data/lib/mongoid/errors/invalid_storage_options.rb +1 -4
  210. data/lib/mongoid/errors/invalid_time.rb +1 -4
  211. data/lib/mongoid/errors/invalid_transaction_nesting.rb +0 -3
  212. data/lib/mongoid/errors/inverse_not_found.rb +1 -4
  213. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -5
  214. data/lib/mongoid/errors/mixed_relations.rb +1 -3
  215. data/lib/mongoid/errors/mongoid_error.rb +7 -11
  216. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -4
  217. data/lib/mongoid/errors/no_client_config.rb +1 -4
  218. data/lib/mongoid/errors/no_client_database.rb +2 -5
  219. data/lib/mongoid/errors/no_client_hosts.rb +2 -5
  220. data/lib/mongoid/errors/no_clients_config.rb +1 -4
  221. data/lib/mongoid/errors/no_default_client.rb +1 -4
  222. data/lib/mongoid/errors/no_encryption_schema.rb +28 -0
  223. data/lib/mongoid/errors/no_environment.rb +1 -4
  224. data/lib/mongoid/errors/no_map_reduce_output.rb +1 -4
  225. data/lib/mongoid/errors/no_metadata.rb +1 -4
  226. data/lib/mongoid/errors/no_parent.rb +1 -4
  227. data/lib/mongoid/errors/readonly_association.rb +29 -0
  228. data/lib/mongoid/errors/readonly_attribute.rb +1 -4
  229. data/lib/mongoid/errors/readonly_document.rb +1 -4
  230. data/lib/mongoid/errors/rollback.rb +0 -2
  231. data/lib/mongoid/errors/scope_overwrite.rb +2 -4
  232. data/lib/mongoid/errors/sessions_not_supported.rb +0 -3
  233. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -3
  234. data/lib/mongoid/errors/transaction_error.rb +0 -3
  235. data/lib/mongoid/errors/transactions_not_supported.rb +0 -3
  236. data/lib/mongoid/errors/unknown_attribute.rb +1 -4
  237. data/lib/mongoid/errors/unknown_model.rb +1 -4
  238. data/lib/mongoid/errors/unregistered_class.rb +1 -1
  239. data/lib/mongoid/errors/unsaved_document.rb +1 -3
  240. data/lib/mongoid/errors/unsupported_isolation_level.rb +22 -0
  241. data/lib/mongoid/errors/unsupported_javascript.rb +1 -4
  242. data/lib/mongoid/errors/validations.rb +3 -5
  243. data/lib/mongoid/errors.rb +76 -72
  244. data/lib/mongoid/evolvable.rb +0 -3
  245. data/lib/mongoid/extensions/array.rb +5 -7
  246. data/lib/mongoid/extensions/big_decimal.rb +6 -7
  247. data/lib/mongoid/extensions/binary.rb +3 -6
  248. data/lib/mongoid/extensions/boolean.rb +4 -7
  249. data/lib/mongoid/extensions/bson_document.rb +28 -0
  250. data/lib/mongoid/extensions/date.rb +10 -14
  251. data/lib/mongoid/extensions/date_time.rb +2 -6
  252. data/lib/mongoid/extensions/decimal128.rb +1 -5
  253. data/lib/mongoid/extensions/false_class.rb +3 -5
  254. data/lib/mongoid/extensions/float.rb +5 -10
  255. data/lib/mongoid/extensions/hash.rb +5 -10
  256. data/lib/mongoid/extensions/integer.rb +5 -10
  257. data/lib/mongoid/extensions/module.rb +1 -4
  258. data/lib/mongoid/extensions/nil_class.rb +0 -1
  259. data/lib/mongoid/extensions/object.rb +9 -14
  260. data/lib/mongoid/extensions/object_id.rb +2 -6
  261. data/lib/mongoid/extensions/range.rb +14 -15
  262. data/lib/mongoid/extensions/raw_value.rb +0 -3
  263. data/lib/mongoid/extensions/regexp.rb +3 -6
  264. data/lib/mongoid/extensions/set.rb +3 -4
  265. data/lib/mongoid/extensions/string.rb +8 -12
  266. data/lib/mongoid/extensions/symbol.rb +3 -7
  267. data/lib/mongoid/extensions/time.rb +24 -26
  268. data/lib/mongoid/extensions/time_with_zone.rb +4 -7
  269. data/lib/mongoid/extensions/true_class.rb +3 -5
  270. data/lib/mongoid/extensions/vector.rb +64 -0
  271. data/lib/mongoid/extensions.rb +27 -26
  272. data/lib/mongoid/factory.rb +5 -9
  273. data/lib/mongoid/field_readable.rb +69 -0
  274. data/lib/mongoid/fields/encrypted.rb +0 -1
  275. data/lib/mongoid/fields/foreign_key.rb +9 -10
  276. data/lib/mongoid/fields/localized.rb +12 -12
  277. data/lib/mongoid/fields/standard.rb +5 -7
  278. data/lib/mongoid/fields/validators/macro.rb +23 -34
  279. data/lib/mongoid/fields/validators.rb +1 -2
  280. data/lib/mongoid/fields.rb +151 -58
  281. data/lib/mongoid/findable.rb +82 -53
  282. data/lib/mongoid/indexable/specification.rb +20 -6
  283. data/lib/mongoid/indexable/validators/options.rb +33 -40
  284. data/lib/mongoid/indexable.rb +53 -40
  285. data/lib/mongoid/inspectable.rb +4 -7
  286. data/lib/mongoid/interceptable.rb +41 -40
  287. data/lib/mongoid/loadable.rb +17 -18
  288. data/lib/mongoid/loggable.rb +4 -8
  289. data/lib/mongoid/matchable.rb +6 -3
  290. data/lib/mongoid/matcher/all.rb +2 -5
  291. data/lib/mongoid/matcher/and.rb +0 -3
  292. data/lib/mongoid/matcher/bits.rb +13 -8
  293. data/lib/mongoid/matcher/bits_all_clear.rb +1 -3
  294. data/lib/mongoid/matcher/bits_all_set.rb +1 -3
  295. data/lib/mongoid/matcher/bits_any_clear.rb +1 -3
  296. data/lib/mongoid/matcher/bits_any_set.rb +1 -3
  297. data/lib/mongoid/matcher/elem_match.rb +13 -15
  298. data/lib/mongoid/matcher/elem_match_expression.rb +0 -3
  299. data/lib/mongoid/matcher/eq.rb +0 -3
  300. data/lib/mongoid/matcher/eq_impl.rb +12 -17
  301. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +4 -9
  302. data/lib/mongoid/matcher/exists.rb +1 -4
  303. data/lib/mongoid/matcher/expression.rb +5 -10
  304. data/lib/mongoid/matcher/expression_operator.rb +1 -3
  305. data/lib/mongoid/matcher/field_expression.rb +10 -13
  306. data/lib/mongoid/matcher/field_operator.rb +4 -6
  307. data/lib/mongoid/matcher/gt.rb +0 -3
  308. data/lib/mongoid/matcher/gte.rb +0 -3
  309. data/lib/mongoid/matcher/in.rb +9 -12
  310. data/lib/mongoid/matcher/lt.rb +0 -3
  311. data/lib/mongoid/matcher/lte.rb +0 -3
  312. data/lib/mongoid/matcher/mod.rb +4 -8
  313. data/lib/mongoid/matcher/ne.rb +0 -3
  314. data/lib/mongoid/matcher/nin.rb +0 -3
  315. data/lib/mongoid/matcher/nor.rb +1 -6
  316. data/lib/mongoid/matcher/not.rb +0 -3
  317. data/lib/mongoid/matcher/or.rb +0 -3
  318. data/lib/mongoid/matcher/regex.rb +9 -13
  319. data/lib/mongoid/matcher/regexp_budget.rb +372 -0
  320. data/lib/mongoid/matcher/size.rb +2 -5
  321. data/lib/mongoid/matcher/type.rb +32 -37
  322. data/lib/mongoid/matcher.rb +8 -15
  323. data/lib/mongoid/model_resolver.rb +1 -0
  324. data/lib/mongoid/persistable/creatable.rb +23 -7
  325. data/lib/mongoid/persistable/deletable.rb +6 -7
  326. data/lib/mongoid/persistable/destroyable.rb +2 -6
  327. data/lib/mongoid/persistable/incrementable.rb +1 -3
  328. data/lib/mongoid/persistable/logical.rb +3 -5
  329. data/lib/mongoid/persistable/maxable.rb +2 -4
  330. data/lib/mongoid/persistable/minable.rb +2 -4
  331. data/lib/mongoid/persistable/multipliable.rb +1 -3
  332. data/lib/mongoid/persistable/poppable.rb +2 -4
  333. data/lib/mongoid/persistable/pullable.rb +3 -5
  334. data/lib/mongoid/persistable/pushable.rb +5 -7
  335. data/lib/mongoid/persistable/renamable.rb +1 -3
  336. data/lib/mongoid/persistable/savable.rb +0 -3
  337. data/lib/mongoid/persistable/settable.rb +4 -13
  338. data/lib/mongoid/persistable/unsettable.rb +1 -3
  339. data/lib/mongoid/persistable/updatable.rb +23 -33
  340. data/lib/mongoid/persistable/upsertable.rb +8 -10
  341. data/lib/mongoid/persistable.rb +28 -27
  342. data/lib/mongoid/persistence_context.rb +69 -41
  343. data/lib/mongoid/pluckable.rb +0 -2
  344. data/lib/mongoid/positional.rb +5 -11
  345. data/lib/mongoid/railtie.rb +16 -22
  346. data/lib/mongoid/railties/console_sandbox.rb +6 -8
  347. data/lib/mongoid/railties/controller_runtime.rb +7 -11
  348. data/lib/mongoid/railties/database.rake +42 -44
  349. data/lib/mongoid/scopable.rb +23 -31
  350. data/lib/mongoid/search_indexable.rb +378 -7
  351. data/lib/mongoid/selectable.rb +1 -3
  352. data/lib/mongoid/serializable.rb +18 -12
  353. data/lib/mongoid/shardable.rb +8 -17
  354. data/lib/mongoid/stateful.rb +5 -10
  355. data/lib/mongoid/stringified_symbol.rb +5 -9
  356. data/lib/mongoid/tasks/database.rake +31 -32
  357. data/lib/mongoid/tasks/database.rb +51 -39
  358. data/lib/mongoid/tasks/encryption.rb +10 -15
  359. data/lib/mongoid/threaded/lifecycle.rb +6 -9
  360. data/lib/mongoid/threaded.rb +168 -32
  361. data/lib/mongoid/timestamps/created/short.rb +2 -3
  362. data/lib/mongoid/timestamps/created.rb +1 -2
  363. data/lib/mongoid/timestamps/short.rb +0 -1
  364. data/lib/mongoid/timestamps/timeless.rb +92 -23
  365. data/lib/mongoid/timestamps/updated/short.rb +2 -3
  366. data/lib/mongoid/timestamps/updated.rb +2 -5
  367. data/lib/mongoid/timestamps.rb +4 -6
  368. data/lib/mongoid/touchable.rb +19 -11
  369. data/lib/mongoid/traversable.rb +5 -4
  370. data/lib/mongoid/validatable/associated.rb +19 -7
  371. data/lib/mongoid/validatable/format.rb +0 -2
  372. data/lib/mongoid/validatable/length.rb +0 -2
  373. data/lib/mongoid/validatable/localizable.rb +0 -3
  374. data/lib/mongoid/validatable/macros.rb +0 -2
  375. data/lib/mongoid/validatable/numericality.rb +24 -3
  376. data/lib/mongoid/validatable/presence.rb +8 -10
  377. data/lib/mongoid/validatable/queryable.rb +0 -3
  378. data/lib/mongoid/validatable/uniqueness.rb +12 -14
  379. data/lib/mongoid/validatable.rb +15 -20
  380. data/lib/mongoid/version.rb +1 -1
  381. data/lib/mongoid/warnings.rb +10 -11
  382. data/lib/mongoid.rb +30 -34
  383. data/lib/rails/generators/mongoid/config/config_generator.rb +2 -4
  384. data/lib/rails/generators/mongoid/config/templates/mongoid.rb +4 -5
  385. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +2 -2
  386. data/lib/rails/generators/mongoid/model/model_generator.rb +5 -8
  387. data/lib/rails/generators/mongoid_generator.rb +6 -10
  388. data/lib/rails/mongoid.rb +1 -3
  389. data/spec/integration/active_job_spec.rb +1 -2
  390. data/spec/integration/app_spec.rb +149 -179
  391. data/spec/integration/associations/belongs_to_spec.rb +43 -28
  392. data/spec/integration/associations/embedded_dirty_spec.rb +0 -1
  393. data/spec/integration/associations/embedded_spec.rb +41 -43
  394. data/spec/integration/associations/embeds_many_spec.rb +46 -29
  395. data/spec/integration/associations/embeds_one_spec.rb +2 -1
  396. data/spec/integration/associations/foreign_key_spec.rb +10 -11
  397. data/spec/integration/associations/foreign_key_spec_models.rb +8 -9
  398. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +33 -15
  399. data/spec/integration/associations/has_many_spec.rb +17 -18
  400. data/spec/integration/associations/has_one_spec.rb +42 -45
  401. data/spec/integration/associations/nested_attributes_assignment_spec.rb +36 -39
  402. data/spec/integration/associations/reverse_population_spec.rb +4 -5
  403. data/spec/integration/associations/reverse_population_spec_models.rb +0 -1
  404. data/spec/integration/associations/scope_option_spec.rb +18 -20
  405. data/spec/integration/atomic/modifiers_spec.rb +72 -52
  406. data/spec/integration/bson_regexp_raw_spec.rb +2 -3
  407. data/spec/integration/caching_spec.rb +68 -0
  408. data/spec/integration/callbacks_models.rb +11 -9
  409. data/spec/integration/callbacks_spec.rb +78 -80
  410. data/spec/integration/contextual/empty_spec.rb +19 -20
  411. data/spec/integration/criteria/alias_query_spec.rb +12 -19
  412. data/spec/integration/criteria/date_field_spec.rb +1 -2
  413. data/spec/integration/criteria/default_scope_spec.rb +23 -18
  414. data/spec/integration/criteria/logical_spec.rb +18 -19
  415. data/spec/integration/criteria/range_spec.rb +77 -86
  416. data/spec/integration/criteria/raw_value_spec.rb +122 -109
  417. data/spec/integration/criteria/time_with_zone_spec.rb +33 -24
  418. data/spec/integration/discriminator_key_spec.rb +85 -85
  419. data/spec/integration/discriminator_value_spec.rb +70 -73
  420. data/spec/integration/document_spec.rb +9 -10
  421. data/spec/integration/dots_and_dollars_spec.rb +115 -120
  422. data/spec/integration/encryption_spec.rb +157 -9
  423. data/spec/integration/i18n_fallbacks_spec.rb +7 -8
  424. data/spec/integration/isolation_state_spec.rb +241 -0
  425. data/spec/integration/matcher_examples_spec.rb +145 -168
  426. data/spec/integration/matcher_operator_data/in.yml +6 -6
  427. data/spec/integration/matcher_operator_data/regex.yml +21 -0
  428. data/spec/integration/matcher_operator_spec.rb +16 -26
  429. data/spec/integration/matcher_regexp_timeout_spec.rb +215 -0
  430. data/spec/integration/matcher_spec.rb +31 -32
  431. data/spec/integration/persistence/collection_options_spec.rb +0 -2
  432. data/spec/integration/persistence/range_field_spec.rb +24 -2
  433. data/spec/integration/query_operator_guard_spec.rb +89 -0
  434. data/spec/integration/server_query_spec.rb +43 -37
  435. data/spec/integration/shardable_spec.rb +10 -11
  436. data/spec/integration/stringified_symbol_field_spec.rb +28 -43
  437. data/spec/lite_spec_helper.rb +11 -12
  438. data/spec/mongoid/association/accessors_spec.rb +197 -285
  439. data/spec/mongoid/association/auto_save_spec.rb +62 -93
  440. data/spec/mongoid/association/builders_spec.rb +121 -74
  441. data/spec/mongoid/association/constrainable_spec.rb +9 -22
  442. data/spec/mongoid/association/counter_cache_spec.rb +71 -104
  443. data/spec/mongoid/association/depending_spec.rb +166 -208
  444. data/spec/mongoid/association/eager_loadable_spec.rb +47 -0
  445. data/spec/mongoid/association/eager_spec.rb +416 -80
  446. data/spec/mongoid/association/embedded/cyclic_spec.rb +36 -48
  447. data/spec/mongoid/association/embedded/dirty_spec.rb +15 -20
  448. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +36 -54
  449. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +8 -15
  450. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +135 -175
  451. data/spec/mongoid/association/embedded/embedded_in_spec.rb +25 -127
  452. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +9 -14
  453. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +38 -51
  454. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +1184 -1340
  455. data/spec/mongoid/association/embedded/embeds_many_models.rb +17 -17
  456. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +11 -11
  457. data/spec/mongoid/association/embedded/embeds_many_spec.rb +25 -138
  458. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +15 -23
  459. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +18 -26
  460. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +204 -273
  461. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +0 -1
  462. data/spec/mongoid/association/embedded/embeds_one_models.rb +0 -1
  463. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +5 -6
  464. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -143
  465. data/spec/mongoid/association/fallback_spec.rb +425 -0
  466. data/spec/mongoid/association/macros_spec.rb +239 -300
  467. data/spec/mongoid/association/nested/many_spec.rb +51 -73
  468. data/spec/mongoid/association/nested/one_spec.rb +56 -80
  469. data/spec/mongoid/association/options_spec.rb +187 -310
  470. data/spec/mongoid/association/polymorphic_spec.rb +35 -53
  471. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +55 -76
  472. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +36 -41
  473. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +98 -101
  474. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +258 -345
  475. data/spec/mongoid/association/referenced/belongs_to_models.rb +4 -3
  476. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +3 -4
  477. data/spec/mongoid/association/referenced/belongs_to_spec.rb +91 -294
  478. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +42 -56
  479. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +41 -32
  480. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +36 -42
  481. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +8 -9
  482. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +819 -975
  483. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +9 -9
  484. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +5 -6
  485. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +109 -177
  486. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +29 -43
  487. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +53 -53
  488. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +137 -67
  489. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +431 -675
  490. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -2
  491. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +318 -11
  492. data/spec/mongoid/association/referenced/has_many_models.rb +1 -2
  493. data/spec/mongoid/association/referenced/has_many_query_spec.rb +3 -4
  494. data/spec/mongoid/association/referenced/has_many_spec.rb +44 -188
  495. data/spec/mongoid/association/referenced/has_many_through/eager_spec.rb +58 -0
  496. data/spec/mongoid/association/referenced/has_many_through/proxy_spec.rb +62 -0
  497. data/spec/mongoid/association/referenced/has_many_through_spec.rb +399 -0
  498. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +26 -38
  499. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +28 -29
  500. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +29 -42
  501. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +270 -332
  502. data/spec/mongoid/association/referenced/has_one_models.rb +1 -2
  503. data/spec/mongoid/association/referenced/has_one_query_spec.rb +3 -4
  504. data/spec/mongoid/association/referenced/has_one_spec.rb +40 -188
  505. data/spec/mongoid/association/referenced/has_one_through/eager_spec.rb +58 -0
  506. data/spec/mongoid/association/referenced/has_one_through/proxy_spec.rb +49 -0
  507. data/spec/mongoid/association/referenced/has_one_through_spec.rb +211 -0
  508. data/spec/mongoid/association/reflections_spec.rb +14 -24
  509. data/spec/mongoid/association/syncable_spec.rb +102 -125
  510. data/spec/mongoid/association_spec.rb +47 -70
  511. data/spec/mongoid/atomic/modifiers_spec.rb +184 -197
  512. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +39 -52
  513. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +35 -49
  514. data/spec/mongoid/atomic/paths/root_spec.rb +9 -15
  515. data/spec/mongoid/atomic/paths_spec.rb +81 -117
  516. data/spec/mongoid/atomic_spec.rb +156 -171
  517. data/spec/mongoid/attributes/dynamic_spec.rb +5 -6
  518. data/spec/mongoid/attributes/nested_spec.rb +1461 -1693
  519. data/spec/mongoid/attributes/nested_spec_models.rb +8 -9
  520. data/spec/mongoid/attributes/projector_spec.rb +2 -6
  521. data/spec/mongoid/attributes/readonly_spec.rb +73 -97
  522. data/spec/mongoid/attributes_spec.rb +669 -826
  523. data/spec/mongoid/cacheable_spec.rb +74 -44
  524. data/spec/mongoid/changeable_spec.rb +591 -733
  525. data/spec/mongoid/clients/factory_spec.rb +122 -154
  526. data/spec/mongoid/clients/options_spec.rb +40 -59
  527. data/spec/mongoid/clients/sessions_spec.rb +25 -44
  528. data/spec/mongoid/clients/transactions_spec.rb +33 -50
  529. data/spec/mongoid/clients/transactions_spec_models.rb +3 -4
  530. data/spec/mongoid/clients_spec.rb +265 -355
  531. data/spec/mongoid/collection_configurable_spec.rb +9 -12
  532. data/spec/mongoid/composable_spec.rb +2 -9
  533. data/spec/mongoid/config/defaults_spec.rb +56 -30
  534. data/spec/mongoid/config/encryption_spec.rb +282 -57
  535. data/spec/mongoid/config/environment_spec.rb +30 -40
  536. data/spec/mongoid/config/introspection_spec.rb +42 -37
  537. data/spec/mongoid/config/options_spec.rb +14 -21
  538. data/spec/mongoid/config_spec.rb +145 -195
  539. data/spec/mongoid/contextual/aggregable/memory_spec.rb +189 -135
  540. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +4 -7
  541. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +149 -187
  542. data/spec/mongoid/contextual/aggregable/none_spec.rb +14 -16
  543. data/spec/mongoid/contextual/atomic_spec.rb +223 -271
  544. data/spec/mongoid/contextual/map_reduce_spec.rb +110 -138
  545. data/spec/mongoid/contextual/memory_spec.rb +883 -854
  546. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +12 -13
  547. data/spec/mongoid/contextual/mongo_spec.rb +1008 -1213
  548. data/spec/mongoid/contextual/none_spec.rb +54 -59
  549. data/spec/mongoid/contextual/short_circuit_spec.rb +139 -0
  550. data/spec/mongoid/copyable_spec.rb +254 -300
  551. data/spec/mongoid/copyable_spec_models.rb +0 -1
  552. data/spec/mongoid/criteria/findable_spec.rb +322 -387
  553. data/spec/mongoid/criteria/includable_spec.rb +1356 -432
  554. data/spec/mongoid/criteria/includable_spec_models.rb +16 -7
  555. data/spec/mongoid/criteria/inspectable_spec.rb +11 -14
  556. data/spec/mongoid/criteria/marshalable_spec.rb +11 -14
  557. data/spec/mongoid/criteria/modifiable_spec.rb +366 -512
  558. data/spec/mongoid/criteria/options_spec.rb +2 -7
  559. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +112 -141
  560. data/spec/mongoid/criteria/queryable/expandable_spec.rb +8 -11
  561. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +127 -184
  562. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +123 -60
  563. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +84 -117
  564. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +44 -65
  565. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +86 -108
  566. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +94 -33
  567. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +103 -138
  568. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +95 -34
  569. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +25 -38
  570. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +26 -28
  571. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +32 -54
  572. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +136 -130
  573. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +16 -24
  574. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +15 -24
  575. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +12 -19
  576. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +46 -63
  577. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +28 -42
  578. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +73 -96
  579. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +71 -92
  580. data/spec/mongoid/criteria/queryable/key_spec.rb +32 -36
  581. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +44 -49
  582. data/spec/mongoid/criteria/queryable/optional_spec.rb +373 -486
  583. data/spec/mongoid/criteria/queryable/options_spec.rb +172 -123
  584. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +65 -87
  585. data/spec/mongoid/criteria/queryable/queryable_spec.rb +41 -53
  586. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +589 -679
  587. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +7 -11
  588. data/spec/mongoid/criteria/queryable/selectable_spec.rb +807 -998
  589. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +354 -190
  590. data/spec/mongoid/criteria/queryable/selector_spec.rb +294 -390
  591. data/spec/mongoid/criteria/queryable/smash_spec.rb +6 -11
  592. data/spec/mongoid/criteria/queryable/storable_spec.rb +54 -81
  593. data/spec/mongoid/criteria/queryable_mql_spec.rb +92 -0
  594. data/spec/mongoid/criteria/scopable_spec.rb +102 -138
  595. data/spec/mongoid/criteria/translator_spec.rb +59 -60
  596. data/spec/mongoid/criteria_projection_spec.rb +81 -99
  597. data/spec/mongoid/criteria_spec.rb +937 -949
  598. data/spec/mongoid/document_fields_spec.rb +28 -30
  599. data/spec/mongoid/document_persistence_context_spec.rb +13 -15
  600. data/spec/mongoid/document_query_spec.rb +9 -12
  601. data/spec/mongoid/document_spec.rb +317 -409
  602. data/spec/mongoid/encryptable_spec.rb +61 -0
  603. data/spec/mongoid/equality_spec.rb +69 -102
  604. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +8 -11
  605. data/spec/mongoid/errors/attribute_not_loaded_spec.rb +7 -10
  606. data/spec/mongoid/errors/callback_spec.rb +8 -11
  607. data/spec/mongoid/errors/config_redactor_spec.rb +112 -0
  608. data/spec/mongoid/errors/delete_restriction_spec.rb +5 -8
  609. data/spec/mongoid/errors/document_not_destroyed_spec.rb +7 -10
  610. data/spec/mongoid/errors/document_not_found_spec.rb +51 -61
  611. data/spec/mongoid/errors/invalid_collection_spec.rb +9 -13
  612. data/spec/mongoid/errors/invalid_config_file_spec.rb +8 -11
  613. data/spec/mongoid/errors/invalid_config_option_spec.rb +8 -11
  614. data/spec/mongoid/errors/invalid_field_option_spec.rb +7 -10
  615. data/spec/mongoid/errors/invalid_field_spec.rb +10 -11
  616. data/spec/mongoid/errors/invalid_field_type_spec.rb +9 -12
  617. data/spec/mongoid/errors/invalid_find_spec.rb +8 -11
  618. data/spec/mongoid/errors/invalid_includes_spec.rb +9 -13
  619. data/spec/mongoid/errors/invalid_index_spec.rb +8 -11
  620. data/spec/mongoid/errors/invalid_options_spec.rb +8 -11
  621. data/spec/mongoid/errors/invalid_path_spec.rb +7 -10
  622. data/spec/mongoid/errors/invalid_relation_spec.rb +15 -16
  623. data/spec/mongoid/errors/invalid_scope_spec.rb +8 -11
  624. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -6
  625. data/spec/mongoid/errors/invalid_storage_options_spec.rb +8 -11
  626. data/spec/mongoid/errors/invalid_time_spec.rb +8 -11
  627. data/spec/mongoid/errors/inverse_not_found_spec.rb +9 -12
  628. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +40 -12
  629. data/spec/mongoid/errors/mixed_relations_spec.rb +8 -11
  630. data/spec/mongoid/errors/mongoid_error_spec.rb +21 -24
  631. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -9
  632. data/spec/mongoid/errors/no_client_config_spec.rb +7 -10
  633. data/spec/mongoid/errors/no_client_database_spec.rb +38 -12
  634. data/spec/mongoid/errors/no_client_hosts_spec.rb +35 -12
  635. data/spec/mongoid/errors/no_clients_config_spec.rb +7 -10
  636. data/spec/mongoid/errors/no_environment_spec.rb +8 -11
  637. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +8 -11
  638. data/spec/mongoid/errors/no_metadata_spec.rb +7 -10
  639. data/spec/mongoid/errors/no_parent_spec.rb +7 -10
  640. data/spec/mongoid/errors/readonly_association_spec.rb +34 -0
  641. data/spec/mongoid/errors/readonly_attribute_spec.rb +7 -10
  642. data/spec/mongoid/errors/readonly_document_spec.rb +6 -9
  643. data/spec/mongoid/errors/scope_overwrite_spec.rb +9 -12
  644. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +9 -12
  645. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -8
  646. data/spec/mongoid/errors/unsaved_document_spec.rb +8 -11
  647. data/spec/mongoid/errors/unsupported_javascript_spec.rb +9 -12
  648. data/spec/mongoid/errors/validations_spec.rb +11 -14
  649. data/spec/mongoid/extensions/array_spec.rb +70 -92
  650. data/spec/mongoid/extensions/big_decimal_spec.rb +233 -313
  651. data/spec/mongoid/extensions/binary_spec.rb +21 -32
  652. data/spec/mongoid/extensions/boolean_spec.rb +52 -75
  653. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +43 -54
  654. data/spec/mongoid/extensions/date_spec.rb +26 -38
  655. data/spec/mongoid/extensions/date_time_spec.rb +22 -32
  656. data/spec/mongoid/extensions/decimal128_spec.rb +12 -18
  657. data/spec/mongoid/extensions/false_class_spec.rb +10 -17
  658. data/spec/mongoid/extensions/float_spec.rb +40 -61
  659. data/spec/mongoid/extensions/hash_spec.rb +46 -64
  660. data/spec/mongoid/extensions/integer_spec.rb +40 -61
  661. data/spec/mongoid/extensions/module_spec.rb +13 -18
  662. data/spec/mongoid/extensions/nil_class_spec.rb +2 -5
  663. data/spec/mongoid/extensions/object_id_spec.rb +159 -247
  664. data/spec/mongoid/extensions/object_spec.rb +31 -47
  665. data/spec/mongoid/extensions/range_spec.rb +112 -115
  666. data/spec/mongoid/extensions/raw_value_spec.rb +10 -12
  667. data/spec/mongoid/extensions/regexp_spec.rb +23 -36
  668. data/spec/mongoid/extensions/set_spec.rb +38 -49
  669. data/spec/mongoid/extensions/string_spec.rb +118 -167
  670. data/spec/mongoid/extensions/stringified_symbol_spec.rb +29 -43
  671. data/spec/mongoid/extensions/symbol_spec.rb +12 -20
  672. data/spec/mongoid/extensions/time_spec.rb +160 -202
  673. data/spec/mongoid/extensions/time_with_zone_spec.rb +79 -105
  674. data/spec/mongoid/extensions/true_class_spec.rb +10 -17
  675. data/spec/mongoid/extensions/vector_spec.rb +175 -0
  676. data/spec/mongoid/factory_spec.rb +125 -148
  677. data/spec/mongoid/fields/foreign_key_spec.rb +124 -169
  678. data/spec/mongoid/fields/localized_spec.rb +140 -185
  679. data/spec/mongoid/fields/standard_spec.rb +43 -59
  680. data/spec/mongoid/fields_spec.rb +751 -620
  681. data/spec/mongoid/findable_spec.rb +260 -228
  682. data/spec/mongoid/indexable/specification_spec.rb +42 -58
  683. data/spec/mongoid/indexable_spec.rb +260 -264
  684. data/spec/mongoid/inspectable_spec.rb +45 -55
  685. data/spec/mongoid/interceptable_spec.rb +784 -922
  686. data/spec/mongoid/interceptable_spec_models.rb +35 -35
  687. data/spec/mongoid/loading_spec.rb +47 -43
  688. data/spec/mongoid/loggable_spec.rb +3 -6
  689. data/spec/mongoid/matcher/extract_attribute_spec.rb +2 -6
  690. data/spec/mongoid/matcher/regexp_budget_spec.rb +570 -0
  691. data/spec/mongoid/mongoizable_spec.rb +81 -90
  692. data/spec/mongoid/monkey_patches_spec.rb +4 -0
  693. data/spec/mongoid/persistable/creatable_spec.rb +181 -220
  694. data/spec/mongoid/persistable/deletable_spec.rb +139 -179
  695. data/spec/mongoid/persistable/destroyable_spec.rb +135 -164
  696. data/spec/mongoid/persistable/incrementable_spec.rb +65 -84
  697. data/spec/mongoid/persistable/logical_spec.rb +48 -61
  698. data/spec/mongoid/persistable/maxable_spec.rb +45 -44
  699. data/spec/mongoid/persistable/minable_spec.rb +45 -44
  700. data/spec/mongoid/persistable/multipliable_spec.rb +54 -69
  701. data/spec/mongoid/persistable/poppable_spec.rb +47 -60
  702. data/spec/mongoid/persistable/pullable_spec.rb +79 -103
  703. data/spec/mongoid/persistable/pushable_spec.rb +106 -131
  704. data/spec/mongoid/persistable/renamable_spec.rb +52 -65
  705. data/spec/mongoid/persistable/savable_spec.rb +152 -189
  706. data/spec/mongoid/persistable/settable_spec.rb +121 -145
  707. data/spec/mongoid/persistable/unsettable_spec.rb +56 -73
  708. data/spec/mongoid/persistable/updatable_spec.rb +185 -232
  709. data/spec/mongoid/persistable/upsertable_spec.rb +66 -77
  710. data/spec/mongoid/persistable_spec.rb +132 -139
  711. data/spec/mongoid/persistence_context_spec.rb +31 -89
  712. data/spec/mongoid/positional_spec.rb +67 -79
  713. data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +0 -3
  714. data/spec/mongoid/railties/console_sandbox_spec.rb +0 -1
  715. data/spec/mongoid/relations/proxy_spec.rb +0 -1
  716. data/spec/mongoid/reloadable_spec.rb +250 -145
  717. data/spec/mongoid/scopable_spec.rb +319 -398
  718. data/spec/mongoid/search_indexable_spec.rb +735 -44
  719. data/spec/mongoid/selectable_spec.rb +36 -51
  720. data/spec/mongoid/serializable_spec.rb +269 -312
  721. data/spec/mongoid/shardable_models.rb +5 -5
  722. data/spec/mongoid/shardable_spec.rb +44 -46
  723. data/spec/mongoid/stateful_spec.rb +55 -75
  724. data/spec/mongoid/tasks/database_rake_spec.rb +138 -141
  725. data/spec/mongoid/tasks/database_spec.rb +98 -80
  726. data/spec/mongoid/tasks/encryption_spec.rb +22 -20
  727. data/spec/mongoid/threaded_spec.rb +57 -83
  728. data/spec/mongoid/timestamps/created/short_spec.rb +12 -16
  729. data/spec/mongoid/timestamps/created_spec.rb +16 -20
  730. data/spec/mongoid/timestamps/timeless_spec.rb +228 -48
  731. data/spec/mongoid/timestamps/updated/short_spec.rb +21 -28
  732. data/spec/mongoid/timestamps/updated_spec.rb +18 -25
  733. data/spec/mongoid/timestamps_spec.rb +171 -188
  734. data/spec/mongoid/timestamps_spec_models.rb +12 -13
  735. data/spec/mongoid/touchable_spec.rb +355 -294
  736. data/spec/mongoid/touchable_spec_models.rb +45 -37
  737. data/spec/mongoid/traversable_spec.rb +435 -471
  738. data/spec/mongoid/validatable/associated_spec.rb +60 -59
  739. data/spec/mongoid/validatable/format_spec.rb +24 -34
  740. data/spec/mongoid/validatable/length_spec.rb +62 -86
  741. data/spec/mongoid/validatable/numericality_spec.rb +114 -23
  742. data/spec/mongoid/validatable/presence_spec.rb +149 -203
  743. data/spec/mongoid/validatable/uniqueness_spec.rb +632 -830
  744. data/spec/mongoid/validatable_spec.rb +71 -103
  745. data/spec/mongoid/warnings_spec.rb +5 -9
  746. data/spec/mongoid_spec.rb +25 -41
  747. data/spec/rails/controller_extension/controller_runtime_spec.rb +45 -49
  748. data/spec/rails/mongoid_spec.rb +15 -15
  749. data/spec/shared/lib/mrss/cluster_config.rb +5 -40
  750. data/spec/shared/lib/mrss/constraints.rb +7 -46
  751. data/spec/shared/lib/mrss/docker_runner.rb +10 -21
  752. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -31
  753. data/spec/shared/lib/mrss/release/candidate.rb +18 -12
  754. data/spec/shared/lib/mrss/server_version_registry.rb +1 -5
  755. data/spec/shared/share/Dockerfile.erb +6 -8
  756. data/spec/shared/shlib/server.sh +0 -50
  757. data/spec/shared/shlib/set_env.sh +4 -10
  758. data/spec/spec_helper.rb +59 -32
  759. data/spec/support/authorization.rb +0 -1
  760. data/spec/support/client_registry.rb +1 -2
  761. data/spec/support/constraints.rb +8 -25
  762. data/spec/support/crypt/models.rb +164 -8
  763. data/spec/support/crypt.rb +6 -9
  764. data/spec/support/expectations.rb +21 -7
  765. data/spec/support/feature_sandbox.rb +1 -4
  766. data/spec/support/helpers.rb +0 -1
  767. data/spec/support/immutable_ids.rb +20 -21
  768. data/spec/support/macros.rb +1 -3
  769. data/spec/support/models/account.rb +4 -5
  770. data/spec/support/models/acolyte.rb +5 -5
  771. data/spec/support/models/actor.rb +3 -3
  772. data/spec/support/models/actress.rb +0 -1
  773. data/spec/support/models/address.rb +11 -11
  774. data/spec/support/models/address_component.rb +1 -1
  775. data/spec/support/models/address_number.rb +1 -1
  776. data/spec/support/models/agency.rb +1 -1
  777. data/spec/support/models/agent.rb +1 -1
  778. data/spec/support/models/album.rb +1 -2
  779. data/spec/support/models/alert.rb +1 -1
  780. data/spec/support/models/animal.rb +4 -5
  781. data/spec/support/models/answer.rb +1 -1
  782. data/spec/support/models/appointment.rb +2 -2
  783. data/spec/support/models/armrest.rb +0 -1
  784. data/spec/support/models/array_field.rb +0 -1
  785. data/spec/support/models/article.rb +0 -1
  786. data/spec/support/models/artist.rb +16 -12
  787. data/spec/support/models/artwork.rb +1 -1
  788. data/spec/support/models/audible_sound.rb +0 -1
  789. data/spec/support/models/audio.rb +2 -2
  790. data/spec/support/models/augmentation.rb +1 -2
  791. data/spec/support/models/author.rb +1 -1
  792. data/spec/support/models/baby.rb +1 -1
  793. data/spec/support/models/band.rb +0 -1
  794. data/spec/support/models/bar.rb +2 -2
  795. data/spec/support/models/basic.rb +0 -1
  796. data/spec/support/models/bed.rb +0 -1
  797. data/spec/support/models/big_palette.rb +0 -1
  798. data/spec/support/models/birthday.rb +3 -5
  799. data/spec/support/models/bolt.rb +0 -1
  800. data/spec/support/models/bomb.rb +1 -1
  801. data/spec/support/models/book.rb +1 -1
  802. data/spec/support/models/breed.rb +1 -1
  803. data/spec/support/models/browser.rb +1 -2
  804. data/spec/support/models/building.rb +0 -1
  805. data/spec/support/models/building_address.rb +1 -1
  806. data/spec/support/models/bus.rb +1 -1
  807. data/spec/support/models/business.rb +2 -2
  808. data/spec/support/models/callback_test.rb +1 -1
  809. data/spec/support/models/canvas.rb +5 -6
  810. data/spec/support/models/car.rb +0 -1
  811. data/spec/support/models/cat.rb +0 -2
  812. data/spec/support/models/catalog.rb +0 -1
  813. data/spec/support/models/category.rb +1 -1
  814. data/spec/support/models/child.rb +1 -1
  815. data/spec/support/models/child_doc.rb +5 -6
  816. data/spec/support/models/church.rb +1 -1
  817. data/spec/support/models/circle.rb +0 -1
  818. data/spec/support/models/circuit.rb +2 -2
  819. data/spec/support/models/circus.rb +0 -1
  820. data/spec/support/models/code.rb +2 -1
  821. data/spec/support/models/coding/pull_request.rb +0 -1
  822. data/spec/support/models/coding.rb +0 -1
  823. data/spec/support/models/comment.rb +0 -1
  824. data/spec/support/models/company.rb +0 -1
  825. data/spec/support/models/consumption_period.rb +0 -1
  826. data/spec/support/models/contextable_item.rb +1 -1
  827. data/spec/support/models/contractor.rb +1 -1
  828. data/spec/support/models/cookie.rb +0 -1
  829. data/spec/support/models/country_code.rb +2 -3
  830. data/spec/support/models/courier_job.rb +2 -2
  831. data/spec/support/models/cover.rb +0 -1
  832. data/spec/support/models/crate.rb +0 -1
  833. data/spec/support/models/customer.rb +0 -1
  834. data/spec/support/models/customer_address.rb +0 -1
  835. data/spec/support/models/deed.rb +1 -1
  836. data/spec/support/models/definition.rb +1 -1
  837. data/spec/support/models/delegating_patient.rb +0 -1
  838. data/spec/support/models/description.rb +0 -1
  839. data/spec/support/models/dictionary.rb +1 -1
  840. data/spec/support/models/division.rb +2 -2
  841. data/spec/support/models/doctor.rb +0 -1
  842. data/spec/support/models/dog.rb +2 -2
  843. data/spec/support/models/dokument.rb +1 -1
  844. data/spec/support/models/draft.rb +0 -1
  845. data/spec/support/models/dragon.rb +1 -1
  846. data/spec/support/models/driver.rb +2 -2
  847. data/spec/support/models/drug.rb +1 -1
  848. data/spec/support/models/dungeon.rb +1 -1
  849. data/spec/support/models/edit.rb +1 -1
  850. data/spec/support/models/email.rb +1 -1
  851. data/spec/support/models/employer.rb +1 -2
  852. data/spec/support/models/entry.rb +1 -1
  853. data/spec/support/models/eraser.rb +0 -1
  854. data/spec/support/models/even.rb +1 -1
  855. data/spec/support/models/event.rb +3 -4
  856. data/spec/support/models/exhibition.rb +1 -1
  857. data/spec/support/models/exhibitor.rb +1 -1
  858. data/spec/support/models/explosion.rb +1 -1
  859. data/spec/support/models/eye.rb +0 -1
  860. data/spec/support/models/eye_bowl.rb +2 -3
  861. data/spec/support/models/face.rb +2 -3
  862. data/spec/support/models/fanatic.rb +1 -1
  863. data/spec/support/models/favorite.rb +1 -1
  864. data/spec/support/models/filesystem.rb +1 -1
  865. data/spec/support/models/fire_hydrant.rb +1 -1
  866. data/spec/support/models/firefox.rb +0 -1
  867. data/spec/support/models/fish.rb +0 -1
  868. data/spec/support/models/folder.rb +0 -2
  869. data/spec/support/models/folder_item.rb +1 -3
  870. data/spec/support/models/fruits.rb +9 -5
  871. data/spec/support/models/game.rb +3 -4
  872. data/spec/support/models/ghost.rb +0 -1
  873. data/spec/support/models/guitar.rb +0 -1
  874. data/spec/support/models/hole.rb +0 -1
  875. data/spec/support/models/home.rb +1 -1
  876. data/spec/support/models/house.rb +2 -2
  877. data/spec/support/models/html_writer.rb +0 -1
  878. data/spec/support/models/id_key.rb +3 -3
  879. data/spec/support/models/idnodef.rb +0 -1
  880. data/spec/support/models/image.rb +0 -1
  881. data/spec/support/models/implant.rb +1 -2
  882. data/spec/support/models/instrument.rb +2 -3
  883. data/spec/support/models/item.rb +2 -2
  884. data/spec/support/models/jar.rb +1 -2
  885. data/spec/support/models/kaleidoscope.rb +1 -1
  886. data/spec/support/models/kangaroo.rb +1 -1
  887. data/spec/support/models/label.rb +2 -2
  888. data/spec/support/models/language.rb +1 -1
  889. data/spec/support/models/lat_lng.rb +0 -1
  890. data/spec/support/models/league.rb +1 -1
  891. data/spec/support/models/learner.rb +0 -1
  892. data/spec/support/models/line_item.rb +1 -1
  893. data/spec/support/models/location.rb +1 -1
  894. data/spec/support/models/login.rb +1 -2
  895. data/spec/support/models/manufacturer.rb +0 -1
  896. data/spec/support/models/meat.rb +1 -1
  897. data/spec/support/models/membership.rb +1 -1
  898. data/spec/support/models/message.rb +1 -2
  899. data/spec/support/models/minim.rb +0 -1
  900. data/spec/support/models/mixed_drink.rb +1 -1
  901. data/spec/support/models/modifier_models.rb +25 -0
  902. data/spec/support/models/mop.rb +0 -1
  903. data/spec/support/models/movie.rb +1 -1
  904. data/spec/support/models/my_hash.rb +1 -2
  905. data/spec/support/models/name.rb +4 -5
  906. data/spec/support/models/name_only.rb +0 -1
  907. data/spec/support/models/node.rb +1 -1
  908. data/spec/support/models/note.rb +3 -3
  909. data/spec/support/models/nut.rb +0 -1
  910. data/spec/support/models/odd.rb +1 -1
  911. data/spec/support/models/order.rb +1 -1
  912. data/spec/support/models/ordered_post.rb +1 -1
  913. data/spec/support/models/ordered_preference.rb +1 -1
  914. data/spec/support/models/oscar.rb +1 -1
  915. data/spec/support/models/other_owner_object.rb +0 -1
  916. data/spec/support/models/override.rb +3 -11
  917. data/spec/support/models/ownable.rb +1 -1
  918. data/spec/support/models/owner.rb +1 -1
  919. data/spec/support/models/pack.rb +0 -1
  920. data/spec/support/models/page.rb +3 -3
  921. data/spec/support/models/page_question.rb +1 -1
  922. data/spec/support/models/palette.rb +2 -2
  923. data/spec/support/models/parent.rb +2 -2
  924. data/spec/support/models/parent_doc.rb +1 -1
  925. data/spec/support/models/passport.rb +0 -1
  926. data/spec/support/models/patient.rb +2 -2
  927. data/spec/support/models/pdf_writer.rb +0 -1
  928. data/spec/support/models/pencil.rb +0 -1
  929. data/spec/support/models/person.rb +32 -28
  930. data/spec/support/models/pet.rb +1 -1
  931. data/spec/support/models/pet_owner.rb +1 -1
  932. data/spec/support/models/phone.rb +1 -2
  933. data/spec/support/models/piano.rb +0 -1
  934. data/spec/support/models/pizza.rb +1 -1
  935. data/spec/support/models/player.rb +5 -5
  936. data/spec/support/models/post.rb +12 -12
  937. data/spec/support/models/post_genre.rb +1 -1
  938. data/spec/support/models/powerup.rb +1 -2
  939. data/spec/support/models/preference.rb +2 -2
  940. data/spec/support/models/princess.rb +1 -1
  941. data/spec/support/models/product.rb +3 -3
  942. data/spec/support/models/profile.rb +2 -1
  943. data/spec/support/models/pronunciation.rb +1 -1
  944. data/spec/support/models/pub.rb +2 -2
  945. data/spec/support/models/publication/encyclopedia.rb +0 -1
  946. data/spec/support/models/publication/review.rb +0 -1
  947. data/spec/support/models/publication.rb +0 -1
  948. data/spec/support/models/purchase.rb +1 -1
  949. data/spec/support/models/purchased_item.rb +1 -1
  950. data/spec/support/models/question.rb +2 -2
  951. data/spec/support/models/quiz.rb +1 -1
  952. data/spec/support/models/rating.rb +1 -1
  953. data/spec/support/models/record.rb +2 -3
  954. data/spec/support/models/registry.rb +1 -1
  955. data/spec/support/models/role.rb +1 -1
  956. data/spec/support/models/root_category.rb +1 -1
  957. data/spec/support/models/sandbox/app/models/app_models_message.rb +0 -1
  958. data/spec/support/models/sandbox/lib/models/lib_models_message.rb +0 -1
  959. data/spec/support/models/sandbox/sandbox_message.rb +0 -1
  960. data/spec/support/models/sandbox/sandbox_user.rb +0 -1
  961. data/spec/support/models/sandbox/subdir/sandbox_comment.rb +0 -1
  962. data/spec/support/models/sandwich.rb +1 -1
  963. data/spec/support/models/scheduler.rb +0 -1
  964. data/spec/support/models/school.rb +0 -1
  965. data/spec/support/models/scribe.rb +1 -1
  966. data/spec/support/models/sealer.rb +0 -1
  967. data/spec/support/models/seat.rb +0 -1
  968. data/spec/support/models/seo.rb +1 -1
  969. data/spec/support/models/series.rb +1 -1
  970. data/spec/support/models/server.rb +1 -1
  971. data/spec/support/models/service.rb +2 -2
  972. data/spec/support/models/shape.rb +3 -3
  973. data/spec/support/models/shelf.rb +1 -1
  974. data/spec/support/models/shield.rb +2 -2
  975. data/spec/support/models/shipment_address.rb +0 -1
  976. data/spec/support/models/shipping_container.rb +1 -1
  977. data/spec/support/models/shipping_pack.rb +0 -1
  978. data/spec/support/models/shirt.rb +0 -1
  979. data/spec/support/models/shop.rb +2 -2
  980. data/spec/support/models/short_agent.rb +0 -1
  981. data/spec/support/models/short_quiz.rb +1 -1
  982. data/spec/support/models/simple.rb +1 -1
  983. data/spec/support/models/slave.rb +1 -1
  984. data/spec/support/models/song.rb +1 -2
  985. data/spec/support/models/sound.rb +2 -2
  986. data/spec/support/models/spacer.rb +0 -1
  987. data/spec/support/models/square.rb +0 -1
  988. data/spec/support/models/staff.rb +0 -1
  989. data/spec/support/models/store_as_dup_test1.rb +2 -2
  990. data/spec/support/models/store_as_dup_test2.rb +1 -1
  991. data/spec/support/models/store_as_dup_test3.rb +2 -2
  992. data/spec/support/models/store_as_dup_test4.rb +1 -1
  993. data/spec/support/models/strategy.rb +0 -1
  994. data/spec/support/models/student.rb +1 -2
  995. data/spec/support/models/sub_item.rb +0 -1
  996. data/spec/support/models/subscription.rb +2 -2
  997. data/spec/support/models/survey.rb +2 -2
  998. data/spec/support/models/symptom.rb +2 -2
  999. data/spec/support/models/system_role.rb +2 -3
  1000. data/spec/support/models/tag.rb +2 -2
  1001. data/spec/support/models/target.rb +1 -1
  1002. data/spec/support/models/template.rb +1 -1
  1003. data/spec/support/models/thing.rb +1 -1
  1004. data/spec/support/models/threadlocker.rb +0 -1
  1005. data/spec/support/models/title.rb +0 -1
  1006. data/spec/support/models/tool.rb +3 -3
  1007. data/spec/support/models/topping.rb +1 -1
  1008. data/spec/support/models/toy.rb +0 -1
  1009. data/spec/support/models/track.rb +1 -1
  1010. data/spec/support/models/translation.rb +1 -1
  1011. data/spec/support/models/tree.rb +2 -3
  1012. data/spec/support/models/truck.rb +0 -1
  1013. data/spec/support/models/updatable.rb +0 -1
  1014. data/spec/support/models/user.rb +3 -4
  1015. data/spec/support/models/user_account.rb +3 -3
  1016. data/spec/support/models/validation_callback.rb +4 -4
  1017. data/spec/support/models/vehicle.rb +2 -3
  1018. data/spec/support/models/version.rb +1 -1
  1019. data/spec/support/models/vertex.rb +0 -1
  1020. data/spec/support/models/vet_visit.rb +1 -1
  1021. data/spec/support/models/video.rb +2 -2
  1022. data/spec/support/models/video_game.rb +0 -1
  1023. data/spec/support/models/washer.rb +0 -1
  1024. data/spec/support/models/weapon.rb +1 -2
  1025. data/spec/support/models/wiki_page.rb +2 -3
  1026. data/spec/support/models/word.rb +2 -2
  1027. data/spec/support/models/word_origin.rb +1 -2
  1028. data/spec/support/models/writer.rb +3 -3
  1029. data/spec/support/rails_mock.rb +7 -12
  1030. data/spec/support/shared/time.rb +0 -1
  1031. data/spec/support/sinatra_mock.rb +4 -2
  1032. data/spec/support/spec_config.rb +19 -18
  1033. metadata +64 -2
@@ -1,19 +1,17 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
- require "spec_helper"
3
+ require 'spec_helper'
5
4
 
6
5
  describe Mongoid::Contextual::Memory do
7
-
8
- shared_examples "raises an error when no documents" do
9
- context "when there are no matching documents" do
6
+ shared_examples 'raises an error when no documents' do
7
+ context 'when there are no matching documents' do
10
8
  let(:criteria) do
11
9
  Address.all.tap do |crit|
12
10
  crit.documents = []
13
11
  end
14
12
  end
15
13
 
16
- it "returns nil" do
14
+ it 'returns nil' do
17
15
  expect do
18
16
  context.send(method)
19
17
  end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Address./)
@@ -21,36 +19,33 @@ describe Mongoid::Contextual::Memory do
21
19
  end
22
20
  end
23
21
 
24
- shared_examples "returns nil when no documents" do
25
- context "when there are no matching documents" do
22
+ shared_examples 'returns nil when no documents' do
23
+ context 'when there are no matching documents' do
26
24
  let(:criteria) do
27
25
  Address.all.tap do |crit|
28
26
  crit.documents = []
29
27
  end
30
28
  end
31
29
 
32
- it "returns nil" do
30
+ it 'returns nil' do
33
31
  expect(context.send(method)).to be_nil
34
32
  end
35
33
  end
36
34
  end
37
35
 
38
- [ :blank?, :empty? ].each do |method|
39
-
36
+ %i[blank? empty?].each do |method|
40
37
  describe "##{method}" do
41
-
42
38
  let(:hobrecht) do
43
- Address.new(street: "hobrecht")
39
+ Address.new(street: 'hobrecht')
44
40
  end
45
41
 
46
42
  let(:friedel) do
47
- Address.new(street: "friedel")
43
+ Address.new(street: 'friedel')
48
44
  end
49
45
 
50
- context "when there are matching documents" do
51
-
46
+ context 'when there are matching documents' do
52
47
  let(:criteria) do
53
- Address.where(street: "hobrecht").tap do |crit|
48
+ Address.where(street: 'hobrecht').tap do |crit|
54
49
  crit.documents = [ hobrecht, friedel ]
55
50
  end
56
51
  end
@@ -59,15 +54,14 @@ describe Mongoid::Contextual::Memory do
59
54
  described_class.new(criteria)
60
55
  end
61
56
 
62
- it "returns false" do
57
+ it 'returns false' do
63
58
  expect(context.send(method)).to be false
64
59
  end
65
60
  end
66
61
 
67
- context "when there are no matching documents" do
68
-
62
+ context 'when there are no matching documents' do
69
63
  let(:criteria) do
70
- Address.where(street: "pfluger").tap do |crit|
64
+ Address.where(street: 'pfluger').tap do |crit|
71
65
  crit.documents = [ hobrecht, friedel ]
72
66
  end
73
67
  end
@@ -76,40 +70,38 @@ describe Mongoid::Contextual::Memory do
76
70
  described_class.new(criteria)
77
71
  end
78
72
 
79
- it "returns true" do
73
+ it 'returns true' do
80
74
  expect(context.send(method)).to be true
81
75
  end
82
76
  end
83
77
 
84
78
  context 'when there is a collation on the criteria' do
85
-
86
79
  let(:criteria) do
87
- Address.where(street: "hobrecht").tap do |crit|
80
+ Address.where(street: 'hobrecht').tap do |crit|
88
81
  crit.documents = [ hobrecht, friedel ]
89
82
  end.collation(locale: 'en_US', strength: 2)
90
83
  end
91
84
 
92
- it "raises an exception" do
93
- expect {
85
+ it 'raises an exception' do
86
+ expect do
94
87
  context.send(method)
95
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
88
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
96
89
  end
97
90
  end
98
91
  end
99
92
  end
100
93
 
101
- describe "#count" do
102
-
94
+ describe '#count' do
103
95
  let!(:hobrecht) do
104
- Address.new(street: "hobrecht")
96
+ Address.new(street: 'hobrecht')
105
97
  end
106
98
 
107
99
  let!(:friedel) do
108
- Address.new(street: "friedel")
100
+ Address.new(street: 'friedel')
109
101
  end
110
102
 
111
103
  let(:criteria) do
112
- Address.where(street: "hobrecht").tap do |crit|
104
+ Address.where(street: 'hobrecht').tap do |crit|
113
105
  crit.documents = [ hobrecht, friedel ]
114
106
  end
115
107
  end
@@ -118,107 +110,96 @@ describe Mongoid::Contextual::Memory do
118
110
  described_class.new(criteria)
119
111
  end
120
112
 
121
- context "context when no arguments are provided" do
122
-
123
- it "returns the number of matches" do
113
+ context 'context when no arguments are provided' do
114
+ it 'returns the number of matches' do
124
115
  expect(context.count).to eq(1)
125
116
  end
126
117
  end
127
118
 
128
119
  context 'when there is a collation on the criteria' do
129
-
130
120
  let(:criteria) do
131
- Address.where(street: "hobrecht").tap do |crit|
121
+ Address.where(street: 'hobrecht').tap do |crit|
132
122
  crit.documents = [ hobrecht, friedel ]
133
123
  end.collation(locale: 'en_US', strength: 2)
134
124
  end
135
125
 
136
- it "raises an exception" do
137
- expect {
126
+ it 'raises an exception' do
127
+ expect do
138
128
  context.count
139
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
129
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
140
130
  end
141
131
  end
142
132
 
143
- context "when provided a document" do
144
-
145
- context "when the document matches" do
146
-
133
+ context 'when provided a document' do
134
+ context 'when the document matches' do
147
135
  let(:count) do
148
136
  context.count(hobrecht)
149
137
  end
150
138
 
151
- it "returns 1" do
139
+ it 'returns 1' do
152
140
  expect(count).to eq(1)
153
141
  end
154
142
  end
155
143
 
156
- context "when the document does not match" do
157
-
144
+ context 'when the document does not match' do
158
145
  let(:count) do
159
146
  context.count(friedel)
160
147
  end
161
148
 
162
- it "returns 0" do
149
+ it 'returns 0' do
163
150
  expect(count).to eq(0)
164
151
  end
165
152
  end
166
153
  end
167
154
 
168
- context "when provided a block" do
169
-
170
- context "when the block evals 1 to true" do
171
-
155
+ context 'when provided a block' do
156
+ context 'when the block evals 1 to true' do
172
157
  let(:count) do
173
158
  context.count do |doc|
174
- doc.street == "hobrecht"
159
+ doc.street == 'hobrecht'
175
160
  end
176
161
  end
177
162
 
178
- it "returns 1" do
163
+ it 'returns 1' do
179
164
  expect(count).to eq(1)
180
165
  end
181
166
  end
182
167
 
183
- context "when the block evals none to true" do
184
-
168
+ context 'when the block evals none to true' do
185
169
  let(:count) do
186
170
  context.count do |doc|
187
- doc.street == "friedel"
171
+ doc.street == 'friedel'
188
172
  end
189
173
  end
190
174
 
191
- it "returns 0" do
175
+ it 'returns 0' do
192
176
  expect(count).to eq(0)
193
177
  end
194
178
  end
195
179
  end
196
180
  end
197
181
 
198
- [ :delete, :delete_all ].each do |method|
199
-
182
+ %i[delete delete_all].each do |method|
200
183
  let(:person) do
201
184
  Person.create!
202
185
  end
203
186
 
204
187
  let(:hobrecht) do
205
- person.addresses.create!(street: "hobrecht")
188
+ person.addresses.create!(street: 'hobrecht')
206
189
  end
207
190
 
208
191
  let(:friedel) do
209
- person.addresses.create!(street: "friedel")
192
+ person.addresses.create!(street: 'friedel')
210
193
  end
211
194
 
212
195
  let(:pfluger) do
213
- person.addresses.create!(street: "pfluger")
196
+ person.addresses.create!(street: 'pfluger')
214
197
  end
215
198
 
216
199
  describe "##{method}" do
217
-
218
- context "when embedded a single level" do
219
-
200
+ context 'when embedded a single level' do
220
201
  let(:criteria) do
221
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
202
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
222
203
  crit.documents = [ hobrecht, friedel, pfluger ]
223
204
  end
224
205
  end
@@ -231,47 +212,46 @@ describe Mongoid::Contextual::Memory do
231
212
  context.send(method)
232
213
  end
233
214
 
234
- it "deletes the first matching document" do
215
+ it 'deletes the first matching document' do
235
216
  expect(hobrecht).to be_destroyed
236
217
  end
237
218
 
238
- it "deletes the last matching document" do
219
+ it 'deletes the last matching document' do
239
220
  expect(friedel).to be_destroyed
240
221
  end
241
222
 
242
- it "does not delete non matching docs" do
243
- expect(pfluger).to_not be_destroyed
223
+ it 'does not delete non matching docs' do
224
+ expect(pfluger).not_to be_destroyed
244
225
  end
245
226
 
246
- it "removes the docs from the relation" do
227
+ it 'removes the docs from the relation' do
247
228
  expect(person.addresses).to eq([ pfluger ])
248
229
  end
249
230
 
250
- it "removes the docs from the context" do
231
+ it 'removes the docs from the context' do
251
232
  expect(context.entries).to be_empty
252
233
  end
253
234
 
254
- it "persists the changes to the database" do
235
+ it 'persists the changes to the database' do
255
236
  expect(person.reload.addresses).to eq([ pfluger ])
256
237
  end
257
238
 
258
- it "returns the number of deleted documents" do
239
+ it 'returns the number of deleted documents' do
259
240
  expect(deleted).to eq(2)
260
241
  end
261
242
  end
262
243
 
263
- context "when embedded multiple levels" do
264
-
244
+ context 'when embedded multiple levels' do
265
245
  let!(:home) do
266
- hobrecht.locations.create!(name: "home")
246
+ hobrecht.locations.create!(name: 'home')
267
247
  end
268
248
 
269
249
  let!(:work) do
270
- hobrecht.locations.create!(name: "work")
250
+ hobrecht.locations.create!(name: 'work')
271
251
  end
272
252
 
273
253
  let(:criteria) do
274
- Location.where(name: "work").tap do |crit|
254
+ Location.where(name: 'work').tap do |crit|
275
255
  crit.documents = [ home, work ]
276
256
  end
277
257
  end
@@ -284,68 +264,66 @@ describe Mongoid::Contextual::Memory do
284
264
  context.send(method)
285
265
  end
286
266
 
287
- it "deletes the first matching document" do
267
+ it 'deletes the first matching document' do
288
268
  expect(work).to be_destroyed
289
269
  end
290
270
 
291
- it "does not delete non matching docs" do
292
- expect(home).to_not be_destroyed
271
+ it 'does not delete non matching docs' do
272
+ expect(home).not_to be_destroyed
293
273
  end
294
274
 
295
- it "removes the docs from the relation" do
275
+ it 'removes the docs from the relation' do
296
276
  expect(person.addresses.first.locations).to eq([ home ])
297
277
  end
298
278
 
299
- it "removes the docs from the context" do
279
+ it 'removes the docs from the context' do
300
280
  expect(context.entries).to be_empty
301
281
  end
302
282
 
303
- it "persists the changes to the database" do
283
+ it 'persists the changes to the database' do
304
284
  expect(person.reload.addresses.first.locations).to eq([ home ])
305
285
  end
306
286
 
307
- it "returns the number of deleted documents" do
287
+ it 'returns the number of deleted documents' do
308
288
  expect(deleted).to eq(1)
309
289
  end
310
290
  end
311
291
 
312
292
  context 'when there is a collation on the criteria' do
313
-
314
293
  let(:criteria) do
315
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
294
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
316
295
  crit.documents = [ hobrecht, friedel, pfluger ]
317
296
  end.collation(locale: 'en_US', strength: 2)
318
297
  end
319
298
 
320
- it "raises an exception" do
321
- expect {
299
+ it 'raises an exception' do
300
+ expect do
322
301
  context.send(method)
323
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
302
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
324
303
  end
325
304
  end
326
305
  end
327
306
  end
328
307
 
329
- [ :destroy, :destroy_all ].each do |method|
330
-
308
+ %i[destroy destroy_all].each do |method|
331
309
  let(:person) do
332
310
  Person.create!
333
311
  end
334
312
 
335
313
  let(:hobrecht) do
336
- person.addresses.create!(street: "hobrecht")
314
+ person.addresses.create!(street: 'hobrecht')
337
315
  end
338
316
 
339
317
  let(:friedel) do
340
- person.addresses.create!(street: "friedel")
318
+ person.addresses.create!(street: 'friedel')
341
319
  end
342
320
 
343
321
  let(:pfluger) do
344
- person.addresses.create!(street: "pfluger")
322
+ person.addresses.create!(street: 'pfluger')
345
323
  end
346
324
 
347
325
  let(:criteria) do
348
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
326
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
349
327
  crit.documents = [ hobrecht, friedel, pfluger ]
350
328
  end
351
329
  end
@@ -355,63 +333,60 @@ describe Mongoid::Contextual::Memory do
355
333
  end
356
334
 
357
335
  describe "##{method}" do
358
-
359
336
  context 'when there is no collation on the criteria' do
360
-
361
337
  let!(:destroyed) do
362
338
  context.send(method)
363
339
  end
364
340
 
365
- it "deletes the first matching document" do
341
+ it 'deletes the first matching document' do
366
342
  expect(hobrecht).to be_destroyed
367
343
  end
368
344
 
369
- it "deletes the last matching document" do
345
+ it 'deletes the last matching document' do
370
346
  expect(friedel).to be_destroyed
371
347
  end
372
348
 
373
- it "does not delete non matching docs" do
374
- expect(pfluger).to_not be_destroyed
349
+ it 'does not delete non matching docs' do
350
+ expect(pfluger).not_to be_destroyed
375
351
  end
376
352
 
377
- it "removes the docs from the relation" do
353
+ it 'removes the docs from the relation' do
378
354
  expect(person.addresses).to eq([ pfluger ])
379
355
  end
380
356
 
381
- it "removes the docs from the context" do
357
+ it 'removes the docs from the context' do
382
358
  expect(context.entries).to be_empty
383
359
  end
384
360
 
385
- it "persists the changes to the database" do
361
+ it 'persists the changes to the database' do
386
362
  expect(person.reload.addresses).to eq([ pfluger ])
387
363
  end
388
364
 
389
- it "returns the number of destroyed documents" do
365
+ it 'returns the number of destroyed documents' do
390
366
  expect(destroyed).to eq(2)
391
367
  end
392
368
  end
393
369
 
394
370
  context 'when there is a collation on the criteria' do
395
-
396
371
  let(:criteria) do
397
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
372
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
398
373
  crit.documents = [ hobrecht, friedel, pfluger ]
399
374
  end.collation(locale: 'en_US', strength: 2)
400
375
  end
401
376
 
402
- it "raises an exception" do
403
- expect {
377
+ it 'raises an exception' do
378
+ expect do
404
379
  context.send(method)
405
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
380
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
406
381
  end
407
382
  end
408
383
  end
409
384
  end
410
385
 
411
- describe "#distinct" do
412
- let(:depeche) { Band.create!(name: "Depeche Mode", years: 30, sales: "1E2") }
413
- let(:new_order) { Band.create!(name: "New Order", years: 25, sales: "2E3") }
414
- let(:maniacs) { Band.create!(name: "10,000 Maniacs", years: 20, sales: "1E2") }
386
+ describe '#distinct' do
387
+ let(:depeche) { Band.create!(name: 'Depeche Mode', years: 30, sales: '1E2') }
388
+ let(:new_order) { Band.create!(name: 'New Order', years: 25, sales: '2E3') }
389
+ let(:maniacs) { Band.create!(name: '10,000 Maniacs', years: 20, sales: '1E2') }
415
390
 
416
391
  let(:criteria) do
417
392
  Band.all.tap do |crit|
@@ -423,41 +398,37 @@ describe Mongoid::Contextual::Memory do
423
398
  described_class.new(criteria)
424
399
  end
425
400
 
426
- context "when limiting the result set" do
427
-
401
+ context 'when limiting the result set' do
428
402
  let(:criteria) do
429
- Band.where(name: "Depeche Mode").tap do |crit|
403
+ Band.where(name: 'Depeche Mode').tap do |crit|
430
404
  crit.documents = [ depeche ]
431
405
  end
432
406
  end
433
407
 
434
- it "returns the distinct matching fields" do
435
- expect(context.distinct(:name)).to eq([ "Depeche Mode" ])
408
+ it 'returns the distinct matching fields' do
409
+ expect(context.distinct(:name)).to eq([ 'Depeche Mode' ])
436
410
  end
437
411
  end
438
412
 
439
- context "when not limiting the result set" do
440
-
441
- it "returns the distinct field values" do
442
- expect(context.distinct(:name).sort).to eq([ "10,000 Maniacs", "Depeche Mode", "New Order" ].sort)
413
+ context 'when not limiting the result set' do
414
+ it 'returns the distinct field values' do
415
+ expect(context.distinct(:name).sort).to eq([ '10,000 Maniacs', 'Depeche Mode', 'New Order' ].sort)
443
416
  end
444
417
  end
445
418
 
446
- context "when providing an aliased field" do
447
-
448
- it "returns the distinct field values" do
419
+ context 'when providing an aliased field' do
420
+ it 'returns the distinct field values' do
449
421
  expect(context.distinct(:years).sort).to eq([ 20, 25, 30 ])
450
422
  end
451
423
  end
452
424
 
453
- context "when providing a demongoizable field" do
454
-
455
- it "returns the non-demongoized distinct field values" do
456
- expect(context.distinct(:sales).sort).to eq([ BigDecimal("1E2"), BigDecimal("2E3") ])
425
+ context 'when providing a demongoizable field' do
426
+ it 'returns the non-demongoized distinct field values' do
427
+ expect(context.distinct(:sales).sort).to eq([ BigDecimal('1E2'), BigDecimal('2E3') ])
457
428
  end
458
429
  end
459
430
 
460
- context "when getting a localized field" do
431
+ context 'when getting a localized field' do
461
432
  with_default_i18n_configs
462
433
 
463
434
  before do
@@ -474,38 +445,36 @@ describe Mongoid::Contextual::Memory do
474
445
  end
475
446
  end
476
447
 
477
- context "when getting the field without _translations" do
478
- it "gets the demongoized localized field" do
448
+ context 'when getting the field without _translations' do
449
+ it 'gets the demongoized localized field' do
479
450
  expect(context.distinct(:description)).to eq([ 'deutsch-text' ])
480
451
  end
481
452
  end
482
453
 
483
- context "when getting the field with _translations" do
484
-
485
- it "gets the full hash" do
486
- expect(context.distinct(:description_translations)).to eq([ { "de" => "deutsch-text", "en" => "english-text" } ])
454
+ context 'when getting the field with _translations' do
455
+ it 'gets the full hash' do
456
+ expect(context.distinct(:description_translations)).to eq([ { 'de' => 'deutsch-text',
457
+ 'en' => 'english-text' } ])
487
458
  end
488
459
  end
489
460
 
490
461
  context 'when plucking a specific locale' do
491
-
492
462
  let(:distinct) do
493
463
  context.distinct(:'description.de')
494
464
  end
495
465
 
496
466
  it 'returns the specific translation' do
497
- expect(distinct).to eq([ "deutsch-text" ])
467
+ expect(distinct).to eq([ 'deutsch-text' ])
498
468
  end
499
469
  end
500
470
 
501
471
  context 'when plucking a specific locale from _translations field' do
502
-
503
472
  let(:distinct) do
504
473
  context.distinct(:'description_translations.de')
505
474
  end
506
475
 
507
476
  it 'returns the specific translations' do
508
- expect(distinct).to eq(['deutsch-text'])
477
+ expect(distinct).to eq([ 'deutsch-text' ])
509
478
  end
510
479
  end
511
480
 
@@ -521,62 +490,61 @@ describe Mongoid::Contextual::Memory do
521
490
  context.distinct(:description).first
522
491
  end
523
492
 
524
- it "correctly uses the fallback" do
493
+ it 'correctly uses the fallback' do
525
494
  I18n.locale = :en
526
495
  Dictionary.create!(description: 'english-text')
527
496
  I18n.locale = :he
528
- distinct.should == "english-text"
497
+ distinct.should eq 'english-text'
529
498
  end
530
499
  end
531
500
 
532
- context "when the localized field is embedded" do
501
+ context 'when the localized field is embedded' do
533
502
  with_default_i18n_configs
534
503
 
535
504
  let(:person) do
536
505
  p = Passport.new
537
506
  I18n.locale = :en
538
- p.name = "Neil"
507
+ p.name = 'Neil'
539
508
  I18n.locale = :he
540
- p.name = "Nissim"
509
+ p.name = 'Nissim'
541
510
 
542
- Person.create!(passport: p, employer_id: 12345)
511
+ Person.create!(passport: p, employer_id: 12_345)
543
512
  end
544
513
 
545
514
  let(:criteria) do
546
- Person.where(employer_id: 12345).tap do |crit|
515
+ Person.where(employer_id: 12_345).tap do |crit|
547
516
  crit.documents = [ person ]
548
517
  end
549
518
  end
550
519
 
551
520
  let(:distinct) do
552
- context.distinct("pass.name").first
521
+ context.distinct('pass.name').first
553
522
  end
554
523
 
555
524
  let(:distinct_translations) do
556
- context.distinct("pass.name_translations").first
525
+ context.distinct('pass.name_translations').first
557
526
  end
558
527
 
559
528
  let(:distinct_translations_field) do
560
- context.distinct("pass.name_translations.en").first
529
+ context.distinct('pass.name_translations.en').first
561
530
  end
562
531
 
563
- it "returns the translation for the current locale" do
564
- expect(distinct).to eq("Nissim")
532
+ it 'returns the translation for the current locale' do
533
+ expect(distinct).to eq('Nissim')
565
534
  end
566
535
 
567
- it "returns the full _translation hash" do
568
- expect(distinct_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
536
+ it 'returns the full _translation hash' do
537
+ expect(distinct_translations).to eq({ 'en' => 'Neil', 'he' => 'Nissim' })
569
538
  end
570
539
 
571
- it "returns the translation for the requested locale" do
572
- expect(distinct_translations_field).to eq("Neil")
540
+ it 'returns the translation for the requested locale' do
541
+ expect(distinct_translations_field).to eq('Neil')
573
542
  end
574
543
  end
575
544
  end
576
545
 
577
- context "when getting an embedded field" do
578
-
579
- let(:label) { Label.new(sales: "1E2") }
546
+ context 'when getting an embedded field' do
547
+ let(:label) { Label.new(sales: '1E2') }
580
548
  let!(:band) { Band.create!(label: label) }
581
549
  let(:criteria) do
582
550
  Band.where(_id: band.id).tap do |crit|
@@ -584,24 +552,44 @@ describe Mongoid::Contextual::Memory do
584
552
  end
585
553
  end
586
554
 
587
- it "returns the distinct matching fields" do
588
- expect(context.distinct("label.sales")).to eq([ BigDecimal("1E2") ])
555
+ it 'returns the distinct matching fields' do
556
+ expect(context.distinct('label.sales')).to eq([ BigDecimal('1E2') ])
589
557
  end
590
558
  end
591
- end
592
559
 
593
- describe "#each" do
560
+ context 'when the field name is a method name' do
561
+ let!(:person) do
562
+ Person.create!(ssn: 'secret-ssn')
563
+ end
564
+
565
+ let!(:address) do
566
+ person.addresses.create!(street: 'hobrecht')
567
+ end
594
568
 
569
+ let(:criteria) do
570
+ Address.all.tap do |crit|
571
+ crit.documents = [ address ]
572
+ end
573
+ end
574
+
575
+ it 'does not call the method' do
576
+ expect(address).not_to receive(:destroy)
577
+ expect(context.distinct(:destroy)).to eq([ nil ])
578
+ end
579
+ end
580
+ end
581
+
582
+ describe '#each' do
595
583
  let(:hobrecht) do
596
- Address.new(street: "hobrecht")
584
+ Address.new(street: 'hobrecht')
597
585
  end
598
586
 
599
587
  let(:friedel) do
600
- Address.new(street: "friedel")
588
+ Address.new(street: 'friedel')
601
589
  end
602
590
 
603
591
  let(:criteria) do
604
- Address.where(street: "hobrecht").tap do |crit|
592
+ Address.where(street: 'hobrecht').tap do |crit|
605
593
  crit.documents = [ hobrecht, friedel ]
606
594
  end
607
595
  end
@@ -610,65 +598,52 @@ describe Mongoid::Contextual::Memory do
610
598
  described_class.new(criteria)
611
599
  end
612
600
 
613
- context "when skip and limit outside of range" do
614
-
601
+ context 'when skip and limit outside of range' do
615
602
  before do
616
603
  context.skip(10).limit(2)
617
604
  end
618
605
 
619
- it "contains no documents" do
606
+ it 'contains no documents' do
620
607
  expect(context.map(&:street)).to be_empty
621
608
  end
622
609
 
623
- context "when calling next on the enumerator" do
624
-
625
- it "raises a stop iteration error" do
626
- expect {
610
+ context 'when calling next on the enumerator' do
611
+ it 'raises a stop iteration error' do
612
+ expect do
627
613
  context.each.next
628
- }.to raise_error(StopIteration)
614
+ end.to raise_error(StopIteration)
629
615
  end
630
616
  end
631
617
  end
632
618
 
633
- context "when providing a block" do
634
-
635
- it "yields mongoid documents to the block" do
636
- context.each do |doc|
637
- expect(doc).to be_a(Mongoid::Document)
638
- end
619
+ context 'when providing a block' do
620
+ it 'yields mongoid documents to the block' do
621
+ expect(context).to all(be_a(Mongoid::Document))
639
622
  end
640
623
 
641
- it "iterates over the matching documents" do
642
- context.each do |doc|
643
- expect(doc).to eq(hobrecht)
644
- end
624
+ it 'iterates over the matching documents' do
625
+ expect(context).to all(eq(hobrecht))
645
626
  end
646
627
  end
647
628
 
648
- context "when no block is provided" do
649
-
629
+ context 'when no block is provided' do
650
630
  let(:enum) do
651
631
  context.each
652
632
  end
653
633
 
654
- it "returns an enumerator" do
634
+ it 'returns an enumerator' do
655
635
  expect(enum).to be_a(Enumerator)
656
636
  end
657
637
 
658
- context "when iterating over the enumerator" do
659
-
660
- context "when iterating with each" do
661
-
662
- it "yields mongoid documents to the block" do
663
- enum.each do |doc|
664
- expect(doc).to be_a(Mongoid::Document)
665
- end
638
+ context 'when iterating over the enumerator' do
639
+ context 'when iterating with each' do
640
+ it 'yields mongoid documents to the block' do
641
+ expect(enum).to all(be_a(Mongoid::Document))
666
642
  end
667
643
  end
668
644
 
669
- context "when iterating with next" do
670
-
671
- it "yields mongoid documents" do
645
+ context 'when iterating with next' do
646
+ it 'yields mongoid documents' do
672
647
  expect(enum.next).to be_a(Mongoid::Document)
673
648
  end
674
649
  end
@@ -676,54 +651,49 @@ describe Mongoid::Contextual::Memory do
676
651
  end
677
652
 
678
653
  context 'when there is a collation on the criteria' do
679
-
680
654
  let(:criteria) do
681
- Address.where(street: "hobrecht").tap do |crit|
655
+ Address.where(street: 'hobrecht').tap do |crit|
682
656
  crit.documents = [ hobrecht, friedel ]
683
657
  end.collation(locale: 'en_US', strength: 2)
684
658
  end
685
659
 
686
- it "raises an exception" do
687
- expect {
660
+ it 'raises an exception' do
661
+ expect do
688
662
  context.each
689
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
663
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
690
664
  end
691
665
  end
692
666
  end
693
667
 
694
- describe "#exists?" do
695
-
668
+ describe '#exists?' do
696
669
  let(:hobrecht) do
697
- Address.new(street: "hobrecht")
670
+ Address.new(street: 'hobrecht')
698
671
  end
699
672
 
700
673
  let(:friedel) do
701
- Address.new(street: "friedel")
674
+ Address.new(street: 'friedel')
702
675
  end
703
676
 
704
677
  let(:criteria) do
705
- Address.where(street: "hobrecht").tap do |crit|
678
+ Address.where(street: 'hobrecht').tap do |crit|
706
679
  crit.documents = [ hobrecht, friedel ]
707
680
  end
708
681
  end
709
682
 
710
- context "when not passing options" do
711
-
712
- context "when there are matching documents" do
713
-
683
+ context 'when not passing options' do
684
+ context 'when there are matching documents' do
714
685
  let(:context) do
715
686
  described_class.new(criteria)
716
687
  end
717
688
 
718
- it "returns true" do
689
+ it 'returns true' do
719
690
  expect(context).to be_exists
720
691
  end
721
692
  end
722
693
 
723
- context "when there are no matching documents" do
724
-
694
+ context 'when there are no matching documents' do
725
695
  let(:criteria) do
726
- Address.where(street: "pfluger").tap do |crit|
696
+ Address.where(street: 'pfluger').tap do |crit|
727
697
  crit.documents = [ hobrecht, friedel ]
728
698
  end
729
699
  end
@@ -732,147 +702,127 @@ describe Mongoid::Contextual::Memory do
732
702
  described_class.new(criteria)
733
703
  end
734
704
 
735
- it "returns false" do
736
- expect(context).to_not be_exists
705
+ it 'returns false' do
706
+ expect(context).not_to be_exists
737
707
  end
738
708
  end
739
709
 
740
710
  context 'when there is a collation on the criteria' do
741
-
742
711
  let(:criteria) do
743
- Address.where(street: "pfluger").tap do |crit|
712
+ Address.where(street: 'pfluger').tap do |crit|
744
713
  crit.documents = [ hobrecht, friedel ]
745
714
  end.collation(locale: 'en_US', strength: 2)
746
715
  end
747
716
 
748
- it "raises an exception" do
749
- expect {
717
+ it 'raises an exception' do
718
+ expect do
750
719
  context
751
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
720
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
752
721
  end
753
722
  end
754
723
  end
755
724
 
756
- context "when passing an _id" do
757
-
758
- context "when its of type BSON::ObjectId" do
759
-
760
- context "when calling it on an empty criteria" do
761
-
762
- it "returns true" do
725
+ context 'when passing an _id' do
726
+ context 'when its of type BSON::ObjectId' do
727
+ context 'when calling it on an empty criteria' do
728
+ it 'returns true' do
763
729
  expect(criteria.exists?(hobrecht._id)).to be true
764
730
  end
765
731
  end
766
732
 
767
- context "when calling it on a criteria that includes the object" do
768
-
769
- it "returns true" do
733
+ context 'when calling it on a criteria that includes the object' do
734
+ it 'returns true' do
770
735
  expect(criteria.where(street: hobrecht.street).exists?(hobrecht._id)).to be true
771
736
  end
772
737
  end
773
738
 
774
- context "when calling it on a criteria that does not include the object" do
775
-
776
- it "returns false" do
777
- expect(criteria.where(street: "bogus").exists?(hobrecht._id)).to be false
739
+ context 'when calling it on a criteria that does not include the object' do
740
+ it 'returns false' do
741
+ expect(criteria.where(street: 'bogus').exists?(hobrecht._id)).to be false
778
742
  end
779
743
  end
780
744
 
781
- context "when the id does not exist" do
782
-
783
- it "returns false" do
745
+ context 'when the id does not exist' do
746
+ it 'returns false' do
784
747
  expect(criteria.exists?(BSON::ObjectId.new)).to be false
785
748
  end
786
749
  end
787
750
  end
788
751
 
789
- context "when its of type String" do
790
-
791
- context "when the id exists" do
792
-
793
- it "returns true" do
752
+ context 'when its of type String' do
753
+ context 'when the id exists' do
754
+ it 'returns true' do
794
755
  expect(criteria.exists?(hobrecht._id.to_s)).to be true
795
756
  end
796
757
  end
797
758
 
798
- context "when the id does not exist" do
799
-
800
- it "returns false" do
759
+ context 'when the id does not exist' do
760
+ it 'returns false' do
801
761
  expect(criteria.exists?(BSON::ObjectId.new.to_s)).to be false
802
762
  end
803
763
  end
804
764
  end
805
765
  end
806
766
 
807
- context "when passing a hash" do
808
-
809
- context "when calling it on an empty criteria" do
810
-
811
- it "returns true" do
767
+ context 'when passing a hash' do
768
+ context 'when calling it on an empty criteria' do
769
+ it 'returns true' do
812
770
  expect(criteria.exists?(street: hobrecht.street)).to be true
813
771
  end
814
772
  end
815
773
 
816
- context "when calling it on a criteria that includes the object" do
817
-
818
- it "returns true" do
774
+ context 'when calling it on a criteria that includes the object' do
775
+ it 'returns true' do
819
776
  expect(criteria.where(_id: hobrecht._id).exists?(street: hobrecht.street)).to be true
820
777
  end
821
778
  end
822
779
 
823
- context "when calling it on a criteria that does not include the object" do
824
-
825
- it "returns false" do
780
+ context 'when calling it on a criteria that does not include the object' do
781
+ it 'returns false' do
826
782
  expect(criteria.where(_id: BSON::ObjectId.new).exists?(street: hobrecht.street)).to be false
827
783
  end
828
784
  end
829
785
 
830
786
  context "when the conditions don't match" do
831
-
832
- it "returns false" do
833
- expect(criteria.exists?(street: "bogus")).to be false
787
+ it 'returns false' do
788
+ expect(criteria.exists?(street: 'bogus')).to be false
834
789
  end
835
790
  end
836
791
  end
837
792
 
838
- context "when passing false" do
839
-
840
- it "returns false" do
793
+ context 'when passing false' do
794
+ it 'returns false' do
841
795
  expect(criteria.exists?(false)).to be false
842
796
  end
843
797
  end
844
798
 
845
- context "when passing nil" do
846
-
847
- it "returns false" do
799
+ context 'when passing nil' do
800
+ it 'returns false' do
848
801
  expect(criteria.exists?(nil)).to be false
849
802
  end
850
803
  end
851
804
 
852
- context "when the limit is 0" do
853
-
854
- it "returns false" do
805
+ context 'when the limit is 0' do
806
+ it 'returns false' do
855
807
  expect(criteria.limit(0).exists?).to be false
856
808
  end
857
809
  end
858
810
  end
859
811
 
860
- [ :first, :one ].each do |method|
861
-
812
+ %i[first one].each do |method|
862
813
  describe "##{method}" do
863
-
864
814
  let(:method) { method }
865
815
 
866
816
  let(:hobrecht) do
867
- Address.new(street: "hobrecht")
817
+ Address.new(street: 'hobrecht')
868
818
  end
869
819
 
870
820
  let(:friedel) do
871
- Address.new(street: "friedel")
821
+ Address.new(street: 'friedel')
872
822
  end
873
823
 
874
824
  let(:criteria) do
875
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
825
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
876
826
  crit.documents = [ hobrecht, friedel ]
877
827
  end
878
828
  end
@@ -881,51 +831,49 @@ describe Mongoid::Contextual::Memory do
881
831
  described_class.new(criteria)
882
832
  end
883
833
 
884
- it "returns the first matching document" do
834
+ it 'returns the first matching document' do
885
835
  expect(context.send(method)).to eq(hobrecht)
886
836
  end
887
837
 
888
- it "returns a list when passing a limit" do
838
+ it 'returns a list when passing a limit' do
889
839
  expect(context.send(method, 2)).to eq([ hobrecht, friedel ])
890
840
  end
891
841
 
892
- it "returns a list when passing 1" do
842
+ it 'returns a list when passing 1' do
893
843
  expect(context.send(method, 1)).to eq([ hobrecht ])
894
844
  end
895
845
 
896
- include_examples "returns nil when no documents"
846
+ include_examples 'returns nil when no documents'
897
847
 
898
848
  context 'when there is a collation on the criteria' do
899
-
900
849
  let(:criteria) do
901
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
850
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
902
851
  crit.documents = [ hobrecht, friedel ]
903
852
  end.collation(locale: 'en_US', strength: 2)
904
853
  end
905
854
 
906
- it "raises an exception" do
907
- expect {
855
+ it 'raises an exception' do
856
+ expect do
908
857
  context.send(method)
909
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
858
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
910
859
  end
911
860
  end
912
861
  end
913
862
  end
914
863
 
915
- describe "#first!" do
916
-
864
+ describe '#first!' do
917
865
  let(:method) { :first! }
918
866
 
919
867
  let(:hobrecht) do
920
- Address.new(street: "hobrecht")
868
+ Address.new(street: 'hobrecht')
921
869
  end
922
870
 
923
871
  let(:friedel) do
924
- Address.new(street: "friedel")
872
+ Address.new(street: 'friedel')
925
873
  end
926
874
 
927
875
  let(:criteria) do
928
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
876
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
929
877
  crit.documents = [ hobrecht, friedel ]
930
878
  end
931
879
  end
@@ -934,27 +882,26 @@ describe Mongoid::Contextual::Memory do
934
882
  described_class.new(criteria)
935
883
  end
936
884
 
937
- it "returns the first matching document" do
885
+ it 'returns the first matching document' do
938
886
  expect(context.first!).to eq(hobrecht)
939
887
  end
940
888
 
941
- include_examples "raises an error when no documents"
889
+ include_examples 'raises an error when no documents'
942
890
  end
943
891
 
944
- describe "#take" do
945
-
892
+ describe '#take' do
946
893
  let(:method) { :take }
947
894
 
948
895
  let(:hobrecht) do
949
- Address.new(street: "hobrecht")
896
+ Address.new(street: 'hobrecht')
950
897
  end
951
898
 
952
899
  let(:friedel) do
953
- Address.new(street: "friedel")
900
+ Address.new(street: 'friedel')
954
901
  end
955
902
 
956
903
  let(:criteria) do
957
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
904
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
958
905
  crit.documents = [ hobrecht, friedel ]
959
906
  end
960
907
  end
@@ -963,50 +910,48 @@ describe Mongoid::Contextual::Memory do
963
910
  described_class.new(criteria)
964
911
  end
965
912
 
966
- it "returns the first matching document" do
913
+ it 'returns the first matching document' do
967
914
  expect(context.take).to eq(hobrecht)
968
915
  end
969
916
 
970
- it "returns an array when passing a limit" do
917
+ it 'returns an array when passing a limit' do
971
918
  expect(context.take(2)).to eq([ hobrecht, friedel ])
972
919
  end
973
920
 
974
- it "returns an array when passing a limit as 1" do
921
+ it 'returns an array when passing a limit as 1' do
975
922
  expect(context.take(1)).to eq([ hobrecht ])
976
923
  end
977
924
 
978
- include_examples "returns nil when no documents"
925
+ include_examples 'returns nil when no documents'
979
926
 
980
927
  context 'when there is a collation on the criteria' do
981
-
982
928
  let(:criteria) do
983
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
929
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
984
930
  crit.documents = [ hobrecht, friedel ]
985
931
  end.collation(locale: 'en_US', strength: 2)
986
932
  end
987
933
 
988
- it "raises an exception" do
989
- expect {
934
+ it 'raises an exception' do
935
+ expect do
990
936
  context.take
991
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
937
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
992
938
  end
993
939
  end
994
940
  end
995
941
 
996
- describe "#take!" do
997
-
942
+ describe '#take!' do
998
943
  let(:method) { :take! }
999
944
 
1000
945
  let(:hobrecht) do
1001
- Address.new(street: "hobrecht")
946
+ Address.new(street: 'hobrecht')
1002
947
  end
1003
948
 
1004
949
  let(:friedel) do
1005
- Address.new(street: "friedel")
950
+ Address.new(street: 'friedel')
1006
951
  end
1007
952
 
1008
953
  let(:criteria) do
1009
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
954
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
1010
955
  crit.documents = [ hobrecht, friedel ]
1011
956
  end
1012
957
  end
@@ -1015,42 +960,39 @@ describe Mongoid::Contextual::Memory do
1015
960
  described_class.new(criteria)
1016
961
  end
1017
962
 
1018
- it "returns the first matching document" do
963
+ it 'returns the first matching document' do
1019
964
  expect(context.take!).to eq(hobrecht)
1020
965
  end
1021
966
 
1022
- include_examples "raises an error when no documents"
967
+ include_examples 'raises an error when no documents'
1023
968
 
1024
969
  context 'when there is a collation on the criteria' do
1025
-
1026
970
  let(:criteria) do
1027
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
971
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
1028
972
  crit.documents = [ hobrecht, friedel ]
1029
973
  end.collation(locale: 'en_US', strength: 2)
1030
974
  end
1031
975
 
1032
- it "raises an exception" do
1033
- expect {
976
+ it 'raises an exception' do
977
+ expect do
1034
978
  context.take
1035
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
979
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1036
980
  end
1037
981
  end
1038
982
  end
1039
983
 
1040
- describe "#initialize" do
1041
-
1042
- context "when the criteria has no options" do
1043
-
984
+ describe '#initialize' do
985
+ context 'when the criteria has no options' do
1044
986
  let(:hobrecht) do
1045
- Address.new(street: "hobrecht")
987
+ Address.new(street: 'hobrecht')
1046
988
  end
1047
989
 
1048
990
  let(:friedel) do
1049
- Address.new(street: "friedel")
991
+ Address.new(street: 'friedel')
1050
992
  end
1051
993
 
1052
994
  let(:criteria) do
1053
- Address.where(street: "hobrecht").tap do |crit|
995
+ Address.where(street: 'hobrecht').tap do |crit|
1054
996
  crit.documents = [ hobrecht, friedel ]
1055
997
  end
1056
998
  end
@@ -1059,27 +1001,26 @@ describe Mongoid::Contextual::Memory do
1059
1001
  described_class.new(criteria)
1060
1002
  end
1061
1003
 
1062
- it "sets the criteria" do
1004
+ it 'sets the criteria' do
1063
1005
  expect(context.criteria).to eq(criteria)
1064
1006
  end
1065
1007
 
1066
- it "sets the klass" do
1008
+ it 'sets the klass' do
1067
1009
  expect(context.klass).to eq(Address)
1068
1010
  end
1069
1011
 
1070
- it "sets the matching documents" do
1012
+ it 'sets the matching documents' do
1071
1013
  expect(context.documents).to eq([ hobrecht ])
1072
1014
  end
1073
1015
  end
1074
1016
 
1075
- context "when the criteria skips" do
1076
-
1017
+ context 'when the criteria skips' do
1077
1018
  let(:hobrecht) do
1078
- Address.new(street: "hobrecht")
1019
+ Address.new(street: 'hobrecht')
1079
1020
  end
1080
1021
 
1081
1022
  let(:friedel) do
1082
- Address.new(street: "friedel")
1023
+ Address.new(street: 'friedel')
1083
1024
  end
1084
1025
 
1085
1026
  let(:criteria) do
@@ -1092,19 +1033,18 @@ describe Mongoid::Contextual::Memory do
1092
1033
  described_class.new(criteria)
1093
1034
  end
1094
1035
 
1095
- it "limits the matching documents" do
1036
+ it 'limits the matching documents' do
1096
1037
  expect(context).to eq([ friedel ])
1097
1038
  end
1098
1039
  end
1099
1040
 
1100
- context "when the criteria limits" do
1101
-
1041
+ context 'when the criteria limits' do
1102
1042
  let(:hobrecht) do
1103
- Address.new(street: "hobrecht")
1043
+ Address.new(street: 'hobrecht')
1104
1044
  end
1105
1045
 
1106
1046
  let(:friedel) do
1107
- Address.new(street: "friedel")
1047
+ Address.new(street: 'friedel')
1108
1048
  end
1109
1049
 
1110
1050
  let(:criteria) do
@@ -1117,41 +1057,39 @@ describe Mongoid::Contextual::Memory do
1117
1057
  described_class.new(criteria)
1118
1058
  end
1119
1059
 
1120
- it "limits the matching documents" do
1060
+ it 'limits the matching documents' do
1121
1061
  expect(context).to eq([ hobrecht ])
1122
1062
  end
1123
1063
  end
1124
1064
 
1125
1065
  context 'when there is a collation on the criteria' do
1126
-
1127
1066
  let(:criteria) do
1128
1067
  Address.all.limit(1).tap do |crit|
1129
1068
  crit.documents = [ hobrecht, friedel ]
1130
1069
  end.collation(locale: 'en_US', strength: 2)
1131
1070
  end
1132
1071
 
1133
- it "raises an exception" do
1134
- expect {
1072
+ it 'raises an exception' do
1073
+ expect do
1135
1074
  context
1136
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1075
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1137
1076
  end
1138
1077
  end
1139
1078
  end
1140
1079
 
1141
- describe "#last" do
1142
-
1080
+ describe '#last' do
1143
1081
  let(:method) { :last }
1144
1082
 
1145
1083
  let(:hobrecht) do
1146
- Address.new(street: "hobrecht")
1084
+ Address.new(street: 'hobrecht')
1147
1085
  end
1148
1086
 
1149
1087
  let(:friedel) do
1150
- Address.new(street: "friedel")
1088
+ Address.new(street: 'friedel')
1151
1089
  end
1152
1090
 
1153
1091
  let(:criteria) do
1154
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
1092
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
1155
1093
  crit.documents = [ hobrecht, friedel ]
1156
1094
  end
1157
1095
  end
@@ -1160,49 +1098,48 @@ describe Mongoid::Contextual::Memory do
1160
1098
  described_class.new(criteria)
1161
1099
  end
1162
1100
 
1163
- it "returns the last matching document" do
1101
+ it 'returns the last matching document' do
1164
1102
  expect(context.last).to eq(friedel)
1165
1103
  end
1166
1104
 
1167
- it "returns a list when a limit is passed" do
1105
+ it 'returns a list when a limit is passed' do
1168
1106
  expect(context.last(2)).to eq([ hobrecht, friedel ])
1169
1107
  end
1170
1108
 
1171
- it "returns a list when the limit is 1" do
1109
+ it 'returns a list when the limit is 1' do
1172
1110
  expect(context.last(1)).to eq([ friedel ])
1173
1111
  end
1174
1112
 
1175
- include_examples "returns nil when no documents"
1113
+ include_examples 'returns nil when no documents'
1176
1114
 
1177
1115
  context 'when there is a collation on the criteria' do
1178
-
1179
1116
  let(:criteria) do
1180
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
1117
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
1181
1118
  crit.documents = [ hobrecht, friedel ]
1182
1119
  end.collation(locale: 'en_US', strength: 2)
1183
1120
  end
1184
1121
 
1185
- it "raises an exception" do
1186
- expect {
1122
+ it 'raises an exception' do
1123
+ expect do
1187
1124
  context.last
1188
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1125
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1189
1126
  end
1190
1127
  end
1191
1128
  end
1192
1129
 
1193
- describe "#last!" do
1130
+ describe '#last!' do
1194
1131
  let(:method) { :last! }
1195
1132
 
1196
1133
  let(:hobrecht) do
1197
- Address.new(street: "hobrecht")
1134
+ Address.new(street: 'hobrecht')
1198
1135
  end
1199
1136
 
1200
1137
  let(:friedel) do
1201
- Address.new(street: "friedel")
1138
+ Address.new(street: 'friedel')
1202
1139
  end
1203
1140
 
1204
1141
  let(:criteria) do
1205
- Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
1142
+ Address.where(:street.in => %w[hobrecht friedel]).tap do |crit|
1206
1143
  crit.documents = [ hobrecht, friedel ]
1207
1144
  end
1208
1145
  end
@@ -1211,20 +1148,19 @@ describe Mongoid::Contextual::Memory do
1211
1148
  described_class.new(criteria)
1212
1149
  end
1213
1150
 
1214
- it "returns the last matching document" do
1151
+ it 'returns the last matching document' do
1215
1152
  expect(context.last!).to eq(friedel)
1216
1153
  end
1217
1154
 
1218
- include_examples "raises an error when no documents"
1155
+ include_examples 'raises an error when no documents'
1219
1156
  end
1220
1157
 
1221
- [ :second,
1222
- :third,
1223
- :fourth,
1224
- :fifth,
1225
- :second_to_last,
1226
- :third_to_last
1227
- ].each do |meth|
1158
+ %i[second
1159
+ third
1160
+ fourth
1161
+ fifth
1162
+ second_to_last
1163
+ third_to_last].each do |meth|
1228
1164
  describe "##{meth}" do
1229
1165
  let(:method) { meth }
1230
1166
 
@@ -1234,7 +1170,7 @@ describe Mongoid::Contextual::Memory do
1234
1170
  Address.new,
1235
1171
  Address.new,
1236
1172
  Address.new,
1237
- Address.new,
1173
+ Address.new
1238
1174
  ]
1239
1175
  end
1240
1176
 
@@ -1248,11 +1184,11 @@ describe Mongoid::Contextual::Memory do
1248
1184
  described_class.new(criteria)
1249
1185
  end
1250
1186
 
1251
- it "returns the matching document" do
1187
+ it 'returns the matching document' do
1252
1188
  expect(context.send(method)).to eq(addresses.send(method))
1253
1189
  end
1254
1190
 
1255
- include_examples "returns nil when no documents"
1191
+ include_examples 'returns nil when no documents'
1256
1192
  end
1257
1193
 
1258
1194
  describe "##{meth}!" do
@@ -1264,7 +1200,7 @@ describe Mongoid::Contextual::Memory do
1264
1200
  Address.new,
1265
1201
  Address.new,
1266
1202
  Address.new,
1267
- Address.new,
1203
+ Address.new
1268
1204
  ]
1269
1205
  end
1270
1206
 
@@ -1278,30 +1214,27 @@ describe Mongoid::Contextual::Memory do
1278
1214
  described_class.new(criteria)
1279
1215
  end
1280
1216
 
1281
- it "returns the matching document" do
1217
+ it 'returns the matching document' do
1282
1218
  expect(context.send(method)).to eq(addresses.send(meth))
1283
1219
  end
1284
1220
 
1285
- include_examples "raises an error when no documents"
1221
+ include_examples 'raises an error when no documents'
1286
1222
  end
1287
1223
  end
1288
1224
 
1289
- [ :length, :size ].each do |method|
1290
-
1225
+ %i[length size].each do |method|
1291
1226
  describe "##{method}" do
1292
-
1293
1227
  let(:hobrecht) do
1294
- Address.new(street: "hobrecht")
1228
+ Address.new(street: 'hobrecht')
1295
1229
  end
1296
1230
 
1297
1231
  let(:friedel) do
1298
- Address.new(street: "friedel")
1232
+ Address.new(street: 'friedel')
1299
1233
  end
1300
1234
 
1301
- context "when there are matching documents" do
1302
-
1235
+ context 'when there are matching documents' do
1303
1236
  let(:criteria) do
1304
- Address.where(street: "hobrecht").tap do |crit|
1237
+ Address.where(street: 'hobrecht').tap do |crit|
1305
1238
  crit.documents = [ hobrecht, friedel ]
1306
1239
  end
1307
1240
  end
@@ -1310,15 +1243,14 @@ describe Mongoid::Contextual::Memory do
1310
1243
  described_class.new(criteria)
1311
1244
  end
1312
1245
 
1313
- it "returns the number of matches" do
1246
+ it 'returns the number of matches' do
1314
1247
  expect(context.send(method)).to eq(1)
1315
1248
  end
1316
1249
  end
1317
1250
 
1318
- context "when there are no matching documents" do
1319
-
1251
+ context 'when there are no matching documents' do
1320
1252
  let(:criteria) do
1321
- Address.where(street: "pfluger").tap do |crit|
1253
+ Address.where(street: 'pfluger').tap do |crit|
1322
1254
  crit.documents = [ hobrecht, friedel ]
1323
1255
  end
1324
1256
  end
@@ -1327,40 +1259,38 @@ describe Mongoid::Contextual::Memory do
1327
1259
  described_class.new(criteria)
1328
1260
  end
1329
1261
 
1330
- it "returns zero" do
1262
+ it 'returns zero' do
1331
1263
  expect(context.send(method)).to eq(0)
1332
1264
  end
1333
1265
  end
1334
1266
 
1335
1267
  context 'when there is a collation on the criteria' do
1336
-
1337
1268
  let(:criteria) do
1338
- Address.where(street: "hobrecht").tap do |crit|
1269
+ Address.where(street: 'hobrecht').tap do |crit|
1339
1270
  crit.documents = [ hobrecht, friedel ]
1340
1271
  end.collation(locale: 'en_US', strength: 2)
1341
1272
  end
1342
1273
 
1343
- it "raises an exception" do
1344
- expect {
1274
+ it 'raises an exception' do
1275
+ expect do
1345
1276
  context.send(method)
1346
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1277
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1347
1278
  end
1348
1279
  end
1349
1280
  end
1350
1281
  end
1351
1282
 
1352
- describe "#limit" do
1353
-
1283
+ describe '#limit' do
1354
1284
  let(:hobrecht) do
1355
- Address.new(street: "hobrecht")
1285
+ Address.new(street: 'hobrecht')
1356
1286
  end
1357
1287
 
1358
1288
  let(:friedel) do
1359
- Address.new(street: "friedel")
1289
+ Address.new(street: 'friedel')
1360
1290
  end
1361
1291
 
1362
1292
  let(:pfluger) do
1363
- Address.new(street: "pfluger")
1293
+ Address.new(street: 'pfluger')
1364
1294
  end
1365
1295
 
1366
1296
  let(:criteria) do
@@ -1374,31 +1304,27 @@ describe Mongoid::Contextual::Memory do
1374
1304
  end
1375
1305
 
1376
1306
  context 'when there is no collation on the criteria' do
1377
-
1378
1307
  let!(:limit) do
1379
1308
  context.limit(2)
1380
1309
  end
1381
1310
 
1382
- it "returns the context" do
1311
+ it 'returns the context' do
1383
1312
  expect(limit).to eq(context)
1384
1313
  end
1385
1314
 
1386
- context "when asking for all documents" do
1387
-
1388
- context "when only a limit exists" do
1389
-
1390
- it "only returns the limited documents" do
1315
+ context 'when asking for all documents' do
1316
+ context 'when only a limit exists' do
1317
+ it 'only returns the limited documents' do
1391
1318
  expect(context.entries).to eq([ hobrecht, friedel ])
1392
1319
  end
1393
1320
  end
1394
1321
 
1395
- context "when a skip and limit exist" do
1396
-
1322
+ context 'when a skip and limit exist' do
1397
1323
  before do
1398
1324
  limit.skip(1)
1399
1325
  end
1400
1326
 
1401
- it "applies the skip before the limit" do
1327
+ it 'applies the skip before the limit' do
1402
1328
  expect(context.entries).to eq([ friedel, pfluger ])
1403
1329
  end
1404
1330
  end
@@ -1406,41 +1332,39 @@ describe Mongoid::Contextual::Memory do
1406
1332
  end
1407
1333
 
1408
1334
  context 'when there is a collation on the criteria' do
1409
-
1410
1335
  let(:criteria) do
1411
1336
  Address.all.tap do |crit|
1412
1337
  crit.documents = [ hobrecht, friedel, pfluger ]
1413
1338
  end.collation(locale: 'en_US', strength: 2)
1414
1339
  end
1415
1340
 
1416
- it "raises an exception" do
1417
- expect {
1341
+ it 'raises an exception' do
1342
+ expect do
1418
1343
  context.limit(2)
1419
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1344
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1420
1345
  end
1421
1346
  end
1422
1347
  end
1423
1348
 
1424
- describe "#pluck" do
1425
-
1349
+ describe '#pluck' do
1426
1350
  let(:context) do
1427
1351
  described_class.new(criteria)
1428
1352
  end
1429
1353
 
1430
1354
  let!(:depeche) do
1431
- Band.create!(name: "Depeche Mode", likes: 3)
1355
+ Band.create!(name: 'Depeche Mode', likes: 3)
1432
1356
  end
1433
1357
 
1434
1358
  let!(:tool) do
1435
- Band.create!(name: "Tool", likes: 3)
1359
+ Band.create!(name: 'Tool', likes: 3)
1436
1360
  end
1437
1361
 
1438
1362
  let!(:photek) do
1439
- Band.create!(name: "Photek", likes: 1)
1363
+ Band.create!(name: 'Photek', likes: 1)
1440
1364
  end
1441
1365
 
1442
1366
  let!(:maniacs) do
1443
- Band.create!(name: "10,000 Maniacs", likes: 1, sales: "1E2")
1367
+ Band.create!(name: '10,000 Maniacs', likes: 1, sales: '1E2')
1444
1368
  end
1445
1369
 
1446
1370
  let(:criteria) do
@@ -1449,10 +1373,9 @@ describe Mongoid::Contextual::Memory do
1449
1373
  end
1450
1374
  end
1451
1375
 
1452
- context "when the field is aliased" do
1453
-
1376
+ context 'when the field is aliased' do
1454
1377
  let!(:expensive) do
1455
- Product.create!(price: 100000)
1378
+ Product.create!(price: 100_000)
1456
1379
  end
1457
1380
 
1458
1381
  let!(:cheap) do
@@ -1465,39 +1388,34 @@ describe Mongoid::Contextual::Memory do
1465
1388
  end
1466
1389
  end
1467
1390
 
1468
- context "when using alias_attribute" do
1469
-
1391
+ context 'when using alias_attribute' do
1470
1392
  let(:plucked) do
1471
1393
  context.pluck(:price)
1472
1394
  end
1473
1395
 
1474
- it "uses the aliases" do
1475
- expect(plucked).to eq([ 100000, 1 ])
1396
+ it 'uses the aliases' do
1397
+ expect(plucked).to eq([ 100_000, 1 ])
1476
1398
  end
1477
1399
  end
1478
1400
  end
1479
1401
 
1480
- context "when the criteria matches" do
1481
-
1482
- context "when there are no duplicate values" do
1483
-
1402
+ context 'when the criteria matches' do
1403
+ context 'when there are no duplicate values' do
1484
1404
  let!(:plucked) do
1485
1405
  context.pluck(:name)
1486
1406
  end
1487
1407
 
1488
- it "returns the values" do
1489
- expect(plucked).to contain_exactly("10,000 Maniacs", "Depeche Mode", "Tool", "Photek")
1408
+ it 'returns the values' do
1409
+ expect(plucked).to contain_exactly('10,000 Maniacs', 'Depeche Mode', 'Tool', 'Photek')
1490
1410
  end
1491
1411
 
1492
- context "when subsequently executing the criteria without a pluck" do
1493
-
1494
- it "does not limit the fields" do
1412
+ context 'when subsequently executing the criteria without a pluck' do
1413
+ it 'does not limit the fields' do
1495
1414
  expect(context.first.likes).to eq(3)
1496
1415
  end
1497
1416
  end
1498
1417
 
1499
1418
  context 'when the field is a subdocument' do
1500
-
1501
1419
  context 'when a top-level field and a subdocument field are plucked' do
1502
1420
  let(:criteria) do
1503
1421
  Band.where(name: 'FKA Twigs').tap do |crit|
@@ -1514,8 +1432,8 @@ describe Mongoid::Contextual::Memory do
1514
1432
 
1515
1433
  let(:expected) do
1516
1434
  [
1517
- ["FKA Twigs", []],
1518
- ['FKA Twigs', ["LP1"]]
1435
+ [ 'FKA Twigs', [] ],
1436
+ [ 'FKA Twigs', [ 'LP1' ] ]
1519
1437
  ]
1520
1438
  end
1521
1439
 
@@ -1525,7 +1443,6 @@ describe Mongoid::Contextual::Memory do
1525
1443
  end
1526
1444
 
1527
1445
  context 'when only a subdocument field is plucked' do
1528
-
1529
1446
  let(:criteria) do
1530
1447
  Band.where(name: 'FKA Twigs').tap do |crit|
1531
1448
  crit.documents = [
@@ -1542,7 +1459,7 @@ describe Mongoid::Contextual::Memory do
1542
1459
  let(:expected) do
1543
1460
  [
1544
1461
  [],
1545
- ["LP1"]
1462
+ [ 'LP1' ]
1546
1463
  ]
1547
1464
  end
1548
1465
 
@@ -1553,72 +1470,66 @@ describe Mongoid::Contextual::Memory do
1553
1470
  end
1554
1471
  end
1555
1472
 
1556
- context "when plucking multi-fields" do
1557
-
1473
+ context 'when plucking multi-fields' do
1558
1474
  let(:plucked) do
1559
1475
  context.pluck(:name, :likes)
1560
1476
  end
1561
1477
 
1562
- it "returns the values" do
1563
- expect(plucked).to contain_exactly(["10,000 Maniacs", 1], ["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
1478
+ it 'returns the values' do
1479
+ expect(plucked).to contain_exactly([ '10,000 Maniacs', 1 ], [ 'Depeche Mode', 3 ], [ 'Tool', 3 ],
1480
+ [ 'Photek', 1 ])
1564
1481
  end
1565
1482
  end
1566
1483
 
1567
- context "when there are duplicate values" do
1568
-
1484
+ context 'when there are duplicate values' do
1569
1485
  let(:plucked) do
1570
1486
  context.pluck(:likes)
1571
1487
  end
1572
1488
 
1573
- it "returns the duplicates" do
1489
+ it 'returns the duplicates' do
1574
1490
  expect(plucked).to contain_exactly(1, 3, 3, 1)
1575
1491
  end
1576
1492
  end
1577
1493
  end
1578
1494
 
1579
- context "when plucking an aliased field" do
1580
-
1495
+ context 'when plucking an aliased field' do
1581
1496
  let(:plucked) do
1582
1497
  context.pluck(:id)
1583
1498
  end
1584
1499
 
1585
- it "returns the field values" do
1500
+ it 'returns the field values' do
1586
1501
  expect(plucked).to eq([ depeche.id, tool.id, photek.id, maniacs.id ])
1587
1502
  end
1588
1503
  end
1589
1504
 
1590
- context "when plucking existent and non-existent fields" do
1591
-
1505
+ context 'when plucking existent and non-existent fields' do
1592
1506
  let(:plucked) do
1593
1507
  context.pluck(:id, :fooz)
1594
1508
  end
1595
1509
 
1596
- it "returns nil for the field that doesnt exist" do
1597
- expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil], [maniacs.id, nil] ])
1510
+ it 'returns nil for the field that doesnt exist' do
1511
+ expect(plucked).to eq([ [ depeche.id, nil ], [ tool.id, nil ], [ photek.id, nil ], [ maniacs.id, nil ] ])
1598
1512
  end
1599
1513
  end
1600
1514
 
1601
- context "when plucking a field that doesnt exist" do
1602
-
1603
- context "when pluck one field" do
1604
-
1515
+ context 'when plucking a field that doesnt exist' do
1516
+ context 'when pluck one field' do
1605
1517
  let(:plucked) do
1606
1518
  context.pluck(:foo)
1607
1519
  end
1608
1520
 
1609
- it "returns an array with nil values" do
1610
- expect(plucked).to eq([nil, nil, nil, nil])
1521
+ it 'returns an array with nil values' do
1522
+ expect(plucked).to eq([ nil, nil, nil, nil ])
1611
1523
  end
1612
1524
  end
1613
1525
 
1614
- context "when pluck multiple fields" do
1615
-
1526
+ context 'when pluck multiple fields' do
1616
1527
  let(:plucked) do
1617
1528
  context.pluck(:foo, :bar)
1618
1529
  end
1619
1530
 
1620
- it "returns an array of arrays with nil values" do
1621
- expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil], [nil, nil]])
1531
+ it 'returns an array of arrays with nil values' do
1532
+ expect(plucked).to eq([ [ nil, nil ], [ nil, nil ], [ nil, nil ], [ nil, nil ] ])
1622
1533
  end
1623
1534
  end
1624
1535
  end
@@ -1641,7 +1552,6 @@ describe Mongoid::Contextual::Memory do
1641
1552
  end
1642
1553
 
1643
1554
  context 'when plucking the entire field' do
1644
-
1645
1555
  let(:plucked) do
1646
1556
  context.pluck(:description)
1647
1557
  end
@@ -1659,16 +1569,16 @@ describe Mongoid::Contextual::Memory do
1659
1569
  end
1660
1570
 
1661
1571
  it 'returns the full translations hash to _translations' do
1662
- expect(plucked_translations.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
1572
+ expect(plucked_translations.first).to eq({ 'de' => 'deutsch-text', 'en' => 'english-text' })
1663
1573
  end
1664
1574
 
1665
1575
  it 'returns both' do
1666
- expect(plucked_translations_both.first).to eq([{"de"=>"deutsch-text", "en"=>"english-text"}, "deutsch-text"])
1576
+ expect(plucked_translations_both.first).to eq([ { 'de' => 'deutsch-text', 'en' => 'english-text' },
1577
+ 'deutsch-text' ])
1667
1578
  end
1668
1579
  end
1669
1580
 
1670
1581
  context 'when plucking a specific locale' do
1671
-
1672
1582
  let(:plucked) do
1673
1583
  context.pluck(:'description.de')
1674
1584
  end
@@ -1679,7 +1589,6 @@ describe Mongoid::Contextual::Memory do
1679
1589
  end
1680
1590
 
1681
1591
  context 'when plucking a specific locale from _translations field' do
1682
-
1683
1592
  let(:plucked) do
1684
1593
  context.pluck(:'description_translations.de')
1685
1594
  end
@@ -1701,141 +1610,250 @@ describe Mongoid::Contextual::Memory do
1701
1610
  context.pluck(:description).first
1702
1611
  end
1703
1612
 
1704
- it "correctly uses the fallback" do
1613
+ it 'correctly uses the fallback' do
1705
1614
  I18n.locale = :en
1706
1615
  Dictionary.create!(description: 'english-text')
1707
1616
  I18n.locale = :he
1708
- plucked.should == "english-text"
1617
+ plucked.should eq 'english-text'
1709
1618
  end
1710
1619
  end
1711
1620
 
1712
- context "when the localized field is embedded" do
1621
+ context 'when the localized field is embedded' do
1713
1622
  with_default_i18n_configs
1714
1623
 
1715
1624
  before do
1716
1625
  p = Passport.new
1717
1626
  I18n.locale = :en
1718
- p.name = "Neil"
1627
+ p.name = 'Neil'
1719
1628
  I18n.locale = :he
1720
- p.name = "Nissim"
1629
+ p.name = 'Nissim'
1721
1630
 
1722
- Person.create!(passport: p, employer_id: 12345)
1631
+ Person.create!(passport: p, employer_id: 12_345)
1723
1632
  end
1724
1633
 
1725
1634
  let(:plucked) do
1726
- Person.where(employer_id: 12345).pluck("pass.name").first
1635
+ Person.where(employer_id: 12_345).pluck('pass.name').first
1727
1636
  end
1728
1637
 
1729
1638
  let(:plucked_translations) do
1730
- Person.where(employer_id: 12345).pluck("pass.name_translations").first
1639
+ Person.where(employer_id: 12_345).pluck('pass.name_translations').first
1731
1640
  end
1732
1641
 
1733
1642
  let(:plucked_translations_field) do
1734
- Person.where(employer_id: 12345).pluck("pass.name_translations.en").first
1643
+ Person.where(employer_id: 12_345).pluck('pass.name_translations.en').first
1735
1644
  end
1736
1645
 
1737
- it "returns the translation for the current locale" do
1738
- expect(plucked).to eq("Nissim")
1646
+ it 'returns the translation for the current locale' do
1647
+ expect(plucked).to eq('Nissim')
1739
1648
  end
1740
1649
 
1741
- it "returns the full _translation hash" do
1742
- expect(plucked_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
1650
+ it 'returns the full _translation hash' do
1651
+ expect(plucked_translations).to eq({ 'en' => 'Neil', 'he' => 'Nissim' })
1743
1652
  end
1744
1653
 
1745
- it "returns the translation for the requested locale" do
1746
- expect(plucked_translations_field).to eq("Neil")
1654
+ it 'returns the translation for the requested locale' do
1655
+ expect(plucked_translations_field).to eq('Neil')
1747
1656
  end
1748
1657
  end
1749
1658
  end
1750
1659
 
1751
1660
  context 'when plucking a field to be demongoized' do
1752
-
1753
1661
  let(:plucked) do
1754
1662
  Band.where(name: maniacs.name).pluck(:sales)
1755
1663
  end
1756
1664
 
1757
1665
  with_config_values :map_big_decimal_to_decimal128, true, false do
1758
-
1759
- it "demongoizes the field" do
1666
+ it 'demongoizes the field' do
1760
1667
  expect(plucked.first).to be_a(BigDecimal)
1761
- expect(plucked.first).to eq(BigDecimal("1E2"))
1668
+ expect(plucked.first).to eq(BigDecimal('1E2'))
1762
1669
  end
1763
1670
  end
1764
1671
  end
1765
1672
 
1766
- context "when plucking an embedded field" do
1767
- let(:label) { Label.new(sales: "1E2") }
1673
+ context 'when plucking an embedded field' do
1674
+ let(:label) { Label.new(sales: '1E2') }
1768
1675
  let!(:band) { Band.create!(label: label) }
1769
1676
 
1770
1677
  let(:plucked) do
1771
1678
  Band.where(_id: band.id).tap do |crit|
1772
1679
  crit.documents = [ band ]
1773
- end.pluck("label.sales")
1680
+ end.pluck('label.sales')
1774
1681
  end
1775
1682
 
1776
- it "demongoizes the field" do
1777
- expect(plucked).to eq([ BigDecimal("1E2") ])
1683
+ it 'demongoizes the field' do
1684
+ expect(plucked).to eq([ BigDecimal('1E2') ])
1778
1685
  end
1779
1686
  end
1780
1687
 
1781
- context "when plucking an embeds_many field" do
1782
- let(:label) { Label.new(sales: "1E2") }
1783
- let!(:band) { Band.create!(labels: [label]) }
1688
+ context 'when plucking an embeds_many field' do
1689
+ let(:label) { Label.new(sales: '1E2') }
1690
+ let!(:band) { Band.create!(labels: [ label ]) }
1784
1691
 
1785
- let(:plucked) { Band.where(_id: band.id).pluck("labels.sales") }
1692
+ let(:plucked) { Band.where(_id: band.id).pluck('labels.sales') }
1786
1693
 
1787
- it "demongoizes the field" do
1788
- expect(plucked.first).to eq([ BigDecimal("1E2") ])
1694
+ it 'demongoizes the field' do
1695
+ expect(plucked.first).to eq([ BigDecimal('1E2') ])
1789
1696
  end
1790
1697
  end
1791
1698
 
1792
- context "when plucking a nonexistent embedded field" do
1793
- let(:label) { Label.new(sales: "1E2") }
1699
+ context 'when plucking a nonexistent embedded field' do
1700
+ let(:label) { Label.new(sales: '1E2') }
1794
1701
  let!(:band) { Band.create!(label: label) }
1795
1702
 
1796
1703
  let(:plucked) do
1797
1704
  Band.where(_id: band.id).tap do |crit|
1798
1705
  crit.documents = [ band ]
1799
- end.pluck("label.qwerty")
1706
+ end.pluck('label.qwerty')
1800
1707
  end
1801
1708
 
1802
- it "returns nil" do
1709
+ it 'returns nil' do
1803
1710
  expect(plucked.first).to eq(nil)
1804
1711
  end
1805
1712
  end
1806
1713
 
1807
- context "when plucking deeply nested arrays/embedded associations" do
1808
-
1714
+ context 'when plucking deeply nested arrays/embedded associations' do
1809
1715
  let(:criteria) do
1810
1716
  Person.all.tap do |crit|
1811
1717
  crit.documents = [
1812
- Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
1813
- Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
1814
- Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]),
1718
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
1719
+ { y: { z: 2 } } ]))) ]),
1720
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
1721
+ { y: { z: 2 } } ]))) ]),
1722
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
1723
+ { y: { z: 3 } } ]))) ])
1815
1724
  ]
1816
1725
  end
1817
1726
  end
1818
1727
 
1819
1728
  let(:plucked) do
1820
- context.pluck("addresses.code.deepest.array.y.z")
1729
+ context.pluck('addresses.code.deepest.array.y.z')
1821
1730
  end
1822
1731
 
1823
- it "returns the correct hash" do
1732
+ it 'returns the correct hash' do
1824
1733
  expect(plucked).to eq([
1825
- [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
1826
- ])
1734
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
1735
+ ])
1827
1736
  end
1828
1737
  end
1829
- end
1830
1738
 
1831
- describe "#pick" do
1739
+ context 'when plucking a dynamic attribute' do
1740
+ let(:criteria) do
1741
+ Band.all.tap do |crit|
1742
+ crit.documents = [ Band.create!(name: 'Depeche Mode', mood: 'dark') ]
1743
+ end
1744
+ end
1745
+
1746
+ it 'returns the value from the attributes' do
1747
+ expect(context.pluck(:mood)).to eq([ 'dark' ])
1748
+ end
1749
+ end
1750
+
1751
+ context 'when the field name is a method name' do
1752
+ let!(:person) do
1753
+ Person.create!(ssn: 'secret-ssn')
1754
+ end
1755
+
1756
+ let!(:address) do
1757
+ person.addresses.create!(street: 'hobrecht')
1758
+ end
1759
+
1760
+ let(:criteria) do
1761
+ Address.all.tap do |crit|
1762
+ crit.documents = [ address ]
1763
+ end
1764
+ end
1765
+
1766
+ it 'does not call the method' do
1767
+ expect(address).not_to receive(:destroy)
1768
+ expect(context.pluck(:destroy)).to eq([ nil ])
1769
+ end
1770
+
1771
+ it 'does not return the attributes hash' do
1772
+ expect(context.pluck(:attributes)).to eq([ nil ])
1773
+ end
1774
+
1775
+ it 'does not traverse to the parent document' do
1776
+ expect(context.pluck('_root.ssn')).to eq([ nil ])
1777
+ end
1778
+
1779
+ it 'does not destroy the parent document' do
1780
+ expect(context.pluck('_root.destroy')).to eq([ nil ])
1781
+ expect(Person.where(_id: person.id).count).to eq(1)
1782
+ end
1783
+ end
1784
+
1785
+ context 'when plucking a belongs_to association' do
1786
+ let!(:band) do
1787
+ Band.create!(name: 'Depeche Mode')
1788
+ end
1832
1789
 
1790
+ let!(:artist) do
1791
+ Artist.create!(band: band)
1792
+ end
1793
+
1794
+ let(:criteria) do
1795
+ Artist.all.tap do |crit|
1796
+ crit.documents = [ artist ]
1797
+ end
1798
+ end
1799
+
1800
+ it 'traverses to the associated document' do
1801
+ expect(context.pluck('band.name')).to eq([ 'Depeche Mode' ])
1802
+ end
1803
+
1804
+ it 'returns the document for the association name' do
1805
+ expect(context.pluck(:band)).to eq([ band ])
1806
+ end
1807
+
1808
+ it 'returns the id for the foreign key' do
1809
+ expect(context.pluck(:band_id)).to eq([ band.id ])
1810
+ end
1811
+ end
1812
+
1813
+ context 'when plucking the foreign key of a many to many association' do
1814
+ let!(:preference) do
1815
+ Preference.create!(name: 'nature')
1816
+ end
1817
+
1818
+ let!(:person) do
1819
+ Person.create!(preferences: [ preference ])
1820
+ end
1821
+
1822
+ let(:criteria) do
1823
+ Person.all.tap do |crit|
1824
+ crit.documents = [ person ]
1825
+ end
1826
+ end
1827
+
1828
+ it 'returns the stored ids' do
1829
+ expect(context.pluck(:preference_ids)).to eq([ [ preference.id ] ])
1830
+ end
1831
+ end
1832
+
1833
+ context 'when the field path has an empty segment' do
1834
+ let!(:band) do
1835
+ Band.create!(name: 'Depeche Mode', label: Label.new(name: 'Mute'))
1836
+ end
1837
+
1838
+ let(:criteria) do
1839
+ Band.all.tap do |crit|
1840
+ crit.documents = [ band ]
1841
+ end
1842
+ end
1843
+
1844
+ it 'returns nil' do
1845
+ expect(context.pluck('label..name')).to eq([ nil ])
1846
+ end
1847
+ end
1848
+ end
1849
+
1850
+ describe '#pick' do
1833
1851
  let(:depeche) do
1834
- Band.create!(name: "Depeche Mode", likes: 3)
1852
+ Band.create!(name: 'Depeche Mode', likes: 3)
1835
1853
  end
1836
1854
 
1837
1855
  let(:tool) do
1838
- Band.create!(name: "Tool", likes: 3)
1856
+ Band.create!(name: 'Tool', likes: 3)
1839
1857
  end
1840
1858
 
1841
1859
  let(:criteria) do
@@ -1848,30 +1866,27 @@ describe Mongoid::Contextual::Memory do
1848
1866
  described_class.new(criteria)
1849
1867
  end
1850
1868
 
1851
- context "when picking a field" do
1852
-
1869
+ context 'when picking a field' do
1853
1870
  let(:picked) do
1854
1871
  context.pick(:name)
1855
1872
  end
1856
1873
 
1857
- it "returns one element" do
1858
- expect(picked).to eq("Depeche Mode")
1874
+ it 'returns one element' do
1875
+ expect(picked).to eq('Depeche Mode')
1859
1876
  end
1860
1877
  end
1861
1878
 
1862
- context "when picking multiple fields" do
1863
-
1879
+ context 'when picking multiple fields' do
1864
1880
  let(:picked) do
1865
1881
  context.pick(:name, :likes)
1866
1882
  end
1867
1883
 
1868
- it "returns an array" do
1869
- expect(picked).to eq([ "Depeche Mode", 3 ])
1884
+ it 'returns an array' do
1885
+ expect(picked).to eq([ 'Depeche Mode', 3 ])
1870
1886
  end
1871
1887
  end
1872
1888
 
1873
- context "when no documents to pick" do
1874
-
1889
+ context 'when no documents to pick' do
1875
1890
  let(:criteria) do
1876
1891
  Band.all.tap do |crit|
1877
1892
  crit.documents = []
@@ -1882,41 +1897,67 @@ describe Mongoid::Contextual::Memory do
1882
1897
  context.pick(:name)
1883
1898
  end
1884
1899
 
1885
- it "returns nil" do
1900
+ it 'returns nil' do
1886
1901
  expect(picked).to be_nil
1887
1902
  end
1888
1903
  end
1889
- end
1890
1904
 
1891
- describe "#tally" do
1892
- let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
1893
- let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
1894
- let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
1905
+ context 'when the field name is a method name' do
1906
+ let!(:person) do
1907
+ Person.create!(ssn: 'secret-ssn')
1908
+ end
1909
+
1910
+ let!(:address) do
1911
+ person.addresses.create!(street: 'hobrecht')
1912
+ end
1913
+
1914
+ let(:criteria) do
1915
+ Address.all.tap do |crit|
1916
+ crit.documents = [ address ]
1917
+ end
1918
+ end
1919
+
1920
+ it 'does not call the method' do
1921
+ expect(address).not_to receive(:destroy)
1922
+ expect(context.pick(:destroy)).to be_nil
1923
+ end
1924
+ end
1925
+ end
1895
1926
 
1896
- let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
1897
- let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
1898
- let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
1927
+ describe '#tally' do
1928
+ let(:fans1) { [ Fanatic.new(age: 1), Fanatic.new(age: 2) ] }
1929
+ let(:fans2) { [ Fanatic.new(age: 1), Fanatic.new(age: 2) ] }
1930
+ let(:fans3) { [ Fanatic.new(age: 1), Fanatic.new(age: 3) ] }
1899
1931
 
1900
- let(:label1) { Label.new(name: "Atlantic") }
1901
- let(:label2) { Label.new(name: "Atlantic") }
1902
- let(:label3) { Label.new(name: "Columbia") }
1932
+ let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ] }
1933
+ let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ] }
1934
+ let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ] }
1903
1935
 
1936
+ let(:label1) { Label.new(name: 'Atlantic') }
1937
+ let(:label2) { Label.new(name: 'Atlantic') }
1938
+ let(:label3) { Label.new(name: 'Columbia') }
1904
1939
 
1905
- let(:band1) { Band.new(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1) }
1906
- let(:band2) { Band.new(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2) }
1907
- let(:band3) { Band.new(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3) }
1908
- let(:band4) { Band.new(origin: "tally2", fanatics: fans1, genres: [1, 2]) }
1909
- let(:band5) { Band.new(origin: "tally2", fanatics: fans2, genres: [1, 2]) }
1910
- let(:band6) { Band.new(origin: "tally2", fanatics: fans3, genres: [1, 3]) }
1940
+ let(:band1) do
1941
+ Band.new(origin: 'tally', name: 'Depeche Mode', years: 30, sales: '1E2', label: label1, genres: genres1)
1942
+ end
1943
+ let(:band2) do
1944
+ Band.new(origin: 'tally', name: 'New Order', years: 30, sales: '2E3', label: label2, genres: genres2)
1945
+ end
1946
+ let(:band3) do
1947
+ Band.new(origin: 'tally', name: '10,000 Maniacs', years: 30, sales: '1E2', label: label3, genres: genres3)
1948
+ end
1949
+ let(:band4) { Band.new(origin: 'tally2', fanatics: fans1, genres: [ 1, 2 ]) }
1950
+ let(:band5) { Band.new(origin: 'tally2', fanatics: fans2, genres: [ 1, 2 ]) }
1951
+ let(:band6) { Band.new(origin: 'tally2', fanatics: fans3, genres: [ 1, 3 ]) }
1911
1952
 
1912
1953
  let(:criteria) do
1913
- Band.where(origin: "tally").all.tap do |crit|
1954
+ Band.where(origin: 'tally').all.tap do |crit|
1914
1955
  crit.documents = [ band1, band2, band3 ]
1915
1956
  end
1916
1957
  end
1917
1958
 
1918
1959
  let(:criteria2) do
1919
- Band.where(origin: "tally2").tap do |crit|
1960
+ Band.where(origin: 'tally2').tap do |crit|
1920
1961
  crit.documents = [ band4, band5, band6 ]
1921
1962
  end
1922
1963
  end
@@ -1929,40 +1970,45 @@ describe Mongoid::Contextual::Memory do
1929
1970
  described_class.new(criteria2)
1930
1971
  end
1931
1972
 
1932
- context "when tallying a string" do
1973
+ context 'when tallying a string' do
1933
1974
  let(:tally) do
1934
1975
  context.tally(:name)
1935
1976
  end
1936
1977
 
1937
- it "returns the correct hash" do
1938
- expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
1978
+ it 'returns the correct hash' do
1979
+ expect(tally).to eq('Depeche Mode' => 1, 'New Order' => 1, '10,000 Maniacs' => 1)
1939
1980
  end
1940
1981
  end
1941
1982
 
1942
- context "using an aliased field" do
1983
+ context 'using an aliased field' do
1943
1984
  let(:tally) do
1944
1985
  context.tally(:years)
1945
1986
  end
1946
1987
 
1947
- it "returns the correct hash" do
1988
+ it 'returns the correct hash' do
1948
1989
  expect(tally).to eq(30 => 3)
1949
1990
  end
1950
1991
  end
1951
1992
 
1952
- context "when tallying a demongoizable field" do
1993
+ context 'when tallying a demongoizable field' do
1953
1994
  let(:tally) do
1954
1995
  context.tally(:sales)
1955
1996
  end
1956
1997
 
1957
- it "returns the correct hash" do
1958
- expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
1998
+ it 'returns the correct hash' do
1999
+ expect(tally).to eq(BigDecimal('1E2') => 2, BigDecimal('2E3') => 1)
1959
2000
  end
1960
2001
  end
1961
2002
 
1962
- context "when tallying a localized field" do
2003
+ context 'when tallying a localized field' do
1963
2004
  with_default_i18n_configs
1964
2005
 
1965
2006
  let(:d1) { Dictionary.new(description: 'en1') }
2007
+ let(:criteria) do
2008
+ Dictionary.all.tap do |crit|
2009
+ crit.documents = [ d1, d2, d3, d4 ]
2010
+ end
2011
+ end
1966
2012
  let(:d2) { Dictionary.new(description: 'en1') }
1967
2013
  let(:d3) { Dictionary.new(description: 'en1') }
1968
2014
  let(:d4) { Dictionary.new(description: 'en2') }
@@ -1981,57 +2027,56 @@ describe Mongoid::Contextual::Memory do
1981
2027
  I18n.locale = :en
1982
2028
  end
1983
2029
 
1984
- let(:criteria) do
1985
- Dictionary.all.tap do |crit|
1986
- crit.documents = [ d1, d2, d3, d4 ]
1987
- end
1988
- end
1989
-
1990
- context "when getting the demongoized field" do
2030
+ context 'when getting the demongoized field' do
1991
2031
  let(:tallied) do
1992
2032
  context.tally(:description)
1993
2033
  end
1994
2034
 
1995
- it "returns the translation for the current locale" do
1996
- expect(tallied).to eq("en1" => 3, "en2" => 1)
2035
+ it 'returns the translation for the current locale' do
2036
+ expect(tallied).to eq('en1' => 3, 'en2' => 1)
1997
2037
  end
1998
2038
  end
1999
2039
 
2000
- context "when getting a specific locale" do
2040
+ context 'when getting a specific locale' do
2001
2041
  let(:tallied) do
2002
- context.tally("description.de")
2042
+ context.tally('description.de')
2003
2043
  end
2004
2044
 
2005
- it "returns the translation for the the specific locale" do
2006
- expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
2045
+ it 'returns the translation for the the specific locale' do
2046
+ expect(tallied).to eq('de1' => 2, 'de2' => 1, 'de3' => 1)
2007
2047
  end
2008
2048
  end
2009
2049
 
2010
- context "when getting the full hash" do
2050
+ context 'when getting the full hash' do
2011
2051
  let(:tallied) do
2012
- context.tally("description_translations")
2052
+ context.tally('description_translations')
2013
2053
  end
2014
2054
 
2015
- it "returns the correct hash" do
2055
+ it 'returns the correct hash' do
2016
2056
  expect(tallied).to eq(
2017
- {"de" => "de1", "en" => "en1" } => 2,
2018
- {"de" => "de2", "en" => "en1" } => 1,
2019
- {"de" => "de3", "en" => "en2" } => 1
2057
+ { 'de' => 'de1', 'en' => 'en1' } => 2,
2058
+ { 'de' => 'de2', 'en' => 'en1' } => 1,
2059
+ { 'de' => 'de3', 'en' => 'en2' } => 1
2020
2060
  )
2021
2061
  end
2022
2062
  end
2023
2063
  end
2024
2064
 
2025
- context "when tallying an embedded localized field" do
2065
+ context 'when tallying an embedded localized field' do
2026
2066
  with_default_i18n_configs
2027
2067
 
2028
2068
  let(:person1) { Person.create!(addresses: [ address1a, address1b ]) }
2069
+ let(:criteria) do
2070
+ Person.all.tap do |crit|
2071
+ crit.documents = [ person1, person2 ]
2072
+ end
2073
+ end
2029
2074
  let(:person2) { Person.create!(addresses: [ address2a, address2b ]) }
2030
2075
 
2031
- let(:address1a) { Address.new(name: "en1") }
2032
- let(:address1b) { Address.new(name: "en2") }
2033
- let(:address2a) { Address.new(name: "en1") }
2034
- let(:address2b) { Address.new(name: "en3") }
2076
+ let(:address1a) { Address.new(name: 'en1') }
2077
+ let(:address1b) { Address.new(name: 'en2') }
2078
+ let(:address2a) { Address.new(name: 'en1') }
2079
+ let(:address2b) { Address.new(name: 'en3') }
2035
2080
 
2036
2081
  before do
2037
2082
  I18n.locale = :en
@@ -2040,153 +2085,141 @@ describe Mongoid::Contextual::Memory do
2040
2085
  address2a
2041
2086
  address2b
2042
2087
  I18n.locale = :de
2043
- address1a.name = "de1"
2044
- address1b.name = "de2"
2045
- address2a.name = "de1"
2046
- address2b.name = "de3"
2088
+ address1a.name = 'de1'
2089
+ address1b.name = 'de2'
2090
+ address2a.name = 'de1'
2091
+ address2b.name = 'de3'
2047
2092
  person1
2048
2093
  person2
2049
2094
  I18n.locale = :en
2050
2095
  end
2051
2096
 
2052
- let(:criteria) do
2053
- Person.all.tap do |crit|
2054
- crit.documents = [ person1, person2 ]
2055
- end
2056
- end
2057
-
2058
- context "when getting the demongoized field" do
2097
+ context 'when getting the demongoized field' do
2059
2098
  let(:tallied) do
2060
- context.tally("addresses.name")
2099
+ context.tally('addresses.name')
2061
2100
  end
2062
2101
 
2063
- it "returns the translation for the current locale" do
2102
+ it 'returns the translation for the current locale' do
2064
2103
  expect(tallied).to eq(
2065
- [ "en1", "en2" ] => 1,
2066
- [ "en1", "en3" ] => 1,
2104
+ %w[en1 en2] => 1,
2105
+ %w[en1 en3] => 1
2067
2106
  )
2068
2107
  end
2069
2108
  end
2070
2109
 
2071
- context "when getting a specific locale" do
2110
+ context 'when getting a specific locale' do
2072
2111
  let(:tallied) do
2073
- context.tally("addresses.name.de")
2112
+ context.tally('addresses.name.de')
2074
2113
  end
2075
2114
 
2076
- it "returns the translation for the the specific locale" do
2115
+ it 'returns the translation for the the specific locale' do
2077
2116
  expect(tallied).to eq(
2078
- [ "de1", "de2" ] => 1,
2079
- [ "de1", "de3" ] => 1,
2117
+ %w[de1 de2] => 1,
2118
+ %w[de1 de3] => 1
2080
2119
  )
2081
2120
  end
2082
2121
  end
2083
2122
 
2084
- context "when getting the full hash" do
2123
+ context 'when getting the full hash' do
2085
2124
  let(:tallied) do
2086
- context.tally("addresses.name_translations")
2125
+ context.tally('addresses.name_translations')
2087
2126
  end
2088
2127
 
2089
- it "returns the correct hash" do
2128
+ it 'returns the correct hash' do
2090
2129
  expect(tallied).to eq(
2091
- [{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
2092
- [{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
2130
+ [ { 'de' => 'de1', 'en' => 'en1' }, { 'de' => 'de2', 'en' => 'en2' } ] => 1,
2131
+ [ { 'de' => 'de1', 'en' => 'en1' }, { 'de' => 'de3', 'en' => 'en3' } ] => 1
2093
2132
  )
2094
2133
  end
2095
2134
  end
2096
2135
  end
2097
2136
 
2098
- context "when tallying an embedded field" do
2137
+ context 'when tallying an embedded field' do
2099
2138
  let(:tally) do
2100
- context.tally("label.name")
2139
+ context.tally('label.name')
2101
2140
  end
2102
2141
 
2103
- it "returns the correct hash" do
2104
- expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
2142
+ it 'returns the correct hash' do
2143
+ expect(tally).to eq('Atlantic' => 2, 'Columbia' => 1)
2105
2144
  end
2106
2145
  end
2107
2146
 
2108
- context "when tallying an element in an embeds_many field" do
2109
-
2147
+ context 'when tallying an element in an embeds_many field' do
2110
2148
  let(:tally) do
2111
- context2.tally("fanatics.age")
2149
+ context2.tally('fanatics.age')
2112
2150
  end
2113
2151
 
2114
- it "returns the correct hash" do
2152
+ it 'returns the correct hash' do
2115
2153
  expect(tally).to eq(
2116
- [1, 2] => 2,
2117
- [1, 3] => 1
2154
+ [ 1, 2 ] => 2,
2155
+ [ 1, 3 ] => 1
2118
2156
  )
2119
2157
  end
2120
2158
  end
2121
2159
 
2122
- context "when tallying an embeds_many field" do
2123
-
2160
+ context 'when tallying an embeds_many field' do
2124
2161
  let(:tally) do
2125
- context2.tally("fanatics")
2162
+ context2.tally('fanatics')
2126
2163
  end
2127
2164
 
2128
- it "returns the correct hash" do
2165
+ it 'returns the correct hash' do
2129
2166
  expect(tally).to eq(
2130
2167
  fans1 => 1,
2131
2168
  fans2 => 1,
2132
- fans3 => 1,
2169
+ fans3 => 1
2133
2170
  )
2134
2171
  end
2135
2172
  end
2136
2173
 
2137
- context "when tallying a field of type array" do
2138
-
2174
+ context 'when tallying a field of type array' do
2139
2175
  let(:tally) do
2140
- context2.tally("genres")
2176
+ context2.tally('genres')
2141
2177
  end
2142
2178
 
2143
- it "returns the correct hash" do
2179
+ it 'returns the correct hash' do
2144
2180
  expect(tally).to eq(
2145
- [1, 2] => 2,
2146
- [1, 3] => 1
2181
+ [ 1, 2 ] => 2,
2182
+ [ 1, 3 ] => 1
2147
2183
  )
2148
2184
  end
2149
2185
  end
2150
2186
 
2151
- context "when tallying an element from an array of hashes" do
2152
-
2187
+ context 'when tallying an element from an array of hashes' do
2153
2188
  let(:tally) do
2154
- context.tally("genres.x")
2189
+ context.tally('genres.x')
2155
2190
  end
2156
2191
 
2157
- it "returns the correct hash without the nil keys" do
2192
+ it 'returns the correct hash without the nil keys' do
2158
2193
  expect(tally).to eq(
2159
- [1, 2] => 2,
2160
- [1, 3] => 1
2194
+ [ 1, 2 ] => 2,
2195
+ [ 1, 3 ] => 1
2161
2196
  )
2162
2197
  end
2163
2198
  end
2164
2199
 
2165
- context "when tallying an element from an array of hashes; with duplicate" do
2166
-
2167
- let(:band4) { Band.new(origin: "tally", genres: [ { x: 1 }, {x: 1} ] ) }
2200
+ context 'when tallying an element from an array of hashes; with duplicate' do
2201
+ let(:band4) { Band.new(origin: 'tally', genres: [ { x: 1 }, { x: 1 } ]) }
2168
2202
 
2169
2203
  let(:criteria) do
2170
- Band.where(origin: "tally").all.tap do |crit|
2204
+ Band.where(origin: 'tally').all.tap do |crit|
2171
2205
  crit.documents = [ band1, band2, band3, band4 ]
2172
2206
  end
2173
2207
  end
2174
2208
 
2175
2209
  let(:tally) do
2176
- context.tally("genres.x")
2210
+ context.tally('genres.x')
2177
2211
  end
2178
2212
 
2179
- it "returns the correct hash without the nil keys" do
2213
+ it 'returns the correct hash without the nil keys' do
2180
2214
  expect(tally).to eq(
2181
- [1, 2] => 2,
2182
- [1, 3] => 1,
2183
- [1, 1] => 1,
2215
+ [ 1, 2 ] => 2,
2216
+ [ 1, 3 ] => 1,
2217
+ [ 1, 1 ] => 1
2184
2218
  )
2185
2219
  end
2186
2220
  end
2187
2221
 
2188
- context "when tallying an aliased field of type array" do
2189
-
2222
+ context 'when tallying an aliased field of type array' do
2190
2223
  let(:person1) { Person.new(array: [ 1, 2 ]) }
2191
2224
  let(:person2) { Person.new(array: [ 1, 3 ]) }
2192
2225
 
@@ -2197,50 +2230,56 @@ describe Mongoid::Contextual::Memory do
2197
2230
  end
2198
2231
 
2199
2232
  let(:tally) do
2200
- context.tally("array")
2233
+ context.tally('array')
2201
2234
  end
2202
2235
 
2203
- it "returns the correct hash" do
2236
+ it 'returns the correct hash' do
2204
2237
  expect(tally).to eq(
2205
- [1, 2] => 1,
2206
- [1, 3] => 1
2238
+ [ 1, 2 ] => 1,
2239
+ [ 1, 3 ] => 1
2207
2240
  )
2208
2241
  end
2209
2242
  end
2210
2243
 
2211
- context "when going multiple levels deep in arrays" do
2212
-
2244
+ context 'when going multiple levels deep in arrays' do
2213
2245
  let(:tally) do
2214
- context.tally("genres.y.z")
2246
+ context.tally('genres.y.z')
2215
2247
  end
2216
2248
 
2217
- it "returns the correct hash" do
2249
+ it 'returns the correct hash' do
2218
2250
  expect(tally).to eq(
2219
- [1, 2] => 2,
2220
- [1, 3] => 1
2251
+ [ 1, 2 ] => 2,
2252
+ [ 1, 3 ] => 1
2221
2253
  )
2222
2254
  end
2223
2255
  end
2224
2256
 
2225
- context "when going multiple levels deep in an array" do
2226
-
2257
+ context 'when going multiple levels deep in an array' do
2227
2258
  let(:tally) do
2228
- context.tally("genres.y.z")
2259
+ context.tally('genres.y.z')
2229
2260
  end
2230
2261
 
2231
- it "returns the correct hash" do
2262
+ it 'returns the correct hash' do
2232
2263
  expect(tally).to eq(
2233
- [1, 2] => 2,
2234
- [1, 3] => 1
2264
+ [ 1, 2 ] => 2,
2265
+ [ 1, 3 ] => 1
2235
2266
  )
2236
2267
  end
2237
2268
  end
2238
2269
 
2239
- context "when tallying deeply nested arrays/embedded associations" do
2240
-
2241
- let(:person1) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
2242
- let(:person2) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
2243
- let(:person3) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]) }
2270
+ context 'when tallying deeply nested arrays/embedded associations' do
2271
+ let(:person1) do
2272
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2273
+ { y: { z: 2 } } ]))) ])
2274
+ end
2275
+ let(:person2) do
2276
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2277
+ { y: { z: 2 } } ]))) ])
2278
+ end
2279
+ let(:person3) do
2280
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2281
+ { y: { z: 3 } } ]))) ])
2282
+ end
2244
2283
 
2245
2284
  let(:criteria) do
2246
2285
  Person.all.tap do |crit|
@@ -2249,10 +2288,10 @@ describe Mongoid::Contextual::Memory do
2249
2288
  end
2250
2289
 
2251
2290
  let(:tally) do
2252
- context.tally("addresses.code.deepest.array.y.z")
2291
+ context.tally('addresses.code.deepest.array.y.z')
2253
2292
  end
2254
2293
 
2255
- it "returns the correct hash" do
2294
+ it 'returns the correct hash' do
2256
2295
  expect(tally).to eq(
2257
2296
  [ [ 1, 2 ] ] => 2,
2258
2297
  [ [ 1, 3 ] ] => 1
@@ -2260,21 +2299,23 @@ describe Mongoid::Contextual::Memory do
2260
2299
  end
2261
2300
  end
2262
2301
 
2263
- context "when tallying deeply nested arrays/embedded associations" do
2264
-
2302
+ context 'when tallying deeply nested arrays/embedded associations' do
2265
2303
  let(:person1) do
2266
2304
  Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
2267
- Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2305
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2306
+ { y: { z: 2 } } ]))) ])
2268
2307
  end
2269
2308
 
2270
2309
  let(:person2) do
2271
2310
  Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
2272
- Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2311
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2312
+ { y: { z: 2 } } ]))) ])
2273
2313
  end
2274
2314
 
2275
2315
  let(:person3) do
2276
2316
  Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
2277
- Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2317
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } },
2318
+ { y: { z: 3 } } ]))) ])
2278
2319
  end
2279
2320
 
2280
2321
  let(:criteria) do
@@ -2284,10 +2325,10 @@ describe Mongoid::Contextual::Memory do
2284
2325
  end
2285
2326
 
2286
2327
  let(:tally) do
2287
- context.tally("addresses.code.deepest.array.y.z")
2328
+ context.tally('addresses.code.deepest.array.y.z')
2288
2329
  end
2289
2330
 
2290
- it "returns the correct hash" do
2331
+ it 'returns the correct hash' do
2291
2332
  expect(tally).to eq(
2292
2333
  [ [ 1, 2 ], [ 1, 2 ] ] => 2,
2293
2334
  [ [ 1, 3 ], [ 1, 3 ] ] => 1
@@ -2295,12 +2336,11 @@ describe Mongoid::Contextual::Memory do
2295
2336
  end
2296
2337
  end
2297
2338
 
2298
- context "when some keys are missing" do
2299
-
2339
+ context 'when some keys are missing' do
2300
2340
  let(:criteria) do
2301
- Band.where(origin: "tally").all.tap do |crit|
2341
+ Band.where(origin: 'tally').all.tap do |crit|
2302
2342
  crit.documents = [ band1, band2, band3 ]
2303
- 3.times{ crit.documents << Band.new(origin: "tally") }
2343
+ 3.times { crit.documents << Band.new(origin: 'tally') }
2304
2344
  end
2305
2345
  end
2306
2346
 
@@ -2308,20 +2348,26 @@ describe Mongoid::Contextual::Memory do
2308
2348
  context.tally(:name)
2309
2349
  end
2310
2350
 
2311
- it "returns the correct hash" do
2351
+ it 'returns the correct hash' do
2312
2352
  expect(tally).to eq(
2313
- "Depeche Mode" => 1,
2314
- "New Order" => 1,
2315
- "10,000 Maniacs" => 1,
2353
+ 'Depeche Mode' => 1,
2354
+ 'New Order' => 1,
2355
+ '10,000 Maniacs' => 1,
2316
2356
  nil => 3
2317
2357
  )
2318
2358
  end
2319
2359
  end
2320
2360
 
2321
- context "when the first element is an embeds_one" do
2322
- let(:person1) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
2323
- let(:person2) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
2324
- let(:person3) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ])) }
2361
+ context 'when the first element is an embeds_one' do
2362
+ let(:person1) do
2363
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
2364
+ end
2365
+ let(:person2) do
2366
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
2367
+ end
2368
+ let(:person3) do
2369
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
2370
+ end
2325
2371
 
2326
2372
  let(:criteria) do
2327
2373
  Person.all.tap do |crit|
@@ -2330,20 +2376,44 @@ describe Mongoid::Contextual::Memory do
2330
2376
  end
2331
2377
 
2332
2378
  let(:tally) do
2333
- context.tally("name.translations.language")
2379
+ context.tally('name.translations.language')
2334
2380
  end
2335
2381
 
2336
- it "returns the correct hash" do
2382
+ it 'returns the correct hash' do
2337
2383
  expect(tally).to eq(
2338
- [1, 2] => 2,
2339
- [1, 3] => 1
2384
+ [ 1, 2 ] => 2,
2385
+ [ 1, 3 ] => 1
2340
2386
  )
2341
2387
  end
2342
2388
  end
2389
+
2390
+ context 'when the field name is a method name' do
2391
+ let!(:person) do
2392
+ Person.create!(ssn: 'secret-ssn')
2393
+ end
2394
+
2395
+ let!(:address) do
2396
+ person.addresses.create!(street: 'hobrecht')
2397
+ end
2398
+
2399
+ let(:criteria) do
2400
+ Address.all.tap do |crit|
2401
+ crit.documents = [ address ]
2402
+ end
2403
+ end
2404
+
2405
+ it 'does not call the method' do
2406
+ expect(address).not_to receive(:destroy)
2407
+ expect(context.tally(:destroy)).to eq(nil => 1)
2408
+ end
2409
+
2410
+ it 'does not disclose the parent document fields' do
2411
+ expect(context.tally('_root.ssn')).to eq(nil => 1)
2412
+ end
2413
+ end
2343
2414
  end
2344
2415
 
2345
2416
  describe '#inc' do
2346
-
2347
2417
  let(:criteria) do
2348
2418
  Address.all.tap do |crit|
2349
2419
  crit.documents = [ Address.new(number: 1),
@@ -2357,22 +2427,21 @@ describe Mongoid::Contextual::Memory do
2357
2427
  end
2358
2428
 
2359
2429
  it 'increases each member' do
2360
- expect(context.inc(number: 10).collect(&:number)).to eql([11, 12, 13])
2430
+ expect(context.inc(number: 10).collect(&:number)).to eql([ 11, 12, 13 ])
2361
2431
  end
2362
2432
  end
2363
2433
 
2364
- describe "#skip" do
2365
-
2434
+ describe '#skip' do
2366
2435
  let(:hobrecht) do
2367
- Address.new(street: "hobrecht")
2436
+ Address.new(street: 'hobrecht')
2368
2437
  end
2369
2438
 
2370
2439
  let(:friedel) do
2371
- Address.new(street: "friedel")
2440
+ Address.new(street: 'friedel')
2372
2441
  end
2373
2442
 
2374
2443
  let(:pfluger) do
2375
- Address.new(street: "pfluger")
2444
+ Address.new(street: 'pfluger')
2376
2445
  end
2377
2446
 
2378
2447
  let(:criteria) do
@@ -2386,31 +2455,27 @@ describe Mongoid::Contextual::Memory do
2386
2455
  end
2387
2456
 
2388
2457
  context 'when there is no collation on the criteria' do
2389
-
2390
2458
  let!(:skip) do
2391
2459
  context.skip(1)
2392
2460
  end
2393
2461
 
2394
- it "returns the context" do
2462
+ it 'returns the context' do
2395
2463
  expect(skip).to eq(context)
2396
2464
  end
2397
2465
 
2398
- context "when asking for all documents" do
2399
-
2400
- context "when only a skip exists" do
2401
-
2402
- it "skips the correct number" do
2466
+ context 'when asking for all documents' do
2467
+ context 'when only a skip exists' do
2468
+ it 'skips the correct number' do
2403
2469
  expect(context.entries).to eq([ friedel, pfluger ])
2404
2470
  end
2405
2471
  end
2406
2472
 
2407
- context "when a skip and limit exist" do
2408
-
2473
+ context 'when a skip and limit exist' do
2409
2474
  before do
2410
2475
  skip.limit(1)
2411
2476
  end
2412
2477
 
2413
- it "applies the skip before the limit" do
2478
+ it 'applies the skip before the limit' do
2414
2479
  expect(context.entries).to eq([ friedel ])
2415
2480
  end
2416
2481
  end
@@ -2418,33 +2483,31 @@ describe Mongoid::Contextual::Memory do
2418
2483
  end
2419
2484
 
2420
2485
  context 'when there is a collation on the criteria' do
2421
-
2422
2486
  let(:criteria) do
2423
2487
  Address.all.tap do |crit|
2424
2488
  crit.documents = [ hobrecht, friedel, pfluger ]
2425
2489
  end.collation(locale: 'en_US', strength: 2)
2426
2490
  end
2427
2491
 
2428
- it "raises an exception" do
2429
- expect {
2492
+ it 'raises an exception' do
2493
+ expect do
2430
2494
  context.skip(1)
2431
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2495
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2432
2496
  end
2433
2497
  end
2434
2498
  end
2435
2499
 
2436
- describe "#sort" do
2437
-
2500
+ describe '#sort' do
2438
2501
  let(:hobrecht) do
2439
- Address.new(street: "hobrecht", number: 9, name: "hobrecht")
2502
+ Address.new(street: 'hobrecht', number: 9, name: 'hobrecht')
2440
2503
  end
2441
2504
 
2442
2505
  let(:friedel) do
2443
- Address.new(street: "friedel", number: 1, name: "friedel")
2506
+ Address.new(street: 'friedel', number: 1, name: 'friedel')
2444
2507
  end
2445
2508
 
2446
2509
  let(:pfluger) do
2447
- Address.new(street: "pfluger", number: 5, name: "pfluger")
2510
+ Address.new(street: 'pfluger', number: 5, name: 'pfluger')
2448
2511
  end
2449
2512
 
2450
2513
  let(:criteria) do
@@ -2457,42 +2520,37 @@ describe Mongoid::Contextual::Memory do
2457
2520
  described_class.new(criteria)
2458
2521
  end
2459
2522
 
2460
- context "when providing a single field sort" do
2461
-
2462
- context "when the sort is ascending" do
2463
-
2523
+ context 'when providing a single field sort' do
2524
+ context 'when the sort is ascending' do
2464
2525
  let!(:sorted) do
2465
2526
  context.sort(street: 1)
2466
2527
  end
2467
2528
 
2468
- it "sorts the documents" do
2529
+ it 'sorts the documents' do
2469
2530
  expect(context.entries).to eq([ friedel, hobrecht, pfluger ])
2470
2531
  end
2471
2532
 
2472
- it "returns the context" do
2533
+ it 'returns the context' do
2473
2534
  expect(sorted).to eq(context)
2474
2535
  end
2475
2536
  end
2476
2537
 
2477
- context "when the sort is descending" do
2478
-
2479
- context "when sorting on a string" do
2480
-
2538
+ context 'when the sort is descending' do
2539
+ context 'when sorting on a string' do
2481
2540
  let!(:sorted) do
2482
2541
  context.sort(street: -1)
2483
2542
  end
2484
2543
 
2485
- it "sorts the documents" do
2544
+ it 'sorts the documents' do
2486
2545
  expect(context.entries).to eq([ pfluger, hobrecht, friedel ])
2487
2546
  end
2488
2547
 
2489
- it "returns the context" do
2548
+ it 'returns the context' do
2490
2549
  expect(sorted).to eq(context)
2491
2550
  end
2492
2551
  end
2493
2552
 
2494
- context "when sorting on a time" do
2495
-
2553
+ context 'when sorting on a time' do
2496
2554
  before do
2497
2555
  pfluger.move_in = 30.days.ago
2498
2556
  hobrecht.move_in = 25.days.ago
@@ -2502,25 +2560,24 @@ describe Mongoid::Contextual::Memory do
2502
2560
  context.sort(move_in: -1)
2503
2561
  end
2504
2562
 
2505
- it "sorts the documents" do
2563
+ it 'sorts the documents' do
2506
2564
  expect(context.entries).to eq([ friedel, hobrecht, pfluger ])
2507
2565
  end
2508
2566
 
2509
- it "returns the context" do
2567
+ it 'returns the context' do
2510
2568
  expect(sorted).to eq(context)
2511
2569
  end
2512
2570
  end
2513
2571
  end
2514
2572
  end
2515
2573
 
2516
- context "when providing multiple sort fields" do
2517
-
2574
+ context 'when providing multiple sort fields' do
2518
2575
  let(:lenau) do
2519
- Address.new(street: "lenau", number: 5, name: "lenau")
2576
+ Address.new(street: 'lenau', number: 5, name: 'lenau')
2520
2577
  end
2521
2578
 
2522
2579
  let(:kampuchea_krom) do
2523
- Address.new(street: "kampuchea krom", number: 5, name: "kampuchea krom")
2580
+ Address.new(street: 'kampuchea krom', number: 5, name: 'kampuchea krom')
2524
2581
  end
2525
2582
 
2526
2583
  before do
@@ -2528,101 +2585,94 @@ describe Mongoid::Contextual::Memory do
2528
2585
  criteria.documents.unshift(kampuchea_krom)
2529
2586
  end
2530
2587
 
2531
- context "when the sort is ascending" do
2532
-
2588
+ context 'when the sort is ascending' do
2533
2589
  let!(:sorted) do
2534
2590
  context.sort(number: 1, street: 1)
2535
2591
  end
2536
2592
 
2537
- it "sorts the documents" do
2593
+ it 'sorts the documents' do
2538
2594
  expect(context.entries).to eq([ friedel, kampuchea_krom, lenau, pfluger, hobrecht ])
2539
2595
  end
2540
2596
 
2541
- it "returns the context" do
2597
+ it 'returns the context' do
2542
2598
  expect(sorted).to eq(context)
2543
2599
  end
2544
2600
  end
2545
2601
 
2546
- context "when the sort is descending" do
2547
-
2602
+ context 'when the sort is descending' do
2548
2603
  let!(:sorted) do
2549
2604
  context.sort(number: -1, street: -1)
2550
2605
  end
2551
2606
 
2552
- it "sorts the documents" do
2607
+ it 'sorts the documents' do
2553
2608
  expect(context.entries).to eq([ hobrecht, pfluger, lenau, kampuchea_krom, friedel ])
2554
2609
  end
2555
2610
 
2556
- it "returns the context" do
2611
+ it 'returns the context' do
2557
2612
  expect(sorted).to eq(context)
2558
2613
  end
2559
2614
  end
2560
2615
  end
2561
2616
 
2562
- context "when the field is nil" do
2563
-
2617
+ context 'when the field is nil' do
2564
2618
  let!(:sorted) do
2565
2619
  context.sort(state: 1)
2566
2620
  end
2567
2621
 
2568
- it "does not sort the documents" do
2622
+ it 'does not sort the documents' do
2569
2623
  expect(context.entries).to eq([ hobrecht, friedel, pfluger ])
2570
2624
  end
2571
2625
 
2572
- it "returns the context" do
2626
+ it 'returns the context' do
2573
2627
  expect(sorted).to eq(context)
2574
2628
  end
2575
2629
  end
2576
2630
 
2577
- context "with localized field" do
2578
-
2631
+ context 'with localized field' do
2579
2632
  let!(:sorted) do
2580
- context.sort("name.en" => 1)
2633
+ context.sort('name.en' => 1)
2581
2634
  end
2582
2635
 
2583
- it "sorts the documents" do
2636
+ it 'sorts the documents' do
2584
2637
  expect(context.entries).to eq([ friedel, hobrecht, pfluger ])
2585
2638
  end
2586
2639
  end
2587
2640
 
2588
2641
  context 'when there is a collation on the criteria' do
2589
-
2590
2642
  let(:criteria) do
2591
2643
  Address.all.tap do |crit|
2592
2644
  crit.documents = [ hobrecht, friedel, pfluger ]
2593
2645
  end.collation(locale: 'en_US', strength: 2)
2594
2646
  end
2595
2647
 
2596
- it "raises an exception" do
2597
- expect {
2648
+ it 'raises an exception' do
2649
+ expect do
2598
2650
  context.sort(state: 1)
2599
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2651
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2600
2652
  end
2601
2653
  end
2602
2654
  end
2603
2655
 
2604
- describe "#update" do
2605
-
2656
+ describe '#update' do
2606
2657
  let(:person) do
2607
2658
  Person.create!
2608
2659
  end
2609
2660
 
2610
2661
  let(:hobrecht) do
2611
- person.addresses.create!(street: "hobrecht")
2662
+ person.addresses.create!(street: 'hobrecht')
2612
2663
  end
2613
2664
 
2614
2665
  let(:friedel) do
2615
- person.addresses.create!(street: "friedel")
2666
+ person.addresses.create!(street: 'friedel')
2616
2667
  end
2617
2668
 
2618
2669
  let(:pfluger) do
2619
- person.addresses.create!(street: "pfluger")
2670
+ person.addresses.create!(street: 'pfluger')
2620
2671
  end
2621
2672
 
2622
- context "when the documents are embedded one level" do
2623
-
2673
+ context 'when the documents are embedded one level' do
2624
2674
  let(:criteria) do
2625
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
2675
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
2626
2676
  crit.documents = [ hobrecht, friedel, pfluger ]
2627
2677
  end
2628
2678
  end
@@ -2631,60 +2681,56 @@ describe Mongoid::Contextual::Memory do
2631
2681
  described_class.new(criteria)
2632
2682
  end
2633
2683
 
2634
- context "when attributes are provided" do
2635
-
2684
+ context 'when attributes are provided' do
2636
2685
  before do
2637
2686
  context.update(number: 5)
2638
2687
  end
2639
2688
 
2640
- it "updates the first matching document" do
2689
+ it 'updates the first matching document' do
2641
2690
  expect(hobrecht.number).to eq(5)
2642
2691
  end
2643
2692
 
2644
- it "does not update the last matching document" do
2693
+ it 'does not update the last matching document' do
2645
2694
  expect(friedel.number).to be_nil
2646
2695
  end
2647
2696
 
2648
- it "does not update non matching docs" do
2697
+ it 'does not update non matching docs' do
2649
2698
  expect(pfluger.number).to be_nil
2650
2699
  end
2651
2700
 
2652
- context "when reloading the embedded documents" do
2653
-
2654
- it "updates the first matching document" do
2701
+ context 'when reloading the embedded documents' do
2702
+ it 'updates the first matching document' do
2655
2703
  expect(hobrecht.reload.number).to eq(5)
2656
2704
  end
2657
2705
 
2658
- it "updates the last matching document" do
2706
+ it 'updates the last matching document' do
2659
2707
  expect(friedel.reload.number).to be_nil
2660
2708
  end
2661
2709
 
2662
- it "does not update non matching docs" do
2710
+ it 'does not update non matching docs' do
2663
2711
  expect(pfluger.reload.number).to be_nil
2664
2712
  end
2665
2713
  end
2666
2714
  end
2667
2715
 
2668
- context "when no attributes are provided" do
2669
-
2670
- it "returns false" do
2716
+ context 'when no attributes are provided' do
2717
+ it 'returns false' do
2671
2718
  expect(context.update).to be false
2672
2719
  end
2673
2720
  end
2674
2721
  end
2675
2722
 
2676
- context "when the documents are embedded multiple levels" do
2677
-
2723
+ context 'when the documents are embedded multiple levels' do
2678
2724
  let!(:home) do
2679
- hobrecht.locations.create!(name: "home")
2725
+ hobrecht.locations.create!(name: 'home')
2680
2726
  end
2681
2727
 
2682
2728
  let!(:work) do
2683
- hobrecht.locations.create!(name: "work")
2729
+ hobrecht.locations.create!(name: 'work')
2684
2730
  end
2685
2731
 
2686
2732
  let(:criteria) do
2687
- Location.where(name: "work").tap do |crit|
2733
+ Location.where(name: 'work').tap do |crit|
2688
2734
  crit.documents = [ home, work ]
2689
2735
  end
2690
2736
  end
@@ -2693,87 +2739,80 @@ describe Mongoid::Contextual::Memory do
2693
2739
  described_class.new(criteria)
2694
2740
  end
2695
2741
 
2696
- context "when attributes are provided" do
2697
-
2742
+ context 'when attributes are provided' do
2698
2743
  before do
2699
2744
  context.update(number: 5)
2700
2745
  end
2701
2746
 
2702
- it "updates the first matching document" do
2747
+ it 'updates the first matching document' do
2703
2748
  expect(work.number).to eq(5)
2704
2749
  end
2705
2750
 
2706
- it "does not update non matching docs" do
2751
+ it 'does not update non matching docs' do
2707
2752
  expect(home.number).to be_nil
2708
2753
  end
2709
2754
 
2710
- context "when reloading the embedded documents" do
2711
-
2712
- it "updates the first matching document" do
2755
+ context 'when reloading the embedded documents' do
2756
+ it 'updates the first matching document' do
2713
2757
  expect(work.reload.number).to eq(5)
2714
2758
  end
2715
2759
 
2716
- it "does not update non matching docs" do
2760
+ it 'does not update non matching docs' do
2717
2761
  expect(home.reload.number).to be_nil
2718
2762
  end
2719
2763
  end
2720
2764
  end
2721
2765
 
2722
- context "when no attributes are provided" do
2723
-
2724
- it "returns false" do
2766
+ context 'when no attributes are provided' do
2767
+ it 'returns false' do
2725
2768
  expect(context.update).to be false
2726
2769
  end
2727
2770
  end
2728
2771
  end
2729
2772
 
2730
2773
  context 'when there is a collation on the criteria' do
2731
-
2732
2774
  let(:criteria) do
2733
2775
  Address.all.collation(locale: 'en_US', strength: 2)
2734
2776
  end
2735
2777
 
2736
- it "raises an exception" do
2737
- expect {
2778
+ it 'raises an exception' do
2779
+ expect do
2738
2780
  context.update
2739
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2781
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2740
2782
  end
2741
2783
  end
2742
2784
  end
2743
2785
 
2744
- describe "#update_all" do
2745
-
2786
+ describe '#update_all' do
2746
2787
  let(:person) do
2747
2788
  Person.create!
2748
2789
  end
2749
2790
 
2750
2791
  let(:hobrecht) do
2751
- person.addresses.create!(street: "hobrecht")
2792
+ person.addresses.create!(street: 'hobrecht')
2752
2793
  end
2753
2794
 
2754
2795
  let(:friedel) do
2755
- person.addresses.create!(street: "friedel")
2796
+ person.addresses.create!(street: 'friedel')
2756
2797
  end
2757
2798
 
2758
2799
  let(:pfluger) do
2759
- person.addresses.create!(street: "pfluger")
2800
+ person.addresses.create!(street: 'pfluger')
2760
2801
  end
2761
2802
 
2762
2803
  context 'when there is a collation on the criteria' do
2763
-
2764
2804
  let(:criteria) do
2765
2805
  Address.all.collation(locale: 'en_US', strength: 2)
2766
2806
  end
2767
2807
 
2768
- it "raises an exception" do
2769
- expect {
2808
+ it 'raises an exception' do
2809
+ expect do
2770
2810
  context.update_all({})
2771
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2811
+ end.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
2772
2812
  end
2773
2813
  end
2774
2814
 
2775
- context "when the documents are empty" do
2776
-
2815
+ context 'when the documents are empty' do
2777
2816
  let(:person_two) do
2778
2817
  Person.create!
2779
2818
  end
@@ -2786,15 +2825,14 @@ describe Mongoid::Contextual::Memory do
2786
2825
  described_class.new(criteria)
2787
2826
  end
2788
2827
 
2789
- it "returns false" do
2828
+ it 'returns false' do
2790
2829
  expect(context.update_all({})).to be false
2791
2830
  end
2792
2831
  end
2793
2832
 
2794
- context "when the documents are embedded one level" do
2795
-
2833
+ context 'when the documents are embedded one level' do
2796
2834
  let(:criteria) do
2797
- Address.any_in(street: [ "hobrecht", "friedel" ]).tap do |crit|
2835
+ Address.any_in(street: %w[hobrecht friedel]).tap do |crit|
2798
2836
  crit.documents = [ hobrecht, friedel, pfluger ]
2799
2837
  end
2800
2838
  end
@@ -2803,90 +2841,84 @@ describe Mongoid::Contextual::Memory do
2803
2841
  described_class.new(criteria)
2804
2842
  end
2805
2843
 
2806
- context "when providing aliased fields" do
2807
-
2844
+ context 'when providing aliased fields' do
2808
2845
  before do
2809
- context.update_all(suite: "10B")
2846
+ context.update_all(suite: '10B')
2810
2847
  end
2811
2848
 
2812
- it "updates the first matching document" do
2813
- expect(hobrecht.suite).to eq("10B")
2849
+ it 'updates the first matching document' do
2850
+ expect(hobrecht.suite).to eq('10B')
2814
2851
  end
2815
2852
 
2816
- it "updates the last matching document" do
2817
- expect(friedel.suite).to eq("10B")
2853
+ it 'updates the last matching document' do
2854
+ expect(friedel.suite).to eq('10B')
2818
2855
  end
2819
2856
 
2820
- it "does not update non matching docs" do
2857
+ it 'does not update non matching docs' do
2821
2858
  expect(pfluger.suite).to be_nil
2822
2859
  end
2823
2860
  end
2824
2861
 
2825
- context "when attributes are provided" do
2826
-
2862
+ context 'when attributes are provided' do
2827
2863
  before do
2828
2864
  context.update_all(number: 5)
2829
2865
  end
2830
2866
 
2831
- it "updates the first matching document" do
2867
+ it 'updates the first matching document' do
2832
2868
  expect(hobrecht.number).to eq(5)
2833
2869
  end
2834
2870
 
2835
- it "updates the last matching document" do
2871
+ it 'updates the last matching document' do
2836
2872
  expect(friedel.number).to eq(5)
2837
2873
  end
2838
2874
 
2839
- it "does not update non matching docs" do
2875
+ it 'does not update non matching docs' do
2840
2876
  expect(pfluger.number).to be_nil
2841
2877
  end
2842
2878
 
2843
- context "when reloading the embedded documents" do
2844
-
2845
- it "updates the first matching document" do
2879
+ context 'when reloading the embedded documents' do
2880
+ it 'updates the first matching document' do
2846
2881
  expect(hobrecht.reload.number).to eq(5)
2847
2882
  end
2848
2883
 
2849
- it "updates the last matching document" do
2884
+ it 'updates the last matching document' do
2850
2885
  expect(friedel.reload.number).to eq(5)
2851
2886
  end
2852
2887
 
2853
- it "does not update non matching docs" do
2888
+ it 'does not update non matching docs' do
2854
2889
  expect(pfluger.reload.number).to be_nil
2855
2890
  end
2856
2891
  end
2857
2892
 
2858
- context "when updating the documents a second time" do
2859
-
2893
+ context 'when updating the documents a second time' do
2860
2894
  before do
2861
2895
  context.update_all(number: 5)
2862
2896
  end
2863
2897
 
2864
- it "does not error on the update" do
2898
+ it 'does not error on the update' do
2865
2899
  expect(hobrecht.number).to eq(5)
2866
2900
  end
2867
2901
  end
2868
2902
  end
2869
2903
 
2870
- context "when no attributes are provided" do
2871
-
2872
- it "returns false" do
2904
+ context 'when no attributes are provided' do
2905
+ it 'returns false' do
2873
2906
  expect(context.update_all).to be false
2874
2907
  end
2875
2908
  end
2876
2909
  end
2877
2910
 
2878
- context "when the documents are embedded multiple levels" do
2879
-
2911
+ context 'when the documents are embedded multiple levels' do
2880
2912
  let!(:home) do
2881
- hobrecht.locations.create!(name: "home")
2913
+ hobrecht.locations.create!(name: 'home')
2882
2914
  end
2883
2915
 
2884
2916
  let!(:work) do
2885
- hobrecht.locations.create!(name: "work")
2917
+ hobrecht.locations.create!(name: 'work')
2886
2918
  end
2887
2919
 
2888
2920
  let(:criteria) do
2889
- Location.where(name: "work").tap do |crit|
2921
+ Location.where(name: 'work').tap do |crit|
2890
2922
  crit.documents = [ home, work ]
2891
2923
  end
2892
2924
  end
@@ -2895,35 +2927,32 @@ describe Mongoid::Contextual::Memory do
2895
2927
  described_class.new(criteria)
2896
2928
  end
2897
2929
 
2898
- context "when attributes are provided" do
2899
-
2930
+ context 'when attributes are provided' do
2900
2931
  before do
2901
2932
  context.update_all(number: 5)
2902
2933
  end
2903
2934
 
2904
- it "updates the first matching document" do
2935
+ it 'updates the first matching document' do
2905
2936
  expect(work.number).to eq(5)
2906
2937
  end
2907
2938
 
2908
- it "does not update non matching docs" do
2939
+ it 'does not update non matching docs' do
2909
2940
  expect(home.number).to be_nil
2910
2941
  end
2911
2942
 
2912
- context "when reloading the embedded documents" do
2913
-
2914
- it "updates the first matching document" do
2943
+ context 'when reloading the embedded documents' do
2944
+ it 'updates the first matching document' do
2915
2945
  expect(work.reload.number).to eq(5)
2916
2946
  end
2917
2947
 
2918
- it "does not update non matching docs" do
2948
+ it 'does not update non matching docs' do
2919
2949
  expect(home.reload.number).to be_nil
2920
2950
  end
2921
2951
  end
2922
2952
  end
2923
2953
 
2924
- context "when no attributes are provided" do
2925
-
2926
- it "returns false" do
2954
+ context 'when no attributes are provided' do
2955
+ it 'returns false' do
2927
2956
  expect(context.update_all).to be false
2928
2957
  end
2929
2958
  end