mongoid 3.1.5 → 8.0.2

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 (1501) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +636 -33
  4. data/LICENSE +2 -1
  5. data/README.md +32 -24
  6. data/Rakefile +75 -5
  7. data/lib/config/locales/en.yml +301 -132
  8. data/lib/mongoid/association/accessors.rb +431 -0
  9. data/lib/mongoid/association/bindable.rb +227 -0
  10. data/lib/mongoid/association/builders.rb +86 -0
  11. data/lib/mongoid/association/constrainable.rb +42 -0
  12. data/lib/mongoid/association/depending.rb +128 -0
  13. data/lib/mongoid/association/eager_loadable.rb +57 -0
  14. data/lib/mongoid/association/embedded/batchable.rb +398 -0
  15. data/lib/mongoid/association/embedded/cyclic.rb +102 -0
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +74 -0
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +38 -0
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +111 -0
  19. data/lib/mongoid/association/embedded/embedded_in.rb +135 -0
  20. data/lib/mongoid/association/embedded/embeds_many/binding.rb +42 -0
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +45 -0
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +571 -0
  23. data/lib/mongoid/association/embedded/embeds_many.rb +183 -0
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +43 -0
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +53 -0
  26. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +164 -0
  27. data/lib/mongoid/association/embedded/embeds_one.rb +150 -0
  28. data/lib/mongoid/association/embedded.rb +6 -0
  29. data/lib/mongoid/association/macros.rb +228 -0
  30. data/lib/mongoid/association/many.rb +202 -0
  31. data/lib/mongoid/association/marshalable.rb +31 -0
  32. data/lib/mongoid/association/nested/many.rb +192 -0
  33. data/lib/mongoid/association/nested/nested_buildable.rb +66 -0
  34. data/lib/mongoid/association/nested/one.rb +116 -0
  35. data/lib/mongoid/association/nested.rb +15 -0
  36. data/lib/mongoid/association/one.rb +53 -0
  37. data/lib/mongoid/association/options.rb +122 -0
  38. data/lib/mongoid/association/proxy.rb +200 -0
  39. data/lib/mongoid/association/referenced/auto_save.rb +74 -0
  40. data/lib/mongoid/association/referenced/belongs_to/binding.rb +83 -0
  41. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +48 -0
  42. data/lib/mongoid/association/referenced/belongs_to/eager.rb +73 -0
  43. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +124 -0
  44. data/lib/mongoid/association/referenced/belongs_to.rb +226 -0
  45. data/lib/mongoid/association/referenced/counter_cache.rb +152 -0
  46. data/lib/mongoid/association/referenced/eager.rb +163 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +72 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +53 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +345 -0
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +273 -0
  52. data/lib/mongoid/association/referenced/has_many/binding.rb +36 -0
  53. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  54. data/lib/mongoid/association/referenced/has_many/eager.rb +44 -0
  55. data/lib/mongoid/association/referenced/has_many/enumerable.rb +494 -0
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +551 -0
  57. data/lib/mongoid/association/referenced/has_many.rb +251 -0
  58. data/lib/mongoid/association/referenced/has_one/binding.rb +42 -0
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +74 -0
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +36 -0
  61. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +113 -0
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +108 -0
  63. data/lib/mongoid/association/referenced/has_one.rb +184 -0
  64. data/lib/mongoid/association/referenced/syncable.rb +155 -0
  65. data/lib/mongoid/association/referenced.rb +9 -0
  66. data/lib/mongoid/association/reflections.rb +69 -0
  67. data/lib/mongoid/association/relatable.rb +489 -0
  68. data/lib/mongoid/association.rb +135 -0
  69. data/lib/mongoid/atomic/modifiers.rb +41 -61
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +24 -8
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -8
  72. data/lib/mongoid/atomic/paths/embedded.rb +3 -34
  73. data/lib/mongoid/atomic/paths/root.rb +4 -20
  74. data/lib/mongoid/atomic/paths.rb +2 -1
  75. data/lib/mongoid/atomic.rb +52 -69
  76. data/lib/mongoid/attributes/dynamic.rb +141 -0
  77. data/lib/mongoid/attributes/nested.rb +93 -0
  78. data/lib/mongoid/attributes/processing.rb +35 -97
  79. data/lib/mongoid/attributes/projector.rb +119 -0
  80. data/lib/mongoid/attributes/readonly.rb +27 -10
  81. data/lib/mongoid/attributes.rb +159 -181
  82. data/lib/mongoid/cacheable.rb +33 -0
  83. data/lib/mongoid/changeable.rb +420 -0
  84. data/lib/mongoid/clients/factory.rb +105 -0
  85. data/lib/mongoid/clients/options.rb +111 -0
  86. data/lib/mongoid/clients/sessions.rb +113 -0
  87. data/lib/mongoid/clients/storage_options.rb +79 -0
  88. data/lib/mongoid/clients/validators/storage.rb +58 -0
  89. data/lib/mongoid/clients/validators.rb +3 -0
  90. data/lib/mongoid/clients.rb +79 -0
  91. data/lib/mongoid/composable.rb +128 -0
  92. data/lib/mongoid/config/environment.rb +51 -13
  93. data/lib/mongoid/config/options.rb +30 -18
  94. data/lib/mongoid/config/validators/client.rb +128 -0
  95. data/lib/mongoid/config/validators/option.rb +3 -4
  96. data/lib/mongoid/config/validators.rb +3 -2
  97. data/lib/mongoid/config.rb +170 -89
  98. data/lib/mongoid/contextual/aggregable/memory.rb +40 -27
  99. data/lib/mongoid/contextual/aggregable/mongo.rb +33 -36
  100. data/lib/mongoid/contextual/aggregable/none.rb +65 -0
  101. data/lib/mongoid/contextual/aggregable.rb +17 -0
  102. data/lib/mongoid/contextual/atomic.rb +80 -79
  103. data/lib/mongoid/contextual/command.rb +8 -11
  104. data/lib/mongoid/contextual/geo_near.rb +42 -44
  105. data/lib/mongoid/contextual/map_reduce.rb +33 -127
  106. data/lib/mongoid/contextual/memory.rb +226 -88
  107. data/lib/mongoid/contextual/mongo.rb +466 -293
  108. data/lib/mongoid/contextual/none.rb +193 -0
  109. data/lib/mongoid/contextual/queryable.rb +3 -4
  110. data/lib/mongoid/contextual.rb +11 -11
  111. data/lib/mongoid/copyable.rb +68 -20
  112. data/lib/mongoid/criteria/findable.rb +143 -0
  113. data/lib/mongoid/criteria/includable.rb +92 -0
  114. data/lib/mongoid/criteria/inspectable.rb +24 -0
  115. data/lib/mongoid/criteria/marshalable.rb +55 -0
  116. data/lib/mongoid/criteria/modifiable.rb +235 -0
  117. data/lib/mongoid/criteria/options.rb +24 -0
  118. data/lib/mongoid/criteria/permission.rb +71 -0
  119. data/lib/mongoid/criteria/queryable/aggregable.rb +109 -0
  120. data/lib/mongoid/criteria/queryable/expandable.rb +68 -0
  121. data/lib/mongoid/criteria/queryable/extensions/array.rb +151 -0
  122. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +57 -0
  123. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +33 -0
  124. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  125. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +52 -0
  126. data/lib/mongoid/criteria/queryable/extensions/hash.rb +163 -0
  127. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +75 -0
  128. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +81 -0
  129. data/lib/mongoid/criteria/queryable/extensions/object.rb +182 -0
  130. data/lib/mongoid/criteria/queryable/extensions/range.rb +102 -0
  131. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +72 -0
  132. data/lib/mongoid/criteria/queryable/extensions/set.rb +33 -0
  133. data/lib/mongoid/criteria/queryable/extensions/string.rb +122 -0
  134. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +74 -0
  135. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  136. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +66 -0
  137. data/lib/mongoid/criteria/queryable/extensions.rb +25 -0
  138. data/lib/mongoid/criteria/queryable/key.rb +177 -0
  139. data/lib/mongoid/criteria/queryable/macroable.rb +26 -0
  140. data/lib/mongoid/criteria/queryable/mergeable.rb +434 -0
  141. data/lib/mongoid/criteria/queryable/optional.rb +380 -0
  142. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  143. data/lib/mongoid/criteria/queryable/pipeline.rb +106 -0
  144. data/lib/mongoid/criteria/queryable/selectable.rb +937 -0
  145. data/lib/mongoid/criteria/queryable/selector.rb +287 -0
  146. data/lib/mongoid/criteria/queryable/smash.rb +128 -0
  147. data/lib/mongoid/criteria/queryable/storable.rb +237 -0
  148. data/lib/mongoid/criteria/queryable.rb +90 -0
  149. data/lib/mongoid/criteria/scopable.rb +166 -0
  150. data/lib/mongoid/criteria.rb +177 -189
  151. data/lib/mongoid/deprecable.rb +36 -0
  152. data/lib/mongoid/deprecation.rb +25 -0
  153. data/lib/mongoid/document.rb +193 -139
  154. data/lib/mongoid/equality.rb +35 -18
  155. data/lib/mongoid/errors/ambiguous_relationship.rb +5 -6
  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 +22 -0
  160. data/lib/mongoid/errors/document_not_found.rb +36 -21
  161. data/lib/mongoid/errors/empty_config_file.rb +25 -0
  162. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +19 -0
  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 +31 -0
  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 +10 -9
  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 +26 -0
  182. data/lib/mongoid/errors/invalid_query.rb +40 -0
  183. data/lib/mongoid/errors/invalid_relation.rb +61 -0
  184. data/lib/mongoid/errors/invalid_relation_option.rb +28 -0
  185. data/lib/mongoid/errors/invalid_scope.rb +2 -3
  186. data/lib/mongoid/errors/invalid_session_use.rb +21 -0
  187. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -5
  188. data/lib/mongoid/errors/invalid_storage_options.rb +4 -5
  189. data/lib/mongoid/errors/invalid_storage_parent.rb +25 -0
  190. data/lib/mongoid/errors/invalid_time.rb +2 -3
  191. data/lib/mongoid/errors/inverse_not_found.rb +4 -5
  192. data/lib/mongoid/errors/mixed_client_configuration.rb +27 -0
  193. data/lib/mongoid/errors/mixed_relations.rb +2 -3
  194. data/lib/mongoid/errors/mongoid_error.rb +22 -23
  195. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -4
  196. data/lib/mongoid/errors/no_client_config.rb +21 -0
  197. data/lib/mongoid/errors/no_client_database.rb +26 -0
  198. data/lib/mongoid/errors/no_client_hosts.rb +26 -0
  199. data/lib/mongoid/errors/no_clients_config.rb +19 -0
  200. data/lib/mongoid/errors/no_default_client.rb +22 -0
  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 +21 -0
  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 +24 -0
  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 +30 -9
  215. data/lib/mongoid/evolvable.rb +4 -5
  216. data/lib/mongoid/extensions/array.rb +45 -52
  217. data/lib/mongoid/extensions/big_decimal.rb +41 -22
  218. data/lib/mongoid/extensions/binary.rb +42 -0
  219. data/lib/mongoid/extensions/boolean.rb +19 -17
  220. data/lib/mongoid/extensions/date.rb +33 -23
  221. data/lib/mongoid/extensions/date_time.rb +5 -13
  222. data/lib/mongoid/extensions/decimal128.rb +36 -0
  223. data/lib/mongoid/extensions/false_class.rb +5 -8
  224. data/lib/mongoid/extensions/float.rb +11 -16
  225. data/lib/mongoid/extensions/hash.rb +88 -49
  226. data/lib/mongoid/extensions/integer.rb +10 -18
  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 +38 -62
  230. data/lib/mongoid/extensions/object_id.rb +7 -12
  231. data/lib/mongoid/extensions/range.rb +46 -17
  232. data/lib/mongoid/extensions/regexp.rb +15 -8
  233. data/lib/mongoid/extensions/set.rb +17 -15
  234. data/lib/mongoid/extensions/string.rb +40 -80
  235. data/lib/mongoid/extensions/symbol.rb +7 -23
  236. data/lib/mongoid/extensions/time.rb +42 -25
  237. data/lib/mongoid/extensions/time_with_zone.rb +27 -10
  238. data/lib/mongoid/extensions/true_class.rb +5 -8
  239. data/lib/mongoid/extensions.rb +31 -13
  240. data/lib/mongoid/factory.rb +99 -11
  241. data/lib/mongoid/fields/foreign_key.rb +26 -34
  242. data/lib/mongoid/fields/localized.rb +24 -13
  243. data/lib/mongoid/fields/standard.rb +19 -73
  244. data/lib/mongoid/fields/validators/macro.rb +56 -15
  245. data/lib/mongoid/fields/validators.rb +2 -1
  246. data/lib/mongoid/fields.rb +342 -87
  247. data/lib/mongoid/findable.rb +219 -0
  248. data/lib/mongoid/indexable/specification.rb +103 -0
  249. data/lib/mongoid/indexable/validators/options.rb +110 -0
  250. data/lib/mongoid/indexable.rb +148 -0
  251. data/lib/mongoid/inspectable.rb +52 -0
  252. data/lib/mongoid/interceptable.rb +312 -0
  253. data/lib/mongoid/loggable.rb +15 -18
  254. data/lib/mongoid/matchable.rb +23 -0
  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 +115 -0
  287. data/lib/mongoid/persistable/creatable.rb +181 -0
  288. data/lib/mongoid/persistable/deletable.rb +132 -0
  289. data/lib/mongoid/persistable/destroyable.rb +57 -0
  290. data/lib/mongoid/persistable/incrementable.rb +35 -0
  291. data/lib/mongoid/persistable/logical.rb +36 -0
  292. data/lib/mongoid/persistable/poppable.rb +36 -0
  293. data/lib/mongoid/persistable/pullable.rb +50 -0
  294. data/lib/mongoid/persistable/pushable.rb +66 -0
  295. data/lib/mongoid/persistable/renamable.rb +37 -0
  296. data/lib/mongoid/persistable/savable.rb +47 -0
  297. data/lib/mongoid/persistable/settable.rb +93 -0
  298. data/lib/mongoid/persistable/unsettable.rb +36 -0
  299. data/lib/mongoid/persistable/updatable.rb +165 -0
  300. data/lib/mongoid/persistable/upsertable.rb +51 -0
  301. data/lib/mongoid/persistable.rb +305 -0
  302. data/lib/mongoid/persistence_context.rb +239 -0
  303. data/lib/mongoid/positional.rb +72 -0
  304. data/lib/mongoid/query_cache.rb +64 -0
  305. data/lib/mongoid/railtie.rb +35 -78
  306. data/lib/mongoid/railties/controller_runtime.rb +88 -0
  307. data/lib/mongoid/railties/database.rake +18 -25
  308. data/lib/mongoid/reloadable.rb +94 -0
  309. data/lib/mongoid/scopable.rb +324 -0
  310. data/lib/mongoid/selectable.rb +49 -0
  311. data/lib/mongoid/serializable.rb +170 -0
  312. data/lib/mongoid/shardable.rb +130 -0
  313. data/lib/mongoid/stateful.rb +134 -0
  314. data/lib/mongoid/stringified_symbol.rb +52 -0
  315. data/lib/mongoid/tasks/database.rake +38 -0
  316. data/lib/mongoid/tasks/database.rb +194 -0
  317. data/lib/mongoid/threaded/lifecycle.rb +28 -70
  318. data/lib/mongoid/threaded.rb +142 -219
  319. data/lib/mongoid/timestamps/created/short.rb +2 -1
  320. data/lib/mongoid/timestamps/created.rb +9 -5
  321. data/lib/mongoid/timestamps/short.rb +2 -1
  322. data/lib/mongoid/timestamps/timeless.rb +52 -16
  323. data/lib/mongoid/timestamps/updated/short.rb +4 -3
  324. data/lib/mongoid/timestamps/updated.rb +14 -9
  325. data/lib/mongoid/timestamps.rb +4 -3
  326. data/lib/mongoid/touchable.rb +131 -0
  327. data/lib/mongoid/traversable.rb +337 -0
  328. data/lib/mongoid/validatable/associated.rb +47 -0
  329. data/lib/mongoid/validatable/format.rb +21 -0
  330. data/lib/mongoid/validatable/length.rb +21 -0
  331. data/lib/mongoid/validatable/localizable.rb +29 -0
  332. data/lib/mongoid/validatable/macros.rb +89 -0
  333. data/lib/mongoid/validatable/presence.rb +81 -0
  334. data/lib/mongoid/validatable/queryable.rb +29 -0
  335. data/lib/mongoid/validatable/uniqueness.rb +304 -0
  336. data/lib/mongoid/validatable.rb +160 -0
  337. data/lib/mongoid/version.rb +3 -2
  338. data/lib/mongoid/warnings.rb +28 -0
  339. data/lib/mongoid.rb +68 -109
  340. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -2
  341. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +150 -45
  342. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -3
  343. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -4
  344. data/lib/rails/generators/mongoid_generator.rb +5 -41
  345. data/lib/rails/mongoid.rb +6 -129
  346. data/spec/README.md +33 -0
  347. data/spec/config/mongoid.yml +56 -25
  348. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  349. data/spec/integration/app_spec.rb +345 -0
  350. data/spec/integration/associations/belongs_to_spec.rb +33 -0
  351. data/spec/integration/associations/embedded_dirty_spec.rb +57 -0
  352. data/spec/integration/associations/embedded_spec.rb +283 -0
  353. data/spec/integration/associations/embeds_many_spec.rb +219 -0
  354. data/spec/integration/associations/embeds_one_spec.rb +41 -0
  355. data/spec/integration/associations/foreign_key_spec.rb +107 -0
  356. data/spec/integration/associations/foreign_key_spec_models.rb +64 -0
  357. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  358. data/spec/integration/associations/has_many_spec.rb +128 -0
  359. data/spec/integration/associations/has_one_spec.rb +272 -0
  360. data/spec/integration/associations/nested_attributes_assignment_spec.rb +115 -0
  361. data/spec/integration/associations/reverse_population_spec.rb +34 -0
  362. data/spec/integration/associations/reverse_population_spec_models.rb +36 -0
  363. data/spec/integration/associations/scope_option_spec.rb +101 -0
  364. data/spec/integration/atomic/modifiers_spec.rb +116 -0
  365. data/spec/integration/bson_regexp_raw_spec.rb +19 -0
  366. data/spec/integration/callbacks_models.rb +155 -0
  367. data/spec/integration/callbacks_spec.rb +450 -0
  368. data/spec/integration/contextual/empty_spec.rb +141 -0
  369. data/spec/integration/criteria/alias_query_spec.rb +161 -0
  370. data/spec/integration/criteria/date_field_spec.rb +40 -0
  371. data/spec/integration/criteria/default_scope_spec.rb +72 -0
  372. data/spec/integration/criteria/logical_spec.rb +124 -0
  373. data/spec/integration/criteria/range_spec.rb +359 -0
  374. data/spec/integration/criteria/time_with_zone_spec.rb +142 -0
  375. data/spec/integration/discriminator_key_spec.rb +392 -0
  376. data/spec/integration/discriminator_value_spec.rb +206 -0
  377. data/spec/integration/document_spec.rb +51 -0
  378. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  379. data/spec/integration/i18n_fallbacks_spec.rb +89 -0
  380. data/spec/integration/matcher_examples_spec.rb +765 -0
  381. data/spec/integration/matcher_operator_data/all.yml +140 -0
  382. data/spec/integration/matcher_operator_data/and.yml +93 -0
  383. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  384. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  385. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  386. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  387. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  388. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  389. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  390. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  391. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  392. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  393. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  394. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  395. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  396. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  397. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  398. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  399. data/spec/integration/matcher_operator_data/in.yml +210 -0
  400. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  401. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  402. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  403. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  404. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  405. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  406. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  407. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  408. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  409. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  410. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  411. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  412. data/spec/integration/matcher_operator_data/not.yml +196 -0
  413. data/spec/integration/matcher_operator_data/or.yml +137 -0
  414. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  415. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  416. data/spec/integration/matcher_operator_data/size.yml +174 -0
  417. data/spec/integration/matcher_operator_data/type.yml +70 -0
  418. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  419. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  420. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  421. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  422. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  423. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  424. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  425. data/spec/integration/matcher_operator_data/type_decimal.yml +41 -0
  426. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  427. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  428. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  429. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  430. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  431. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  432. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  433. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  434. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  435. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  436. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  437. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  438. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  439. data/spec/integration/matcher_operator_spec.rb +122 -0
  440. data/spec/integration/matcher_spec.rb +283 -0
  441. data/spec/integration/persistence/range_field_spec.rb +350 -0
  442. data/spec/integration/server_query_spec.rb +141 -0
  443. data/spec/integration/shardable_spec.rb +148 -0
  444. data/spec/integration/stringified_symbol_field_spec.rb +203 -0
  445. data/spec/lite_spec_helper.rb +83 -0
  446. data/spec/mongoid/association/accessors_spec.rb +1067 -0
  447. data/spec/mongoid/association/auto_save_spec.rb +403 -0
  448. data/spec/mongoid/association/builders_spec.rb +255 -0
  449. data/spec/mongoid/association/constrainable_spec.rb +117 -0
  450. data/spec/mongoid/association/counter_cache_spec.rb +452 -0
  451. data/spec/mongoid/association/depending_spec.rb +959 -0
  452. data/spec/mongoid/association/eager_spec.rb +282 -0
  453. data/spec/mongoid/association/embedded/cyclic_spec.rb +180 -0
  454. data/spec/mongoid/association/embedded/dirty_spec.rb +67 -0
  455. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +174 -0
  456. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +90 -0
  457. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +619 -0
  458. data/spec/mongoid/association/embedded/embedded_in_spec.rb +903 -0
  459. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +56 -0
  460. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +218 -0
  461. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4863 -0
  462. data/spec/mongoid/association/embedded/embeds_many_models.rb +226 -0
  463. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +63 -0
  464. data/spec/mongoid/association/embedded/embeds_many_spec.rb +932 -0
  465. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +79 -0
  466. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +106 -0
  467. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +1025 -0
  468. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +8 -0
  469. data/spec/mongoid/association/embedded/embeds_one_models.rb +73 -0
  470. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  471. data/spec/mongoid/association/embedded/embeds_one_spec.rb +984 -0
  472. data/spec/mongoid/association/macros_spec.rb +1116 -0
  473. data/spec/mongoid/association/nested/many_spec.rb +232 -0
  474. data/spec/mongoid/association/nested/one_spec.rb +253 -0
  475. data/spec/mongoid/association/options_spec.rb +1323 -0
  476. data/spec/mongoid/association/polymorphic_spec.rb +162 -0
  477. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +244 -0
  478. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +292 -0
  479. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +412 -0
  480. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1388 -0
  481. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  482. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +57 -0
  483. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2046 -0
  484. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +180 -0
  485. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +148 -0
  486. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +196 -0
  487. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +76 -0
  488. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +3836 -0
  489. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +92 -0
  490. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +39 -0
  491. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1104 -0
  492. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +155 -0
  493. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +251 -0
  494. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +290 -0
  495. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2232 -0
  496. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  497. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +4161 -0
  498. data/spec/mongoid/association/referenced/has_many_models.rb +97 -0
  499. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  500. data/spec/mongoid/association/referenced/has_many_spec.rb +1273 -0
  501. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +133 -0
  502. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +159 -0
  503. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +193 -0
  504. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +1248 -0
  505. data/spec/mongoid/association/referenced/has_one_models.rb +113 -0
  506. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  507. data/spec/mongoid/association/referenced/has_one_spec.rb +1383 -0
  508. data/spec/mongoid/association/reflections_spec.rb +92 -0
  509. data/spec/mongoid/association/syncable_spec.rb +513 -0
  510. data/spec/mongoid/association_spec.rb +191 -0
  511. data/spec/mongoid/atomic/modifiers_spec.rb +88 -39
  512. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +10 -49
  513. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +9 -49
  514. data/spec/mongoid/atomic/paths/root_spec.rb +5 -61
  515. data/spec/mongoid/atomic/paths_spec.rb +115 -35
  516. data/spec/mongoid/atomic_spec.rb +89 -42
  517. data/spec/mongoid/attributes/dynamic_spec.rb +152 -0
  518. data/spec/mongoid/attributes/nested_spec.rb +5000 -0
  519. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  520. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  521. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  522. data/spec/mongoid/attributes/projector_spec.rb +40 -0
  523. data/spec/mongoid/attributes/readonly_spec.rb +166 -64
  524. data/spec/mongoid/attributes_spec.rb +1418 -409
  525. data/spec/mongoid/cacheable_spec.rb +114 -0
  526. data/spec/mongoid/changeable_spec.rb +1914 -0
  527. data/spec/mongoid/clients/factory_spec.rb +426 -0
  528. data/spec/mongoid/clients/options_spec.rb +521 -0
  529. data/spec/mongoid/clients/sessions_spec.rb +297 -0
  530. data/spec/mongoid/clients/transactions_spec.rb +415 -0
  531. data/spec/mongoid/clients_spec.rb +1084 -0
  532. data/spec/mongoid/composable_spec.rb +33 -0
  533. data/spec/mongoid/config/environment_spec.rb +138 -17
  534. data/spec/mongoid/config/options_spec.rb +26 -7
  535. data/spec/mongoid/config_spec.rb +607 -93
  536. data/spec/mongoid/contextual/aggregable/memory_spec.rb +433 -153
  537. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  538. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  539. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +221 -56
  540. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  541. data/spec/mongoid/contextual/atomic_spec.rb +577 -162
  542. data/spec/mongoid/contextual/geo_near_spec.rb +104 -38
  543. data/spec/mongoid/contextual/map_reduce_spec.rb +137 -142
  544. data/spec/mongoid/contextual/memory_spec.rb +1880 -269
  545. data/spec/mongoid/contextual/mongo_spec.rb +2523 -601
  546. data/spec/mongoid/contextual/none_spec.rb +123 -0
  547. data/spec/mongoid/copyable_spec.rb +833 -76
  548. data/spec/mongoid/copyable_spec_models.rb +47 -0
  549. data/spec/mongoid/criteria/findable_spec.rb +1132 -0
  550. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  551. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  552. data/spec/mongoid/criteria/inspectable_spec.rb +29 -0
  553. data/spec/mongoid/criteria/marshalable_spec.rb +47 -0
  554. data/spec/mongoid/criteria/modifiable_spec.rb +1812 -0
  555. data/spec/mongoid/criteria/options_spec.rb +31 -0
  556. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +372 -0
  557. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  558. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +513 -0
  559. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +169 -0
  560. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +60 -0
  561. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +215 -0
  562. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +343 -0
  563. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +434 -0
  564. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +60 -0
  565. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +67 -0
  566. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +314 -0
  567. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +67 -0
  568. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +79 -0
  569. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +119 -0
  570. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +110 -0
  571. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +370 -0
  572. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +91 -0
  573. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +92 -0
  574. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +41 -0
  575. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +347 -0
  576. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +169 -0
  577. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +406 -0
  578. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +387 -0
  579. data/spec/mongoid/criteria/queryable/key_spec.rb +96 -0
  580. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +182 -0
  581. data/spec/mongoid/criteria/queryable/optional_spec.rb +1317 -0
  582. data/spec/mongoid/criteria/queryable/options_spec.rb +362 -0
  583. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +214 -0
  584. data/spec/mongoid/criteria/queryable/queryable_spec.rb +139 -0
  585. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2119 -0
  586. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  587. data/spec/mongoid/criteria/queryable/selectable_spec.rb +2462 -0
  588. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  589. data/spec/mongoid/criteria/queryable/selector_spec.rb +895 -0
  590. data/spec/mongoid/criteria/queryable/smash_spec.rb +32 -0
  591. data/spec/mongoid/criteria/queryable/storable_spec.rb +226 -0
  592. data/spec/mongoid/criteria/scopable_spec.rb +601 -0
  593. data/spec/mongoid/criteria_projection_spec.rb +410 -0
  594. data/spec/mongoid/criteria_spec.rb +1828 -3572
  595. data/spec/mongoid/document_fields_spec.rb +262 -0
  596. data/spec/mongoid/document_persistence_context_spec.rb +32 -0
  597. data/spec/mongoid/document_query_spec.rb +89 -0
  598. data/spec/mongoid/document_spec.rb +452 -221
  599. data/spec/mongoid/equality_spec.rb +155 -52
  600. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +8 -6
  601. data/spec/mongoid/errors/callback_spec.rb +5 -3
  602. data/spec/mongoid/errors/delete_restriction_spec.rb +7 -5
  603. data/spec/mongoid/errors/document_not_destroyed_spec.rb +35 -0
  604. data/spec/mongoid/errors/document_not_found_spec.rb +89 -11
  605. data/spec/mongoid/errors/invalid_collection_spec.rb +5 -3
  606. data/spec/mongoid/errors/invalid_config_file_spec.rb +31 -0
  607. data/spec/mongoid/errors/invalid_config_option_spec.rb +5 -3
  608. data/spec/mongoid/errors/invalid_field_option_spec.rb +5 -3
  609. data/spec/mongoid/errors/invalid_field_spec.rb +6 -4
  610. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  611. data/spec/mongoid/errors/invalid_find_spec.rb +5 -3
  612. data/spec/mongoid/errors/invalid_includes_spec.rb +5 -3
  613. data/spec/mongoid/errors/invalid_index_spec.rb +5 -3
  614. data/spec/mongoid/errors/invalid_options_spec.rb +7 -5
  615. data/spec/mongoid/errors/invalid_path_spec.rb +5 -3
  616. data/spec/mongoid/errors/invalid_relation_spec.rb +39 -0
  617. data/spec/mongoid/errors/invalid_scope_spec.rb +7 -5
  618. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +5 -3
  619. data/spec/mongoid/errors/invalid_storage_options_spec.rb +5 -3
  620. data/spec/mongoid/errors/invalid_time_spec.rb +5 -3
  621. data/spec/mongoid/errors/inverse_not_found_spec.rb +6 -4
  622. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +31 -0
  623. data/spec/mongoid/errors/mixed_relations_spec.rb +5 -3
  624. data/spec/mongoid/errors/mongoid_error_spec.rb +45 -10
  625. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +8 -6
  626. data/spec/mongoid/errors/no_client_config_spec.rb +31 -0
  627. data/spec/mongoid/errors/no_client_database_spec.rb +31 -0
  628. data/spec/mongoid/errors/no_client_hosts_spec.rb +31 -0
  629. data/spec/mongoid/errors/no_clients_config_spec.rb +31 -0
  630. data/spec/mongoid/errors/no_environment_spec.rb +8 -6
  631. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +5 -3
  632. data/spec/mongoid/errors/no_metadata_spec.rb +5 -3
  633. data/spec/mongoid/errors/no_parent_spec.rb +6 -4
  634. data/spec/mongoid/errors/readonly_attribute_spec.rb +5 -3
  635. data/spec/mongoid/errors/readonly_document_spec.rb +31 -0
  636. data/spec/mongoid/errors/scope_overwrite_spec.rb +5 -3
  637. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +6 -4
  638. data/spec/mongoid/errors/unknown_attribute_spec.rb +7 -5
  639. data/spec/mongoid/errors/unsaved_document_spec.rb +6 -4
  640. data/spec/mongoid/errors/unsupported_javascript_spec.rb +5 -3
  641. data/spec/mongoid/errors/validations_spec.rb +9 -7
  642. data/spec/mongoid/extensions/array_spec.rb +108 -116
  643. data/spec/mongoid/extensions/big_decimal_spec.rb +838 -49
  644. data/spec/mongoid/extensions/binary_spec.rb +55 -18
  645. data/spec/mongoid/extensions/boolean_spec.rb +76 -74
  646. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +339 -0
  647. data/spec/mongoid/extensions/date_spec.rb +59 -145
  648. data/spec/mongoid/extensions/date_time_spec.rb +35 -76
  649. data/spec/mongoid/extensions/decimal128_spec.rb +46 -0
  650. data/spec/mongoid/extensions/false_class_spec.rb +7 -5
  651. data/spec/mongoid/extensions/float_spec.rb +69 -62
  652. data/spec/mongoid/extensions/hash_spec.rb +197 -30
  653. data/spec/mongoid/extensions/integer_spec.rb +63 -65
  654. data/spec/mongoid/extensions/module_spec.rb +4 -2
  655. data/spec/mongoid/extensions/nil_class_spec.rb +3 -1
  656. data/spec/mongoid/extensions/object_id_spec.rb +136 -134
  657. data/spec/mongoid/extensions/object_spec.rb +53 -57
  658. data/spec/mongoid/extensions/range_spec.rb +287 -28
  659. data/spec/mongoid/extensions/regexp_spec.rb +71 -21
  660. data/spec/mongoid/extensions/set_spec.rb +112 -4
  661. data/spec/mongoid/extensions/string_spec.rb +188 -89
  662. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  663. data/spec/mongoid/extensions/symbol_spec.rb +25 -30
  664. data/spec/mongoid/extensions/time_spec.rb +703 -110
  665. data/spec/mongoid/extensions/time_with_zone_spec.rb +82 -67
  666. data/spec/mongoid/extensions/true_class_spec.rb +7 -5
  667. data/spec/mongoid/extensions_spec.rb +43 -0
  668. data/spec/mongoid/factory_spec.rb +374 -25
  669. data/spec/mongoid/fields/foreign_key_spec.rb +116 -92
  670. data/spec/mongoid/fields/localized_spec.rb +177 -35
  671. data/spec/mongoid/fields/standard_spec.rb +15 -13
  672. data/spec/mongoid/fields_spec.rb +952 -238
  673. data/spec/mongoid/findable_spec.rb +632 -0
  674. data/spec/mongoid/indexable/specification_spec.rb +129 -0
  675. data/spec/mongoid/indexable_spec.rb +643 -0
  676. data/spec/mongoid/inspectable_spec.rb +86 -0
  677. data/spec/mongoid/interceptable_spec.rb +2373 -0
  678. data/spec/mongoid/interceptable_spec_models.rb +307 -0
  679. data/spec/mongoid/loggable_spec.rb +3 -1
  680. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  681. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  682. data/spec/mongoid/matcher/extract_attribute_spec.rb +36 -0
  683. data/spec/mongoid/mongoizable_spec.rb +285 -0
  684. data/spec/mongoid/persistable/creatable_spec.rb +662 -0
  685. data/spec/mongoid/persistable/deletable_spec.rb +514 -0
  686. data/spec/mongoid/persistable/destroyable_spec.rb +455 -0
  687. data/spec/mongoid/persistable/incrementable_spec.rb +241 -0
  688. data/spec/mongoid/persistable/logical_spec.rb +159 -0
  689. data/spec/mongoid/persistable/poppable_spec.rb +131 -0
  690. data/spec/mongoid/persistable/pullable_spec.rb +258 -0
  691. data/spec/mongoid/persistable/pushable_spec.rb +353 -0
  692. data/spec/mongoid/persistable/renamable_spec.rb +151 -0
  693. data/spec/mongoid/persistable/savable_spec.rb +684 -0
  694. data/spec/mongoid/persistable/settable_spec.rb +544 -0
  695. data/spec/mongoid/persistable/unsettable_spec.rb +171 -0
  696. data/spec/mongoid/persistable/updatable_spec.rb +760 -0
  697. data/spec/mongoid/persistable/upsertable_spec.rb +122 -0
  698. data/spec/mongoid/persistable_spec.rb +321 -0
  699. data/spec/mongoid/persistence_context_spec.rb +745 -0
  700. data/spec/mongoid/positional_spec.rb +223 -0
  701. data/spec/mongoid/query_cache_middleware_spec.rb +50 -0
  702. data/spec/mongoid/query_cache_spec.rb +870 -0
  703. data/spec/mongoid/relations/proxy_spec.rb +125 -47
  704. data/spec/mongoid/reloadable_spec.rb +665 -0
  705. data/spec/mongoid/scopable_spec.rb +1234 -0
  706. data/spec/mongoid/selectable_spec.rb +136 -0
  707. data/spec/mongoid/serializable_spec.rb +963 -0
  708. data/spec/mongoid/shardable_models.rb +61 -0
  709. data/spec/mongoid/shardable_spec.rb +204 -0
  710. data/spec/mongoid/stateful_spec.rb +157 -0
  711. data/spec/mongoid/tasks/database_rake_spec.rb +287 -0
  712. data/spec/mongoid/tasks/database_spec.rb +181 -0
  713. data/spec/mongoid/threaded_spec.rb +88 -78
  714. data/spec/mongoid/timestamps/created/short_spec.rb +9 -7
  715. data/spec/mongoid/timestamps/created_spec.rb +8 -6
  716. data/spec/mongoid/timestamps/timeless_spec.rb +29 -10
  717. data/spec/mongoid/timestamps/updated/short_spec.rb +16 -14
  718. data/spec/mongoid/timestamps/updated_spec.rb +14 -16
  719. data/spec/mongoid/timestamps_spec.rb +406 -18
  720. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  721. data/spec/mongoid/touchable_spec.rb +704 -0
  722. data/spec/mongoid/touchable_spec_models.rb +57 -0
  723. data/spec/mongoid/traversable_spec.rb +1410 -0
  724. data/spec/mongoid/validatable/associated_spec.rb +208 -0
  725. data/spec/mongoid/validatable/format_spec.rb +85 -0
  726. data/spec/mongoid/validatable/length_spec.rb +225 -0
  727. data/spec/mongoid/validatable/numericality_spec.rb +32 -0
  728. data/spec/mongoid/validatable/presence_spec.rb +592 -0
  729. data/spec/mongoid/validatable/uniqueness_spec.rb +2504 -0
  730. data/spec/mongoid/validatable_spec.rb +327 -0
  731. data/spec/mongoid/warnings_spec.rb +35 -0
  732. data/spec/mongoid_spec.rb +20 -20
  733. data/spec/rails/controller_extension/controller_runtime_spec.rb +112 -0
  734. data/spec/rails/mongoid_spec.rb +37 -354
  735. data/spec/shared/LICENSE +20 -0
  736. data/spec/shared/bin/get-mongodb-download-url +17 -0
  737. data/spec/shared/bin/s3-copy +45 -0
  738. data/spec/shared/bin/s3-upload +69 -0
  739. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  740. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  741. data/spec/shared/lib/mrss/constraints.rb +378 -0
  742. data/spec/shared/lib/mrss/docker_runner.rb +291 -0
  743. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  744. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  745. data/spec/shared/lib/mrss/lite_constraints.rb +230 -0
  746. data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
  747. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  748. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  749. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  750. data/spec/shared/lib/mrss/utils.rb +15 -0
  751. data/spec/shared/share/Dockerfile.erb +325 -0
  752. data/spec/shared/share/haproxy-1.conf +16 -0
  753. data/spec/shared/share/haproxy-2.conf +17 -0
  754. data/spec/shared/shlib/config.sh +27 -0
  755. data/spec/shared/shlib/distro.sh +74 -0
  756. data/spec/shared/shlib/server.sh +392 -0
  757. data/spec/shared/shlib/set_env.sh +169 -0
  758. data/spec/spec_helper.rb +163 -42
  759. data/spec/support/authorization.rb +15 -0
  760. data/spec/support/client_registry.rb +9 -0
  761. data/spec/support/constraints.rb +77 -0
  762. data/spec/support/expectations.rb +32 -0
  763. data/spec/support/helpers.rb +11 -0
  764. data/spec/support/macros.rb +81 -0
  765. data/spec/support/models/account.rb +38 -0
  766. data/spec/support/models/acolyte.rb +19 -0
  767. data/spec/support/models/actor.rb +20 -0
  768. data/spec/support/models/actress.rb +4 -0
  769. data/spec/support/models/address.rb +85 -0
  770. data/spec/support/models/address_component.rb +7 -0
  771. data/spec/support/models/address_number.rb +8 -0
  772. data/spec/support/models/agency.rb +7 -0
  773. data/spec/support/models/agent.rb +18 -0
  774. data/spec/support/models/album.rb +20 -0
  775. data/spec/support/models/alert.rb +9 -0
  776. data/spec/support/models/animal.rb +28 -0
  777. data/spec/support/models/answer.rb +8 -0
  778. data/spec/support/models/appointment.rb +9 -0
  779. data/spec/support/models/armrest.rb +9 -0
  780. data/spec/support/models/array_field.rb +7 -0
  781. data/spec/support/models/article.rb +14 -0
  782. data/spec/support/models/artist.rb +91 -0
  783. data/spec/support/models/artwork.rb +6 -0
  784. data/spec/support/models/audible_sound.rb +3 -0
  785. data/spec/support/models/audio.rb +7 -0
  786. data/spec/support/models/augmentation.rb +25 -0
  787. data/spec/support/models/author.rb +8 -0
  788. data/spec/support/models/baby.rb +6 -0
  789. data/spec/support/models/band.rb +40 -0
  790. data/spec/support/models/bar.rb +12 -0
  791. data/spec/support/models/basic.rb +8 -0
  792. data/spec/support/models/bed.rb +3 -0
  793. data/spec/support/models/big_palette.rb +4 -0
  794. data/spec/support/models/birthday.rb +15 -0
  795. data/spec/support/models/bolt.rb +7 -0
  796. data/spec/support/models/bomb.rb +6 -0
  797. data/spec/support/models/book.rb +18 -0
  798. data/spec/support/models/breed.rb +6 -0
  799. data/spec/support/models/browser.rb +8 -0
  800. data/spec/support/models/building.rb +8 -0
  801. data/spec/support/models/building_address.rb +9 -0
  802. data/spec/support/models/bus.rb +9 -0
  803. data/spec/support/models/business.rb +7 -0
  804. data/spec/support/models/callback_test.rb +11 -0
  805. data/spec/support/models/canvas.rb +27 -0
  806. data/spec/support/models/car.rb +3 -0
  807. data/spec/support/models/cat.rb +10 -0
  808. data/spec/support/models/catalog.rb +24 -0
  809. data/spec/support/models/category.rb +10 -0
  810. data/spec/support/models/child.rb +6 -0
  811. data/spec/support/models/child_doc.rb +24 -0
  812. data/spec/support/models/church.rb +8 -0
  813. data/spec/support/models/circle.rb +5 -0
  814. data/spec/support/models/circuit.rb +6 -0
  815. data/spec/support/models/circus.rb +12 -0
  816. data/spec/support/models/code.rb +15 -0
  817. data/spec/support/models/coding/pull_request.rb +11 -0
  818. data/spec/support/models/coding.rb +3 -0
  819. data/spec/support/models/comment.rb +18 -0
  820. data/spec/support/models/company.rb +7 -0
  821. data/spec/support/models/consumption_period.rb +9 -0
  822. data/spec/support/models/contextable_item.rb +7 -0
  823. data/spec/support/models/contractor.rb +7 -0
  824. data/spec/support/models/cookie.rb +8 -0
  825. data/spec/support/models/country_code.rb +12 -0
  826. data/spec/support/models/courier_job.rb +6 -0
  827. data/spec/support/models/crate.rb +12 -0
  828. data/spec/support/models/customer.rb +10 -0
  829. data/spec/support/models/customer_address.rb +11 -0
  830. data/spec/support/models/deed.rb +7 -0
  831. data/spec/support/models/definition.rb +11 -0
  832. data/spec/support/models/delegating_patient.rb +15 -0
  833. data/spec/support/models/description.rb +13 -0
  834. data/spec/support/models/dictionary.rb +18 -0
  835. data/spec/support/models/division.rb +12 -0
  836. data/spec/support/models/doctor.rb +14 -0
  837. data/spec/support/models/dog.rb +9 -0
  838. data/spec/support/models/dokument.rb +8 -0
  839. data/spec/support/models/draft.rb +11 -0
  840. data/spec/support/models/dragon.rb +6 -0
  841. data/spec/support/models/driver.rb +9 -0
  842. data/spec/support/models/drug.rb +8 -0
  843. data/spec/support/models/dungeon.rb +6 -0
  844. data/spec/support/models/edit.rb +7 -0
  845. data/spec/support/models/email.rb +8 -0
  846. data/spec/support/models/employer.rb +7 -0
  847. data/spec/support/models/entry.rb +8 -0
  848. data/spec/support/models/eraser.rb +3 -0
  849. data/spec/support/models/even.rb +9 -0
  850. data/spec/support/models/event.rb +24 -0
  851. data/spec/support/models/exhibition.rb +6 -0
  852. data/spec/support/models/exhibitor.rb +8 -0
  853. data/spec/support/models/explosion.rb +6 -0
  854. data/spec/support/models/eye.rb +11 -0
  855. data/spec/support/models/eye_bowl.rb +11 -0
  856. data/spec/support/models/face.rb +10 -0
  857. data/spec/support/models/fanatic.rb +8 -0
  858. data/spec/support/models/favorite.rb +8 -0
  859. data/spec/support/models/filesystem.rb +7 -0
  860. data/spec/support/models/fire_hydrant.rb +8 -0
  861. data/spec/support/models/firefox.rb +6 -0
  862. data/spec/support/models/fish.rb +9 -0
  863. data/spec/support/models/folder.rb +9 -0
  864. data/spec/support/models/folder_item.rb +11 -0
  865. data/spec/support/models/fruits.rb +36 -0
  866. data/spec/support/models/game.rb +21 -0
  867. data/spec/support/models/ghost.rb +9 -0
  868. data/spec/support/models/guitar.rb +4 -0
  869. data/spec/support/models/hole.rb +12 -0
  870. data/spec/support/models/home.rb +6 -0
  871. data/spec/support/models/house.rb +8 -0
  872. data/spec/support/models/html_writer.rb +5 -0
  873. data/spec/support/models/id_key.rb +8 -0
  874. data/spec/support/models/idnodef.rb +7 -0
  875. data/spec/support/models/image.rb +24 -0
  876. data/spec/support/models/implant.rb +27 -0
  877. data/spec/support/models/instrument.rb +8 -0
  878. data/spec/support/models/item.rb +10 -0
  879. data/spec/support/models/jar.rb +9 -0
  880. data/spec/support/models/kaleidoscope.rb +8 -0
  881. data/spec/support/models/kangaroo.rb +6 -0
  882. data/spec/support/models/label.rb +52 -0
  883. data/spec/support/models/language.rb +7 -0
  884. data/spec/support/models/lat_lng.rb +17 -0
  885. data/spec/support/models/league.rb +13 -0
  886. data/spec/support/models/learner.rb +4 -0
  887. data/spec/support/models/line_item.rb +8 -0
  888. data/spec/support/models/location.rb +10 -0
  889. data/spec/support/models/login.rb +10 -0
  890. data/spec/support/models/manufacturer.rb +9 -0
  891. data/spec/support/models/meat.rb +6 -0
  892. data/spec/support/models/membership.rb +7 -0
  893. data/spec/support/models/message.rb +13 -0
  894. data/spec/support/models/minim.rb +6 -0
  895. data/spec/support/models/mixed_drink.rb +6 -0
  896. data/spec/support/models/mop.rb +24 -0
  897. data/spec/support/models/movie.rb +15 -0
  898. data/spec/support/models/my_hash.rb +4 -0
  899. data/spec/support/models/name.rb +26 -0
  900. data/spec/support/models/name_only.rb +8 -0
  901. data/spec/support/models/node.rb +7 -0
  902. data/spec/support/models/note.rb +19 -0
  903. data/spec/support/models/nut.rb +7 -0
  904. data/spec/support/models/odd.rb +9 -0
  905. data/spec/support/models/order.rb +12 -0
  906. data/spec/support/models/ordered_post.rb +13 -0
  907. data/spec/support/models/ordered_preference.rb +8 -0
  908. data/spec/support/models/oscar.rb +16 -0
  909. data/spec/support/models/other_owner_object.rb +4 -0
  910. data/spec/support/models/override.rb +18 -0
  911. data/spec/support/models/ownable.rb +8 -0
  912. data/spec/support/models/owner.rb +10 -0
  913. data/spec/support/models/pack.rb +5 -0
  914. data/spec/support/models/page.rb +18 -0
  915. data/spec/support/models/page_question.rb +6 -0
  916. data/spec/support/models/palette.rb +9 -0
  917. data/spec/support/models/parent.rb +7 -0
  918. data/spec/support/models/parent_doc.rb +8 -0
  919. data/spec/support/models/passport.rb +22 -0
  920. data/spec/support/models/patient.rb +11 -0
  921. data/spec/support/models/pdf_writer.rb +5 -0
  922. data/spec/support/models/pencil.rb +3 -0
  923. data/spec/support/models/person.rb +231 -0
  924. data/spec/support/models/pet.rb +25 -0
  925. data/spec/support/models/pet_owner.rb +8 -0
  926. data/spec/support/models/phone.rb +13 -0
  927. data/spec/support/models/piano.rb +4 -0
  928. data/spec/support/models/pizza.rb +9 -0
  929. data/spec/support/models/player.rb +39 -0
  930. data/spec/support/models/post.rb +52 -0
  931. data/spec/support/models/post_genre.rb +8 -0
  932. data/spec/support/models/powerup.rb +25 -0
  933. data/spec/support/models/preference.rb +11 -0
  934. data/spec/support/models/princess.rb +12 -0
  935. data/spec/support/models/product.rb +19 -0
  936. data/spec/support/models/profile.rb +17 -0
  937. data/spec/support/models/pronunciation.rb +7 -0
  938. data/spec/support/models/pub.rb +8 -0
  939. data/spec/support/models/publication/encyclopedia.rb +11 -0
  940. data/spec/support/models/publication/review.rb +13 -0
  941. data/spec/support/models/publication.rb +4 -0
  942. data/spec/support/models/purchase.rb +6 -0
  943. data/spec/support/models/purchased_item.rb +10 -0
  944. data/spec/support/models/question.rb +10 -0
  945. data/spec/support/models/quiz.rb +9 -0
  946. data/spec/support/models/rating.rb +10 -0
  947. data/spec/support/models/record.rb +54 -0
  948. data/spec/support/models/registry.rb +7 -0
  949. data/spec/support/models/role.rb +9 -0
  950. data/spec/support/models/root_category.rb +6 -0
  951. data/spec/support/models/sandwich.rb +11 -0
  952. data/spec/support/models/scheduler.rb +9 -0
  953. data/spec/support/models/school.rb +14 -0
  954. data/spec/support/models/scribe.rb +7 -0
  955. data/spec/support/models/sealer.rb +7 -0
  956. data/spec/support/models/seat.rb +24 -0
  957. data/spec/support/models/seo.rb +9 -0
  958. data/spec/support/models/series.rb +7 -0
  959. data/spec/support/models/server.rb +15 -0
  960. data/spec/support/models/service.rb +24 -0
  961. data/spec/support/models/shape.rb +14 -0
  962. data/spec/support/models/shelf.rb +7 -0
  963. data/spec/support/models/shield.rb +18 -0
  964. data/spec/support/models/shipment_address.rb +5 -0
  965. data/spec/support/models/shipping_container.rb +7 -0
  966. data/spec/support/models/shipping_pack.rb +5 -0
  967. data/spec/support/models/shirt.rb +11 -0
  968. data/spec/support/models/shop.rb +8 -0
  969. data/spec/support/models/short_agent.rb +6 -0
  970. data/spec/support/models/short_quiz.rb +7 -0
  971. data/spec/support/models/simple.rb +7 -0
  972. data/spec/support/models/slave.rb +8 -0
  973. data/spec/support/models/song.rb +10 -0
  974. data/spec/support/models/sound.rb +7 -0
  975. data/spec/support/models/spacer.rb +7 -0
  976. data/spec/support/models/square.rb +6 -0
  977. data/spec/support/models/staff.rb +9 -0
  978. data/spec/support/models/store_as_dup_test1.rb +7 -0
  979. data/spec/support/models/store_as_dup_test2.rb +7 -0
  980. data/spec/support/models/store_as_dup_test3.rb +7 -0
  981. data/spec/support/models/store_as_dup_test4.rb +7 -0
  982. data/spec/support/models/strategy.rb +5 -0
  983. data/spec/support/models/student.rb +14 -0
  984. data/spec/support/models/sub_item.rb +5 -0
  985. data/spec/support/models/subscription.rb +7 -0
  986. data/spec/support/models/survey.rb +7 -0
  987. data/spec/support/models/symptom.rb +8 -0
  988. data/spec/support/models/system_role.rb +7 -0
  989. data/spec/support/models/tag.rb +10 -0
  990. data/spec/support/models/target.rb +7 -0
  991. data/spec/support/models/template.rb +7 -0
  992. data/spec/support/models/thing.rb +11 -0
  993. data/spec/support/models/threadlocker.rb +7 -0
  994. data/spec/support/models/title.rb +5 -0
  995. data/spec/support/models/tool.rb +10 -0
  996. data/spec/support/models/topping.rb +7 -0
  997. data/spec/support/models/toy.rb +9 -0
  998. data/spec/support/models/track.rb +40 -0
  999. data/spec/support/models/translation.rb +7 -0
  1000. data/spec/support/models/tree.rb +11 -0
  1001. data/spec/support/models/truck.rb +7 -0
  1002. data/spec/support/models/updatable.rb +7 -0
  1003. data/spec/support/models/user.rb +23 -0
  1004. data/spec/support/models/user_account.rb +12 -0
  1005. data/spec/support/models/validation_callback.rb +12 -0
  1006. data/spec/support/models/vehicle.rb +18 -0
  1007. data/spec/support/models/version.rb +7 -0
  1008. data/spec/support/models/vertex.rb +8 -0
  1009. data/spec/support/models/vet_visit.rb +7 -0
  1010. data/spec/support/models/video.rb +15 -0
  1011. data/spec/support/models/video_game.rb +3 -0
  1012. data/spec/support/models/washer.rb +7 -0
  1013. data/spec/support/models/weapon.rb +25 -0
  1014. data/spec/support/models/wiki_page.rb +17 -0
  1015. data/spec/support/models/word.rb +17 -0
  1016. data/spec/support/models/word_origin.rb +13 -0
  1017. data/spec/support/models/writer.rb +13 -0
  1018. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1019. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1020. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1021. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1022. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1023. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1024. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1025. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1026. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1027. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1028. data/spec/support/shared/time.rb +53 -0
  1029. data/spec/support/spec_config.rb +64 -0
  1030. data.tar.gz.sig +0 -0
  1031. metadata +1582 -912
  1032. metadata.gz.sig +0 -0
  1033. data/lib/mongoid/atomic/positionable.rb +0 -73
  1034. data/lib/mongoid/callbacks.rb +0 -314
  1035. data/lib/mongoid/components.rb +0 -93
  1036. data/lib/mongoid/config/inflections.rb +0 -6
  1037. data/lib/mongoid/config/validators/session.rb +0 -140
  1038. data/lib/mongoid/contextual/eager.rb +0 -158
  1039. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  1040. data/lib/mongoid/criterion/findable.rb +0 -179
  1041. data/lib/mongoid/criterion/inspection.rb +0 -25
  1042. data/lib/mongoid/criterion/marshalable.rb +0 -48
  1043. data/lib/mongoid/criterion/modifiable.rb +0 -189
  1044. data/lib/mongoid/criterion/scoping.rb +0 -158
  1045. data/lib/mongoid/dirty.rb +0 -376
  1046. data/lib/mongoid/errors/eager_load.rb +0 -22
  1047. data/lib/mongoid/errors/mixed_session_configuration.rb +0 -28
  1048. data/lib/mongoid/errors/no_default_session.rb +0 -23
  1049. data/lib/mongoid/errors/no_session_config.rb +0 -22
  1050. data/lib/mongoid/errors/no_session_database.rb +0 -27
  1051. data/lib/mongoid/errors/no_session_hosts.rb +0 -27
  1052. data/lib/mongoid/errors/no_sessions_config.rb +0 -20
  1053. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  1054. data/lib/mongoid/finders.rb +0 -130
  1055. data/lib/mongoid/hierarchy.rb +0 -188
  1056. data/lib/mongoid/identity_map.rb +0 -163
  1057. data/lib/mongoid/indexes/validators/options.rb +0 -102
  1058. data/lib/mongoid/indexes.rb +0 -154
  1059. data/lib/mongoid/inspection.rb +0 -55
  1060. data/lib/mongoid/json.rb +0 -16
  1061. data/lib/mongoid/matchers/all.rb +0 -27
  1062. data/lib/mongoid/matchers/and.rb +0 -30
  1063. data/lib/mongoid/matchers/default.rb +0 -72
  1064. data/lib/mongoid/matchers/exists.rb +0 -23
  1065. data/lib/mongoid/matchers/gt.rb +0 -21
  1066. data/lib/mongoid/matchers/gte.rb +0 -21
  1067. data/lib/mongoid/matchers/in.rb +0 -24
  1068. data/lib/mongoid/matchers/lt.rb +0 -21
  1069. data/lib/mongoid/matchers/lte.rb +0 -21
  1070. data/lib/mongoid/matchers/ne.rb +0 -21
  1071. data/lib/mongoid/matchers/nin.rb +0 -21
  1072. data/lib/mongoid/matchers/or.rb +0 -33
  1073. data/lib/mongoid/matchers/size.rb +0 -21
  1074. data/lib/mongoid/matchers/strategies.rb +0 -97
  1075. data/lib/mongoid/matchers.rb +0 -32
  1076. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  1077. data/lib/mongoid/nested_attributes.rb +0 -78
  1078. data/lib/mongoid/observer.rb +0 -192
  1079. data/lib/mongoid/paranoia.rb +0 -137
  1080. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  1081. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  1082. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  1083. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  1084. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  1085. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  1086. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  1087. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  1088. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  1089. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  1090. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  1091. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  1092. data/lib/mongoid/persistence/atomic.rb +0 -231
  1093. data/lib/mongoid/persistence/deletion.rb +0 -32
  1094. data/lib/mongoid/persistence/insertion.rb +0 -38
  1095. data/lib/mongoid/persistence/modification.rb +0 -35
  1096. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  1097. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  1098. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  1099. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  1100. data/lib/mongoid/persistence/operations/update.rb +0 -59
  1101. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  1102. data/lib/mongoid/persistence/operations.rb +0 -214
  1103. data/lib/mongoid/persistence/upsertion.rb +0 -31
  1104. data/lib/mongoid/persistence.rb +0 -352
  1105. data/lib/mongoid/railties/document.rb +0 -12
  1106. data/lib/mongoid/relations/accessors.rb +0 -299
  1107. data/lib/mongoid/relations/auto_save.rb +0 -107
  1108. data/lib/mongoid/relations/binding.rb +0 -241
  1109. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -63
  1110. data/lib/mongoid/relations/bindings/embedded/many.rb +0 -52
  1111. data/lib/mongoid/relations/bindings/embedded/one.rb +0 -55
  1112. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -70
  1113. data/lib/mongoid/relations/bindings/referenced/many.rb +0 -42
  1114. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -67
  1115. data/lib/mongoid/relations/bindings/referenced/one.rb +0 -44
  1116. data/lib/mongoid/relations/bindings.rb +0 -9
  1117. data/lib/mongoid/relations/builder.rb +0 -57
  1118. data/lib/mongoid/relations/builders/embedded/in.rb +0 -29
  1119. data/lib/mongoid/relations/builders/embedded/many.rb +0 -36
  1120. data/lib/mongoid/relations/builders/embedded/one.rb +0 -30
  1121. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -177
  1122. data/lib/mongoid/relations/builders/nested_attributes/one.rb +0 -127
  1123. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  1124. data/lib/mongoid/relations/builders/referenced/many.rb +0 -27
  1125. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -40
  1126. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  1127. data/lib/mongoid/relations/builders.rb +0 -104
  1128. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  1129. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  1130. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  1131. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  1132. data/lib/mongoid/relations/cascading.rb +0 -58
  1133. data/lib/mongoid/relations/constraint.rb +0 -49
  1134. data/lib/mongoid/relations/conversions.rb +0 -34
  1135. data/lib/mongoid/relations/counter_cache.rb +0 -107
  1136. data/lib/mongoid/relations/cyclic.rb +0 -107
  1137. data/lib/mongoid/relations/embedded/batchable.rb +0 -356
  1138. data/lib/mongoid/relations/embedded/in.rb +0 -231
  1139. data/lib/mongoid/relations/embedded/many.rb +0 -659
  1140. data/lib/mongoid/relations/embedded/one.rb +0 -223
  1141. data/lib/mongoid/relations/macros.rb +0 -359
  1142. data/lib/mongoid/relations/many.rb +0 -217
  1143. data/lib/mongoid/relations/marshalable.rb +0 -32
  1144. data/lib/mongoid/relations/metadata.rb +0 -1227
  1145. data/lib/mongoid/relations/nested_builder.rb +0 -74
  1146. data/lib/mongoid/relations/one.rb +0 -60
  1147. data/lib/mongoid/relations/options.rb +0 -48
  1148. data/lib/mongoid/relations/polymorphic.rb +0 -40
  1149. data/lib/mongoid/relations/proxy.rb +0 -264
  1150. data/lib/mongoid/relations/referenced/in.rb +0 -314
  1151. data/lib/mongoid/relations/referenced/many.rb +0 -789
  1152. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -495
  1153. data/lib/mongoid/relations/referenced/one.rb +0 -297
  1154. data/lib/mongoid/relations/reflections.rb +0 -62
  1155. data/lib/mongoid/relations/synchronization.rb +0 -169
  1156. data/lib/mongoid/relations/targets/enumerable.rb +0 -473
  1157. data/lib/mongoid/relations/targets.rb +0 -2
  1158. data/lib/mongoid/relations/touchable.rb +0 -61
  1159. data/lib/mongoid/relations.rb +0 -162
  1160. data/lib/mongoid/reloading.rb +0 -92
  1161. data/lib/mongoid/scoping.rb +0 -356
  1162. data/lib/mongoid/serialization.rb +0 -161
  1163. data/lib/mongoid/sessions/factory.rb +0 -129
  1164. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  1165. data/lib/mongoid/sessions/validators/storage.rb +0 -49
  1166. data/lib/mongoid/sessions/validators.rb +0 -2
  1167. data/lib/mongoid/sessions.rb +0 -433
  1168. data/lib/mongoid/sharding.rb +0 -61
  1169. data/lib/mongoid/state.rb +0 -97
  1170. data/lib/mongoid/unit_of_work.rb +0 -61
  1171. data/lib/mongoid/validations/associated.rb +0 -46
  1172. data/lib/mongoid/validations/format.rb +0 -20
  1173. data/lib/mongoid/validations/length.rb +0 -20
  1174. data/lib/mongoid/validations/localizable.rb +0 -30
  1175. data/lib/mongoid/validations/macros.rb +0 -93
  1176. data/lib/mongoid/validations/presence.rb +0 -86
  1177. data/lib/mongoid/validations/queryable.rb +0 -31
  1178. data/lib/mongoid/validations/uniqueness.rb +0 -330
  1179. data/lib/mongoid/validations.rb +0 -166
  1180. data/lib/mongoid/versioning.rb +0 -217
  1181. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  1182. data/lib/rack/mongoid.rb +0 -2
  1183. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  1184. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  1185. data/lib/support/ruby_version.rb +0 -26
  1186. data/spec/app/models/account.rb +0 -32
  1187. data/spec/app/models/acolyte.rb +0 -16
  1188. data/spec/app/models/actor.rb +0 -19
  1189. data/spec/app/models/actor_observer.rb +0 -15
  1190. data/spec/app/models/actress.rb +0 -2
  1191. data/spec/app/models/address.rb +0 -72
  1192. data/spec/app/models/address_component.rb +0 -5
  1193. data/spec/app/models/address_number.rb +0 -6
  1194. data/spec/app/models/agency.rb +0 -5
  1195. data/spec/app/models/agent.rb +0 -12
  1196. data/spec/app/models/album.rb +0 -14
  1197. data/spec/app/models/alert.rb +0 -5
  1198. data/spec/app/models/animal.rb +0 -25
  1199. data/spec/app/models/answer.rb +0 -4
  1200. data/spec/app/models/appointment.rb +0 -7
  1201. data/spec/app/models/article.rb +0 -13
  1202. data/spec/app/models/artist.rb +0 -66
  1203. data/spec/app/models/artwork.rb +0 -4
  1204. data/spec/app/models/augmentation.rb +0 -11
  1205. data/spec/app/models/author.rb +0 -6
  1206. data/spec/app/models/band.rb +0 -25
  1207. data/spec/app/models/bar.rb +0 -9
  1208. data/spec/app/models/basic.rb +0 -6
  1209. data/spec/app/models/bed.rb +0 -1
  1210. data/spec/app/models/big_palette.rb +0 -2
  1211. data/spec/app/models/birthday.rb +0 -13
  1212. data/spec/app/models/book.rb +0 -12
  1213. data/spec/app/models/breed.rb +0 -4
  1214. data/spec/app/models/browser.rb +0 -6
  1215. data/spec/app/models/building.rb +0 -7
  1216. data/spec/app/models/building_address.rb +0 -7
  1217. data/spec/app/models/bus.rb +0 -7
  1218. data/spec/app/models/business.rb +0 -5
  1219. data/spec/app/models/callback_recorder.rb +0 -25
  1220. data/spec/app/models/callback_test.rb +0 -9
  1221. data/spec/app/models/canvas.rb +0 -25
  1222. data/spec/app/models/car.rb +0 -1
  1223. data/spec/app/models/cat.rb +0 -8
  1224. data/spec/app/models/category.rb +0 -8
  1225. data/spec/app/models/child.rb +0 -4
  1226. data/spec/app/models/child_doc.rb +0 -22
  1227. data/spec/app/models/church.rb +0 -4
  1228. data/spec/app/models/circle.rb +0 -3
  1229. data/spec/app/models/circuit.rb +0 -4
  1230. data/spec/app/models/circus.rb +0 -7
  1231. data/spec/app/models/code.rb +0 -5
  1232. data/spec/app/models/comment.rb +0 -16
  1233. data/spec/app/models/contractor.rb +0 -7
  1234. data/spec/app/models/cookie.rb +0 -6
  1235. data/spec/app/models/country_code.rb +0 -8
  1236. data/spec/app/models/definition.rb +0 -8
  1237. data/spec/app/models/description.rb +0 -11
  1238. data/spec/app/models/dictionary.rb +0 -10
  1239. data/spec/app/models/division.rb +0 -10
  1240. data/spec/app/models/doctor.rb +0 -12
  1241. data/spec/app/models/dog.rb +0 -7
  1242. data/spec/app/models/dokument.rb +0 -5
  1243. data/spec/app/models/driver.rb +0 -7
  1244. data/spec/app/models/drug.rb +0 -8
  1245. data/spec/app/models/email.rb +0 -6
  1246. data/spec/app/models/employer.rb +0 -5
  1247. data/spec/app/models/entry.rb +0 -6
  1248. data/spec/app/models/eraser.rb +0 -1
  1249. data/spec/app/models/event.rb +0 -22
  1250. data/spec/app/models/exhibition.rb +0 -4
  1251. data/spec/app/models/exhibitor.rb +0 -5
  1252. data/spec/app/models/eye.rb +0 -9
  1253. data/spec/app/models/eye_bowl.rb +0 -9
  1254. data/spec/app/models/face.rb +0 -8
  1255. data/spec/app/models/favorite.rb +0 -6
  1256. data/spec/app/models/filesystem.rb +0 -4
  1257. data/spec/app/models/fire_hydrant.rb +0 -6
  1258. data/spec/app/models/firefox.rb +0 -4
  1259. data/spec/app/models/fish.rb +0 -8
  1260. data/spec/app/models/folder.rb +0 -7
  1261. data/spec/app/models/folder_item.rb +0 -9
  1262. data/spec/app/models/fruits.rb +0 -28
  1263. data/spec/app/models/game.rb +0 -21
  1264. data/spec/app/models/ghost.rb +0 -7
  1265. data/spec/app/models/home.rb +0 -4
  1266. data/spec/app/models/house.rb +0 -8
  1267. data/spec/app/models/html_writer.rb +0 -3
  1268. data/spec/app/models/image.rb +0 -22
  1269. data/spec/app/models/implant.rb +0 -16
  1270. data/spec/app/models/item.rb +0 -12
  1271. data/spec/app/models/jar.rb +0 -7
  1272. data/spec/app/models/label.rb +0 -40
  1273. data/spec/app/models/language.rb +0 -5
  1274. data/spec/app/models/lat_lng.rb +0 -15
  1275. data/spec/app/models/league.rb +0 -11
  1276. data/spec/app/models/learner.rb +0 -2
  1277. data/spec/app/models/line_item.rb +0 -6
  1278. data/spec/app/models/location.rb +0 -8
  1279. data/spec/app/models/login.rb +0 -8
  1280. data/spec/app/models/manufacturer.rb +0 -7
  1281. data/spec/app/models/meat.rb +0 -4
  1282. data/spec/app/models/membership.rb +0 -4
  1283. data/spec/app/models/mixed_drink.rb +0 -4
  1284. data/spec/app/models/movie.rb +0 -12
  1285. data/spec/app/models/my_hash.rb +0 -2
  1286. data/spec/app/models/name.rb +0 -23
  1287. data/spec/app/models/node.rb +0 -5
  1288. data/spec/app/models/note.rb +0 -12
  1289. data/spec/app/models/ordered_post.rb +0 -6
  1290. data/spec/app/models/ordered_preference.rb +0 -6
  1291. data/spec/app/models/oscar.rb +0 -15
  1292. data/spec/app/models/override.rb +0 -16
  1293. data/spec/app/models/ownable.rb +0 -6
  1294. data/spec/app/models/owner.rb +0 -6
  1295. data/spec/app/models/pack.rb +0 -3
  1296. data/spec/app/models/page.rb +0 -5
  1297. data/spec/app/models/page_question.rb +0 -4
  1298. data/spec/app/models/palette.rb +0 -7
  1299. data/spec/app/models/paranoid_phone.rb +0 -25
  1300. data/spec/app/models/paranoid_post.rb +0 -36
  1301. data/spec/app/models/parent.rb +0 -5
  1302. data/spec/app/models/parent_doc.rb +0 -6
  1303. data/spec/app/models/passport.rb +0 -5
  1304. data/spec/app/models/patient.rb +0 -9
  1305. data/spec/app/models/pdf_writer.rb +0 -3
  1306. data/spec/app/models/pencil.rb +0 -1
  1307. data/spec/app/models/person.rb +0 -201
  1308. data/spec/app/models/pet.rb +0 -23
  1309. data/spec/app/models/pet_owner.rb +0 -6
  1310. data/spec/app/models/phone.rb +0 -11
  1311. data/spec/app/models/phone_observer.rb +0 -6
  1312. data/spec/app/models/pizza.rb +0 -7
  1313. data/spec/app/models/player.rb +0 -35
  1314. data/spec/app/models/post.rb +0 -43
  1315. data/spec/app/models/powerup.rb +0 -11
  1316. data/spec/app/models/preference.rb +0 -9
  1317. data/spec/app/models/princess.rb +0 -8
  1318. data/spec/app/models/product.rb +0 -17
  1319. data/spec/app/models/profile.rb +0 -5
  1320. data/spec/app/models/pronunciation.rb +0 -5
  1321. data/spec/app/models/purchase.rb +0 -4
  1322. data/spec/app/models/question.rb +0 -8
  1323. data/spec/app/models/quiz.rb +0 -10
  1324. data/spec/app/models/rating.rb +0 -8
  1325. data/spec/app/models/record.rb +0 -46
  1326. data/spec/app/models/registry.rb +0 -4
  1327. data/spec/app/models/role.rb +0 -7
  1328. data/spec/app/models/root_category.rb +0 -4
  1329. data/spec/app/models/sandwich.rb +0 -4
  1330. data/spec/app/models/scheduler.rb +0 -7
  1331. data/spec/app/models/seo.rb +0 -7
  1332. data/spec/app/models/series.rb +0 -4
  1333. data/spec/app/models/server.rb +0 -13
  1334. data/spec/app/models/service.rb +0 -22
  1335. data/spec/app/models/shape.rb +0 -12
  1336. data/spec/app/models/shelf.rb +0 -5
  1337. data/spec/app/models/shipping_container.rb +0 -5
  1338. data/spec/app/models/shipping_pack.rb +0 -3
  1339. data/spec/app/models/shop.rb +0 -6
  1340. data/spec/app/models/short_agent.rb +0 -4
  1341. data/spec/app/models/short_quiz.rb +0 -5
  1342. data/spec/app/models/slave.rb +0 -6
  1343. data/spec/app/models/song.rb +0 -8
  1344. data/spec/app/models/square.rb +0 -4
  1345. data/spec/app/models/strategy.rb +0 -3
  1346. data/spec/app/models/sub_item.rb +0 -3
  1347. data/spec/app/models/subscription.rb +0 -4
  1348. data/spec/app/models/survey.rb +0 -5
  1349. data/spec/app/models/symptom.rb +0 -6
  1350. data/spec/app/models/tag.rb +0 -8
  1351. data/spec/app/models/target.rb +0 -5
  1352. data/spec/app/models/template.rb +0 -5
  1353. data/spec/app/models/thing.rb +0 -9
  1354. data/spec/app/models/title.rb +0 -4
  1355. data/spec/app/models/tool.rb +0 -8
  1356. data/spec/app/models/topping.rb +0 -5
  1357. data/spec/app/models/track.rb +0 -38
  1358. data/spec/app/models/translation.rb +0 -5
  1359. data/spec/app/models/tree.rb +0 -9
  1360. data/spec/app/models/truck.rb +0 -3
  1361. data/spec/app/models/user.rb +0 -21
  1362. data/spec/app/models/user_account.rb +0 -10
  1363. data/spec/app/models/validation_callback.rb +0 -10
  1364. data/spec/app/models/vehicle.rb +0 -11
  1365. data/spec/app/models/version.rb +0 -5
  1366. data/spec/app/models/vet_visit.rb +0 -5
  1367. data/spec/app/models/video.rb +0 -17
  1368. data/spec/app/models/video_game.rb +0 -1
  1369. data/spec/app/models/weapon.rb +0 -11
  1370. data/spec/app/models/wiki_page.rb +0 -17
  1371. data/spec/app/models/word.rb +0 -12
  1372. data/spec/app/models/word_origin.rb +0 -11
  1373. data/spec/app/models/writer.rb +0 -11
  1374. data/spec/mongoid/atomic/positionable_spec.rb +0 -227
  1375. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  1376. data/spec/mongoid/callbacks_spec.rb +0 -1564
  1377. data/spec/mongoid/components_spec.rb +0 -24
  1378. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  1379. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  1380. data/spec/mongoid/criterion/inspection_spec.rb +0 -27
  1381. data/spec/mongoid/criterion/marshalable_spec.rb +0 -28
  1382. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  1383. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  1384. data/spec/mongoid/criterion/scoping_spec.rb +0 -391
  1385. data/spec/mongoid/dirty_spec.rb +0 -1508
  1386. data/spec/mongoid/errors/eager_load_spec.rb +0 -29
  1387. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +0 -29
  1388. data/spec/mongoid/errors/no_session_config_spec.rb +0 -29
  1389. data/spec/mongoid/errors/no_session_database_spec.rb +0 -29
  1390. data/spec/mongoid/errors/no_session_hosts_spec.rb +0 -29
  1391. data/spec/mongoid/errors/no_sessions_config_spec.rb +0 -29
  1392. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  1393. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  1394. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  1395. data/spec/mongoid/finders_spec.rb +0 -321
  1396. data/spec/mongoid/hierarchy_spec.rb +0 -244
  1397. data/spec/mongoid/identity_map_spec.rb +0 -564
  1398. data/spec/mongoid/indexes_spec.rb +0 -404
  1399. data/spec/mongoid/inspection_spec.rb +0 -57
  1400. data/spec/mongoid/json_spec.rb +0 -33
  1401. data/spec/mongoid/matchers/all_spec.rb +0 -31
  1402. data/spec/mongoid/matchers/and_spec.rb +0 -162
  1403. data/spec/mongoid/matchers/default_spec.rb +0 -130
  1404. data/spec/mongoid/matchers/exists_spec.rb +0 -57
  1405. data/spec/mongoid/matchers/gt_spec.rb +0 -74
  1406. data/spec/mongoid/matchers/gte_spec.rb +0 -74
  1407. data/spec/mongoid/matchers/in_spec.rb +0 -25
  1408. data/spec/mongoid/matchers/lt_spec.rb +0 -74
  1409. data/spec/mongoid/matchers/lte_spec.rb +0 -74
  1410. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  1411. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  1412. data/spec/mongoid/matchers/or_spec.rb +0 -106
  1413. data/spec/mongoid/matchers/size_spec.rb +0 -25
  1414. data/spec/mongoid/matchers_spec.rb +0 -532
  1415. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  1416. data/spec/mongoid/nested_attributes_spec.rb +0 -4945
  1417. data/spec/mongoid/observer_spec.rb +0 -290
  1418. data/spec/mongoid/paranoia_spec.rb +0 -759
  1419. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  1420. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  1421. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  1422. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  1423. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  1424. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  1425. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  1426. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  1427. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  1428. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  1429. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  1430. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  1431. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  1432. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  1433. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  1434. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  1435. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  1436. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  1437. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  1438. data/spec/mongoid/persistence_spec.rb +0 -2279
  1439. data/spec/mongoid/railties/document_spec.rb +0 -24
  1440. data/spec/mongoid/relations/accessors_spec.rb +0 -844
  1441. data/spec/mongoid/relations/auto_save_spec.rb +0 -261
  1442. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +0 -171
  1443. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +0 -54
  1444. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +0 -77
  1445. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +0 -241
  1446. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +0 -153
  1447. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +0 -178
  1448. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +0 -131
  1449. data/spec/mongoid/relations/builders/embedded/in_spec.rb +0 -34
  1450. data/spec/mongoid/relations/builders/embedded/many_spec.rb +0 -132
  1451. data/spec/mongoid/relations/builders/embedded/one_spec.rb +0 -99
  1452. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +0 -234
  1453. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +0 -250
  1454. data/spec/mongoid/relations/builders/referenced/in_spec.rb +0 -241
  1455. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  1456. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  1457. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -124
  1458. data/spec/mongoid/relations/builders_spec.rb +0 -226
  1459. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  1460. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  1461. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  1462. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  1463. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  1464. data/spec/mongoid/relations/constraint_spec.rb +0 -74
  1465. data/spec/mongoid/relations/conversions_spec.rb +0 -126
  1466. data/spec/mongoid/relations/counter_cache_spec.rb +0 -205
  1467. data/spec/mongoid/relations/cyclic_spec.rb +0 -156
  1468. data/spec/mongoid/relations/embedded/dirty_spec.rb +0 -65
  1469. data/spec/mongoid/relations/embedded/in_spec.rb +0 -580
  1470. data/spec/mongoid/relations/embedded/many_spec.rb +0 -3841
  1471. data/spec/mongoid/relations/embedded/one_spec.rb +0 -1055
  1472. data/spec/mongoid/relations/macros_spec.rb +0 -625
  1473. data/spec/mongoid/relations/metadata_spec.rb +0 -2030
  1474. data/spec/mongoid/relations/options_spec.rb +0 -35
  1475. data/spec/mongoid/relations/polymorphic_spec.rb +0 -132
  1476. data/spec/mongoid/relations/referenced/in_spec.rb +0 -1501
  1477. data/spec/mongoid/relations/referenced/many_spec.rb +0 -3632
  1478. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +0 -3561
  1479. data/spec/mongoid/relations/referenced/one_spec.rb +0 -1331
  1480. data/spec/mongoid/relations/reflections_spec.rb +0 -101
  1481. data/spec/mongoid/relations/synchronization_spec.rb +0 -453
  1482. data/spec/mongoid/relations/targets/enumerable_spec.rb +0 -1710
  1483. data/spec/mongoid/relations_spec.rb +0 -188
  1484. data/spec/mongoid/reloading_spec.rb +0 -305
  1485. data/spec/mongoid/scoping_spec.rb +0 -978
  1486. data/spec/mongoid/serialization_spec.rb +0 -833
  1487. data/spec/mongoid/sessions/factory_spec.rb +0 -312
  1488. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  1489. data/spec/mongoid/sessions_spec.rb +0 -1111
  1490. data/spec/mongoid/sharding_spec.rb +0 -61
  1491. data/spec/mongoid/state_spec.rb +0 -102
  1492. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  1493. data/spec/mongoid/validations/associated_spec.rb +0 -183
  1494. data/spec/mongoid/validations/format_spec.rb +0 -83
  1495. data/spec/mongoid/validations/length_spec.rb +0 -223
  1496. data/spec/mongoid/validations/numericality_spec.rb +0 -30
  1497. data/spec/mongoid/validations/presence_spec.rb +0 -592
  1498. data/spec/mongoid/validations/uniqueness_spec.rb +0 -2399
  1499. data/spec/mongoid/validations_spec.rb +0 -309
  1500. data/spec/mongoid/versioning_spec.rb +0 -540
  1501. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  describe Mongoid::Contextual::Mongo do
@@ -7,7 +9,7 @@ describe Mongoid::Contextual::Mongo do
7
9
  describe "##{method}" do
8
10
 
9
11
  before do
10
- Band.create(name: "Depeche Mode")
12
+ Band.create!(name: "Depeche Mode")
11
13
  end
12
14
 
13
15
  context "when the count is zero" do
@@ -21,7 +23,7 @@ describe Mongoid::Contextual::Mongo do
21
23
  end
22
24
 
23
25
  it "returns true" do
24
- context.send(method).should be_true
26
+ expect(context.send(method)).to be true
25
27
  end
26
28
  end
27
29
 
@@ -36,53 +38,20 @@ describe Mongoid::Contextual::Mongo do
36
38
  end
37
39
 
38
40
  it "returns false" do
39
- context.send(method).should be_false
41
+ expect(context.send(method)).to be false
40
42
  end
41
43
  end
42
44
  end
43
45
  end
44
46
 
45
- describe "#cached?" do
46
-
47
- context "when the criteria is cached" do
48
-
49
- let(:criteria) do
50
- Band.all.cache
51
- end
52
-
53
- let(:context) do
54
- described_class.new(criteria)
55
- end
56
-
57
- it "returns true" do
58
- context.should be_cached
59
- end
60
- end
61
-
62
- context "when the criteria is not cached" do
63
-
64
- let(:criteria) do
65
- Band.all
66
- end
67
-
68
- let(:context) do
69
- described_class.new(criteria)
70
- end
71
-
72
- it "returns false" do
73
- context.should_not be_cached
74
- end
75
- end
76
- end
77
-
78
47
  describe "#count" do
79
48
 
80
49
  let!(:depeche) do
81
- Band.create(name: "Depeche Mode")
50
+ Band.create!(name: "Depeche Mode")
82
51
  end
83
52
 
84
53
  let!(:new_order) do
85
- Band.create(name: "New Order")
54
+ Band.create!(name: "New Order")
86
55
  end
87
56
 
88
57
  let(:criteria) do
@@ -96,37 +65,21 @@ describe Mongoid::Contextual::Mongo do
96
65
  end
97
66
 
98
67
  it "returns the number of documents that match" do
99
- context.count.should eq(1)
100
- end
101
- end
102
-
103
- context "when context is cached" do
104
-
105
- let(:context) do
106
- described_class.new(criteria.cache)
107
- end
108
-
109
- before do
110
- context.query.should_receive(:count).once.and_return(1)
111
- end
112
-
113
- it "returns the count cached value after first call" do
114
- 2.times { context.count.should eq(1) }
68
+ expect(context.count).to eq(1)
115
69
  end
116
70
  end
117
71
 
118
- context "when provided a document" do
72
+ context "when the query cache is enabled" do
73
+ query_cache_enabled
119
74
 
120
75
  let(:context) do
121
76
  described_class.new(criteria)
122
77
  end
123
78
 
124
- let(:count) do
125
- context.count(depeche)
126
- end
127
-
128
- it "returns the number of documents that match" do
129
- count.should eq(1)
79
+ it "only executes the count query once" do
80
+ expect_query(1) do
81
+ 2.times { expect(context.count).to eq(1) }
82
+ end
130
83
  end
131
84
  end
132
85
 
@@ -143,13 +96,13 @@ describe Mongoid::Contextual::Mongo do
143
96
  end
144
97
 
145
98
  it "returns the number of documents that match" do
146
- count.should eq(1)
99
+ expect(count).to eq(1)
147
100
  end
148
101
 
149
102
  context "and a limit true" do
150
103
 
151
104
  before do
152
- 2.times { Band.create(name: "Depeche Mode", likes: 1) }
105
+ 2.times { Band.create!(name: "Depeche Mode", likes: 1) }
153
106
  end
154
107
 
155
108
  let(:count) do
@@ -159,41 +112,131 @@ describe Mongoid::Contextual::Mongo do
159
112
  end
160
113
 
161
114
  it "returns the number of documents that match" do
162
- count.should eq(1)
115
+ expect(count).to eq(1)
163
116
  end
164
117
  end
165
118
  end
166
119
 
167
- context "when provided limit true" do
120
+ context "when provided limit" do
168
121
 
169
122
  before do
170
- 2.times { Band.create(name: "Depeche Mode") }
123
+ 2.times { Band.create!(name: "Depeche Mode") }
171
124
  end
172
125
 
173
126
  let(:context) do
174
- described_class.new(criteria.limit(2))
127
+ described_class.new(criteria)
175
128
  end
176
129
 
177
130
  let(:count) do
178
- context.count(true)
131
+ context.count(limit: 2)
179
132
  end
180
133
 
181
134
  it "returns the number of documents that match" do
182
- count.should eq(2)
135
+ expect(count).to eq(2)
136
+ end
137
+ end
138
+
139
+ context 'when a collation is specified' do
140
+ min_server_version '3.4'
141
+
142
+ let(:context) do
143
+ described_class.new(criteria)
144
+ end
145
+
146
+ context 'when the collation is specified on the criteria' do
147
+
148
+ let(:criteria) do
149
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
150
+ end
151
+
152
+ let(:count) do
153
+ context.count
154
+ end
155
+
156
+ it 'applies the collation' do
157
+ expect(count).to eq(1)
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "#estimated_count" do
164
+
165
+ let!(:depeche) do
166
+ Band.create!(name: "Depeche Mode")
167
+ end
168
+
169
+ let!(:new_order) do
170
+ Band.create!(name: "New Order")
171
+ end
172
+
173
+ let(:criteria) do
174
+ Band.where
175
+ end
176
+
177
+ context "when not providing options" do
178
+ it 'returns the correct count' do
179
+ expect(criteria.estimated_count).to eq(2)
180
+ end
181
+ end
182
+
183
+ context "when providing options" do
184
+ it 'returns the correct count' do
185
+ expect(criteria.estimated_count(maxTimeMS: 1000)).to eq(2)
186
+ end
187
+ end
188
+
189
+ context "when the query cache is enabled" do
190
+ query_cache_enabled
191
+
192
+ let(:context) do
193
+ described_class.new(criteria)
194
+ end
195
+
196
+ it "the results are not cached" do
197
+ expect_query(2) do
198
+ 2.times do
199
+ context.estimated_count
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ context "when the criteria contains a selector", :focus do
206
+ let(:criteria) do
207
+ Band.where(name: "New Order")
208
+ end
209
+
210
+ context "when not providing options" do
211
+ it 'raises an error' do
212
+ expect do
213
+ criteria.estimated_count
214
+ end.to raise_error(Mongoid::Errors::InvalidEstimatedCountCriteria)
215
+ end
216
+ end
217
+
218
+ context "when providing options" do
219
+ it 'raises an error' do
220
+ expect do
221
+ criteria.estimated_count(maxTimeMS: 1000)
222
+ end.to raise_error(Mongoid::Errors::InvalidEstimatedCountCriteria)
223
+ end
183
224
  end
184
225
  end
185
226
  end
186
227
 
228
+
229
+
187
230
  [ :delete, :delete_all ].each do |method|
188
231
 
189
232
  describe "##{method}" do
190
233
 
191
234
  let!(:depeche_mode) do
192
- Band.create(name: "Depeche Mode")
235
+ Band.create!(name: "Depeche Mode")
193
236
  end
194
237
 
195
238
  let!(:new_order) do
196
- Band.create(name: "New Order")
239
+ Band.create!(name: "New Order")
197
240
  end
198
241
 
199
242
  context "when the selector is contraining" do
@@ -211,15 +254,43 @@ describe Mongoid::Contextual::Mongo do
211
254
  end
212
255
 
213
256
  it "deletes the matching documents" do
214
- Band.find(new_order.id).should eq(new_order)
257
+ expect(Band.find(new_order.id)).to eq(new_order)
215
258
  end
216
259
 
217
260
  it "deletes the correct number of documents" do
218
- Band.count.should eq(1)
261
+ expect(Band.count).to eq(1)
219
262
  end
220
263
 
221
264
  it "returns the number of documents deleted" do
222
- deleted.should eq(1)
265
+ expect(deleted).to eq(1)
266
+ end
267
+
268
+ context 'when the criteria has a collation' do
269
+ min_server_version '3.4'
270
+
271
+ let(:criteria) do
272
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
273
+ end
274
+
275
+ let(:context) do
276
+ described_class.new(criteria)
277
+ end
278
+
279
+ let!(:deleted) do
280
+ context.send(method)
281
+ end
282
+
283
+ it "deletes the matching documents" do
284
+ expect(Band.find(new_order.id)).to eq(new_order)
285
+ end
286
+
287
+ it "deletes the correct number of documents" do
288
+ expect(Band.count).to eq(1)
289
+ end
290
+
291
+ it "returns the number of documents deleted" do
292
+ expect(deleted).to eq(1)
293
+ end
223
294
  end
224
295
  end
225
296
 
@@ -238,7 +309,24 @@ describe Mongoid::Contextual::Mongo do
238
309
  end
239
310
 
240
311
  it "deletes all the documents" do
241
- Band.count.should eq(0)
312
+ expect(Band.count).to eq(0)
313
+ end
314
+ end
315
+
316
+ context 'when the write concern is unacknowledged' do
317
+
318
+ let(:criteria) do
319
+ Band.all
320
+ end
321
+
322
+ let!(:deleted) do
323
+ criteria.with(write: { w: 0 }) do |crit|
324
+ crit.send(method)
325
+ end
326
+ end
327
+
328
+ it 'returns 0' do
329
+ expect(deleted).to eq(0)
242
330
  end
243
331
  end
244
332
  end
@@ -249,11 +337,11 @@ describe Mongoid::Contextual::Mongo do
249
337
  describe "##{method}" do
250
338
 
251
339
  let!(:depeche_mode) do
252
- Band.create(name: "Depeche Mode")
340
+ Band.create!(name: "Depeche Mode")
253
341
  end
254
342
 
255
343
  let!(:new_order) do
256
- Band.create(name: "New Order")
344
+ Band.create!(name: "New Order")
257
345
  end
258
346
 
259
347
  context "when the selector is contraining" do
@@ -271,15 +359,43 @@ describe Mongoid::Contextual::Mongo do
271
359
  end
272
360
 
273
361
  it "destroys the matching documents" do
274
- Band.find(new_order.id).should eq(new_order)
362
+ expect(Band.find(new_order.id)).to eq(new_order)
275
363
  end
276
364
 
277
365
  it "destroys the correct number of documents" do
278
- Band.count.should eq(1)
366
+ expect(Band.count).to eq(1)
279
367
  end
280
368
 
281
369
  it "returns the number of documents destroyed" do
282
- destroyed.should eq(1)
370
+ expect(destroyed).to eq(1)
371
+ end
372
+
373
+ context 'when the criteria has a collation' do
374
+ min_server_version '3.4'
375
+
376
+ let(:criteria) do
377
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
378
+ end
379
+
380
+ let(:context) do
381
+ described_class.new(criteria)
382
+ end
383
+
384
+ let!(:destroyed) do
385
+ context.send(method)
386
+ end
387
+
388
+ it "destroys the matching documents" do
389
+ expect(Band.find(new_order.id)).to eq(new_order)
390
+ end
391
+
392
+ it "destroys the correct number of documents" do
393
+ expect(Band.count).to eq(1)
394
+ end
395
+
396
+ it "returns the number of documents destroyed" do
397
+ expect(destroyed).to eq(1)
398
+ end
283
399
  end
284
400
  end
285
401
 
@@ -298,51 +414,113 @@ describe Mongoid::Contextual::Mongo do
298
414
  end
299
415
 
300
416
  it "destroys all the documents" do
301
- Band.count.should eq(0)
417
+ expect(Band.count).to eq(0)
418
+ end
419
+ end
420
+ end
421
+
422
+ context 'when the write concern is unacknowledged' do
423
+
424
+ before do
425
+ 2.times { Band.create! }
426
+ end
427
+
428
+ let(:criteria) do
429
+ Band.all
430
+ end
431
+
432
+ let!(:deleted) do
433
+ criteria.with(write: { w: 0 }) do |crit|
434
+ crit.send(method)
302
435
  end
303
436
  end
437
+
438
+ it 'returns 0' do
439
+ expect(deleted).to eq(0)
440
+ end
304
441
  end
305
442
  end
306
443
 
307
444
  describe "#distinct" do
308
445
 
309
446
  before do
310
- Band.create(name: "Depeche Mode", years: 30)
311
- Band.create(name: "New Order", years: 25)
447
+ Band.create!(name: "Depeche Mode", years: 30, sales: "1E2")
448
+ Band.create!(name: "New Order", years: 25, sales: "2E3")
449
+ Band.create!(name: "10,000 Maniacs", years: 20, sales: "1E2")
312
450
  end
313
451
 
314
- context "when limiting the result set" do
452
+ with_config_values :legacy_pluck_distinct, true, false do
453
+ context "when limiting the result set" do
315
454
 
316
- let(:criteria) do
317
- Band.where(name: "Depeche Mode")
318
- end
455
+ let(:criteria) do
456
+ Band.where(name: "Depeche Mode")
457
+ end
319
458
 
320
- let(:context) do
321
- described_class.new(criteria)
322
- end
459
+ let(:context) do
460
+ described_class.new(criteria)
461
+ end
323
462
 
324
- it "returns the distinct matching fields" do
325
- context.distinct(:name).should eq([ "Depeche Mode" ])
463
+ it "returns the distinct matching fields" do
464
+ expect(context.distinct(:name)).to eq([ "Depeche Mode" ])
465
+ end
326
466
  end
327
- end
328
467
 
329
- context "when not limiting the result set" do
468
+ context "when not limiting the result set" do
330
469
 
331
- let(:criteria) do
332
- Band.criteria
470
+ let(:criteria) do
471
+ Band.criteria
472
+ end
473
+
474
+ let(:context) do
475
+ described_class.new(criteria)
476
+ end
477
+
478
+ it "returns the distinct field values" do
479
+ expect(context.distinct(:name).sort).to eq([ "10,000 Maniacs", "Depeche Mode", "New Order" ].sort)
480
+ end
333
481
  end
334
482
 
335
- let(:context) do
336
- described_class.new(criteria)
483
+ context "when providing an aliased field" do
484
+
485
+ let(:criteria) do
486
+ Band.criteria
487
+ end
488
+
489
+ let(:context) do
490
+ described_class.new(criteria)
491
+ end
492
+
493
+ it "returns the distinct field values" do
494
+ expect(context.distinct(:years).sort).to eq([ 20, 25, 30 ])
495
+ end
337
496
  end
338
497
 
339
- it "returns the distinct field values" do
340
- context.distinct(:name).should eq([ "Depeche Mode", "New Order" ])
498
+ context 'when a collation is specified' do
499
+ min_server_version '3.4'
500
+
501
+ before do
502
+ Band.create!(name: 'DEPECHE MODE')
503
+ end
504
+
505
+ let(:context) do
506
+ described_class.new(criteria)
507
+ end
508
+
509
+ let(:expected_results) do
510
+ ["10,000 Maniacs", "Depeche Mode", "New Order"]
511
+ end
512
+
513
+ let(:criteria) do
514
+ Band.where({}).collation(locale: 'en_US', strength: 2)
515
+ end
516
+
517
+ it 'applies the collation' do
518
+ expect(context.distinct(:name).sort).to eq(expected_results.sort)
519
+ end
341
520
  end
342
521
  end
343
522
 
344
- context "when providing an aliased field" do
345
-
523
+ context "when providing a demongoizable field" do
346
524
  let(:criteria) do
347
525
  Band.criteria
348
526
  end
@@ -351,548 +529,2037 @@ describe Mongoid::Contextual::Mongo do
351
529
  described_class.new(criteria)
352
530
  end
353
531
 
354
- it "returns the distinct field values" do
355
- context.distinct(:years).should eq([ 30, 25 ])
356
- end
357
- end
358
- end
359
-
360
- describe "#each" do
361
-
362
- before do
363
- Band.create(name: "Depeche Mode")
364
- end
532
+ context "when legacy_pluck_distinct is set" do
533
+ config_override :legacy_pluck_distinct, true
365
534
 
366
- let(:criteria) do
367
- Band.where(name: "Depeche Mode")
368
- end
535
+ context 'when storing BigDecimal as string' do
536
+ config_override :map_big_decimal_to_decimal128, false
369
537
 
370
- let(:context) do
371
- described_class.new(criteria)
372
- end
538
+ it "returns the non-demongoized distinct field values" do
539
+ expect(context.distinct(:sales).sort).to eq([ "1E2", "2E3" ])
540
+ end
541
+ end
373
542
 
374
- context "when providing a block" do
543
+ context 'when storing BigDecimal as decimal128' do
544
+ config_override :map_big_decimal_to_decimal128, true
545
+ min_bson_version '4.15.0'
546
+ max_bson_version '4.99.99'
375
547
 
376
- it "yields mongoid documents to the block" do
377
- context.each do |doc|
378
- doc.should be_a(Mongoid::Document)
548
+ it "returns the non-demongoized distinct field values" do
549
+ expect(context.distinct(:sales).sort).to eq([ BSON::Decimal128.new("1E2"), BSON::Decimal128.new("2E3") ])
550
+ end
379
551
  end
380
552
  end
381
553
 
382
- it "iterates over the matching documents" do
383
- context.each do |doc|
384
- doc.name.should eq("Depeche Mode")
385
- end
386
- end
554
+ context "when legacy_pluck_distinct is not set" do
555
+ config_override :legacy_pluck_distinct, false
387
556
 
388
- it "returns self" do
389
- context.each{}.should be(context)
557
+ it "returns the non-demongoized distinct field values" do
558
+ expect(context.distinct(:sales).sort).to eq([ BigDecimal("1E2"), BigDecimal("2E3") ])
559
+ end
390
560
  end
391
561
  end
392
562
 
393
- context "when no block is provided" do
394
-
395
- let(:enum) do
396
- context.each
563
+ context "when getting a localized field" do
564
+ before do
565
+ I18n.locale = :en
566
+ d = Dictionary.create!(description: 'english-text')
567
+ I18n.locale = :de
568
+ d.description = 'deutsch-text'
569
+ d.save!
397
570
  end
398
571
 
399
- it "returns an enumerator" do
400
- enum.should be_a(Enumerator)
572
+ let(:criteria) do
573
+ Dictionary.criteria
401
574
  end
402
575
 
403
- context "when iterating over the enumerator" do
576
+ let(:context) do
577
+ described_class.new(criteria)
578
+ end
404
579
 
405
- context "when iterating with each" do
580
+ context "when getting the field without _translations" do
581
+ context "when legacy_pluck_distinct is set" do
582
+ config_override :legacy_pluck_distinct, true
406
583
 
407
- it "yields mongoid documents to the block" do
408
- enum.each do |doc|
409
- doc.should be_a(Mongoid::Document)
410
- end
584
+ it "gets the full hash" do
585
+ expect(context.distinct(:description)).to eq([{ "de" => "deutsch-text", "en" => "english-text" }])
411
586
  end
412
587
  end
413
588
 
414
- context "when iterating with next" do
589
+ context "when legacy_pluck_distinct is not set" do
590
+ config_override :legacy_pluck_distinct, false
415
591
 
416
- it "yields mongoid documents" do
417
- enum.next.should be_a(Mongoid::Document)
592
+ it "gets the demongoized localized field" do
593
+ expect(context.distinct(:description)).to eq([ 'deutsch-text' ])
418
594
  end
419
595
  end
420
596
  end
421
- end
422
- end
423
597
 
424
- describe "#eager_load" do
598
+ context "when getting the field with _translations" do
599
+ context "when legacy_pluck_distinct is set" do
600
+ config_override :legacy_pluck_distinct, true
425
601
 
426
- let(:criteria) do
427
- Person.includes(:game)
428
- end
602
+ it "gets an empty list" do
603
+ expect(context.distinct(:description_translations)).to eq([])
604
+ end
605
+ end
606
+
607
+ context "when legacy_pluck_distinct is not set" do
608
+ config_override :legacy_pluck_distinct, false
609
+
610
+ it "gets the full hash" do
611
+ expect(context.distinct(:description_translations)).to eq([ { "de" => "deutsch-text", "en" => "english-text" } ])
612
+ end
613
+ end
614
+ end
615
+
616
+ context 'when plucking a specific locale' do
617
+
618
+ let(:distinct) do
619
+ context.distinct(:'description.de')
620
+ end
621
+
622
+ context "when legacy_pluck_distinct is set" do
623
+ config_override :legacy_pluck_distinct, true
624
+
625
+ it 'returns the specific translation' do
626
+ expect(distinct).to eq([ 'deutsch-text' ])
627
+ end
628
+ end
629
+
630
+ context "when legacy_pluck_distinct is not set" do
631
+ config_override :legacy_pluck_distinct, false
632
+
633
+ it 'returns the specific translation' do
634
+ expect(distinct).to eq([ "deutsch-text" ])
635
+ end
636
+ end
637
+ end
638
+
639
+ context 'when plucking a specific locale from _translations field' do
640
+
641
+ let(:distinct) do
642
+ context.distinct(:'description_translations.de')
643
+ end
644
+
645
+ context "when legacy_pluck_distinct is set" do
646
+ config_override :legacy_pluck_distinct, true
647
+
648
+ it 'returns the empty list' do
649
+ expect(distinct).to eq([])
650
+ end
651
+ end
652
+
653
+ context "when legacy_pluck_distinct is not set" do
654
+ config_override :legacy_pluck_distinct, false
655
+
656
+ it 'returns the specific translations' do
657
+ expect(distinct).to eq(['deutsch-text'])
658
+ end
659
+ end
660
+ end
661
+
662
+ context 'when fallbacks are enabled with a locale list' do
663
+ require_fallbacks
664
+
665
+ around(:all) do |example|
666
+ prev_fallbacks = I18n.fallbacks.dup
667
+ I18n.fallbacks[:he] = [ :en ]
668
+ example.run
669
+ I18n.fallbacks = prev_fallbacks
670
+ end
671
+
672
+ let(:distinct) do
673
+ context.distinct(:description).first
674
+ end
675
+
676
+ context "when legacy_pluck_distinct is set" do
677
+ config_override :legacy_pluck_distinct, true
678
+
679
+ it "does not correctly use the fallback" do
680
+ distinct.should == {"de"=>"deutsch-text", "en"=>"english-text"}
681
+ end
682
+ end
683
+
684
+ context "when legacy_pluck_distinct is not set" do
685
+ config_override :legacy_pluck_distinct, false
686
+
687
+ it "correctly uses the fallback" do
688
+ I18n.locale = :en
689
+ d = Dictionary.create!(description: 'english-text')
690
+ I18n.locale = :he
691
+ distinct.should == "english-text"
692
+ end
693
+ end
694
+ end
695
+
696
+ context "when the localized field is embedded" do
697
+ before do
698
+ p = Passport.new
699
+ I18n.locale = :en
700
+ p.name = "Neil"
701
+ I18n.locale = :he
702
+ p.name = "Nissim"
703
+
704
+ Person.create!(passport: p, employer_id: 12345)
705
+ end
706
+
707
+ let(:criteria) do
708
+ Person.where(employer_id: 12345)
709
+ end
710
+
711
+ let(:context) do
712
+ described_class.new(criteria)
713
+ end
714
+
715
+ let(:distinct) do
716
+ context.distinct("pass.name").first
717
+ end
718
+
719
+ let(:distinct_translations) do
720
+ context.distinct("pass.name_translations").first
721
+ end
722
+
723
+ let(:distinct_translations_field) do
724
+ context.distinct("pass.name_translations.en").first
725
+ end
726
+
727
+ context "when legacy_pluck_distinct is set" do
728
+ config_override :legacy_pluck_distinct, true
729
+
730
+ it "returns the full hash" do
731
+ expect(distinct).to eq({ "en" => "Neil", "he" => "Nissim" })
732
+ end
733
+
734
+ it "returns the empty hash" do
735
+ expect(distinct_translations).to eq(nil)
736
+ end
737
+
738
+ it "returns the empty hash" do
739
+ expect(distinct_translations_field).to eq(nil)
740
+ end
741
+ end
742
+
743
+ context "when legacy_pluck_distinct is not set" do
744
+ config_override :legacy_pluck_distinct, false
745
+
746
+ it "returns the translation for the current locale" do
747
+ expect(distinct).to eq("Nissim")
748
+ end
749
+
750
+ it "returns the full _translation hash" do
751
+ expect(distinct_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
752
+ end
753
+
754
+ it "returns the translation for the requested locale" do
755
+ expect(distinct_translations_field).to eq("Neil")
756
+ end
757
+ end
758
+ end
759
+ end
760
+
761
+ context "when getting an embedded field" do
762
+
763
+ let(:label) { Label.new(sales: "1E2") }
764
+ let!(:band) { Band.create!(label: label) }
765
+ let(:criteria) { Band.where(_id: band.id) }
766
+ let(:context) { described_class.new(criteria) }
767
+
768
+ context "when legacy_pluck_distinct is set" do
769
+ config_override :legacy_pluck_distinct, true
770
+ config_override :map_big_decimal_to_decimal128, true
771
+ max_bson_version '4.99.99'
772
+
773
+ it "returns the distinct matching fields" do
774
+ expect(context.distinct("label.sales")).to eq([ BSON::Decimal128.new('1E+2') ])
775
+ end
776
+ end
777
+
778
+ context "when legacy_pluck_distinct is not set" do
779
+ config_override :legacy_pluck_distinct, false
780
+ it "returns the distinct matching fields" do
781
+ expect(context.distinct("label.sales")).to eq([ BigDecimal("1E2") ])
782
+ end
783
+ end
784
+ end
785
+ end
786
+
787
+ describe "#tally" do
788
+ let(:fans1) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
789
+ let(:fans2) { [ Fanatic.new(age:1), Fanatic.new(age:2) ] }
790
+ let(:fans3) { [ Fanatic.new(age:1), Fanatic.new(age:3) ] }
791
+
792
+ let(:genres1) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 3 } ]}
793
+ let(:genres2) { [ { x: 1, y: { z: 1 } }, { x: 2, y: { z: 2 } }, { y: 4 } ]}
794
+ let(:genres3) { [ { x: 1, y: { z: 1 } }, { x: 3, y: { z: 3 } }, { y: 5 } ]}
795
+
796
+ let(:label1) { Label.new(name: "Atlantic") }
797
+ let(:label2) { Label.new(name: "Atlantic") }
798
+ let(:label3) { Label.new(name: "Columbia") }
799
+
800
+ before do
801
+ Band.create!(origin: "tally", name: "Depeche Mode", years: 30, sales: "1E2", label: label1, genres: genres1)
802
+ Band.create!(origin: "tally", name: "New Order", years: 30, sales: "2E3", label: label2, genres: genres2)
803
+ Band.create!(origin: "tally", name: "10,000 Maniacs", years: 30, sales: "1E2", label: label3, genres: genres3)
804
+ Band.create!(origin: "tally2", fanatics: fans1, genres: [1, 2])
805
+ Band.create!(origin: "tally2", fanatics: fans2, genres: [1, 2])
806
+ Band.create!(origin: "tally2", fanatics: fans3, genres: [1, 3])
807
+ end
808
+
809
+ let(:criteria) { Band.where(origin: "tally") }
810
+
811
+ context "when tallying a string" do
812
+ let(:tally) do
813
+ criteria.tally(:name)
814
+ end
815
+
816
+ it "returns the correct hash" do
817
+ expect(tally).to eq("Depeche Mode" => 1, "New Order" => 1, "10,000 Maniacs" => 1)
818
+ end
819
+ end
820
+
821
+ context "using an aliased field" do
822
+ let(:tally) do
823
+ criteria.tally(:years)
824
+ end
825
+
826
+ it "returns the correct hash" do
827
+ expect(tally).to eq(30 => 3)
828
+ end
829
+ end
830
+
831
+ context "when tallying a demongoizable field" do
832
+ let(:tally) do
833
+ criteria.tally(:sales)
834
+ end
835
+
836
+ it "returns the correct hash" do
837
+ expect(tally).to eq(BigDecimal("1E2") => 2, BigDecimal("2E3") => 1)
838
+ end
839
+ end
840
+
841
+ context "when tallying a localized field" do
842
+ before do
843
+ I18n.locale = :en
844
+ d1 = Dictionary.create!(description: 'en1')
845
+ d2 = Dictionary.create!(description: 'en1')
846
+ d3 = Dictionary.create!(description: 'en1')
847
+ d4 = Dictionary.create!(description: 'en2')
848
+ I18n.locale = :de
849
+ d1.description = 'de1'
850
+ d2.description = 'de1'
851
+ d3.description = 'de2'
852
+ d4.description = 'de3'
853
+ d1.save!
854
+ d2.save!
855
+ d3.save!
856
+ d4.save!
857
+
858
+ I18n.locale = :en
859
+ end
860
+
861
+ context "when getting the demongoized field" do
862
+ let(:tallied) do
863
+ Dictionary.tally(:description)
864
+ end
865
+
866
+ it "returns the translation for the current locale" do
867
+ expect(tallied).to eq("en1" => 3, "en2" => 1)
868
+ end
869
+ end
870
+
871
+ context "when getting a specific locale" do
872
+ let(:tallied) do
873
+ Dictionary.tally("description.de")
874
+ end
875
+
876
+ it "returns the translation for the the specific locale" do
877
+ expect(tallied).to eq("de1" => 2, "de2" => 1, "de3" => 1)
878
+ end
879
+ end
880
+
881
+ context "when getting the full hash" do
882
+ let(:tallied) do
883
+ Dictionary.tally("description_translations")
884
+ end
885
+
886
+ it "returns the correct hash" do
887
+ expect(tallied).to eq(
888
+ {"de" => "de1", "en" => "en1" } => 2,
889
+ {"de" => "de2", "en" => "en1" } => 1,
890
+ {"de" => "de3", "en" => "en2" } => 1
891
+ )
892
+ end
893
+ end
894
+ end
895
+
896
+ context "when tallying an embedded localized field" do
897
+
898
+ before do
899
+ I18n.locale = :en
900
+ address1a = Address.new(name: "en1")
901
+ address1b = Address.new(name: "en2")
902
+ address2a = Address.new(name: "en1")
903
+ address2b = Address.new(name: "en3")
904
+ I18n.locale = :de
905
+ address1a.name = "de1"
906
+ address1b.name = "de2"
907
+ address2a.name = "de1"
908
+ address2b.name = "de3"
909
+ Person.create!(addresses: [ address1a, address1b ])
910
+ Person.create!(addresses: [ address2a, address2b ])
911
+
912
+ I18n.locale = :en
913
+ end
914
+
915
+ context "when getting the demongoized field" do
916
+ let(:tallied) do
917
+ Person.tally("addresses.name")
918
+ end
919
+
920
+ it "returns the translation for the current locale" do
921
+ expect(tallied).to eq(
922
+ [ "en1", "en2" ] => 1,
923
+ [ "en1", "en3" ] => 1,
924
+ )
925
+ end
926
+ end
927
+
928
+ context "when getting a specific locale" do
929
+ let(:tallied) do
930
+ Person.tally("addresses.name.de")
931
+ end
932
+
933
+ it "returns the translation for the the specific locale" do
934
+ expect(tallied).to eq(
935
+ [ "de1", "de2" ] => 1,
936
+ [ "de1", "de3" ] => 1,
937
+ )
938
+ end
939
+ end
940
+
941
+ context "when getting the full hash" do
942
+ let(:tallied) do
943
+ Person.tally("addresses.name_translations")
944
+ end
945
+
946
+ it "returns the correct hash" do
947
+ expect(tallied).to eq(
948
+ [{ "de" => "de1", "en" => "en1" }, { "de" => "de2", "en" => "en2" }] => 1,
949
+ [{ "de" => "de1", "en" => "en1" }, { "de" => "de3", "en" => "en3" }] => 1,
950
+ )
951
+ end
952
+ end
953
+
954
+ end
955
+
956
+ context "when tallying an embedded field" do
957
+ let(:tally) do
958
+ criteria.tally("label.name")
959
+ end
960
+
961
+ it "returns the correct hash" do
962
+ expect(tally).to eq("Atlantic" => 2, "Columbia" => 1)
963
+ end
964
+ end
965
+
966
+ context "when tallying an element in an embeds_many field" do
967
+ let(:criteria) { Band.where(origin: "tally2") }
968
+
969
+ let(:tally) do
970
+ criteria.tally("fanatics.age")
971
+ end
972
+
973
+ it "returns the correct hash" do
974
+ expect(tally).to eq(
975
+ [1, 2] => 2,
976
+ [1, 3] => 1
977
+ )
978
+ end
979
+ end
980
+
981
+ context "when tallying an embeds_many field" do
982
+ let(:criteria) { Band.where(origin: "tally2") }
983
+
984
+ let(:tally) do
985
+ criteria.tally("fanatics")
986
+ end
987
+
988
+ it "returns the correct hash" do
989
+ expect(tally).to eq(
990
+ fans1.map(&:attributes) => 1,
991
+ fans2.map(&:attributes) => 1,
992
+ fans3.map(&:attributes) => 1,
993
+ )
994
+ end
995
+ end
996
+
997
+ context "when tallying a field of type array" do
998
+ let(:criteria) { Band.where(origin: "tally2") }
999
+
1000
+ let(:tally) do
1001
+ criteria.tally("genres")
1002
+ end
1003
+
1004
+ it "returns the correct hash" do
1005
+ expect(tally).to eq(
1006
+ [1, 2] => 2,
1007
+ [1, 3] => 1
1008
+ )
1009
+ end
1010
+ end
1011
+
1012
+ context "when tallying an element from an array of hashes" do
1013
+ let(:criteria) { Band.where(origin: "tally") }
1014
+
1015
+ let(:tally) do
1016
+ criteria.tally("genres.x")
1017
+ end
1018
+
1019
+ it "returns the correct hash without the nil keys" do
1020
+ expect(tally).to eq(
1021
+ [1, 2] => 2,
1022
+ [1, 3] => 1
1023
+ )
1024
+ end
1025
+ end
1026
+
1027
+ context "when tallying an element from an array of hashes; with duplicate" do
1028
+
1029
+ before do
1030
+ Band.create!(origin: "tally", genres: [ { x: 1 }, {x: 1} ] )
1031
+ end
1032
+
1033
+ let(:criteria) { Band.where(origin: "tally") }
1034
+
1035
+ let(:tally) do
1036
+ criteria.tally("genres.x")
1037
+ end
1038
+
1039
+ it "returns the correct hash without the nil keys" do
1040
+ expect(tally).to eq(
1041
+ [1, 2] => 2,
1042
+ [1, 3] => 1,
1043
+ [1, 1] => 1,
1044
+ )
1045
+ end
1046
+ end
1047
+
1048
+ context "when tallying an aliased field of type array" do
1049
+
1050
+ before do
1051
+ Person.create!(array: [ 1, 2 ])
1052
+ Person.create!(array: [ 1, 3 ])
1053
+ end
1054
+
1055
+ let(:tally) do
1056
+ Person.tally("array")
1057
+ end
1058
+
1059
+ it "returns the correct hash" do
1060
+ expect(tally).to eq(
1061
+ [1, 2] => 1,
1062
+ [1, 3] => 1
1063
+ )
1064
+ end
1065
+ end
1066
+
1067
+ context "when going multiple levels deep in arrays" do
1068
+ let(:criteria) { Band.where(origin: "tally") }
1069
+
1070
+ let(:tally) do
1071
+ criteria.tally("genres.y.z")
1072
+ end
1073
+
1074
+ it "returns the correct hash" do
1075
+ expect(tally).to eq(
1076
+ [1, 2] => 2,
1077
+ [1, 3] => 1
1078
+ )
1079
+ end
1080
+ end
1081
+
1082
+ context "when going multiple levels deep in an array" do
1083
+ let(:criteria) { Band.where(origin: "tally") }
1084
+
1085
+ let(:tally) do
1086
+ criteria.tally("genres.y.z")
1087
+ end
1088
+
1089
+ it "returns the correct hash" do
1090
+ expect(tally).to eq(
1091
+ [1, 2] => 2,
1092
+ [1, 3] => 1
1093
+ )
1094
+ end
1095
+ end
1096
+
1097
+ context "when tallying deeply nested arrays/embedded associations" do
1098
+
1099
+ before do
1100
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
1101
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
1102
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
1103
+ end
1104
+
1105
+ let(:tally) do
1106
+ Person.tally("addresses.code.deepest.array.y.z")
1107
+ end
1108
+
1109
+ it "returns the correct hash" do
1110
+ expect(tally).to eq(
1111
+ [ [ 1, 2 ] ] => 2,
1112
+ [ [ 1, 3 ] ] => 1
1113
+ )
1114
+ end
1115
+ end
1116
+
1117
+ context "when tallying deeply nested arrays/embedded associations" do
1118
+
1119
+ before do
1120
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
1121
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
1122
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))),
1123
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
1124
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))),
1125
+ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
1126
+ end
1127
+
1128
+ let(:tally) do
1129
+ Person.tally("addresses.code.deepest.array.y.z")
1130
+ end
1131
+
1132
+ it "returns the correct hash" do
1133
+ expect(tally).to eq(
1134
+ [ [ 1, 2 ], [ 1, 2 ] ] => 2,
1135
+ [ [ 1, 3 ], [ 1, 3 ] ] => 1
1136
+ )
1137
+ end
1138
+ end
1139
+
1140
+ context "when some keys are missing" do
1141
+ before do
1142
+ 3.times { Band.create!(origin: "tally") }
1143
+ end
1144
+
1145
+ let(:tally) do
1146
+ criteria.tally(:name)
1147
+ end
1148
+
1149
+ it "returns the correct hash" do
1150
+ expect(tally).to eq(
1151
+ "Depeche Mode" => 1,
1152
+ "New Order" => 1,
1153
+ "10,000 Maniacs" => 1,
1154
+ nil => 3
1155
+ )
1156
+ end
1157
+ end
1158
+
1159
+ context "when the first element is an embeds_one" do
1160
+ before do
1161
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
1162
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 2) ]))
1163
+ Person.create!(name: Name.new(translations: [ Translation.new(language: 1), Translation.new(language: 3) ]))
1164
+ end
1165
+
1166
+ let(:tally) do
1167
+ Person.tally("name.translations.language")
1168
+ end
1169
+
1170
+ it "returns the correct hash" do
1171
+ expect(tally).to eq(
1172
+ [1, 2] => 2,
1173
+ [1, 3] => 1
1174
+ )
1175
+ end
1176
+ end
1177
+
1178
+ context "when tallying demongoizable values from typeless fields" do
1179
+
1180
+ let!(:person1) { Person.create!(ssn: /hello/) }
1181
+ let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
1182
+ let(:tally) { Person.tally("ssn") }
1183
+
1184
+ context "< BSON 5" do
1185
+ max_bson_version '4.99.99'
1186
+
1187
+ it "stores the correct types in the database" do
1188
+ Person.find(person1.id).attributes["ssn"].should be_a BSON::Regexp::Raw
1189
+ Person.find(person2.id).attributes["ssn"].should be_a BSON::Decimal128
1190
+ end
1191
+
1192
+ it "tallies the correct type" do
1193
+ tally.keys.map(&:class).sort do |a,b|
1194
+ a.to_s <=> b.to_s
1195
+ end.should == [BSON::Decimal128, BSON::Regexp::Raw]
1196
+ end
1197
+ end
1198
+
1199
+ context ">= BSON 5" do
1200
+ min_bson_version "5.0"
1201
+
1202
+ it "stores the correct types in the database" do
1203
+ Person.find(person1.id).ssn.should be_a BSON::Regexp::Raw
1204
+ Person.find(person2.id).ssn.should be_a BigDeimal
1205
+ end
1206
+
1207
+ it "tallies the correct type" do
1208
+ tally.keys.map(&:class).sort do |a,b|
1209
+ a.to_s <=> b.to_s
1210
+ end.should == [BigDecimal, BSON::Regexp::Raw]
1211
+ end
1212
+ end
1213
+ end
1214
+ end
1215
+
1216
+ describe "#each" do
1217
+
1218
+ before do
1219
+ Band.create!(name: "Depeche Mode")
1220
+ end
1221
+
1222
+ let(:criteria) do
1223
+ Band.where(name: "Depeche Mode")
1224
+ end
1225
+
1226
+ let(:context) do
1227
+ described_class.new(criteria)
1228
+ end
1229
+
1230
+ context 'when the criteria has a collation' do
1231
+ min_server_version '3.4'
1232
+
1233
+ let(:criteria) do
1234
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1235
+ end
1236
+
1237
+ it "yields mongoid documents to the block" do
1238
+ context.each do |doc|
1239
+ expect(doc).to be_a(Mongoid::Document)
1240
+ end
1241
+ end
1242
+
1243
+ it "iterates over the matching documents" do
1244
+ context.each do |doc|
1245
+ expect(doc.name).to eq("Depeche Mode")
1246
+ end
1247
+ end
1248
+
1249
+ it "returns self" do
1250
+ expect(context.each{}).to be(context)
1251
+ end
1252
+ end
1253
+
1254
+ context "when providing a block" do
1255
+
1256
+ it "yields mongoid documents to the block" do
1257
+ context.each do |doc|
1258
+ expect(doc).to be_a(Mongoid::Document)
1259
+ end
1260
+ end
1261
+
1262
+ it "iterates over the matching documents" do
1263
+ context.each do |doc|
1264
+ expect(doc.name).to eq("Depeche Mode")
1265
+ end
1266
+ end
1267
+
1268
+ it "returns self" do
1269
+ expect(context.each{}).to be(context)
1270
+ end
1271
+ end
1272
+
1273
+ context "when no block is provided" do
1274
+
1275
+ let(:enum) do
1276
+ context.each
1277
+ end
1278
+
1279
+ it "returns an enumerator" do
1280
+ expect(enum).to be_a(Enumerator)
1281
+ end
1282
+
1283
+ context "when iterating over the enumerator" do
1284
+
1285
+ context "when iterating with each" do
1286
+
1287
+ it "yields mongoid documents to the block" do
1288
+ enum.each do |doc|
1289
+ expect(doc).to be_a(Mongoid::Document)
1290
+ end
1291
+ end
1292
+ end
1293
+
1294
+ context "when iterating with next" do
1295
+
1296
+ before do
1297
+ 10.times { |i| Band.create!(name: "Test #{i}") }
1298
+ end
1299
+
1300
+ let(:criteria) do
1301
+ Band.batch_size(5)
1302
+ end
1303
+
1304
+ it "yields mongoid documents" do
1305
+ expect(enum.next).to be_a(Mongoid::Document)
1306
+ end
1307
+
1308
+ it "does not load all documents" do
1309
+ subscriber = Mrss::EventSubscriber.new
1310
+ context.view.client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
1311
+
1312
+ enum.next
1313
+
1314
+ find_events = subscriber.all_events.select do |evt|
1315
+ evt.command_name == 'find'
1316
+ end
1317
+ expect(find_events.length).to be(2)
1318
+ get_more_events = subscriber.all_events.select do |evt|
1319
+ evt.command_name == 'getMore'
1320
+ end
1321
+ expect(get_more_events.length).to be(0)
1322
+ ensure
1323
+ context.view.client.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
1324
+ end
1325
+ end
1326
+ end
1327
+ end
1328
+
1329
+ context 'when the criteria has a parent document' do
1330
+
1331
+ before do
1332
+ Post.create!(person: person)
1333
+ Post.create!(person: person)
1334
+ Post.create!(person: person)
1335
+ end
1336
+
1337
+ let(:person) do
1338
+ Person.new
1339
+ end
1340
+
1341
+ let(:criteria) do
1342
+ person.posts.all
1343
+ end
1344
+
1345
+ let(:persons) do
1346
+ criteria.collect(&:person)
1347
+ end
1348
+
1349
+ it 'sets the same parent object on each related object' do
1350
+ expect(persons.uniq.size).to eq(1)
1351
+ end
1352
+ end
1353
+ end
1354
+
1355
+ describe "#eager_load" do
1356
+
1357
+ let(:criteria) do
1358
+ Person.includes(:game)
1359
+ end
1360
+
1361
+ let(:context) do
1362
+ described_class.new(criteria)
1363
+ end
1364
+
1365
+ context "when no documents are returned" do
1366
+
1367
+ let(:game_association) do
1368
+ Person.reflect_on_association(:game)
1369
+ end
1370
+
1371
+ it "does not make any additional database queries" do
1372
+ expect(game_association).to receive(:eager_load).never
1373
+ context.send(:eager_load, [])
1374
+ end
1375
+ end
1376
+ end
1377
+
1378
+ describe "#exists?" do
1379
+
1380
+ before do
1381
+ Band.create!(name: "Depeche Mode")
1382
+ end
1383
+
1384
+ context "when the count is zero" do
1385
+
1386
+ let(:criteria) do
1387
+ Band.where(name: "New Order")
1388
+ end
1389
+
1390
+ let(:context) do
1391
+ described_class.new(criteria)
1392
+ end
1393
+
1394
+ it "returns false" do
1395
+ expect(context).to_not be_exists
1396
+ end
1397
+ end
1398
+
1399
+ context "when the count is greater than zero" do
1400
+
1401
+ let(:criteria) do
1402
+ Band.where(name: "Depeche Mode")
1403
+ end
1404
+
1405
+ let(:context) do
1406
+ described_class.new(criteria)
1407
+ end
1408
+
1409
+ it "returns true" do
1410
+ expect(context).to be_exists
1411
+ end
1412
+ end
1413
+
1414
+ context "when caching is not enabled" do
1415
+
1416
+ let(:criteria) do
1417
+ Band.where(name: "Depeche Mode")
1418
+ end
1419
+
1420
+ let(:context) do
1421
+ described_class.new(criteria)
1422
+ end
1423
+
1424
+ context "when exists? already called and query cache is enabled" do
1425
+ query_cache_enabled
1426
+
1427
+ before do
1428
+ context.exists?
1429
+ end
1430
+
1431
+ it "does not hit the database again" do
1432
+ expect_no_queries do
1433
+ expect(context).to be_exists
1434
+ end
1435
+ end
1436
+ end
1437
+ end
1438
+ end
1439
+
1440
+ describe "#explain" do
1441
+
1442
+ let(:criteria) do
1443
+ Band.where(name: "Depeche Mode")
1444
+ end
1445
+
1446
+ let(:context) do
1447
+ described_class.new(criteria)
1448
+ end
1449
+
1450
+ it "returns the criteria explain path" do
1451
+ expect(context.explain).to_not be_empty
1452
+ end
1453
+ end
1454
+
1455
+ describe "#find_one_and_replace" do
1456
+
1457
+ let!(:depeche) do
1458
+ Band.create!(name: "Depeche Mode")
1459
+ end
1460
+
1461
+ let!(:tool) do
1462
+ Band.create!(name: "Tool")
1463
+ end
1464
+
1465
+ context "when the selector matches" do
1466
+
1467
+ context "when not providing options" do
1468
+
1469
+ let(:criteria) do
1470
+ Band.where(name: "Depeche Mode")
1471
+ end
1472
+
1473
+ let(:context) do
1474
+ described_class.new(criteria)
1475
+ end
1476
+
1477
+ let!(:result) do
1478
+ context.find_one_and_replace(name: 'FKA Twigs')
1479
+ end
1480
+
1481
+ it "returns the first matching document" do
1482
+ expect(result).to eq(depeche)
1483
+ end
1484
+
1485
+ it "updates the document in the database" do
1486
+ expect(depeche.reload.name).to eq('FKA Twigs')
1487
+ end
1488
+ end
1489
+
1490
+ context "when sorting" do
1491
+
1492
+ let(:criteria) do
1493
+ Band.desc(:name)
1494
+ end
1495
+
1496
+ let(:context) do
1497
+ described_class.new(criteria)
1498
+ end
1499
+
1500
+ let!(:result) do
1501
+ context.find_one_and_replace(likes: 1)
1502
+ end
1503
+
1504
+ it "returns the first matching document" do
1505
+ expect(result).to eq(tool)
1506
+ end
1507
+
1508
+ it "updates the document in the database" do
1509
+ expect(tool.reload.likes).to eq(1)
1510
+ expect(tool.reload.name).to be_nil
1511
+ end
1512
+ end
1513
+
1514
+ context "when limiting fields" do
1515
+
1516
+ let(:criteria) do
1517
+ Band.only(:_id)
1518
+ end
1519
+
1520
+ let(:context) do
1521
+ described_class.new(criteria)
1522
+ end
1523
+
1524
+ let!(:result) do
1525
+ context.find_one_and_replace(name: 'FKA Twigs', likes: 1)
1526
+ end
1527
+
1528
+ it "returns the first matching document" do
1529
+ expect(result).to eq(depeche)
1530
+ end
1531
+
1532
+ it "limits the returned fields" do
1533
+ expect(result.name).to be_nil
1534
+ end
1535
+
1536
+ it "updates the document in the database" do
1537
+ expect(depeche.reload.likes).to eq(1)
1538
+ end
1539
+ end
1540
+
1541
+ context "when returning new" do
1542
+
1543
+ let(:criteria) do
1544
+ Band.where(name: "Depeche Mode")
1545
+ end
1546
+
1547
+ let(:context) do
1548
+ described_class.new(criteria)
1549
+ end
1550
+
1551
+ let!(:result) do
1552
+ context.find_one_and_replace({ likes: 1 }, return_document: :after)
1553
+ end
1554
+
1555
+ it "returns the first matching document" do
1556
+ expect(result).to eq(depeche)
1557
+ end
1558
+
1559
+ it "returns the updated document" do
1560
+ expect(result.name).to be_nil
1561
+ expect(result.likes).to eq(1)
1562
+ end
1563
+ end
1564
+
1565
+ context 'when a collation is specified on the criteria' do
1566
+ min_server_version '3.4'
1567
+
1568
+ let(:criteria) do
1569
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1570
+ end
1571
+
1572
+ let(:context) do
1573
+ described_class.new(criteria)
1574
+ end
1575
+
1576
+ let!(:result) do
1577
+ context.find_one_and_replace({ likes: 1 }, return_document: :after)
1578
+ end
1579
+
1580
+ it "returns the first matching document" do
1581
+ expect(result).to eq(depeche)
1582
+ end
1583
+
1584
+ it "returns the updated document" do
1585
+ expect(result.likes).to eq(1)
1586
+ expect(result.name).to be_nil
1587
+ end
1588
+ end
1589
+ end
1590
+
1591
+ context "when the selector does not match" do
1592
+
1593
+ let(:criteria) do
1594
+ Band.where(name: "DEPECHE MODE")
1595
+ end
1596
+
1597
+ let(:context) do
1598
+ described_class.new(criteria)
1599
+ end
1600
+
1601
+ let(:result) do
1602
+ context.find_one_and_replace(name: 'FKA Twigs')
1603
+ end
1604
+
1605
+ it "returns nil" do
1606
+ expect(result).to be_nil
1607
+ end
1608
+ end
1609
+ end
1610
+
1611
+ describe "#find_one_and_update" do
1612
+
1613
+ let!(:depeche) do
1614
+ Band.create!(name: "Depeche Mode")
1615
+ end
1616
+
1617
+ let!(:tool) do
1618
+ Band.create!(name: "Tool")
1619
+ end
1620
+
1621
+ context "when the selector matches" do
1622
+
1623
+ context "when not providing options" do
1624
+
1625
+ let(:criteria) do
1626
+ Band.where(name: "Depeche Mode")
1627
+ end
1628
+
1629
+ let(:context) do
1630
+ described_class.new(criteria)
1631
+ end
1632
+
1633
+ let!(:result) do
1634
+ context.find_one_and_update("$inc" => { likes: 1 })
1635
+ end
1636
+
1637
+ it "returns the first matching document" do
1638
+ expect(result).to eq(depeche)
1639
+ end
1640
+
1641
+ it "updates the document in the database" do
1642
+ expect(depeche.reload.likes).to eq(1)
1643
+ end
1644
+ end
1645
+
1646
+ context "when sorting" do
1647
+
1648
+ let(:criteria) do
1649
+ Band.desc(:name)
1650
+ end
1651
+
1652
+ let(:context) do
1653
+ described_class.new(criteria)
1654
+ end
1655
+
1656
+ let!(:result) do
1657
+ context.find_one_and_update("$inc" => { likes: 1 })
1658
+ end
1659
+
1660
+ it "returns the first matching document" do
1661
+ expect(result).to eq(tool)
1662
+ end
1663
+
1664
+ it "updates the document in the database" do
1665
+ expect(tool.reload.likes).to eq(1)
1666
+ end
1667
+ end
1668
+
1669
+ context "when limiting fields" do
1670
+
1671
+ let(:criteria) do
1672
+ Band.only(:_id)
1673
+ end
1674
+
1675
+ let(:context) do
1676
+ described_class.new(criteria)
1677
+ end
1678
+
1679
+ let!(:result) do
1680
+ context.find_one_and_update("$inc" => { likes: 1 })
1681
+ end
1682
+
1683
+ it "returns the first matching document" do
1684
+ expect(result).to eq(depeche)
1685
+ end
1686
+
1687
+ it "limits the returned fields" do
1688
+ expect(result.name).to be_nil
1689
+ end
1690
+
1691
+ it "updates the document in the database" do
1692
+ expect(depeche.reload.likes).to eq(1)
1693
+ end
1694
+ end
1695
+
1696
+ context "when returning new" do
1697
+
1698
+ let(:criteria) do
1699
+ Band.where(name: "Depeche Mode")
1700
+ end
1701
+
1702
+ let(:context) do
1703
+ described_class.new(criteria)
1704
+ end
1705
+
1706
+ let!(:result) do
1707
+ context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
1708
+ end
1709
+
1710
+ it "returns the first matching document" do
1711
+ expect(result).to eq(depeche)
1712
+ end
1713
+
1714
+ it "returns the updated document" do
1715
+ expect(result.likes).to eq(1)
1716
+ end
1717
+ end
1718
+
1719
+ context 'when a collation is specified on the criteria' do
1720
+ min_server_version '3.4'
1721
+
1722
+ let(:criteria) do
1723
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1724
+ end
1725
+
1726
+ let(:context) do
1727
+ described_class.new(criteria)
1728
+ end
1729
+
1730
+ let!(:result) do
1731
+ context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
1732
+ end
1733
+
1734
+ it "returns the first matching document" do
1735
+ expect(result).to eq(depeche)
1736
+ end
1737
+
1738
+ it "returns the updated document" do
1739
+ expect(result.likes).to eq(1)
1740
+ end
1741
+ end
1742
+ end
1743
+
1744
+ context "when the selector does not match" do
1745
+
1746
+ let(:criteria) do
1747
+ Band.where(name: "Placebo")
1748
+ end
1749
+
1750
+ let(:context) do
1751
+ described_class.new(criteria)
1752
+ end
1753
+
1754
+ let(:result) do
1755
+ context.find_one_and_update("$inc" => { likes: 1 })
1756
+ end
1757
+
1758
+ it "returns nil" do
1759
+ expect(result).to be_nil
1760
+ end
1761
+ end
1762
+ end
1763
+
1764
+ describe "#find_one_and_delete" do
1765
+
1766
+ let!(:depeche) do
1767
+ Band.create!(name: "Depeche Mode")
1768
+ end
1769
+
1770
+ let(:criteria) do
1771
+ Band.where(name: "Depeche Mode")
1772
+ end
429
1773
 
430
1774
  let(:context) do
431
1775
  described_class.new(criteria)
432
1776
  end
433
1777
 
434
- context "when no documents are returned" do
1778
+ let!(:result) do
1779
+ context.find_one_and_delete
1780
+ end
1781
+
1782
+ context 'when the selector matches a document' do
1783
+
1784
+ it "returns the first matching document" do
1785
+ expect(result).to eq(depeche)
1786
+ end
1787
+
1788
+ it "deletes the document from the database" do
1789
+ expect {
1790
+ depeche.reload
1791
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1792
+ end
1793
+
1794
+ context 'when a collation is specified on the criteria' do
1795
+ min_server_version '3.4'
1796
+
1797
+ let(:criteria) do
1798
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1799
+ end
1800
+
1801
+ let(:context) do
1802
+ described_class.new(criteria)
1803
+ end
1804
+
1805
+ let!(:result) do
1806
+ context.find_one_and_delete
1807
+ end
1808
+
1809
+ it "returns the first matching document" do
1810
+ expect(result).to eq(depeche)
1811
+ end
1812
+
1813
+ it "deletes the document from the database" do
1814
+ expect {
1815
+ depeche.reload
1816
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1817
+ end
1818
+ end
1819
+ end
1820
+
1821
+ context 'when the selector does not match a document' do
1822
+
1823
+ let(:criteria) do
1824
+ Band.where(name: "Placebo")
1825
+ end
1826
+
1827
+ let(:context) do
1828
+ described_class.new(criteria)
1829
+ end
1830
+
1831
+ let(:result) do
1832
+ context.find_one_and_delete
1833
+ end
1834
+
1835
+ it "returns nil" do
1836
+ expect(result).to be_nil
1837
+ end
1838
+ end
1839
+ end
1840
+
1841
+ [ :first, :one ].each do |method|
1842
+
1843
+ describe "##{method}" do
1844
+
1845
+ let!(:depeche_mode) do
1846
+ Band.create!(name: "Depeche Mode")
1847
+ end
1848
+
1849
+ let!(:new_order) do
1850
+ Band.create!(name: "New Order")
1851
+ end
1852
+
1853
+ let!(:rolling_stones) do
1854
+ Band.create!(name: "The Rolling Stones")
1855
+ end
1856
+
1857
+ context "when the context is not cached" do
1858
+
1859
+ let(:criteria) do
1860
+ Band.where(name: "Depeche Mode")
1861
+ end
1862
+
1863
+ let(:context) do
1864
+ described_class.new(criteria)
1865
+ end
1866
+
1867
+ it "returns the first matching document" do
1868
+ expect(context.send(method)).to eq(depeche_mode)
1869
+ end
1870
+
1871
+ context 'when the criteria has a collation' do
1872
+ min_server_version '3.4'
1873
+
1874
+ let(:criteria) do
1875
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1876
+ end
1877
+
1878
+ it "returns the first matching document" do
1879
+ expect(context.send(method)).to eq(depeche_mode)
1880
+ end
1881
+ end
1882
+ end
1883
+
1884
+ context "when using .desc" do
1885
+
1886
+ let(:criteria) do
1887
+ Band.desc(:name)
1888
+ end
1889
+
1890
+ let(:context) do
1891
+ described_class.new(criteria)
1892
+ end
1893
+
1894
+ context "when there is sort on the context" do
1895
+
1896
+ it "follows the main sort" do
1897
+ expect(context.send(method)).to eq(rolling_stones)
1898
+ end
1899
+ end
1900
+
1901
+ context "when subsequently calling #last" do
1902
+
1903
+ it "returns the correct document" do
1904
+ expect(context.send(method)).to eq(rolling_stones)
1905
+ expect(context.last).to eq(depeche_mode)
1906
+ end
1907
+ end
1908
+ end
1909
+
1910
+ context 'when the criteria has no sort' do
1911
+
1912
+ let(:criteria) do
1913
+ Band.all
1914
+ end
1915
+
1916
+ let(:context) do
1917
+ described_class.new(criteria)
1918
+ end
1919
+
1920
+
1921
+ it 'applies a sort on _id' do
1922
+ expect(context.send(method)).to eq(depeche_mode)
1923
+ end
1924
+
1925
+ context 'when calling #last' do
1926
+
1927
+ it 'returns the last document, sorted by _id' do
1928
+ expect(context.send(method)).to eq(depeche_mode)
1929
+ expect(context.last).to eq(rolling_stones)
1930
+ end
1931
+ end
1932
+ end
1933
+
1934
+ context 'when the criteria has a sort' do
1935
+
1936
+ let(:criteria) do
1937
+ Band.desc(:name)
1938
+ end
1939
+
1940
+ let(:context) do
1941
+ described_class.new(criteria)
1942
+ end
1943
+
1944
+ it 'applies the criteria sort' do
1945
+ expect(context.send(method)).to eq(rolling_stones)
1946
+ end
1947
+
1948
+ context 'when calling #last' do
1949
+
1950
+ it 'applies the criteria sort' do
1951
+ expect(context.send(method)).to eq(rolling_stones)
1952
+ expect(context.last).to eq(depeche_mode)
1953
+ end
1954
+ end
1955
+ end
1956
+
1957
+ context "when using .sort" do
1958
+
1959
+ let(:criteria) do
1960
+ Band.all.sort(:name => -1).criteria
1961
+ end
1962
+
1963
+ let(:context) do
1964
+ described_class.new(criteria)
1965
+ end
1966
+
1967
+ context "when there is sort on the context" do
1968
+
1969
+ it "follows the main sort" do
1970
+ expect(context.send(method)).to eq(rolling_stones)
1971
+ end
1972
+ end
1973
+
1974
+ context "when subsequently calling #last" do
1975
+
1976
+ it "returns the correct document" do
1977
+ expect(context.send(method)).to eq(rolling_stones)
1978
+ expect(context.last).to eq(depeche_mode)
1979
+ end
1980
+ end
1981
+ end
1982
+
1983
+ context "when the query cache is enabled" do
1984
+ query_cache_enabled
1985
+
1986
+ let(:criteria) do
1987
+ Band.where(name: "Depeche Mode")
1988
+ end
1989
+
1990
+ let(:context) do
1991
+ described_class.new(criteria)
1992
+ end
1993
+
1994
+ context "when first method was called before" do
1995
+
1996
+ before do
1997
+ context.first
1998
+ end
1999
+
2000
+ it "returns the first document without touching the database" do
2001
+ expect_no_queries do
2002
+ expect(context.send(method)).to eq(depeche_mode)
2003
+ end
2004
+ end
2005
+ end
2006
+ end
2007
+
2008
+ context "when including a limit" do
2009
+
2010
+ context "when the context is not cached" do
2011
+
2012
+ let(:context) do
2013
+ described_class.new(criteria)
2014
+ end
2015
+
2016
+ context "when the limit is 1" do
2017
+ let(:criteria) do
2018
+ Band.criteria
2019
+ end
2020
+
2021
+ let(:docs) do
2022
+ context.send(method, 1)
2023
+ end
2024
+
2025
+ it "returns an array of documents" do
2026
+ expect(docs).to eq([ depeche_mode ])
2027
+ end
2028
+ end
2029
+
2030
+ context "when the limit is >1" do
2031
+ let(:criteria) do
2032
+ Band.criteria
2033
+ end
2034
+
2035
+ let(:docs) do
2036
+ context.send(method, 2)
2037
+ end
2038
+
2039
+ it "returns the number of documents in order" do
2040
+ expect(docs).to eq([ depeche_mode, new_order ])
2041
+ end
2042
+ end
2043
+
2044
+ context 'when the criteria has a collation' do
2045
+ min_server_version '3.4'
2046
+
2047
+ let(:criteria) do
2048
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
2049
+ end
2050
+
2051
+ it "returns the first matching document" do
2052
+ expect(context.send(method, 1)).to eq([ depeche_mode ])
2053
+ end
2054
+ end
2055
+ end
2056
+
2057
+ context "when the query cache is enabled" do
2058
+
2059
+ let(:context) do
2060
+ described_class.new(criteria)
2061
+ end
2062
+
2063
+ context "when calling first beforehand" do
2064
+ query_cache_enabled
2065
+
2066
+ let(:context) do
2067
+ described_class.new(criteria)
2068
+ end
2069
+
2070
+ let(:criteria) do
2071
+ Band.all
2072
+ end
2073
+
2074
+ before do
2075
+ context.first(before_limit)
2076
+ end
2077
+
2078
+ let(:docs) do
2079
+ context.send(method, limit)
2080
+ end
435
2081
 
436
- let(:game_metadata) do
437
- Person.reflect_on_association(:game)
438
- end
2082
+ context "when getting all of the documents before" do
2083
+ let(:before_limit) { 3 }
439
2084
 
440
- it "does not make any additional database queries" do
441
- game_metadata.should_receive(:eager_load).never
442
- context.send(:eager_load, [])
443
- end
444
- end
445
- end
2085
+ context "when getting all of the documents" do
2086
+ let(:limit) { 3 }
446
2087
 
447
- describe "#exists?" do
2088
+ it "returns all documents without touching the database" do
2089
+ expect_no_queries do
2090
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2091
+ end
2092
+ end
2093
+ end
448
2094
 
449
- before do
450
- Band.create(name: "Depeche Mode")
451
- end
2095
+ context "when getting fewer documents" do
2096
+ let(:limit) { 2 }
452
2097
 
453
- context "when the count is zero" do
2098
+ it "returns the correct documents without touching the database" do
2099
+ expect_no_queries do
2100
+ expect(docs).to eq([ depeche_mode, new_order ])
2101
+ end
2102
+ end
2103
+ end
2104
+ end
454
2105
 
455
- let(:criteria) do
456
- Band.where(name: "New Order")
457
- end
2106
+ context "when getting fewer documents before" do
2107
+ let(:before_limit) { 2 }
458
2108
 
459
- let(:context) do
460
- described_class.new(criteria)
461
- end
2109
+ context "when getting the same number of documents" do
2110
+ let(:limit) { 2 }
462
2111
 
463
- it "returns false" do
464
- context.should_not be_exists
465
- end
466
- end
2112
+ it "returns the correct documents without touching the database" do
2113
+ expect_no_queries do
2114
+ expect(docs).to eq([ depeche_mode, new_order ])
2115
+ end
2116
+ end
2117
+ end
467
2118
 
468
- context "when the count is greater than zero" do
2119
+ context "when getting more documents" do
2120
+ let(:limit) { 3 }
469
2121
 
470
- let(:criteria) do
471
- Band.where(name: "Depeche Mode")
472
- end
2122
+ it "returns the correct documents and touches the database" do
2123
+ expect_query(1) do
2124
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2125
+ end
2126
+ end
2127
+ end
2128
+ end
473
2129
 
474
- let(:context) do
475
- described_class.new(criteria)
476
- end
2130
+ context "when getting one document before" do
2131
+ let(:before_limit) { 1 }
477
2132
 
478
- it "returns true" do
479
- context.should be_exists
480
- end
481
- end
2133
+ context "when getting one document" do
2134
+ let(:limit) { 1 }
482
2135
 
483
- context "when caching is enabled" do
2136
+ it "returns the correct documents without touching the database" do
2137
+ expect_no_queries do
2138
+ expect(docs).to eq([ depeche_mode ])
2139
+ end
2140
+ end
2141
+ end
484
2142
 
485
- let(:criteria) do
486
- Band.where(name: "Depeche Mode").cache
487
- end
2143
+ context "when getting more than one document" do
2144
+ let(:limit) { 3 }
488
2145
 
489
- let(:context) do
490
- described_class.new(criteria)
2146
+ it "returns the correct documents and touches the database" do
2147
+ expect_query(1) do
2148
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2149
+ end
2150
+ end
2151
+ end
2152
+ end
2153
+ end
2154
+ end
491
2155
  end
492
2156
 
493
- context "when the cache is loaded" do
2157
+ context "when calling #first then #last and the query cache is enabled" do
2158
+ query_cache_enabled
494
2159
 
495
- before do
496
- context.to_a
2160
+ let(:context) do
2161
+ described_class.new(criteria)
497
2162
  end
498
2163
 
499
- it "does not hit the database" do
500
- context.should_receive(:query).never
501
- context.should be_exists
2164
+ let(:criteria) do
2165
+ Band.all
502
2166
  end
503
- end
504
2167
 
505
- context "when the cache is not loaded" do
2168
+ before do
2169
+ context.first(before_limit)
2170
+ end
506
2171
 
507
- context "when a count has been executed" do
2172
+ let(:docs) do
2173
+ context.last(limit)
2174
+ end
508
2175
 
509
- before do
510
- context.count
511
- end
2176
+ context "when getting one from the beginning and one from the end" do
2177
+ let(:before_limit) { 2 }
2178
+ let(:limit) { 1 }
512
2179
 
513
- it "does not hit the database" do
514
- context.should_receive(:query).never
515
- context.should be_exists
2180
+ it "gets the correct document and hits the database" do
2181
+ expect_query(1) do
2182
+ expect(docs).to eq([rolling_stones])
2183
+ end
516
2184
  end
517
2185
  end
518
2186
  end
519
2187
  end
520
2188
  end
521
2189
 
522
- describe "#explain" do
523
-
524
- let(:criteria) do
525
- Band.where(name: "Depeche Mode")
526
- end
527
-
528
- let(:context) do
529
- described_class.new(criteria)
530
- end
531
-
532
- it "returns the criteria explain path" do
533
- context.explain["cursor"].should eq("BasicCursor")
2190
+ describe "#last" do
2191
+ let!(:depeche_mode) do
2192
+ Band.create!(name: "Depeche Mode")
534
2193
  end
535
- end
536
-
537
- describe "#find_and_modify" do
538
2194
 
539
- let!(:depeche) do
540
- Band.create(name: "Depeche Mode")
2195
+ let!(:new_order) do
2196
+ Band.create!(name: "New Order")
541
2197
  end
542
2198
 
543
- let!(:tool) do
544
- Band.create(name: "Tool")
2199
+ let!(:rolling_stones) do
2200
+ Band.create!(name: "The Rolling Stones")
545
2201
  end
546
2202
 
547
- context "when the selector matches" do
548
-
549
- context "when not providing options" do
550
-
551
- let(:criteria) do
552
- Band.where(name: "Depeche Mode")
553
- end
554
-
555
- let(:context) do
556
- described_class.new(criteria)
557
- end
2203
+ context "when the context is not cached" do
558
2204
 
559
- let!(:result) do
560
- context.find_and_modify("$inc" => { likes: 1 })
561
- end
2205
+ let(:criteria) do
2206
+ Band.where(name: "Depeche Mode")
2207
+ end
562
2208
 
563
- it "returns the first matching document" do
564
- result.should eq(depeche)
565
- end
2209
+ let(:context) do
2210
+ described_class.new(criteria)
2211
+ end
566
2212
 
567
- it "updates the document in the database" do
568
- depeche.reload.likes.should eq(1)
569
- end
2213
+ it "returns the last matching document" do
2214
+ expect(context.last).to eq(depeche_mode)
570
2215
  end
571
2216
 
572
- context "when sorting" do
2217
+ context 'when the criteria has a collation' do
2218
+ min_server_version '3.4'
573
2219
 
574
2220
  let(:criteria) do
575
- Band.desc(:name)
576
- end
577
-
578
- let(:context) do
579
- described_class.new(criteria)
2221
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
580
2222
  end
581
2223
 
582
- let!(:result) do
583
- context.find_and_modify("$inc" => { likes: 1 })
2224
+ it "returns the last matching document" do
2225
+ expect(context.last).to eq(depeche_mode)
584
2226
  end
2227
+ end
2228
+ end
585
2229
 
586
- it "returns the first matching document" do
587
- result.should eq(tool)
588
- end
2230
+ context "when using .desc" do
589
2231
 
590
- it "updates the document in the database" do
591
- tool.reload.likes.should eq(1)
592
- end
2232
+ let(:criteria) do
2233
+ Band.desc(:name)
593
2234
  end
594
2235
 
595
- context "when limiting fields" do
2236
+ let(:context) do
2237
+ described_class.new(criteria)
2238
+ end
596
2239
 
597
- let(:criteria) do
598
- Band.only(:_id)
599
- end
2240
+ context "when there is sort on the context" do
600
2241
 
601
- let(:context) do
602
- described_class.new(criteria)
2242
+ it "follows the main sort" do
2243
+ expect(context.last).to eq(depeche_mode)
603
2244
  end
2245
+ end
604
2246
 
605
- let!(:result) do
606
- context.find_and_modify("$inc" => { likes: 1 })
607
- end
2247
+ context "when subsequently calling #first" do
608
2248
 
609
- it "returns the first matching document" do
610
- result.should eq(depeche)
2249
+ it "returns the correct document" do
2250
+ expect(context.last).to eq(depeche_mode)
2251
+ expect(context.first).to eq(rolling_stones)
611
2252
  end
2253
+ end
2254
+ end
612
2255
 
613
- it "limits the returned fields" do
614
- result.name.should be_nil
615
- end
2256
+ context 'when the criteria has no sort' do
616
2257
 
617
- it "updates the document in the database" do
618
- depeche.reload.likes.should eq(1)
619
- end
2258
+ let(:criteria) do
2259
+ Band.all
620
2260
  end
621
2261
 
622
- context "when returning new" do
2262
+ let(:context) do
2263
+ described_class.new(criteria)
2264
+ end
623
2265
 
624
- let(:criteria) do
625
- Band.where(name: "Depeche Mode")
626
- end
2266
+ it 'applies a sort on _id' do
2267
+ expect(context.last).to eq(rolling_stones)
2268
+ end
627
2269
 
628
- let(:context) do
629
- described_class.new(criteria)
630
- end
2270
+ context 'when calling #first' do
631
2271
 
632
- let!(:result) do
633
- context.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
2272
+ it 'returns the first document, sorted by _id' do
2273
+ expect(context.last).to eq(rolling_stones)
2274
+ expect(context.first).to eq(depeche_mode)
634
2275
  end
2276
+ end
2277
+ end
635
2278
 
636
- it "returns the first matching document" do
637
- result.should eq(depeche)
638
- end
2279
+ context 'when the criteria has a sort' do
639
2280
 
640
- it "returns the updated document" do
641
- result.likes.should eq(1)
642
- end
2281
+ let(:criteria) do
2282
+ Band.desc(:name)
643
2283
  end
644
2284
 
645
- context "when removing" do
646
-
647
- let(:criteria) do
648
- Band.where(name: "Depeche Mode")
649
- end
2285
+ let(:context) do
2286
+ described_class.new(criteria)
2287
+ end
650
2288
 
651
- let(:context) do
652
- described_class.new(criteria)
653
- end
654
2289
 
655
- let!(:result) do
656
- context.find_and_modify({}, remove: true)
657
- end
2290
+ it 'applies the criteria sort' do
2291
+ expect(context.last).to eq(depeche_mode)
2292
+ end
658
2293
 
659
- it "returns the first matching document" do
660
- result.should eq(depeche)
661
- end
2294
+ context 'when calling #first' do
662
2295
 
663
- it "deletes the document from the database" do
664
- expect {
665
- depeche.reload
666
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2296
+ it 'applies the criteria sort' do
2297
+ expect(context.last).to eq(depeche_mode)
2298
+ expect(context.first).to eq(rolling_stones)
667
2299
  end
668
2300
  end
669
2301
  end
670
2302
 
671
- context "when the selector does not match" do
2303
+ context "when using .sort" do
672
2304
 
673
2305
  let(:criteria) do
674
- Band.where(name: "Placebo")
2306
+ Band.all.sort(:name => -1).criteria
675
2307
  end
676
2308
 
677
2309
  let(:context) do
678
2310
  described_class.new(criteria)
679
2311
  end
680
2312
 
681
- let(:result) do
682
- context.find_and_modify("$inc" => { likes: 1 })
2313
+ context "when there is sort on the context" do
2314
+
2315
+ it "follows the main sort" do
2316
+ expect(context.last).to eq(depeche_mode)
2317
+ end
683
2318
  end
684
2319
 
685
- it "returns nil" do
686
- result.should be_nil
2320
+ context "when subsequently calling #first" do
2321
+
2322
+ it "returns the correct document" do
2323
+ expect(context.last).to eq(depeche_mode)
2324
+ expect(context.first).to eq(rolling_stones)
2325
+ end
687
2326
  end
688
2327
  end
689
- end
690
2328
 
691
- [ :first, :one ].each do |method|
692
-
693
- describe "##{method}" do
2329
+ context "when the query cache is enabled" do
2330
+ query_cache_enabled
694
2331
 
695
- let!(:depeche_mode) do
696
- Band.create(name: "Depeche Mode")
2332
+ let(:criteria) do
2333
+ Band.where(name: "Depeche Mode")
697
2334
  end
698
2335
 
699
- let!(:new_order) do
700
- Band.create(name: "New Order")
2336
+ let(:context) do
2337
+ described_class.new(criteria)
701
2338
  end
702
2339
 
703
- context "when the context is not cached" do
704
-
705
- let(:criteria) do
706
- Band.where(name: "Depeche Mode")
707
- end
2340
+ context "when last method was called before" do
708
2341
 
709
- let(:context) do
710
- described_class.new(criteria)
2342
+ before do
2343
+ context.last
711
2344
  end
712
2345
 
713
- it "returns the first matching document" do
714
- context.send(method).should eq(depeche_mode)
2346
+ it "returns the last document without touching the database" do
2347
+ expect_no_queries do
2348
+ expect(context.last).to eq(depeche_mode)
2349
+ end
715
2350
  end
716
2351
  end
2352
+ end
717
2353
 
718
- context "when using .desc" do
2354
+ context "when including a limit" do
719
2355
 
720
- let(:criteria) do
721
- Band.desc(:name)
722
- end
2356
+ context "when the context is not cached" do
723
2357
 
724
2358
  let(:context) do
725
2359
  described_class.new(criteria)
726
2360
  end
727
2361
 
728
- context "when there is sort on the context" do
729
-
730
- it "follows the main sort" do
731
- context.send(method).should eq(new_order)
2362
+ context "when the limit is 1" do
2363
+ let(:criteria) do
2364
+ Band.criteria
732
2365
  end
733
- end
734
2366
 
735
- context "when subsequently calling #last" do
2367
+ let(:docs) do
2368
+ context.last(1)
2369
+ end
736
2370
 
737
- it "returns the correnct document" do
738
- context.send(method).should eq(new_order)
739
- context.last.should eq(depeche_mode)
2371
+ it "returns an array of documents" do
2372
+ expect(docs).to eq([ rolling_stones ])
740
2373
  end
741
2374
  end
742
- end
743
2375
 
744
- context "when using .sort" do
2376
+ context "when the limit is >1" do
2377
+ let(:criteria) do
2378
+ Band.criteria
2379
+ end
745
2380
 
746
- let(:criteria) do
747
- Band.all.sort(:name => -1).criteria
748
- end
2381
+ let(:docs) do
2382
+ context.last(2)
2383
+ end
749
2384
 
750
- let(:context) do
751
- described_class.new(criteria)
2385
+ it "returns the number of documents in order" do
2386
+ expect(docs).to eq([ new_order, rolling_stones ])
2387
+ end
752
2388
  end
753
2389
 
754
- context "when there is sort on the context" do
2390
+ context 'when the criteria has a collation' do
2391
+ min_server_version '3.4'
755
2392
 
756
- it "follows the main sort" do
757
- context.send(method).should eq(new_order)
2393
+ let(:criteria) do
2394
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
758
2395
  end
759
- end
760
2396
 
761
- context "when subsequently calling #last" do
762
-
763
- it "returns the correnct document" do
764
- context.send(method).should eq(new_order)
765
- context.last.should eq(depeche_mode)
2397
+ it "returns the first matching document" do
2398
+ expect(context.last(1)).to eq([ depeche_mode ])
766
2399
  end
767
2400
  end
768
2401
  end
769
2402
 
770
2403
  context "when the context is cached" do
771
2404
 
772
- let(:criteria) do
773
- Band.where(name: "Depeche Mode").cache
774
- end
775
-
776
2405
  let(:context) do
777
2406
  described_class.new(criteria)
778
2407
  end
779
2408
 
780
- context "when the cache is loaded" do
2409
+ context "when query cache is enabled" do
2410
+ query_cache_enabled
2411
+
2412
+ let(:context) do
2413
+ described_class.new(criteria)
2414
+ end
2415
+
2416
+ let(:criteria) do
2417
+ Band.all
2418
+ end
781
2419
 
782
2420
  before do
783
- context.to_a
2421
+ context.last(before_limit)
784
2422
  end
785
2423
 
786
- it "returns the first document without touching the database" do
787
- context.should_receive(:query).never
788
- context.send(method).should eq(depeche_mode)
2424
+ let(:docs) do
2425
+ context.last(limit)
789
2426
  end
790
- end
791
- end
792
- end
793
- end
794
2427
 
795
- describe "#initialize" do
2428
+ context "when getting all of the documents before" do
2429
+ let(:before_limit) { 3 }
796
2430
 
797
- let(:criteria) do
798
- Band.where(name: "Depeche Mode").no_timeout
799
- end
2431
+ context "when getting all of the documents" do
2432
+ let(:limit) { 3 }
800
2433
 
801
- let(:context) do
802
- described_class.new(criteria)
803
- end
2434
+ it "returns all documents without touching the db" do
2435
+ expect_no_queries do
2436
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2437
+ end
2438
+ end
2439
+ end
804
2440
 
805
- it "sets the criteria" do
806
- context.criteria.should eq(criteria)
807
- end
2441
+ context "when getting fewer documents" do
2442
+ let(:limit) { 2 }
808
2443
 
809
- it "sets the klass" do
810
- context.klass.should eq(Band)
811
- end
2444
+ it "returns the correct documents without touching the db" do
2445
+ expect_no_queries do
2446
+ expect(docs).to eq([ new_order, rolling_stones ])
2447
+ end
2448
+ end
2449
+ end
2450
+ end
2451
+
2452
+ context "when getting fewer documents before" do
2453
+ let(:before_limit) { 2 }
2454
+
2455
+ context "when getting the same number of documents" do
2456
+ let(:limit) { 2 }
2457
+
2458
+ it "returns the correct documents without touching the db" do
2459
+ expect_no_queries do
2460
+ expect(docs).to eq([ new_order, rolling_stones ])
2461
+ end
2462
+ end
2463
+ end
812
2464
 
813
- it "sets the query" do
814
- context.query.should be_a(Moped::Query)
815
- end
2465
+ context "when getting more documents" do
2466
+ let(:limit) { 3 }
816
2467
 
817
- it "sets the query selector" do
818
- context.query.selector.should eq({ "name" => "Depeche Mode" })
819
- end
2468
+ it "returns the correct documents and touches the database" do
2469
+ expect_query(1) do
2470
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2471
+ end
2472
+ end
2473
+ end
2474
+ end
820
2475
 
821
- it "sets timeout options" do
822
- context.query.operation.flags.should eq([ :no_cursor_timeout ])
823
- end
824
- end
2476
+ context "when getting one document before" do
2477
+ let(:before_limit) { 1 }
825
2478
 
826
- describe "#last" do
2479
+ context "when getting one document" do
2480
+ let(:limit) { 1 }
827
2481
 
828
- context "when no default scope" do
2482
+ it "returns the correct documents without touching the database" do
2483
+ expect_no_queries do
2484
+ expect(docs).to eq([ rolling_stones ])
2485
+ end
2486
+ end
2487
+ end
829
2488
 
830
- let!(:depeche_mode) do
831
- Band.create(name: "Depeche Mode")
832
- end
2489
+ context "when getting more than one document" do
2490
+ let(:limit) { 3 }
833
2491
 
834
- let!(:new_order) do
835
- Band.create(name: "New Order")
2492
+ it "returns the correct documents and touches the database" do
2493
+ expect_query(1) do
2494
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2495
+ end
2496
+ end
2497
+ end
2498
+ end
2499
+ end
836
2500
  end
2501
+ end
837
2502
 
838
- let(:criteria) do
839
- Band.all
840
- end
2503
+ context "when calling #last then #first and the query cache is enabled" do
2504
+ query_cache_enabled
841
2505
 
842
2506
  let(:context) do
843
2507
  described_class.new(criteria)
844
2508
  end
845
2509
 
846
- it "returns the last matching document" do
847
- context.last.should eq(new_order)
2510
+ let(:criteria) do
2511
+ Band.all
848
2512
  end
849
- end
850
2513
 
851
- context "when default scope" do
852
-
853
- let!(:palm) do
854
- Tree.create(name: "Palm")
2514
+ before do
2515
+ context.last(before_limit)
855
2516
  end
856
2517
 
857
- let!(:maple) do
858
- Tree.create(name: "Maple")
2518
+ let(:docs) do
2519
+ context.first(limit)
859
2520
  end
860
2521
 
861
- let(:criteria) do
862
- Tree.all
863
- end
2522
+ context "when getting one from the beginning and one from the end" do
2523
+ let(:before_limit) { 2 }
2524
+ let(:limit) { 1 }
864
2525
 
865
- let(:context) do
866
- described_class.new(criteria)
867
- end
2526
+ it "hits the database" do
2527
+ expect_query(1) do
2528
+ docs
2529
+ end
2530
+ end
868
2531
 
869
- it "respects default scope" do
870
- context.last.should eq(palm)
2532
+ it "gets the correct document" do
2533
+ expect(docs).to eq([ depeche_mode ])
2534
+ end
871
2535
  end
872
2536
  end
2537
+ end
873
2538
 
874
- context "when subsequently calling #first" do
2539
+ describe "#initialize" do
875
2540
 
876
- let!(:depeche_mode) do
877
- Band.create(name: "Depeche Mode")
878
- end
2541
+ let(:criteria) do
2542
+ Band.where(name: "Depeche Mode").no_timeout
2543
+ end
879
2544
 
880
- let!(:new_order) do
881
- Band.create(name: "New Order")
882
- end
2545
+ let(:context) do
2546
+ described_class.new(criteria)
2547
+ end
883
2548
 
884
- let(:criteria) do
885
- Band.asc(:name)
886
- end
2549
+ it "sets the criteria" do
2550
+ expect(context.criteria).to eq(criteria)
2551
+ end
887
2552
 
888
- let(:context) do
889
- described_class.new(criteria)
890
- end
2553
+ it "sets the klass" do
2554
+ expect(context.klass).to eq(Band)
2555
+ end
891
2556
 
892
- it "returns the correnct document" do
893
- context.last.should eq(new_order)
894
- context.first.should eq(depeche_mode)
895
- end
2557
+ it "sets the view" do
2558
+ expect(context.view).to be_a(Mongo::Collection::View)
2559
+ end
2560
+
2561
+ it "sets the view selector" do
2562
+ expect(context.view.selector).to eq({ "name" => "Depeche Mode" })
896
2563
  end
897
2564
  end
898
2565
 
@@ -901,8 +2568,8 @@ describe Mongoid::Contextual::Mongo do
901
2568
  describe "##{method}" do
902
2569
 
903
2570
  before do
904
- Band.create(name: "Depeche Mode")
905
- Band.create(name: "New Order")
2571
+ Band.create!(name: "Depeche Mode")
2572
+ Band.create!(name: "New Order")
906
2573
  end
907
2574
 
908
2575
  context "when the criteria has a limit" do
@@ -915,41 +2582,28 @@ describe Mongoid::Contextual::Mongo do
915
2582
  described_class.new(criteria)
916
2583
  end
917
2584
 
918
- it "returns the number of documents that match" do
919
- context.send(method).should eq(2)
920
- end
921
-
922
- context "when calling more than once" do
923
-
924
- before do
925
- context.query.should_receive(:count).once.and_return(2)
926
- end
2585
+ context "when broken_view_options is false" do
2586
+ driver_config_override :broken_view_options, false
927
2587
 
928
- it "returns the cached value for subsequent calls" do
929
- 2.times { context.send(method).should eq(2) }
2588
+ it "returns the number of documents that match" do
2589
+ expect(context.send(method)).to eq(1)
930
2590
  end
931
2591
  end
932
2592
 
933
- context "when the results have been iterated over" do
934
-
935
- before do
936
- context.entries
937
- context.query.should_receive(:count).once.and_return(2)
938
- end
2593
+ context "when broken_view_options is true" do
2594
+ driver_config_override :broken_view_options, true
939
2595
 
940
- it "returns the cached value for all calls" do
941
- context.send(method).should eq(2)
2596
+ it "returns the number of documents that match" do
2597
+ expect(context.send(method)).to eq(2)
942
2598
  end
2599
+ end
943
2600
 
944
- context "when the results have been iterated over multiple times" do
945
-
946
- before do
947
- context.entries
948
- end
2601
+ context "when calling more than once with different limits" do
2602
+ driver_config_override :broken_view_options, false
949
2603
 
950
- it "resets the length on each full iteration" do
951
- context.should have(2).items
952
- end
2604
+ it "does not cache the value" do
2605
+ expect(context.limit(1).send(method)).to eq(1)
2606
+ expect(context.limit(2).send(method)).to eq(2)
953
2607
  end
954
2608
  end
955
2609
  end
@@ -965,17 +2619,15 @@ describe Mongoid::Contextual::Mongo do
965
2619
  end
966
2620
 
967
2621
  it "returns the number of documents that match" do
968
- context.send(method).should eq(1)
2622
+ expect(context.send(method)).to eq(1)
969
2623
  end
970
2624
 
971
- context "when calling more than once" do
2625
+ context "when calling more than once with different skips" do
2626
+ driver_config_override :broken_view_options, false
972
2627
 
973
- before do
974
- context.query.should_receive(:count).once.and_return(1)
975
- end
976
-
977
- it "returns the cached value for subsequent calls" do
978
- 2.times { context.send(method).should eq(1) }
2628
+ it "does not cache the value" do
2629
+ expect(context.skip(0).send(method)).to eq(1)
2630
+ expect(context.skip(1).send(method)).to eq(0)
979
2631
  end
980
2632
  end
981
2633
 
@@ -983,11 +2635,11 @@ describe Mongoid::Contextual::Mongo do
983
2635
 
984
2636
  before do
985
2637
  context.entries
986
- context.query.should_receive(:count).once.and_return(1)
987
2638
  end
988
2639
 
989
2640
  it "returns the cached value for all calls" do
990
- context.send(method).should eq(1)
2641
+ expect(context.view).to receive(:count_documents).once.and_return(1)
2642
+ expect(context.send(method)).to eq(1)
991
2643
  end
992
2644
 
993
2645
  context "when the results have been iterated over multiple times" do
@@ -997,7 +2649,7 @@ describe Mongoid::Contextual::Mongo do
997
2649
  end
998
2650
 
999
2651
  it "resets the length on each full iteration" do
1000
- context.should have(1).item
2652
+ expect(context.size).to eq(1)
1001
2653
  end
1002
2654
  end
1003
2655
  end
@@ -1008,11 +2660,11 @@ describe Mongoid::Contextual::Mongo do
1008
2660
  describe "#limit" do
1009
2661
 
1010
2662
  let!(:depeche_mode) do
1011
- Band.create(name: "Depeche Mode")
2663
+ Band.create!(name: "Depeche Mode")
1012
2664
  end
1013
2665
 
1014
2666
  let!(:new_order) do
1015
- Band.create(name: "New Order")
2667
+ Band.create!(name: "New Order")
1016
2668
  end
1017
2669
 
1018
2670
  let(:criteria) do
@@ -1024,15 +2676,89 @@ describe Mongoid::Contextual::Mongo do
1024
2676
  end
1025
2677
 
1026
2678
  it "limits the results" do
1027
- context.limit(1).entries.should eq([ depeche_mode ])
2679
+ expect(context.limit(1).entries).to eq([ depeche_mode ])
2680
+ end
2681
+ end
2682
+
2683
+ describe "#take" do
2684
+
2685
+ let!(:depeche_mode) do
2686
+ Band.create!(name: "Depeche Mode")
2687
+ end
2688
+
2689
+ let!(:new_order) do
2690
+ Band.create!(name: "New Order")
2691
+ end
2692
+
2693
+ let!(:rolling_stones) do
2694
+ Band.create!(name: "The Rolling Stones")
2695
+ end
2696
+
2697
+ let(:criteria) do
2698
+ Band.all
2699
+ end
2700
+
2701
+ let(:context) do
2702
+ described_class.new(criteria)
2703
+ end
2704
+
2705
+ it "takes the correct number results" do
2706
+ expect(context.take(2)).to eq([ depeche_mode, new_order ])
2707
+ end
2708
+
2709
+ it "returns an array when passing 1" do
2710
+ expect(context.take(1)).to eq([ depeche_mode ])
2711
+ end
2712
+
2713
+ it "does not return an array when not passing an argument" do
2714
+ expect(context.take).to eq(depeche_mode)
2715
+ end
2716
+
2717
+ it "returns all the documents taking more than whats in the db" do
2718
+ expect(context.take(5)).to eq([ depeche_mode, new_order, rolling_stones ])
2719
+ end
2720
+ end
2721
+
2722
+ describe "#take!" do
2723
+
2724
+ let!(:depeche_mode) do
2725
+ Band.create!(name: "Depeche Mode")
2726
+ end
2727
+
2728
+ let!(:new_order) do
2729
+ Band.create!(name: "New Order")
2730
+ end
2731
+
2732
+ let!(:rolling_stones) do
2733
+ Band.create!(name: "The Rolling Stones")
2734
+ end
2735
+
2736
+ let(:criteria) do
2737
+ Band.all
2738
+ end
2739
+
2740
+ let(:context) do
2741
+ described_class.new(criteria)
2742
+ end
2743
+
2744
+ it "takes the first document" do
2745
+ expect(context.take!).to eq(depeche_mode)
2746
+ end
2747
+
2748
+ context "when there are no documents" do
2749
+ it "raises an error" do
2750
+ expect do
2751
+ Person.take!
2752
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Person./)
2753
+ end
1028
2754
  end
1029
2755
  end
1030
2756
 
1031
2757
  describe "#map" do
1032
2758
 
1033
2759
  before do
1034
- Band.create(name: "Depeche Mode")
1035
- Band.create(name: "New Order")
2760
+ Band.create!(name: "Depeche Mode")
2761
+ Band.create!(name: "New Order")
1036
2762
  end
1037
2763
 
1038
2764
  let(:criteria) do
@@ -1045,20 +2771,17 @@ describe Mongoid::Contextual::Mongo do
1045
2771
 
1046
2772
  context "when passed the symbol field name" do
1047
2773
 
1048
- it "limits query to that field" do
1049
- criteria.should_receive(:only).with(:name).and_call_original
1050
- context.map(:name)
1051
- end
1052
-
1053
- it "performs mapping" do
1054
- context.map(:name).should eq ["Depeche Mode", "New Order"]
2774
+ it "raises an error" do
2775
+ expect do
2776
+ context.map(:name)
2777
+ end.to raise_error(ArgumentError)
1055
2778
  end
1056
2779
  end
1057
2780
 
1058
2781
  context "when passed a block" do
1059
2782
 
1060
2783
  it "performs mapping" do
1061
- context.map(&:name).should eq ["Depeche Mode", "New Order"]
2784
+ expect(context.map(&:name)).to eq ["Depeche Mode", "New Order"]
1062
2785
  end
1063
2786
  end
1064
2787
  end
@@ -1066,11 +2789,11 @@ describe Mongoid::Contextual::Mongo do
1066
2789
  describe "#map_reduce" do
1067
2790
 
1068
2791
  let!(:depeche_mode) do
1069
- Band.create(name: "Depeche Mode", likes: 200)
2792
+ Band.create!(name: "Depeche Mode", likes: 200)
1070
2793
  end
1071
2794
 
1072
2795
  let!(:tool) do
1073
- Band.create(name: "Tool", likes: 100)
2796
+ Band.create!(name: "Tool", likes: 100)
1074
2797
  end
1075
2798
 
1076
2799
  let(:map) do
@@ -1091,6 +2814,10 @@ describe Mongoid::Contextual::Mongo do
1091
2814
  }}
1092
2815
  end
1093
2816
 
2817
+ let(:ordered_results) do
2818
+ results['results'].sort_by { |doc| doc['_id'] }
2819
+ end
2820
+
1094
2821
  context "when no selection is provided" do
1095
2822
 
1096
2823
  let(:criteria) do
@@ -1106,52 +2833,56 @@ describe Mongoid::Contextual::Mongo do
1106
2833
  end
1107
2834
 
1108
2835
  it "returns the first aggregate result" do
1109
- results.should include(
2836
+ expect(results).to include(
1110
2837
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1111
2838
  )
1112
2839
  end
1113
2840
 
1114
2841
  it "returns the second aggregate result" do
1115
- results.should include(
2842
+ expect(results).to include(
1116
2843
  { "_id" => "Tool", "value" => { "likes" => 100 }}
1117
2844
  )
1118
2845
  end
1119
2846
 
1120
2847
  it "returns the correct number of documents" do
1121
- results.count.should eq(2)
2848
+ expect(results.count).to eq(2)
1122
2849
  end
1123
2850
 
1124
2851
  it "contains the entire raw results" do
1125
- results["results"].should eq([
2852
+ expect(ordered_results).to eq([
1126
2853
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1127
2854
  { "_id" => "Tool", "value" => { "likes" => 100 }}
1128
2855
  ])
1129
2856
  end
1130
2857
 
1131
- it "contains the execution time" do
1132
- results.time.should_not be_nil
1133
- end
2858
+ context 'when statistics are available' do
2859
+ max_server_version '4.2'
1134
2860
 
1135
- it "contains the count statistics" do
1136
- results["counts"].should eq({
1137
- "input" => 2, "emit" => 2, "reduce" => 0, "output" => 2
1138
- })
1139
- end
2861
+ it "contains the execution time" do
2862
+ expect(results.time).to_not be_nil
2863
+ end
1140
2864
 
1141
- it "contains the input count" do
1142
- results.input.should eq(2)
1143
- end
2865
+ it "contains the count statistics" do
2866
+ expect(results["counts"]).to eq({
2867
+ "input" => 2, "emit" => 2, "reduce" => 0, "output" => 2
2868
+ })
2869
+ end
1144
2870
 
1145
- it "contains the emitted count" do
1146
- results.emitted.should eq(2)
1147
- end
2871
+ it "contains the input count" do
2872
+ expect(results.input).to eq(2)
2873
+ end
1148
2874
 
1149
- it "contains the reduced count" do
1150
- results.reduced.should eq(0)
1151
- end
2875
+ it "contains the emitted count" do
2876
+ expect(results.emitted).to eq(2)
2877
+ end
1152
2878
 
1153
- it "contains the output count" do
1154
- results.output.should eq(2)
2879
+ it "contains the reduced count" do
2880
+ expect(results.reduced).to eq(0)
2881
+ end
2882
+
2883
+ it "contains the output count" do
2884
+ expect(results.output).to eq(2)
2885
+ end
1155
2886
  end
1156
2887
  end
1157
2888
 
@@ -1170,45 +2901,49 @@ describe Mongoid::Contextual::Mongo do
1170
2901
  end
1171
2902
 
1172
2903
  it "includes the aggregate result" do
1173
- results.should include(
2904
+ expect(results).to include(
1174
2905
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1175
2906
  )
1176
2907
  end
1177
2908
 
1178
2909
  it "returns the correct number of documents" do
1179
- results.count.should eq(1)
2910
+ expect(results.count).to eq(1)
1180
2911
  end
1181
2912
 
1182
2913
  it "contains the entire raw results" do
1183
- results["results"].should eq([
2914
+ expect(ordered_results).to eq([
1184
2915
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1185
2916
  ])
1186
2917
  end
1187
2918
 
1188
- it "contains the execution time" do
1189
- results.time.should_not be_nil
1190
- end
2919
+ context 'when statistics are available' do
2920
+ max_server_version '4.2'
1191
2921
 
1192
- it "contains the count statistics" do
1193
- results["counts"].should eq({
1194
- "input" => 1, "emit" => 1, "reduce" => 0, "output" => 1
1195
- })
1196
- end
2922
+ it "contains the execution time" do
2923
+ expect(results.time).to_not be_nil
2924
+ end
1197
2925
 
1198
- it "contains the input count" do
1199
- results.input.should eq(1)
1200
- end
2926
+ it "contains the count statistics" do
2927
+ expect(results["counts"]).to eq({
2928
+ "input" => 1, "emit" => 1, "reduce" => 0, "output" => 1
2929
+ })
2930
+ end
1201
2931
 
1202
- it "contains the emitted count" do
1203
- results.emitted.should eq(1)
1204
- end
2932
+ it "contains the input count" do
2933
+ expect(results.input).to eq(1)
2934
+ end
1205
2935
 
1206
- it "contains the reduced count" do
1207
- results.reduced.should eq(0)
1208
- end
2936
+ it "contains the emitted count" do
2937
+ expect(results.emitted).to eq(1)
2938
+ end
1209
2939
 
1210
- it "contains the output count" do
1211
- results.output.should eq(1)
2940
+ it "contains the reduced count" do
2941
+ expect(results.reduced).to eq(0)
2942
+ end
2943
+
2944
+ it "contains the output count" do
2945
+ expect(results.output).to eq(1)
2946
+ end
1212
2947
  end
1213
2948
  end
1214
2949
 
@@ -1232,23 +2967,23 @@ describe Mongoid::Contextual::Mongo do
1232
2967
  end
1233
2968
 
1234
2969
  it "returns the first aggregate result" do
1235
- results.should include(
2970
+ expect(results).to include(
1236
2971
  { "_id" => "Tool", "value" => { "likes" => 100 }}
1237
2972
  )
1238
2973
  end
1239
2974
 
1240
2975
  it "returns the second aggregate result" do
1241
- results.should include(
2976
+ expect(results).to include(
1242
2977
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1243
2978
  )
1244
2979
  end
1245
2980
 
1246
2981
  it "returns the correct number of documents" do
1247
- results.count.should eq(2)
2982
+ expect(results.count).to eq(2)
1248
2983
  end
1249
2984
 
1250
2985
  it "contains the entire raw results" do
1251
- results["results"].should eq([
2986
+ expect(ordered_results).to eq([
1252
2987
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1253
2988
  { "_id" => "Tool", "value" => { "likes" => 100 }}
1254
2989
  ])
@@ -1256,6 +2991,9 @@ describe Mongoid::Contextual::Mongo do
1256
2991
  end
1257
2992
 
1258
2993
  context "when limiting is provided" do
2994
+ # map/reduce with limit is not supported on sharded clusters:
2995
+ # https://jira.mongodb.org/browse/SERVER-2099
2996
+ require_topology :single, :replica_set
1259
2997
 
1260
2998
  let(:criteria) do
1261
2999
  Band.limit(1)
@@ -1270,17 +3008,17 @@ describe Mongoid::Contextual::Mongo do
1270
3008
  end
1271
3009
 
1272
3010
  it "returns the first aggregate result" do
1273
- results.should include(
3011
+ expect(results).to include(
1274
3012
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1275
3013
  )
1276
3014
  end
1277
3015
 
1278
3016
  it "returns the correct number of documents" do
1279
- results.count.should eq(1)
3017
+ expect(results.count).to eq(1)
1280
3018
  end
1281
3019
 
1282
3020
  it "contains the entire raw results" do
1283
- results["results"].should eq([
3021
+ expect(results["results"]).to eq([
1284
3022
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1285
3023
  ])
1286
3024
  end
@@ -1301,11 +3039,11 @@ describe Mongoid::Contextual::Mongo do
1301
3039
  end
1302
3040
 
1303
3041
  it "returns the correct number of documents" do
1304
- results.count.should eq(1)
3042
+ expect(results.count).to eq(1)
1305
3043
  end
1306
3044
 
1307
3045
  it "contains the entire results" do
1308
- results.should eq([
3046
+ expect(results).to eq([
1309
3047
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1310
3048
  ])
1311
3049
  end
@@ -1326,11 +3064,11 @@ describe Mongoid::Contextual::Mongo do
1326
3064
  end
1327
3065
 
1328
3066
  it "returns the correct number of documents" do
1329
- results.count.should eq(1)
3067
+ expect(results.count).to eq(1)
1330
3068
  end
1331
3069
 
1332
3070
  it "contains the entire results" do
1333
- results.should eq([
3071
+ expect(results).to eq([
1334
3072
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1335
3073
  ])
1336
3074
  end
@@ -1351,16 +3089,77 @@ describe Mongoid::Contextual::Mongo do
1351
3089
  end
1352
3090
 
1353
3091
  it "returns the correct number of documents" do
1354
- results.count.should eq(1)
3092
+ expect(results.count).to eq(1)
1355
3093
  end
1356
3094
 
1357
3095
  it "contains the entire results" do
1358
- results.should eq([
3096
+ expect(results).to eq([
1359
3097
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1360
3098
  ])
1361
3099
  end
1362
3100
  end
1363
3101
 
3102
+ context "when the output specifies a different db" do
3103
+ # Limit is not supported in sharded clusters
3104
+ require_topology :single, :replica_set
3105
+
3106
+ let(:criteria) do
3107
+ Band.limit(1)
3108
+ end
3109
+
3110
+ let(:context) do
3111
+ described_class.new(criteria)
3112
+ end
3113
+
3114
+ after do
3115
+ Band.with(database: 'another-db') do |b|
3116
+ b.all.delete
3117
+ end
3118
+ end
3119
+
3120
+ context 'when db is a string' do
3121
+
3122
+ let(:results) do
3123
+ context.map_reduce(map, reduce).out(merge: :mr_output, db: 'another-db')
3124
+ end
3125
+
3126
+ it "returns the correct number of documents" do
3127
+ expect(results.count).to eq(1)
3128
+ end
3129
+
3130
+ it "contains the entire results" do
3131
+ expect(results).to eq([
3132
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
3133
+ ])
3134
+ end
3135
+
3136
+ it 'writes to the specified db' do
3137
+ expect(Band.mongo_client.with(database: 'another-db')[:mr_output].find.count).to eq(1)
3138
+ end
3139
+ end
3140
+
3141
+ context 'when db is a symbol' do
3142
+
3143
+ let(:results) do
3144
+ context.map_reduce(map, reduce).out(merge: :mr_output, 'db' => 'another-db')
3145
+ end
3146
+
3147
+ it "returns the correct number of documents" do
3148
+ expect(results.count).to eq(1)
3149
+ end
3150
+
3151
+ it "contains the entire results" do
3152
+ expect(results).to eq([
3153
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
3154
+ ])
3155
+ end
3156
+
3157
+ it 'writes to the specified db' do
3158
+ expect(Band.mongo_client.with(database: 'another-db')[:mr_output].find.count).to eq(1)
3159
+ end
3160
+ end
3161
+ end
3162
+
1364
3163
  context "when providing no output" do
1365
3164
 
1366
3165
  let(:criteria) do
@@ -1405,11 +3204,11 @@ describe Mongoid::Contextual::Mongo do
1405
3204
  end
1406
3205
 
1407
3206
  it "returns the correct number of documents" do
1408
- results.count.should eq(1)
3207
+ expect(results.count).to eq(1)
1409
3208
  end
1410
3209
 
1411
3210
  it "contains the entire results" do
1412
- results.should eq([
3211
+ expect(results).to eq([
1413
3212
  { "_id" => "Depeche Mode", "value" => { "likes" => 200, "extra" => true }}
1414
3213
  ])
1415
3214
  end
@@ -1419,11 +3218,11 @@ describe Mongoid::Contextual::Mongo do
1419
3218
  describe "#skip" do
1420
3219
 
1421
3220
  let!(:depeche_mode) do
1422
- Band.create(name: "Depeche Mode")
3221
+ Band.create!(name: "Depeche Mode")
1423
3222
  end
1424
3223
 
1425
3224
  let!(:new_order) do
1426
- Band.create(name: "New Order")
3225
+ Band.create!(name: "New Order")
1427
3226
  end
1428
3227
 
1429
3228
  let(:criteria) do
@@ -1435,18 +3234,18 @@ describe Mongoid::Contextual::Mongo do
1435
3234
  end
1436
3235
 
1437
3236
  it "limits the results" do
1438
- context.skip(1).entries.should eq([ new_order ])
3237
+ expect(context.skip(1).entries).to eq([ new_order ])
1439
3238
  end
1440
3239
  end
1441
3240
 
1442
3241
  describe "#sort" do
1443
3242
 
1444
3243
  let!(:depeche_mode) do
1445
- Band.create(name: "Depeche Mode")
3244
+ Band.create!(name: "Depeche Mode")
1446
3245
  end
1447
3246
 
1448
3247
  let!(:new_order) do
1449
- Band.create(name: "New Order")
3248
+ Band.create!(name: "New Order")
1450
3249
  end
1451
3250
 
1452
3251
  let(:criteria) do
@@ -1460,11 +3259,11 @@ describe Mongoid::Contextual::Mongo do
1460
3259
  context "when providing a spec" do
1461
3260
 
1462
3261
  it "sorts the results" do
1463
- context.sort(name: -1).entries.should eq([ new_order, depeche_mode ])
3262
+ expect(context.sort(name: -1).entries).to eq([ new_order, depeche_mode ])
1464
3263
  end
1465
3264
 
1466
3265
  it "returns the context" do
1467
- context.sort(name: 1).should eq(context)
3266
+ expect(context.sort(name: 1)).to eq(context)
1468
3267
  end
1469
3268
  end
1470
3269
 
@@ -1477,7 +3276,7 @@ describe Mongoid::Contextual::Mongo do
1477
3276
  end
1478
3277
 
1479
3278
  it "sorts the results in memory" do
1480
- sorted.should eq([ new_order, depeche_mode ])
3279
+ expect(sorted).to eq([ new_order, depeche_mode ])
1481
3280
  end
1482
3281
  end
1483
3282
  end
@@ -1485,11 +3284,11 @@ describe Mongoid::Contextual::Mongo do
1485
3284
  describe "#update" do
1486
3285
 
1487
3286
  let!(:depeche_mode) do
1488
- Band.create(name: "Depeche Mode")
3287
+ Band.create!(name: "Depeche Mode")
1489
3288
  end
1490
3289
 
1491
3290
  let!(:new_order) do
1492
- Band.create(name: "New Order")
3291
+ Band.create!(name: "New Order")
1493
3292
  end
1494
3293
 
1495
3294
  let(:criteria) do
@@ -1500,6 +3299,26 @@ describe Mongoid::Contextual::Mongo do
1500
3299
  described_class.new(criteria)
1501
3300
  end
1502
3301
 
3302
+ context "when adding an element to a HABTM set" do
3303
+
3304
+ let(:person) do
3305
+ Person.create!
3306
+ end
3307
+
3308
+ let(:preference) do
3309
+ Preference.create!
3310
+ end
3311
+
3312
+ before do
3313
+ Person.where(id: person.id).
3314
+ update("$addToSet" => { preference_ids: preference.id })
3315
+ end
3316
+
3317
+ it "adds a single element to the array" do
3318
+ expect(person.reload.preference_ids).to eq([ preference.id ])
3319
+ end
3320
+ end
3321
+
1503
3322
  context "when providing attributes" do
1504
3323
 
1505
3324
  context "when the attributes are of the correct type" do
@@ -1509,11 +3328,11 @@ describe Mongoid::Contextual::Mongo do
1509
3328
  end
1510
3329
 
1511
3330
  it "updates only the first matching document" do
1512
- depeche_mode.reload.name.should eq("Smiths")
3331
+ expect(depeche_mode.reload.name).to eq("Smiths")
1513
3332
  end
1514
3333
 
1515
3334
  it "does not update the last matching document" do
1516
- new_order.reload.name.should eq("New Order")
3335
+ expect(new_order.reload.name).to eq("New Order")
1517
3336
  end
1518
3337
  end
1519
3338
 
@@ -1526,11 +3345,11 @@ describe Mongoid::Contextual::Mongo do
1526
3345
  end
1527
3346
 
1528
3347
  it "updates the first matching document" do
1529
- depeche_mode.reload.member_count.should eq(1)
3348
+ expect(depeche_mode.reload.member_count).to eq(1)
1530
3349
  end
1531
3350
 
1532
3351
  it "does not update the last matching document" do
1533
- new_order.reload.member_count.should be_nil
3352
+ expect(new_order.reload.member_count).to be_nil
1534
3353
  end
1535
3354
  end
1536
3355
 
@@ -1541,11 +3360,11 @@ describe Mongoid::Contextual::Mongo do
1541
3360
  end
1542
3361
 
1543
3362
  it "updates the first matching document" do
1544
- depeche_mode.reload.founded.should eq(Date.new(1979, 1, 1))
3363
+ expect(depeche_mode.reload.founded).to eq(Date.new(1979, 1, 1))
1545
3364
  end
1546
3365
 
1547
3366
  it "does not update the last matching document" do
1548
- new_order.reload.founded.should be_nil
3367
+ expect(new_order.reload.founded).to be_nil
1549
3368
  end
1550
3369
  end
1551
3370
  end
@@ -1562,11 +3381,11 @@ describe Mongoid::Contextual::Mongo do
1562
3381
  end
1563
3382
 
1564
3383
  it "updates the first matching document" do
1565
- depeche_mode.reload.name.should eq("Smiths")
3384
+ expect(depeche_mode.reload.name).to eq("Smiths")
1566
3385
  end
1567
3386
 
1568
3387
  it "does not update the last matching document" do
1569
- new_order.reload.name.should eq("New Order")
3388
+ expect(new_order.reload.name).to eq("New Order")
1570
3389
  end
1571
3390
  end
1572
3391
 
@@ -1577,11 +3396,11 @@ describe Mongoid::Contextual::Mongo do
1577
3396
  end
1578
3397
 
1579
3398
  it "updates the first matching document" do
1580
- depeche_mode.reload.member_count.should eq(1)
3399
+ expect(depeche_mode.reload.member_count).to eq(1)
1581
3400
  end
1582
3401
 
1583
3402
  it "does not update the last matching document" do
1584
- new_order.reload.member_count.should be_nil
3403
+ expect(new_order.reload.member_count).to be_nil
1585
3404
  end
1586
3405
  end
1587
3406
  end
@@ -1593,19 +3412,19 @@ describe Mongoid::Contextual::Mongo do
1593
3412
  end
1594
3413
 
1595
3414
  it "updates the first matching document's set" do
1596
- depeche_mode.reload.name.should eq("Smiths")
3415
+ expect(depeche_mode.reload.name).to eq("Smiths")
1597
3416
  end
1598
3417
 
1599
3418
  it "updates the first matching document's updates" do
1600
- depeche_mode.reload.likes.should eq(100)
3419
+ expect(depeche_mode.reload.likes).to eq(100)
1601
3420
  end
1602
3421
 
1603
3422
  it "does not update the last matching document's set" do
1604
- new_order.reload.name.should eq("New Order")
3423
+ expect(new_order.reload.name).to eq("New Order")
1605
3424
  end
1606
3425
 
1607
3426
  it "does not update the last matching document's updates" do
1608
- new_order.reload.likes.should be_nil
3427
+ expect(new_order.reload.likes).to be_nil
1609
3428
  end
1610
3429
  end
1611
3430
  end
@@ -1613,7 +3432,43 @@ describe Mongoid::Contextual::Mongo do
1613
3432
  context "when providing no attributes" do
1614
3433
 
1615
3434
  it "returns false" do
1616
- context.update.should be_false
3435
+ expect(context.update).to be false
3436
+ end
3437
+ end
3438
+
3439
+ context 'when provided array filters' do
3440
+ min_server_version '3.6'
3441
+
3442
+ before do
3443
+ Band.delete_all
3444
+ b = Band.new(name: 'Depeche Mode')
3445
+ b.labels << Label.new(name: 'Warner')
3446
+ b.labels << Label.new(name: 'Sony')
3447
+ b.labels << Label.new(name: 'Cbs')
3448
+ b.save!
3449
+
3450
+ b = Band.new(name: 'FKA Twigs')
3451
+ b.labels << Label.new(name: 'Warner')
3452
+ b.labels << Label.new(name: 'Cbs')
3453
+ b.save!
3454
+ end
3455
+
3456
+
3457
+ let(:criteria) do
3458
+ Band.where(name: 'Depeche Mode')
3459
+ end
3460
+
3461
+ let!(:update) do
3462
+ context.update({ '$set' => { 'labels.$[i].name' => 'Sony' } },
3463
+ array_filters: [{ 'i.name' => 'Cbs' }])
3464
+ end
3465
+
3466
+ it 'applies the array filters' do
3467
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
3468
+ end
3469
+
3470
+ it 'does not affect other documents' do
3471
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Cbs'])
1617
3472
  end
1618
3473
  end
1619
3474
  end
@@ -1621,11 +3476,11 @@ describe Mongoid::Contextual::Mongo do
1621
3476
  describe "#update_all" do
1622
3477
 
1623
3478
  let!(:depeche_mode) do
1624
- Band.create(name: "Depeche Mode", origin: "Essex")
3479
+ Band.create!(name: "Depeche Mode", origin: "Essex")
1625
3480
  end
1626
3481
 
1627
3482
  let!(:new_order) do
1628
- Band.create(name: "New Order")
3483
+ Band.create!(name: "New Order")
1629
3484
  end
1630
3485
 
1631
3486
  let(:criteria) do
@@ -1645,15 +3500,15 @@ describe Mongoid::Contextual::Mongo do
1645
3500
  end
1646
3501
 
1647
3502
  it "updates the first matching document" do
1648
- depeche_mode.reload.name.should eq("Smiths")
3503
+ expect(depeche_mode.reload.name).to eq("Smiths")
1649
3504
  end
1650
3505
 
1651
3506
  it "does not clear out other attributes" do
1652
- depeche_mode.reload.origin.should eq("Essex")
3507
+ expect(depeche_mode.reload.origin).to eq("Essex")
1653
3508
  end
1654
3509
 
1655
3510
  it "updates the last matching document" do
1656
- new_order.reload.name.should eq("Smiths")
3511
+ expect(new_order.reload.name).to eq("Smiths")
1657
3512
  end
1658
3513
  end
1659
3514
 
@@ -1664,11 +3519,11 @@ describe Mongoid::Contextual::Mongo do
1664
3519
  end
1665
3520
 
1666
3521
  it "updates the first matching document" do
1667
- depeche_mode.reload.member_count.should eq(1)
3522
+ expect(depeche_mode.reload.member_count).to eq(1)
1668
3523
  end
1669
3524
 
1670
3525
  it "updates the last matching document" do
1671
- new_order.reload.member_count.should eq(1)
3526
+ expect(new_order.reload.member_count).to eq(1)
1672
3527
  end
1673
3528
  end
1674
3529
 
@@ -1679,11 +3534,11 @@ describe Mongoid::Contextual::Mongo do
1679
3534
  end
1680
3535
 
1681
3536
  it "updates the first matching document" do
1682
- depeche_mode.reload.years.should eq(100)
3537
+ expect(depeche_mode.reload.years).to eq(100)
1683
3538
  end
1684
3539
 
1685
3540
  it "updates the last matching document" do
1686
- new_order.reload.years.should eq(100)
3541
+ expect(new_order.reload.years).to eq(100)
1687
3542
  end
1688
3543
  end
1689
3544
  end
@@ -1699,11 +3554,11 @@ describe Mongoid::Contextual::Mongo do
1699
3554
  end
1700
3555
 
1701
3556
  it "updates the first matching document" do
1702
- depeche_mode.reload.name.should eq("Smiths")
3557
+ expect(depeche_mode.reload.name).to eq("Smiths")
1703
3558
  end
1704
3559
 
1705
3560
  it "updates the last matching document" do
1706
- new_order.reload.name.should eq("Smiths")
3561
+ expect(new_order.reload.name).to eq("Smiths")
1707
3562
  end
1708
3563
  end
1709
3564
 
@@ -1714,11 +3569,11 @@ describe Mongoid::Contextual::Mongo do
1714
3569
  end
1715
3570
 
1716
3571
  it "updates the first matching document" do
1717
- depeche_mode.reload.member_count.should eq(1)
3572
+ expect(depeche_mode.reload.member_count).to eq(1)
1718
3573
  end
1719
3574
 
1720
3575
  it "updates the last matching document" do
1721
- new_order.reload.member_count.should eq(1)
3576
+ expect(new_order.reload.member_count).to eq(1)
1722
3577
  end
1723
3578
  end
1724
3579
  end
@@ -1730,19 +3585,19 @@ describe Mongoid::Contextual::Mongo do
1730
3585
  end
1731
3586
 
1732
3587
  it "updates the first matching document's set" do
1733
- depeche_mode.reload.name.should eq("Smiths")
3588
+ expect(depeche_mode.reload.name).to eq("Smiths")
1734
3589
  end
1735
3590
 
1736
3591
  it "updates the first matching document's updates" do
1737
- depeche_mode.reload.likes.should eq(100)
3592
+ expect(depeche_mode.reload.likes).to eq(100)
1738
3593
  end
1739
3594
 
1740
3595
  it "updates the last matching document's set" do
1741
- new_order.reload.name.should eq("Smiths")
3596
+ expect(new_order.reload.name).to eq("Smiths")
1742
3597
  end
1743
3598
 
1744
3599
  it "updates the last matching document's updates" do
1745
- new_order.reload.likes.should eq(100)
3600
+ expect(new_order.reload.likes).to eq(100)
1746
3601
  end
1747
3602
  end
1748
3603
  end
@@ -1750,7 +3605,74 @@ describe Mongoid::Contextual::Mongo do
1750
3605
  context "when providing no attributes" do
1751
3606
 
1752
3607
  it "returns false" do
1753
- context.update_all.should be_false
3608
+ expect(context.update_all).to be false
3609
+ end
3610
+ end
3611
+
3612
+ context 'when provided array filters' do
3613
+ min_server_version '3.6'
3614
+
3615
+ before do
3616
+ Band.delete_all
3617
+ b = Band.new(name: 'Depeche Mode')
3618
+ b.labels << Label.new(name: 'Warner')
3619
+ b.labels << Label.new(name: 'Sony')
3620
+ b.labels << Label.new(name: 'Cbs')
3621
+ b.save!
3622
+
3623
+ b = Band.new(name: 'FKA Twigs')
3624
+ b.labels << Label.new(name: 'Warner')
3625
+ b.labels << Label.new(name: 'Cbs')
3626
+ b.save!
3627
+ end
3628
+
3629
+
3630
+ let(:criteria) do
3631
+ Band.all
3632
+ end
3633
+
3634
+ let!(:update) do
3635
+ context.update_all({ '$set' => { 'labels.$[i].name' => 'Sony' } },
3636
+ array_filters: [{ 'i.name' => 'Cbs' }])
3637
+ end
3638
+
3639
+ it 'applies the array filters' do
3640
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
3641
+ end
3642
+
3643
+ it 'updates all documents' do
3644
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Sony'])
3645
+ end
3646
+ end
3647
+ end
3648
+
3649
+ describe '#pipeline' do
3650
+
3651
+ context 'when the criteria has a selector' do
3652
+
3653
+ before do
3654
+ Artist.index(name: "text")
3655
+ Artist.create_indexes
3656
+ end
3657
+
3658
+ let(:criteria) do
3659
+ Artist.text_search("New Order")
3660
+ end
3661
+
3662
+ let(:context) do
3663
+ described_class.new(criteria)
3664
+ end
3665
+
3666
+ let(:pipeline_match) do
3667
+ context.send(:pipeline, :some_field).first['$match']
3668
+ end
3669
+
3670
+ it 'creates a pipeline with the selector as one of the $match criteria' do
3671
+ expect(pipeline_match).to include({ '$text' => { '$search' => "New Order" } })
3672
+ end
3673
+
3674
+ it 'creates a pipeline with the $exists operator as one of the $match criteria' do
3675
+ expect(pipeline_match).to include({ 'some_field' => { '$exists' => true } })
1754
3676
  end
1755
3677
  end
1756
3678
  end