mongoid 7.0.13 → 8.0.8

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 (1089) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +30 -30
  4. data/README.md +32 -19
  5. data/Rakefile +43 -0
  6. data/lib/config/locales/en.yml +178 -95
  7. data/lib/mongoid/association/accessors.rb +175 -83
  8. data/lib/mongoid/association/bindable.rb +57 -28
  9. data/lib/mongoid/association/builders.rb +8 -14
  10. data/lib/mongoid/association/constrainable.rb +5 -7
  11. data/lib/mongoid/association/depending.rb +9 -18
  12. data/lib/mongoid/association/eager_loadable.rb +31 -10
  13. data/lib/mongoid/association/embedded/batchable.rb +67 -53
  14. data/lib/mongoid/association/embedded/cyclic.rb +10 -17
  15. data/lib/mongoid/association/embedded/embedded_in/binding.rb +27 -9
  16. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +7 -4
  17. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +14 -24
  18. data/lib/mongoid/association/embedded/embedded_in.rb +9 -28
  19. data/lib/mongoid/association/embedded/embeds_many/binding.rb +5 -8
  20. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +8 -5
  21. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +143 -122
  22. data/lib/mongoid/association/embedded/embeds_many.rb +8 -36
  23. data/lib/mongoid/association/embedded/embeds_one/binding.rb +4 -8
  24. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +26 -9
  25. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +63 -29
  26. data/lib/mongoid/association/embedded/embeds_one.rb +9 -33
  27. data/lib/mongoid/association/embedded.rb +2 -0
  28. data/lib/mongoid/association/macros.rb +71 -41
  29. data/lib/mongoid/association/many.rb +25 -35
  30. data/lib/mongoid/association/marshalable.rb +3 -6
  31. data/lib/mongoid/association/nested/many.rb +22 -30
  32. data/lib/mongoid/association/nested/nested_buildable.rb +9 -15
  33. data/lib/mongoid/association/nested/one.rb +19 -30
  34. data/lib/mongoid/association/nested.rb +3 -3
  35. data/lib/mongoid/association/one.rb +5 -12
  36. data/lib/mongoid/association/options.rb +16 -46
  37. data/lib/mongoid/association/proxy.rb +37 -38
  38. data/lib/mongoid/association/referenced/auto_save.rb +9 -14
  39. data/lib/mongoid/association/referenced/belongs_to/binding.rb +5 -9
  40. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +11 -9
  41. data/lib/mongoid/association/referenced/belongs_to/eager.rb +40 -3
  42. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +19 -31
  43. data/lib/mongoid/association/referenced/belongs_to.rb +16 -38
  44. data/lib/mongoid/association/referenced/counter_cache.rb +14 -25
  45. data/lib/mongoid/association/referenced/eager.rb +41 -40
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +12 -11
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +5 -5
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -1
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +105 -68
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +29 -46
  51. data/lib/mongoid/association/referenced/has_many/binding.rb +3 -6
  52. data/lib/mongoid/association/referenced/has_many/buildable.rb +5 -5
  53. data/lib/mongoid/association/referenced/has_many/eager.rb +2 -1
  54. data/lib/mongoid/association/referenced/has_many/enumerable.rb +440 -456
  55. data/lib/mongoid/association/referenced/has_many/proxy.rb +101 -124
  56. data/lib/mongoid/association/referenced/has_many.rb +21 -45
  57. data/lib/mongoid/association/referenced/has_one/binding.rb +4 -9
  58. data/lib/mongoid/association/referenced/has_one/buildable.rb +20 -6
  59. data/lib/mongoid/association/referenced/has_one/eager.rb +2 -1
  60. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +16 -29
  61. data/lib/mongoid/association/referenced/has_one/proxy.rb +25 -30
  62. data/lib/mongoid/association/referenced/has_one.rb +16 -36
  63. data/lib/mongoid/association/referenced/syncable.rb +11 -26
  64. data/lib/mongoid/association/referenced.rb +2 -0
  65. data/lib/mongoid/association/reflections.rb +7 -6
  66. data/lib/mongoid/association/relatable.rb +62 -84
  67. data/lib/mongoid/association.rb +13 -27
  68. data/lib/mongoid/atomic/modifiers.rb +29 -53
  69. data/lib/mongoid/atomic/paths/embedded/many.rb +23 -7
  70. data/lib/mongoid/atomic/paths/embedded/one.rb +4 -7
  71. data/lib/mongoid/atomic/paths/embedded.rb +2 -3
  72. data/lib/mongoid/atomic/paths/root.rb +4 -7
  73. data/lib/mongoid/atomic/paths.rb +2 -1
  74. data/lib/mongoid/atomic.rb +45 -51
  75. data/lib/mongoid/attributes/dynamic.rb +6 -21
  76. data/lib/mongoid/attributes/nested.rb +11 -14
  77. data/lib/mongoid/attributes/processing.rb +46 -30
  78. data/lib/mongoid/attributes/projector.rb +119 -0
  79. data/lib/mongoid/attributes/readonly.rb +5 -8
  80. data/lib/mongoid/attributes.rb +80 -98
  81. data/lib/mongoid/cacheable.rb +7 -10
  82. data/lib/mongoid/changeable.rb +49 -70
  83. data/lib/mongoid/clients/factory.rb +42 -17
  84. data/lib/mongoid/clients/options.rb +15 -14
  85. data/lib/mongoid/clients/sessions.rb +4 -20
  86. data/lib/mongoid/clients/storage_options.rb +7 -12
  87. data/lib/mongoid/clients/validators/storage.rb +5 -12
  88. data/lib/mongoid/clients/validators.rb +2 -1
  89. data/lib/mongoid/clients.rb +3 -10
  90. data/lib/mongoid/composable.rb +5 -9
  91. data/lib/mongoid/config/environment.rb +30 -5
  92. data/lib/mongoid/config/options.rb +23 -23
  93. data/lib/mongoid/config/validators/client.rb +8 -23
  94. data/lib/mongoid/config/validators/option.rb +2 -3
  95. data/lib/mongoid/config/validators.rb +2 -1
  96. data/lib/mongoid/config.rb +164 -48
  97. data/lib/mongoid/contextual/aggregable/memory.rb +40 -27
  98. data/lib/mongoid/contextual/aggregable/mongo.rb +32 -33
  99. data/lib/mongoid/contextual/aggregable/none.rb +65 -0
  100. data/lib/mongoid/contextual/aggregable.rb +17 -0
  101. data/lib/mongoid/contextual/atomic.rb +29 -31
  102. data/lib/mongoid/contextual/command.rb +2 -5
  103. data/lib/mongoid/contextual/geo_near.rb +13 -44
  104. data/lib/mongoid/contextual/map_reduce.rb +7 -35
  105. data/lib/mongoid/contextual/memory.rb +187 -81
  106. data/lib/mongoid/contextual/mongo.rb +360 -239
  107. data/lib/mongoid/contextual/none.rb +109 -31
  108. data/lib/mongoid/contextual/queryable.rb +3 -4
  109. data/lib/mongoid/contextual.rb +9 -11
  110. data/lib/mongoid/copyable.rb +42 -17
  111. data/lib/mongoid/criteria/findable.rb +19 -19
  112. data/lib/mongoid/criteria/includable.rb +30 -33
  113. data/lib/mongoid/criteria/inspectable.rb +2 -3
  114. data/lib/mongoid/criteria/marshalable.rb +12 -7
  115. data/lib/mongoid/criteria/modifiable.rb +2 -19
  116. data/lib/mongoid/criteria/options.rb +2 -3
  117. data/lib/mongoid/criteria/permission.rb +3 -2
  118. data/lib/mongoid/criteria/queryable/aggregable.rb +4 -15
  119. data/lib/mongoid/criteria/queryable/expandable.rb +68 -0
  120. data/lib/mongoid/criteria/queryable/extensions/array.rb +7 -41
  121. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +28 -8
  122. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +5 -6
  123. data/lib/mongoid/criteria/queryable/extensions/date.rb +9 -9
  124. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +11 -12
  125. data/lib/mongoid/criteria/queryable/extensions/hash.rb +4 -41
  126. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -14
  127. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -21
  128. data/lib/mongoid/criteria/queryable/extensions/object.rb +6 -30
  129. data/lib/mongoid/criteria/queryable/extensions/range.rb +49 -17
  130. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +9 -16
  131. data/lib/mongoid/criteria/queryable/extensions/set.rb +4 -5
  132. data/lib/mongoid/criteria/queryable/extensions/string.rb +7 -32
  133. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +7 -22
  134. data/lib/mongoid/criteria/queryable/extensions/time.rb +9 -9
  135. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +9 -9
  136. data/lib/mongoid/criteria/queryable/extensions.rb +1 -4
  137. data/lib/mongoid/criteria/queryable/key.rb +39 -24
  138. data/lib/mongoid/criteria/queryable/macroable.rb +3 -4
  139. data/lib/mongoid/criteria/queryable/mergeable.rb +200 -40
  140. data/lib/mongoid/criteria/queryable/optional.rb +10 -59
  141. data/lib/mongoid/criteria/queryable/options.rb +4 -21
  142. data/lib/mongoid/criteria/queryable/pipeline.rb +5 -15
  143. data/lib/mongoid/criteria/queryable/selectable.rb +417 -171
  144. data/lib/mongoid/criteria/queryable/selector.rb +127 -30
  145. data/lib/mongoid/criteria/queryable/smash.rb +42 -18
  146. data/lib/mongoid/criteria/queryable/storable.rb +237 -0
  147. data/lib/mongoid/criteria/queryable.rb +18 -15
  148. data/lib/mongoid/criteria/scopable.rb +29 -21
  149. data/lib/mongoid/criteria/translator.rb +45 -0
  150. data/lib/mongoid/criteria.rb +95 -107
  151. data/lib/mongoid/deprecable.rb +37 -0
  152. data/lib/mongoid/deprecation.rb +25 -0
  153. data/lib/mongoid/document.rb +148 -97
  154. data/lib/mongoid/equality.rb +35 -18
  155. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -5
  156. data/lib/mongoid/errors/callback.rb +2 -3
  157. data/lib/mongoid/errors/criteria_argument_required.rb +18 -0
  158. data/lib/mongoid/errors/delete_restriction.rb +10 -13
  159. data/lib/mongoid/errors/document_not_destroyed.rb +4 -7
  160. data/lib/mongoid/errors/document_not_found.rb +35 -21
  161. data/lib/mongoid/errors/empty_config_file.rb +25 -0
  162. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -3
  163. data/lib/mongoid/errors/invalid_collection.rb +2 -1
  164. data/lib/mongoid/errors/invalid_config_file.rb +25 -0
  165. data/lib/mongoid/errors/invalid_config_option.rb +3 -4
  166. data/lib/mongoid/errors/invalid_dependent_strategy.rb +3 -4
  167. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +24 -0
  168. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  169. data/lib/mongoid/errors/invalid_elem_match_operator.rb +32 -0
  170. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +25 -0
  171. data/lib/mongoid/errors/invalid_expression_operator.rb +27 -0
  172. data/lib/mongoid/errors/invalid_field.rb +8 -7
  173. data/lib/mongoid/errors/invalid_field_operator.rb +32 -0
  174. data/lib/mongoid/errors/invalid_field_option.rb +2 -3
  175. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  176. data/lib/mongoid/errors/invalid_find.rb +2 -3
  177. data/lib/mongoid/errors/invalid_includes.rb +2 -3
  178. data/lib/mongoid/errors/invalid_index.rb +2 -3
  179. data/lib/mongoid/errors/invalid_options.rb +4 -5
  180. data/lib/mongoid/errors/invalid_path.rb +2 -3
  181. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -5
  182. data/lib/mongoid/errors/invalid_query.rb +40 -0
  183. data/lib/mongoid/errors/invalid_relation.rb +5 -10
  184. data/lib/mongoid/errors/invalid_relation_option.rb +4 -5
  185. data/lib/mongoid/errors/invalid_scope.rb +2 -3
  186. data/lib/mongoid/errors/invalid_session_use.rb +3 -6
  187. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -5
  188. data/lib/mongoid/errors/invalid_storage_options.rb +3 -4
  189. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -3
  190. data/lib/mongoid/errors/invalid_time.rb +2 -3
  191. data/lib/mongoid/errors/inverse_not_found.rb +3 -4
  192. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -3
  193. data/lib/mongoid/errors/mixed_relations.rb +2 -3
  194. data/lib/mongoid/errors/mongoid_error.rb +6 -13
  195. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -4
  196. data/lib/mongoid/errors/no_client_config.rb +4 -5
  197. data/lib/mongoid/errors/no_client_database.rb +3 -4
  198. data/lib/mongoid/errors/no_client_hosts.rb +3 -4
  199. data/lib/mongoid/errors/no_clients_config.rb +2 -3
  200. data/lib/mongoid/errors/no_default_client.rb +3 -4
  201. data/lib/mongoid/errors/no_environment.rb +2 -3
  202. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -3
  203. data/lib/mongoid/errors/no_metadata.rb +2 -3
  204. data/lib/mongoid/errors/no_parent.rb +2 -3
  205. data/lib/mongoid/errors/readonly_attribute.rb +3 -4
  206. data/lib/mongoid/errors/readonly_document.rb +3 -6
  207. data/lib/mongoid/errors/scope_overwrite.rb +2 -1
  208. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -1
  209. data/lib/mongoid/errors/unknown_attribute.rb +3 -4
  210. data/lib/mongoid/errors/unknown_model.rb +2 -3
  211. data/lib/mongoid/errors/unsaved_document.rb +3 -2
  212. data/lib/mongoid/errors/unsupported_javascript.rb +2 -3
  213. data/lib/mongoid/errors/validations.rb +2 -1
  214. data/lib/mongoid/errors.rb +14 -3
  215. data/lib/mongoid/evolvable.rb +4 -5
  216. data/lib/mongoid/extensions/array.rb +37 -44
  217. data/lib/mongoid/extensions/big_decimal.rb +35 -21
  218. data/lib/mongoid/extensions/binary.rb +42 -0
  219. data/lib/mongoid/extensions/boolean.rb +10 -6
  220. data/lib/mongoid/extensions/date.rb +32 -25
  221. data/lib/mongoid/extensions/date_time.rb +5 -13
  222. data/lib/mongoid/extensions/decimal128.rb +2 -5
  223. data/lib/mongoid/extensions/false_class.rb +5 -8
  224. data/lib/mongoid/extensions/float.rb +12 -14
  225. data/lib/mongoid/extensions/hash.rb +87 -45
  226. data/lib/mongoid/extensions/integer.rb +12 -16
  227. data/lib/mongoid/extensions/module.rb +3 -4
  228. data/lib/mongoid/extensions/nil_class.rb +2 -5
  229. data/lib/mongoid/extensions/object.rb +25 -50
  230. data/lib/mongoid/extensions/object_id.rb +2 -7
  231. data/lib/mongoid/extensions/range.rb +42 -20
  232. data/lib/mongoid/extensions/regexp.rb +13 -7
  233. data/lib/mongoid/extensions/set.rb +13 -11
  234. data/lib/mongoid/extensions/string.rb +30 -61
  235. data/lib/mongoid/extensions/symbol.rb +6 -22
  236. data/lib/mongoid/extensions/time.rb +37 -23
  237. data/lib/mongoid/extensions/time_with_zone.rb +26 -9
  238. data/lib/mongoid/extensions/true_class.rb +5 -8
  239. data/lib/mongoid/extensions.rb +19 -3
  240. data/lib/mongoid/factory.rb +104 -17
  241. data/lib/mongoid/fields/foreign_key.rb +14 -26
  242. data/lib/mongoid/fields/localized.rb +11 -15
  243. data/lib/mongoid/fields/standard.rb +13 -43
  244. data/lib/mongoid/fields/validators/macro.rb +32 -20
  245. data/lib/mongoid/fields/validators.rb +2 -1
  246. data/lib/mongoid/fields.rb +328 -85
  247. data/lib/mongoid/findable.rb +90 -33
  248. data/lib/mongoid/indexable/specification.rb +5 -18
  249. data/lib/mongoid/indexable/validators/options.rb +8 -9
  250. data/lib/mongoid/indexable.rb +6 -21
  251. data/lib/mongoid/inspectable.rb +4 -11
  252. data/lib/mongoid/interceptable.rb +191 -41
  253. data/lib/mongoid/loggable.rb +13 -16
  254. data/lib/mongoid/matchable.rb +3 -154
  255. data/lib/mongoid/matcher/all.rb +22 -0
  256. data/lib/mongoid/matcher/and.rb +21 -0
  257. data/lib/mongoid/matcher/bits.rb +41 -0
  258. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  259. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  260. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  261. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  262. data/lib/mongoid/matcher/elem_match.rb +36 -0
  263. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  264. data/lib/mongoid/matcher/eq.rb +11 -0
  265. data/lib/mongoid/matcher/eq_impl.rb +67 -0
  266. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +26 -0
  267. data/lib/mongoid/matcher/exists.rb +15 -0
  268. data/lib/mongoid/matcher/expression.rb +35 -0
  269. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  270. data/lib/mongoid/matcher/field_expression.rb +62 -0
  271. data/lib/mongoid/matcher/field_operator.rb +54 -0
  272. data/lib/mongoid/matcher/gt.rb +17 -0
  273. data/lib/mongoid/matcher/gte.rb +17 -0
  274. data/lib/mongoid/matcher/in.rb +25 -0
  275. data/lib/mongoid/matcher/lt.rb +17 -0
  276. data/lib/mongoid/matcher/lte.rb +17 -0
  277. data/lib/mongoid/matcher/mod.rb +17 -0
  278. data/lib/mongoid/matcher/ne.rb +16 -0
  279. data/lib/mongoid/matcher/nin.rb +11 -0
  280. data/lib/mongoid/matcher/nor.rb +25 -0
  281. data/lib/mongoid/matcher/not.rb +29 -0
  282. data/lib/mongoid/matcher/or.rb +21 -0
  283. data/lib/mongoid/matcher/regex.rb +41 -0
  284. data/lib/mongoid/matcher/size.rb +26 -0
  285. data/lib/mongoid/matcher/type.rb +99 -0
  286. data/lib/mongoid/matcher.rb +130 -0
  287. data/lib/mongoid/persistable/creatable.rb +22 -30
  288. data/lib/mongoid/persistable/deletable.rb +6 -22
  289. data/lib/mongoid/persistable/destroyable.rb +12 -11
  290. data/lib/mongoid/persistable/incrementable.rb +6 -7
  291. data/lib/mongoid/persistable/logical.rb +4 -6
  292. data/lib/mongoid/persistable/poppable.rb +3 -6
  293. data/lib/mongoid/persistable/pullable.rb +3 -8
  294. data/lib/mongoid/persistable/pushable.rb +3 -8
  295. data/lib/mongoid/persistable/renamable.rb +10 -8
  296. data/lib/mongoid/persistable/savable.rb +5 -10
  297. data/lib/mongoid/persistable/settable.rb +3 -6
  298. data/lib/mongoid/persistable/unsettable.rb +9 -9
  299. data/lib/mongoid/persistable/updatable.rb +50 -31
  300. data/lib/mongoid/persistable/upsertable.rb +5 -10
  301. data/lib/mongoid/persistable.rb +135 -40
  302. data/lib/mongoid/persistence_context.rb +85 -45
  303. data/lib/mongoid/positional.rb +2 -5
  304. data/lib/mongoid/query_cache.rb +13 -280
  305. data/lib/mongoid/railtie.rb +3 -16
  306. data/lib/mongoid/railties/controller_runtime.rb +4 -2
  307. data/lib/mongoid/railties/database.rake +9 -0
  308. data/lib/mongoid/reloadable.rb +19 -22
  309. data/lib/mongoid/scopable.rb +34 -57
  310. data/lib/mongoid/selectable.rb +8 -18
  311. data/lib/mongoid/serializable.rb +33 -34
  312. data/lib/mongoid/shardable.rb +108 -21
  313. data/lib/mongoid/stateful.rb +38 -19
  314. data/lib/mongoid/stringified_symbol.rb +52 -0
  315. data/lib/mongoid/tasks/database.rake +12 -5
  316. data/lib/mongoid/tasks/database.rb +85 -7
  317. data/lib/mongoid/threaded/lifecycle.rb +7 -26
  318. data/lib/mongoid/threaded.rb +44 -67
  319. data/lib/mongoid/timestamps/created/short.rb +2 -1
  320. data/lib/mongoid/timestamps/created.rb +4 -3
  321. data/lib/mongoid/timestamps/short.rb +2 -1
  322. data/lib/mongoid/timestamps/timeless.rb +6 -9
  323. data/lib/mongoid/timestamps/updated/short.rb +2 -1
  324. data/lib/mongoid/timestamps/updated.rb +5 -6
  325. data/lib/mongoid/timestamps.rb +3 -2
  326. data/lib/mongoid/touchable.rb +54 -25
  327. data/lib/mongoid/traversable.rb +185 -61
  328. data/lib/mongoid/validatable/associated.rb +99 -22
  329. data/lib/mongoid/validatable/format.rb +2 -1
  330. data/lib/mongoid/validatable/length.rb +2 -1
  331. data/lib/mongoid/validatable/localizable.rb +3 -4
  332. data/lib/mongoid/validatable/macros.rb +2 -9
  333. data/lib/mongoid/validatable/presence.rb +10 -15
  334. data/lib/mongoid/validatable/queryable.rb +2 -3
  335. data/lib/mongoid/validatable/uniqueness.rb +29 -41
  336. data/lib/mongoid/validatable.rb +22 -33
  337. data/lib/mongoid/version.rb +2 -2
  338. data/lib/mongoid/warnings.rb +28 -0
  339. data/lib/mongoid.rb +34 -15
  340. data/lib/rails/generators/mongoid/config/config_generator.rb +2 -1
  341. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +53 -32
  342. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -2
  343. data/lib/rails/generators/mongoid_generator.rb +2 -1
  344. data/lib/rails/mongoid.rb +4 -5
  345. data/spec/README.md +19 -4
  346. data/spec/config/mongoid.yml +17 -0
  347. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  348. data/spec/integration/app_spec.rb +31 -27
  349. data/spec/integration/associations/belongs_to_spec.rb +20 -0
  350. data/spec/integration/associations/embedded_dirty_spec.rb +57 -0
  351. data/spec/integration/associations/embedded_spec.rb +162 -55
  352. data/spec/integration/associations/embeds_many_spec.rb +219 -0
  353. data/spec/integration/associations/embeds_one_spec.rb +41 -0
  354. data/spec/integration/associations/foreign_key_spec.rb +107 -0
  355. data/spec/integration/associations/foreign_key_spec_models.rb +64 -0
  356. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +61 -0
  357. data/spec/integration/associations/has_many_spec.rb +128 -0
  358. data/spec/integration/associations/has_one_spec.rb +272 -0
  359. data/spec/integration/associations/nested_attributes_assignment_spec.rb +115 -0
  360. data/spec/integration/associations/reverse_population_spec.rb +34 -0
  361. data/spec/integration/associations/reverse_population_spec_models.rb +36 -0
  362. data/spec/integration/associations/scope_option_spec.rb +101 -0
  363. data/spec/integration/atomic/modifiers_spec.rb +116 -0
  364. data/spec/integration/bson_regexp_raw_spec.rb +19 -0
  365. data/spec/integration/callbacks_models.rb +107 -1
  366. data/spec/integration/callbacks_spec.rb +262 -8
  367. data/spec/integration/contextual/empty_spec.rb +141 -0
  368. data/spec/integration/criteria/alias_query_spec.rb +161 -0
  369. data/spec/integration/criteria/date_field_spec.rb +1 -2
  370. data/spec/integration/criteria/default_scope_spec.rb +72 -0
  371. data/spec/integration/criteria/logical_spec.rb +124 -0
  372. data/spec/integration/criteria/range_spec.rb +359 -0
  373. data/spec/integration/criteria/time_with_zone_spec.rb +125 -15
  374. data/spec/integration/discriminator_key_spec.rb +392 -0
  375. data/spec/integration/discriminator_value_spec.rb +206 -0
  376. data/spec/integration/document_spec.rb +30 -1
  377. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  378. data/spec/integration/i18n_fallbacks_spec.rb +73 -0
  379. data/spec/integration/{matchable_spec.rb → matcher_examples_spec.rb} +130 -45
  380. data/spec/integration/matcher_operator_data/all.yml +140 -0
  381. data/spec/integration/matcher_operator_data/and.yml +93 -0
  382. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  383. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  384. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  385. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  386. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  387. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  388. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  389. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  390. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  391. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  392. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  393. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  394. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  395. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  396. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  397. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  398. data/spec/integration/matcher_operator_data/in.yml +210 -0
  399. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  400. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  401. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  402. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  403. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  404. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  405. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  406. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  407. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  408. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  409. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  410. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  411. data/spec/integration/matcher_operator_data/not.yml +196 -0
  412. data/spec/integration/matcher_operator_data/or.yml +137 -0
  413. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  414. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  415. data/spec/integration/matcher_operator_data/size.yml +174 -0
  416. data/spec/integration/matcher_operator_data/type.yml +70 -0
  417. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  418. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  419. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  420. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  421. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  422. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  423. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  424. data/spec/integration/matcher_operator_data/type_decimal.yml +41 -0
  425. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  426. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  427. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  428. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  429. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  430. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  431. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  432. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  433. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  434. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  435. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  436. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  437. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  438. data/spec/integration/matcher_operator_spec.rb +122 -0
  439. data/spec/integration/matcher_spec.rb +283 -0
  440. data/spec/integration/persistence/range_field_spec.rb +350 -0
  441. data/spec/integration/server_query_spec.rb +141 -0
  442. data/spec/integration/shardable_spec.rb +148 -0
  443. data/spec/integration/stringified_symbol_field_spec.rb +203 -0
  444. data/spec/lite_spec_helper.rb +18 -6
  445. data/spec/mongoid/association/accessors_spec.rb +284 -77
  446. data/spec/mongoid/association/auto_save_spec.rb +74 -33
  447. data/spec/mongoid/association/builders_spec.rb +3 -1
  448. data/spec/mongoid/association/constrainable_spec.rb +2 -0
  449. data/spec/mongoid/association/counter_cache_spec.rb +35 -33
  450. data/spec/mongoid/association/depending_spec.rb +431 -338
  451. data/spec/mongoid/association/eager_spec.rb +8 -5
  452. data/spec/mongoid/association/embedded/cyclic_spec.rb +4 -2
  453. data/spec/mongoid/association/embedded/dirty_spec.rb +4 -2
  454. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +4 -1
  455. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +56 -0
  456. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +84 -22
  457. data/spec/mongoid/association/embedded/embedded_in_spec.rb +3 -1
  458. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +2 -0
  459. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +114 -0
  460. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +687 -173
  461. data/spec/mongoid/association/embedded/embeds_many_models.rb +174 -1
  462. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +63 -0
  463. data/spec/mongoid/association/embedded/embeds_many_spec.rb +71 -1
  464. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +2 -0
  465. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +27 -0
  466. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +23 -21
  467. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +2 -0
  468. data/spec/mongoid/association/embedded/embeds_one_models.rb +22 -0
  469. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  470. data/spec/mongoid/association/embedded/embeds_one_spec.rb +31 -1
  471. data/spec/mongoid/association/macros_spec.rb +11 -9
  472. data/spec/mongoid/association/nested/many_spec.rb +2 -0
  473. data/spec/mongoid/association/nested/one_spec.rb +18 -12
  474. data/spec/mongoid/association/options_spec.rb +2 -0
  475. data/spec/mongoid/association/polymorphic_spec.rb +2 -0
  476. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +4 -1
  477. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +111 -16
  478. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +242 -12
  479. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +114 -58
  480. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  481. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +57 -0
  482. data/spec/mongoid/association/referenced/belongs_to_spec.rb +26 -3
  483. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +3 -1
  484. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +28 -1
  485. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +46 -2
  486. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +25 -5
  487. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +418 -361
  488. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +68 -2
  489. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +39 -0
  490. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +81 -4
  491. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +3 -1
  492. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +132 -0
  493. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +40 -9
  494. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +314 -133
  495. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +848 -451
  496. data/spec/mongoid/association/referenced/has_many_models.rb +61 -1
  497. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  498. data/spec/mongoid/association/referenced/has_many_spec.rb +48 -0
  499. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +2 -0
  500. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +55 -9
  501. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +34 -4
  502. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +135 -27
  503. data/spec/mongoid/association/referenced/has_one_models.rb +65 -0
  504. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  505. data/spec/mongoid/association/referenced/has_one_spec.rb +24 -1
  506. data/spec/mongoid/association/reflections_spec.rb +2 -0
  507. data/spec/mongoid/association/syncable_spec.rb +47 -31
  508. data/spec/mongoid/association_spec.rb +2 -0
  509. data/spec/mongoid/atomic/modifiers_spec.rb +49 -0
  510. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +2 -0
  511. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +2 -0
  512. data/spec/mongoid/atomic/paths/root_spec.rb +2 -0
  513. data/spec/mongoid/atomic/paths_spec.rb +66 -26
  514. data/spec/mongoid/atomic_spec.rb +53 -6
  515. data/spec/mongoid/attributes/dynamic_spec.rb +0 -1
  516. data/spec/mongoid/attributes/nested_spec.rb +149 -78
  517. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  518. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  519. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  520. data/spec/mongoid/attributes/projector_spec.rb +40 -0
  521. data/spec/mongoid/attributes/readonly_spec.rb +24 -22
  522. data/spec/mongoid/attributes_spec.rb +683 -65
  523. data/spec/mongoid/cacheable_spec.rb +6 -4
  524. data/spec/mongoid/changeable_spec.rb +185 -43
  525. data/spec/mongoid/clients/factory_spec.rb +128 -28
  526. data/spec/mongoid/clients/options_spec.rb +45 -26
  527. data/spec/mongoid/clients/sessions_spec.rb +25 -66
  528. data/spec/mongoid/clients/transactions_spec.rb +54 -29
  529. data/spec/mongoid/clients_spec.rb +65 -8
  530. data/spec/mongoid/composable_spec.rb +2 -0
  531. data/spec/mongoid/config/environment_spec.rb +126 -8
  532. data/spec/mongoid/config/options_spec.rb +22 -3
  533. data/spec/mongoid/config_spec.rb +377 -1
  534. data/spec/mongoid/contextual/aggregable/memory_spec.rb +433 -153
  535. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  536. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  537. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +122 -20
  538. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  539. data/spec/mongoid/contextual/atomic_spec.rb +205 -67
  540. data/spec/mongoid/contextual/geo_near_spec.rb +20 -18
  541. data/spec/mongoid/contextual/map_reduce_spec.rb +6 -18
  542. data/spec/mongoid/contextual/memory_spec.rb +1360 -91
  543. data/spec/mongoid/contextual/mongo_spec.rb +1871 -544
  544. data/spec/mongoid/contextual/none_spec.rb +39 -73
  545. data/spec/mongoid/copyable_spec.rb +657 -26
  546. data/spec/mongoid/copyable_spec_models.rb +30 -0
  547. data/spec/mongoid/criteria/findable_spec.rb +161 -228
  548. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  549. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  550. data/spec/mongoid/criteria/inspectable_spec.rb +2 -0
  551. data/spec/mongoid/criteria/marshalable_spec.rb +20 -1
  552. data/spec/mongoid/criteria/modifiable_spec.rb +43 -40
  553. data/spec/mongoid/criteria/options_spec.rb +2 -0
  554. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -1
  555. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  556. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +9 -19
  557. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +136 -26
  558. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +2 -0
  559. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -1
  560. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +13 -0
  561. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +46 -17
  562. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +2 -0
  563. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +2 -0
  564. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +2 -15
  565. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +2 -0
  566. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +2 -0
  567. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -8
  568. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +2 -0
  569. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +239 -178
  570. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +3 -1
  571. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +2 -0
  572. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +2 -0
  573. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +2 -59
  574. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +2 -59
  575. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +34 -16
  576. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +13 -0
  577. data/spec/mongoid/criteria/queryable/key_spec.rb +2 -0
  578. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +145 -12
  579. data/spec/mongoid/criteria/queryable/optional_spec.rb +18 -485
  580. data/spec/mongoid/criteria/queryable/options_spec.rb +2 -0
  581. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +2 -0
  582. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -1
  583. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1643 -286
  584. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  585. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1191 -2752
  586. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  587. data/spec/mongoid/criteria/queryable/selector_spec.rb +91 -4
  588. data/spec/mongoid/criteria/queryable/smash_spec.rb +2 -0
  589. data/spec/mongoid/criteria/queryable/storable_spec.rb +298 -0
  590. data/spec/mongoid/criteria/scopable_spec.rb +129 -0
  591. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  592. data/spec/mongoid/criteria_projection_spec.rb +409 -0
  593. data/spec/mongoid/criteria_spec.rb +1322 -1723
  594. data/spec/mongoid/document_fields_spec.rb +179 -5
  595. data/spec/mongoid/document_persistence_context_spec.rb +0 -1
  596. data/spec/mongoid/document_query_spec.rb +89 -0
  597. data/spec/mongoid/document_spec.rb +153 -87
  598. data/spec/mongoid/equality_spec.rb +144 -41
  599. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +5 -3
  600. data/spec/mongoid/errors/callback_spec.rb +2 -0
  601. data/spec/mongoid/errors/delete_restriction_spec.rb +4 -2
  602. data/spec/mongoid/errors/document_not_destroyed_spec.rb +2 -0
  603. data/spec/mongoid/errors/document_not_found_spec.rb +78 -0
  604. data/spec/mongoid/errors/invalid_collection_spec.rb +2 -0
  605. data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +7 -5
  606. data/spec/mongoid/errors/invalid_config_option_spec.rb +2 -0
  607. data/spec/mongoid/errors/invalid_field_option_spec.rb +2 -0
  608. data/spec/mongoid/errors/invalid_field_spec.rb +3 -1
  609. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  610. data/spec/mongoid/errors/invalid_find_spec.rb +2 -0
  611. data/spec/mongoid/errors/invalid_includes_spec.rb +2 -0
  612. data/spec/mongoid/errors/invalid_index_spec.rb +2 -0
  613. data/spec/mongoid/errors/invalid_options_spec.rb +4 -2
  614. data/spec/mongoid/errors/invalid_path_spec.rb +2 -0
  615. data/spec/mongoid/errors/invalid_relation_spec.rb +4 -2
  616. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -1
  617. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +2 -0
  618. data/spec/mongoid/errors/invalid_storage_options_spec.rb +2 -0
  619. data/spec/mongoid/errors/invalid_time_spec.rb +2 -0
  620. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -1
  621. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +2 -0
  622. data/spec/mongoid/errors/mixed_relations_spec.rb +2 -0
  623. data/spec/mongoid/errors/mongoid_error_spec.rb +24 -8
  624. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +5 -3
  625. data/spec/mongoid/errors/no_client_config_spec.rb +4 -2
  626. data/spec/mongoid/errors/no_client_database_spec.rb +5 -3
  627. data/spec/mongoid/errors/no_client_hosts_spec.rb +5 -3
  628. data/spec/mongoid/errors/no_clients_config_spec.rb +2 -0
  629. data/spec/mongoid/errors/no_environment_spec.rb +5 -3
  630. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +2 -0
  631. data/spec/mongoid/errors/no_metadata_spec.rb +4 -2
  632. data/spec/mongoid/errors/no_parent_spec.rb +3 -1
  633. data/spec/mongoid/errors/readonly_attribute_spec.rb +2 -0
  634. data/spec/mongoid/errors/readonly_document_spec.rb +2 -0
  635. data/spec/mongoid/errors/scope_overwrite_spec.rb +2 -0
  636. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -1
  637. data/spec/mongoid/errors/unknown_attribute_spec.rb +4 -2
  638. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -1
  639. data/spec/mongoid/errors/unsupported_javascript_spec.rb +2 -0
  640. data/spec/mongoid/errors/validations_spec.rb +2 -0
  641. data/spec/mongoid/extensions/array_spec.rb +41 -45
  642. data/spec/mongoid/extensions/big_decimal_spec.rb +714 -212
  643. data/spec/mongoid/extensions/binary_spec.rb +46 -9
  644. data/spec/mongoid/extensions/boolean_spec.rb +70 -82
  645. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +339 -0
  646. data/spec/mongoid/extensions/date_spec.rb +58 -140
  647. data/spec/mongoid/extensions/date_time_spec.rb +32 -69
  648. data/spec/mongoid/extensions/decimal128_spec.rb +2 -0
  649. data/spec/mongoid/extensions/false_class_spec.rb +3 -1
  650. data/spec/mongoid/extensions/float_spec.rb +66 -73
  651. data/spec/mongoid/extensions/hash_spec.rb +138 -3
  652. data/spec/mongoid/extensions/integer_spec.rb +61 -63
  653. data/spec/mongoid/extensions/module_spec.rb +2 -0
  654. data/spec/mongoid/extensions/nil_class_spec.rb +2 -0
  655. data/spec/mongoid/extensions/object_id_spec.rb +2 -0
  656. data/spec/mongoid/extensions/object_spec.rb +13 -24
  657. data/spec/mongoid/extensions/range_spec.rb +257 -54
  658. data/spec/mongoid/extensions/regexp_spec.rb +60 -33
  659. data/spec/mongoid/extensions/set_spec.rb +108 -0
  660. data/spec/mongoid/extensions/string_spec.rb +111 -50
  661. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  662. data/spec/mongoid/extensions/symbol_spec.rb +20 -25
  663. data/spec/mongoid/extensions/time_spec.rb +663 -66
  664. data/spec/mongoid/extensions/time_with_zone_spec.rb +50 -31
  665. data/spec/mongoid/extensions/true_class_spec.rb +3 -1
  666. data/spec/mongoid/extensions_spec.rb +16 -2
  667. data/spec/mongoid/factory_spec.rb +347 -27
  668. data/spec/mongoid/fields/foreign_key_spec.rb +2 -0
  669. data/spec/mongoid/fields/localized_spec.rb +43 -16
  670. data/spec/mongoid/fields/standard_spec.rb +2 -0
  671. data/spec/mongoid/fields_spec.rb +776 -80
  672. data/spec/mongoid/findable_spec.rb +133 -34
  673. data/spec/mongoid/indexable/specification_spec.rb +4 -2
  674. data/spec/mongoid/indexable_spec.rb +65 -18
  675. data/spec/mongoid/inspectable_spec.rb +39 -2
  676. data/spec/mongoid/interceptable_spec.rb +955 -103
  677. data/spec/mongoid/interceptable_spec_models.rb +307 -0
  678. data/spec/mongoid/loggable_spec.rb +2 -0
  679. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  680. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  681. data/spec/mongoid/matcher/extract_attribute_spec.rb +36 -0
  682. data/spec/mongoid/mongoizable_spec.rb +285 -0
  683. data/spec/mongoid/persistable/creatable_spec.rb +114 -29
  684. data/spec/mongoid/persistable/deletable_spec.rb +274 -12
  685. data/spec/mongoid/persistable/destroyable_spec.rb +202 -12
  686. data/spec/mongoid/persistable/incrementable_spec.rb +23 -7
  687. data/spec/mongoid/persistable/logical_spec.rb +19 -3
  688. data/spec/mongoid/persistable/poppable_spec.rb +19 -3
  689. data/spec/mongoid/persistable/pullable_spec.rb +36 -6
  690. data/spec/mongoid/persistable/pushable_spec.rb +36 -6
  691. data/spec/mongoid/persistable/renamable_spec.rb +18 -2
  692. data/spec/mongoid/persistable/savable_spec.rb +188 -25
  693. data/spec/mongoid/persistable/settable_spec.rb +24 -8
  694. data/spec/mongoid/persistable/unsettable_spec.rb +19 -3
  695. data/spec/mongoid/persistable/updatable_spec.rb +45 -23
  696. data/spec/mongoid/persistable/upsertable_spec.rb +18 -2
  697. data/spec/mongoid/persistable_spec.rb +85 -9
  698. data/spec/mongoid/persistence_context_spec.rb +52 -1
  699. data/spec/mongoid/positional_spec.rb +2 -0
  700. data/spec/mongoid/query_cache_middleware_spec.rb +50 -0
  701. data/spec/mongoid/query_cache_spec.rb +339 -87
  702. data/spec/mongoid/relations/proxy_spec.rb +8 -6
  703. data/spec/mongoid/reloadable_spec.rb +357 -22
  704. data/spec/mongoid/scopable_spec.rb +121 -37
  705. data/spec/mongoid/selectable_spec.rb +8 -6
  706. data/spec/mongoid/serializable_spec.rb +160 -29
  707. data/spec/mongoid/shardable_models.rb +75 -0
  708. data/spec/mongoid/shardable_spec.rb +239 -34
  709. data/spec/mongoid/stateful_spec.rb +31 -1
  710. data/spec/mongoid/tasks/database_rake_spec.rb +2 -0
  711. data/spec/mongoid/tasks/database_spec.rb +2 -0
  712. data/spec/mongoid/threaded_spec.rb +4 -2
  713. data/spec/mongoid/timestamps/created/short_spec.rb +3 -1
  714. data/spec/mongoid/timestamps/created_spec.rb +3 -1
  715. data/spec/mongoid/timestamps/timeless_spec.rb +4 -2
  716. data/spec/mongoid/timestamps/updated/short_spec.rb +5 -3
  717. data/spec/mongoid/timestamps/updated_spec.rb +5 -3
  718. data/spec/mongoid/timestamps_spec.rb +398 -6
  719. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  720. data/spec/mongoid/touchable_spec.rb +296 -33
  721. data/spec/mongoid/touchable_spec_models.rb +57 -0
  722. data/spec/mongoid/traversable_spec.rb +1160 -1
  723. data/spec/mongoid/validatable/associated_spec.rb +15 -30
  724. data/spec/mongoid/validatable/format_spec.rb +2 -0
  725. data/spec/mongoid/validatable/length_spec.rb +2 -0
  726. data/spec/mongoid/validatable/numericality_spec.rb +2 -0
  727. data/spec/mongoid/validatable/presence_spec.rb +28 -22
  728. data/spec/mongoid/validatable/uniqueness_spec.rb +128 -98
  729. data/spec/mongoid/validatable_spec.rb +5 -3
  730. data/spec/mongoid/warnings_spec.rb +35 -0
  731. data/spec/mongoid_spec.rb +3 -1
  732. data/spec/rails/controller_extension/controller_runtime_spec.rb +5 -3
  733. data/spec/rails/mongoid_spec.rb +8 -18
  734. data/spec/shared/bin/s3-copy +45 -0
  735. data/spec/shared/bin/s3-upload +69 -0
  736. data/spec/shared/lib/mrss/cluster_config.rb +14 -4
  737. data/spec/shared/lib/mrss/constraints.rb +51 -27
  738. data/spec/shared/lib/mrss/docker_runner.rb +37 -4
  739. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  740. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  741. data/spec/shared/lib/mrss/lite_constraints.rb +48 -1
  742. data/spec/shared/lib/mrss/server_version_registry.rb +16 -18
  743. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  744. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  745. data/spec/shared/lib/mrss/spec_organizer.rb +18 -1
  746. data/spec/shared/lib/mrss/utils.rb +28 -6
  747. data/spec/shared/share/Dockerfile.erb +156 -66
  748. data/spec/shared/share/haproxy-1.conf +16 -0
  749. data/spec/shared/share/haproxy-2.conf +17 -0
  750. data/spec/shared/shlib/config.sh +27 -0
  751. data/spec/shared/shlib/distro.sh +2 -1
  752. data/spec/shared/shlib/server.sh +171 -45
  753. data/spec/shared/shlib/set_env.sh +47 -6
  754. data/spec/spec_helper.rb +38 -36
  755. data/spec/support/authorization.rb +2 -0
  756. data/spec/support/client_registry.rb +9 -0
  757. data/spec/support/constraints.rb +39 -8
  758. data/spec/support/expectations.rb +5 -1
  759. data/spec/support/helpers.rb +11 -0
  760. data/spec/support/macros.rb +77 -0
  761. data/spec/{app → support}/models/account.rb +3 -1
  762. data/spec/{app → support}/models/acolyte.rb +2 -0
  763. data/spec/{app → support}/models/actor.rb +3 -1
  764. data/spec/support/models/actress.rb +4 -0
  765. data/spec/{app → support}/models/address.rb +6 -0
  766. data/spec/{app → support}/models/address_component.rb +2 -0
  767. data/spec/{app → support}/models/address_number.rb +2 -0
  768. data/spec/{app → support}/models/agency.rb +2 -0
  769. data/spec/{app → support}/models/agent.rb +2 -0
  770. data/spec/{app → support}/models/album.rb +2 -0
  771. data/spec/{app → support}/models/alert.rb +2 -0
  772. data/spec/{app → support}/models/animal.rb +2 -0
  773. data/spec/{app → support}/models/answer.rb +2 -0
  774. data/spec/{app → support}/models/appointment.rb +2 -0
  775. data/spec/support/models/armrest.rb +9 -0
  776. data/spec/{app → support}/models/article.rb +2 -0
  777. data/spec/{app → support}/models/artist.rb +4 -0
  778. data/spec/{app → support}/models/artwork.rb +2 -0
  779. data/spec/support/models/audible_sound.rb +3 -0
  780. data/spec/{app → support}/models/audio.rb +2 -0
  781. data/spec/support/models/augmentation.rb +25 -0
  782. data/spec/{app → support}/models/author.rb +2 -0
  783. data/spec/{app → support}/models/baby.rb +2 -0
  784. data/spec/{app → support}/models/band.rb +9 -0
  785. data/spec/{app → support}/models/bar.rb +2 -0
  786. data/spec/{app → support}/models/basic.rb +2 -0
  787. data/spec/support/models/bed.rb +3 -0
  788. data/spec/{app → support}/models/big_palette.rb +2 -0
  789. data/spec/{app → support}/models/birthday.rb +2 -0
  790. data/spec/support/models/bolt.rb +7 -0
  791. data/spec/{app → support}/models/bomb.rb +2 -0
  792. data/spec/{app → support}/models/book.rb +2 -0
  793. data/spec/{app → support}/models/breed.rb +2 -0
  794. data/spec/{app → support}/models/browser.rb +3 -1
  795. data/spec/{app → support}/models/building.rb +2 -0
  796. data/spec/{app → support}/models/building_address.rb +2 -0
  797. data/spec/{app → support}/models/bus.rb +2 -0
  798. data/spec/{app → support}/models/business.rb +2 -0
  799. data/spec/{app → support}/models/callback_test.rb +2 -0
  800. data/spec/{app → support}/models/canvas.rb +3 -1
  801. data/spec/support/models/car.rb +3 -0
  802. data/spec/{app → support}/models/cat.rb +2 -0
  803. data/spec/support/models/catalog.rb +24 -0
  804. data/spec/{app → support}/models/category.rb +2 -0
  805. data/spec/{app → support}/models/child.rb +2 -0
  806. data/spec/{app → support}/models/child_doc.rb +5 -3
  807. data/spec/{app → support}/models/church.rb +2 -0
  808. data/spec/{app → support}/models/circle.rb +2 -0
  809. data/spec/{app → support}/models/circuit.rb +2 -0
  810. data/spec/support/models/circus.rb +12 -0
  811. data/spec/{app → support}/models/code.rb +4 -0
  812. data/spec/support/models/coding/pull_request.rb +11 -0
  813. data/spec/support/models/coding.rb +3 -0
  814. data/spec/{app → support}/models/comment.rb +2 -0
  815. data/spec/{app → support}/models/company.rb +2 -0
  816. data/spec/{app → support}/models/consumption_period.rb +2 -0
  817. data/spec/{app → support}/models/contextable_item.rb +2 -0
  818. data/spec/{app → support}/models/contractor.rb +2 -0
  819. data/spec/{app → support}/models/cookie.rb +2 -0
  820. data/spec/{app → support}/models/country_code.rb +4 -0
  821. data/spec/{app → support}/models/courier_job.rb +2 -0
  822. data/spec/support/models/crate.rb +12 -0
  823. data/spec/{app → support}/models/customer.rb +0 -1
  824. data/spec/{app → support}/models/customer_address.rb +0 -1
  825. data/spec/support/models/deed.rb +7 -0
  826. data/spec/{app → support}/models/definition.rb +2 -0
  827. data/spec/{app → support}/models/delegating_patient.rb +0 -1
  828. data/spec/{app → support}/models/description.rb +2 -0
  829. data/spec/{app → support}/models/dictionary.rb +8 -0
  830. data/spec/{app → support}/models/division.rb +2 -0
  831. data/spec/{app → support}/models/doctor.rb +2 -0
  832. data/spec/{app → support}/models/dog.rb +2 -0
  833. data/spec/{app → support}/models/dokument.rb +2 -0
  834. data/spec/{app → support}/models/draft.rb +2 -0
  835. data/spec/{app → support}/models/dragon.rb +2 -0
  836. data/spec/{app → support}/models/driver.rb +3 -1
  837. data/spec/{app → support}/models/drug.rb +2 -0
  838. data/spec/{app → support}/models/dungeon.rb +2 -0
  839. data/spec/{app → support}/models/edit.rb +2 -0
  840. data/spec/{app → support}/models/email.rb +2 -0
  841. data/spec/{app → support}/models/employer.rb +2 -0
  842. data/spec/{app → support}/models/entry.rb +2 -0
  843. data/spec/support/models/eraser.rb +3 -0
  844. data/spec/{app → support}/models/even.rb +2 -0
  845. data/spec/{app → support}/models/event.rb +2 -0
  846. data/spec/{app → support}/models/exhibition.rb +2 -0
  847. data/spec/{app → support}/models/exhibitor.rb +2 -0
  848. data/spec/{app → support}/models/explosion.rb +2 -0
  849. data/spec/{app → support}/models/eye.rb +2 -0
  850. data/spec/{app → support}/models/eye_bowl.rb +2 -0
  851. data/spec/{app → support}/models/face.rb +2 -0
  852. data/spec/support/models/fanatic.rb +8 -0
  853. data/spec/{app → support}/models/favorite.rb +2 -0
  854. data/spec/{app → support}/models/filesystem.rb +2 -0
  855. data/spec/{app → support}/models/fire_hydrant.rb +2 -0
  856. data/spec/{app → support}/models/firefox.rb +2 -0
  857. data/spec/{app → support}/models/fish.rb +2 -0
  858. data/spec/{app → support}/models/folder.rb +2 -0
  859. data/spec/{app → support}/models/folder_item.rb +2 -0
  860. data/spec/{app → support}/models/fruits.rb +2 -0
  861. data/spec/{app → support}/models/game.rb +2 -0
  862. data/spec/{app → support}/models/ghost.rb +2 -0
  863. data/spec/support/models/guitar.rb +4 -0
  864. data/spec/support/models/hole.rb +12 -0
  865. data/spec/{app → support}/models/home.rb +2 -0
  866. data/spec/{app → support}/models/house.rb +2 -0
  867. data/spec/{app → support}/models/html_writer.rb +2 -0
  868. data/spec/{app → support}/models/id_key.rb +2 -0
  869. data/spec/support/models/idnodef.rb +7 -0
  870. data/spec/{app → support}/models/image.rb +2 -0
  871. data/spec/{app → support}/models/implant.rb +11 -0
  872. data/spec/support/models/instrument.rb +8 -0
  873. data/spec/{app → support}/models/item.rb +3 -1
  874. data/spec/{app → support}/models/jar.rb +2 -0
  875. data/spec/{app → support}/models/kaleidoscope.rb +2 -0
  876. data/spec/{app → support}/models/kangaroo.rb +3 -1
  877. data/spec/{app → support}/models/label.rb +6 -1
  878. data/spec/{app → support}/models/language.rb +2 -0
  879. data/spec/{app → support}/models/lat_lng.rb +2 -0
  880. data/spec/{app → support}/models/league.rb +2 -0
  881. data/spec/support/models/learner.rb +4 -0
  882. data/spec/{app → support}/models/line_item.rb +2 -0
  883. data/spec/{app → support}/models/location.rb +2 -0
  884. data/spec/{app → support}/models/login.rb +2 -0
  885. data/spec/{app → support}/models/manufacturer.rb +2 -0
  886. data/spec/{app → support}/models/meat.rb +2 -0
  887. data/spec/{app → support}/models/membership.rb +3 -0
  888. data/spec/{app → support}/models/message.rb +2 -0
  889. data/spec/{app → support}/models/minim.rb +0 -1
  890. data/spec/{app → support}/models/mixed_drink.rb +2 -0
  891. data/spec/support/models/mop.rb +24 -0
  892. data/spec/{app → support}/models/movie.rb +2 -0
  893. data/spec/support/models/my_hash.rb +4 -0
  894. data/spec/{app → support}/models/name.rb +12 -0
  895. data/spec/support/models/name_only.rb +8 -0
  896. data/spec/{app → support}/models/node.rb +2 -0
  897. data/spec/{app → support}/models/note.rb +2 -0
  898. data/spec/support/models/nut.rb +7 -0
  899. data/spec/{app → support}/models/odd.rb +2 -0
  900. data/spec/support/models/order.rb +12 -0
  901. data/spec/{app → support}/models/ordered_post.rb +3 -1
  902. data/spec/{app → support}/models/ordered_preference.rb +2 -0
  903. data/spec/{app → support}/models/oscar.rb +2 -0
  904. data/spec/support/models/other_owner_object.rb +4 -0
  905. data/spec/{app → support}/models/override.rb +2 -0
  906. data/spec/{app → support}/models/ownable.rb +2 -0
  907. data/spec/{app → support}/models/owner.rb +4 -0
  908. data/spec/{app → support}/models/pack.rb +2 -0
  909. data/spec/{app → support}/models/page.rb +2 -0
  910. data/spec/{app → support}/models/page_question.rb +2 -0
  911. data/spec/{app → support}/models/palette.rb +3 -1
  912. data/spec/{app → support}/models/parent.rb +2 -0
  913. data/spec/{app → support}/models/parent_doc.rb +2 -0
  914. data/spec/support/models/passport.rb +22 -0
  915. data/spec/{app → support}/models/patient.rb +2 -0
  916. data/spec/{app → support}/models/pdf_writer.rb +2 -0
  917. data/spec/support/models/pencil.rb +3 -0
  918. data/spec/{app → support}/models/person.rb +23 -1
  919. data/spec/{app → support}/models/pet.rb +2 -0
  920. data/spec/{app → support}/models/pet_owner.rb +2 -0
  921. data/spec/{app → support}/models/phone.rb +5 -1
  922. data/spec/support/models/piano.rb +4 -0
  923. data/spec/{app → support}/models/pizza.rb +2 -0
  924. data/spec/{app → support}/models/player.rb +4 -0
  925. data/spec/{app → support}/models/post.rb +2 -0
  926. data/spec/{app → support}/models/post_genre.rb +2 -0
  927. data/spec/support/models/powerup.rb +25 -0
  928. data/spec/{app → support}/models/preference.rb +2 -0
  929. data/spec/{app → support}/models/princess.rb +2 -0
  930. data/spec/{app → support}/models/product.rb +2 -0
  931. data/spec/support/models/profile.rb +17 -0
  932. data/spec/{app → support}/models/pronunciation.rb +2 -0
  933. data/spec/{app → support}/models/pub.rb +2 -0
  934. data/spec/support/models/publication/encyclopedia.rb +11 -0
  935. data/spec/support/models/publication/review.rb +13 -0
  936. data/spec/support/models/publication.rb +4 -0
  937. data/spec/{app → support}/models/purchase.rb +2 -0
  938. data/spec/support/models/purchased_item.rb +10 -0
  939. data/spec/support/models/purse.rb +9 -0
  940. data/spec/{app → support}/models/question.rb +2 -0
  941. data/spec/{app → support}/models/quiz.rb +2 -0
  942. data/spec/{app → support}/models/rating.rb +2 -0
  943. data/spec/{app → support}/models/record.rb +2 -0
  944. data/spec/{app → support}/models/registry.rb +3 -0
  945. data/spec/{app → support}/models/role.rb +2 -0
  946. data/spec/{app → support}/models/root_category.rb +2 -0
  947. data/spec/{app → support}/models/sandwich.rb +2 -0
  948. data/spec/{app → support}/models/scheduler.rb +2 -0
  949. data/spec/support/models/school.rb +14 -0
  950. data/spec/support/models/scribe.rb +7 -0
  951. data/spec/support/models/sealer.rb +7 -0
  952. data/spec/support/models/seat.rb +24 -0
  953. data/spec/{app → support}/models/seo.rb +2 -0
  954. data/spec/support/models/series.rb +7 -0
  955. data/spec/{app → support}/models/server.rb +2 -0
  956. data/spec/{app → support}/models/service.rb +2 -0
  957. data/spec/{app → support}/models/shape.rb +4 -2
  958. data/spec/{app → support}/models/shelf.rb +2 -0
  959. data/spec/support/models/shield.rb +18 -0
  960. data/spec/{app → support}/models/shipment_address.rb +2 -0
  961. data/spec/{app → support}/models/shipping_container.rb +2 -0
  962. data/spec/{app → support}/models/shipping_pack.rb +2 -0
  963. data/spec/support/models/shirt.rb +11 -0
  964. data/spec/{app → support}/models/shop.rb +2 -0
  965. data/spec/{app → support}/models/short_agent.rb +2 -0
  966. data/spec/{app → support}/models/short_quiz.rb +2 -0
  967. data/spec/{app → support}/models/simple.rb +2 -0
  968. data/spec/{app → support}/models/slave.rb +2 -0
  969. data/spec/{app → support}/models/song.rb +2 -0
  970. data/spec/{app → support}/models/sound.rb +2 -0
  971. data/spec/support/models/spacer.rb +7 -0
  972. data/spec/{app → support}/models/square.rb +2 -0
  973. data/spec/{app → support}/models/staff.rb +2 -0
  974. data/spec/{app → support}/models/store_as_dup_test1.rb +2 -0
  975. data/spec/{app → support}/models/store_as_dup_test2.rb +2 -0
  976. data/spec/{app → support}/models/strategy.rb +2 -0
  977. data/spec/support/models/student.rb +14 -0
  978. data/spec/{app → support}/models/sub_item.rb +2 -0
  979. data/spec/{app → support}/models/subscription.rb +2 -0
  980. data/spec/{app → support}/models/survey.rb +2 -0
  981. data/spec/{app → support}/models/symptom.rb +2 -0
  982. data/spec/support/models/system_role.rb +7 -0
  983. data/spec/{app → support}/models/tag.rb +2 -0
  984. data/spec/{app → support}/models/target.rb +2 -0
  985. data/spec/{app → support}/models/template.rb +2 -0
  986. data/spec/{app → support}/models/thing.rb +2 -0
  987. data/spec/support/models/threadlocker.rb +7 -0
  988. data/spec/{app → support}/models/title.rb +2 -0
  989. data/spec/{app → support}/models/tool.rb +4 -2
  990. data/spec/{app → support}/models/topping.rb +2 -0
  991. data/spec/support/models/toy.rb +9 -0
  992. data/spec/{app → support}/models/track.rb +2 -0
  993. data/spec/{app → support}/models/translation.rb +2 -0
  994. data/spec/{app → support}/models/tree.rb +2 -0
  995. data/spec/support/models/truck.rb +7 -0
  996. data/spec/{app → support}/models/user.rb +2 -0
  997. data/spec/{app → support}/models/user_account.rb +2 -0
  998. data/spec/{app → support}/models/validation_callback.rb +2 -0
  999. data/spec/support/models/vehicle.rb +18 -0
  1000. data/spec/{app → support}/models/version.rb +2 -0
  1001. data/spec/{app → support}/models/vertex.rb +3 -1
  1002. data/spec/{app → support}/models/vet_visit.rb +2 -0
  1003. data/spec/{app → support}/models/video.rb +2 -0
  1004. data/spec/support/models/video_game.rb +3 -0
  1005. data/spec/support/models/washer.rb +7 -0
  1006. data/spec/support/models/weapon.rb +25 -0
  1007. data/spec/{app → support}/models/wiki_page.rb +3 -0
  1008. data/spec/{app → support}/models/word.rb +2 -0
  1009. data/spec/{app → support}/models/word_origin.rb +2 -0
  1010. data/spec/{app → support}/models/writer.rb +4 -2
  1011. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1012. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1013. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1014. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1015. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1016. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1017. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1018. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1019. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1020. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1021. data/spec/support/shared/time.rb +53 -0
  1022. data/spec/support/spec_config.rb +12 -3
  1023. data.tar.gz.sig +0 -0
  1024. metadata +1162 -764
  1025. metadata.gz.sig +0 -0
  1026. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  1027. data/lib/mongoid/errors/eager_load.rb +0 -22
  1028. data/lib/mongoid/errors/invalid_value.rb +0 -16
  1029. data/lib/mongoid/matchable/all.rb +0 -28
  1030. data/lib/mongoid/matchable/and.rb +0 -30
  1031. data/lib/mongoid/matchable/default.rb +0 -119
  1032. data/lib/mongoid/matchable/elem_match.rb +0 -34
  1033. data/lib/mongoid/matchable/eq.rb +0 -22
  1034. data/lib/mongoid/matchable/exists.rb +0 -23
  1035. data/lib/mongoid/matchable/gt.rb +0 -23
  1036. data/lib/mongoid/matchable/gte.rb +0 -23
  1037. data/lib/mongoid/matchable/in.rb +0 -24
  1038. data/lib/mongoid/matchable/lt.rb +0 -23
  1039. data/lib/mongoid/matchable/lte.rb +0 -23
  1040. data/lib/mongoid/matchable/ne.rb +0 -21
  1041. data/lib/mongoid/matchable/nin.rb +0 -22
  1042. data/lib/mongoid/matchable/nor.rb +0 -37
  1043. data/lib/mongoid/matchable/or.rb +0 -33
  1044. data/lib/mongoid/matchable/regexp.rb +0 -27
  1045. data/lib/mongoid/matchable/size.rb +0 -21
  1046. data/lib/support/ruby_version.rb +0 -26
  1047. data/spec/app/models/actress.rb +0 -2
  1048. data/spec/app/models/augmentation.rb +0 -11
  1049. data/spec/app/models/bed.rb +0 -1
  1050. data/spec/app/models/car.rb +0 -1
  1051. data/spec/app/models/circus.rb +0 -7
  1052. data/spec/app/models/eraser.rb +0 -1
  1053. data/spec/app/models/learner.rb +0 -2
  1054. data/spec/app/models/my_hash.rb +0 -2
  1055. data/spec/app/models/other_owner_object.rb +0 -2
  1056. data/spec/app/models/passport.rb +0 -5
  1057. data/spec/app/models/pencil.rb +0 -1
  1058. data/spec/app/models/powerup.rb +0 -11
  1059. data/spec/app/models/profile.rb +0 -5
  1060. data/spec/app/models/series.rb +0 -4
  1061. data/spec/app/models/truck.rb +0 -3
  1062. data/spec/app/models/vehicle.rb +0 -11
  1063. data/spec/app/models/video_game.rb +0 -1
  1064. data/spec/app/models/weapon.rb +0 -11
  1065. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1066. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1067. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1068. data/spec/mongoid/matchable/default_spec.rb +0 -137
  1069. data/spec/mongoid/matchable/elem_match_spec.rb +0 -106
  1070. data/spec/mongoid/matchable/eq_spec.rb +0 -48
  1071. data/spec/mongoid/matchable/exists_spec.rb +0 -57
  1072. data/spec/mongoid/matchable/gt_spec.rb +0 -86
  1073. data/spec/mongoid/matchable/gte_spec.rb +0 -84
  1074. data/spec/mongoid/matchable/in_spec.rb +0 -49
  1075. data/spec/mongoid/matchable/lt_spec.rb +0 -85
  1076. data/spec/mongoid/matchable/lte_spec.rb +0 -85
  1077. data/spec/mongoid/matchable/ne_spec.rb +0 -46
  1078. data/spec/mongoid/matchable/nin_spec.rb +0 -48
  1079. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  1080. data/spec/mongoid/matchable/or_spec.rb +0 -131
  1081. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
  1082. data/spec/mongoid/matchable/size_spec.rb +0 -25
  1083. data/spec/mongoid/matchable_spec.rb +0 -853
  1084. data/spec/support/cluster_config.rb +0 -158
  1085. data/spec/support/session_registry.rb +0 -50
  1086. /data/spec/{app → support}/models/array_field.rb +0 -0
  1087. /data/spec/{app → support}/models/store_as_dup_test3.rb +0 -0
  1088. /data/spec/{app → support}/models/store_as_dup_test4.rb +0 -0
  1089. /data/spec/{app → support}/models/updatable.rb +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  describe Mongoid::Contextual::Memory do
@@ -165,19 +167,19 @@ describe Mongoid::Contextual::Memory do
165
167
  [ :delete, :delete_all ].each do |method|
166
168
 
167
169
  let(:person) do
168
- Person.create
170
+ Person.create!
169
171
  end
170
172
 
171
173
  let(:hobrecht) do
172
- person.addresses.create(street: "hobrecht")
174
+ person.addresses.create!(street: "hobrecht")
173
175
  end
174
176
 
175
177
  let(:friedel) do
176
- person.addresses.create(street: "friedel")
178
+ person.addresses.create!(street: "friedel")
177
179
  end
178
180
 
179
181
  let(:pfluger) do
180
- person.addresses.create(street: "pfluger")
182
+ person.addresses.create!(street: "pfluger")
181
183
  end
182
184
 
183
185
  describe "##{method}" do
@@ -230,11 +232,11 @@ describe Mongoid::Contextual::Memory do
230
232
  context "when embedded multiple levels" do
231
233
 
232
234
  let!(:home) do
233
- hobrecht.locations.create(name: "home")
235
+ hobrecht.locations.create!(name: "home")
234
236
  end
235
237
 
236
238
  let!(:work) do
237
- hobrecht.locations.create(name: "work")
239
+ hobrecht.locations.create!(name: "work")
238
240
  end
239
241
 
240
242
  let(:criteria) do
@@ -296,19 +298,19 @@ describe Mongoid::Contextual::Memory do
296
298
  [ :destroy, :destroy_all ].each do |method|
297
299
 
298
300
  let(:person) do
299
- Person.create
301
+ Person.create!
300
302
  end
301
303
 
302
304
  let(:hobrecht) do
303
- person.addresses.create(street: "hobrecht")
305
+ person.addresses.create!(street: "hobrecht")
304
306
  end
305
307
 
306
308
  let(:friedel) do
307
- person.addresses.create(street: "friedel")
309
+ person.addresses.create!(street: "friedel")
308
310
  end
309
311
 
310
312
  let(:pfluger) do
311
- person.addresses.create(street: "pfluger")
313
+ person.addresses.create!(street: "pfluger")
312
314
  end
313
315
 
314
316
  let(:criteria) do
@@ -377,36 +379,77 @@ describe Mongoid::Contextual::Memory do
377
379
 
378
380
  describe "#distinct" do
379
381
 
380
- let(:hobrecht) do
381
- Address.new(street: "hobrecht")
382
- end
382
+ context "when legacy_pluck_distinct is true" do
383
+ config_override :legacy_pluck_distinct, true
383
384
 
384
- let(:friedel) do
385
- Address.new(street: "friedel")
386
- end
385
+ let(:hobrecht) do
386
+ Address.new(street: "hobrecht")
387
+ end
388
+
389
+ let(:friedel) do
390
+ Address.new(street: "friedel")
391
+ end
387
392
 
388
- context "when limiting the result set" do
393
+ context "when limiting the result set" do
389
394
 
390
- let(:criteria) do
391
- Address.where(street: "hobrecht").tap do |crit|
392
- crit.documents = [ hobrecht, hobrecht, friedel ]
395
+ let(:criteria) do
396
+ Address.where(street: "hobrecht").tap do |crit|
397
+ crit.documents = [ hobrecht, hobrecht, friedel ]
398
+ end
399
+ end
400
+
401
+ let(:context) do
402
+ described_class.new(criteria)
403
+ end
404
+
405
+ it "returns the distinct field values" do
406
+ expect(context.distinct(:street)).to eq([ "hobrecht" ])
393
407
  end
394
408
  end
395
409
 
396
- let(:context) do
397
- described_class.new(criteria)
410
+ context "when not limiting the result set" do
411
+
412
+ let(:criteria) do
413
+ Address.all.tap do |crit|
414
+ crit.documents = [ hobrecht, friedel, friedel ]
415
+ end
416
+ end
417
+
418
+ let(:context) do
419
+ described_class.new(criteria)
420
+ end
421
+
422
+ it "returns the distinct field values" do
423
+ expect(context.distinct(:street)).to eq([ "hobrecht", "friedel" ])
424
+ end
398
425
  end
399
426
 
400
- it "returns the distinct field values" do
401
- expect(context.distinct(:street)).to eq([ "hobrecht" ])
427
+ context 'when there is a collation on the criteria' do
428
+
429
+ let(:criteria) do
430
+ Address.where(street: "hobrecht").tap do |crit|
431
+ crit.documents = [ hobrecht, hobrecht, friedel ]
432
+ end.collation(locale: 'en_US', strength: 2)
433
+ end
434
+
435
+ it "raises an exception" do
436
+ expect {
437
+ context.distinct(:street)
438
+ }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
439
+ end
402
440
  end
403
441
  end
404
442
 
405
- context "when not limiting the result set" do
443
+ context "when legacy_pluck_distinct is false" do
444
+ config_override :legacy_pluck_distinct, false
445
+
446
+ let(:depeche) { Band.create!(name: "Depeche Mode", years: 30, sales: "1E2") }
447
+ let(:new_order) { Band.create!(name: "New Order", years: 25, sales: "2E3") }
448
+ let(:maniacs) { Band.create!(name: "10,000 Maniacs", years: 20, sales: "1E2") }
406
449
 
407
450
  let(:criteria) do
408
- Address.all.tap do |crit|
409
- crit.documents = [ hobrecht, friedel, friedel ]
451
+ Band.all.tap do |crit|
452
+ crit.documents = [ depeche, new_order, maniacs ]
410
453
  end
411
454
  end
412
455
 
@@ -414,23 +457,180 @@ describe Mongoid::Contextual::Memory do
414
457
  described_class.new(criteria)
415
458
  end
416
459
 
417
- it "returns the distinct field values" do
418
- expect(context.distinct(:street)).to eq([ "hobrecht", "friedel" ])
460
+ context "when limiting the result set" do
461
+
462
+ let(:criteria) do
463
+ Band.where(name: "Depeche Mode").tap do |crit|
464
+ crit.documents = [ depeche ]
465
+ end
466
+ end
467
+
468
+ it "returns the distinct matching fields" do
469
+ expect(context.distinct(:name)).to eq([ "Depeche Mode" ])
470
+ end
419
471
  end
420
- end
421
472
 
422
- context 'when there is a collation on the criteria' do
473
+ context "when not limiting the result set" do
423
474
 
424
- let(:criteria) do
425
- Address.where(street: "hobrecht").tap do |crit|
426
- crit.documents = [ hobrecht, hobrecht, friedel ]
427
- end.collation(locale: 'en_US', strength: 2)
475
+ it "returns the distinct field values" do
476
+ expect(context.distinct(:name).sort).to eq([ "10,000 Maniacs", "Depeche Mode", "New Order" ].sort)
477
+ end
428
478
  end
429
479
 
430
- it "raises an exception" do
431
- expect {
432
- context.distinct(:street)
433
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
480
+ context "when providing an aliased field" do
481
+
482
+ it "returns the distinct field values" do
483
+ expect(context.distinct(:years).sort).to eq([ 20, 25, 30 ])
484
+ end
485
+ end
486
+
487
+ context "when providing a demongoizable field" do
488
+
489
+ it "returns the non-demongoized distinct field values" do
490
+ expect(context.distinct(:sales).sort).to eq([ BigDecimal("1E2"), BigDecimal("2E3") ])
491
+ end
492
+ end
493
+
494
+ context "when getting a localized field" do
495
+ before do
496
+ I18n.locale = :en
497
+ d = Dictionary.create!(description: 'english-text')
498
+ I18n.locale = :de
499
+ d.description = 'deutsch-text'
500
+ d.save!
501
+ end
502
+
503
+ after do
504
+ I18n.locale = :en
505
+ end
506
+
507
+ let(:criteria) do
508
+ Dictionary.all.tap do |crit|
509
+ crit.documents = [ Dictionary.first ]
510
+ end
511
+ end
512
+
513
+ context "when getting the field without _translations" do
514
+ it "gets the demongoized localized field" do
515
+ expect(context.distinct(:description)).to eq([ 'deutsch-text' ])
516
+ end
517
+ end
518
+
519
+ context "when getting the field with _translations" do
520
+
521
+ it "gets the full hash" do
522
+ expect(context.distinct(:description_translations)).to eq([ { "de" => "deutsch-text", "en" => "english-text" } ])
523
+ end
524
+ end
525
+
526
+ context 'when plucking a specific locale' do
527
+
528
+ let(:distinct) do
529
+ context.distinct(:'description.de')
530
+ end
531
+
532
+ it 'returns the specific translation' do
533
+ expect(distinct).to eq([ "deutsch-text" ])
534
+ end
535
+ end
536
+
537
+ context 'when plucking a specific locale from _translations field' do
538
+
539
+ let(:distinct) do
540
+ context.distinct(:'description_translations.de')
541
+ end
542
+
543
+ it 'returns the specific translations' do
544
+ expect(distinct).to eq(['deutsch-text'])
545
+ end
546
+ end
547
+
548
+ context 'when fallbacks are enabled with a locale list' do
549
+ with_i18n_fallbacks
550
+
551
+ around(:all) do |example|
552
+ prev_fallbacks = I18n.fallbacks.dup
553
+ I18n.fallbacks[:he] = [ :en ]
554
+ example.run
555
+ I18n.fallbacks = prev_fallbacks
556
+ end
557
+
558
+ after do
559
+ I18n.locale = :en
560
+ end
561
+
562
+ let(:distinct) do
563
+ context.distinct(:description).first
564
+ end
565
+
566
+ it "correctly uses the fallback" do
567
+ I18n.locale = :en
568
+ Dictionary.create!(description: 'english-text')
569
+ I18n.locale = :he
570
+ distinct.should == "english-text"
571
+ end
572
+ end
573
+
574
+ context "when the localized field is embedded" do
575
+ let(:person) do
576
+ p = Passport.new
577
+ I18n.locale = :en
578
+ p.name = "Neil"
579
+ I18n.locale = :he
580
+ p.name = "Nissim"
581
+
582
+ Person.create!(passport: p, employer_id: 12345)
583
+ end
584
+
585
+ after do
586
+ I18n.locale = :en
587
+ end
588
+
589
+ let(:criteria) do
590
+ Person.where(employer_id: 12345).tap do |crit|
591
+ crit.documents = [ person ]
592
+ end
593
+ end
594
+
595
+ let(:distinct) do
596
+ context.distinct("pass.name").first
597
+ end
598
+
599
+ let(:distinct_translations) do
600
+ context.distinct("pass.name_translations").first
601
+ end
602
+
603
+ let(:distinct_translations_field) do
604
+ context.distinct("pass.name_translations.en").first
605
+ end
606
+
607
+ it "returns the translation for the current locale" do
608
+ expect(distinct).to eq("Nissim")
609
+ end
610
+
611
+ it "returns the full _translation hash" do
612
+ expect(distinct_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
613
+ end
614
+
615
+ it "returns the translation for the requested locale" do
616
+ expect(distinct_translations_field).to eq("Neil")
617
+ end
618
+ end
619
+ end
620
+
621
+ context "when getting an embedded field" do
622
+
623
+ let(:label) { Label.new(sales: "1E2") }
624
+ let!(:band) { Band.create!(label: label) }
625
+ let(:criteria) do
626
+ Band.where(_id: band.id).tap do |crit|
627
+ crit.documents = [ band ]
628
+ end
629
+ end
630
+
631
+ it "returns the distinct matching fields" do
632
+ expect(context.distinct("label.sales")).to eq([ BigDecimal("1E2") ])
633
+ end
434
634
  end
435
635
  end
436
636
  end
@@ -622,6 +822,14 @@ describe Mongoid::Contextual::Memory do
622
822
  expect(context.send(method)).to eq(hobrecht)
623
823
  end
624
824
 
825
+ it "returns a list when passing a limit" do
826
+ expect(context.send(method, 2)).to eq([ hobrecht, friedel ])
827
+ end
828
+
829
+ it "returns a list when passing 1" do
830
+ expect(context.send(method, 1)).to eq([ hobrecht ])
831
+ end
832
+
625
833
  context 'when there is a collation on the criteria' do
626
834
 
627
835
  let(:criteria) do
@@ -639,6 +847,108 @@ describe Mongoid::Contextual::Memory do
639
847
  end
640
848
  end
641
849
 
850
+ describe "#take" do
851
+
852
+ let(:hobrecht) do
853
+ Address.new(street: "hobrecht")
854
+ end
855
+
856
+ let(:friedel) do
857
+ Address.new(street: "friedel")
858
+ end
859
+
860
+ let(:criteria) do
861
+ Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
862
+ crit.documents = [ hobrecht, friedel ]
863
+ end
864
+ end
865
+
866
+ let(:context) do
867
+ described_class.new(criteria)
868
+ end
869
+
870
+ it "returns the first matching document" do
871
+ expect(context.take).to eq(hobrecht)
872
+ end
873
+
874
+ it "returns an array when passing a limit" do
875
+ expect(context.take(2)).to eq([ hobrecht, friedel ])
876
+ end
877
+
878
+ it "returns an array when passing a limit as 1" do
879
+ expect(context.take(1)).to eq([ hobrecht ])
880
+ end
881
+
882
+ context 'when there is a collation on the criteria' do
883
+
884
+ let(:criteria) do
885
+ Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
886
+ crit.documents = [ hobrecht, friedel ]
887
+ end.collation(locale: 'en_US', strength: 2)
888
+ end
889
+
890
+ it "raises an exception" do
891
+ expect {
892
+ context.take
893
+ }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
894
+ end
895
+ end
896
+ end
897
+
898
+ describe "#take!" do
899
+
900
+ let(:hobrecht) do
901
+ Address.new(street: "hobrecht")
902
+ end
903
+
904
+ let(:friedel) do
905
+ Address.new(street: "friedel")
906
+ end
907
+
908
+ let(:criteria) do
909
+ Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
910
+ crit.documents = [ hobrecht, friedel ]
911
+ end
912
+ end
913
+
914
+ let(:context) do
915
+ described_class.new(criteria)
916
+ end
917
+
918
+ it "returns the first matching document" do
919
+ expect(context.take!).to eq(hobrecht)
920
+ end
921
+
922
+ context "when the criteria is empty" do
923
+ let(:criteria) do
924
+ Address.where(street: "bogus").tap do |crit|
925
+ crit.documents = []
926
+ end
927
+ end
928
+
929
+ it "raise an error" do
930
+ expect do
931
+ context.take!
932
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Address./)
933
+ end
934
+ end
935
+
936
+ context 'when there is a collation on the criteria' do
937
+
938
+ let(:criteria) do
939
+ Address.where(:street.in => [ "hobrecht", "friedel" ]).tap do |crit|
940
+ crit.documents = [ hobrecht, friedel ]
941
+ end.collation(locale: 'en_US', strength: 2)
942
+ end
943
+
944
+ it "raises an exception" do
945
+ expect {
946
+ context.take
947
+ }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
948
+ end
949
+ end
950
+ end
951
+
642
952
  describe "#initialize" do
643
953
 
644
954
  context "when the criteria has no options" do
@@ -764,6 +1074,14 @@ describe Mongoid::Contextual::Memory do
764
1074
  expect(context.last).to eq(friedel)
765
1075
  end
766
1076
 
1077
+ it "returns a list when a limit is passed" do
1078
+ expect(context.last(2)).to eq([ hobrecht, friedel ])
1079
+ end
1080
+
1081
+ it "returns a list when the limit is 1" do
1082
+ expect(context.last(1)).to eq([ friedel ])
1083
+ end
1084
+
767
1085
  context 'when there is a collation on the criteria' do
768
1086
 
769
1087
  let(:criteria) do
@@ -917,72 +1235,1023 @@ describe Mongoid::Contextual::Memory do
917
1235
 
918
1236
  describe "#pluck" do
919
1237
 
920
- let(:hobrecht) do
921
- Address.new(street: "hobrecht")
922
- end
923
-
924
- let(:friedel) do
925
- Address.new(street: "friedel")
926
- end
927
-
928
- let(:criteria) do
929
- Address.all.tap do |crit|
930
- crit.documents = [ hobrecht, friedel ]
931
- end
932
- end
933
-
934
1238
  let(:context) do
935
1239
  described_class.new(criteria)
936
1240
  end
937
1241
 
938
- context "when plucking" do
1242
+ context "when legacy_pluck_distinct is true" do
1243
+ config_override :legacy_pluck_distinct, true
939
1244
 
940
- let!(:plucked) do
941
- context.pluck(:street)
1245
+ let(:hobrecht) do
1246
+ Address.new(street: "hobrecht")
942
1247
  end
943
1248
 
944
- it "returns the values" do
945
- expect(plucked).to eq([ "hobrecht", "friedel" ])
1249
+ let(:friedel) do
1250
+ Address.new(street: "friedel")
946
1251
  end
947
- end
948
1252
 
949
- context "when plucking a field that doesnt exist" do
1253
+ let(:criteria) do
1254
+ Address.all.tap do |crit|
1255
+ crit.documents = [ hobrecht, friedel ]
1256
+ end
1257
+ end
950
1258
 
951
- context "when pluck one field" do
1259
+ context "when plucking" do
952
1260
 
953
- let(:plucked) do
954
- context.pluck(:foo)
1261
+ let!(:plucked) do
1262
+ context.pluck(:street)
955
1263
  end
956
1264
 
957
- it "returns a empty array" do
958
- expect(plucked).to eq([])
1265
+ it "returns the values" do
1266
+ expect(plucked).to eq([ "hobrecht", "friedel" ])
959
1267
  end
960
1268
  end
961
1269
 
962
- context "when pluck multiple fields" do
1270
+ context "when plucking a mix of empty and non-empty values" do
963
1271
 
964
- let(:plucked) do
965
- context.pluck(:foo, :bar)
1272
+ let(:empty_doc) do
1273
+ Address.new(street: nil)
966
1274
  end
967
1275
 
968
- it "returns a empty array" do
969
- expect(plucked).to eq([[], []])
1276
+ let(:criteria) do
1277
+ Address.all.tap do |crit|
1278
+ crit.documents = [ hobrecht, friedel, empty_doc ]
1279
+ end
1280
+ end
1281
+
1282
+ let!(:plucked) do
1283
+ context.pluck(:street)
1284
+ end
1285
+
1286
+ it "returns the values" do
1287
+ expect(plucked).to eq([ "hobrecht", "friedel", nil ])
1288
+ end
1289
+ end
1290
+
1291
+ context "when plucking a field that doesnt exist" do
1292
+
1293
+ context "when pluck one field" do
1294
+
1295
+ let(:plucked) do
1296
+ context.pluck(:foo)
1297
+ end
1298
+
1299
+ it "returns a empty array" do
1300
+ expect(plucked).to eq([nil, nil])
1301
+ end
1302
+ end
1303
+
1304
+ context "when pluck multiple fields" do
1305
+
1306
+ let(:plucked) do
1307
+ context.pluck(:foo, :bar)
1308
+ end
1309
+
1310
+ it "returns a empty array" do
1311
+ expect(plucked).to eq([[nil, nil], [nil, nil]])
1312
+ end
1313
+ end
1314
+ end
1315
+
1316
+ context 'when there is a collation on the criteria' do
1317
+
1318
+ let(:criteria) do
1319
+ Address.all.tap do |crit|
1320
+ crit.documents = [ hobrecht, friedel ]
1321
+ end.collation(locale: 'en_US', strength: 2)
1322
+ end
1323
+
1324
+ it "raises an exception" do
1325
+ expect {
1326
+ context.pluck(:foo, :bar)
1327
+ }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
970
1328
  end
971
1329
  end
972
1330
  end
973
1331
 
974
- context 'when there is a collation on the criteria' do
1332
+ context "when legacy_pluck_distinct is false" do
1333
+ config_override :legacy_pluck_distinct, false
1334
+
1335
+ let!(:depeche) do
1336
+ Band.create!(name: "Depeche Mode", likes: 3)
1337
+ end
1338
+
1339
+ let!(:tool) do
1340
+ Band.create!(name: "Tool", likes: 3)
1341
+ end
1342
+
1343
+ let!(:photek) do
1344
+ Band.create!(name: "Photek", likes: 1)
1345
+ end
1346
+
1347
+ let!(:maniacs) do
1348
+ Band.create!(name: "10,000 Maniacs", likes: 1, sales: "1E2")
1349
+ end
975
1350
 
976
1351
  let(:criteria) do
977
- Address.all.tap do |crit|
978
- crit.documents = [ hobrecht, friedel ]
979
- end.collation(locale: 'en_US', strength: 2)
1352
+ Band.all.tap do |crit|
1353
+ crit.documents = [ depeche, tool, photek, maniacs ]
1354
+ end
980
1355
  end
981
1356
 
982
- it "raises an exception" do
983
- expect {
984
- context.pluck(:foo, :bar)
985
- }.to raise_exception(Mongoid::Errors::InMemoryCollationNotSupported)
1357
+ context "when the field is aliased" do
1358
+
1359
+ let!(:expensive) do
1360
+ Product.create!(price: 100000)
1361
+ end
1362
+
1363
+ let!(:cheap) do
1364
+ Product.create!(price: 1)
1365
+ end
1366
+
1367
+ let(:criteria) do
1368
+ Product.all.tap do |crit|
1369
+ crit.documents = [ expensive, cheap ]
1370
+ end
1371
+ end
1372
+
1373
+ context "when using alias_attribute" do
1374
+
1375
+ let(:plucked) do
1376
+ context.pluck(:price)
1377
+ end
1378
+
1379
+ it "uses the aliases" do
1380
+ expect(plucked).to eq([ 100000, 1 ])
1381
+ end
1382
+ end
1383
+ end
1384
+
1385
+ context "when the criteria matches" do
1386
+
1387
+ context "when there are no duplicate values" do
1388
+
1389
+ let!(:plucked) do
1390
+ context.pluck(:name)
1391
+ end
1392
+
1393
+ it "returns the values" do
1394
+ expect(plucked).to contain_exactly("10,000 Maniacs", "Depeche Mode", "Tool", "Photek")
1395
+ end
1396
+
1397
+ context "when subsequently executing the criteria without a pluck" do
1398
+
1399
+ it "does not limit the fields" do
1400
+ expect(context.first.likes).to eq(3)
1401
+ end
1402
+ end
1403
+
1404
+ context 'when the field is a subdocument' do
1405
+
1406
+ context 'when a top-level field and a subdocument field are plucked' do
1407
+ let(:criteria) do
1408
+ Band.where(name: 'FKA Twigs').tap do |crit|
1409
+ crit.documents = [
1410
+ Band.create!(name: 'FKA Twigs'),
1411
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1412
+ ]
1413
+ end
1414
+ end
1415
+
1416
+ let(:embedded_pluck) do
1417
+ context.pluck(:name, 'records.name')
1418
+ end
1419
+
1420
+ let(:expected) do
1421
+ [
1422
+ ["FKA Twigs", []],
1423
+ ['FKA Twigs', ["LP1"]]
1424
+ ]
1425
+ end
1426
+
1427
+ it 'returns the list of top-level field and subdocument values' do
1428
+ expect(embedded_pluck).to eq(expected)
1429
+ end
1430
+ end
1431
+
1432
+ context 'when only a subdocument field is plucked' do
1433
+
1434
+ let(:criteria) do
1435
+ Band.where(name: 'FKA Twigs').tap do |crit|
1436
+ crit.documents = [
1437
+ Band.create!(name: 'FKA Twigs'),
1438
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1439
+ ]
1440
+ end
1441
+ end
1442
+
1443
+ let(:embedded_pluck) do
1444
+ context.pluck('records.name')
1445
+ end
1446
+
1447
+ let(:expected) do
1448
+ [
1449
+ [],
1450
+ ["LP1"]
1451
+ ]
1452
+ end
1453
+
1454
+ it 'returns the list of subdocument values' do
1455
+ expect(embedded_pluck).to eq(expected)
1456
+ end
1457
+ end
1458
+ end
1459
+ end
1460
+
1461
+ context "when plucking multi-fields" do
1462
+
1463
+ let(:plucked) do
1464
+ context.pluck(:name, :likes)
1465
+ end
1466
+
1467
+ it "returns the values" do
1468
+ expect(plucked).to contain_exactly(["10,000 Maniacs", 1], ["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
1469
+ end
1470
+ end
1471
+
1472
+ context "when there are duplicate values" do
1473
+
1474
+ let(:plucked) do
1475
+ context.pluck(:likes)
1476
+ end
1477
+
1478
+ it "returns the duplicates" do
1479
+ expect(plucked).to contain_exactly(1, 3, 3, 1)
1480
+ end
1481
+ end
1482
+ end
1483
+
1484
+ context "when plucking an aliased field" do
1485
+
1486
+ let(:plucked) do
1487
+ context.pluck(:id)
1488
+ end
1489
+
1490
+ it "returns the field values" do
1491
+ expect(plucked).to eq([ depeche.id, tool.id, photek.id, maniacs.id ])
1492
+ end
1493
+ end
1494
+
1495
+ context "when plucking existent and non-existent fields" do
1496
+
1497
+ let(:plucked) do
1498
+ context.pluck(:id, :fooz)
1499
+ end
1500
+
1501
+ it "returns nil for the field that doesnt exist" do
1502
+ expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil], [maniacs.id, nil] ])
1503
+ end
1504
+ end
1505
+
1506
+ context "when plucking a field that doesnt exist" do
1507
+
1508
+ context "when pluck one field" do
1509
+
1510
+ let(:plucked) do
1511
+ context.pluck(:foo)
1512
+ end
1513
+
1514
+ it "returns an array with nil values" do
1515
+ expect(plucked).to eq([nil, nil, nil, nil])
1516
+ end
1517
+ end
1518
+
1519
+ context "when pluck multiple fields" do
1520
+
1521
+ let(:plucked) do
1522
+ context.pluck(:foo, :bar)
1523
+ end
1524
+
1525
+ it "returns an array of arrays with nil values" do
1526
+ expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil], [nil, nil]])
1527
+ end
1528
+ end
1529
+ end
1530
+
1531
+ context 'when plucking a localized field' do
1532
+
1533
+ before do
1534
+ I18n.locale = :en
1535
+ d = Dictionary.create!(description: 'english-text')
1536
+ I18n.locale = :de
1537
+ d.description = 'deutsch-text'
1538
+ d.save!
1539
+ end
1540
+
1541
+ after do
1542
+ I18n.locale = :en
1543
+ end
1544
+
1545
+ let(:criteria) do
1546
+ Dictionary.all.tap do |crit|
1547
+ crit.documents = [ Dictionary.first ]
1548
+ end
1549
+ end
1550
+
1551
+ context 'when plucking the entire field' do
1552
+
1553
+ let(:plucked) do
1554
+ context.pluck(:description)
1555
+ end
1556
+
1557
+ let(:plucked_translations) do
1558
+ context.pluck(:description_translations)
1559
+ end
1560
+
1561
+ let(:plucked_translations_both) do
1562
+ context.pluck(:description_translations, :description)
1563
+ end
1564
+
1565
+ it 'returns the demongoized translations' do
1566
+ expect(plucked.first).to eq('deutsch-text')
1567
+ end
1568
+
1569
+ it 'returns the full translations hash to _translations' do
1570
+ expect(plucked_translations.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
1571
+ end
1572
+
1573
+ it 'returns both' do
1574
+ expect(plucked_translations_both.first).to eq([{"de"=>"deutsch-text", "en"=>"english-text"}, "deutsch-text"])
1575
+ end
1576
+ end
1577
+
1578
+ context 'when plucking a specific locale' do
1579
+
1580
+ let(:plucked) do
1581
+ context.pluck(:'description.de')
1582
+ end
1583
+
1584
+ it 'returns the specific translations' do
1585
+ expect(plucked.first).to eq('deutsch-text')
1586
+ end
1587
+ end
1588
+
1589
+ context 'when plucking a specific locale from _translations field' do
1590
+
1591
+ let(:plucked) do
1592
+ context.pluck(:'description_translations.de')
1593
+ end
1594
+
1595
+ it 'returns the specific translations' do
1596
+ expect(plucked.first).to eq('deutsch-text')
1597
+ end
1598
+ end
1599
+
1600
+ context 'when fallbacks are enabled with a locale list' do
1601
+ with_i18n_fallbacks
1602
+
1603
+ around(:all) do |example|
1604
+ prev_fallbacks = I18n.fallbacks.dup
1605
+ I18n.fallbacks[:he] = [ :en ]
1606
+ example.run
1607
+ I18n.fallbacks = prev_fallbacks
1608
+ end
1609
+
1610
+ after do
1611
+ I18n.locale = :en
1612
+ end
1613
+
1614
+ let(:plucked) do
1615
+ context.pluck(:description).first
1616
+ end
1617
+
1618
+ it "correctly uses the fallback" do
1619
+ I18n.locale = :en
1620
+ Dictionary.create!(description: 'english-text')
1621
+ I18n.locale = :he
1622
+ plucked.should == "english-text"
1623
+ end
1624
+ end
1625
+
1626
+ context "when the localized field is embedded" do
1627
+ before do
1628
+ p = Passport.new
1629
+ I18n.locale = :en
1630
+ p.name = "Neil"
1631
+ I18n.locale = :he
1632
+ p.name = "Nissim"
1633
+
1634
+ Person.create!(passport: p, employer_id: 12345)
1635
+ end
1636
+
1637
+ after do
1638
+ I18n.locale = :en
1639
+ end
1640
+
1641
+ let(:plucked) do
1642
+ Person.where(employer_id: 12345).pluck("pass.name").first
1643
+ end
1644
+
1645
+ let(:plucked_translations) do
1646
+ Person.where(employer_id: 12345).pluck("pass.name_translations").first
1647
+ end
1648
+
1649
+ let(:plucked_translations_field) do
1650
+ Person.where(employer_id: 12345).pluck("pass.name_translations.en").first
1651
+ end
1652
+
1653
+ it "returns the translation for the current locale" do
1654
+ expect(plucked).to eq("Nissim")
1655
+ end
1656
+
1657
+ it "returns the full _translation hash" do
1658
+ expect(plucked_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
1659
+ end
1660
+
1661
+ it "returns the translation for the requested locale" do
1662
+ expect(plucked_translations_field).to eq("Neil")
1663
+ end
1664
+ end
1665
+ end
1666
+
1667
+ context 'when plucking a field to be demongoized' do
1668
+
1669
+ let(:plucked) do
1670
+ Band.where(name: maniacs.name).pluck(:sales)
1671
+ end
1672
+
1673
+ with_config_values :map_big_decimal_to_decimal128, true, false do
1674
+
1675
+ it "demongoizes the field" do
1676
+ expect(plucked.first).to be_a(BigDecimal)
1677
+ expect(plucked.first).to eq(BigDecimal("1E2"))
1678
+ end
1679
+ end
1680
+ end
1681
+
1682
+ context "when plucking an embedded field" do
1683
+ let(:label) { Label.new(sales: "1E2") }
1684
+ let!(:band) { Band.create!(label: label) }
1685
+
1686
+ let(:plucked) do
1687
+ Band.where(_id: band.id).tap do |crit|
1688
+ crit.documents = [ band ]
1689
+ end.pluck("label.sales")
1690
+ end
1691
+
1692
+ it "demongoizes the field" do
1693
+ expect(plucked).to eq([ BigDecimal("1E2") ])
1694
+ end
1695
+ end
1696
+
1697
+ context "when plucking an embeds_many field" do
1698
+ let(:label) { Label.new(sales: "1E2") }
1699
+ let!(:band) { Band.create!(labels: [label]) }
1700
+
1701
+ let(:plucked) { Band.where(_id: band.id).pluck("labels.sales") }
1702
+
1703
+ it "demongoizes the field" do
1704
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
1705
+ end
1706
+ end
1707
+
1708
+ context "when plucking a nonexistent embedded field" do
1709
+ let(:label) { Label.new(sales: "1E2") }
1710
+ let!(:band) { Band.create!(label: label) }
1711
+
1712
+ let(:plucked) do
1713
+ Band.where(_id: band.id).tap do |crit|
1714
+ crit.documents = [ band ]
1715
+ end.pluck("label.qwerty")
1716
+ end
1717
+
1718
+ it "returns nil" do
1719
+ expect(plucked.first).to eq(nil)
1720
+ end
1721
+ end
1722
+
1723
+ context "when tallying deeply nested arrays/embedded associations" do
1724
+
1725
+ let(:criteria) do
1726
+ Person.all.tap do |crit|
1727
+ crit.documents = [
1728
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
1729
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]),
1730
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]),
1731
+ ]
1732
+ end
1733
+ end
1734
+
1735
+ let(:plucked) do
1736
+ context.pluck("addresses.code.deepest.array.y.z")
1737
+ end
1738
+
1739
+ it "returns the correct hash" do
1740
+ expect(plucked).to eq([
1741
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
1742
+ ])
1743
+ end
1744
+ end
1745
+ end
1746
+ end
1747
+
1748
+ describe "#pick" do
1749
+
1750
+ let(:depeche) do
1751
+ Band.create!(name: "Depeche Mode", likes: 3)
1752
+ end
1753
+
1754
+ let(:tool) do
1755
+ Band.create!(name: "Tool", likes: 3)
1756
+ end
1757
+
1758
+ let(:criteria) do
1759
+ Band.all.tap do |crit|
1760
+ crit.documents = [ depeche, tool ]
1761
+ end
1762
+ end
1763
+
1764
+ let(:context) do
1765
+ described_class.new(criteria)
1766
+ end
1767
+
1768
+ context "when picking a field" do
1769
+
1770
+ let(:picked) do
1771
+ context.pick(:name)
1772
+ end
1773
+
1774
+ it "returns one element" do
1775
+ expect(picked).to eq("Depeche Mode")
1776
+ end
1777
+ end
1778
+
1779
+ context "when picking multiple fields" do
1780
+
1781
+ let(:picked) do
1782
+ context.pick(:name, :likes)
1783
+ end
1784
+
1785
+ it "returns an array" do
1786
+ expect(picked).to eq([ "Depeche Mode", 3 ])
1787
+ end
1788
+ end
1789
+
1790
+ context "when no documents to pick" do
1791
+
1792
+ let(:criteria) do
1793
+ Band.all.tap do |crit|
1794
+ crit.documents = []
1795
+ end
1796
+ end
1797
+
1798
+ let(:picked) do
1799
+ context.pick(:name)
1800
+ end
1801
+
1802
+ it "returns nil" do
1803
+ expect(picked).to be_nil
1804
+ end
1805
+ end
1806
+ end
1807
+
1808
+ describe "#tally" do
1809
+ let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
1810
+ let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
1811
+ let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
1812
+
1813
+ let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
1814
+ let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
1815
+ let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
1816
+
1817
+ let(:label1) { Label.new(name: "Atlantic") }
1818
+ let(:label2) { Label.new(name: "Atlantic") }
1819
+ let(:label3) { Label.new(name: "Columbia") }
1820
+
1821
+
1822
+ let(:band1) { Band.new(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1) }
1823
+ let(:band2) { Band.new(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2) }
1824
+ let(:band3) { Band.new(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3) }
1825
+ let(:band4) { Band.new(origin: "tally2", fanatics: fans1, genres: [1, 2]) }
1826
+ let(:band5) { Band.new(origin: "tally2", fanatics: fans2, genres: [1, 2]) }
1827
+ let(:band6) { Band.new(origin: "tally2", fanatics: fans3, genres: [1, 3]) }
1828
+
1829
+ let(:criteria) do
1830
+ Band.where(origin: "tally").all.tap do |crit|
1831
+ crit.documents = [ band1, band2, band3 ]
1832
+ end
1833
+ end
1834
+
1835
+ let(:criteria2) do
1836
+ Band.where(origin: "tally2").tap do |crit|
1837
+ crit.documents = [ band4, band5, band6 ]
1838
+ end
1839
+ end
1840
+
1841
+ let(:context) do
1842
+ described_class.new(criteria)
1843
+ end
1844
+
1845
+ let(:context2) do
1846
+ described_class.new(criteria2)
1847
+ end
1848
+
1849
+ context "when tallying a string" do
1850
+ let(:tally) do
1851
+ context.tally(:name)
1852
+ end
1853
+
1854
+ it "returns the correct hash" do
1855
+ expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
1856
+ end
1857
+ end
1858
+
1859
+ context "using an aliased field" do
1860
+ let(:tally) do
1861
+ context.tally(:years)
1862
+ end
1863
+
1864
+ it "returns the correct hash" do
1865
+ expect(tally).to eq(30 => 3)
1866
+ end
1867
+ end
1868
+
1869
+ context "when tallying a demongoizable field" do
1870
+ let(:tally) do
1871
+ context.tally(:sales)
1872
+ end
1873
+
1874
+ it "returns the correct hash" do
1875
+ expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
1876
+ end
1877
+ end
1878
+
1879
+ context "when tallying a localized field" do
1880
+ let(:d1) { Dictionary.new(description: 'en1') }
1881
+ let(:d2) { Dictionary.new(description: 'en1') }
1882
+ let(:d3) { Dictionary.new(description: 'en1') }
1883
+ let(:d4) { Dictionary.new(description: 'en2') }
1884
+
1885
+ before do
1886
+ I18n.locale = :en
1887
+ d1
1888
+ d2
1889
+ d3
1890
+ d4
1891
+ I18n.locale = :de
1892
+ d1.description = 'de1'
1893
+ d2.description = 'de1'
1894
+ d3.description = 'de2'
1895
+ d4.description = 'de3'
1896
+ I18n.locale = :en
1897
+ end
1898
+
1899
+ let(:criteria) do
1900
+ Dictionary.all.tap do |crit|
1901
+ crit.documents = [ d1, d2, d3, d4 ]
1902
+ end
1903
+ end
1904
+
1905
+ context "when getting the demongoized field" do
1906
+ let(:tallied) do
1907
+ context.tally(:description)
1908
+ end
1909
+
1910
+ it "returns the translation for the current locale" do
1911
+ expect(tallied).to eq("en1" => 3, "en2" => 1)
1912
+ end
1913
+ end
1914
+
1915
+ context "when getting a specific locale" do
1916
+ let(:tallied) do
1917
+ context.tally("description.de")
1918
+ end
1919
+
1920
+ it "returns the translation for the the specific locale" do
1921
+ expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
1922
+ end
1923
+ end
1924
+
1925
+ context "when getting the full hash" do
1926
+ let(:tallied) do
1927
+ context.tally("description_translations")
1928
+ end
1929
+
1930
+ it "returns the correct hash" do
1931
+ expect(tallied).to eq(
1932
+ {"de" => "de1", "en" => "en1" } => 2,
1933
+ {"de" => "de2", "en" => "en1" } => 1,
1934
+ {"de" => "de3", "en" => "en2" } => 1
1935
+ )
1936
+ end
1937
+ end
1938
+ end
1939
+
1940
+ context "when tallying an embedded localized field" do
1941
+
1942
+ let(:person1) { Person.create!(addresses: [ address1a, address1b ]) }
1943
+ let(:person2) { Person.create!(addresses: [ address2a, address2b ]) }
1944
+
1945
+ let(:address1a) { Address.new(name: "en1") }
1946
+ let(:address1b) { Address.new(name: "en2") }
1947
+ let(:address2a) { Address.new(name: "en1") }
1948
+ let(:address2b) { Address.new(name: "en3") }
1949
+
1950
+ before do
1951
+ I18n.locale = :en
1952
+ address1a
1953
+ address1b
1954
+ address2a
1955
+ address2b
1956
+ I18n.locale = :de
1957
+ address1a.name = "de1"
1958
+ address1b.name = "de2"
1959
+ address2a.name = "de1"
1960
+ address2b.name = "de3"
1961
+ person1
1962
+ person2
1963
+ I18n.locale = :en
1964
+ end
1965
+
1966
+ let(:criteria) do
1967
+ Person.all.tap do |crit|
1968
+ crit.documents = [ person1, person2 ]
1969
+ end
1970
+ end
1971
+
1972
+ context "when getting the demongoized field" do
1973
+ let(:tallied) do
1974
+ context.tally("addresses.name")
1975
+ end
1976
+
1977
+ it "returns the translation for the current locale" do
1978
+ expect(tallied).to eq(
1979
+ [ "en1", "en2" ] => 1,
1980
+ [ "en1", "en3" ] => 1,
1981
+ )
1982
+ end
1983
+ end
1984
+
1985
+ context "when getting a specific locale" do
1986
+ let(:tallied) do
1987
+ context.tally("addresses.name.de")
1988
+ end
1989
+
1990
+ it "returns the translation for the the specific locale" do
1991
+ expect(tallied).to eq(
1992
+ [ "de1", "de2" ] => 1,
1993
+ [ "de1", "de3" ] => 1,
1994
+ )
1995
+ end
1996
+ end
1997
+
1998
+ context "when getting the full hash" do
1999
+ let(:tallied) do
2000
+ context.tally("addresses.name_translations")
2001
+ end
2002
+
2003
+ it "returns the correct hash" do
2004
+ expect(tallied).to eq(
2005
+ [{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
2006
+ [{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
2007
+ )
2008
+ end
2009
+ end
2010
+ end
2011
+
2012
+ context "when tallying an embedded field" do
2013
+ let(:tally) do
2014
+ context.tally("label.name")
2015
+ end
2016
+
2017
+ it "returns the correct hash" do
2018
+ expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
2019
+ end
2020
+ end
2021
+
2022
+ context "when tallying an element in an embeds_many field" do
2023
+
2024
+ let(:tally) do
2025
+ context2.tally("fanatics.age")
2026
+ end
2027
+
2028
+ it "returns the correct hash" do
2029
+ expect(tally).to eq(
2030
+ [1, 2] => 2,
2031
+ [1, 3] => 1
2032
+ )
2033
+ end
2034
+ end
2035
+
2036
+ context "when tallying an embeds_many field" do
2037
+
2038
+ let(:tally) do
2039
+ context2.tally("fanatics")
2040
+ end
2041
+
2042
+ it "returns the correct hash" do
2043
+ expect(tally).to eq(
2044
+ fans1 => 1,
2045
+ fans2 => 1,
2046
+ fans3 => 1,
2047
+ )
2048
+ end
2049
+ end
2050
+
2051
+ context "when tallying a field of type array" do
2052
+
2053
+ let(:tally) do
2054
+ context2.tally("genres")
2055
+ end
2056
+
2057
+ it "returns the correct hash" do
2058
+ expect(tally).to eq(
2059
+ [1, 2] => 2,
2060
+ [1, 3] => 1
2061
+ )
2062
+ end
2063
+ end
2064
+
2065
+ context "when tallying an element from an array of hashes" do
2066
+
2067
+ let(:tally) do
2068
+ context.tally("genres.x")
2069
+ end
2070
+
2071
+ it "returns the correct hash without the nil keys" do
2072
+ expect(tally).to eq(
2073
+ [1, 2] => 2,
2074
+ [1, 3] => 1
2075
+ )
2076
+ end
2077
+ end
2078
+
2079
+ context "when tallying an element from an array of hashes; with duplicate" do
2080
+
2081
+ let(:band4) { Band.new(origin: "tally", genres: [ { x: 1 }, {x: 1} ] ) }
2082
+
2083
+ let(:criteria) do
2084
+ Band.where(origin: "tally").all.tap do |crit|
2085
+ crit.documents = [ band1, band2, band3, band4 ]
2086
+ end
2087
+ end
2088
+
2089
+ let(:tally) do
2090
+ context.tally("genres.x")
2091
+ end
2092
+
2093
+ it "returns the correct hash without the nil keys" do
2094
+ expect(tally).to eq(
2095
+ [1, 2] => 2,
2096
+ [1, 3] => 1,
2097
+ [1, 1] => 1,
2098
+ )
2099
+ end
2100
+ end
2101
+
2102
+ context "when tallying an aliased field of type array" do
2103
+
2104
+ let(:person1) { Person.new(array: [ 1, 2 ]) }
2105
+ let(:person2) { Person.new(array: [ 1, 3 ]) }
2106
+
2107
+ let(:criteria) do
2108
+ Person.all.tap do |crit|
2109
+ crit.documents = [ person1, person2 ]
2110
+ end
2111
+ end
2112
+
2113
+ let(:tally) do
2114
+ context.tally("array")
2115
+ end
2116
+
2117
+ it "returns the correct hash" do
2118
+ expect(tally).to eq(
2119
+ [1, 2] => 1,
2120
+ [1, 3] => 1
2121
+ )
2122
+ end
2123
+ end
2124
+
2125
+ context "when going multiple levels deep in arrays" do
2126
+
2127
+ let(:tally) do
2128
+ context.tally("genres.y.z")
2129
+ end
2130
+
2131
+ it "returns the correct hash" do
2132
+ expect(tally).to eq(
2133
+ [1, 2] => 2,
2134
+ [1, 3] => 1
2135
+ )
2136
+ end
2137
+ end
2138
+
2139
+ context "when going multiple levels deep in an array" do
2140
+
2141
+ let(:tally) do
2142
+ context.tally("genres.y.z")
2143
+ end
2144
+
2145
+ it "returns the correct hash" do
2146
+ expect(tally).to eq(
2147
+ [1, 2] => 2,
2148
+ [1, 3] => 1
2149
+ )
2150
+ end
2151
+ end
2152
+
2153
+ context "when tallying deeply nested arrays/embedded associations" do
2154
+
2155
+ let(:person1) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
2156
+ let(:person2) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ]) }
2157
+ let(:person3) { Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ]) }
2158
+
2159
+ let(:criteria) do
2160
+ Person.all.tap do |crit|
2161
+ crit.documents = [ person1, person2, person3 ]
2162
+ end
2163
+ end
2164
+
2165
+ let(:tally) do
2166
+ context.tally("addresses.code.deepest.array.y.z")
2167
+ end
2168
+
2169
+ it "returns the correct hash" do
2170
+ expect(tally).to eq(
2171
+ [ [ 1, 2 ] ] => 2,
2172
+ [ [ 1, 3 ] ] => 1
2173
+ )
2174
+ end
2175
+ end
2176
+
2177
+ context "when tallying deeply nested arrays/embedded associations" do
2178
+
2179
+ let(:person1) do
2180
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
2181
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2182
+ end
2183
+
2184
+ let(:person2) do
2185
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
2186
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2187
+ end
2188
+
2189
+ let(:person3) do
2190
+ Person.new(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
2191
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2192
+ end
2193
+
2194
+ let(:criteria) do
2195
+ Person.all.tap do |crit|
2196
+ crit.documents = [ person1, person2, person3 ]
2197
+ end
2198
+ end
2199
+
2200
+ let(:tally) do
2201
+ context.tally("addresses.code.deepest.array.y.z")
2202
+ end
2203
+
2204
+ it "returns the correct hash" do
2205
+ expect(tally).to eq(
2206
+ [ [ 1, 2 ], [ 1, 2 ] ] => 2,
2207
+ [ [ 1, 3 ], [ 1, 3 ] ] => 1
2208
+ )
2209
+ end
2210
+ end
2211
+
2212
+ context "when some keys are missing" do
2213
+
2214
+ let(:criteria) do
2215
+ Band.where(origin: "tally").all.tap do |crit|
2216
+ crit.documents = [ band1, band2, band3 ]
2217
+ 3.times{ crit.documents << Band.new(origin: "tally") }
2218
+ end
2219
+ end
2220
+
2221
+ let(:tally) do
2222
+ context.tally(:name)
2223
+ end
2224
+
2225
+ it "returns the correct hash" do
2226
+ expect(tally).to eq(
2227
+ "Depeche Mode" => 1,
2228
+ "New Order" => 1,
2229
+ "10,000 Maniacs" => 1,
2230
+ nil => 3
2231
+ )
2232
+ end
2233
+ end
2234
+
2235
+ context "when the first element is an embeds_one" do
2236
+ let(:person1) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
2237
+ let(:person2) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ])) }
2238
+ let(:person3) { Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ])) }
2239
+
2240
+ let(:criteria) do
2241
+ Person.all.tap do |crit|
2242
+ crit.documents = [ person1, person2, person3 ]
2243
+ end
2244
+ end
2245
+
2246
+ let(:tally) do
2247
+ context.tally("name.translations.language")
2248
+ end
2249
+
2250
+ it "returns the correct hash" do
2251
+ expect(tally).to eq(
2252
+ [1, 2] => 2,
2253
+ [1, 3] => 1
2254
+ )
986
2255
  end
987
2256
  end
988
2257
  end
@@ -1249,19 +2518,19 @@ describe Mongoid::Contextual::Memory do
1249
2518
  describe "#update" do
1250
2519
 
1251
2520
  let(:person) do
1252
- Person.create
2521
+ Person.create!
1253
2522
  end
1254
2523
 
1255
2524
  let(:hobrecht) do
1256
- person.addresses.create(street: "hobrecht")
2525
+ person.addresses.create!(street: "hobrecht")
1257
2526
  end
1258
2527
 
1259
2528
  let(:friedel) do
1260
- person.addresses.create(street: "friedel")
2529
+ person.addresses.create!(street: "friedel")
1261
2530
  end
1262
2531
 
1263
2532
  let(:pfluger) do
1264
- person.addresses.create(street: "pfluger")
2533
+ person.addresses.create!(street: "pfluger")
1265
2534
  end
1266
2535
 
1267
2536
  context "when the documents are embedded one level" do
@@ -1321,11 +2590,11 @@ describe Mongoid::Contextual::Memory do
1321
2590
  context "when the documents are embedded multiple levels" do
1322
2591
 
1323
2592
  let!(:home) do
1324
- hobrecht.locations.create(name: "home")
2593
+ hobrecht.locations.create!(name: "home")
1325
2594
  end
1326
2595
 
1327
2596
  let!(:work) do
1328
- hobrecht.locations.create(name: "work")
2597
+ hobrecht.locations.create!(name: "work")
1329
2598
  end
1330
2599
 
1331
2600
  let(:criteria) do
@@ -1389,19 +2658,19 @@ describe Mongoid::Contextual::Memory do
1389
2658
  describe "#update_all" do
1390
2659
 
1391
2660
  let(:person) do
1392
- Person.create
2661
+ Person.create!
1393
2662
  end
1394
2663
 
1395
2664
  let(:hobrecht) do
1396
- person.addresses.create(street: "hobrecht")
2665
+ person.addresses.create!(street: "hobrecht")
1397
2666
  end
1398
2667
 
1399
2668
  let(:friedel) do
1400
- person.addresses.create(street: "friedel")
2669
+ person.addresses.create!(street: "friedel")
1401
2670
  end
1402
2671
 
1403
2672
  let(:pfluger) do
1404
- person.addresses.create(street: "pfluger")
2673
+ person.addresses.create!(street: "pfluger")
1405
2674
  end
1406
2675
 
1407
2676
  context 'when there is a collation on the criteria' do
@@ -1420,7 +2689,7 @@ describe Mongoid::Contextual::Memory do
1420
2689
  context "when the documents are empty" do
1421
2690
 
1422
2691
  let(:person_two) do
1423
- Person.create
2692
+ Person.create!
1424
2693
  end
1425
2694
 
1426
2695
  let(:criteria) do
@@ -1523,11 +2792,11 @@ describe Mongoid::Contextual::Memory do
1523
2792
  context "when the documents are embedded multiple levels" do
1524
2793
 
1525
2794
  let!(:home) do
1526
- hobrecht.locations.create(name: "home")
2795
+ hobrecht.locations.create!(name: "home")
1527
2796
  end
1528
2797
 
1529
2798
  let!(:work) do
1530
- hobrecht.locations.create(name: "work")
2799
+ hobrecht.locations.create!(name: "work")
1531
2800
  end
1532
2801
 
1533
2802
  let(:criteria) do