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::Criteria do
@@ -38,7 +40,7 @@ describe Mongoid::Criteria do
38
40
  context "when the entries are the same" do
39
41
 
40
42
  let!(:band) do
41
- Band.create(name: "Depeche Mode")
43
+ Band.create!(name: "Depeche Mode")
42
44
  end
43
45
 
44
46
  let(:other) do
@@ -53,11 +55,11 @@ describe Mongoid::Criteria do
53
55
  context "when the entries are not the same" do
54
56
 
55
57
  let!(:band) do
56
- Band.create(name: "Depeche Mode")
58
+ Band.create!(name: "Depeche Mode")
57
59
  end
58
60
 
59
61
  let!(:other_band) do
60
- Band.create(name: "Tool")
62
+ Band.create!(name: "Tool")
61
63
  end
62
64
 
63
65
  let(:other) do
@@ -102,21 +104,21 @@ describe Mongoid::Criteria do
102
104
  describe "#asc" do
103
105
 
104
106
  let(:person) do
105
- Person.create
107
+ Person.create!
106
108
  end
107
109
 
108
110
  context "when the documents are embedded" do
109
111
 
110
112
  let!(:hobrecht) do
111
- person.addresses.create(street: "hobrecht", name: "hobrecht")
113
+ person.addresses.create!(street: "hobrecht", name: "hobrecht")
112
114
  end
113
115
 
114
116
  let!(:friedel) do
115
- person.addresses.create(street: "friedel", name: "friedel")
117
+ person.addresses.create!(street: "friedel", name: "friedel")
116
118
  end
117
119
 
118
120
  let!(:pfluger) do
119
- person.addresses.create(street: "pfluger", name: "pfluger")
121
+ person.addresses.create!(street: "pfluger", name: "pfluger")
120
122
  end
121
123
 
122
124
  let(:criteria) do
@@ -132,7 +134,7 @@ describe Mongoid::Criteria do
132
134
  describe "#batch_size" do
133
135
 
134
136
  let(:person) do
135
- Person.create
137
+ Person.create!
136
138
  end
137
139
 
138
140
  let(:criteria) do
@@ -151,7 +153,7 @@ describe Mongoid::Criteria do
151
153
  describe "#read" do
152
154
 
153
155
  let(:person) do
154
- Person.create
156
+ Person.create!
155
157
  end
156
158
 
157
159
  let(:criteria) do
@@ -168,11 +170,11 @@ describe Mongoid::Criteria do
168
170
  context "when provided a single field" do
169
171
 
170
172
  let!(:depeche) do
171
- Band.create(name: "Depeche Mode", likes: 1000)
173
+ Band.create!(name: "Depeche Mode", likes: 1000)
172
174
  end
173
175
 
174
176
  let!(:tool) do
175
- Band.create(name: "Tool", likes: 500)
177
+ Band.create!(name: "Tool", likes: 500)
176
178
  end
177
179
 
178
180
  let(:criteria) do
@@ -210,11 +212,11 @@ describe Mongoid::Criteria do
210
212
  context "when provided a single field" do
211
213
 
212
214
  let!(:depeche) do
213
- Band.create(name: "Depeche Mode", likes: 1000)
215
+ Band.create!(name: "Depeche Mode", likes: 1000)
214
216
  end
215
217
 
216
218
  let!(:tool) do
217
- Band.create(name: "Tool", likes: 500)
219
+ Band.create!(name: "Tool", likes: 500)
218
220
  end
219
221
 
220
222
  let(:criteria) do
@@ -236,11 +238,11 @@ describe Mongoid::Criteria do
236
238
  describe "\##{method}" do
237
239
 
238
240
  let!(:match) do
239
- Band.create(genres: [ "electro", "dub" ])
241
+ Band.create!(genres: [ "electro", "dub" ])
240
242
  end
241
243
 
242
244
  let!(:non_match) do
243
- Band.create(genres: [ "house" ])
245
+ Band.create!(genres: [ "house" ])
244
246
  end
245
247
 
246
248
  let(:criteria) do
@@ -258,11 +260,11 @@ describe Mongoid::Criteria do
258
260
  describe "\##{method}" do
259
261
 
260
262
  let!(:match) do
261
- Band.create(name: "Depeche Mode", genres: [ "electro" ])
263
+ Band.create!(name: "Depeche Mode", genres: [ "electro" ])
262
264
  end
263
265
 
264
266
  let!(:non_match) do
265
- Band.create(genres: [ "house" ])
267
+ Band.create!(genres: [ "house" ])
266
268
  end
267
269
 
268
270
  let(:criteria) do
@@ -278,7 +280,7 @@ describe Mongoid::Criteria do
278
280
  describe "#as_json" do
279
281
 
280
282
  let!(:band) do
281
- Band.create(name: "Depeche Mode")
283
+ Band.create!(name: "Depeche Mode")
282
284
  end
283
285
 
284
286
  let(:criteria) do
@@ -308,11 +310,11 @@ describe Mongoid::Criteria do
308
310
  describe "#between" do
309
311
 
310
312
  let!(:match) do
311
- Band.create(member_count: 3)
313
+ Band.create!(member_count: 3)
312
314
  end
313
315
 
314
316
  let!(:non_match) do
315
- Band.create(member_count: 10)
317
+ Band.create!(member_count: 10)
316
318
  end
317
319
 
318
320
  let(:criteria) do
@@ -378,13 +380,14 @@ describe Mongoid::Criteria do
378
380
  describe "#cache" do
379
381
 
380
382
  let!(:person) do
381
- Person.create
383
+ Person.create!
382
384
  end
383
385
 
384
- context "when no eager loading is involved" do
386
+ context "when the query cache is enabled" do
387
+ query_cache_enabled
385
388
 
386
389
  let(:criteria) do
387
- Person.all.cache
390
+ Person.all
388
391
  end
389
392
 
390
393
  before do
@@ -392,17 +395,19 @@ describe Mongoid::Criteria do
392
395
  end
393
396
 
394
397
  it "does not hit the database after first iteration" do
395
- expect(criteria.context.view).to receive(:each).never
396
- criteria.each do |doc|
397
- expect(doc).to eq(person)
398
+ expect_no_queries do
399
+ criteria.each do |doc|
400
+ expect(doc).to eq(person)
401
+ end
398
402
  end
399
403
  end
400
404
  end
401
405
 
402
406
  context "when the criteria is eager loading" do
407
+ query_cache_enabled
403
408
 
404
409
  let(:criteria) do
405
- Person.includes(:posts).cache
410
+ Person.includes(:posts)
406
411
  end
407
412
 
408
413
  before do
@@ -410,9 +415,10 @@ describe Mongoid::Criteria do
410
415
  end
411
416
 
412
417
  it "does not hit the database after first iteration" do
413
- expect(criteria.context.view).to receive(:each).never
414
- criteria.each do |doc|
415
- expect(doc).to eq(person)
418
+ expect_no_queries do
419
+ criteria.each do |doc|
420
+ expect(doc).to eq(person)
421
+ end
416
422
  end
417
423
  end
418
424
  end
@@ -489,17 +495,6 @@ describe Mongoid::Criteria do
489
495
  end
490
496
  end
491
497
 
492
- describe "#cache" do
493
-
494
- let(:criteria) do
495
- Band.where(name: "Depeche Mode")
496
- end
497
-
498
- it "sets the cache option to true" do
499
- expect(criteria.cache).to be_cached
500
- end
501
- end
502
-
503
498
  describe "#context" do
504
499
 
505
500
  context "when the model is embedded" do
@@ -530,11 +525,11 @@ describe Mongoid::Criteria do
530
525
  describe "#delete" do
531
526
 
532
527
  let(:depeche) do
533
- Band.create(name: "Depeche Mode")
528
+ Band.create!(name: "Depeche Mode")
534
529
  end
535
530
 
536
531
  let(:tool) do
537
- Band.create(name: "Tool")
532
+ Band.create!(name: "Tool")
538
533
  end
539
534
 
540
535
  context "when no selector is provided" do
@@ -588,7 +583,7 @@ describe Mongoid::Criteria do
588
583
  describe "#each" do
589
584
 
590
585
  let!(:band) do
591
- Band.create(name: "Depeche Mode")
586
+ Band.create!(name: "Depeche Mode")
592
587
  end
593
588
 
594
589
  context "when provided a block" do
@@ -608,14 +603,14 @@ describe Mongoid::Criteria do
608
603
  describe "#elem_match" do
609
604
 
610
605
  let!(:match) do
611
- Band.create(name: "Depeche Mode").tap do |band|
606
+ Band.create!(name: "Depeche Mode").tap do |band|
612
607
  r = band.records
613
- r.create(name: "101")
608
+ r.create!(name: "101")
614
609
  end
615
610
  end
616
611
 
617
612
  let!(:non_match) do
618
- Band.create(genres: [ "house" ])
613
+ Band.create!(genres: [ "house" ])
619
614
  end
620
615
 
621
616
  let(:criteria) do
@@ -661,7 +656,7 @@ describe Mongoid::Criteria do
661
656
  context "when matching documents exist" do
662
657
 
663
658
  let!(:match) do
664
- Band.create(name: "Depeche Mode")
659
+ Band.create!(name: "Depeche Mode")
665
660
  end
666
661
 
667
662
  let(:criteria) do
@@ -676,7 +671,7 @@ describe Mongoid::Criteria do
676
671
  context "when no matching documents exist" do
677
672
 
678
673
  let!(:nonmatch) do
679
- Band.create(name: "New Order")
674
+ Band.create!(name: "New Order")
680
675
  end
681
676
 
682
677
  let(:criteria) do
@@ -692,11 +687,11 @@ describe Mongoid::Criteria do
692
687
  describe "#exists" do
693
688
 
694
689
  let!(:match) do
695
- Band.create(name: "Depeche Mode")
690
+ Band.create!(name: "Depeche Mode")
696
691
  end
697
692
 
698
693
  let!(:non_match) do
699
- Band.create
694
+ Band.create!
700
695
  end
701
696
 
702
697
  let(:criteria) do
@@ -713,7 +708,7 @@ describe Mongoid::Criteria do
713
708
  context "when matching documents exist" do
714
709
 
715
710
  let!(:match) do
716
- Band.create(name: "Depeche Mode")
711
+ Band.create!(name: "Depeche Mode")
717
712
  end
718
713
 
719
714
  let(:criteria) do
@@ -783,23 +778,83 @@ describe Mongoid::Criteria do
783
778
 
784
779
  describe "#field_list" do
785
780
 
781
+ context "when using the default discriminator key" do
782
+ let(:criteria) do
783
+ Doctor.only(:_id)
784
+ end
785
+
786
+ it "returns the fields with required _id minus type" do
787
+ expect(criteria.field_list).to eq([ "_id" ])
788
+ end
789
+ end
790
+
791
+ context "when using a custom discriminator key" do
792
+ before do
793
+ Person.discriminator_key = "dkey"
794
+ end
795
+
796
+ after do
797
+ Person.discriminator_key = nil
798
+ end
799
+
800
+ let(:criteria) do
801
+ Doctor.only(:_id, :_type)
802
+ end
803
+
804
+ it "returns the fields with type without dkey" do
805
+ expect(criteria.field_list).to eq([ "_id", "_type" ])
806
+ end
807
+ end
808
+ end
809
+
810
+ describe "#find" do
811
+ let!(:depeche) do
812
+ Band.create!(name: "Depeche Mode")
813
+ end
814
+
786
815
  let(:criteria) do
787
- Band.only(:name)
816
+ Band.where(name: "Depeche Mode")
817
+ end
818
+
819
+ context "when given a block" do
820
+ it "behaves as Enumerable" do
821
+ result = criteria.find { |c| c.name == "Depeche Mode" }
822
+ expect(result).to eq(depeche)
823
+ end
824
+ end
825
+
826
+ context "when given a Proc and a block" do
827
+ it "behaves as Enumerable" do
828
+ result = criteria.find(-> {"default"}) { |c| c.name == "Not Depeche Mode" }
829
+ expect(result).to eq("default")
830
+ end
831
+ end
832
+
833
+ context "when given a Proc without a block" do
834
+ it "raises an error" do
835
+ lambda do
836
+ criteria.find(-> {"default"})
837
+ # Proc is not serializable to a BSON type
838
+ end.should raise_error(BSON::Error::UnserializableClass)
839
+ end
788
840
  end
789
841
 
790
- it "returns the fields with required _id minus type" do
791
- expect(criteria.field_list).to eq([ "_id", "name" ])
842
+ context "when given an id" do
843
+ it "behaves as Findable" do
844
+ result = criteria.find(depeche.id)
845
+ expect(result).to eq(depeche)
846
+ end
792
847
  end
793
848
  end
794
849
 
795
850
  describe "#find_one_and_update" do
796
851
 
797
852
  let!(:depeche) do
798
- Band.create(name: "Depeche Mode")
853
+ Band.create!(name: "Depeche Mode")
799
854
  end
800
855
 
801
856
  let!(:tool) do
802
- Band.create(name: "Tool")
857
+ Band.create!(name: "Tool")
803
858
  end
804
859
 
805
860
  context "when the selector matches" do
@@ -938,7 +993,7 @@ describe Mongoid::Criteria do
938
993
  it "deletes the document from the database" do
939
994
  expect {
940
995
  depeche.reload
941
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
996
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
942
997
  end
943
998
  end
944
999
  end
@@ -997,7 +1052,7 @@ describe Mongoid::Criteria do
997
1052
  end
998
1053
 
999
1054
  let!(:match) do
1000
- Bar.create(location: [ 52.30, 13.25 ])
1055
+ Bar.create!(location: [ 52.30, 13.25 ])
1001
1056
  end
1002
1057
 
1003
1058
  let(:criteria) do
@@ -1009,7 +1064,7 @@ describe Mongoid::Criteria do
1009
1064
  end
1010
1065
  end
1011
1066
 
1012
- describe "#gt" do
1067
+ describe "#eq" do
1013
1068
 
1014
1069
  let!(:match) do
1015
1070
  Band.create(member_count: 5)
@@ -1019,6 +1074,25 @@ describe Mongoid::Criteria do
1019
1074
  Band.create(member_count: 1)
1020
1075
  end
1021
1076
 
1077
+ let(:criteria) do
1078
+ Band.eq(member_count: 5)
1079
+ end
1080
+
1081
+ it "returns the matching documents" do
1082
+ expect(criteria).to eq([ match ])
1083
+ end
1084
+ end
1085
+
1086
+ describe "#gt" do
1087
+
1088
+ let!(:match) do
1089
+ Band.create!(member_count: 5)
1090
+ end
1091
+
1092
+ let!(:non_match) do
1093
+ Band.create!(member_count: 1)
1094
+ end
1095
+
1022
1096
  let(:criteria) do
1023
1097
  Band.gt(member_count: 4)
1024
1098
  end
@@ -1031,11 +1105,11 @@ describe Mongoid::Criteria do
1031
1105
  describe "#gte" do
1032
1106
 
1033
1107
  let!(:match) do
1034
- Band.create(member_count: 5)
1108
+ Band.create!(member_count: 5)
1035
1109
  end
1036
1110
 
1037
1111
  let!(:non_match) do
1038
- Band.create(member_count: 1)
1112
+ Band.create!(member_count: 1)
1039
1113
  end
1040
1114
 
1041
1115
  let(:criteria) do
@@ -1054,11 +1128,11 @@ describe Mongoid::Criteria do
1054
1128
  context "when querying on a normal field" do
1055
1129
 
1056
1130
  let!(:match) do
1057
- Band.create(genres: [ "electro", "dub" ])
1131
+ Band.create!(genres: [ "electro", "dub" ])
1058
1132
  end
1059
1133
 
1060
1134
  let!(:non_match) do
1061
- Band.create(genres: [ "house" ])
1135
+ Band.create!(genres: [ "house" ])
1062
1136
  end
1063
1137
 
1064
1138
  let(:criteria) do
@@ -1077,7 +1151,7 @@ describe Mongoid::Criteria do
1077
1151
  end
1078
1152
 
1079
1153
  let!(:match_one) do
1080
- Person.create(preference_ids: [ id ])
1154
+ Person.create!(preference_ids: [ id ])
1081
1155
  end
1082
1156
 
1083
1157
  context "when providing valid ids" do
@@ -1118,7 +1192,7 @@ describe Mongoid::Criteria do
1118
1192
  context "when the relation is a one to one" do
1119
1193
 
1120
1194
  let!(:game) do
1121
- Game.create
1195
+ Game.create!
1122
1196
  end
1123
1197
 
1124
1198
  let(:criteria) do
@@ -1153,1312 +1227,204 @@ describe Mongoid::Criteria do
1153
1227
  end
1154
1228
  end
1155
1229
 
1156
- describe "#includes" do
1230
+ describe "#lt" do
1157
1231
 
1158
- let!(:person) do
1159
- Person.create(age: 1)
1232
+ let!(:match) do
1233
+ Band.create!(member_count: 1)
1160
1234
  end
1161
1235
 
1162
- context "when providing a name that is not a relation" do
1163
-
1164
- it "raises an error" do
1165
- expect {
1166
- Person.includes(:members)
1167
- }.to raise_error(Mongoid::Errors::InvalidIncludes)
1168
- end
1236
+ let!(:non_match) do
1237
+ Band.create!(member_count: 5)
1169
1238
  end
1170
1239
 
1171
- context "when providing one association" do
1172
-
1173
- let!(:user) do
1174
- User.create(posts: [ post1 ])
1175
- end
1176
-
1177
- let!(:post1) do
1178
- Post.create
1179
- end
1180
-
1181
- let(:result) do
1182
- User.includes(:posts).first
1183
- end
1184
-
1185
- it "executes the query" do
1186
- expect(result).to eq(user)
1187
- end
1188
-
1189
- it "includes the related objects" do
1190
- expect(result.posts).to eq([ post1 ])
1191
- end
1240
+ let(:criteria) do
1241
+ Band.lt(member_count: 4)
1192
1242
  end
1193
1243
 
1194
- context "when providing a list of associations" do
1195
-
1196
- let!(:user) do
1197
- User.create(posts: [ post1 ], descriptions: [ description1 ])
1198
- end
1199
-
1200
- let!(:post1) do
1201
- Post.create
1202
- end
1203
-
1204
- let!(:description1) do
1205
- Description.create(details: 1)
1206
- end
1244
+ it "returns the matching documents" do
1245
+ expect(criteria).to eq([ match ])
1246
+ end
1247
+ end
1207
1248
 
1208
- let(:result) do
1209
- User.includes(:posts, :descriptions).first
1210
- end
1249
+ describe "#lte" do
1211
1250
 
1212
- it "executes the query" do
1213
- expect(result).to eq(user)
1214
- end
1251
+ let!(:match) do
1252
+ Band.create!(member_count: 4)
1253
+ end
1215
1254
 
1216
- it "includes the related objects" do
1217
- expect(result.posts).to eq([ post1 ])
1218
- expect(result.descriptions).to eq([ description1 ])
1219
- end
1255
+ let!(:non_match) do
1256
+ Band.create!(member_count: 5)
1220
1257
  end
1221
1258
 
1222
- context "when providing a nested association" do
1259
+ let(:criteria) do
1260
+ Band.lte(member_count: 4)
1261
+ end
1223
1262
 
1224
- let!(:user) do
1225
- User.create
1226
- end
1263
+ it "returns the matching documents" do
1264
+ expect(criteria).to eq([ match ])
1265
+ end
1266
+ end
1227
1267
 
1228
- before do
1229
- p = Post.create(alerts: [ Alert.create ])
1230
- user.posts = [ p ]
1231
- user.save
1232
- end
1268
+ describe "#map_reduce" do
1233
1269
 
1234
- let(:result) do
1235
- User.includes(:posts => [:alerts]).first
1236
- end
1270
+ let(:map) do
1271
+ %Q{
1272
+ function() {
1273
+ emit(this.name, { likes: this.likes });
1274
+ }}
1275
+ end
1237
1276
 
1238
- it "executes the query" do
1239
- expect(result).to eq(user)
1240
- end
1277
+ let(:reduce) do
1278
+ %Q{
1279
+ function(key, values) {
1280
+ var result = { likes: 0 };
1281
+ values.forEach(function(value) {
1282
+ result.likes += value.likes;
1283
+ });
1284
+ return result;
1285
+ }}
1286
+ end
1241
1287
 
1242
- it "includes the related objects" do
1243
- expect(result.posts.size).to eq(1)
1244
- expect(result.posts.first.alerts.size).to eq(1)
1245
- end
1288
+ let!(:depeche_mode) do
1289
+ Band.create!(name: "Depeche Mode", likes: 200)
1246
1290
  end
1247
1291
 
1248
- context "when providing a deeply nested association" do
1292
+ let!(:tool) do
1293
+ Band.create!(name: "Tool", likes: 100)
1294
+ end
1249
1295
 
1250
- let!(:user) do
1251
- User.create
1252
- end
1296
+ context "when no timeout options are provided" do
1253
1297
 
1254
- let(:results) do
1255
- User.includes(:posts => [{ :alerts => :items }]).to_a
1298
+ let(:map_reduce) do
1299
+ Band.limit(2).map_reduce(map, reduce).out(inline: 1)
1256
1300
  end
1257
1301
 
1258
- it "executes the query" do
1259
- expect(results.first).to eq(user)
1302
+ it "returns the map/reduce results" do
1303
+ expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
1304
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1305
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1306
+ ])
1260
1307
  end
1261
1308
  end
1309
+ end
1262
1310
 
1263
- context "when the models are inherited" do
1311
+ describe "#max" do
1264
1312
 
1265
- before(:all) do
1266
- class A
1267
- include Mongoid::Document
1268
- end
1313
+ context "when provided a single field" do
1269
1314
 
1270
- class B < A
1271
- belongs_to :c
1272
- end
1315
+ let!(:depeche) do
1316
+ Band.create!(name: "Depeche Mode", likes: 1000)
1317
+ end
1273
1318
 
1274
- class C
1275
- include Mongoid::Document
1276
- has_one :b
1277
- end
1319
+ let!(:tool) do
1320
+ Band.create!(name: "Tool", likes: 500)
1278
1321
  end
1279
1322
 
1280
- after(:all) do
1281
- Object.send(:remove_const, :A)
1282
- Object.send(:remove_const, :B)
1283
- Object.send(:remove_const, :C)
1323
+ let(:criteria) do
1324
+ Band.all
1284
1325
  end
1285
1326
 
1286
- context "when the includes is on the subclass" do
1327
+ context "when provided a symbol" do
1287
1328
 
1288
- let!(:c_one) do
1289
- C.create
1329
+ let(:max) do
1330
+ criteria.max(:likes)
1290
1331
  end
1291
1332
 
1292
- let!(:c_two) do
1293
- C.create
1333
+ it "returns the max of the provided field" do
1334
+ expect(max).to eq(1000)
1294
1335
  end
1336
+ end
1295
1337
 
1296
- let!(:b) do
1297
- B.create(c: c_two)
1298
- end
1338
+ context "when provided a block" do
1299
1339
 
1300
- let!(:results) do
1301
- C.includes(:b).to_a.detect do |c|
1302
- c.id == c_two.id
1340
+ let(:max) do
1341
+ criteria.max do |a, b|
1342
+ a.likes <=> b.likes
1303
1343
  end
1304
1344
  end
1305
1345
 
1306
- it "returns the correct documents" do
1307
- expect(results).to eq(c_two)
1308
- end
1309
-
1310
- it "does not query the db" do
1311
- expect_query(0) do
1312
- results.b
1313
- end
1346
+ it "returns the document with the max value for the field" do
1347
+ expect(max).to eq(depeche)
1314
1348
  end
1315
1349
  end
1316
1350
  end
1351
+ end
1317
1352
 
1318
- context "when the models are inherited from another one model" do
1353
+ describe "#max_distance" do
1319
1354
 
1320
- context "when the relation is a has_one" do
1355
+ before do
1356
+ Bar.create_indexes
1357
+ end
1321
1358
 
1322
- before(:all) do
1323
- class A
1324
- include Mongoid::Document
1325
- end
1359
+ let!(:match) do
1360
+ Bar.create!(location: [ 52.30, 13.25 ])
1361
+ end
1326
1362
 
1327
- class B < A
1328
- belongs_to :d
1329
- end
1363
+ let!(:non_match) do
1364
+ Bar.create!(location: [ 19.26, 99.70 ])
1365
+ end
1330
1366
 
1331
- class C < A
1332
- belongs_to :d
1333
- end
1367
+ let(:criteria) do
1368
+ Bar.near(location: [ 52, 13 ]).max_distance(location: 5)
1369
+ end
1334
1370
 
1335
- class D
1336
- include Mongoid::Document
1337
- has_one :b
1338
- has_one :c
1339
- end
1340
- end
1371
+ it "returns the matching documents" do
1372
+ expect(criteria).to eq([ match ])
1373
+ end
1374
+ end
1341
1375
 
1342
- after(:all) do
1343
- Object.send(:remove_const, :A)
1344
- Object.send(:remove_const, :B)
1345
- Object.send(:remove_const, :C)
1346
- Object.send(:remove_const, :D)
1347
- end
1376
+ describe "#merge" do
1348
1377
 
1349
- context "when the includes is on the several relations" do
1378
+ let(:band) do
1379
+ Band.new
1380
+ end
1350
1381
 
1351
- let!(:d_one) do
1352
- D.create
1353
- end
1382
+ let(:criteria) do
1383
+ Band.scoped.where(name: "Depeche Mode").asc(:name)
1384
+ end
1354
1385
 
1355
- let!(:d_two) do
1356
- D.create
1357
- end
1386
+ context "when merging with another criteria" do
1358
1387
 
1359
- let!(:b) do
1360
- B.create(d: d_two)
1361
- end
1388
+ let(:mergeable) do
1389
+ Band.includes(:records).tap do |crit|
1390
+ crit.documents = [ band ]
1391
+ end
1392
+ end
1362
1393
 
1363
- let!(:c) do
1364
- C.create(d: d_two)
1365
- end
1394
+ let(:association) do
1395
+ Band.relations["records"]
1396
+ end
1366
1397
 
1367
- let!(:results) do
1368
- D.includes(:b, :c).entries.detect do |d|
1369
- d.id == d_two.id
1370
- end
1371
- end
1398
+ let(:merged) do
1399
+ criteria.merge(mergeable)
1400
+ end
1372
1401
 
1373
- it "returns the correct documents" do
1374
- expect(results).to eq(d_two)
1375
- end
1402
+ it "merges the selector" do
1403
+ expect(merged.selector).to eq({ "name" => "Depeche Mode" })
1404
+ end
1376
1405
 
1377
- it "does not query the db on b" do
1378
- expect_query(0) do
1379
- results.b
1380
- end
1381
- end
1406
+ it "merges the options" do
1407
+ expect(merged.options).to eq({ sort: { "name" => 1 }})
1408
+ end
1382
1409
 
1383
- it "does not query the db on c" do
1384
- expect_query(0) do
1385
- results.b
1386
- end
1387
- end
1388
- end
1410
+ it "merges the documents" do
1411
+ expect(merged.documents).to eq([ band ])
1389
1412
  end
1390
1413
 
1391
- context "when the relation is a has_many" do
1414
+ it "merges the scoping options" do
1415
+ expect(merged.scoping_options).to eq([ nil, nil ])
1416
+ end
1392
1417
 
1393
- before(:all) do
1394
- class A
1395
- include Mongoid::Document
1396
- end
1418
+ it "merges the inclusions" do
1419
+ expect(merged.inclusions).to eq([ association ])
1420
+ end
1397
1421
 
1398
- class B < A
1399
- belongs_to :d
1400
- end
1422
+ it "returns a new criteria" do
1423
+ expect(merged).to_not equal(criteria)
1424
+ end
1425
+ end
1401
1426
 
1402
- class C < A
1403
- belongs_to :d
1404
- end
1405
-
1406
- class D
1407
- include Mongoid::Document
1408
- has_many :b
1409
- has_many :c
1410
- end
1411
- end
1412
-
1413
- after(:all) do
1414
- Object.send(:remove_const, :A)
1415
- Object.send(:remove_const, :B)
1416
- Object.send(:remove_const, :C)
1417
- Object.send(:remove_const, :D)
1418
- end
1419
-
1420
- context "when the includes is on the several relations" do
1421
-
1422
- let!(:d_one) do
1423
- D.create
1424
- end
1425
-
1426
- let!(:d_two) do
1427
- D.create
1428
- end
1429
-
1430
- let!(:bs) do
1431
- 2.times.map { B.create(d: d_two) }
1432
- end
1433
-
1434
- let!(:cs) do
1435
- 2.times.map { C.create(d: d_two) }
1436
- end
1437
-
1438
- let!(:results) do
1439
- D.includes(:b, :c).entries.detect do |d|
1440
- d.id == d_two.id
1441
- end
1442
- end
1443
-
1444
- it "returns the correct documents" do
1445
- expect(results).to eq(d_two)
1446
- end
1447
-
1448
- it "does not query the db on b" do
1449
- expect_query(0) do
1450
- results.b
1451
- end
1452
- end
1453
-
1454
- it "does not query the db on c" do
1455
- expect_query(0) do
1456
- results.b
1457
- end
1458
- end
1459
- end
1460
- end
1461
- end
1462
-
1463
- context "when including the same association multiple times" do
1464
-
1465
- let(:criteria) do
1466
- Person.all.includes(:posts, :posts).includes(:posts)
1467
- end
1468
-
1469
- let(:association) do
1470
- Person.reflect_on_association(:posts)
1471
- end
1472
-
1473
- it "does not duplicate the association in the inclusions" do
1474
- expect(criteria.inclusions).to eq([ association ])
1475
- end
1476
- end
1477
-
1478
- context "when mapping the results more than once" do
1479
-
1480
- let!(:post) do
1481
- person.posts.create(title: "one")
1482
- end
1483
-
1484
- let(:criteria) do
1485
- Post.includes(:person)
1486
- end
1487
-
1488
- let!(:results) do
1489
- criteria.map { |doc| doc }
1490
- criteria.map { |doc| doc }
1491
- end
1492
-
1493
- it "returns the proper results" do
1494
- expect(results.first.title).to eq("one")
1495
- end
1496
- end
1497
-
1498
- context "when including a belongs to relation" do
1499
-
1500
- context "when the criteria is from the root" do
1501
-
1502
- let!(:person_two) do
1503
- Person.create(age: 2)
1504
- end
1505
-
1506
- let!(:post_one) do
1507
- person.posts.create(title: "one")
1508
- end
1509
-
1510
- let!(:post_two) do
1511
- person_two.posts.create(title: "two")
1512
- end
1513
-
1514
- context "when calling first" do
1515
-
1516
- let(:criteria) do
1517
- Post.includes(:person)
1518
- end
1519
-
1520
- let!(:document) do
1521
- criteria.first
1522
- end
1523
-
1524
- it "eager loads the first document" do
1525
- expect_query(0) do
1526
- expect(document.person).to eq(person)
1527
- end
1528
- end
1529
-
1530
- it "returns the first document" do
1531
- expect(document).to eq(post_one)
1532
- end
1533
- end
1534
-
1535
- context "when calling last" do
1536
-
1537
- let!(:criteria) do
1538
- Post.asc(:_id).includes(:person)
1539
- end
1540
-
1541
- let!(:document) do
1542
- criteria.last
1543
- end
1544
-
1545
- it "eager loads the last document" do
1546
- expect_query(0) do
1547
- expect(document.person).to eq(person_two)
1548
- end
1549
- end
1550
-
1551
- it "returns the last document" do
1552
- expect(document).to eq(post_two)
1553
- end
1554
- end
1555
- end
1556
-
1557
- context "when the criteria is from an embedded relation" do
1558
-
1559
- let(:peep) do
1560
- Person.create
1561
- end
1562
-
1563
- let!(:address_one) do
1564
- peep.addresses.create(street: "rosenthaler")
1565
- end
1566
-
1567
- let!(:address_two) do
1568
- peep.addresses.create(street: "weinmeister")
1569
- end
1570
-
1571
- let!(:depeche) do
1572
- Band.create!(name: "Depeche Mode")
1573
- end
1574
-
1575
- let!(:tool) do
1576
- Band.create!(name: "Tool")
1577
- end
1578
-
1579
- before do
1580
- address_one.band = depeche
1581
- address_two.band = tool
1582
- address_one.save
1583
- address_two.save
1584
- end
1585
-
1586
- context "when calling first" do
1587
-
1588
- let(:criteria) do
1589
- peep.reload.addresses.includes(:band)
1590
- end
1591
-
1592
- let(:context) do
1593
- criteria.context
1594
- end
1595
-
1596
- let!(:document) do
1597
- criteria.first
1598
- end
1599
-
1600
- it "eager loads the first document" do
1601
- expect_query(0) do
1602
- expect(document.band).to eq(depeche)
1603
- end
1604
- end
1605
-
1606
- it "returns the document" do
1607
- expect(document).to eq(address_one)
1608
- end
1609
- end
1610
-
1611
- context "when calling last" do
1612
-
1613
- let(:criteria) do
1614
- peep.reload.addresses.includes(:band)
1615
- end
1616
-
1617
- let(:context) do
1618
- criteria.context
1619
- end
1620
-
1621
- let!(:document) do
1622
- criteria.last
1623
- end
1624
-
1625
- it "eager loads the last document" do
1626
- expect_query(0) do
1627
- expect(document.band).to eq(tool)
1628
- end
1629
- end
1630
-
1631
- it "returns the document" do
1632
- expect(document).to eq(address_two)
1633
- end
1634
- end
1635
-
1636
- context "when iterating all documents" do
1637
-
1638
- let(:criteria) do
1639
- peep.reload.addresses.includes(:band)
1640
- end
1641
-
1642
- let(:context) do
1643
- criteria.context
1644
- end
1645
-
1646
- let!(:documents) do
1647
- criteria.to_a
1648
- end
1649
-
1650
- it "eager loads the first document" do
1651
- expect_query(0) do
1652
- expect(documents.first.band).to eq(depeche)
1653
- end
1654
- end
1655
-
1656
- it "eager loads the last document" do
1657
- expect_query(0) do
1658
- expect(documents.last.band).to eq(tool)
1659
- end
1660
- end
1661
-
1662
- it "returns the documents" do
1663
- expect(documents).to eq([ address_one, address_two ])
1664
- end
1665
- end
1666
- end
1667
- end
1668
-
1669
- context "when providing inclusions to the default scope" do
1670
-
1671
- before do
1672
- Person.default_scope(->{ Person.includes(:posts) })
1673
- end
1674
-
1675
- after do
1676
- Person.default_scoping = nil
1677
- end
1678
-
1679
- let!(:post_one) do
1680
- person.posts.create(title: "one")
1681
- end
1682
-
1683
- let!(:post_two) do
1684
- person.posts.create(title: "two")
1685
- end
1686
-
1687
- context "when the criteria has no options" do
1688
-
1689
- let!(:criteria) do
1690
- Person.asc(:age).all
1691
- end
1692
-
1693
- let!(:documents) do
1694
- criteria.entries
1695
- end
1696
-
1697
- it "returns the correct documents" do
1698
- expect(documents).to eq([ person ])
1699
- end
1700
-
1701
- it "eager loads the first document" do
1702
- expect_query(0) do
1703
- expect(documents.first.posts.first).to eq(post_one)
1704
- end
1705
- end
1706
-
1707
- it "eager loads the last document" do
1708
- expect_query(0) do
1709
- expect(documents.first.posts.last).to eq(post_two)
1710
- end
1711
- end
1712
-
1713
- context "when executing the query twice" do
1714
-
1715
- let!(:new_criteria) do
1716
- Person.where(id: person.id)
1717
- end
1718
-
1719
- let!(:new_context) do
1720
- new_criteria.context
1721
- end
1722
-
1723
- before do
1724
- expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
1725
- end
1726
-
1727
- let!(:from_db) do
1728
- new_criteria.first
1729
- end
1730
-
1731
- it "does not duplicate documents in the relation" do
1732
- expect(person.posts.size).to eq(2)
1733
- end
1734
- end
1735
- end
1736
-
1737
- context "when calling first on the criteria" do
1738
-
1739
- let(:criteria) do
1740
- Person.asc(:age).all
1741
- end
1742
-
1743
- let!(:from_db) do
1744
- criteria.first
1745
- end
1746
-
1747
- it "returns the correct documents" do
1748
- expect(from_db).to eq(person)
1749
- end
1750
-
1751
- it "eager loads the first document" do
1752
- expect_query(0) do
1753
- expect(from_db.posts.first).to eq(post_one)
1754
- end
1755
- end
1756
-
1757
- it "eager loads the last document" do
1758
- expect_query(0) do
1759
- expect(from_db.posts.last).to eq(post_two)
1760
- end
1761
- end
1762
- end
1763
-
1764
- context "when calling last on the criteria" do
1765
-
1766
- let(:criteria) do
1767
- Person.asc(:age).all
1768
- end
1769
-
1770
- let!(:context) do
1771
- criteria.context
1772
- end
1773
-
1774
- before do
1775
- expect(context).to receive(:eager_load).with([person]).once.and_call_original
1776
- end
1777
-
1778
- let!(:from_db) do
1779
- criteria.last
1780
- end
1781
-
1782
- it "returns the correct documents" do
1783
- expect(from_db).to eq(person)
1784
- end
1785
-
1786
- it "eager loads the first document" do
1787
- expect_query(0) do
1788
- expect(from_db.posts.first).to eq(post_one)
1789
- end
1790
- end
1791
-
1792
- it "eager loads the last document" do
1793
- expect_query(0) do
1794
- expect(from_db.posts.last).to eq(post_two)
1795
- end
1796
- end
1797
- end
1798
-
1799
- context "when the criteria has limiting options" do
1800
-
1801
- let!(:person_two) do
1802
- Person.create
1803
- end
1804
-
1805
- let!(:post_three) do
1806
- person_two.posts.create(title: "three")
1807
- end
1808
-
1809
- let!(:criteria) do
1810
- Person.asc(:age).limit(1)
1811
- end
1812
-
1813
- let!(:documents) do
1814
- criteria.entries
1815
- end
1816
-
1817
- it "returns the correct documents" do
1818
- expect(criteria).to eq([ person ])
1819
- end
1820
-
1821
- it "eager loads the first document" do
1822
- expect_query(0) do
1823
- expect(documents.first.posts.first).to eq(post_one)
1824
- end
1825
- end
1826
-
1827
- it "eager loads the second document" do
1828
- expect_query(0) do
1829
- expect(documents.first.posts.last).to eq(post_two)
1830
- end
1831
- end
1832
- end
1833
- end
1834
-
1835
- context "when including a has and belongs to many" do
1836
-
1837
- let!(:preference_one) do
1838
- person.preferences.create(name: "one")
1839
- end
1840
-
1841
- let!(:preference_two) do
1842
- person.preferences.create(name: "two")
1843
- end
1844
-
1845
- context "when one of the related items is deleted" do
1846
-
1847
- before do
1848
- person.preferences = [ preference_one, preference_two ]
1849
- preference_two.delete
1850
- end
1851
-
1852
- let(:criteria) do
1853
- Person.where(id: person.id).includes(:preferences)
1854
- end
1855
-
1856
- it "only loads the existing related items" do
1857
- expect(criteria.entries.first.preferences).to eq([ preference_one ])
1858
- end
1859
- end
1860
-
1861
- context "when the criteria has no options" do
1862
-
1863
- let!(:criteria) do
1864
- Person.asc(:age).includes(:preferences)
1865
- end
1866
-
1867
- let!(:documents) do
1868
- criteria.entries
1869
- end
1870
-
1871
- it "returns the correct documents" do
1872
- expect(documents).to eq([ person ])
1873
- end
1874
-
1875
- it "eager loads the first document" do
1876
- expect_query(0) do
1877
- expect(documents.first.preferences.first).to eq(preference_one)
1878
- end
1879
- end
1880
-
1881
- it "eager loads the last document" do
1882
- expect_query(0) do
1883
- expect(documents.first.preferences.last).to eq(preference_two)
1884
- end
1885
- end
1886
- end
1887
-
1888
- context "when calling first on the criteria" do
1889
-
1890
- let!(:criteria) do
1891
- Person.asc(:age).includes(:preferences)
1892
- end
1893
-
1894
- let!(:from_db) do
1895
- criteria.first
1896
- end
1897
-
1898
- it "returns the correct documents" do
1899
- expect(from_db).to eq(person)
1900
- end
1901
-
1902
- it "eager loads the first document" do
1903
- expect_query(0) do
1904
- expect(from_db.preferences.first).to eq(preference_one)
1905
- end
1906
- end
1907
-
1908
- it "eager loads the last document" do
1909
- expect_query(0) do
1910
- expect(from_db.preferences.last).to eq(preference_two)
1911
- end
1912
- end
1913
- end
1914
-
1915
- context "when calling last on the criteria" do
1916
-
1917
- let!(:criteria) do
1918
- Person.asc(:age).includes(:preferences)
1919
- end
1920
-
1921
- let!(:from_db) do
1922
- criteria.last
1923
- end
1924
-
1925
- it "returns the correct documents" do
1926
- expect(from_db).to eq(person)
1927
- end
1928
-
1929
- it "eager loads the first document" do
1930
- expect_query(0) do
1931
- expect(from_db.preferences.first).to eq(preference_one)
1932
- end
1933
- end
1934
-
1935
- it "eager loads the last document" do
1936
- expect_query(0) do
1937
- expect(from_db.preferences.last).to eq(preference_two)
1938
- end
1939
- end
1940
- end
1941
- end
1942
-
1943
- context "when including a has many" do
1944
-
1945
- let!(:post_one) do
1946
- person.posts.create(title: "one")
1947
- end
1948
-
1949
- let!(:post_two) do
1950
- person.posts.create(title: "two")
1951
- end
1952
-
1953
- context "when the criteria has no options" do
1954
-
1955
- let!(:criteria) do
1956
- Person.asc(:age).includes(:posts)
1957
- end
1958
-
1959
- let!(:documents) do
1960
- criteria.entries
1961
- end
1962
-
1963
- it "returns the correct documents" do
1964
- expect(documents).to eq([ person ])
1965
- end
1966
-
1967
- it "eager loads the first document" do
1968
- expect_query(0) do
1969
- expect(documents.first.posts.first).to eq(post_one)
1970
- end
1971
- end
1972
-
1973
- it "eager loads the last document" do
1974
- expect_query(0) do
1975
- expect(documents.first.posts.last).to eq(post_two)
1976
- end
1977
- end
1978
- end
1979
-
1980
- context "when calling first on the criteria" do
1981
-
1982
- let!(:criteria) do
1983
- Person.asc(:age).includes(:posts)
1984
- end
1985
-
1986
- let!(:from_db) do
1987
- criteria.first
1988
- end
1989
-
1990
- it "returns the correct documents" do
1991
- expect(from_db).to eq(person)
1992
- end
1993
-
1994
- context "when subsequently getting all documents" do
1995
-
1996
- let!(:documents) do
1997
- criteria.entries
1998
- end
1999
-
2000
- it "returns the correct documents" do
2001
- expect(documents).to eq([ person ])
2002
- end
2003
- end
2004
- end
2005
-
2006
- context "when calling last on the criteria" do
2007
-
2008
- let!(:criteria) do
2009
- Person.asc(:age).includes(:posts)
2010
- end
2011
-
2012
- let!(:from_db) do
2013
- criteria.last
2014
- end
2015
-
2016
- it "returns the correct documents" do
2017
- expect(from_db).to eq(person)
2018
- end
2019
-
2020
- context "when subsequently getting all documents" do
2021
-
2022
- let!(:documents) do
2023
- criteria.entries
2024
- end
2025
-
2026
- it "returns the correct documents" do
2027
- expect(documents).to eq([ person ])
2028
- end
2029
- end
2030
- end
2031
-
2032
- context "when the criteria has limiting options" do
2033
-
2034
- let!(:person_two) do
2035
- Person.create
2036
- end
2037
-
2038
- let!(:post_three) do
2039
- person_two.posts.create(title: "three")
2040
- end
2041
-
2042
- let!(:criteria) do
2043
- Person.includes(:posts).asc(:age).limit(1)
2044
- end
2045
-
2046
- let(:context) do
2047
- criteria.context
2048
- end
2049
-
2050
- before do
2051
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2052
- end
2053
-
2054
- let!(:documents) do
2055
- criteria.entries
2056
- end
2057
-
2058
- it "returns the correct documents" do
2059
- expect(documents).to eq([ person ])
2060
- end
2061
- end
2062
- end
2063
-
2064
- context "when including a has one" do
2065
-
2066
- let!(:game_one) do
2067
- person.create_game(name: "one")
2068
- end
2069
-
2070
- let!(:game_two) do
2071
- person.create_game(name: "two")
2072
- end
2073
-
2074
- context "when the criteria has no options" do
2075
-
2076
- let!(:criteria) do
2077
- Person.asc(:age).includes(:game)
2078
- end
2079
-
2080
- let(:context) do
2081
- criteria.context
2082
- end
2083
-
2084
- before do
2085
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2086
- end
2087
-
2088
- let!(:documents) do
2089
- criteria.entries
2090
- end
2091
-
2092
- it "returns the correct documents" do
2093
- expect(documents).to eq([ person ])
2094
- end
2095
- end
2096
-
2097
- context "when the criteria has limiting options" do
2098
-
2099
- let!(:person_two) do
2100
- Person.create(age: 2)
2101
- end
2102
-
2103
- let!(:game_three) do
2104
- person_two.create_game(name: "Skyrim")
2105
- end
2106
-
2107
- let!(:criteria) do
2108
- Person.where(id: person.id).includes(:game).asc(:age).limit(1)
2109
- end
2110
-
2111
- let(:context) do
2112
- criteria.context
2113
- end
2114
-
2115
- before do
2116
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2117
- end
2118
-
2119
- let!(:documents) do
2120
- criteria.entries
2121
- end
2122
-
2123
- it "returns the correct documents" do
2124
- expect(documents).to eq([ person ])
2125
- end
2126
- end
2127
- end
2128
-
2129
- context "when including a belongs to" do
2130
-
2131
- let(:person_two) do
2132
- Person.create(age: 2)
2133
- end
2134
-
2135
- let!(:game_one) do
2136
- person.create_game(name: "one")
2137
- end
2138
-
2139
- let!(:game_two) do
2140
- person_two.create_game(name: "two")
2141
- end
2142
-
2143
- context "when providing no options" do
2144
-
2145
- let!(:criteria) do
2146
- Game.includes(:person)
2147
- end
2148
-
2149
- let(:context) do
2150
- criteria.context
2151
- end
2152
-
2153
- before do
2154
- expect(context).to receive(:preload).twice.and_call_original
2155
- end
2156
-
2157
- let!(:documents) do
2158
- criteria.entries
2159
- end
2160
-
2161
- it "returns the correct documents" do
2162
- expect(criteria).to eq([ game_one, game_two ])
2163
- end
2164
- end
2165
-
2166
- context "when the criteria has limiting options" do
2167
-
2168
- let!(:criteria) do
2169
- Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
2170
- end
2171
-
2172
- let(:context) do
2173
- criteria.context
2174
- end
2175
-
2176
- before do
2177
- expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
2178
- end
2179
-
2180
- let!(:documents) do
2181
- criteria.entries
2182
- end
2183
-
2184
- it "returns the correct documents" do
2185
- expect(documents).to eq([ game_one ])
2186
- end
2187
- end
2188
- end
2189
-
2190
- context "when including multiples in the same criteria" do
2191
-
2192
- let!(:post_one) do
2193
- person.posts.create(title: "one")
2194
- end
2195
-
2196
- let!(:post_two) do
2197
- person.posts.create(title: "two")
2198
- end
2199
-
2200
- let!(:game_one) do
2201
- person.create_game(name: "one")
2202
- end
2203
-
2204
- let!(:game_two) do
2205
- person.create_game(name: "two")
2206
- end
2207
-
2208
- let!(:criteria) do
2209
- Person.includes(:posts, :game).asc(:age)
2210
- end
2211
-
2212
- let(:context) do
2213
- criteria.context
2214
- end
2215
-
2216
- before do
2217
- expect(context).to receive(:preload).twice.and_call_original
2218
- end
2219
-
2220
- let!(:documents) do
2221
- criteria.entries
2222
- end
2223
-
2224
- it "returns the correct documents" do
2225
- expect(criteria).to eq([ person ])
2226
- end
2227
- end
2228
- end
2229
-
2230
- describe "#inclusions" do
2231
-
2232
- let(:criteria) do
2233
- Band.includes(:records)
2234
- end
2235
-
2236
- let(:association) do
2237
- Band.relations["records"]
2238
- end
2239
-
2240
- it "returns the inclusions" do
2241
- expect(criteria.inclusions).to eq([ association ])
2242
- end
2243
- end
2244
-
2245
- describe "#inclusions=" do
2246
-
2247
- let(:criteria) do
2248
- Band.all
2249
- end
2250
-
2251
- let(:association) do
2252
- Band.relations["records"]
2253
- end
2254
-
2255
- before do
2256
- criteria.inclusions = [ association ]
2257
- end
2258
-
2259
- it "sets the inclusions" do
2260
- expect(criteria.inclusions).to eq([ association ])
2261
- end
2262
- end
2263
-
2264
- describe "#lt" do
2265
-
2266
- let!(:match) do
2267
- Band.create(member_count: 1)
2268
- end
2269
-
2270
- let!(:non_match) do
2271
- Band.create(member_count: 5)
2272
- end
2273
-
2274
- let(:criteria) do
2275
- Band.lt(member_count: 4)
2276
- end
2277
-
2278
- it "returns the matching documents" do
2279
- expect(criteria).to eq([ match ])
2280
- end
2281
- end
2282
-
2283
- describe "#lte" do
2284
-
2285
- let!(:match) do
2286
- Band.create(member_count: 4)
2287
- end
2288
-
2289
- let!(:non_match) do
2290
- Band.create(member_count: 5)
2291
- end
2292
-
2293
- let(:criteria) do
2294
- Band.lte(member_count: 4)
2295
- end
2296
-
2297
- it "returns the matching documents" do
2298
- expect(criteria).to eq([ match ])
2299
- end
2300
- end
2301
-
2302
- describe "#map_reduce" do
2303
-
2304
- let(:map) do
2305
- %Q{
2306
- function() {
2307
- emit(this.name, { likes: this.likes });
2308
- }}
2309
- end
2310
-
2311
- let(:reduce) do
2312
- %Q{
2313
- function(key, values) {
2314
- var result = { likes: 0 };
2315
- values.forEach(function(value) {
2316
- result.likes += value.likes;
2317
- });
2318
- return result;
2319
- }}
2320
- end
2321
-
2322
- let!(:depeche_mode) do
2323
- Band.create(name: "Depeche Mode", likes: 200)
2324
- end
2325
-
2326
- let!(:tool) do
2327
- Band.create(name: "Tool", likes: 100)
2328
- end
2329
-
2330
- context "when no timeout options are provided" do
2331
-
2332
- let(:map_reduce) do
2333
- Band.limit(2).map_reduce(map, reduce).out(inline: 1)
2334
- end
2335
-
2336
- it "returns the map/reduce results" do
2337
- expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
2338
- { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
2339
- { "_id" => "Tool", "value" => { "likes" => 100 }}
2340
- ])
2341
- end
2342
- end
2343
- end
2344
-
2345
- describe "#max" do
2346
-
2347
- context "when provided a single field" do
2348
-
2349
- let!(:depeche) do
2350
- Band.create(name: "Depeche Mode", likes: 1000)
2351
- end
2352
-
2353
- let!(:tool) do
2354
- Band.create(name: "Tool", likes: 500)
2355
- end
2356
-
2357
- let(:criteria) do
2358
- Band.all
2359
- end
2360
-
2361
- context "when provided a symbol" do
2362
-
2363
- let(:max) do
2364
- criteria.max(:likes)
2365
- end
2366
-
2367
- it "returns the max of the provided field" do
2368
- expect(max).to eq(1000)
2369
- end
2370
- end
2371
-
2372
- context "when provided a block" do
2373
-
2374
- let(:max) do
2375
- criteria.max do |a, b|
2376
- a.likes <=> b.likes
2377
- end
2378
- end
2379
-
2380
- it "returns the document with the max value for the field" do
2381
- expect(max).to eq(depeche)
2382
- end
2383
- end
2384
- end
2385
- end
2386
-
2387
- describe "#max_distance" do
2388
-
2389
- before do
2390
- Bar.create_indexes
2391
- end
2392
-
2393
- let!(:match) do
2394
- Bar.create(location: [ 52.30, 13.25 ])
2395
- end
2396
-
2397
- let!(:non_match) do
2398
- Bar.create(location: [ 19.26, 99.70 ])
2399
- end
2400
-
2401
- let(:criteria) do
2402
- Bar.near(location: [ 52, 13 ]).max_distance(location: 5)
2403
- end
2404
-
2405
- it "returns the matching documents" do
2406
- expect(criteria).to eq([ match ])
2407
- end
2408
- end
2409
-
2410
- describe "#merge" do
2411
-
2412
- let(:band) do
2413
- Band.new
2414
- end
2415
-
2416
- let(:criteria) do
2417
- Band.scoped.where(name: "Depeche Mode").asc(:name)
2418
- end
2419
-
2420
- context "when merging with another criteria" do
2421
-
2422
- let(:mergeable) do
2423
- Band.includes(:records).tap do |crit|
2424
- crit.documents = [ band ]
2425
- end
2426
- end
2427
-
2428
- let(:association) do
2429
- Band.relations["records"]
2430
- end
2431
-
2432
- let(:merged) do
2433
- criteria.merge(mergeable)
2434
- end
2435
-
2436
- it "merges the selector" do
2437
- expect(merged.selector).to eq({ "name" => "Depeche Mode" })
2438
- end
2439
-
2440
- it "merges the options" do
2441
- expect(merged.options).to eq({ sort: { "name" => 1 }})
2442
- end
2443
-
2444
- it "merges the documents" do
2445
- expect(merged.documents).to eq([ band ])
2446
- end
2447
-
2448
- it "merges the scoping options" do
2449
- expect(merged.scoping_options).to eq([ nil, nil ])
2450
- end
2451
-
2452
- it "merges the inclusions" do
2453
- expect(merged.inclusions).to eq([ association ])
2454
- end
2455
-
2456
- it "returns a new criteria" do
2457
- expect(merged).to_not equal(criteria)
2458
- end
2459
- end
2460
-
2461
- context "when merging with a hash" do
1427
+ context "when merging with a hash" do
2462
1428
 
2463
1429
  let(:mergeable) do
2464
1430
  { klass: Band, includes: [ :records ] }
@@ -2548,11 +1514,11 @@ describe Mongoid::Criteria do
2548
1514
  context "when provided a single field" do
2549
1515
 
2550
1516
  let!(:depeche) do
2551
- Band.create(name: "Depeche Mode", likes: 1000)
1517
+ Band.create!(name: "Depeche Mode", likes: 1000)
2552
1518
  end
2553
1519
 
2554
1520
  let!(:tool) do
2555
- Band.create(name: "Tool", likes: 500)
1521
+ Band.create!(name: "Tool", likes: 500)
2556
1522
  end
2557
1523
 
2558
1524
  let(:criteria) do
@@ -2588,11 +1554,11 @@ describe Mongoid::Criteria do
2588
1554
  describe "#mod" do
2589
1555
 
2590
1556
  let!(:match) do
2591
- Band.create(member_count: 5)
1557
+ Band.create!(member_count: 5)
2592
1558
  end
2593
1559
 
2594
1560
  let!(:non_match) do
2595
- Band.create(member_count: 2)
1561
+ Band.create!(member_count: 2)
2596
1562
  end
2597
1563
 
2598
1564
  let(:criteria) do
@@ -2607,11 +1573,11 @@ describe Mongoid::Criteria do
2607
1573
  describe "#ne" do
2608
1574
 
2609
1575
  let!(:match) do
2610
- Band.create(name: "Depeche Mode")
1576
+ Band.create!(name: "Depeche Mode")
2611
1577
  end
2612
1578
 
2613
1579
  let!(:non_match) do
2614
- Band.create(name: "Tool")
1580
+ Band.create!(name: "Tool")
2615
1581
  end
2616
1582
 
2617
1583
  let(:criteria) do
@@ -2629,287 +1595,73 @@ describe Mongoid::Criteria do
2629
1595
  Bar.create_indexes
2630
1596
  end
2631
1597
 
2632
- let!(:match) do
2633
- Bar.create(location: [ 52.30, 13.25 ])
2634
- end
2635
-
2636
- let(:criteria) do
2637
- Bar.near(location: [ 52, 13 ])
2638
- end
2639
-
2640
- it "returns the matching documents" do
2641
- expect(criteria).to eq([ match ])
2642
- end
2643
- end
2644
-
2645
- describe "#near_sphere" do
2646
-
2647
- before do
2648
- Bar.create_indexes
2649
- end
2650
-
2651
- let!(:match) do
2652
- Bar.create(location: [ 52.30, 13.25 ])
2653
- end
2654
-
2655
- let(:criteria) do
2656
- Bar.near_sphere(location: [ 52, 13 ])
2657
- end
2658
-
2659
- it "returns the matching documents" do
2660
- expect(criteria).to eq([ match ])
2661
- end
2662
- end
2663
-
2664
- describe "#nin" do
2665
-
2666
- let!(:match) do
2667
- Band.create(name: "Depeche Mode")
2668
- end
2669
-
2670
- let!(:non_match) do
2671
- Band.create(name: "Tool")
2672
- end
2673
-
2674
- let(:criteria) do
2675
- Band.nin(name: [ "Tool" ])
2676
- end
2677
-
2678
- it "returns the matching documents" do
2679
- expect(criteria).to eq([ match ])
2680
- end
2681
- end
2682
-
2683
- describe "#nor" do
2684
-
2685
- let!(:match) do
2686
- Band.create(name: "Depeche Mode")
2687
- end
2688
-
2689
- let!(:non_match) do
2690
- Band.create(name: "Tool")
2691
- end
2692
-
2693
- let(:criteria) do
2694
- Band.nor({ name: "Tool" }, { name: "New Order" })
2695
- end
2696
-
2697
- it "returns the matching documents" do
2698
- expect(criteria).to eq([ match ])
2699
- end
2700
- end
2701
-
2702
- describe "#only" do
2703
-
2704
- let!(:band) do
2705
- Band.create(name: "Depeche Mode", likes: 3, views: 10)
2706
- end
2707
-
2708
- context "when not using inheritance" do
2709
-
2710
- context "when passing splat args" do
2711
-
2712
- let(:criteria) do
2713
- Band.only(:_id)
2714
- end
2715
-
2716
- it "limits the returned fields" do
2717
- expect {
2718
- criteria.first.name
2719
- }.to raise_error(ActiveModel::MissingAttributeError)
2720
- end
2721
-
2722
- it "does not add _type to the fields" do
2723
- expect(criteria.options[:fields]["_type"]).to be_nil
2724
- end
2725
- end
2726
-
2727
- context "when not including id" do
2728
-
2729
- let(:criteria) do
2730
- Band.only(:name)
2731
- end
2732
-
2733
- it "responds to id anyway" do
2734
- expect {
2735
- criteria.first.id
2736
- }.to_not raise_error
2737
- end
2738
- end
2739
-
2740
- context "when passing an array" do
2741
-
2742
- let(:criteria) do
2743
- Band.only([ :name, :likes ])
2744
- end
2745
-
2746
- it "includes the limited fields" do
2747
- expect(criteria.first.name).to_not be_nil
2748
- end
2749
-
2750
- it "excludes the non included fields" do
2751
- expect {
2752
- criteria.first.active
2753
- }.to raise_error(ActiveModel::MissingAttributeError)
2754
- end
2755
-
2756
- it "does not add _type to the fields" do
2757
- expect(criteria.options[:fields]["_type"]).to be_nil
2758
- end
2759
- end
2760
-
2761
- context "when instantiating a class of another type inside the iteration" do
2762
-
2763
- let(:criteria) do
2764
- Band.only(:name)
2765
- end
2766
-
2767
- it "only limits the fields on the correct model" do
2768
- criteria.each do |band|
2769
- expect(Person.new.age).to eq(100)
2770
- end
2771
- end
2772
- end
2773
-
2774
- context "when instantiating a document not in the result set" do
2775
-
2776
- let(:criteria) do
2777
- Band.only(:name)
2778
- end
2779
-
2780
- it "only limits the fields on the correct criteria" do
2781
- criteria.each do |band|
2782
- expect(Band.new.active).to be true
2783
- end
2784
- end
2785
- end
2786
-
2787
- context "when nesting a criteria within a criteria" do
2788
-
2789
- let(:criteria) do
2790
- Band.only(:name)
2791
- end
2792
-
2793
- it "only limits the fields on the correct criteria" do
2794
- criteria.each do |band|
2795
- Band.all.each do |b|
2796
- expect(b.active).to be true
2797
- end
2798
- end
2799
- end
2800
- end
2801
- end
2802
-
2803
- context "when using inheritance" do
2804
-
2805
- let(:criteria) do
2806
- Doctor.only(:_id)
2807
- end
2808
-
2809
- it "adds _type to the fields" do
2810
- expect(criteria.options[:fields]["_type"]).to eq(1)
2811
- end
2812
- end
2813
-
2814
- context "when limiting to embedded documents" do
2815
-
2816
- context "when the embedded documents are aliased" do
2817
-
2818
- let(:criteria) do
2819
- Person.only(:phones)
2820
- end
2821
-
2822
- it "properly uses the database field name" do
2823
- expect(criteria.options).to eq(fields: { "_id" => 1, "mobile_phones" => 1 })
2824
- end
2825
- end
2826
- end
2827
-
2828
- context 'when the field is localized' do
2829
-
2830
- before do
2831
- I18n.locale = :en
2832
- d = Dictionary.create(description: 'english-text')
2833
- I18n.locale = :de
2834
- d.description = 'deutsch-text'
2835
- d.save
2836
- end
2837
-
2838
- after do
2839
- I18n.locale = :en
2840
- end
1598
+ let!(:match) do
1599
+ Bar.create!(location: [ 52.30, 13.25 ])
1600
+ end
2841
1601
 
2842
- context 'when entire field is included' do
1602
+ let(:criteria) do
1603
+ Bar.near(location: [ 52, 13 ])
1604
+ end
2843
1605
 
2844
- let(:dictionary) do
2845
- Dictionary.only(:description).first
1606
+ it "returns the matching documents" do
1607
+ expect(criteria).to eq([ match ])
1608
+ end
1609
+ end
2846
1610
 
2847
- end
1611
+ describe "#near_sphere" do
2848
1612
 
2849
- it 'loads all translations' do
2850
- expect(dictionary.description_translations.keys).to include('de', 'en')
2851
- end
1613
+ before do
1614
+ Bar.create_indexes
1615
+ end
2852
1616
 
2853
- it 'returns the field value for the current locale' do
2854
- I18n.locale = :en
2855
- expect(dictionary.description).to eq('english-text')
2856
- I18n.locale = :de
2857
- expect(dictionary.description).to eq('deutsch-text')
2858
- end
2859
- end
1617
+ let!(:match) do
1618
+ Bar.create!(location: [ 52.30, 13.25 ])
1619
+ end
2860
1620
 
2861
- context 'when a specific locale is included' do
1621
+ let(:criteria) do
1622
+ Bar.near_sphere(location: [ 52, 13 ])
1623
+ end
2862
1624
 
2863
- let(:dictionary) do
2864
- Dictionary.only(:'description.de').first
2865
- end
1625
+ it "returns the matching documents" do
1626
+ expect(criteria).to eq([ match ])
1627
+ end
1628
+ end
2866
1629
 
2867
- it 'loads translations only for the included locale' do
2868
- expect(dictionary.description_translations.keys).to include('de')
2869
- expect(dictionary.description_translations.keys).to_not include('en')
2870
- end
1630
+ describe "#nin" do
2871
1631
 
2872
- it 'returns the field value for the included locale' do
2873
- I18n.locale = :en
2874
- expect(dictionary.description).to be_nil
2875
- I18n.locale = :de
2876
- expect(dictionary.description).to eq('deutsch-text')
2877
- end
2878
- end
1632
+ let!(:match) do
1633
+ Band.create!(name: "Depeche Mode")
1634
+ end
2879
1635
 
2880
- context 'when entire field is excluded' do
1636
+ let!(:non_match) do
1637
+ Band.create!(name: "Tool")
1638
+ end
2881
1639
 
2882
- let(:dictionary) do
2883
- Dictionary.without(:description).first
2884
- end
1640
+ let(:criteria) do
1641
+ Band.nin(name: [ "Tool" ])
1642
+ end
2885
1643
 
2886
- it 'does not load all translations' do
2887
- expect(dictionary.description_translations.keys).to_not include('de', 'en')
2888
- end
1644
+ it "returns the matching documents" do
1645
+ expect(criteria).to eq([ match ])
1646
+ end
1647
+ end
2889
1648
 
2890
- it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
2891
- expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
2892
- end
2893
- end
1649
+ describe "#nor" do
2894
1650
 
2895
- context 'when a specific locale is excluded' do
1651
+ let!(:match) do
1652
+ Band.create!(name: "Depeche Mode")
1653
+ end
2896
1654
 
2897
- let(:dictionary) do
2898
- Dictionary.without(:'description.de').first
2899
- end
1655
+ let!(:non_match) do
1656
+ Band.create!(name: "Tool")
1657
+ end
2900
1658
 
2901
- it 'does not load excluded translations' do
2902
- expect(dictionary.description_translations.keys).to_not include('de')
2903
- expect(dictionary.description_translations.keys).to include('en')
2904
- end
1659
+ let(:criteria) do
1660
+ Band.nor({ name: "Tool" }, { name: "New Order" })
1661
+ end
2905
1662
 
2906
- it 'returns nil for excluded translations' do
2907
- I18n.locale = :en
2908
- expect(dictionary.description).to eq('english-text')
2909
- I18n.locale = :de
2910
- expect(dictionary.description).to be_nil
2911
- end
2912
- end
1663
+ it "returns the matching documents" do
1664
+ expect(criteria).to eq([ match ])
2913
1665
  end
2914
1666
  end
2915
1667
 
@@ -2918,11 +1670,11 @@ describe Mongoid::Criteria do
2918
1670
  describe "\##{method}" do
2919
1671
 
2920
1672
  let!(:match) do
2921
- Band.create(name: "Depeche Mode")
1673
+ Band.create!(name: "Depeche Mode")
2922
1674
  end
2923
1675
 
2924
1676
  let!(:non_match) do
2925
- Band.create(name: "Tool")
1677
+ Band.create!(name: "Tool")
2926
1678
  end
2927
1679
 
2928
1680
  context "when sending a normal $or criterion" do
@@ -2952,25 +1704,29 @@ describe Mongoid::Criteria do
2952
1704
  describe "#pluck" do
2953
1705
 
2954
1706
  let!(:depeche) do
2955
- Band.create(name: "Depeche Mode", likes: 3)
1707
+ Band.create!(name: "Depeche Mode", likes: 3)
2956
1708
  end
2957
1709
 
2958
1710
  let!(:tool) do
2959
- Band.create(name: "Tool", likes: 3)
1711
+ Band.create!(name: "Tool", likes: 3)
2960
1712
  end
2961
1713
 
2962
1714
  let!(:photek) do
2963
- Band.create(name: "Photek", likes: 1)
1715
+ Band.create!(name: "Photek", likes: 1)
1716
+ end
1717
+
1718
+ let(:maniacs) do
1719
+ Band.create!(name: "10,000 Maniacs", likes: 1, sales: "1E2")
2964
1720
  end
2965
1721
 
2966
1722
  context "when the field is aliased" do
2967
1723
 
2968
1724
  let!(:expensive) do
2969
- Product.create(price: 100000)
1725
+ Product.create!(price: 100000)
2970
1726
  end
2971
1727
 
2972
1728
  let!(:cheap) do
2973
- Product.create(price: 1)
1729
+ Product.create!(price: 1)
2974
1730
  end
2975
1731
 
2976
1732
  context "when using alias_attribute" do
@@ -2979,8 +1735,10 @@ describe Mongoid::Criteria do
2979
1735
  Product.pluck(:price)
2980
1736
  end
2981
1737
 
2982
- it "uses the aliases" do
2983
- expect(plucked).to eq([ 100000, 1 ])
1738
+ with_config_values :legacy_pluck_distinct, true, false do
1739
+ it "uses the aliases" do
1740
+ expect(plucked).to eq([ 100000, 1 ])
1741
+ end
2984
1742
  end
2985
1743
  end
2986
1744
  end
@@ -2997,14 +1755,18 @@ describe Mongoid::Criteria do
2997
1755
  criteria.pluck(:name)
2998
1756
  end
2999
1757
 
3000
- it "returns the values" do
3001
- expect(plucked).to contain_exactly("Depeche Mode", "Tool", "Photek")
1758
+ with_config_values :legacy_pluck_distinct, true, false do
1759
+ it "returns the values" do
1760
+ expect(plucked).to contain_exactly("Depeche Mode", "Tool", "Photek")
1761
+ end
3002
1762
  end
3003
1763
 
3004
1764
  context "when subsequently executing the criteria without a pluck" do
3005
1765
 
3006
- it "does not limit the fields" do
3007
- expect(criteria.first.likes).to eq(3)
1766
+ with_config_values :legacy_pluck_distinct, true, false do
1767
+ it "does not limit the fields" do
1768
+ expect(criteria.first.likes).to eq(3)
1769
+ end
3008
1770
  end
3009
1771
  end
3010
1772
 
@@ -3015,51 +1777,83 @@ describe Mongoid::Criteria do
3015
1777
  end
3016
1778
 
3017
1779
  context 'when a top-level field and a subdocument field are plucked' do
3018
-
3019
1780
  before do
3020
- Band.create(name: 'FKA Twigs')
3021
- Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1781
+ Band.create!(name: 'FKA Twigs')
1782
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
3022
1783
  end
3023
1784
 
3024
1785
  let(:embedded_pluck) do
3025
1786
  criteria.pluck(:name, 'records.name')
3026
1787
  end
3027
1788
 
3028
- let(:expected) do
3029
- [
3030
- ["FKA Twigs", nil],
3031
- ['FKA Twigs', [{ "name" => "LP1" }]]
3032
- ]
1789
+ context "when legacy_pluck_distinct is set" do
1790
+ config_override :legacy_pluck_distinct, true
1791
+ let(:expected) do
1792
+ [
1793
+ ["FKA Twigs", nil],
1794
+ ['FKA Twigs', [{ "name" => "LP1" }]]
1795
+ ]
1796
+ end
1797
+
1798
+ it 'returns the list of top-level field and subdocument values' do
1799
+ expect(embedded_pluck).to eq(expected)
1800
+ end
3033
1801
  end
3034
1802
 
3035
- it 'returns the list of top-level field and subdocument values' do
3036
- expect(embedded_pluck). to eq(expected)
1803
+ context "when legacy_pluck_distinct is not set" do
1804
+ config_override :legacy_pluck_distinct, false
1805
+ let(:expected) do
1806
+ [
1807
+ ["FKA Twigs", nil],
1808
+ ['FKA Twigs', ["LP1"]]
1809
+ ]
1810
+ end
1811
+
1812
+ it 'returns the list of top-level field and subdocument values' do
1813
+ expect(embedded_pluck).to eq(expected)
1814
+ end
3037
1815
  end
3038
1816
  end
3039
1817
 
3040
1818
  context 'when only a subdocument field is plucked' do
3041
1819
 
3042
1820
  before do
3043
- Band.create(name: 'FKA Twigs')
3044
- Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1821
+ Band.create!(name: 'FKA Twigs')
1822
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
3045
1823
  end
3046
1824
 
3047
1825
  let(:embedded_pluck) do
3048
1826
  criteria.pluck('records.name')
3049
1827
  end
3050
1828
 
3051
- let(:expected) do
3052
- [
3053
- nil,
3054
- [{ "name" => "LP1" }]
3055
- ]
1829
+ context "when legacy_pluck_distinct is set" do
1830
+ config_override :legacy_pluck_distinct, true
1831
+ let(:expected) do
1832
+ [
1833
+ nil,
1834
+ [{ "name" => "LP1" }]
1835
+ ]
1836
+ end
1837
+
1838
+ it 'returns the list of subdocument values' do
1839
+ expect(embedded_pluck).to eq(expected)
1840
+ end
3056
1841
  end
3057
1842
 
3058
- it 'returns the list of subdocument values' do
3059
- expect(embedded_pluck). to eq(expected)
1843
+ context "when legacy_pluck_distinct is not set" do
1844
+ config_override :legacy_pluck_distinct, false
1845
+ let(:expected) do
1846
+ [
1847
+ nil,
1848
+ ["LP1"]
1849
+ ]
1850
+ end
1851
+
1852
+ it 'returns the list of subdocument values' do
1853
+ expect(embedded_pluck).to eq(expected)
1854
+ end
3060
1855
  end
3061
1856
  end
3062
-
3063
1857
  end
3064
1858
  end
3065
1859
 
@@ -3069,8 +1863,10 @@ describe Mongoid::Criteria do
3069
1863
  Band.where(:name.exists => true).pluck(:name, :likes)
3070
1864
  end
3071
1865
 
3072
- it "returns the values" do
3073
- expect(plucked).to contain_exactly(["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
1866
+ with_config_values :legacy_pluck_distinct, true, false do
1867
+ it "returns the values" do
1868
+ expect(plucked).to contain_exactly(["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
1869
+ end
3074
1870
  end
3075
1871
  end
3076
1872
 
@@ -3080,8 +1876,10 @@ describe Mongoid::Criteria do
3080
1876
  Band.where(:name.exists => true).pluck(:likes)
3081
1877
  end
3082
1878
 
3083
- it "returns the duplicates" do
3084
- expect(plucked).to contain_exactly(3, 3, 1)
1879
+ with_config_values :legacy_pluck_distinct, true, false do
1880
+ it "returns the duplicates" do
1881
+ expect(plucked).to contain_exactly(3, 3, 1)
1882
+ end
3085
1883
  end
3086
1884
  end
3087
1885
  end
@@ -3092,8 +1890,10 @@ describe Mongoid::Criteria do
3092
1890
  Band.where(name: "New Order").pluck(:_id)
3093
1891
  end
3094
1892
 
3095
- it "returns an empty array" do
3096
- expect(plucked).to be_empty
1893
+ with_config_values :legacy_pluck_distinct, true, false do
1894
+ it "returns an empty array" do
1895
+ expect(plucked).to be_empty
1896
+ end
3097
1897
  end
3098
1898
  end
3099
1899
 
@@ -3103,8 +1903,10 @@ describe Mongoid::Criteria do
3103
1903
  Band.all.pluck(:id)
3104
1904
  end
3105
1905
 
3106
- it "returns the field values" do
3107
- expect(plucked).to eq([ depeche.id, tool.id, photek.id ])
1906
+ with_config_values :legacy_pluck_distinct, true, false do
1907
+ it "returns the field values" do
1908
+ expect(plucked).to eq([ depeche.id, tool.id, photek.id ])
1909
+ end
3108
1910
  end
3109
1911
  end
3110
1912
 
@@ -3114,8 +1916,10 @@ describe Mongoid::Criteria do
3114
1916
  Band.all.pluck(:id, :fooz)
3115
1917
  end
3116
1918
 
3117
- it "returns nil for the field that doesnt exist" do
3118
- expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil] ])
1919
+ with_config_values :legacy_pluck_distinct, true, false do
1920
+ it "returns nil for the field that doesnt exist" do
1921
+ expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil] ])
1922
+ end
3119
1923
  end
3120
1924
  end
3121
1925
 
@@ -3127,8 +1931,10 @@ describe Mongoid::Criteria do
3127
1931
  Band.all.pluck(:foo)
3128
1932
  end
3129
1933
 
3130
- it "returns a array with nil values" do
3131
- expect(plucked).to eq([nil, nil, nil])
1934
+ with_config_values :legacy_pluck_distinct, true, false do
1935
+ it "returns an array with nil values" do
1936
+ expect(plucked).to eq([nil, nil, nil])
1937
+ end
3132
1938
  end
3133
1939
  end
3134
1940
 
@@ -3138,8 +1944,10 @@ describe Mongoid::Criteria do
3138
1944
  Band.all.pluck(:foo, :bar)
3139
1945
  end
3140
1946
 
3141
- it "returns a nil arrays" do
3142
- expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
1947
+ with_config_values :legacy_pluck_distinct, true, false do
1948
+ it "returns an array of arrays with nil values" do
1949
+ expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
1950
+ end
3143
1951
  end
3144
1952
  end
3145
1953
  end
@@ -3148,10 +1956,10 @@ describe Mongoid::Criteria do
3148
1956
 
3149
1957
  before do
3150
1958
  I18n.locale = :en
3151
- d = Dictionary.create(description: 'english-text')
1959
+ d = Dictionary.create!(description: 'english-text')
3152
1960
  I18n.locale = :de
3153
1961
  d.description = 'deutsch-text'
3154
- d.save
1962
+ d.save!
3155
1963
  end
3156
1964
 
3157
1965
  after do
@@ -3159,25 +1967,370 @@ describe Mongoid::Criteria do
3159
1967
  end
3160
1968
 
3161
1969
  context 'when plucking the entire field' do
3162
-
3163
1970
  let(:plucked) do
3164
1971
  Dictionary.all.pluck(:description)
3165
1972
  end
3166
1973
 
3167
- it 'returns all translations' do
3168
- expect(plucked.first).to eq({'en' => 'english-text', 'de' => 'deutsch-text'})
3169
- end
1974
+ let(:plucked_translations) do
1975
+ Dictionary.all.pluck(:description_translations)
1976
+ end
1977
+
1978
+ let(:plucked_translations_both) do
1979
+ Dictionary.all.pluck(:description_translations, :description)
1980
+ end
1981
+
1982
+ context "when legacy_pluck_distinct is set" do
1983
+ config_override :legacy_pluck_distinct, true
1984
+
1985
+ it 'returns the non-demongoized translations' do
1986
+ expect(plucked.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
1987
+ end
1988
+
1989
+ it 'returns nil' do
1990
+ expect(plucked_translations.first).to eq(nil)
1991
+ end
1992
+
1993
+ it 'returns nil for _translations' do
1994
+ expect(plucked_translations_both.first).to eq([nil, {"de"=>"deutsch-text", "en"=>"english-text"}])
1995
+ end
1996
+ end
1997
+
1998
+ context "when legacy_pluck_distinct is not set" do
1999
+ config_override :legacy_pluck_distinct, false
2000
+
2001
+ it 'returns the demongoized translations' do
2002
+ expect(plucked.first).to eq('deutsch-text')
2003
+ end
2004
+
2005
+ it 'returns the full translations hash to _translations' do
2006
+ expect(plucked_translations.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
2007
+ end
2008
+
2009
+ it 'returns both' do
2010
+ expect(plucked_translations_both.first).to eq([{"de"=>"deutsch-text", "en"=>"english-text"}, "deutsch-text"])
2011
+ end
2012
+ end
2013
+ end
2014
+
2015
+ context 'when plucking a specific locale' do
2016
+
2017
+ let(:plucked) do
2018
+ Dictionary.all.pluck(:'description.de')
2019
+ end
2020
+
2021
+ context "when legacy_pluck_distinct is set" do
2022
+ config_override :legacy_pluck_distinct, true
2023
+
2024
+ it 'returns the specific translations' do
2025
+ expect(plucked.first).to eq({'de' => 'deutsch-text'})
2026
+ end
2027
+ end
2028
+
2029
+ context "when legacy_pluck_distinct is not set" do
2030
+ config_override :legacy_pluck_distinct, false
2031
+
2032
+ it 'returns the specific translations' do
2033
+ expect(plucked.first).to eq('deutsch-text')
2034
+ end
2035
+ end
2036
+ end
2037
+
2038
+ context 'when plucking a specific locale from _translations field' do
2039
+
2040
+ let(:plucked) do
2041
+ Dictionary.all.pluck(:'description_translations.de')
2042
+ end
2043
+
2044
+ context "when legacy_pluck_distinct is set" do
2045
+ config_override :legacy_pluck_distinct, true
2046
+
2047
+ it 'returns the specific translations' do
2048
+ expect(plucked.first).to eq(nil)
2049
+ end
2050
+ end
2051
+
2052
+ context "when legacy_pluck_distinct is not set" do
2053
+ config_override :legacy_pluck_distinct, false
2054
+
2055
+ it 'returns the specific translations' do
2056
+ expect(plucked.first).to eq('deutsch-text')
2057
+ end
2058
+ end
2059
+ end
2060
+
2061
+ context 'when fallbacks are enabled with a locale list' do
2062
+ with_i18n_fallbacks
2063
+
2064
+ around(:all) do |example|
2065
+ prev_fallbacks = I18n.fallbacks.dup
2066
+ I18n.fallbacks[:he] = [ :en ]
2067
+ example.run
2068
+ I18n.fallbacks = prev_fallbacks
2069
+ end
2070
+
2071
+ let(:plucked) do
2072
+ Dictionary.all.pluck(:description).first
2073
+ end
2074
+
2075
+ context "when legacy_pluck_distinct is set" do
2076
+ config_override :legacy_pluck_distinct, true
2077
+
2078
+ it "does not correctly use the fallback" do
2079
+ plucked.should == {"de"=>"deutsch-text", "en"=>"english-text"}
2080
+ end
2081
+ end
2082
+
2083
+ context "when legacy_pluck_distinct is not set" do
2084
+ config_override :legacy_pluck_distinct, false
2085
+
2086
+ it "correctly uses the fallback" do
2087
+ I18n.locale = :en
2088
+ d = Dictionary.create!(description: 'english-text')
2089
+ I18n.locale = :he
2090
+ plucked.should == "english-text"
2091
+ end
2092
+ end
2093
+ end
2094
+
2095
+ context "when the localized field is embedded" do
2096
+ before do
2097
+ p = Passport.new
2098
+ I18n.locale = :en
2099
+ p.name = "Neil"
2100
+ I18n.locale = :he
2101
+ p.name = "Nissim"
2102
+
2103
+ Person.create!(passport: p, employer_id: 12345)
2104
+ end
2105
+
2106
+ let(:plucked) do
2107
+ Person.where(employer_id: 12345).pluck("pass.name").first
2108
+ end
2109
+
2110
+ let(:plucked_translations) do
2111
+ Person.where(employer_id: 12345).pluck("pass.name_translations").first
2112
+ end
2113
+
2114
+ let(:plucked_translations_field) do
2115
+ Person.where(employer_id: 12345).pluck("pass.name_translations.en").first
2116
+ end
2117
+
2118
+ context "when legacy_pluck_distinct is set" do
2119
+ config_override :legacy_pluck_distinct, true
2120
+
2121
+ it "returns the full hash embedded" do
2122
+ expect(plucked).to eq({ "name" => { "en" => "Neil", "he" => "Nissim" } })
2123
+ end
2124
+
2125
+ it "returns the empty hash" do
2126
+ expect(plucked_translations).to eq({})
2127
+ end
2128
+
2129
+ it "returns the empty hash" do
2130
+ expect(plucked_translations_field).to eq({})
2131
+ end
2132
+ end
2133
+
2134
+ context "when legacy_pluck_distinct is not set" do
2135
+ config_override :legacy_pluck_distinct, false
2136
+
2137
+ it "returns the translation for the current locale" do
2138
+ expect(plucked).to eq("Nissim")
2139
+ end
2140
+
2141
+ it "returns the full _translation hash" do
2142
+ expect(plucked_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
2143
+ end
2144
+
2145
+ it "returns the translation for the requested locale" do
2146
+ expect(plucked_translations_field).to eq("Neil")
2147
+ end
2148
+ end
2149
+ end
2150
+ end
2151
+
2152
+ context 'when plucking a field to be demongoized' do
2153
+
2154
+ let(:plucked) do
2155
+ Band.where(name: maniacs.name).pluck(:sales)
2156
+ end
2157
+
2158
+ context "when legacy_pluck_distinct is set" do
2159
+ config_override :legacy_pluck_distinct, true
2160
+
2161
+ context 'when value is stored as string' do
2162
+ config_override :map_big_decimal_to_decimal128, false
2163
+
2164
+ it "does not demongoize the field" do
2165
+ expect(plucked.first).to be_a(String)
2166
+ expect(plucked.first).to eq("1E2")
2167
+ end
2168
+ end
2169
+
2170
+ context 'when value is stored as decimal128' do
2171
+ config_override :map_big_decimal_to_decimal128, true
2172
+ max_bson_version '4.99.99'
2173
+
2174
+ it "does not demongoize the field" do
2175
+ expect(plucked.first).to be_a(BSON::Decimal128)
2176
+ expect(plucked.first).to eq(BSON::Decimal128.new("1E2"))
2177
+ end
2178
+ end
2179
+ end
2180
+
2181
+ context "when legacy_pluck_distinct is not set" do
2182
+ config_override :legacy_pluck_distinct, false
2183
+
2184
+ context 'when value is stored as string' do
2185
+ config_override :map_big_decimal_to_decimal128, false
2186
+
2187
+ it "demongoizes the field" do
2188
+ expect(plucked.first).to be_a(BigDecimal)
2189
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2190
+ end
2191
+ end
2192
+
2193
+ context 'when value is stored as decimal128' do
2194
+ config_override :map_big_decimal_to_decimal128, true
2195
+
2196
+ it "demongoizes the field" do
2197
+ expect(plucked.first).to be_a(BigDecimal)
2198
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2199
+ end
2200
+ end
2201
+ end
2202
+ end
2203
+
2204
+ context "when plucking an embedded field" do
2205
+ let(:label) { Label.new(sales: "1E2") }
2206
+ let!(:band) { Band.create!(label: label) }
2207
+
2208
+ let(:plucked) { Band.where(_id: band.id).pluck("label.sales") }
2209
+
2210
+ context "when legacy_pluck_distinct is set" do
2211
+ config_override :legacy_pluck_distinct, true
2212
+ config_override :map_big_decimal_to_decimal128, true
2213
+ max_bson_version '4.99.99'
2214
+
2215
+ it "returns a hash with a non-demongoized field" do
2216
+ expect(plucked.first).to eq({ 'sales' => BSON::Decimal128.new('1E+2') })
2217
+ end
2218
+ end
2219
+
2220
+ context "when legacy_pluck_distinct is not set" do
2221
+ config_override :legacy_pluck_distinct, false
2222
+
2223
+ it "demongoizes the field" do
2224
+ expect(plucked).to eq([ BigDecimal("1E2") ])
2225
+ end
2226
+ end
2227
+ end
2228
+
2229
+ context "when plucking an embeds_many field" do
2230
+ let(:label) { Label.new(sales: "1E2") }
2231
+ let!(:band) { Band.create!(labels: [label]) }
2232
+
2233
+ let(:plucked) { Band.where(_id: band.id).pluck("labels.sales") }
2234
+
2235
+ context "when legacy_pluck_distinct is set" do
2236
+ config_override :legacy_pluck_distinct, true
2237
+ config_override :map_big_decimal_to_decimal128, true
2238
+ max_bson_version '4.99.99'
2239
+
2240
+ it "returns a hash with a non-demongoized field" do
2241
+ expect(plucked.first).to eq([{ 'sales' => BSON::Decimal128.new('1E+2') }])
2242
+ end
2243
+ end
2244
+
2245
+ context "when legacy_pluck_distinct is not set" do
2246
+ config_override :legacy_pluck_distinct, false
2247
+
2248
+ it "demongoizes the field" do
2249
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
2250
+ end
2251
+ end
2252
+ end
2253
+
2254
+ context "when plucking a nonexistent embedded field" do
2255
+ let(:label) { Label.new(sales: "1E2") }
2256
+ let!(:band) { Band.create!(label: label) }
2257
+
2258
+ let(:plucked) { Band.where(_id: band.id).pluck("label.qwerty") }
2259
+
2260
+ context "when legacy_pluck_distinct is set" do
2261
+ config_override :legacy_pluck_distinct, true
2262
+
2263
+ it "returns an empty hash" do
2264
+ expect(plucked.first).to eq({})
2265
+ end
2266
+ end
2267
+
2268
+ context "when legacy_pluck_distinct is not set" do
2269
+ config_override :legacy_pluck_distinct, false
2270
+
2271
+ it "returns nil" do
2272
+ expect(plucked.first).to eq(nil)
2273
+ end
2274
+ end
2275
+ end
2276
+
2277
+ context "when tallying deeply nested arrays/embedded associations" do
2278
+
2279
+ before do
2280
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2281
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2282
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2283
+ end
2284
+
2285
+ let(:plucked) do
2286
+ Person.pluck("addresses.code.deepest.array.y.z")
2287
+ end
2288
+
2289
+ it "returns the correct hash" do
2290
+ expect(plucked).to eq([
2291
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2292
+ ])
2293
+ end
2294
+ end
2295
+ end
2296
+
2297
+ describe "#pick" do
2298
+
2299
+ let!(:depeche) do
2300
+ Band.create!(name: "Depeche Mode", likes: 3)
2301
+ end
2302
+
2303
+ let!(:tool) do
2304
+ Band.create!(name: "Tool", likes: 3)
2305
+ end
2306
+
2307
+ context "when picking a field" do
2308
+
2309
+ let(:criteria) do
2310
+ Band.all
2311
+ end
2312
+
2313
+ let(:picked) do
2314
+ criteria.pick(:name)
2315
+ end
2316
+
2317
+ it "returns one element" do
2318
+ expect(picked).to eq("Depeche Mode")
3170
2319
  end
2320
+ end
3171
2321
 
3172
- context 'when plucking a specific locale' do
2322
+ context "when picking multiple fields" do
3173
2323
 
3174
- let(:plucked) do
3175
- Dictionary.all.pluck(:'description.de')
3176
- end
2324
+ let(:criteria) do
2325
+ Band.all
2326
+ end
3177
2327
 
3178
- it 'returns the specific translations' do
3179
- expect(plucked.first).to eq({'de' => 'deutsch-text'})
3180
- end
2328
+ let(:picked) do
2329
+ criteria.pick(:name, :likes)
2330
+ end
2331
+
2332
+ it "returns an array" do
2333
+ expect(picked).to eq([ "Depeche Mode", 3 ])
3181
2334
  end
3182
2335
  end
3183
2336
  end
@@ -3263,11 +2416,11 @@ describe Mongoid::Criteria do
3263
2416
  describe "#sort" do
3264
2417
 
3265
2418
  let!(:depeche) do
3266
- Band.create(name: "Depeche Mode", likes: 1000)
2419
+ Band.create!(name: "Depeche Mode", likes: 1000)
3267
2420
  end
3268
2421
 
3269
2422
  let!(:tool) do
3270
- Band.create(name: "Tool", likes: 500)
2423
+ Band.create!(name: "Tool", likes: 500)
3271
2424
  end
3272
2425
 
3273
2426
  let(:sorted) do
@@ -3286,11 +2439,11 @@ describe Mongoid::Criteria do
3286
2439
  context "when provided a single field" do
3287
2440
 
3288
2441
  let!(:depeche) do
3289
- Band.create(name: "Depeche Mode", likes: 1000)
2442
+ Band.create!(name: "Depeche Mode", likes: 1000)
3290
2443
  end
3291
2444
 
3292
2445
  let!(:tool) do
3293
- Band.create(name: "Tool", likes: 500)
2446
+ Band.create!(name: "Tool", likes: 500)
3294
2447
  end
3295
2448
 
3296
2449
  let(:criteria) do
@@ -3324,7 +2477,7 @@ describe Mongoid::Criteria do
3324
2477
  describe "#to_ary" do
3325
2478
 
3326
2479
  let!(:band) do
3327
- Band.create(name: "Depeche Mode")
2480
+ Band.create!(name: "Depeche Mode")
3328
2481
  end
3329
2482
 
3330
2483
  let(:criteria) do
@@ -3340,11 +2493,11 @@ describe Mongoid::Criteria do
3340
2493
  max_server_version '4.0'
3341
2494
 
3342
2495
  let!(:band) do
3343
- Band.create(name: "Depeche Mode")
2496
+ Band.create!(name: "Depeche Mode")
3344
2497
  end
3345
2498
 
3346
2499
  let!(:band2) do
3347
- Band.create(name: "Tool")
2500
+ Band.create!(name: "Tool")
3348
2501
  end
3349
2502
 
3350
2503
  let(:criteria) do
@@ -3383,34 +2536,75 @@ describe Mongoid::Criteria do
3383
2536
  end
3384
2537
 
3385
2538
  describe "#type" do
2539
+ context "when using the default discriminator_key" do
2540
+ context "when the type is a string" do
3386
2541
 
3387
- context "when the type is a string" do
2542
+ let!(:browser) do
2543
+ Browser.create!
2544
+ end
3388
2545
 
3389
- let!(:browser) do
3390
- Browser.create
3391
- end
2546
+ let(:criteria) do
2547
+ Canvas.all.type("Browser")
2548
+ end
3392
2549
 
3393
- let(:criteria) do
3394
- Canvas.all.type("Browser")
2550
+ it "returns documents with the provided type" do
2551
+ expect(criteria).to eq([ browser ])
2552
+ end
3395
2553
  end
3396
2554
 
3397
- it "returns documents with the provided type" do
3398
- expect(criteria).to eq([ browser ])
2555
+ context "when the type is an Array of type" do
2556
+
2557
+ let!(:browser) do
2558
+ Firefox.create!
2559
+ end
2560
+
2561
+ let(:criteria) do
2562
+ Canvas.all.type([ "Browser", "Firefox" ])
2563
+ end
2564
+
2565
+ it "returns documents with the provided types" do
2566
+ expect(criteria).to eq([ browser ])
2567
+ end
3399
2568
  end
3400
2569
  end
3401
2570
 
3402
- context "when the type is an Array of type" do
2571
+ context "when using a custom discriminator_key" do
2572
+ before do
2573
+ Canvas.discriminator_key = "dkey"
2574
+ end
3403
2575
 
3404
- let!(:browser) do
3405
- Firefox.create
2576
+ after do
2577
+ Canvas.discriminator_key = nil
3406
2578
  end
3407
2579
 
3408
- let(:criteria) do
3409
- Canvas.all.type([ "Browser", "Firefox" ])
2580
+ context "when the type is a string" do
2581
+
2582
+ let!(:browser) do
2583
+ Browser.create!
2584
+ end
2585
+
2586
+ let(:criteria) do
2587
+ Canvas.all.type("Browser")
2588
+ end
2589
+
2590
+ it "returns documents with the provided type" do
2591
+ expect(criteria).to eq([ browser ])
2592
+ end
3410
2593
  end
3411
2594
 
3412
- it "returns documents with the provided types" do
3413
- expect(criteria).to eq([ browser ])
2595
+ context "when the type is an Array of type" do
2596
+
2597
+ let!(:browser) do
2598
+ Firefox.create!
2599
+ end
2600
+
2601
+ let(:criteria) do
2602
+ Canvas.all.type([ "Browser", "Firefox" ])
2603
+ end
2604
+
2605
+ it "returns documents with the provided types" do
2606
+ expect(criteria).to eq([ browser ])
2607
+ end
3414
2608
  end
3415
2609
  end
3416
2610
  end
@@ -3418,11 +2612,43 @@ describe Mongoid::Criteria do
3418
2612
  describe "#where" do
3419
2613
 
3420
2614
  let!(:match) do
3421
- Band.create(name: "Depeche Mode")
2615
+ Band.create!(name: "Depeche Mode")
3422
2616
  end
3423
2617
 
3424
2618
  let!(:non_match) do
3425
- Band.create(name: "Tool")
2619
+ Band.create!(name: "Tool")
2620
+ end
2621
+
2622
+ context 'when provided no arguments' do
2623
+ context 'on a model class' do
2624
+ it 'returns an empty criteria' do
2625
+ Band.where.selector.should == {}
2626
+ end
2627
+ end
2628
+
2629
+ context 'on an association' do
2630
+ it 'returns an empty criteria' do
2631
+ match.records.where.selector.should == {}
2632
+ end
2633
+ end
2634
+ end
2635
+
2636
+ context 'when provided multiple arguments' do
2637
+ context 'on a model class' do
2638
+ it 'raises ArgumentError' do
2639
+ lambda do
2640
+ Band.where({foo: 1}, {bar: 2})
2641
+ end.should raise_error(ArgumentError, /where requires zero or one arguments/)
2642
+ end
2643
+ end
2644
+
2645
+ context 'on an association' do
2646
+ it 'raises ArgumentError' do
2647
+ lambda do
2648
+ match.records.where({foo: 1}, {bar: 2})
2649
+ end.should raise_error(ArgumentError, /where requires zero or one arguments/)
2650
+ end
2651
+ end
3426
2652
  end
3427
2653
 
3428
2654
  context "when provided a string" do
@@ -3482,20 +2708,109 @@ describe Mongoid::Criteria do
3482
2708
 
3483
2709
  context "when querying on a big decimal" do
3484
2710
 
3485
- let(:sales) do
3486
- BigDecimal('0.1')
2711
+ context 'when map_big_decimal_to_decimal128 is false' do
2712
+ config_override :map_big_decimal_to_decimal128, false
2713
+
2714
+ let(:sales) do
2715
+ BigDecimal('0.1')
2716
+ end
2717
+
2718
+ let!(:band) do
2719
+ Band.create!(name: "Boards of Canada", sales: sales)
2720
+ end
2721
+
2722
+ let(:from_db) do
2723
+ Band.where(sales: sales).first
2724
+ end
2725
+
2726
+ it "finds the document by the big decimal value" do
2727
+ expect(from_db).to eq(band)
2728
+ end
3487
2729
  end
3488
2730
 
3489
- let!(:band) do
3490
- Band.create(name: "Boards of Canada", sales: sales)
2731
+ context 'when map_big_decimal_to_decimal128 is true' do
2732
+ config_override :map_big_decimal_to_decimal128, true
2733
+
2734
+ let(:sales) do
2735
+ BigDecimal('0.1')
2736
+ end
2737
+
2738
+ let!(:band) do
2739
+ Band.create!(name: "Boards of Canada", sales: sales)
2740
+ end
2741
+
2742
+ let(:from_db) do
2743
+ Band.where(sales: sales).first
2744
+ end
2745
+
2746
+ it "finds the document by the big decimal value" do
2747
+ expect(from_db).to eq(band)
2748
+ end
3491
2749
  end
3492
2750
 
3493
- let(:from_db) do
3494
- Band.where(sales: sales).first
2751
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2752
+ config_override :map_big_decimal_to_decimal128, false
2753
+
2754
+ let(:sales) do
2755
+ BigDecimal('0.1')
2756
+ end
2757
+
2758
+ let!(:band) do
2759
+ Mongoid.map_big_decimal_to_decimal128 = false
2760
+ Band.create!(name: "Boards of Canada", sales: sales)
2761
+ end
2762
+
2763
+ let(:from_db) do
2764
+ Mongoid.map_big_decimal_to_decimal128 = true
2765
+ Band.where(sales: sales.to_s).first
2766
+ end
2767
+
2768
+ it "finds the document by the big decimal value" do
2769
+ expect(from_db).to eq(band)
2770
+ end
3495
2771
  end
2772
+ end
3496
2773
 
3497
- it "finds the document by the big decimal value" do
3498
- expect(from_db).to eq(band)
2774
+ context "when querying on a big decimal from a dynamic field" do
2775
+
2776
+ context 'when map_big_decimal_to_decimal128 is false' do
2777
+ config_override :map_big_decimal_to_decimal128, false
2778
+
2779
+ let(:fans) do
2780
+ BigDecimal('139432.0002')
2781
+ end
2782
+
2783
+ let!(:band) do
2784
+ Band.create!(name: "Boards of Canada", fans: fans)
2785
+ end
2786
+
2787
+ let(:from_db) do
2788
+ Band.where(fans: fans.to_s).first
2789
+ end
2790
+
2791
+ it "finds the document by the big decimal value" do
2792
+ expect(from_db).to eq(band)
2793
+ end
2794
+ end
2795
+
2796
+ context 'when map_big_decimal_to_decimal128 is true' do
2797
+ config_override :map_big_decimal_to_decimal128, true
2798
+
2799
+ let(:fans) do
2800
+ BigDecimal('139432.0002')
2801
+ end
2802
+
2803
+ let!(:band) do
2804
+ Band.create!(name: "Boards of Canada", fans: fans)
2805
+ end
2806
+
2807
+ let(:from_db) do
2808
+ Band.where(fans: fans).first
2809
+ end
2810
+
2811
+ it "only finds the document by the string value" do
2812
+ expect(from_db).to eq(band)
2813
+ end
3499
2814
  end
3500
2815
  end
3501
2816
 
@@ -3507,7 +2822,7 @@ describe Mongoid::Criteria do
3507
2822
  end
3508
2823
 
3509
2824
  let!(:band) do
3510
- Band.create(name: "Boards of Canada", decimal: decimal)
2825
+ Band.create!(name: "Boards of Canada", decimal: decimal)
3511
2826
  end
3512
2827
 
3513
2828
  let(:from_db) do
@@ -3522,7 +2837,7 @@ describe Mongoid::Criteria do
3522
2837
  context 'when querying on a polymorphic relation' do
3523
2838
 
3524
2839
  let(:movie) do
3525
- Movie.create
2840
+ Movie.create!
3526
2841
  end
3527
2842
 
3528
2843
  let(:selector) do
@@ -3534,12 +2849,289 @@ describe Mongoid::Criteria do
3534
2849
  end
3535
2850
  end
3536
2851
  end
2852
+
2853
+ context 'when given multiple keys in separate calls' do
2854
+ let(:criteria) { Band.where(foo: 1).where(bar: 2) }
2855
+
2856
+ it 'combines criteria' do
2857
+ expect(criteria.selector).to eq('foo' => 1, 'bar' => 2)
2858
+ end
2859
+ end
2860
+
2861
+ context 'when given same key in separate calls' do
2862
+ let(:criteria) { Band.where(foo: 1).where(foo: 2) }
2863
+
2864
+ it 'combines criteria' do
2865
+ expect(criteria.selector).to eq('foo' => 1, '$and' => [{'foo' => 2}])
2866
+ end
2867
+ end
2868
+
2869
+ context 'when given same key in separate calls and there are other criteria' do
2870
+ let(:criteria) { Band.where(foo: 1, bar: 3).where(foo: 2) }
2871
+
2872
+ it 'combines criteria' do
2873
+ expect(criteria.selector).to eq(
2874
+ 'foo' => 1, '$and' => [{'foo' => 2}], 'bar' => 3)
2875
+ end
2876
+ end
2877
+
2878
+ context 'when given same key in separate calls and other criteria are added later' do
2879
+ let(:criteria) { Band.where(foo: 1).where(foo: 2).where(bar: 3) }
2880
+
2881
+ it 'combines criteria' do
2882
+ expect(criteria.selector).to eq(
2883
+ 'foo' => 1, '$and' => [{'foo' => 2}], 'bar' => 3)
2884
+ end
2885
+ end
2886
+
2887
+ context "when duplicating where conditions" do
2888
+ let(:criteria) { Sound.where(active: true).where(active: true) }
2889
+
2890
+ it 'does not duplicate criteria' do
2891
+ expect(criteria.selector).to eq('active' => true)
2892
+ end
2893
+ end
2894
+
2895
+ context "when duplicating where conditions with different values" do
2896
+ let(:criteria) { Sound.where(active: true).where(active: false).where(active: true).where(active: false) }
2897
+
2898
+ it 'does not duplicate criteria' do
2899
+ expect(criteria.selector).to eq(
2900
+ 'active' => true, '$and' => [{'active' => false}])
2901
+ end
2902
+ end
2903
+
2904
+ # Used to test MONGOID-5251 where the find command was adding unnecessary
2905
+ # and clauses. Since the find command creates the criteria and executes it,
2906
+ # it is difficult to analyze the criteria used. For this reason, I have
2907
+ # extracted the crux of the issue, adding an _id to the the criteria twice,
2908
+ # and used that for the test case.
2909
+ context "when searching by _id twice" do
2910
+ let(:_id) { BSON::ObjectId.new }
2911
+ let(:criteria) { Band.where(_id: _id) }
2912
+ let(:dup_criteria) { criteria.where(_id: _id)}
2913
+
2914
+ it "does not duplicate the criteria" do
2915
+ expect(dup_criteria.selector).to eq({ "_id" => _id })
2916
+ end
2917
+ end
2918
+
2919
+ context "when querying an embedded field" do
2920
+ let(:criteria) { Band.where("label.name": 12345) }
2921
+
2922
+ it "mongoizes the embedded field in the selector" do
2923
+ expect(criteria.selector).to eq("label.name" => "12345")
2924
+ end
2925
+ end
2926
+
2927
+ context "when querying with a range" do
2928
+
2929
+ context "when querying an embeds_many association" do
2930
+ let(:criteria) do
2931
+ Band.where("labels" => 10..15)
2932
+ end
2933
+
2934
+ it "correctly uses elemMatch without an inner key" do
2935
+ expect(criteria.selector).to eq(
2936
+ "labels" => {
2937
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2938
+ }
2939
+ )
2940
+ end
2941
+ end
2942
+
2943
+ context "when querying an element in an embeds_many association" do
2944
+ let(:criteria) do
2945
+ Band.where("labels.age" => 10..15)
2946
+ end
2947
+
2948
+ it "correctly uses elemMatch" do
2949
+ expect(criteria.selector).to eq(
2950
+ "labels" => {
2951
+ "$elemMatch" => {
2952
+ "age" => { "$gte" => 10, "$lte" => 15 }
2953
+ }
2954
+ }
2955
+ )
2956
+ end
2957
+ end
2958
+
2959
+ context "when querying a field of type array" do
2960
+ let(:criteria) do
2961
+ Band.where("genres" => 10..15)
2962
+ end
2963
+
2964
+ it "correctly uses elemMatch without an inner key" do
2965
+ expect(criteria.selector).to eq(
2966
+ "genres" => {
2967
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2968
+ }
2969
+ )
2970
+ end
2971
+ end
2972
+
2973
+ context "when querying an aliased field of type array" do
2974
+ let(:criteria) do
2975
+ Person.where("array" => 10..15)
2976
+ end
2977
+
2978
+ it "correctly uses the aliased field and elemMatch" do
2979
+ expect(criteria.selector).to eq(
2980
+ "a" => {
2981
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2982
+ }
2983
+ )
2984
+ end
2985
+ end
2986
+
2987
+ context "when querying a field inside an array" do
2988
+ let(:criteria) do
2989
+ Band.where("genres.age" => 10..15)
2990
+ end
2991
+
2992
+ it "correctly uses elemMatch" do
2993
+ expect(criteria.selector).to eq(
2994
+ "genres" => {
2995
+ "$elemMatch" => {
2996
+ "age" => { "$gte" => 10, "$lte" => 15 }
2997
+ }
2998
+ }
2999
+ )
3000
+ end
3001
+ end
3002
+
3003
+ context "when there are no embeds_manys or Arrays" do
3004
+ let(:criteria) do
3005
+ Band.where("fans.info.age" => 10..15)
3006
+ end
3007
+
3008
+ it "does not use elemMatch" do
3009
+ expect(criteria.selector).to eq(
3010
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
3011
+ )
3012
+ end
3013
+ end
3014
+
3015
+ context "when querying a nested element in an embeds_many association" do
3016
+ let(:criteria) do
3017
+ Band.where("labels.age.number" => 10..15)
3018
+ end
3019
+
3020
+ it "correctly uses elemMatch" do
3021
+ expect(criteria.selector).to eq(
3022
+ "labels" => {
3023
+ "$elemMatch" => {
3024
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
3025
+ }
3026
+ }
3027
+ )
3028
+ end
3029
+ end
3030
+
3031
+ context "when querying a nested element in an Array" do
3032
+ let(:criteria) do
3033
+ Band.where("genres.name.length" => 10..15)
3034
+ end
3035
+
3036
+ it "correctly uses elemMatch" do
3037
+ expect(criteria.selector).to eq(
3038
+ "genres" => {
3039
+ "$elemMatch" => {
3040
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3041
+ }
3042
+ }
3043
+ )
3044
+ end
3045
+ end
3046
+
3047
+ context "when querying a nested element in a nested embeds_many association" do
3048
+ context "when the outer association is an embeds_many" do
3049
+ let(:criteria) do
3050
+ Band.where("records.tracks.name.length" => 10..15)
3051
+ end
3052
+
3053
+ it "correctly uses elemMatch" do
3054
+ expect(criteria.selector).to eq(
3055
+ "records.tracks" => {
3056
+ "$elemMatch" => {
3057
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3058
+ }
3059
+ }
3060
+ )
3061
+ end
3062
+ end
3063
+
3064
+ context "when the outer association is an embeds_one" do
3065
+ let(:criteria) do
3066
+ Person.where("name.translations.language.length" => 10..15)
3067
+ end
3068
+
3069
+ it "correctly uses elemMatch" do
3070
+ expect(criteria.selector).to eq(
3071
+ "name.translations" => {
3072
+ "$elemMatch" => {
3073
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
3074
+ }
3075
+ }
3076
+ )
3077
+ end
3078
+ end
3079
+ end
3080
+
3081
+ context "when querying a deeply nested array" do
3082
+ let(:criteria) do
3083
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
3084
+ end
3085
+
3086
+ it "correctly uses elemMatch" do
3087
+ expect(criteria.selector).to eq(
3088
+ "addresses.code.deepest.array" => {
3089
+ "$elemMatch" => {
3090
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
3091
+ }
3092
+ }
3093
+ )
3094
+ end
3095
+ end
3096
+
3097
+ context "when there are multiple conditions" do
3098
+ let(:criteria) do
3099
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
3100
+ end
3101
+
3102
+ it "correctly combines the conditions" do
3103
+ expect(criteria.selector).to eq("$or" => [
3104
+ { "labels" => {
3105
+ "$elemMatch" => {
3106
+ "age" => { "$gte" => 10, "$lte" => 15 }
3107
+ } } },
3108
+ { "labels" => 8 }
3109
+ ])
3110
+ end
3111
+ end
3112
+
3113
+ context "when the association is aliased" do
3114
+ let(:criteria) do
3115
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
3116
+ end
3117
+
3118
+ it "correctly uses the aliased association" do
3119
+ expect(criteria.selector).to eq(
3120
+ "pass.passport_pages" => {
3121
+ "$elemMatch" => {
3122
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
3123
+ }
3124
+ }
3125
+ )
3126
+ end
3127
+ end
3128
+ end
3537
3129
  end
3538
3130
 
3539
3131
  describe "#for_js" do
3540
3132
 
3541
3133
  let!(:match) do
3542
- Band.create(name: "Depeche Mode")
3134
+ Band.create!(name: "Depeche Mode")
3543
3135
  end
3544
3136
 
3545
3137
  context "when the code has no scope" do
@@ -3576,10 +3168,14 @@ describe Mongoid::Criteria do
3576
3168
 
3577
3169
  before do
3578
3170
  expect(Person).to receive(:minor).and_call_original
3171
+ expect(Person).to receive(:older_than).and_call_original
3579
3172
  end
3580
3173
 
3581
3174
  it "calls the method on the class" do
3582
3175
  expect(criteria.minor).to be_empty
3176
+ expect do
3177
+ criteria.older_than(age: 25)
3178
+ end.not_to raise_error
3583
3179
  end
3584
3180
  end
3585
3181
 
@@ -3622,11 +3218,11 @@ describe Mongoid::Criteria do
3622
3218
  describe "#uniq" do
3623
3219
 
3624
3220
  let!(:band_one) do
3625
- Band.create(name: "New Order")
3221
+ Band.create!(name: "New Order")
3626
3222
  end
3627
3223
 
3628
3224
  let!(:band_two) do
3629
- Band.create(name: "New Order")
3225
+ Band.create!(name: "New Order")
3630
3226
  end
3631
3227
 
3632
3228
  let(:criteria) do
@@ -3666,7 +3262,7 @@ describe Mongoid::Criteria do
3666
3262
  end
3667
3263
  end
3668
3264
 
3669
- describe "#geo_spacial" do
3265
+ describe "#geo_spatial" do
3670
3266
 
3671
3267
  context "when checking within a polygon" do
3672
3268
 
@@ -3675,11 +3271,11 @@ describe Mongoid::Criteria do
3675
3271
  end
3676
3272
 
3677
3273
  let!(:match) do
3678
- Bar.create(location: [ 52.30, 13.25 ])
3274
+ Bar.create!(location: [ 52.30, 13.25 ])
3679
3275
  end
3680
3276
 
3681
3277
  let(:criteria) do
3682
- Bar.geo_spacial(
3278
+ Bar.geo_spatial(
3683
3279
  :location.within_polygon => [[[ 50, 10 ], [ 50, 20 ], [ 60, 20 ], [ 60, 10 ], [ 50, 10 ]]]
3684
3280
  )
3685
3281
  end
@@ -3693,11 +3289,11 @@ describe Mongoid::Criteria do
3693
3289
  describe "#with_size" do
3694
3290
 
3695
3291
  let!(:match) do
3696
- Band.create(genres: [ "electro", "dub" ])
3292
+ Band.create!(genres: [ "electro", "dub" ])
3697
3293
  end
3698
3294
 
3699
3295
  let!(:non_match) do
3700
- Band.create(genres: [ "house" ])
3296
+ Band.create!(genres: [ "house" ])
3701
3297
  end
3702
3298
 
3703
3299
  let(:criteria) do
@@ -3712,7 +3308,7 @@ describe Mongoid::Criteria do
3712
3308
  describe "#with_type" do
3713
3309
 
3714
3310
  let!(:match) do
3715
- Band.create(name: "Depeche Mode")
3311
+ Band.create!(name: "Depeche Mode")
3716
3312
  end
3717
3313
 
3718
3314
  let(:criteria) do
@@ -3724,73 +3320,76 @@ describe Mongoid::Criteria do
3724
3320
  end
3725
3321
  end
3726
3322
 
3727
- describe "#without" do
3323
+ describe "#type_selection" do
3324
+ context "when using the default discriminator_key" do
3325
+ context "when only one subclass exists" do
3728
3326
 
3729
- let!(:person) do
3730
- Person.create!(username: "davinci", age: 50, pets: false)
3731
- end
3327
+ let(:criteria) do
3328
+ described_class.new(Firefox)
3329
+ end
3732
3330
 
3733
- context "when omitting to embedded documents" do
3331
+ let(:selection) do
3332
+ criteria.send(:type_selection)
3333
+ end
3334
+
3335
+ it "does not use an $in query" do
3336
+ expect(selection).to eq({ _type: "Firefox" })
3337
+ end
3338
+ end
3734
3339
 
3735
- context "when the embedded documents are aliased" do
3340
+ context "when more than one subclass exists" do
3736
3341
 
3737
3342
  let(:criteria) do
3738
- Person.without(:phones)
3343
+ described_class.new(Browser)
3739
3344
  end
3740
3345
 
3741
- it "properly uses the database field name" do
3742
- expect(criteria.options).to eq(fields: { "mobile_phones" => 0 })
3346
+ let(:selection) do
3347
+ criteria.send(:type_selection)
3743
3348
  end
3744
- end
3745
- end
3746
3349
 
3747
- context "when excluding id" do
3748
-
3749
- let(:criteria) do
3750
- Person.without(:_id, :id, "_id", "id")
3350
+ it "does not use an $in query" do
3351
+ expect(selection).to eq({ _type: { "$in" => [ "Firefox", "Browser" ]}})
3352
+ end
3751
3353
  end
3354
+ end
3752
3355
 
3753
- it "does not raise error" do
3754
- expect {
3755
- criteria.first.id
3756
- }.to_not raise_error
3356
+ context "when using a custom discriminator_key" do
3357
+ before do
3358
+ Canvas.discriminator_key = "dkey"
3757
3359
  end
3758
3360
 
3759
- it "returns id anyway" do
3760
- expect(criteria.first.id).to_not be_nil
3361
+ after do
3362
+ Canvas.discriminator_key = nil
3761
3363
  end
3762
- end
3763
- end
3764
-
3765
- describe "#type_selection" do
3766
3364
 
3767
- context "when only one subclass exists" do
3365
+ context "when only one subclass exists" do
3768
3366
 
3769
- let(:criteria) do
3770
- described_class.new(Firefox)
3771
- end
3367
+ let(:criteria) do
3368
+ described_class.new(Firefox)
3369
+ end
3772
3370
 
3773
- let(:selection) do
3774
- criteria.send(:type_selection)
3775
- end
3371
+ let(:selection) do
3372
+ criteria.send(:type_selection)
3373
+ end
3776
3374
 
3777
- it "does not use an $in query" do
3778
- expect(selection).to eq({ _type: "Firefox" })
3375
+ it "does not use an $in query" do
3376
+ expect(selection).to eq({ dkey: "Firefox" })
3377
+ end
3779
3378
  end
3780
- end
3781
3379
 
3782
- context "when more than one subclass exists" do
3380
+ context "when more than one subclass exists" do
3783
3381
 
3784
- let(:criteria) do
3785
- described_class.new(Browser)
3786
- end
3382
+ let(:criteria) do
3383
+ described_class.new(Browser)
3384
+ end
3787
3385
 
3788
- let(:selection) do
3789
- criteria.send(:type_selection)
3790
- end
3386
+ let(:selection) do
3387
+ criteria.send(:type_selection)
3388
+ end
3791
3389
 
3792
- it "does not use an $in query" do
3793
- expect(selection).to eq({ _type: { "$in" => [ "Firefox", "Browser" ]}})
3390
+ it "does not use an $in query" do
3391
+ expect(selection).to eq({ dkey: { "$in" => [ "Firefox", "Browser" ]}})
3392
+ end
3794
3393
  end
3795
3394
  end
3796
3395
  end