mongoid 9.0.12 → 9.1.0

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 (1006) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -8
  3. data/README.md +5 -11
  4. data/Rakefile +35 -38
  5. data/lib/config/locales/en.yml +11 -45
  6. data/lib/mongoid/association/accessors.rb +19 -26
  7. data/lib/mongoid/association/bindable.rb +43 -45
  8. data/lib/mongoid/association/builders.rb +18 -15
  9. data/lib/mongoid/association/constrainable.rb +3 -5
  10. data/lib/mongoid/association/depending.rb +38 -46
  11. data/lib/mongoid/association/eager.rb +47 -13
  12. data/lib/mongoid/association/eager_loadable.rb +152 -24
  13. data/lib/mongoid/association/embedded/batchable.rb +28 -30
  14. data/lib/mongoid/association/embedded/cyclic.rb +8 -11
  15. data/lib/mongoid/association/embedded/eager.rb +1 -6
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +6 -9
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -3
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -0
  19. data/lib/mongoid/association/embedded/embedded_in.rb +25 -22
  20. data/lib/mongoid/association/embedded/embeds_many/binding.rb +0 -2
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +2 -3
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +1 -1
  23. data/lib/mongoid/association/embedded/embeds_many.rb +24 -21
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +0 -2
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +2 -6
  26. data/lib/mongoid/association/embedded/embeds_one.rb +20 -18
  27. data/lib/mongoid/association/embedded.rb +0 -1
  28. data/lib/mongoid/association/macros.rb +3 -7
  29. data/lib/mongoid/association/many.rb +75 -3
  30. data/lib/mongoid/association/marshalable.rb +0 -3
  31. data/lib/mongoid/association/nested/many.rb +23 -47
  32. data/lib/mongoid/association/nested/nested_buildable.rb +6 -23
  33. data/lib/mongoid/association/nested/one.rb +4 -7
  34. data/lib/mongoid/association/nested.rb +1 -3
  35. data/lib/mongoid/association/one.rb +0 -3
  36. data/lib/mongoid/association/options.rb +8 -7
  37. data/lib/mongoid/association/referenced/auto_save.rb +0 -2
  38. data/lib/mongoid/association/referenced/belongs_to/binding.rb +11 -15
  39. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +23 -5
  40. data/lib/mongoid/association/referenced/belongs_to/eager.rb +1 -3
  41. data/lib/mongoid/association/referenced/belongs_to.rb +48 -43
  42. data/lib/mongoid/association/referenced/counter_cache.rb +5 -10
  43. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +0 -2
  44. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +8 -4
  45. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +0 -3
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +52 -47
  47. data/lib/mongoid/association/referenced/has_many/binding.rb +0 -2
  48. data/lib/mongoid/association/referenced/has_many/buildable.rb +11 -5
  49. data/lib/mongoid/association/referenced/has_many/eager.rb +0 -3
  50. data/lib/mongoid/association/referenced/has_many/enumerable.rb +107 -38
  51. data/lib/mongoid/association/referenced/has_many/proxy.rb +11 -106
  52. data/lib/mongoid/association/referenced/has_many.rb +30 -24
  53. data/lib/mongoid/association/referenced/has_one/binding.rb +0 -2
  54. data/lib/mongoid/association/referenced/has_one/buildable.rb +11 -9
  55. data/lib/mongoid/association/referenced/has_one/eager.rb +0 -3
  56. data/lib/mongoid/association/referenced/has_one.rb +26 -21
  57. data/lib/mongoid/association/referenced/syncable.rb +30 -34
  58. data/lib/mongoid/association/referenced.rb +0 -1
  59. data/lib/mongoid/association/reflections.rb +0 -3
  60. data/lib/mongoid/association/relatable.rb +69 -83
  61. data/lib/mongoid/association.rb +12 -15
  62. data/lib/mongoid/atomic/modifiers.rb +65 -25
  63. data/lib/mongoid/atomic/paths/embedded/many.rb +4 -7
  64. data/lib/mongoid/atomic/paths/embedded/one.rb +2 -4
  65. data/lib/mongoid/atomic/paths/embedded.rb +3 -6
  66. data/lib/mongoid/atomic/paths/root.rb +1 -4
  67. data/lib/mongoid/atomic/paths.rb +2 -3
  68. data/lib/mongoid/atomic.rb +0 -3
  69. data/lib/mongoid/attributes/dynamic.rb +6 -7
  70. data/lib/mongoid/attributes/nested.rb +8 -10
  71. data/lib/mongoid/attributes/projector.rb +7 -20
  72. data/lib/mongoid/attributes/readonly.rb +6 -11
  73. data/lib/mongoid/attributes.rb +18 -34
  74. data/lib/mongoid/cacheable.rb +24 -6
  75. data/lib/mongoid/clients/factory.rb +12 -15
  76. data/lib/mongoid/clients/options.rb +2 -5
  77. data/lib/mongoid/clients/sessions.rb +50 -60
  78. data/lib/mongoid/clients/storage_options.rb +1 -4
  79. data/lib/mongoid/clients/validators/storage.rb +2 -3
  80. data/lib/mongoid/clients/validators.rb +1 -2
  81. data/lib/mongoid/clients.rb +8 -11
  82. data/lib/mongoid/collection_configurable.rb +10 -22
  83. data/lib/mongoid/composable.rb +30 -34
  84. data/lib/mongoid/config/defaults.rb +7 -4
  85. data/lib/mongoid/config/encryption.rb +19 -39
  86. data/lib/mongoid/config/environment.rb +7 -16
  87. data/lib/mongoid/config/introspection.rb +14 -16
  88. data/lib/mongoid/config/options.rb +16 -10
  89. data/lib/mongoid/config/validators/async_query_executor.rb +3 -6
  90. data/lib/mongoid/config/validators/client.rb +12 -15
  91. data/lib/mongoid/config/validators/option.rb +3 -5
  92. data/lib/mongoid/config/validators.rb +3 -4
  93. data/lib/mongoid/config.rb +127 -84
  94. data/lib/mongoid/contextual/aggregable/memory.rb +4 -9
  95. data/lib/mongoid/contextual/aggregable/mongo.rb +20 -22
  96. data/lib/mongoid/contextual/aggregable/none.rb +2 -4
  97. data/lib/mongoid/contextual/aggregable.rb +5 -7
  98. data/lib/mongoid/contextual/atomic.rb +20 -24
  99. data/lib/mongoid/contextual/command.rb +0 -3
  100. data/lib/mongoid/contextual/map_reduce.rb +12 -16
  101. data/lib/mongoid/contextual/memory.rb +76 -80
  102. data/lib/mongoid/contextual/mongo/documents_loader.rb +2 -3
  103. data/lib/mongoid/contextual/mongo.rb +169 -85
  104. data/lib/mongoid/contextual/none.rb +9 -9
  105. data/lib/mongoid/contextual/queryable.rb +1 -4
  106. data/lib/mongoid/contextual.rb +18 -7
  107. data/lib/mongoid/copyable.rb +7 -9
  108. data/lib/mongoid/criteria/findable.rb +5 -7
  109. data/lib/mongoid/criteria/includable.rb +37 -8
  110. data/lib/mongoid/criteria/inspectable.rb +2 -5
  111. data/lib/mongoid/criteria/marshalable.rb +4 -8
  112. data/lib/mongoid/criteria/modifiable.rb +3 -11
  113. data/lib/mongoid/criteria/options.rb +0 -3
  114. data/lib/mongoid/criteria/permission.rb +34 -37
  115. data/lib/mongoid/criteria/queryable/aggregable.rb +9 -10
  116. data/lib/mongoid/criteria/queryable/expandable.rb +4 -9
  117. data/lib/mongoid/criteria/queryable/extensions/array.rb +7 -10
  118. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -5
  119. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -4
  120. data/lib/mongoid/criteria/queryable/extensions/date.rb +2 -6
  121. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +3 -7
  122. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -4
  123. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +20 -11
  124. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -11
  125. data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -8
  126. data/lib/mongoid/criteria/queryable/extensions/range.rb +6 -9
  127. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -12
  128. data/lib/mongoid/criteria/queryable/extensions/set.rb +4 -6
  129. data/lib/mongoid/criteria/queryable/extensions/string.rb +5 -9
  130. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -7
  131. data/lib/mongoid/criteria/queryable/extensions/time.rb +2 -6
  132. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +2 -12
  133. data/lib/mongoid/criteria/queryable/extensions.rb +18 -21
  134. data/lib/mongoid/criteria/queryable/key.rb +12 -18
  135. data/lib/mongoid/criteria/queryable/macroable.rb +0 -3
  136. data/lib/mongoid/criteria/queryable/mergeable.rb +31 -43
  137. data/lib/mongoid/criteria/queryable/optional.rb +17 -18
  138. data/lib/mongoid/criteria/queryable/options.rb +20 -9
  139. data/lib/mongoid/criteria/queryable/pipeline.rb +6 -9
  140. data/lib/mongoid/criteria/queryable/selectable.rb +130 -301
  141. data/lib/mongoid/criteria/queryable/selector.rb +20 -29
  142. data/lib/mongoid/criteria/queryable/smash.rb +1 -6
  143. data/lib/mongoid/criteria/queryable/storable.rb +20 -39
  144. data/lib/mongoid/criteria/queryable.rb +25 -15
  145. data/lib/mongoid/criteria/scopable.rb +5 -11
  146. data/lib/mongoid/criteria/translator.rb +5 -8
  147. data/lib/mongoid/criteria.rb +109 -54
  148. data/lib/mongoid/deprecable.rb +1 -4
  149. data/lib/mongoid/deprecation.rb +2 -6
  150. data/lib/mongoid/document.rb +1 -1
  151. data/lib/mongoid/encryptable.rb +1 -48
  152. data/lib/mongoid/equality.rb +4 -5
  153. data/lib/mongoid/errors/ambiguous_relationship.rb +2 -5
  154. data/lib/mongoid/errors/attribute_not_loaded.rb +1 -4
  155. data/lib/mongoid/errors/callback.rb +1 -4
  156. data/lib/mongoid/errors/create_collection_failure.rb +8 -11
  157. data/lib/mongoid/errors/criteria_argument_required.rb +2 -5
  158. data/lib/mongoid/errors/delete_restriction.rb +1 -4
  159. data/lib/mongoid/errors/document_not_destroyed.rb +1 -4
  160. data/lib/mongoid/errors/document_not_found.rb +16 -21
  161. data/lib/mongoid/errors/drop_collection_failure.rb +7 -10
  162. data/lib/mongoid/errors/empty_config_file.rb +1 -4
  163. data/lib/mongoid/errors/immutable_attribute.rb +1 -4
  164. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -4
  165. data/lib/mongoid/errors/invalid_async_query_executor.rb +2 -5
  166. data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +2 -5
  167. data/lib/mongoid/errors/invalid_collection.rb +1 -3
  168. data/lib/mongoid/errors/invalid_config_file.rb +1 -4
  169. data/lib/mongoid/errors/invalid_config_option.rb +2 -5
  170. data/lib/mongoid/errors/invalid_dependent_strategy.rb +6 -10
  171. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +2 -4
  172. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +1 -4
  173. data/lib/mongoid/errors/invalid_elem_match_operator.rb +5 -9
  174. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +1 -4
  175. data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +1 -4
  176. data/lib/mongoid/errors/invalid_expression_operator.rb +3 -7
  177. data/lib/mongoid/errors/invalid_field.rb +2 -5
  178. data/lib/mongoid/errors/invalid_field_operator.rb +5 -9
  179. data/lib/mongoid/errors/invalid_field_option.rb +2 -5
  180. data/lib/mongoid/errors/invalid_field_type.rb +1 -4
  181. data/lib/mongoid/errors/invalid_find.rb +1 -4
  182. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +1 -4
  183. data/lib/mongoid/errors/invalid_includes.rb +3 -6
  184. data/lib/mongoid/errors/invalid_index.rb +1 -4
  185. data/lib/mongoid/errors/invalid_options.rb +1 -4
  186. data/lib/mongoid/errors/invalid_path.rb +1 -4
  187. data/lib/mongoid/errors/invalid_persistence_option.rb +4 -7
  188. data/lib/mongoid/errors/invalid_query.rb +6 -11
  189. data/lib/mongoid/errors/invalid_relation.rb +10 -13
  190. data/lib/mongoid/errors/invalid_relation_option.rb +4 -7
  191. data/lib/mongoid/errors/invalid_scope.rb +1 -4
  192. data/lib/mongoid/errors/invalid_session_nesting.rb +0 -3
  193. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +2 -4
  194. data/lib/mongoid/errors/invalid_storage_options.rb +1 -4
  195. data/lib/mongoid/errors/invalid_time.rb +1 -4
  196. data/lib/mongoid/errors/invalid_transaction_nesting.rb +0 -3
  197. data/lib/mongoid/errors/inverse_not_found.rb +1 -4
  198. data/lib/mongoid/errors/mixed_client_configuration.rb +1 -4
  199. data/lib/mongoid/errors/mixed_relations.rb +1 -3
  200. data/lib/mongoid/errors/mongoid_error.rb +7 -11
  201. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -4
  202. data/lib/mongoid/errors/no_client_config.rb +1 -4
  203. data/lib/mongoid/errors/no_client_database.rb +1 -4
  204. data/lib/mongoid/errors/no_client_hosts.rb +1 -4
  205. data/lib/mongoid/errors/no_clients_config.rb +1 -4
  206. data/lib/mongoid/errors/no_default_client.rb +1 -4
  207. data/lib/mongoid/errors/no_environment.rb +1 -4
  208. data/lib/mongoid/errors/no_map_reduce_output.rb +1 -4
  209. data/lib/mongoid/errors/no_metadata.rb +1 -4
  210. data/lib/mongoid/errors/no_parent.rb +1 -4
  211. data/lib/mongoid/errors/readonly_attribute.rb +1 -4
  212. data/lib/mongoid/errors/readonly_document.rb +1 -4
  213. data/lib/mongoid/errors/rollback.rb +0 -2
  214. data/lib/mongoid/errors/scope_overwrite.rb +2 -4
  215. data/lib/mongoid/errors/sessions_not_supported.rb +0 -3
  216. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -3
  217. data/lib/mongoid/errors/transaction_error.rb +0 -3
  218. data/lib/mongoid/errors/transactions_not_supported.rb +0 -3
  219. data/lib/mongoid/errors/unknown_attribute.rb +1 -4
  220. data/lib/mongoid/errors/unknown_model.rb +1 -4
  221. data/lib/mongoid/errors/unregistered_class.rb +1 -1
  222. data/lib/mongoid/errors/unsaved_document.rb +1 -3
  223. data/lib/mongoid/errors/unsupported_isolation_level.rb +22 -0
  224. data/lib/mongoid/errors/unsupported_javascript.rb +1 -4
  225. data/lib/mongoid/errors/validations.rb +3 -5
  226. data/lib/mongoid/errors.rb +72 -74
  227. data/lib/mongoid/evolvable.rb +0 -3
  228. data/lib/mongoid/extensions/array.rb +5 -7
  229. data/lib/mongoid/extensions/big_decimal.rb +6 -7
  230. data/lib/mongoid/extensions/binary.rb +3 -6
  231. data/lib/mongoid/extensions/boolean.rb +4 -7
  232. data/lib/mongoid/extensions/bson_document.rb +28 -0
  233. data/lib/mongoid/extensions/date.rb +10 -14
  234. data/lib/mongoid/extensions/date_time.rb +2 -6
  235. data/lib/mongoid/extensions/decimal128.rb +1 -5
  236. data/lib/mongoid/extensions/false_class.rb +3 -5
  237. data/lib/mongoid/extensions/float.rb +5 -10
  238. data/lib/mongoid/extensions/hash.rb +5 -10
  239. data/lib/mongoid/extensions/integer.rb +5 -10
  240. data/lib/mongoid/extensions/module.rb +1 -4
  241. data/lib/mongoid/extensions/nil_class.rb +0 -1
  242. data/lib/mongoid/extensions/object.rb +9 -14
  243. data/lib/mongoid/extensions/object_id.rb +2 -6
  244. data/lib/mongoid/extensions/range.rb +14 -15
  245. data/lib/mongoid/extensions/raw_value.rb +0 -3
  246. data/lib/mongoid/extensions/regexp.rb +3 -6
  247. data/lib/mongoid/extensions/set.rb +3 -4
  248. data/lib/mongoid/extensions/string.rb +8 -12
  249. data/lib/mongoid/extensions/symbol.rb +3 -7
  250. data/lib/mongoid/extensions/time.rb +24 -26
  251. data/lib/mongoid/extensions/time_with_zone.rb +4 -7
  252. data/lib/mongoid/extensions/true_class.rb +3 -5
  253. data/lib/mongoid/extensions.rb +26 -26
  254. data/lib/mongoid/factory.rb +5 -9
  255. data/lib/mongoid/fields/encrypted.rb +0 -1
  256. data/lib/mongoid/fields/foreign_key.rb +9 -10
  257. data/lib/mongoid/fields/localized.rb +12 -12
  258. data/lib/mongoid/fields/standard.rb +5 -7
  259. data/lib/mongoid/fields/validators/macro.rb +23 -34
  260. data/lib/mongoid/fields/validators.rb +1 -2
  261. data/lib/mongoid/fields.rb +151 -58
  262. data/lib/mongoid/findable.rb +82 -53
  263. data/lib/mongoid/indexable/specification.rb +20 -6
  264. data/lib/mongoid/indexable/validators/options.rb +33 -40
  265. data/lib/mongoid/indexable.rb +41 -52
  266. data/lib/mongoid/inspectable.rb +4 -7
  267. data/lib/mongoid/interceptable.rb +41 -40
  268. data/lib/mongoid/loadable.rb +17 -18
  269. data/lib/mongoid/loggable.rb +4 -8
  270. data/lib/mongoid/matchable.rb +1 -8
  271. data/lib/mongoid/matcher/all.rb +2 -5
  272. data/lib/mongoid/matcher/and.rb +0 -3
  273. data/lib/mongoid/matcher/bits.rb +13 -8
  274. data/lib/mongoid/matcher/bits_all_clear.rb +1 -3
  275. data/lib/mongoid/matcher/bits_all_set.rb +1 -3
  276. data/lib/mongoid/matcher/bits_any_clear.rb +1 -3
  277. data/lib/mongoid/matcher/bits_any_set.rb +1 -3
  278. data/lib/mongoid/matcher/elem_match.rb +13 -15
  279. data/lib/mongoid/matcher/elem_match_expression.rb +0 -3
  280. data/lib/mongoid/matcher/eq.rb +0 -3
  281. data/lib/mongoid/matcher/eq_impl.rb +12 -17
  282. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +4 -2
  283. data/lib/mongoid/matcher/exists.rb +1 -4
  284. data/lib/mongoid/matcher/expression.rb +5 -10
  285. data/lib/mongoid/matcher/expression_operator.rb +1 -3
  286. data/lib/mongoid/matcher/field_expression.rb +10 -13
  287. data/lib/mongoid/matcher/field_operator.rb +4 -6
  288. data/lib/mongoid/matcher/gt.rb +0 -3
  289. data/lib/mongoid/matcher/gte.rb +0 -3
  290. data/lib/mongoid/matcher/in.rb +9 -12
  291. data/lib/mongoid/matcher/lt.rb +0 -3
  292. data/lib/mongoid/matcher/lte.rb +0 -3
  293. data/lib/mongoid/matcher/mod.rb +4 -8
  294. data/lib/mongoid/matcher/ne.rb +0 -3
  295. data/lib/mongoid/matcher/nin.rb +0 -3
  296. data/lib/mongoid/matcher/nor.rb +1 -6
  297. data/lib/mongoid/matcher/not.rb +0 -3
  298. data/lib/mongoid/matcher/or.rb +0 -3
  299. data/lib/mongoid/matcher/regex.rb +12 -11
  300. data/lib/mongoid/matcher/size.rb +2 -5
  301. data/lib/mongoid/matcher/type.rb +32 -37
  302. data/lib/mongoid/matcher.rb +7 -16
  303. data/lib/mongoid/model_resolver.rb +1 -0
  304. data/lib/mongoid/persistable/creatable.rb +23 -7
  305. data/lib/mongoid/persistable/deletable.rb +6 -7
  306. data/lib/mongoid/persistable/destroyable.rb +2 -6
  307. data/lib/mongoid/persistable/incrementable.rb +1 -3
  308. data/lib/mongoid/persistable/logical.rb +3 -5
  309. data/lib/mongoid/persistable/maxable.rb +2 -4
  310. data/lib/mongoid/persistable/minable.rb +2 -4
  311. data/lib/mongoid/persistable/multipliable.rb +1 -3
  312. data/lib/mongoid/persistable/poppable.rb +2 -4
  313. data/lib/mongoid/persistable/pullable.rb +3 -5
  314. data/lib/mongoid/persistable/pushable.rb +5 -7
  315. data/lib/mongoid/persistable/renamable.rb +1 -3
  316. data/lib/mongoid/persistable/savable.rb +0 -3
  317. data/lib/mongoid/persistable/settable.rb +4 -13
  318. data/lib/mongoid/persistable/unsettable.rb +1 -3
  319. data/lib/mongoid/persistable/updatable.rb +16 -24
  320. data/lib/mongoid/persistable/upsertable.rb +8 -10
  321. data/lib/mongoid/persistable.rb +28 -27
  322. data/lib/mongoid/persistence_context.rb +34 -76
  323. data/lib/mongoid/pluckable.rb +0 -2
  324. data/lib/mongoid/positional.rb +5 -11
  325. data/lib/mongoid/railtie.rb +16 -22
  326. data/lib/mongoid/railties/console_sandbox.rb +6 -8
  327. data/lib/mongoid/railties/controller_runtime.rb +7 -11
  328. data/lib/mongoid/railties/database.rake +42 -44
  329. data/lib/mongoid/scopable.rb +23 -31
  330. data/lib/mongoid/search_indexable.rb +337 -14
  331. data/lib/mongoid/selectable.rb +1 -3
  332. data/lib/mongoid/serializable.rb +6 -8
  333. data/lib/mongoid/shardable.rb +8 -17
  334. data/lib/mongoid/stateful.rb +5 -10
  335. data/lib/mongoid/stringified_symbol.rb +5 -9
  336. data/lib/mongoid/tasks/database.rake +31 -32
  337. data/lib/mongoid/tasks/database.rb +37 -53
  338. data/lib/mongoid/tasks/encryption.rb +10 -15
  339. data/lib/mongoid/threaded/lifecycle.rb +6 -9
  340. data/lib/mongoid/threaded.rb +132 -69
  341. data/lib/mongoid/timestamps/created/short.rb +2 -3
  342. data/lib/mongoid/timestamps/created.rb +1 -2
  343. data/lib/mongoid/timestamps/short.rb +0 -1
  344. data/lib/mongoid/timestamps/timeless.rb +8 -13
  345. data/lib/mongoid/timestamps/updated/short.rb +2 -3
  346. data/lib/mongoid/timestamps/updated.rb +2 -5
  347. data/lib/mongoid/timestamps.rb +4 -6
  348. data/lib/mongoid/touchable.rb +19 -11
  349. data/lib/mongoid/traversable.rb +3 -2
  350. data/lib/mongoid/validatable/associated.rb +1 -5
  351. data/lib/mongoid/validatable/format.rb +0 -2
  352. data/lib/mongoid/validatable/length.rb +0 -2
  353. data/lib/mongoid/validatable/localizable.rb +0 -3
  354. data/lib/mongoid/validatable/macros.rb +0 -2
  355. data/lib/mongoid/validatable/numericality.rb +24 -3
  356. data/lib/mongoid/validatable/presence.rb +8 -10
  357. data/lib/mongoid/validatable/queryable.rb +0 -3
  358. data/lib/mongoid/validatable/uniqueness.rb +12 -14
  359. data/lib/mongoid/validatable.rb +15 -20
  360. data/lib/mongoid/version.rb +1 -1
  361. data/lib/mongoid/warnings.rb +10 -11
  362. data/lib/mongoid.rb +30 -34
  363. data/lib/rails/generators/mongoid/config/config_generator.rb +2 -4
  364. data/lib/rails/generators/mongoid/config/templates/mongoid.rb +4 -5
  365. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +2 -2
  366. data/lib/rails/generators/mongoid/model/model_generator.rb +5 -8
  367. data/lib/rails/generators/mongoid_generator.rb +6 -10
  368. data/lib/rails/mongoid.rb +1 -3
  369. data/spec/integration/active_job_spec.rb +1 -2
  370. data/spec/integration/app_spec.rb +142 -185
  371. data/spec/integration/associations/belongs_to_spec.rb +30 -28
  372. data/spec/integration/associations/embedded_dirty_spec.rb +0 -1
  373. data/spec/integration/associations/embedded_spec.rb +41 -43
  374. data/spec/integration/associations/embeds_many_spec.rb +46 -29
  375. data/spec/integration/associations/embeds_one_spec.rb +2 -1
  376. data/spec/integration/associations/foreign_key_spec.rb +10 -11
  377. data/spec/integration/associations/foreign_key_spec_models.rb +8 -9
  378. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +18 -30
  379. data/spec/integration/associations/has_many_spec.rb +17 -18
  380. data/spec/integration/associations/has_one_spec.rb +42 -45
  381. data/spec/integration/associations/nested_attributes_assignment_spec.rb +36 -39
  382. data/spec/integration/associations/reverse_population_spec.rb +4 -5
  383. data/spec/integration/associations/reverse_population_spec_models.rb +0 -1
  384. data/spec/integration/associations/scope_option_spec.rb +18 -20
  385. data/spec/integration/atomic/modifiers_spec.rb +72 -52
  386. data/spec/integration/bson_regexp_raw_spec.rb +2 -3
  387. data/spec/integration/caching_spec.rb +68 -0
  388. data/spec/integration/callbacks_models.rb +11 -9
  389. data/spec/integration/callbacks_spec.rb +78 -80
  390. data/spec/integration/contextual/empty_spec.rb +19 -20
  391. data/spec/integration/criteria/alias_query_spec.rb +12 -19
  392. data/spec/integration/criteria/date_field_spec.rb +1 -2
  393. data/spec/integration/criteria/default_scope_spec.rb +23 -18
  394. data/spec/integration/criteria/logical_spec.rb +18 -19
  395. data/spec/integration/criteria/range_spec.rb +77 -86
  396. data/spec/integration/criteria/raw_value_spec.rb +122 -109
  397. data/spec/integration/criteria/time_with_zone_spec.rb +33 -24
  398. data/spec/integration/discriminator_key_spec.rb +85 -85
  399. data/spec/integration/discriminator_value_spec.rb +70 -73
  400. data/spec/integration/document_spec.rb +9 -10
  401. data/spec/integration/dots_and_dollars_spec.rb +105 -130
  402. data/spec/integration/encryption_spec.rb +8 -160
  403. data/spec/integration/i18n_fallbacks_spec.rb +7 -8
  404. data/spec/integration/isolation_state_spec.rb +241 -0
  405. data/spec/integration/matcher_examples_spec.rb +145 -168
  406. data/spec/integration/matcher_operator_data/in.yml +6 -6
  407. data/spec/integration/matcher_operator_data/regex.yml +0 -21
  408. data/spec/integration/matcher_operator_spec.rb +16 -26
  409. data/spec/integration/matcher_spec.rb +31 -32
  410. data/spec/integration/persistence/collection_options_spec.rb +0 -2
  411. data/spec/integration/persistence/range_field_spec.rb +24 -2
  412. data/spec/integration/server_query_spec.rb +43 -37
  413. data/spec/integration/shardable_spec.rb +10 -11
  414. data/spec/integration/stringified_symbol_field_spec.rb +28 -43
  415. data/spec/lite_spec_helper.rb +11 -12
  416. data/spec/mongoid/association/accessors_spec.rb +197 -285
  417. data/spec/mongoid/association/auto_save_spec.rb +62 -93
  418. data/spec/mongoid/association/builders_spec.rb +121 -74
  419. data/spec/mongoid/association/constrainable_spec.rb +9 -22
  420. data/spec/mongoid/association/counter_cache_spec.rb +71 -104
  421. data/spec/mongoid/association/depending_spec.rb +166 -208
  422. data/spec/mongoid/association/eager_spec.rb +416 -80
  423. data/spec/mongoid/association/embedded/cyclic_spec.rb +36 -48
  424. data/spec/mongoid/association/embedded/dirty_spec.rb +15 -20
  425. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +36 -54
  426. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +8 -15
  427. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +135 -175
  428. data/spec/mongoid/association/embedded/embedded_in_spec.rb +25 -127
  429. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +9 -14
  430. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +38 -51
  431. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +1151 -1340
  432. data/spec/mongoid/association/embedded/embeds_many_models.rb +17 -17
  433. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +11 -11
  434. data/spec/mongoid/association/embedded/embeds_many_spec.rb +25 -138
  435. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +15 -23
  436. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +18 -26
  437. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +204 -273
  438. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +0 -1
  439. data/spec/mongoid/association/embedded/embeds_one_models.rb +0 -1
  440. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +5 -6
  441. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -143
  442. data/spec/mongoid/association/macros_spec.rb +213 -300
  443. data/spec/mongoid/association/nested/many_spec.rb +51 -73
  444. data/spec/mongoid/association/nested/one_spec.rb +56 -80
  445. data/spec/mongoid/association/options_spec.rb +187 -310
  446. data/spec/mongoid/association/polymorphic_spec.rb +35 -53
  447. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +55 -76
  448. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +36 -41
  449. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +81 -101
  450. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +258 -345
  451. data/spec/mongoid/association/referenced/belongs_to_models.rb +4 -3
  452. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +3 -4
  453. data/spec/mongoid/association/referenced/belongs_to_spec.rb +91 -294
  454. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +42 -56
  455. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +41 -32
  456. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +36 -42
  457. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +8 -9
  458. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +771 -1023
  459. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +9 -9
  460. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +5 -6
  461. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +59 -177
  462. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +29 -43
  463. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +53 -53
  464. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +104 -67
  465. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +431 -675
  466. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -2
  467. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -156
  468. data/spec/mongoid/association/referenced/has_many_models.rb +1 -2
  469. data/spec/mongoid/association/referenced/has_many_query_spec.rb +3 -4
  470. data/spec/mongoid/association/referenced/has_many_spec.rb +44 -188
  471. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +26 -38
  472. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +28 -29
  473. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +29 -42
  474. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +270 -332
  475. data/spec/mongoid/association/referenced/has_one_models.rb +1 -2
  476. data/spec/mongoid/association/referenced/has_one_query_spec.rb +3 -4
  477. data/spec/mongoid/association/referenced/has_one_spec.rb +40 -188
  478. data/spec/mongoid/association/reflections_spec.rb +14 -24
  479. data/spec/mongoid/association/syncable_spec.rb +102 -125
  480. data/spec/mongoid/association_spec.rb +47 -70
  481. data/spec/mongoid/atomic/modifiers_spec.rb +184 -197
  482. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +39 -52
  483. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +35 -49
  484. data/spec/mongoid/atomic/paths/root_spec.rb +9 -15
  485. data/spec/mongoid/atomic/paths_spec.rb +81 -117
  486. data/spec/mongoid/atomic_spec.rb +156 -171
  487. data/spec/mongoid/attributes/dynamic_spec.rb +5 -6
  488. data/spec/mongoid/attributes/nested_spec.rb +1221 -1888
  489. data/spec/mongoid/attributes/nested_spec_models.rb +8 -9
  490. data/spec/mongoid/attributes/projector_spec.rb +2 -6
  491. data/spec/mongoid/attributes/readonly_spec.rb +73 -97
  492. data/spec/mongoid/attributes_spec.rb +669 -826
  493. data/spec/mongoid/cacheable_spec.rb +74 -44
  494. data/spec/mongoid/changeable_spec.rb +591 -733
  495. data/spec/mongoid/clients/factory_spec.rb +122 -154
  496. data/spec/mongoid/clients/options_spec.rb +40 -59
  497. data/spec/mongoid/clients/sessions_spec.rb +25 -44
  498. data/spec/mongoid/clients/transactions_spec.rb +33 -50
  499. data/spec/mongoid/clients/transactions_spec_models.rb +3 -4
  500. data/spec/mongoid/clients_spec.rb +265 -355
  501. data/spec/mongoid/collection_configurable_spec.rb +9 -12
  502. data/spec/mongoid/composable_spec.rb +2 -9
  503. data/spec/mongoid/config/defaults_spec.rb +24 -49
  504. data/spec/mongoid/config/encryption_spec.rb +53 -284
  505. data/spec/mongoid/config/environment_spec.rb +30 -40
  506. data/spec/mongoid/config/introspection_spec.rb +42 -37
  507. data/spec/mongoid/config/options_spec.rb +14 -21
  508. data/spec/mongoid/config_spec.rb +145 -195
  509. data/spec/mongoid/contextual/aggregable/memory_spec.rb +98 -226
  510. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +4 -7
  511. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +149 -187
  512. data/spec/mongoid/contextual/aggregable/none_spec.rb +14 -16
  513. data/spec/mongoid/contextual/atomic_spec.rb +223 -271
  514. data/spec/mongoid/contextual/map_reduce_spec.rb +110 -138
  515. data/spec/mongoid/contextual/memory_spec.rb +706 -1031
  516. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +12 -13
  517. data/spec/mongoid/contextual/mongo_spec.rb +1008 -1213
  518. data/spec/mongoid/contextual/none_spec.rb +54 -59
  519. data/spec/mongoid/contextual/short_circuit_spec.rb +139 -0
  520. data/spec/mongoid/copyable_spec.rb +254 -300
  521. data/spec/mongoid/copyable_spec_models.rb +0 -1
  522. data/spec/mongoid/criteria/findable_spec.rb +322 -387
  523. data/spec/mongoid/criteria/includable_spec.rb +421 -372
  524. data/spec/mongoid/criteria/includable_spec_models.rb +16 -7
  525. data/spec/mongoid/criteria/inspectable_spec.rb +11 -14
  526. data/spec/mongoid/criteria/marshalable_spec.rb +11 -14
  527. data/spec/mongoid/criteria/modifiable_spec.rb +366 -512
  528. data/spec/mongoid/criteria/options_spec.rb +2 -7
  529. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +112 -141
  530. data/spec/mongoid/criteria/queryable/expandable_spec.rb +8 -11
  531. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +127 -184
  532. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +123 -60
  533. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +84 -117
  534. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +44 -65
  535. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +86 -108
  536. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +94 -33
  537. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +103 -138
  538. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +95 -34
  539. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +25 -38
  540. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +26 -28
  541. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +32 -54
  542. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +136 -130
  543. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +16 -24
  544. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +15 -24
  545. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +12 -19
  546. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +46 -63
  547. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +28 -42
  548. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +73 -96
  549. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +71 -92
  550. data/spec/mongoid/criteria/queryable/key_spec.rb +32 -36
  551. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +44 -49
  552. data/spec/mongoid/criteria/queryable/optional_spec.rb +373 -486
  553. data/spec/mongoid/criteria/queryable/options_spec.rb +172 -123
  554. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +65 -87
  555. data/spec/mongoid/criteria/queryable/queryable_spec.rb +41 -53
  556. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +576 -682
  557. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +7 -11
  558. data/spec/mongoid/criteria/queryable/selectable_spec.rb +807 -998
  559. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +154 -391
  560. data/spec/mongoid/criteria/queryable/selector_spec.rb +294 -390
  561. data/spec/mongoid/criteria/queryable/smash_spec.rb +6 -11
  562. data/spec/mongoid/criteria/queryable/storable_spec.rb +54 -81
  563. data/spec/mongoid/criteria/queryable_mql_spec.rb +92 -0
  564. data/spec/mongoid/criteria/scopable_spec.rb +102 -138
  565. data/spec/mongoid/criteria/translator_spec.rb +59 -60
  566. data/spec/mongoid/criteria_projection_spec.rb +81 -99
  567. data/spec/mongoid/criteria_spec.rb +935 -952
  568. data/spec/mongoid/document_fields_spec.rb +28 -30
  569. data/spec/mongoid/document_persistence_context_spec.rb +13 -15
  570. data/spec/mongoid/document_query_spec.rb +9 -12
  571. data/spec/mongoid/document_spec.rb +317 -409
  572. data/spec/mongoid/equality_spec.rb +69 -102
  573. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +8 -11
  574. data/spec/mongoid/errors/attribute_not_loaded_spec.rb +7 -10
  575. data/spec/mongoid/errors/callback_spec.rb +8 -11
  576. data/spec/mongoid/errors/delete_restriction_spec.rb +5 -8
  577. data/spec/mongoid/errors/document_not_destroyed_spec.rb +7 -10
  578. data/spec/mongoid/errors/document_not_found_spec.rb +51 -61
  579. data/spec/mongoid/errors/invalid_collection_spec.rb +9 -13
  580. data/spec/mongoid/errors/invalid_config_file_spec.rb +8 -11
  581. data/spec/mongoid/errors/invalid_config_option_spec.rb +8 -11
  582. data/spec/mongoid/errors/invalid_field_option_spec.rb +7 -10
  583. data/spec/mongoid/errors/invalid_field_spec.rb +10 -11
  584. data/spec/mongoid/errors/invalid_field_type_spec.rb +9 -12
  585. data/spec/mongoid/errors/invalid_find_spec.rb +8 -11
  586. data/spec/mongoid/errors/invalid_includes_spec.rb +9 -13
  587. data/spec/mongoid/errors/invalid_index_spec.rb +8 -11
  588. data/spec/mongoid/errors/invalid_options_spec.rb +8 -11
  589. data/spec/mongoid/errors/invalid_path_spec.rb +7 -10
  590. data/spec/mongoid/errors/invalid_relation_spec.rb +15 -16
  591. data/spec/mongoid/errors/invalid_scope_spec.rb +8 -11
  592. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -6
  593. data/spec/mongoid/errors/invalid_storage_options_spec.rb +8 -11
  594. data/spec/mongoid/errors/invalid_time_spec.rb +8 -11
  595. data/spec/mongoid/errors/inverse_not_found_spec.rb +9 -12
  596. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +9 -12
  597. data/spec/mongoid/errors/mixed_relations_spec.rb +8 -11
  598. data/spec/mongoid/errors/mongoid_error_spec.rb +21 -24
  599. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -9
  600. data/spec/mongoid/errors/no_client_config_spec.rb +7 -10
  601. data/spec/mongoid/errors/no_client_database_spec.rb +9 -12
  602. data/spec/mongoid/errors/no_client_hosts_spec.rb +9 -12
  603. data/spec/mongoid/errors/no_clients_config_spec.rb +7 -10
  604. data/spec/mongoid/errors/no_environment_spec.rb +8 -11
  605. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +8 -11
  606. data/spec/mongoid/errors/no_metadata_spec.rb +7 -10
  607. data/spec/mongoid/errors/no_parent_spec.rb +7 -10
  608. data/spec/mongoid/errors/readonly_attribute_spec.rb +7 -10
  609. data/spec/mongoid/errors/readonly_document_spec.rb +6 -9
  610. data/spec/mongoid/errors/scope_overwrite_spec.rb +9 -12
  611. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +9 -12
  612. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -8
  613. data/spec/mongoid/errors/unsaved_document_spec.rb +8 -11
  614. data/spec/mongoid/errors/unsupported_javascript_spec.rb +9 -12
  615. data/spec/mongoid/errors/validations_spec.rb +11 -14
  616. data/spec/mongoid/extensions/array_spec.rb +70 -92
  617. data/spec/mongoid/extensions/big_decimal_spec.rb +233 -313
  618. data/spec/mongoid/extensions/binary_spec.rb +21 -32
  619. data/spec/mongoid/extensions/boolean_spec.rb +52 -75
  620. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +43 -54
  621. data/spec/mongoid/extensions/date_spec.rb +26 -38
  622. data/spec/mongoid/extensions/date_time_spec.rb +22 -32
  623. data/spec/mongoid/extensions/decimal128_spec.rb +12 -18
  624. data/spec/mongoid/extensions/false_class_spec.rb +10 -17
  625. data/spec/mongoid/extensions/float_spec.rb +40 -61
  626. data/spec/mongoid/extensions/hash_spec.rb +46 -64
  627. data/spec/mongoid/extensions/integer_spec.rb +40 -61
  628. data/spec/mongoid/extensions/module_spec.rb +13 -18
  629. data/spec/mongoid/extensions/nil_class_spec.rb +2 -5
  630. data/spec/mongoid/extensions/object_id_spec.rb +159 -247
  631. data/spec/mongoid/extensions/object_spec.rb +31 -47
  632. data/spec/mongoid/extensions/range_spec.rb +112 -115
  633. data/spec/mongoid/extensions/raw_value_spec.rb +10 -12
  634. data/spec/mongoid/extensions/regexp_spec.rb +23 -36
  635. data/spec/mongoid/extensions/set_spec.rb +38 -49
  636. data/spec/mongoid/extensions/string_spec.rb +118 -167
  637. data/spec/mongoid/extensions/stringified_symbol_spec.rb +29 -43
  638. data/spec/mongoid/extensions/symbol_spec.rb +12 -20
  639. data/spec/mongoid/extensions/time_spec.rb +160 -202
  640. data/spec/mongoid/extensions/time_with_zone_spec.rb +79 -105
  641. data/spec/mongoid/extensions/true_class_spec.rb +10 -17
  642. data/spec/mongoid/factory_spec.rb +125 -148
  643. data/spec/mongoid/fields/foreign_key_spec.rb +124 -169
  644. data/spec/mongoid/fields/localized_spec.rb +140 -185
  645. data/spec/mongoid/fields/standard_spec.rb +43 -59
  646. data/spec/mongoid/fields_spec.rb +751 -620
  647. data/spec/mongoid/findable_spec.rb +260 -228
  648. data/spec/mongoid/indexable/specification_spec.rb +42 -58
  649. data/spec/mongoid/indexable_spec.rb +260 -264
  650. data/spec/mongoid/inspectable_spec.rb +45 -55
  651. data/spec/mongoid/interceptable_spec.rb +784 -922
  652. data/spec/mongoid/interceptable_spec_models.rb +35 -35
  653. data/spec/mongoid/loading_spec.rb +47 -43
  654. data/spec/mongoid/loggable_spec.rb +3 -6
  655. data/spec/mongoid/matcher/extract_attribute_spec.rb +2 -6
  656. data/spec/mongoid/mongoizable_spec.rb +81 -90
  657. data/spec/mongoid/monkey_patches_spec.rb +4 -0
  658. data/spec/mongoid/persistable/creatable_spec.rb +181 -220
  659. data/spec/mongoid/persistable/deletable_spec.rb +139 -179
  660. data/spec/mongoid/persistable/destroyable_spec.rb +135 -164
  661. data/spec/mongoid/persistable/incrementable_spec.rb +65 -84
  662. data/spec/mongoid/persistable/logical_spec.rb +48 -61
  663. data/spec/mongoid/persistable/maxable_spec.rb +45 -44
  664. data/spec/mongoid/persistable/minable_spec.rb +45 -44
  665. data/spec/mongoid/persistable/multipliable_spec.rb +54 -69
  666. data/spec/mongoid/persistable/poppable_spec.rb +47 -60
  667. data/spec/mongoid/persistable/pullable_spec.rb +79 -103
  668. data/spec/mongoid/persistable/pushable_spec.rb +106 -131
  669. data/spec/mongoid/persistable/renamable_spec.rb +52 -65
  670. data/spec/mongoid/persistable/savable_spec.rb +152 -189
  671. data/spec/mongoid/persistable/settable_spec.rb +121 -145
  672. data/spec/mongoid/persistable/unsettable_spec.rb +56 -73
  673. data/spec/mongoid/persistable/updatable_spec.rb +185 -232
  674. data/spec/mongoid/persistable/upsertable_spec.rb +66 -77
  675. data/spec/mongoid/persistable_spec.rb +132 -139
  676. data/spec/mongoid/persistence_context_spec.rb +31 -89
  677. data/spec/mongoid/positional_spec.rb +67 -79
  678. data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +0 -3
  679. data/spec/mongoid/railties/console_sandbox_spec.rb +0 -1
  680. data/spec/mongoid/relations/proxy_spec.rb +0 -1
  681. data/spec/mongoid/reloadable_spec.rb +250 -145
  682. data/spec/mongoid/scopable_spec.rb +319 -398
  683. data/spec/mongoid/search_indexable_spec.rb +446 -41
  684. data/spec/mongoid/selectable_spec.rb +36 -51
  685. data/spec/mongoid/serializable_spec.rb +269 -312
  686. data/spec/mongoid/shardable_models.rb +5 -5
  687. data/spec/mongoid/shardable_spec.rb +44 -46
  688. data/spec/mongoid/stateful_spec.rb +55 -75
  689. data/spec/mongoid/tasks/database_rake_spec.rb +138 -141
  690. data/spec/mongoid/tasks/database_spec.rb +80 -98
  691. data/spec/mongoid/tasks/encryption_spec.rb +22 -20
  692. data/spec/mongoid/threaded_spec.rb +57 -83
  693. data/spec/mongoid/timestamps/created/short_spec.rb +12 -16
  694. data/spec/mongoid/timestamps/created_spec.rb +16 -20
  695. data/spec/mongoid/timestamps/timeless_spec.rb +31 -43
  696. data/spec/mongoid/timestamps/updated/short_spec.rb +21 -28
  697. data/spec/mongoid/timestamps/updated_spec.rb +18 -25
  698. data/spec/mongoid/timestamps_spec.rb +171 -188
  699. data/spec/mongoid/timestamps_spec_models.rb +12 -13
  700. data/spec/mongoid/touchable_spec.rb +330 -294
  701. data/spec/mongoid/touchable_spec_models.rb +35 -37
  702. data/spec/mongoid/traversable_spec.rb +435 -471
  703. data/spec/mongoid/validatable/associated_spec.rb +42 -60
  704. data/spec/mongoid/validatable/format_spec.rb +24 -34
  705. data/spec/mongoid/validatable/length_spec.rb +62 -86
  706. data/spec/mongoid/validatable/numericality_spec.rb +114 -23
  707. data/spec/mongoid/validatable/presence_spec.rb +149 -203
  708. data/spec/mongoid/validatable/uniqueness_spec.rb +632 -830
  709. data/spec/mongoid/validatable_spec.rb +71 -103
  710. data/spec/mongoid/warnings_spec.rb +5 -9
  711. data/spec/mongoid_spec.rb +25 -41
  712. data/spec/rails/controller_extension/controller_runtime_spec.rb +45 -49
  713. data/spec/rails/mongoid_spec.rb +15 -15
  714. data/spec/shared/lib/mrss/cluster_config.rb +5 -40
  715. data/spec/shared/lib/mrss/constraints.rb +7 -46
  716. data/spec/shared/lib/mrss/docker_runner.rb +10 -21
  717. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -31
  718. data/spec/shared/lib/mrss/release/candidate.rb +18 -12
  719. data/spec/shared/lib/mrss/server_version_registry.rb +1 -5
  720. data/spec/shared/share/Dockerfile.erb +6 -8
  721. data/spec/shared/shlib/server.sh +0 -50
  722. data/spec/shared/shlib/set_env.sh +4 -10
  723. data/spec/spec_helper.rb +54 -31
  724. data/spec/support/authorization.rb +0 -1
  725. data/spec/support/client_registry.rb +1 -2
  726. data/spec/support/constraints.rb +8 -25
  727. data/spec/support/crypt/models.rb +7 -165
  728. data/spec/support/crypt.rb +6 -9
  729. data/spec/support/expectations.rb +21 -7
  730. data/spec/support/feature_sandbox.rb +1 -4
  731. data/spec/support/helpers.rb +0 -1
  732. data/spec/support/immutable_ids.rb +20 -21
  733. data/spec/support/macros.rb +1 -3
  734. data/spec/support/models/account.rb +4 -5
  735. data/spec/support/models/acolyte.rb +5 -5
  736. data/spec/support/models/actor.rb +3 -3
  737. data/spec/support/models/actress.rb +0 -1
  738. data/spec/support/models/address.rb +11 -11
  739. data/spec/support/models/address_component.rb +1 -1
  740. data/spec/support/models/address_number.rb +1 -1
  741. data/spec/support/models/agency.rb +1 -1
  742. data/spec/support/models/agent.rb +1 -1
  743. data/spec/support/models/album.rb +1 -2
  744. data/spec/support/models/alert.rb +1 -1
  745. data/spec/support/models/animal.rb +4 -5
  746. data/spec/support/models/answer.rb +1 -1
  747. data/spec/support/models/appointment.rb +2 -2
  748. data/spec/support/models/armrest.rb +0 -1
  749. data/spec/support/models/array_field.rb +0 -1
  750. data/spec/support/models/article.rb +0 -1
  751. data/spec/support/models/artist.rb +16 -12
  752. data/spec/support/models/artwork.rb +1 -1
  753. data/spec/support/models/audible_sound.rb +0 -1
  754. data/spec/support/models/audio.rb +2 -2
  755. data/spec/support/models/augmentation.rb +1 -2
  756. data/spec/support/models/author.rb +1 -1
  757. data/spec/support/models/baby.rb +1 -1
  758. data/spec/support/models/band.rb +0 -1
  759. data/spec/support/models/bar.rb +2 -2
  760. data/spec/support/models/basic.rb +0 -1
  761. data/spec/support/models/bed.rb +0 -1
  762. data/spec/support/models/big_palette.rb +0 -1
  763. data/spec/support/models/birthday.rb +3 -5
  764. data/spec/support/models/bolt.rb +0 -1
  765. data/spec/support/models/bomb.rb +1 -1
  766. data/spec/support/models/book.rb +1 -1
  767. data/spec/support/models/breed.rb +1 -1
  768. data/spec/support/models/browser.rb +1 -2
  769. data/spec/support/models/building.rb +0 -1
  770. data/spec/support/models/building_address.rb +1 -1
  771. data/spec/support/models/bus.rb +1 -1
  772. data/spec/support/models/business.rb +2 -2
  773. data/spec/support/models/callback_test.rb +1 -1
  774. data/spec/support/models/canvas.rb +5 -6
  775. data/spec/support/models/car.rb +0 -1
  776. data/spec/support/models/cat.rb +0 -2
  777. data/spec/support/models/catalog.rb +0 -1
  778. data/spec/support/models/category.rb +1 -1
  779. data/spec/support/models/child.rb +1 -1
  780. data/spec/support/models/child_doc.rb +5 -6
  781. data/spec/support/models/church.rb +1 -1
  782. data/spec/support/models/circle.rb +0 -1
  783. data/spec/support/models/circuit.rb +2 -2
  784. data/spec/support/models/circus.rb +0 -1
  785. data/spec/support/models/code.rb +2 -1
  786. data/spec/support/models/coding/pull_request.rb +0 -1
  787. data/spec/support/models/coding.rb +0 -1
  788. data/spec/support/models/comment.rb +0 -1
  789. data/spec/support/models/company.rb +0 -1
  790. data/spec/support/models/consumption_period.rb +0 -1
  791. data/spec/support/models/contextable_item.rb +1 -1
  792. data/spec/support/models/contractor.rb +1 -1
  793. data/spec/support/models/cookie.rb +0 -1
  794. data/spec/support/models/country_code.rb +2 -3
  795. data/spec/support/models/courier_job.rb +2 -2
  796. data/spec/support/models/cover.rb +0 -1
  797. data/spec/support/models/crate.rb +0 -1
  798. data/spec/support/models/customer.rb +0 -1
  799. data/spec/support/models/customer_address.rb +0 -1
  800. data/spec/support/models/deed.rb +1 -1
  801. data/spec/support/models/definition.rb +1 -1
  802. data/spec/support/models/delegating_patient.rb +0 -1
  803. data/spec/support/models/description.rb +0 -1
  804. data/spec/support/models/dictionary.rb +1 -1
  805. data/spec/support/models/division.rb +2 -2
  806. data/spec/support/models/doctor.rb +0 -1
  807. data/spec/support/models/dog.rb +2 -2
  808. data/spec/support/models/dokument.rb +1 -1
  809. data/spec/support/models/draft.rb +0 -1
  810. data/spec/support/models/dragon.rb +1 -1
  811. data/spec/support/models/driver.rb +2 -2
  812. data/spec/support/models/drug.rb +1 -1
  813. data/spec/support/models/dungeon.rb +1 -1
  814. data/spec/support/models/edit.rb +1 -1
  815. data/spec/support/models/email.rb +1 -1
  816. data/spec/support/models/employer.rb +1 -2
  817. data/spec/support/models/entry.rb +1 -1
  818. data/spec/support/models/eraser.rb +0 -1
  819. data/spec/support/models/even.rb +1 -1
  820. data/spec/support/models/event.rb +3 -4
  821. data/spec/support/models/exhibition.rb +1 -1
  822. data/spec/support/models/exhibitor.rb +1 -1
  823. data/spec/support/models/explosion.rb +1 -1
  824. data/spec/support/models/eye.rb +0 -1
  825. data/spec/support/models/eye_bowl.rb +2 -3
  826. data/spec/support/models/face.rb +2 -3
  827. data/spec/support/models/fanatic.rb +1 -1
  828. data/spec/support/models/favorite.rb +1 -1
  829. data/spec/support/models/filesystem.rb +1 -1
  830. data/spec/support/models/fire_hydrant.rb +1 -1
  831. data/spec/support/models/firefox.rb +0 -1
  832. data/spec/support/models/fish.rb +0 -1
  833. data/spec/support/models/folder.rb +0 -2
  834. data/spec/support/models/folder_item.rb +1 -3
  835. data/spec/support/models/fruits.rb +9 -5
  836. data/spec/support/models/game.rb +3 -4
  837. data/spec/support/models/ghost.rb +0 -1
  838. data/spec/support/models/guitar.rb +0 -1
  839. data/spec/support/models/hole.rb +0 -1
  840. data/spec/support/models/home.rb +1 -1
  841. data/spec/support/models/house.rb +2 -2
  842. data/spec/support/models/html_writer.rb +0 -1
  843. data/spec/support/models/id_key.rb +3 -3
  844. data/spec/support/models/idnodef.rb +0 -1
  845. data/spec/support/models/image.rb +0 -1
  846. data/spec/support/models/implant.rb +1 -2
  847. data/spec/support/models/instrument.rb +2 -3
  848. data/spec/support/models/item.rb +2 -2
  849. data/spec/support/models/jar.rb +1 -2
  850. data/spec/support/models/kaleidoscope.rb +1 -1
  851. data/spec/support/models/kangaroo.rb +1 -1
  852. data/spec/support/models/label.rb +2 -2
  853. data/spec/support/models/language.rb +1 -1
  854. data/spec/support/models/lat_lng.rb +0 -1
  855. data/spec/support/models/league.rb +1 -1
  856. data/spec/support/models/learner.rb +0 -1
  857. data/spec/support/models/line_item.rb +1 -1
  858. data/spec/support/models/location.rb +1 -1
  859. data/spec/support/models/login.rb +1 -2
  860. data/spec/support/models/manufacturer.rb +0 -1
  861. data/spec/support/models/meat.rb +1 -1
  862. data/spec/support/models/membership.rb +1 -1
  863. data/spec/support/models/message.rb +1 -2
  864. data/spec/support/models/minim.rb +0 -1
  865. data/spec/support/models/mixed_drink.rb +1 -1
  866. data/spec/support/models/modifier_models.rb +25 -0
  867. data/spec/support/models/mop.rb +0 -1
  868. data/spec/support/models/movie.rb +1 -1
  869. data/spec/support/models/my_hash.rb +1 -2
  870. data/spec/support/models/name.rb +4 -5
  871. data/spec/support/models/name_only.rb +0 -1
  872. data/spec/support/models/node.rb +1 -1
  873. data/spec/support/models/note.rb +3 -3
  874. data/spec/support/models/nut.rb +0 -1
  875. data/spec/support/models/odd.rb +1 -1
  876. data/spec/support/models/order.rb +1 -1
  877. data/spec/support/models/ordered_post.rb +1 -1
  878. data/spec/support/models/ordered_preference.rb +1 -1
  879. data/spec/support/models/oscar.rb +1 -1
  880. data/spec/support/models/other_owner_object.rb +0 -1
  881. data/spec/support/models/override.rb +3 -11
  882. data/spec/support/models/ownable.rb +1 -1
  883. data/spec/support/models/owner.rb +1 -1
  884. data/spec/support/models/pack.rb +0 -1
  885. data/spec/support/models/page.rb +3 -3
  886. data/spec/support/models/page_question.rb +1 -1
  887. data/spec/support/models/palette.rb +2 -2
  888. data/spec/support/models/parent.rb +2 -2
  889. data/spec/support/models/parent_doc.rb +1 -1
  890. data/spec/support/models/passport.rb +0 -1
  891. data/spec/support/models/patient.rb +2 -2
  892. data/spec/support/models/pdf_writer.rb +0 -1
  893. data/spec/support/models/pencil.rb +0 -1
  894. data/spec/support/models/person.rb +32 -28
  895. data/spec/support/models/pet.rb +1 -1
  896. data/spec/support/models/pet_owner.rb +1 -1
  897. data/spec/support/models/phone.rb +1 -2
  898. data/spec/support/models/piano.rb +0 -1
  899. data/spec/support/models/pizza.rb +1 -1
  900. data/spec/support/models/player.rb +5 -5
  901. data/spec/support/models/post.rb +12 -12
  902. data/spec/support/models/post_genre.rb +1 -1
  903. data/spec/support/models/powerup.rb +1 -2
  904. data/spec/support/models/preference.rb +2 -2
  905. data/spec/support/models/princess.rb +1 -1
  906. data/spec/support/models/product.rb +3 -3
  907. data/spec/support/models/profile.rb +2 -1
  908. data/spec/support/models/pronunciation.rb +1 -1
  909. data/spec/support/models/pub.rb +2 -2
  910. data/spec/support/models/publication/encyclopedia.rb +0 -1
  911. data/spec/support/models/publication/review.rb +0 -1
  912. data/spec/support/models/publication.rb +0 -1
  913. data/spec/support/models/purchase.rb +1 -1
  914. data/spec/support/models/purchased_item.rb +1 -1
  915. data/spec/support/models/question.rb +2 -2
  916. data/spec/support/models/quiz.rb +1 -1
  917. data/spec/support/models/rating.rb +1 -1
  918. data/spec/support/models/record.rb +2 -3
  919. data/spec/support/models/registry.rb +1 -1
  920. data/spec/support/models/role.rb +1 -1
  921. data/spec/support/models/root_category.rb +1 -1
  922. data/spec/support/models/sandbox/app/models/app_models_message.rb +0 -1
  923. data/spec/support/models/sandbox/lib/models/lib_models_message.rb +0 -1
  924. data/spec/support/models/sandbox/sandbox_message.rb +0 -1
  925. data/spec/support/models/sandbox/sandbox_user.rb +0 -1
  926. data/spec/support/models/sandbox/subdir/sandbox_comment.rb +0 -1
  927. data/spec/support/models/sandwich.rb +1 -1
  928. data/spec/support/models/scheduler.rb +0 -1
  929. data/spec/support/models/school.rb +0 -1
  930. data/spec/support/models/scribe.rb +1 -1
  931. data/spec/support/models/sealer.rb +0 -1
  932. data/spec/support/models/seat.rb +0 -1
  933. data/spec/support/models/seo.rb +1 -1
  934. data/spec/support/models/series.rb +1 -1
  935. data/spec/support/models/server.rb +1 -1
  936. data/spec/support/models/service.rb +2 -2
  937. data/spec/support/models/shape.rb +3 -3
  938. data/spec/support/models/shelf.rb +1 -1
  939. data/spec/support/models/shield.rb +2 -2
  940. data/spec/support/models/shipment_address.rb +0 -1
  941. data/spec/support/models/shipping_container.rb +1 -1
  942. data/spec/support/models/shipping_pack.rb +0 -1
  943. data/spec/support/models/shirt.rb +0 -1
  944. data/spec/support/models/shop.rb +2 -2
  945. data/spec/support/models/short_agent.rb +0 -1
  946. data/spec/support/models/short_quiz.rb +1 -1
  947. data/spec/support/models/simple.rb +1 -1
  948. data/spec/support/models/slave.rb +1 -1
  949. data/spec/support/models/song.rb +1 -2
  950. data/spec/support/models/sound.rb +2 -2
  951. data/spec/support/models/spacer.rb +0 -1
  952. data/spec/support/models/square.rb +0 -1
  953. data/spec/support/models/staff.rb +0 -1
  954. data/spec/support/models/store_as_dup_test1.rb +2 -2
  955. data/spec/support/models/store_as_dup_test2.rb +1 -1
  956. data/spec/support/models/store_as_dup_test3.rb +2 -2
  957. data/spec/support/models/store_as_dup_test4.rb +1 -1
  958. data/spec/support/models/strategy.rb +0 -1
  959. data/spec/support/models/student.rb +1 -2
  960. data/spec/support/models/sub_item.rb +0 -1
  961. data/spec/support/models/subscription.rb +2 -2
  962. data/spec/support/models/survey.rb +2 -2
  963. data/spec/support/models/symptom.rb +2 -2
  964. data/spec/support/models/system_role.rb +2 -3
  965. data/spec/support/models/tag.rb +2 -2
  966. data/spec/support/models/target.rb +1 -1
  967. data/spec/support/models/template.rb +1 -1
  968. data/spec/support/models/thing.rb +1 -1
  969. data/spec/support/models/threadlocker.rb +0 -1
  970. data/spec/support/models/title.rb +0 -1
  971. data/spec/support/models/tool.rb +3 -3
  972. data/spec/support/models/topping.rb +1 -1
  973. data/spec/support/models/toy.rb +0 -1
  974. data/spec/support/models/track.rb +1 -1
  975. data/spec/support/models/translation.rb +1 -1
  976. data/spec/support/models/tree.rb +2 -3
  977. data/spec/support/models/truck.rb +0 -1
  978. data/spec/support/models/updatable.rb +0 -1
  979. data/spec/support/models/user.rb +3 -4
  980. data/spec/support/models/user_account.rb +3 -3
  981. data/spec/support/models/validation_callback.rb +4 -4
  982. data/spec/support/models/vehicle.rb +2 -3
  983. data/spec/support/models/version.rb +1 -1
  984. data/spec/support/models/vertex.rb +0 -1
  985. data/spec/support/models/vet_visit.rb +1 -1
  986. data/spec/support/models/video.rb +2 -2
  987. data/spec/support/models/video_game.rb +0 -1
  988. data/spec/support/models/washer.rb +0 -1
  989. data/spec/support/models/weapon.rb +1 -2
  990. data/spec/support/models/wiki_page.rb +2 -3
  991. data/spec/support/models/word.rb +2 -2
  992. data/spec/support/models/word_origin.rb +1 -2
  993. data/spec/support/models/writer.rb +3 -3
  994. data/spec/support/rails_mock.rb +7 -12
  995. data/spec/support/shared/time.rb +0 -1
  996. data/spec/support/sinatra_mock.rb +4 -2
  997. data/spec/support/spec_config.rb +19 -18
  998. metadata +14 -14
  999. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
  1000. data/lib/mongoid/errors/no_encryption_schema.rb +0 -28
  1001. data/lib/mongoid/field_readable.rb +0 -70
  1002. data/lib/mongoid/matcher/regexp_budget.rb +0 -383
  1003. data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
  1004. data/spec/integration/query_operator_guard_spec.rb +0 -89
  1005. data/spec/mongoid/encryptable_spec.rb +0 -61
  1006. data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
@@ -1,91 +1,81 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
- require "spec_helper"
5
- require_relative './selectable_shared_examples'
3
+ require 'spec_helper'
4
+ require_relative 'selectable_shared_examples'
6
5
 
7
6
  describe Mongoid::Criteria::Queryable::Selectable do
8
-
9
7
  let(:query) do
10
- Mongoid::Query.new("id" => "_id")
8
+ Mongoid::Query.new('id' => '_id')
11
9
  end
12
10
 
13
- describe "#where" do
14
-
11
+ describe '#where' do
15
12
  let(:query_method) { :where }
16
13
 
17
- context "when provided no criterion" do
18
-
14
+ context 'when provided no criterion' do
19
15
  let(:selection) do
20
16
  query.where
21
17
  end
22
18
 
23
- it "does not add any criterion" do
19
+ it 'does not add any criterion' do
24
20
  expect(selection.selector).to eq({})
25
21
  end
26
22
 
27
- it "returns the query" do
23
+ it 'returns the query' do
28
24
  expect(selection).to eq(query)
29
25
  end
30
26
 
31
- it "returns a cloned query" do
32
- expect(selection).to_not equal(query)
27
+ it 'returns a cloned query' do
28
+ expect(selection).not_to equal(query)
33
29
  end
34
30
  end
35
31
 
36
32
  it_behaves_like 'requires a non-nil argument'
37
33
 
38
- context "when provided a string" do
39
- # String criteria compile to $where, which requires the opt-in.
40
- config_override :allow_unsafe_query_operators, true
41
-
34
+ context 'when provided a string' do
42
35
  let(:selection) do
43
- query.where("this.value = 10")
36
+ query.where('this.value = 10')
44
37
  end
45
38
 
46
- it "adds the $where criterion" do
47
- expect(selection.selector).to eq({ "$where" => "this.value = 10" })
39
+ it 'adds the $where criterion' do
40
+ expect(selection.selector).to eq({ '$where' => 'this.value = 10' })
48
41
  end
49
42
 
50
- it "returns a cloned query" do
51
- expect(selection).to_not equal(query)
43
+ it 'returns a cloned query' do
44
+ expect(selection).not_to equal(query)
52
45
  end
53
46
 
54
47
  context 'when multiple calls with string argument are made' do
55
-
56
48
  let(:selection) do
57
- query.where("this.value = 10").where('foo.bar')
49
+ query.where('this.value = 10').where('foo.bar')
58
50
  end
59
51
 
60
52
  it 'combines conditions' do
61
53
  expect(selection.selector).to eq(
62
- "$where" => "this.value = 10", '$and' => [{'$where' => 'foo.bar'}],
54
+ '$where' => 'this.value = 10', '$and' => [ { '$where' => 'foo.bar' } ]
63
55
  )
64
56
  end
65
57
  end
66
58
 
67
59
  context 'when called with string argument and with hash argument' do
68
-
69
60
  let(:selection) do
70
- query.where("this.value = 10").where(foo: 'bar')
61
+ query.where('this.value = 10').where(foo: 'bar')
71
62
  end
72
63
 
73
64
  it 'combines conditions' do
74
65
  expect(selection.selector).to eq(
75
- "$where" => "this.value = 10", 'foo' => 'bar',
66
+ '$where' => 'this.value = 10', 'foo' => 'bar'
76
67
  )
77
68
  end
78
69
  end
79
70
 
80
71
  context 'when called with hash argument and with string argument' do
81
-
82
72
  let(:selection) do
83
- query.where(foo: 'bar').where("this.value = 10")
73
+ query.where(foo: 'bar').where('this.value = 10')
84
74
  end
85
75
 
86
76
  it 'combines conditions' do
87
77
  expect(selection.selector).to eq(
88
- 'foo' => 'bar', "$where" => "this.value = 10",
78
+ 'foo' => 'bar', '$where' => 'this.value = 10'
89
79
  )
90
80
  end
91
81
  end
@@ -93,46 +83,41 @@ describe Mongoid::Criteria::Queryable::Selectable do
93
83
  context 'when called with two hash arguments' do
94
84
  context 'when arguments use operators' do
95
85
  shared_examples 'combines conditions' do
96
-
97
86
  it 'combines conditions' do
98
87
  expect(selection.selector).to eq(
99
- 'foo' => {'$in' => [1]},
100
- '$and' => ['foo' => {'$in' => [2]}],
88
+ 'foo' => { '$in' => [ 1 ] },
89
+ '$and' => [ { 'foo' => { '$in' => [ 2 ] } } ]
101
90
  )
102
91
  end
103
92
  end
104
93
 
105
94
  context 'string operators' do
106
-
107
95
  let(:selection) do
108
- query.where(foo: {'$in' => [1]}).where(foo: {'$in' => [2]})
96
+ query.where(foo: { '$in' => [ 1 ] }).where(foo: { '$in' => [ 2 ] })
109
97
  end
110
98
 
111
99
  include_examples 'combines conditions'
112
100
  end
113
101
 
114
102
  context 'symbol operators' do
115
-
116
103
  let(:selection) do
117
- query.where(foo: {:$in => [1]}).where(foo: {:$in => [2]})
104
+ query.where(foo: { :$in => [ 1 ] }).where(foo: { :$in => [ 2 ] })
118
105
  end
119
106
 
120
107
  include_examples 'combines conditions'
121
108
  end
122
109
 
123
110
  context 'string and symbol operators' do
124
-
125
111
  let(:selection) do
126
- query.where(foo: {'$in' => [1]}).where(foo: {:$in => [2]})
112
+ query.where(foo: { '$in' => [ 1 ] }).where(foo: { :$in => [ 2 ] })
127
113
  end
128
114
 
129
115
  include_examples 'combines conditions'
130
116
  end
131
117
 
132
118
  context 'symbol and string operators' do
133
-
134
119
  let(:selection) do
135
- query.where(foo: {:$in => [1]}).where(foo: {'$in' => [2]})
120
+ query.where(foo: { :$in => [ 1 ] }).where(foo: { '$in' => [ 2 ] })
136
121
  end
137
122
 
138
123
  include_examples 'combines conditions'
@@ -141,26 +126,24 @@ describe Mongoid::Criteria::Queryable::Selectable do
141
126
  end
142
127
  end
143
128
 
144
- context "when provided a single criterion" do
145
-
146
- context "when the value needs no evolution" do
147
-
129
+ context 'when provided a single criterion' do
130
+ context 'when the value needs no evolution' do
148
131
  let(:selection) do
149
- query.where(name: "Syd")
132
+ query.where(name: 'Syd')
150
133
  end
151
134
 
152
- it "adds the criterion to the selection" do
153
- expect(selection.selector).to eq({ "name" => "Syd" })
135
+ it 'adds the criterion to the selection' do
136
+ expect(selection.selector).to eq({ 'name' => 'Syd' })
154
137
  end
155
138
  end
156
139
 
157
- context "when the value must be evolved" do
158
-
140
+ context 'when the value must be evolved' do
159
141
  before(:all) do
160
142
  class Document
161
143
  def id
162
144
  13
163
145
  end
146
+
164
147
  def self.evolve(object)
165
148
  object.id
166
149
  end
@@ -171,10 +154,9 @@ describe Mongoid::Criteria::Queryable::Selectable do
171
154
  Object.send(:remove_const, :Document)
172
155
  end
173
156
 
174
- context "when the key needs evolution" do
175
-
157
+ context 'when the key needs evolution' do
176
158
  let(:query) do
177
- Mongoid::Query.new({ "user" => "user_id" })
159
+ Mongoid::Query.new({ 'user' => 'user_id' })
178
160
  end
179
161
 
180
162
  let(:document) do
@@ -185,13 +167,12 @@ describe Mongoid::Criteria::Queryable::Selectable do
185
167
  query.where(user: document)
186
168
  end
187
169
 
188
- it "alters the key and value" do
189
- expect(selection.selector).to eq({ "user_id" => document.id })
170
+ it 'alters the key and value' do
171
+ expect(selection.selector).to eq({ 'user_id' => document.id })
190
172
  end
191
173
  end
192
174
 
193
175
  context 'when the field is a String and the value is a BSON::Regexp::Raw' do
194
-
195
176
  let(:raw_regexp) do
196
177
  BSON::Regexp::Raw.new('^Em')
197
178
  end
@@ -201,338 +182,314 @@ describe Mongoid::Criteria::Queryable::Selectable do
201
182
  end
202
183
 
203
184
  it 'does not convert the bson raw regexp object to a String' do
204
- expect(selection.selector).to eq({ "_id" => raw_regexp })
185
+ expect(selection.selector).to eq({ '_id' => raw_regexp })
205
186
  end
206
187
  end
207
188
  end
208
189
  end
209
190
 
210
- context "when provided complex criterion" do
211
-
212
- context "when performing an $all" do
213
-
214
- context "when performing a single query" do
215
-
191
+ context 'when provided complex criterion' do
192
+ context 'when performing an $all' do
193
+ context 'when performing a single query' do
216
194
  let(:selection) do
217
195
  query.where(:field.all => [ 1, 2 ])
218
196
  end
219
197
 
220
- it "adds the $all criterion" do
221
- expect(selection.selector).to eq({ "field" => { "$all" => [ 1, 2 ] }})
198
+ it 'adds the $all criterion' do
199
+ expect(selection.selector).to eq({ 'field' => { '$all' => [ 1, 2 ] } })
222
200
  end
223
201
 
224
- it "returns a cloned query" do
225
- expect(selection).to_not eq(query)
202
+ it 'returns a cloned query' do
203
+ expect(selection).not_to eq(query)
226
204
  end
227
205
  end
228
206
  end
229
207
 
230
- context "when performing an $elemMatch" do
231
-
232
- context "when the value is not complex" do
233
-
208
+ context 'when performing an $elemMatch' do
209
+ context 'when the value is not complex' do
234
210
  let(:selection) do
235
211
  query.where(:field.elem_match => { key: 1 })
236
212
  end
237
213
 
238
- it "adds the $elemMatch criterion" do
214
+ it 'adds the $elemMatch criterion' do
239
215
  expect(selection.selector).to eq(
240
- { "field" => { "$elemMatch" => { 'key' => 1 } }}
216
+ { 'field' => { '$elemMatch' => { 'key' => 1 } } }
241
217
  )
242
218
  end
243
219
 
244
- it "returns a cloned query" do
245
- expect(selection).to_not eq(query)
220
+ it 'returns a cloned query' do
221
+ expect(selection).not_to eq(query)
246
222
  end
247
223
  end
248
224
 
249
- context "when the value is complex" do
250
-
225
+ context 'when the value is complex' do
251
226
  let(:selection) do
252
227
  query.where(:field.elem_match => { :key.gt => 1 })
253
228
  end
254
229
 
255
- it "adds the $elemMatch criterion" do
230
+ it 'adds the $elemMatch criterion' do
256
231
  expect(selection.selector).to eq(
257
- { "field" => { "$elemMatch" => { "key" => { "$gt" => 1 }}}}
232
+ { 'field' => { '$elemMatch' => { 'key' => { '$gt' => 1 } } } }
258
233
  )
259
234
  end
260
235
 
261
- it "returns a cloned query" do
262
- expect(selection).to_not eq(query)
236
+ it 'returns a cloned query' do
237
+ expect(selection).not_to eq(query)
263
238
  end
264
239
  end
265
240
  end
266
241
 
267
- context "when performing an $exists" do
268
-
269
- context "when providing boolean values" do
270
-
242
+ context 'when performing an $exists' do
243
+ context 'when providing boolean values' do
271
244
  let(:selection) do
272
245
  query.where(:field.exists => true)
273
246
  end
274
247
 
275
- it "adds the $exists criterion" do
248
+ it 'adds the $exists criterion' do
276
249
  expect(selection.selector).to eq(
277
- { "field" => { "$exists" => true }}
250
+ { 'field' => { '$exists' => true } }
278
251
  )
279
252
  end
280
253
 
281
- it "returns a cloned query" do
282
- expect(selection).to_not eq(query)
254
+ it 'returns a cloned query' do
255
+ expect(selection).not_to eq(query)
283
256
  end
284
257
  end
285
258
 
286
- context "when providing string values" do
287
-
259
+ context 'when providing string values' do
288
260
  let(:selection) do
289
- query.where(:field.exists => "t")
261
+ query.where(:field.exists => 't')
290
262
  end
291
263
 
292
- it "adds the $exists criterion" do
264
+ it 'adds the $exists criterion' do
293
265
  expect(selection.selector).to eq(
294
- { "field" => { "$exists" => true }}
266
+ { 'field' => { '$exists' => true } }
295
267
  )
296
268
  end
297
269
 
298
- it "returns a cloned query" do
299
- expect(selection).to_not eq(query)
270
+ it 'returns a cloned query' do
271
+ expect(selection).not_to eq(query)
300
272
  end
301
273
  end
302
274
  end
303
275
 
304
- context "when performing a $gt" do
305
-
276
+ context 'when performing a $gt' do
306
277
  let(:selection) do
307
278
  query.where(:field.gt => 10)
308
279
  end
309
280
 
310
- it "adds the $gt criterion" do
281
+ it 'adds the $gt criterion' do
311
282
  expect(selection.selector).to eq(
312
- { "field" => { "$gt" => 10 }}
283
+ { 'field' => { '$gt' => 10 } }
313
284
  )
314
285
  end
315
286
 
316
- it "returns a cloned query" do
317
- expect(selection).to_not eq(query)
287
+ it 'returns a cloned query' do
288
+ expect(selection).not_to eq(query)
318
289
  end
319
290
  end
320
291
 
321
- context "when performing a $gte" do
322
-
292
+ context 'when performing a $gte' do
323
293
  let(:selection) do
324
294
  query.where(:field.gte => 10)
325
295
  end
326
296
 
327
- it "adds the $gte criterion" do
297
+ it 'adds the $gte criterion' do
328
298
  expect(selection.selector).to eq(
329
- { "field" => { "$gte" => 10 }}
299
+ { 'field' => { '$gte' => 10 } }
330
300
  )
331
301
  end
332
302
 
333
- it "returns a cloned query" do
334
- expect(selection).to_not eq(query)
303
+ it 'returns a cloned query' do
304
+ expect(selection).not_to eq(query)
335
305
  end
336
306
  end
337
307
 
338
- context "when performing an $in" do
339
-
308
+ context 'when performing an $in' do
340
309
  let(:selection) do
341
310
  query.where(:field.in => [ 1, 2 ])
342
311
  end
343
312
 
344
- it "adds the $in criterion" do
345
- expect(selection.selector).to eq({ "field" => { "$in" => [ 1, 2 ] }})
313
+ it 'adds the $in criterion' do
314
+ expect(selection.selector).to eq({ 'field' => { '$in' => [ 1, 2 ] } })
346
315
  end
347
316
 
348
- it "returns a cloned query" do
349
- expect(selection).to_not eq(query)
317
+ it 'returns a cloned query' do
318
+ expect(selection).not_to eq(query)
350
319
  end
351
320
  end
352
321
 
353
- context "when performing a $lt" do
354
-
322
+ context 'when performing a $lt' do
355
323
  let(:selection) do
356
324
  query.where(:field.lt => 10)
357
325
  end
358
326
 
359
- it "adds the $lt criterion" do
327
+ it 'adds the $lt criterion' do
360
328
  expect(selection.selector).to eq(
361
- { "field" => { "$lt" => 10 }}
329
+ { 'field' => { '$lt' => 10 } }
362
330
  )
363
331
  end
364
332
 
365
- it "returns a cloned query" do
366
- expect(selection).to_not eq(query)
333
+ it 'returns a cloned query' do
334
+ expect(selection).not_to eq(query)
367
335
  end
368
336
  end
369
337
 
370
- context "when performing a $lte" do
371
-
338
+ context 'when performing a $lte' do
372
339
  let(:selection) do
373
340
  query.where(:field.lte => 10)
374
341
  end
375
342
 
376
- it "adds the $lte criterion" do
343
+ it 'adds the $lte criterion' do
377
344
  expect(selection.selector).to eq(
378
- { "field" => { "$lte" => 10 }}
345
+ { 'field' => { '$lte' => 10 } }
379
346
  )
380
347
  end
381
348
 
382
- it "returns a cloned query" do
383
- expect(selection).to_not eq(query)
349
+ it 'returns a cloned query' do
350
+ expect(selection).not_to eq(query)
384
351
  end
385
352
  end
386
353
 
387
- context "when performing a $mod" do
388
-
354
+ context 'when performing a $mod' do
389
355
  let(:selection) do
390
356
  query.where(:field.mod => [ 10, 1 ])
391
357
  end
392
358
 
393
- it "adds the $lte criterion" do
359
+ it 'adds the $lte criterion' do
394
360
  expect(selection.selector).to eq(
395
- { "field" => { "$mod" => [ 10, 1 ]}}
361
+ { 'field' => { '$mod' => [ 10, 1 ] } }
396
362
  )
397
363
  end
398
364
 
399
- it "returns a cloned query" do
400
- expect(selection).to_not eq(query)
365
+ it 'returns a cloned query' do
366
+ expect(selection).not_to eq(query)
401
367
  end
402
368
  end
403
369
 
404
- context "when performing a $ne" do
405
-
370
+ context 'when performing a $ne' do
406
371
  let(:selection) do
407
372
  query.where(:field.ne => 10)
408
373
  end
409
374
 
410
- it "adds the $ne criterion" do
375
+ it 'adds the $ne criterion' do
411
376
  expect(selection.selector).to eq(
412
- { "field" => { "$ne" => 10 }}
377
+ { 'field' => { '$ne' => 10 } }
413
378
  )
414
379
  end
415
380
 
416
- it "returns a cloned query" do
417
- expect(selection).to_not eq(query)
381
+ it 'returns a cloned query' do
382
+ expect(selection).not_to eq(query)
418
383
  end
419
384
  end
420
385
 
421
- context "when performing a $near" do
422
-
386
+ context 'when performing a $near' do
423
387
  let(:selection) do
424
388
  query.where(:field.near => [ 1, 1 ])
425
389
  end
426
390
 
427
- it "adds the $near criterion" do
391
+ it 'adds the $near criterion' do
428
392
  expect(selection.selector).to eq(
429
- { "field" => { "$near" => [ 1, 1 ] }}
393
+ { 'field' => { '$near' => [ 1, 1 ] } }
430
394
  )
431
395
  end
432
396
 
433
- it "returns a cloned query" do
434
- expect(selection).to_not eq(query)
397
+ it 'returns a cloned query' do
398
+ expect(selection).not_to eq(query)
435
399
  end
436
400
  end
437
401
 
438
- context "when performing a $nearSphere" do
439
-
402
+ context 'when performing a $nearSphere' do
440
403
  let(:selection) do
441
404
  query.where(:field.near_sphere => [ 1, 1 ])
442
405
  end
443
406
 
444
- it "adds the $nearSphere criterion" do
407
+ it 'adds the $nearSphere criterion' do
445
408
  expect(selection.selector).to eq(
446
- { "field" => { "$nearSphere" => [ 1, 1 ] }}
409
+ { 'field' => { '$nearSphere' => [ 1, 1 ] } }
447
410
  )
448
411
  end
449
412
 
450
- it "returns a cloned query" do
451
- expect(selection).to_not eq(query)
413
+ it 'returns a cloned query' do
414
+ expect(selection).not_to eq(query)
452
415
  end
453
416
  end
454
417
 
455
- context "when performing a $nin" do
456
-
418
+ context 'when performing a $nin' do
457
419
  let(:selection) do
458
420
  query.where(:field.nin => [ 1, 2 ])
459
421
  end
460
422
 
461
- it "adds the $nin criterion" do
462
- expect(selection.selector).to eq({ "field" => { "$nin" => [ 1, 2 ] }})
423
+ it 'adds the $nin criterion' do
424
+ expect(selection.selector).to eq({ 'field' => { '$nin' => [ 1, 2 ] } })
463
425
  end
464
426
 
465
- it "returns a cloned query" do
466
- expect(selection).to_not eq(query)
427
+ it 'returns a cloned query' do
428
+ expect(selection).not_to eq(query)
467
429
  end
468
430
  end
469
431
 
470
- context "when performing a $not" do
471
-
432
+ context 'when performing a $not' do
472
433
  let(:selection) do
473
434
  query.where(:field.not => /test/)
474
435
  end
475
436
 
476
- it "adds the $not criterion" do
477
- expect(selection.selector).to eq({ "field" => { "$not" => /test/ }})
437
+ it 'adds the $not criterion' do
438
+ expect(selection.selector).to eq({ 'field' => { '$not' => /test/ } })
478
439
  end
479
440
 
480
- it "returns a cloned query" do
481
- expect(selection).to_not eq(query)
441
+ it 'returns a cloned query' do
442
+ expect(selection).not_to eq(query)
482
443
  end
483
444
  end
484
445
 
485
- context "when performing a $size" do
486
-
487
- context "when providing an integer" do
488
-
446
+ context 'when performing a $size' do
447
+ context 'when providing an integer' do
489
448
  let(:selection) do
490
449
  query.where(:field.with_size => 10)
491
450
  end
492
451
 
493
- it "adds the $size criterion" do
452
+ it 'adds the $size criterion' do
494
453
  expect(selection.selector).to eq(
495
- { "field" => { "$size" => 10 }}
454
+ { 'field' => { '$size' => 10 } }
496
455
  )
497
456
  end
498
457
 
499
- it "returns a cloned query" do
500
- expect(selection).to_not eq(query)
458
+ it 'returns a cloned query' do
459
+ expect(selection).not_to eq(query)
501
460
  end
502
461
  end
503
462
 
504
- context "when providing a string" do
505
-
463
+ context 'when providing a string' do
506
464
  let(:selection) do
507
- query.where(:field.with_size => "10")
465
+ query.where(:field.with_size => '10')
508
466
  end
509
467
 
510
- it "adds the $size criterion" do
468
+ it 'adds the $size criterion' do
511
469
  expect(selection.selector).to eq(
512
- { "field" => { "$size" => 10 }}
470
+ { 'field' => { '$size' => 10 } }
513
471
  )
514
472
  end
515
473
 
516
- it "returns a cloned query" do
517
- expect(selection).to_not eq(query)
474
+ it 'returns a cloned query' do
475
+ expect(selection).not_to eq(query)
518
476
  end
519
477
  end
520
478
  end
521
479
 
522
- context "when performing a $type" do
523
-
480
+ context 'when performing a $type' do
524
481
  let(:selection) do
525
482
  query.where(:field.with_type => 10)
526
483
  end
527
484
 
528
- it "adds the $type criterion" do
485
+ it 'adds the $type criterion' do
529
486
  expect(selection.selector).to eq(
530
- { "field" => { "$type" => 10 }}
487
+ { 'field' => { '$type' => 10 } }
531
488
  )
532
489
  end
533
490
 
534
- it "returns a cloned query" do
535
- expect(selection).to_not eq(query)
491
+ it 'returns a cloned query' do
492
+ expect(selection).not_to eq(query)
536
493
  end
537
494
  end
538
495
  end
@@ -543,24 +500,28 @@ describe Mongoid::Criteria::Queryable::Selectable do
543
500
  end
544
501
 
545
502
  let(:selection) do
546
- base_query.where(mql_operator => ['hello' => 'world'])
503
+ base_query.where(mql_operator => [ { 'hello' => 'world' } ])
547
504
  end
548
505
 
549
506
  shared_examples_for 'adds conditions to existing query' do
550
507
  it 'adds conditions to existing query' do
551
- selection.selector.should == {
552
- 'test' => 1,
553
- mql_operator => ['hello' => 'world'],
554
- }
508
+ selection.selector.should eq(
509
+ {
510
+ 'test' => 1,
511
+ mql_operator => [ { 'hello' => 'world' } ]
512
+ }
513
+ )
555
514
  end
556
515
  end
557
516
 
558
517
  shared_examples_for 'adds conditions to existing query with an extra $and' do
559
518
  it 'adds conditions to existing query' do
560
- selection.selector.should == {
561
- 'test' => 1,
562
- mql_operator => ['hello' => 'world'],
563
- }
519
+ selection.selector.should eq(
520
+ {
521
+ 'test' => 1,
522
+ mql_operator => [ { 'hello' => 'world' } ]
523
+ }
524
+ )
564
525
  end
565
526
  end
566
527
 
@@ -589,202 +550,4 @@ describe Mongoid::Criteria::Queryable::Selectable do
589
550
  end
590
551
  end
591
552
  end
592
-
593
- describe 'top-level operator injection guard' do
594
- context 'when allow_unsafe_query_operators is true' do
595
- config_override :allow_unsafe_query_operators, true
596
-
597
- context 'when passing $where' do
598
- it 'does not raise' do
599
- expect do
600
- query.where('$where' => 'this.name == "admin"')
601
- end.not_to raise_error
602
- end
603
- end
604
-
605
- context 'when passing a string criterion' do
606
- it 'does not raise' do
607
- expect do
608
- query.where('this.name == "admin"')
609
- end.not_to raise_error
610
- end
611
- end
612
-
613
- context 'when passing a string criterion to a negated query' do
614
- it 'does not raise' do
615
- expect do
616
- query.not.where('this.name == "admin"')
617
- end.not_to raise_error
618
- end
619
- end
620
-
621
- context 'when passing $function' do
622
- it 'does not raise' do
623
- expect do
624
- query.where('$function' => { body: 'function() { return true; }', args: [], lang: 'js' })
625
- end.not_to raise_error
626
- end
627
- end
628
- end
629
-
630
- context 'when allow_unsafe_query_operators is false' do
631
- config_override :allow_unsafe_query_operators, false
632
-
633
- context 'when passing $where' do
634
- it 'raises InvalidQuery' do
635
- expect do
636
- query.where('$where' => 'this.name == "admin"')
637
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
638
- end
639
- end
640
-
641
- context 'when passing $function' do
642
- it 'raises InvalidQuery' do
643
- expect do
644
- query.where('$function' => { body: 'function() { return true; }', args: [], lang: 'js' })
645
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$function/)
646
- end
647
- end
648
-
649
- context 'when the error mentions allow_unsafe_query_operators' do
650
- it 'includes the config opt-in in the message' do
651
- expect do
652
- query.where('$where' => 'true')
653
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
654
- end
655
- end
656
-
657
- context 'when passing a string criterion' do
658
- it 'raises InvalidQuery' do
659
- expect do
660
- query.where('this.name == "admin"')
661
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
662
- end
663
-
664
- it 'includes the config opt-in in the message' do
665
- expect do
666
- query.where('this.name == "admin"')
667
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
668
- end
669
- end
670
-
671
- context 'when passing a string criterion to a negated query' do
672
- it 'raises InvalidQuery' do
673
- expect do
674
- query.not.where('this.name == "admin"')
675
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
676
- end
677
- end
678
-
679
- %w[$and $or $nor $not $text $comment $expr $jsonSchema $alwaysFalse $alwaysTrue].each do |op|
680
- context "when passing #{op} (allowlisted)" do
681
- it 'does not raise' do
682
- value = case op
683
- when '$and', '$or', '$nor', '$not' then [ { 'x' => 1 } ]
684
- when '$text' then { '$search' => 'hi' }
685
- when '$expr' then { '$gt' => [ '$a', 1 ] }
686
- when '$jsonSchema' then { 'required' => [ 'x' ] }
687
- else true
688
- end
689
- expect { query.where(op => value) }.not_to raise_error
690
- end
691
- end
692
- end
693
- end
694
- end
695
-
696
- describe 'nested operator injection guard' do
697
- js = 'this.name == "admin"'
698
-
699
- function_expr = {
700
- '$function' => { 'body' => 'function() { return true; }', 'args' => [], 'lang' => 'js' }
701
- }.freeze
702
-
703
- accumulator_expr = {
704
- '$accumulator' => {
705
- 'init' => 'function() { return 0; }',
706
- 'accumulate' => 'function() { return 0; }',
707
- 'accumulateArgs' => [],
708
- 'merge' => 'function() { return 0; }',
709
- 'lang' => 'js'
710
- }
711
- }.freeze
712
-
713
- # Every path into the selector that does not route through #expr_query,
714
- # plus the nested forms that a top-level key check cannot see.
715
- unsafe_queries = {
716
- 'and with a $where key' => ->(query) { query.and('$where' => js) },
717
- 'or with a $where key' => ->(query) { query.or('$where' => js) },
718
- 'nor with a $where key' => ->(query) { query.nor('$where' => js) },
719
- 'not with a $where key' => ->(query) { query.not('$where' => js) },
720
- 'any_of with a $where key' => ->(query) { query.any_of('$where' => js) },
721
- 'none_of with a $where key' => ->(query) { query.none_of('$where' => js) },
722
- 'elem_match with a nested $where' => ->(query) { query.elem_match(a: { '$where' => js }) },
723
- 'where with $where inside $or' => ->(query) { query.where('$or' => [ { '$where' => js } ]) },
724
- 'where with $function inside $expr' => ->(query) { query.where('$expr' => function_expr) },
725
- 'where with $accumulator inside $expr' => ->(query) { query.where('$expr' => accumulator_expr) },
726
- 'where with $where three levels deep' => lambda { |query|
727
- query.where('$and' => [ { '$or' => [ { '$where' => js } ] } ])
728
- },
729
- 'where with a symbol $where key inside $or' => ->(query) { query.where('$or' => [ { :$where => js } ]) }
730
- }.freeze
731
-
732
- context 'when allow_unsafe_query_operators is false' do
733
- config_override :allow_unsafe_query_operators, false
734
-
735
- unsafe_queries.each do |description, builder|
736
- context "when querying with #{description}" do
737
- it 'raises InvalidQuery' do
738
- expect do
739
- builder.call(query)
740
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where|\$function|\$accumulator/)
741
- end
742
- end
743
- end
744
-
745
- it 'includes the config opt-in in the message' do
746
- expect do
747
- query.or('$where' => js)
748
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
749
- end
750
-
751
- context 'when the nested expression is safe' do
752
- it 'permits $or with field expressions' do
753
- expect do
754
- query.where('$or' => [ { 'a' => 1 }, { 'b' => { '$gt' => 2 } } ])
755
- end.not_to raise_error
756
- end
757
-
758
- it 'permits $expr with aggregation operators' do
759
- expect do
760
- query.where('$expr' => { '$gt' => [ '$a', '$b' ] })
761
- end.not_to raise_error
762
- end
763
-
764
- it 'permits a field whose name resembles a javascript operator' do
765
- expect do
766
- query.where('where' => js)
767
- end.not_to raise_error
768
- end
769
-
770
- it 'permits a value that resembles a javascript operator' do
771
- expect do
772
- query.where('name' => '$where')
773
- end.not_to raise_error
774
- end
775
- end
776
- end
777
-
778
- context 'when allow_unsafe_query_operators is true' do
779
- config_override :allow_unsafe_query_operators, true
780
-
781
- unsafe_queries.each do |description, builder|
782
- context "when querying with #{description}" do
783
- it 'does not raise' do
784
- expect { builder.call(query) }.not_to raise_error
785
- end
786
- end
787
- end
788
- end
789
- end
790
553
  end