mongoid 7.5.4 → 8.1.9

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 (446) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -3
  3. data/README.md +6 -6
  4. data/Rakefile +44 -46
  5. data/lib/config/locales/en.yml +92 -43
  6. data/lib/mongoid/association/accessors.rb +44 -11
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +5 -3
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +32 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  16. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  17. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  18. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +85 -46
  20. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  21. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  23. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  24. data/lib/mongoid/association/macros.rb +8 -1
  25. data/lib/mongoid/association/many.rb +11 -7
  26. data/lib/mongoid/association/nested/many.rb +5 -4
  27. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  28. data/lib/mongoid/association/nested/one.rb +45 -7
  29. data/lib/mongoid/association/one.rb +2 -2
  30. data/lib/mongoid/association/options.rb +9 -9
  31. data/lib/mongoid/association/proxy.rb +15 -4
  32. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  33. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  34. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  35. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  36. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  37. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  38. data/lib/mongoid/association/referenced/eager.rb +2 -2
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  41. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  42. data/lib/mongoid/association/referenced/has_many/proxy.rb +40 -21
  43. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  44. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  45. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  46. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  47. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  48. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  49. data/lib/mongoid/association/reflections.rb +4 -4
  50. data/lib/mongoid/association/relatable.rb +44 -10
  51. data/lib/mongoid/association.rb +5 -5
  52. data/lib/mongoid/atomic/modifiers.rb +2 -2
  53. data/lib/mongoid/atomic.rb +16 -7
  54. data/lib/mongoid/attributes/dynamic.rb +4 -4
  55. data/lib/mongoid/attributes/nested.rb +6 -6
  56. data/lib/mongoid/attributes/processing.rb +37 -6
  57. data/lib/mongoid/attributes/projector.rb +2 -2
  58. data/lib/mongoid/attributes/readonly.rb +11 -6
  59. data/lib/mongoid/attributes.rb +51 -42
  60. data/lib/mongoid/changeable.rb +147 -14
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/storage_options.rb +2 -5
  64. data/lib/mongoid/clients/validators/storage.rb +3 -15
  65. data/lib/mongoid/collection_configurable.rb +58 -0
  66. data/lib/mongoid/composable.rb +2 -0
  67. data/lib/mongoid/config/defaults.rb +60 -0
  68. data/lib/mongoid/config/options.rb +3 -0
  69. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  70. data/lib/mongoid/config/validators/client.rb +6 -6
  71. data/lib/mongoid/config/validators.rb +1 -0
  72. data/lib/mongoid/config.rb +153 -18
  73. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  74. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  75. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  76. data/lib/mongoid/contextual/atomic.rb +1 -1
  77. data/lib/mongoid/contextual/geo_near.rb +7 -7
  78. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  79. data/lib/mongoid/contextual/memory.rb +285 -58
  80. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  81. data/lib/mongoid/contextual/mongo.rb +540 -346
  82. data/lib/mongoid/contextual/none.rb +193 -20
  83. data/lib/mongoid/contextual/queryable.rb +1 -1
  84. data/lib/mongoid/contextual.rb +14 -2
  85. data/lib/mongoid/copyable.rb +32 -8
  86. data/lib/mongoid/criteria/findable.rb +8 -5
  87. data/lib/mongoid/criteria/includable.rb +27 -22
  88. data/lib/mongoid/criteria/marshalable.rb +10 -2
  89. data/lib/mongoid/criteria/permission.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  92. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  93. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  97. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -9
  98. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  99. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  100. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  101. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  102. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  103. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  104. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  105. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  107. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  109. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  110. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/selectable.rb +48 -39
  112. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  113. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  114. data/lib/mongoid/criteria/queryable.rb +12 -7
  115. data/lib/mongoid/criteria/scopable.rb +2 -2
  116. data/lib/mongoid/criteria/translator.rb +45 -0
  117. data/lib/mongoid/criteria.rb +20 -40
  118. data/lib/mongoid/deprecable.rb +37 -0
  119. data/lib/mongoid/deprecation.rb +25 -0
  120. data/lib/mongoid/document.rb +135 -36
  121. data/lib/mongoid/equality.rb +9 -8
  122. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  123. data/lib/mongoid/errors/document_not_found.rb +10 -6
  124. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  125. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  126. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  127. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  128. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  129. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  130. data/lib/mongoid/errors/invalid_field.rb +6 -2
  131. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  132. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  133. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  134. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  135. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  136. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  137. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  138. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  139. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  140. data/lib/mongoid/errors/no_client_database.rb +1 -1
  141. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  142. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  143. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  144. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  145. data/lib/mongoid/errors.rb +6 -3
  146. data/lib/mongoid/extensions/array.rb +9 -7
  147. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  148. data/lib/mongoid/extensions/binary.rb +42 -0
  149. data/lib/mongoid/extensions/boolean.rb +8 -2
  150. data/lib/mongoid/extensions/date.rb +26 -20
  151. data/lib/mongoid/extensions/date_time.rb +1 -1
  152. data/lib/mongoid/extensions/false_class.rb +1 -1
  153. data/lib/mongoid/extensions/float.rb +7 -4
  154. data/lib/mongoid/extensions/hash.rb +38 -9
  155. data/lib/mongoid/extensions/integer.rb +7 -4
  156. data/lib/mongoid/extensions/module.rb +1 -1
  157. data/lib/mongoid/extensions/object.rb +10 -8
  158. data/lib/mongoid/extensions/range.rb +41 -10
  159. data/lib/mongoid/extensions/regexp.rb +11 -4
  160. data/lib/mongoid/extensions/set.rb +11 -4
  161. data/lib/mongoid/extensions/string.rb +11 -22
  162. data/lib/mongoid/extensions/symbol.rb +4 -15
  163. data/lib/mongoid/extensions/time.rb +29 -16
  164. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  165. data/lib/mongoid/extensions/true_class.rb +1 -1
  166. data/lib/mongoid/extensions.rb +1 -0
  167. data/lib/mongoid/factory.rb +55 -7
  168. data/lib/mongoid/fields/foreign_key.rb +11 -4
  169. data/lib/mongoid/fields/localized.rb +19 -4
  170. data/lib/mongoid/fields/standard.rb +17 -7
  171. data/lib/mongoid/fields/validators/macro.rb +3 -9
  172. data/lib/mongoid/fields.rb +142 -28
  173. data/lib/mongoid/findable.rb +54 -24
  174. data/lib/mongoid/indexable/specification.rb +2 -2
  175. data/lib/mongoid/indexable/validators/options.rb +6 -2
  176. data/lib/mongoid/interceptable.rb +187 -16
  177. data/lib/mongoid/matchable.rb +1 -1
  178. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  179. data/lib/mongoid/matcher/type.rb +1 -1
  180. data/lib/mongoid/matcher.rb +48 -14
  181. data/lib/mongoid/persistable/creatable.rb +19 -9
  182. data/lib/mongoid/persistable/deletable.rb +2 -2
  183. data/lib/mongoid/persistable/destroyable.rb +1 -1
  184. data/lib/mongoid/persistable/savable.rb +14 -2
  185. data/lib/mongoid/persistable/unsettable.rb +2 -2
  186. data/lib/mongoid/persistable/updatable.rb +69 -12
  187. data/lib/mongoid/persistable/upsertable.rb +21 -2
  188. data/lib/mongoid/persistable.rb +6 -3
  189. data/lib/mongoid/persistence_context.rb +6 -4
  190. data/lib/mongoid/query_cache.rb +13 -261
  191. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  192. data/lib/mongoid/railties/database.rake +7 -2
  193. data/lib/mongoid/reloadable.rb +10 -8
  194. data/lib/mongoid/scopable.rb +15 -13
  195. data/lib/mongoid/selectable.rb +1 -2
  196. data/lib/mongoid/serializable.rb +17 -13
  197. data/lib/mongoid/stateful.rb +57 -10
  198. data/lib/mongoid/tasks/database.rake +12 -0
  199. data/lib/mongoid/tasks/database.rb +20 -2
  200. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  201. data/lib/mongoid/threaded.rb +42 -12
  202. data/lib/mongoid/timestamps/created.rb +9 -2
  203. data/lib/mongoid/timestamps/updated.rb +2 -2
  204. data/lib/mongoid/touchable.rb +3 -4
  205. data/lib/mongoid/traversable.rb +41 -5
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/associated.rb +98 -17
  208. data/lib/mongoid/validatable/localizable.rb +1 -1
  209. data/lib/mongoid/validatable/macros.rb +5 -7
  210. data/lib/mongoid/validatable/presence.rb +2 -2
  211. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  212. data/lib/mongoid/validatable.rb +17 -6
  213. data/lib/mongoid/version.rb +1 -1
  214. data/lib/mongoid/warnings.rb +19 -4
  215. data/lib/mongoid.rb +17 -3
  216. data/spec/config/mongoid.yml +16 -0
  217. data/spec/integration/app_spec.rb +24 -19
  218. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  219. data/spec/integration/associations/embedded_spec.rb +15 -0
  220. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  221. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  222. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  223. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +61 -0
  224. data/spec/integration/associations/has_one_spec.rb +97 -1
  225. data/spec/integration/associations/scope_option_spec.rb +1 -1
  226. data/spec/integration/callbacks_models.rb +132 -1
  227. data/spec/integration/callbacks_spec.rb +381 -4
  228. data/spec/integration/criteria/range_spec.rb +95 -1
  229. data/spec/integration/discriminator_key_spec.rb +118 -80
  230. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  231. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  232. data/spec/integration/matcher_examples_spec.rb +20 -13
  233. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  234. data/spec/integration/matcher_operator_spec.rb +3 -5
  235. data/spec/integration/persistence/range_field_spec.rb +350 -0
  236. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  237. data/spec/mongoid/association/depending_spec.rb +9 -9
  238. data/spec/mongoid/association/eager_spec.rb +26 -3
  239. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  240. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  241. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  242. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  243. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +290 -65
  244. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  245. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +16 -0
  246. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  247. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  248. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  249. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  250. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  251. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  252. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  253. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +19 -0
  254. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  255. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  256. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  258. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  259. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  260. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  261. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +215 -177
  262. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  263. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  264. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  265. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  266. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  267. data/spec/mongoid/association/syncable_spec.rb +15 -1
  268. data/spec/mongoid/association_spec.rb +60 -0
  269. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  270. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  271. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  272. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  273. data/spec/mongoid/attributes/readonly_spec.rb +19 -0
  274. data/spec/mongoid/attributes_spec.rb +526 -33
  275. data/spec/mongoid/changeable_spec.rb +429 -37
  276. data/spec/mongoid/clients/factory_spec.rb +23 -30
  277. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  278. data/spec/mongoid/clients_spec.rb +149 -15
  279. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  280. data/spec/mongoid/config/defaults_spec.rb +160 -0
  281. data/spec/mongoid/config_spec.rb +214 -31
  282. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  283. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  284. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  285. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  286. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  287. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  288. data/spec/mongoid/contextual/mongo_spec.rb +2256 -1005
  289. data/spec/mongoid/contextual/none_spec.rb +60 -21
  290. data/spec/mongoid/copyable_spec.rb +453 -11
  291. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  292. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  293. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  294. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  295. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  296. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  297. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  298. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  299. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  300. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  301. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  302. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  303. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  304. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  305. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  306. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  307. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  308. data/spec/mongoid/criteria/queryable/selectable_spec.rb +107 -86
  309. data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
  310. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  311. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  312. data/spec/mongoid/criteria_spec.rb +469 -1205
  313. data/spec/mongoid/document_fields_spec.rb +173 -24
  314. data/spec/mongoid/document_spec.rb +59 -41
  315. data/spec/mongoid/equality_spec.rb +6 -0
  316. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  317. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  318. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  319. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  320. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  321. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  322. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  323. data/spec/mongoid/extensions/array_spec.rb +16 -2
  324. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  325. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  326. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  327. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  328. data/spec/mongoid/extensions/date_spec.rb +71 -1
  329. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  330. data/spec/mongoid/extensions/float_spec.rb +53 -74
  331. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  332. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  333. data/spec/mongoid/extensions/range_spec.rb +255 -54
  334. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  335. data/spec/mongoid/extensions/set_spec.rb +106 -0
  336. data/spec/mongoid/extensions/string_spec.rb +53 -25
  337. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  338. data/spec/mongoid/extensions/time_spec.rb +639 -106
  339. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  340. data/spec/mongoid/factory_spec.rb +61 -1
  341. data/spec/mongoid/fields/localized_spec.rb +80 -37
  342. data/spec/mongoid/fields_spec.rb +503 -87
  343. data/spec/mongoid/findable_spec.rb +450 -58
  344. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  345. data/spec/mongoid/indexable_spec.rb +55 -30
  346. data/spec/mongoid/interceptable_spec.rb +904 -22
  347. data/spec/mongoid/interceptable_spec_models.rb +189 -22
  348. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  349. data/spec/mongoid/mongoizable_spec.rb +285 -0
  350. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  351. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  352. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  353. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  354. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  355. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  356. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  357. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  358. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  359. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  360. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  361. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  362. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  363. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  364. data/spec/mongoid/persistence_context_spec.rb +31 -57
  365. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  366. data/spec/mongoid/query_cache_spec.rb +56 -215
  367. data/spec/mongoid/reloadable_spec.rb +83 -6
  368. data/spec/mongoid/scopable_spec.rb +91 -1
  369. data/spec/mongoid/serializable_spec.rb +25 -39
  370. data/spec/mongoid/shardable_spec.rb +4 -4
  371. data/spec/mongoid/stateful_spec.rb +150 -8
  372. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  373. data/spec/mongoid/tasks/database_spec.rb +127 -0
  374. data/spec/mongoid/timestamps/created_spec.rb +23 -0
  375. data/spec/mongoid/timestamps_spec.rb +392 -4
  376. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  377. data/spec/mongoid/touchable_spec.rb +390 -2
  378. data/spec/mongoid/touchable_spec_models.rb +14 -8
  379. data/spec/mongoid/traversable_spec.rb +13 -35
  380. data/spec/mongoid/validatable/associated_spec.rb +27 -34
  381. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  382. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  383. data/spec/mongoid/warnings_spec.rb +35 -0
  384. data/spec/mongoid_spec.rb +34 -16
  385. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  386. data/spec/rails/mongoid_spec.rb +4 -16
  387. data/spec/spec_helper.rb +5 -0
  388. data/spec/support/constraints.rb +24 -0
  389. data/spec/support/immutable_ids.rb +118 -0
  390. data/spec/support/macros.rb +78 -0
  391. data/spec/support/models/artist.rb +0 -1
  392. data/spec/support/models/augmentation.rb +12 -0
  393. data/spec/support/models/band.rb +5 -0
  394. data/spec/support/models/book.rb +1 -0
  395. data/spec/support/models/building.rb +2 -0
  396. data/spec/support/models/catalog.rb +24 -0
  397. data/spec/support/models/circus.rb +3 -0
  398. data/spec/support/models/cover.rb +10 -0
  399. data/spec/support/models/fanatic.rb +8 -0
  400. data/spec/support/models/implant.rb +9 -0
  401. data/spec/support/models/label.rb +2 -0
  402. data/spec/support/models/lat_lng.rb +6 -0
  403. data/spec/support/models/name.rb +10 -0
  404. data/spec/support/models/passport.rb +9 -0
  405. data/spec/support/models/person.rb +2 -0
  406. data/spec/support/models/player.rb +2 -0
  407. data/spec/support/models/powerup.rb +12 -0
  408. data/spec/support/models/product.rb +1 -0
  409. data/spec/support/models/purse.rb +9 -0
  410. data/spec/support/models/registry.rb +1 -0
  411. data/spec/support/models/school.rb +14 -0
  412. data/spec/support/models/shield.rb +18 -0
  413. data/spec/support/models/student.rb +14 -0
  414. data/spec/support/models/weapon.rb +12 -0
  415. metadata +98 -96
  416. checksums.yaml.gz.sig +0 -0
  417. data/lib/mongoid/errors/eager_load.rb +0 -23
  418. data/lib/mongoid/errors/invalid_value.rb +0 -17
  419. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  420. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  421. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
  422. data/spec/shared/LICENSE +0 -20
  423. data/spec/shared/bin/get-mongodb-download-url +0 -17
  424. data/spec/shared/bin/s3-copy +0 -45
  425. data/spec/shared/bin/s3-upload +0 -69
  426. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  427. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  428. data/spec/shared/lib/mrss/constraints.rb +0 -378
  429. data/spec/shared/lib/mrss/docker_runner.rb +0 -291
  430. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  431. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  432. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  433. data/spec/shared/lib/mrss/server_version_registry.rb +0 -120
  434. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  435. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  436. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  437. data/spec/shared/lib/mrss/utils.rb +0 -15
  438. data/spec/shared/share/Dockerfile.erb +0 -325
  439. data/spec/shared/share/haproxy-1.conf +0 -16
  440. data/spec/shared/share/haproxy-2.conf +0 -17
  441. data/spec/shared/shlib/config.sh +0 -27
  442. data/spec/shared/shlib/distro.sh +0 -74
  443. data/spec/shared/shlib/server.sh +0 -392
  444. data/spec/shared/shlib/set_env.sh +0 -169
  445. data.tar.gz.sig +0 -0
  446. metadata.gz.sig +0 -3
@@ -4,11 +4,11 @@ require "spec_helper"
4
4
 
5
5
  describe Mongoid::Contextual::Aggregable::Memory do
6
6
 
7
- describe "#aggregates" do
8
- let(:context) do
9
- Mongoid::Contextual::Memory.new(criteria)
10
- end
7
+ let(:context) do
8
+ Mongoid::Contextual::Memory.new(criteria)
9
+ end
11
10
 
11
+ describe "#aggregates" do
12
12
  subject { context.aggregates(:likes) }
13
13
 
14
14
  context 'when no documents found' do
@@ -46,289 +46,527 @@ describe Mongoid::Contextual::Aggregable::Memory do
46
46
 
47
47
  describe "#avg" do
48
48
 
49
- context "when provided a single field" do
49
+ context "when the types are Integers" do
50
50
 
51
- context "when there are matching documents" do
51
+ let!(:depeche) do
52
+ Band.create!(name: "Depeche Mode", likes: 1000)
53
+ end
52
54
 
53
- context "when the types are integers" do
55
+ let!(:tool) do
56
+ Band.create!(name: "Tool", likes: 500)
57
+ end
54
58
 
55
- let!(:depeche) do
56
- Band.create!(name: "Depeche Mode", likes: 1000)
57
- end
59
+ let(:criteria) do
60
+ Band.all.tap do |criteria|
61
+ criteria.documents = [ depeche, tool ]
62
+ end
63
+ end
58
64
 
59
- let!(:tool) do
60
- Band.create!(name: "Tool", likes: 500)
61
- end
65
+ let(:avg) do
66
+ context.avg(:likes)
67
+ end
62
68
 
63
- let(:criteria) do
64
- Band.all.tap do |criteria|
65
- criteria.documents = [ depeche, tool ]
66
- end
67
- end
69
+ it "returns the avg of the provided field" do
70
+ expect(avg).to eq(750)
71
+ end
68
72
 
69
- let(:context) do
70
- Mongoid::Contextual::Memory.new(criteria)
71
- end
73
+ it 'returns a float' do
74
+ avg.should be_a(Float)
75
+ end
72
76
 
73
- let(:avg) do
74
- context.avg(:likes)
75
- end
77
+ context 'when integers are negative' do
76
78
 
77
- it "returns the avg of the provided field" do
78
- expect(avg).to eq(750)
79
- end
79
+ let!(:depeche) do
80
+ Band.create!(name: "Depeche Mode", likes: -1000)
80
81
  end
81
82
 
82
- context "when the types are floats" do
83
+ it "returns the avg of the provided field" do
84
+ expect(avg).to eq(-250)
85
+ end
83
86
 
84
- let!(:depeche) do
85
- Band.create!(name: "Depeche Mode", rating: 10)
86
- end
87
+ it 'returns a float' do
88
+ avg.should be_a(Float)
89
+ end
90
+ end
91
+ end
87
92
 
88
- let!(:tool) do
89
- Band.create!(name: "Tool", rating: 5)
90
- end
93
+ context "when the types are Floats" do
91
94
 
92
- let(:criteria) do
93
- Band.all.tap do |criteria|
94
- criteria.documents = [ depeche, tool ]
95
- end
96
- end
97
-
98
- let(:context) do
99
- Mongoid::Contextual::Memory.new(criteria)
100
- end
95
+ let!(:depeche) do
96
+ Band.create!(name: "Depeche Mode", rating: 10)
97
+ end
101
98
 
102
- let(:avg) do
103
- context.avg(:rating)
104
- end
99
+ let!(:tool) do
100
+ Band.create!(name: "Tool", rating: 5)
101
+ end
105
102
 
106
- it "returns the avg of the provided field" do
107
- expect(avg).to eq(7.5)
108
- end
103
+ let(:criteria) do
104
+ Band.all.tap do |criteria|
105
+ criteria.documents = [ depeche, tool ]
109
106
  end
110
107
  end
111
108
 
112
- context "when no documents match" do
109
+ let(:avg) do
110
+ context.avg(:rating)
111
+ end
113
112
 
114
- let!(:depeche) do
115
- Band.create!(name: "Depeche Mode", likes: 1000)
116
- end
113
+ it "returns the avg of the provided field" do
114
+ expect(avg).to eq(7.5)
115
+ end
116
+ end
117
117
 
118
- let(:criteria) do
119
- Band.where(name: "New Order")
120
- end
118
+ context "when no documents match" do
121
119
 
122
- let(:context) do
123
- Mongoid::Contextual::Memory.new(criteria)
124
- end
120
+ let!(:depeche) do
121
+ Band.create!(name: "Depeche Mode", likes: 1000)
122
+ end
123
+
124
+ let(:criteria) do
125
+ Band.where(name: "New Order")
126
+ end
127
+
128
+ let(:avg) do
129
+ context.avg(:likes)
130
+ end
131
+
132
+ it "returns nil" do
133
+ expect(avg).to be_nil
134
+ end
135
+ end
136
+
137
+ context "when there are a mix of types" do
125
138
 
126
- let(:avg) do
127
- context.avg(:likes)
139
+ let!(:bands) do
140
+ [ Band.create!(name: "The Flaming Lips", mojo: 7.7),
141
+ Band.create!(name: "Spirit of the Beehive", mojo: 10),
142
+ Band.create!(name: "Justin Bieber", mojo: nil) ]
143
+ end
144
+
145
+ let(:criteria) do
146
+ Band.all.tap do |criteria|
147
+ criteria.documents = bands
128
148
  end
149
+ end
129
150
 
130
- it "returns nil" do
131
- expect(avg).to be_nil
151
+ let(:avg) do
152
+ context.avg(:mojo)
153
+ end
154
+
155
+ it "coerces types to calculate avg" do
156
+ expect(avg).to eq(8.85)
157
+ end
158
+
159
+ it "database only averages Numeric types" do
160
+ expect(Band.all.avg(:mojo)).to be_within(0.000001).of(8.85)
161
+ end
162
+ end
163
+
164
+ context "when there no numeric values" do
165
+
166
+ let!(:bands) do
167
+ [ Band.create!(name: "Justin Bieber", mojo: nil) ]
168
+ end
169
+
170
+ let(:criteria) do
171
+ Band.all.tap do |criteria|
172
+ criteria.documents = bands
132
173
  end
133
174
  end
175
+
176
+ let(:avg) do
177
+ context.avg(:mojo)
178
+ end
179
+
180
+ it "returns avg as nil" do
181
+ expect(avg).to be_nil
182
+ end
183
+
184
+ it "database returns avg as nil" do
185
+ expect(Band.all.avg(:mojo)).to eq(nil)
186
+ end
134
187
  end
135
188
  end
136
189
 
137
190
  describe "#max" do
138
191
 
139
- context "when provided a single field" do
192
+ let!(:depeche) do
193
+ Band.create!(name: "Depeche Mode", likes: 1000)
194
+ end
140
195
 
141
- let!(:depeche) do
142
- Band.create!(name: "Depeche Mode", likes: 1000)
143
- end
196
+ let!(:tool) do
197
+ Band.create!(name: "Tool", likes: 500)
198
+ end
144
199
 
145
- let!(:tool) do
146
- Band.create!(name: "Tool", likes: 500)
200
+ let(:criteria) do
201
+ Band.all.tap do |crit|
202
+ crit.documents = [ depeche, tool ]
147
203
  end
204
+ end
148
205
 
149
- let(:criteria) do
150
- Band.all.tap do |crit|
151
- crit.documents = [ depeche, tool ]
152
- end
206
+ context "when provided a Symbol" do
207
+
208
+ let(:max) do
209
+ context.max(:likes)
153
210
  end
154
211
 
155
- let(:context) do
156
- Mongoid::Contextual::Memory.new(criteria)
212
+ it "returns the max of the provided field" do
213
+ expect(max).to eq(1000)
157
214
  end
158
215
 
159
- context "when provided a symbol" do
216
+ context "when no documents match" do
217
+
218
+ let(:criteria) do
219
+ Band.where(name: "New Order")
220
+ end
160
221
 
161
222
  let(:max) do
162
223
  context.max(:likes)
163
224
  end
164
225
 
165
- it "returns the max of the provided field" do
166
- expect(max).to eq(1000)
226
+ it "returns nil" do
227
+ expect(max).to be_nil
167
228
  end
229
+ end
168
230
 
169
- context "when no documents match" do
231
+ context "when there are a mix of types" do
170
232
 
171
- let(:criteria) do
172
- Band.where(name: "New Order")
173
- end
233
+ let!(:bands) do
234
+ [ Band.create!(name: "The Flaming Lips", mojo: 7.7),
235
+ Band.create!(name: "Spirit of the Beehive", mojo: 10),
236
+ Band.create!(name: "Justin Bieber", mojo: nil) ]
237
+ end
174
238
 
175
- let(:context) do
176
- Mongoid::Contextual::Memory.new(criteria)
239
+ let(:criteria) do
240
+ Band.all.tap do |criteria|
241
+ criteria.documents = bands
177
242
  end
243
+ end
178
244
 
179
- let(:max) do
180
- context.max(:likes)
181
- end
245
+ let(:max) do
246
+ context.max(:mojo)
247
+ end
182
248
 
183
- it "returns nil" do
184
- expect(max).to be_nil
185
- end
249
+ it "coerces types to calculate max" do
250
+ expect(max).to eq 10
251
+ expect(max).to be_a Integer
186
252
  end
187
253
  end
188
254
 
189
- context "when provided a block" do
255
+ context "when there no numeric values" do
190
256
 
191
- let(:max) do
192
- context.max do |a, b|
193
- a.likes <=> b.likes
257
+ let!(:bands) do
258
+ [ Band.create!(name: "Justin Bieber", mojo: nil) ]
259
+ end
260
+
261
+ let(:criteria) do
262
+ Band.all.tap do |criteria|
263
+ criteria.documents = bands
194
264
  end
195
265
  end
196
266
 
197
- it "returns the document with the max value for the field" do
198
- expect(max).to eq(depeche)
267
+ let(:max) do
268
+ context.avg(:mojo)
199
269
  end
270
+
271
+ it "returns max as nil" do
272
+ expect(max).to be_nil
273
+ end
274
+ end
275
+ end
276
+
277
+ context "when provided a block" do
278
+
279
+ let(:max) do
280
+ context.max do |a, b|
281
+ a.likes <=> b.likes
282
+ end
283
+ end
284
+
285
+ it "returns the document with the max value for the field" do
286
+ expect(max).to eq(depeche)
200
287
  end
201
288
  end
202
289
  end
203
290
 
204
291
  describe "#min" do
205
292
 
206
- context "when provided a single field" do
293
+ let!(:depeche) do
294
+ Band.create!(name: "Depeche Mode", likes: 1000)
295
+ end
207
296
 
208
- let!(:depeche) do
209
- Band.create!(name: "Depeche Mode", likes: 1000)
210
- end
297
+ let!(:tool) do
298
+ Band.create!(name: "Tool", likes: 500)
299
+ end
211
300
 
212
- let!(:tool) do
213
- Band.create!(name: "Tool", likes: 500)
301
+ let(:criteria) do
302
+ Band.all.tap do |crit|
303
+ crit.documents = [ depeche, tool ]
214
304
  end
305
+ end
215
306
 
216
- let(:criteria) do
217
- Band.all.tap do |crit|
218
- crit.documents = [ depeche, tool ]
219
- end
307
+ context "when provided a Symbol" do
308
+
309
+ let(:min) do
310
+ context.min(:likes)
220
311
  end
221
312
 
222
- let(:context) do
223
- Mongoid::Contextual::Memory.new(criteria)
313
+ it "returns the min of the provided field" do
314
+ expect(min).to eq(500)
224
315
  end
225
316
 
226
- context "when provided a symbol" do
317
+ context "when no documents match" do
318
+
319
+ let(:criteria) do
320
+ Band.where(name: "New Order")
321
+ end
227
322
 
228
323
  let(:min) do
229
324
  context.min(:likes)
230
325
  end
231
326
 
232
- it "returns the min of the provided field" do
233
- expect(min).to eq(500)
327
+ it "returns nil" do
328
+ expect(min).to be_nil
234
329
  end
330
+ end
235
331
 
236
- context "when no documents match" do
332
+ context "when there are a mix of types" do
237
333
 
238
- let(:criteria) do
239
- Band.where(name: "New Order")
240
- end
334
+ let!(:bands) do
335
+ [ Band.create!(name: "The Flaming Lips", mojo: 7.7),
336
+ Band.create!(name: "Spirit of the Beehive", mojo: 10),
337
+ Band.create!(name: "Justin Bieber", mojo: nil) ]
338
+ end
241
339
 
242
- let(:context) do
243
- Mongoid::Contextual::Memory.new(criteria)
340
+ let(:criteria) do
341
+ Band.all.tap do |criteria|
342
+ criteria.documents = bands
244
343
  end
344
+ end
245
345
 
246
- let(:min) do
247
- context.min(:likes)
248
- end
346
+ let(:min) do
347
+ context.min(:mojo)
348
+ end
249
349
 
250
- it "returns nil" do
251
- expect(min).to be_nil
252
- end
350
+ it "coerces types to calculate min" do
351
+ expect(min).to eq 7.7
352
+ expect(min).to be_a Float
253
353
  end
254
354
  end
255
355
 
256
- context "when provided a block" do
356
+ context "when there no numeric values" do
257
357
 
258
- let(:min) do
259
- context.min do |a, b|
260
- a.likes <=> b.likes
358
+ let!(:bands) do
359
+ [ Band.create!(name: "Justin Bieber", mojo: nil) ]
360
+ end
361
+
362
+ let(:criteria) do
363
+ Band.all.tap do |criteria|
364
+ criteria.documents = bands
261
365
  end
262
366
  end
263
367
 
264
- it "returns the document with the min value for the field" do
265
- expect(min).to eq(tool)
368
+ let(:min) do
369
+ context.min(:mojo)
370
+ end
371
+
372
+ it "returns min as nil" do
373
+ expect(min).to be_nil
374
+ end
375
+ end
376
+ end
377
+
378
+ context "when provided a block" do
379
+
380
+ let(:min) do
381
+ context.min do |a, b|
382
+ a.likes <=> b.likes
266
383
  end
267
384
  end
385
+
386
+ it "returns the document with the min value for the field" do
387
+ expect(min).to eq(tool)
388
+ end
268
389
  end
269
390
  end
270
391
 
271
392
  describe "#sum" do
272
393
 
273
- context "when provided a single field" do
394
+ let!(:depeche) do
395
+ Band.create!(name: "Depeche Mode", likes: 1000)
396
+ end
397
+
398
+ let!(:tool) do
399
+ Band.create!(name: "Tool", likes: 500)
400
+ end
274
401
 
275
- let!(:depeche) do
276
- Band.create!(name: "Depeche Mode", likes: 1000)
402
+ let(:criteria) do
403
+ Band.all.tap do |crit|
404
+ crit.documents = [ depeche, tool ]
277
405
  end
406
+ end
278
407
 
279
- let!(:tool) do
280
- Band.create!(name: "Tool", likes: 500)
408
+ context 'when values are integers' do
409
+
410
+ let(:sum) do
411
+ context.sum(:likes)
281
412
  end
282
413
 
283
- let(:criteria) do
284
- Band.all.tap do |crit|
285
- crit.documents = [ depeche, tool ]
414
+ shared_examples 'sums and returns an integer' do
415
+ it 'sums' do
416
+ sum.should == 1500
417
+ end
418
+
419
+ it 'returns integer' do
420
+ sum.should be_a(Integer)
421
+ end
422
+ end
423
+
424
+ include_examples 'sums and returns an integer'
425
+
426
+ context 'when values are numeric strings' do
427
+
428
+ let!(:depeche) do
429
+ Band.create!(name: "Depeche Mode", likes: '1000')
286
430
  end
431
+
432
+ include_examples 'sums and returns an integer'
433
+ end
434
+
435
+ context 'when values are negative integers' do
436
+
437
+ let!(:depeche) do
438
+ Band.create!(name: "Depeche Mode", likes: -1000)
439
+ end
440
+
441
+ shared_examples 'sums and returns an integer' do
442
+ it 'sums' do
443
+ sum.should == -500
444
+ end
445
+
446
+ it 'returns integer' do
447
+ sum.should be_a(Integer)
448
+ end
449
+ end
450
+
451
+ include_examples 'sums and returns an integer'
452
+
453
+ context 'when values are negative numeric strings' do
454
+
455
+ let!(:depeche) do
456
+ Band.create!(name: "Depeche Mode", likes: '-1000')
457
+ end
458
+
459
+ include_examples 'sums and returns an integer'
460
+ end
461
+ end
462
+ end
463
+
464
+ context 'when values are floats' do
465
+
466
+ let!(:depeche) do
467
+ Band.create!(name: "Depeche Mode", likes: 1000.0)
468
+ end
469
+
470
+ let(:sum) do
471
+ context.sum(:likes)
472
+ end
473
+
474
+ it 'sums' do
475
+ sum.should == 1500
476
+ end
477
+
478
+ it 'returns integer' do
479
+ sum.should be_a(Integer)
287
480
  end
481
+ end
288
482
 
289
- let(:context) do
290
- Mongoid::Contextual::Memory.new(criteria)
483
+ context "when provided a Symbol" do
484
+
485
+ let(:sum) do
486
+ context.sum(:likes)
291
487
  end
292
488
 
293
- context "when provided a symbol" do
489
+ it "returns the sum of the provided field" do
490
+ expect(sum).to eq(1500)
491
+ end
492
+
493
+ context "when no documents match" do
494
+
495
+ let(:criteria) do
496
+ Band.where(name: "New Order")
497
+ end
294
498
 
295
499
  let(:sum) do
296
500
  context.sum(:likes)
297
501
  end
298
502
 
299
- it "returns the sum of the provided field" do
300
- expect(sum).to eq(1500)
503
+ it "returns zero" do
504
+ expect(sum).to eq(0)
301
505
  end
506
+ end
302
507
 
303
- context "when no documents match" do
508
+ context "when there are a mix of types" do
304
509
 
305
- let(:criteria) do
306
- Band.where(name: "New Order")
307
- end
510
+ let!(:bands) do
511
+ [ Band.create!(name: "The Flaming Lips", mojo: 7.7),
512
+ Band.create!(name: "Spirit of the Beehive", mojo: 10),
513
+ Band.create!(name: "Justin Bieber", mojo: nil) ]
514
+ end
308
515
 
309
- let(:context) do
310
- Mongoid::Contextual::Memory.new(criteria)
516
+ let(:criteria) do
517
+ Band.all.tap do |criteria|
518
+ criteria.documents = bands
311
519
  end
520
+ end
312
521
 
313
- let(:sum) do
314
- context.sum(:likes)
315
- end
522
+ let(:sum) do
523
+ context.sum(:mojo)
524
+ end
316
525
 
317
- it "returns zero" do
318
- expect(sum).to eq(0)
319
- end
526
+ it "coerces types to calculate sum" do
527
+ expect(sum).to eq 17.7
528
+ expect(sum).to be_a Float
529
+ end
530
+
531
+ it "database only sums Float and Integer types" do
532
+ expect(Band.all.sum(:mojo)).to be_within(Float::EPSILON).of(17.7)
320
533
  end
321
534
  end
322
535
 
323
- context "when provided a block" do
536
+ context "when there no numeric values" do
537
+
538
+ let!(:bands) do
539
+ [ Band.create!(name: "Justin Bieber", mojo: nil) ]
540
+ end
541
+
542
+ let(:criteria) do
543
+ Band.all.tap do |criteria|
544
+ criteria.documents = bands
545
+ end
546
+ end
324
547
 
325
548
  let(:sum) do
326
- context.sum(&:likes)
549
+ context.sum(:mojo)
327
550
  end
328
551
 
329
- it "returns the sum for the provided block" do
330
- expect(sum).to eq(1500)
552
+ it "returns sum as zero" do
553
+ expect(sum).to eq 0
331
554
  end
555
+
556
+ it "database returns sum as zero" do
557
+ expect(Band.all.sum(:mojo)).to eq(0)
558
+ end
559
+ end
560
+ end
561
+
562
+ context "when provided a block" do
563
+
564
+ let(:sum) do
565
+ context.sum(&:likes)
566
+ end
567
+
568
+ it "returns the sum for the provided block" do
569
+ expect(sum).to eq(1500)
332
570
  end
333
571
  end
334
572
  end