mongoid 5.4.0 → 6.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +26 -0
  5. data/lib/config/locales/en.yml +40 -0
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic.rb +5 -5
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/attributes.rb +22 -21
  10. data/lib/mongoid/cacheable.rb +36 -0
  11. data/lib/mongoid/changeable.rb +36 -0
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/sessions.rb +113 -0
  14. data/lib/mongoid/clients/storage_options.rb +2 -69
  15. data/lib/mongoid/clients.rb +10 -63
  16. data/lib/mongoid/composable.rb +29 -2
  17. data/lib/mongoid/config.rb +1 -0
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  19. data/lib/mongoid/contextual/atomic.rb +4 -4
  20. data/lib/mongoid/contextual/map_reduce.rb +7 -3
  21. data/lib/mongoid/contextual/memory.rb +9 -4
  22. data/lib/mongoid/contextual/mongo.rb +65 -30
  23. data/lib/mongoid/contextual/none.rb +12 -0
  24. data/lib/mongoid/copyable.rb +13 -6
  25. data/lib/mongoid/criteria/marshalable.rb +2 -2
  26. data/lib/mongoid/criteria/modifiable.rb +29 -3
  27. data/lib/mongoid/criteria/options.rb +25 -0
  28. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  29. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  30. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  32. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  33. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  34. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  35. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  36. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  37. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  38. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  39. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
  40. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  41. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  42. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  43. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  44. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  45. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  46. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  47. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  48. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  49. data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
  50. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  51. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  52. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  53. data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
  54. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  55. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  56. data/lib/mongoid/criteria/queryable.rb +87 -0
  57. data/lib/mongoid/criteria.rb +6 -2
  58. data/lib/mongoid/document.rb +34 -41
  59. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  60. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  61. data/lib/mongoid/errors/invalid_field.rb +2 -2
  62. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  63. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  64. data/lib/mongoid/errors/invalid_session_use.rb +24 -0
  65. data/lib/mongoid/errors.rb +3 -0
  66. data/lib/mongoid/evolvable.rb +1 -1
  67. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  68. data/lib/mongoid/extensions/date.rb +4 -1
  69. data/lib/mongoid/extensions/decimal128.rb +3 -3
  70. data/lib/mongoid/extensions/hash.rb +1 -0
  71. data/lib/mongoid/extensions/regexp.rb +1 -0
  72. data/lib/mongoid/extensions/string.rb +6 -3
  73. data/lib/mongoid/extensions/time.rb +4 -1
  74. data/lib/mongoid/extensions.rb +0 -4
  75. data/lib/mongoid/factory.rb +2 -1
  76. data/lib/mongoid/fields/validators/macro.rb +18 -0
  77. data/lib/mongoid/findable.rb +2 -2
  78. data/lib/mongoid/indexable.rb +16 -14
  79. data/lib/mongoid/interceptable.rb +9 -22
  80. data/lib/mongoid/matchable/all.rb +2 -2
  81. data/lib/mongoid/matchable/and.rb +3 -3
  82. data/lib/mongoid/matchable/default.rb +2 -2
  83. data/lib/mongoid/matchable/elem_match.rb +28 -0
  84. data/lib/mongoid/matchable/exists.rb +2 -2
  85. data/lib/mongoid/matchable/gt.rb +4 -2
  86. data/lib/mongoid/matchable/gte.rb +4 -2
  87. data/lib/mongoid/matchable/in.rb +2 -2
  88. data/lib/mongoid/matchable/lt.rb +4 -2
  89. data/lib/mongoid/matchable/lte.rb +4 -2
  90. data/lib/mongoid/matchable/ne.rb +2 -2
  91. data/lib/mongoid/matchable/nin.rb +2 -2
  92. data/lib/mongoid/matchable/nor.rb +37 -0
  93. data/lib/mongoid/matchable/or.rb +3 -3
  94. data/lib/mongoid/matchable/regexp.rb +3 -3
  95. data/lib/mongoid/matchable/size.rb +2 -2
  96. data/lib/mongoid/matchable.rb +16 -7
  97. data/lib/mongoid/persistable/creatable.rb +5 -3
  98. data/lib/mongoid/persistable/deletable.rb +5 -3
  99. data/lib/mongoid/persistable/destroyable.rb +1 -5
  100. data/lib/mongoid/persistable/settable.rb +5 -5
  101. data/lib/mongoid/persistable/updatable.rb +7 -14
  102. data/lib/mongoid/persistable/upsertable.rb +2 -1
  103. data/lib/mongoid/persistable.rb +4 -6
  104. data/lib/mongoid/persistence_context.rb +220 -0
  105. data/lib/mongoid/query_cache.rb +67 -23
  106. data/lib/mongoid/railtie.rb +17 -1
  107. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  108. data/lib/mongoid/relations/accessors.rb +3 -0
  109. data/lib/mongoid/relations/auto_save.rb +12 -4
  110. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  111. data/lib/mongoid/relations/counter_cache.rb +15 -5
  112. data/lib/mongoid/relations/eager/base.rb +3 -3
  113. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  114. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  115. data/lib/mongoid/relations/eager.rb +6 -11
  116. data/lib/mongoid/relations/embedded/batchable.rb +20 -18
  117. data/lib/mongoid/relations/embedded/in.rb +13 -1
  118. data/lib/mongoid/relations/embedded/many.rb +51 -10
  119. data/lib/mongoid/relations/embedded/one.rb +14 -1
  120. data/lib/mongoid/relations/macros.rb +9 -1
  121. data/lib/mongoid/relations/many.rb +4 -0
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/options.rb +2 -2
  124. data/lib/mongoid/relations/proxy.rb +1 -31
  125. data/lib/mongoid/relations/referenced/in.rb +19 -10
  126. data/lib/mongoid/relations/referenced/many.rb +30 -26
  127. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  128. data/lib/mongoid/relations/referenced/one.rb +15 -1
  129. data/lib/mongoid/relations/synchronization.rb +12 -12
  130. data/lib/mongoid/relations/targets/enumerable.rb +24 -4
  131. data/lib/mongoid/relations/touchable.rb +7 -4
  132. data/lib/mongoid/reloadable.rb +2 -2
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +1 -1
  135. data/lib/mongoid/stateful.rb +1 -0
  136. data/lib/mongoid/tasks/database.rb +3 -2
  137. data/lib/mongoid/threaded.rb +74 -0
  138. data/lib/mongoid/traversable.rb +1 -1
  139. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  140. data/lib/mongoid/version.rb +1 -1
  141. data/lib/mongoid.rb +6 -6
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
  143. data/spec/app/models/agent.rb +2 -0
  144. data/spec/app/models/album.rb +5 -1
  145. data/spec/app/models/array_field.rb +7 -0
  146. data/spec/app/models/artist.rb +21 -0
  147. data/spec/app/models/band.rb +3 -0
  148. data/spec/app/models/book.rb +2 -1
  149. data/spec/app/models/delegating_patient.rb +16 -0
  150. data/spec/app/models/dokument.rb +1 -0
  151. data/spec/app/models/ordered_post.rb +5 -0
  152. data/spec/app/models/oscar.rb +1 -2
  153. data/spec/app/models/page.rb +1 -1
  154. data/spec/app/models/person.rb +3 -3
  155. data/spec/app/models/princess.rb +2 -0
  156. data/spec/app/models/record.rb +1 -0
  157. data/spec/app/models/subscription.rb +1 -0
  158. data/spec/app/models/thing.rb +1 -1
  159. data/spec/config/mongoid.yml +15 -0
  160. data/spec/integration/document_spec.rb +22 -0
  161. data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
  162. data/spec/mongoid/atomic_spec.rb +5 -5
  163. data/spec/mongoid/attributes/nested_spec.rb +18 -14
  164. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  165. data/spec/mongoid/attributes_spec.rb +90 -5
  166. data/spec/mongoid/cacheable_spec.rb +112 -0
  167. data/spec/mongoid/changeable_spec.rb +58 -0
  168. data/spec/mongoid/clients/factory_spec.rb +80 -28
  169. data/spec/mongoid/clients/options_spec.rb +396 -95
  170. data/spec/mongoid/clients/sessions_spec.rb +334 -0
  171. data/spec/mongoid/clients_spec.rb +243 -101
  172. data/spec/mongoid/composable_spec.rb +7 -0
  173. data/spec/mongoid/config_spec.rb +67 -11
  174. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  175. data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
  176. data/spec/mongoid/contextual/mongo_spec.rb +275 -22
  177. data/spec/mongoid/contextual/none_spec.rb +15 -0
  178. data/spec/mongoid/copyable_spec.rb +13 -4
  179. data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
  180. data/spec/mongoid/criteria/options_spec.rb +29 -0
  181. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  182. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  183. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  184. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  185. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  186. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  187. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  189. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  190. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  191. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  192. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  193. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  194. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  195. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  196. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  197. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  198. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  199. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  200. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  201. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  202. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  203. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  204. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  205. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  206. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  207. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  208. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  209. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
  210. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  211. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  212. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  213. data/spec/mongoid/criteria_spec.rb +156 -22
  214. data/spec/mongoid/document_spec.rb +100 -90
  215. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  216. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  217. data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
  218. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  219. data/spec/mongoid/extensions/date_spec.rb +2 -6
  220. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  221. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  222. data/spec/mongoid/extensions/float_spec.rb +8 -1
  223. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  224. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  225. data/spec/mongoid/extensions/object_spec.rb +11 -0
  226. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  227. data/spec/mongoid/extensions/string_spec.rb +53 -4
  228. data/spec/mongoid/extensions/time_spec.rb +2 -6
  229. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  230. data/spec/mongoid/factory_spec.rb +11 -0
  231. data/spec/mongoid/fields_spec.rb +1 -1
  232. data/spec/mongoid/findable_spec.rb +47 -2
  233. data/spec/mongoid/indexable_spec.rb +15 -3
  234. data/spec/mongoid/interceptable_spec.rb +85 -19
  235. data/spec/mongoid/matchable/all_spec.rb +4 -4
  236. data/spec/mongoid/matchable/and_spec.rb +10 -10
  237. data/spec/mongoid/matchable/default_spec.rb +12 -12
  238. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  239. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  240. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  241. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  242. data/spec/mongoid/matchable/in_spec.rb +5 -5
  243. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  244. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  245. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  246. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  247. data/spec/mongoid/matchable/nor_spec.rb +209 -0
  248. data/spec/mongoid/matchable/or_spec.rb +7 -7
  249. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  250. data/spec/mongoid/matchable/size_spec.rb +3 -3
  251. data/spec/mongoid/matchable_spec.rb +199 -54
  252. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  253. data/spec/mongoid/persistable/deletable_spec.rb +35 -1
  254. data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
  255. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  256. data/spec/mongoid/persistable/savable_spec.rb +34 -29
  257. data/spec/mongoid/persistable/settable_spec.rb +77 -27
  258. data/spec/mongoid/persistable/updatable_spec.rb +182 -3
  259. data/spec/mongoid/persistable_spec.rb +16 -16
  260. data/spec/mongoid/persistence_context_spec.rb +694 -0
  261. data/spec/mongoid/positional_spec.rb +1 -1
  262. data/spec/mongoid/query_cache_spec.rb +170 -12
  263. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  264. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  265. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  266. data/spec/mongoid/relations/builders_spec.rb +37 -10
  267. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  268. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  269. data/spec/mongoid/relations/eager_spec.rb +40 -0
  270. data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
  271. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  272. data/spec/mongoid/relations/macros_spec.rb +415 -7
  273. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  274. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  275. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  276. data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
  277. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  278. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  279. data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
  280. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  281. data/spec/mongoid/reloadable_spec.rb +51 -0
  282. data/spec/mongoid/scopable_spec.rb +13 -0
  283. data/spec/mongoid/serializable_spec.rb +0 -50
  284. data/spec/mongoid/threaded_spec.rb +68 -0
  285. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  286. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  287. data/spec/mongoid/validatable_spec.rb +16 -0
  288. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  289. data/spec/spec_helper.rb +101 -8
  290. data/spec/support/cluster_config.rb +158 -0
  291. data/spec/support/constraints.rb +101 -0
  292. data/spec/support/macros.rb +20 -0
  293. data/spec/support/session_registry.rb +50 -0
  294. data/spec/support/spec_config.rb +42 -0
  295. data.tar.gz.sig +0 -0
  296. metadata +163 -61
  297. metadata.gz.sig +0 -0
  298. data/lib/mongoid/clients/thread_options.rb +0 -19
  299. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  300. data/lib/mongoid/railties/document.rb +0 -12
  301. data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Queryable::Smash do
4
+
5
+ let(:smash) do
6
+ described_class.new(ns: :namespace)
7
+ end
8
+
9
+ describe "#[]" do
10
+
11
+ before do
12
+ smash.store(:namespace, :default)
13
+ smash.store(:some_field, 42)
14
+ end
15
+
16
+ context "when accessing aliased field" do
17
+
18
+ it "returns value for original field" do
19
+ expect(smash[:ns]).to eq(:default)
20
+ end
21
+ end
22
+
23
+ context "when accessing non-aliased field" do
24
+
25
+ it "returns value for the field" do
26
+ expect(smash[:some_field]).to eq(42)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -388,4 +388,85 @@ describe Mongoid::Criteria::Scopable do
388
388
  end
389
389
  end
390
390
  end
391
+
392
+ describe 'scope and where' do
393
+ class ScopeWhereModel
394
+ include Mongoid::Document
395
+
396
+ scope :foo, -> { where(foo: true) }
397
+ end
398
+
399
+ shared_examples_for 'restricts to both' do
400
+ it 'restricts to both' do
401
+ expect(result.selector['foo']).to eq(true)
402
+ expect(result.selector['hello']).to eq('world')
403
+ end
404
+ end
405
+
406
+ context 'scope is given first' do
407
+ let(:result) { ScopeWhereModel.foo.where(hello: 'world') }
408
+
409
+ it_behaves_like 'restricts to both'
410
+ end
411
+
412
+ context 'where is given first' do
413
+ let(:result) { ScopeWhereModel.where(hello: 'world').foo }
414
+
415
+ it_behaves_like 'restricts to both'
416
+ end
417
+ end
418
+
419
+ describe 'scope with argument and where' do
420
+ class ArgumentScopeWhereModel
421
+ include Mongoid::Document
422
+
423
+ scope :my_text_search, ->(search) { where('$text' => {'$search' => search}) }
424
+ end
425
+
426
+ shared_examples_for 'restricts to both' do
427
+ it 'restricts to both' do
428
+ expect(result.selector['$text']).to eq({'$search' => 'bar'})
429
+ expect(result.selector['hello']).to eq('world')
430
+ end
431
+ end
432
+
433
+ context 'scope is given first' do
434
+ let(:result) { ArgumentScopeWhereModel.my_text_search('bar').where(hello: 'world') }
435
+
436
+ it_behaves_like 'restricts to both'
437
+ end
438
+
439
+ context 'where is given first' do
440
+ let(:result) { ArgumentScopeWhereModel.where(hello: 'world').my_text_search('bar') }
441
+
442
+ it_behaves_like 'restricts to both'
443
+ end
444
+ end
445
+
446
+ describe 'built in text search scope and where' do
447
+ class TextSearchScopeWhereModel
448
+ include Mongoid::Document
449
+
450
+ # using the default text_search scope
451
+ end
452
+
453
+ shared_examples_for 'restricts to both' do
454
+ it 'restricts to both' do
455
+ expect(result.selector['$text']).to eq({'$search' => 'bar'})
456
+ expect(result.selector['hello']).to eq('world')
457
+ end
458
+ end
459
+
460
+ context 'scope is given first' do
461
+ let(:result) { TextSearchScopeWhereModel.text_search('bar').where(hello: 'world') }
462
+
463
+ it_behaves_like 'restricts to both'
464
+ end
465
+
466
+ context 'where is given first' do
467
+ let(:result) { TextSearchScopeWhereModel.where(hello: 'world').text_search('bar') }
468
+
469
+ it_behaves_like 'restricts to both'
470
+ end
471
+ end
391
472
  end
@@ -412,7 +412,7 @@ describe Mongoid::Criteria do
412
412
  end
413
413
 
414
414
  let(:criteria) do
415
- Band.where(name: "Depeche Mode").asc(:name).includes(:records)
415
+ Band.where(name: "Depeche Mode").asc(:name).includes(:records).read(mode: :secondary)
416
416
  end
417
417
 
418
418
  before do
@@ -433,7 +433,7 @@ describe Mongoid::Criteria do
433
433
  end
434
434
 
435
435
  it "contains equal options" do
436
- expect(clone.options).to eq({ sort: { "name" => 1 }})
436
+ expect(clone.options).to eq({ sort: { "name" => 1 }, read: { mode: :secondary } })
437
437
  end
438
438
 
439
439
  it "clones the options" do
@@ -467,6 +467,10 @@ describe Mongoid::Criteria do
467
467
  it "sets the context to nil" do
468
468
  expect(clone.instance_variable_get(:@context)).to be_nil
469
469
  end
470
+
471
+ it 'does not convert the option keys to string from symbols' do
472
+ expect(clone.options[:read][:mode]).to eq(:secondary)
473
+ end
470
474
  end
471
475
  end
472
476
 
@@ -590,7 +594,8 @@ describe Mongoid::Criteria do
590
594
 
591
595
  let!(:match) do
592
596
  Band.create(name: "Depeche Mode").tap do |band|
593
- band.records.create(name: "101")
597
+ r = band.records
598
+ r.create(name: "101")
594
599
  end
595
600
  end
596
601
 
@@ -970,6 +975,7 @@ describe Mongoid::Criteria do
970
975
  end
971
976
 
972
977
  describe "#geo_near" do
978
+ max_server_version '4.0'
973
979
 
974
980
  before do
975
981
  Bar.create_indexes
@@ -2803,6 +2809,93 @@ describe Mongoid::Criteria do
2803
2809
  end
2804
2810
  end
2805
2811
  end
2812
+
2813
+ context 'when the field is localized' do
2814
+
2815
+ before do
2816
+ I18n.locale = :en
2817
+ d = Dictionary.create(description: 'english-text')
2818
+ I18n.locale = :de
2819
+ d.description = 'deutsch-text'
2820
+ d.save
2821
+ end
2822
+
2823
+ after do
2824
+ I18n.locale = :en
2825
+ end
2826
+
2827
+ context 'when entire field is included' do
2828
+
2829
+ let(:dictionary) do
2830
+ Dictionary.only(:description).first
2831
+
2832
+ end
2833
+
2834
+ it 'loads all translations' do
2835
+ expect(dictionary.description_translations.keys).to include('de', 'en')
2836
+ end
2837
+
2838
+ it 'returns the field value for the current locale' do
2839
+ I18n.locale = :en
2840
+ expect(dictionary.description).to eq('english-text')
2841
+ I18n.locale = :de
2842
+ expect(dictionary.description).to eq('deutsch-text')
2843
+ end
2844
+ end
2845
+
2846
+ context 'when a specific locale is included' do
2847
+
2848
+ let(:dictionary) do
2849
+ Dictionary.only(:'description.de').first
2850
+ end
2851
+
2852
+ it 'loads translations only for the included locale' do
2853
+ expect(dictionary.description_translations.keys).to include('de')
2854
+ expect(dictionary.description_translations.keys).to_not include('en')
2855
+ end
2856
+
2857
+ it 'returns the field value for the included locale' do
2858
+ I18n.locale = :en
2859
+ expect(dictionary.description).to be_nil
2860
+ I18n.locale = :de
2861
+ expect(dictionary.description).to eq('deutsch-text')
2862
+ end
2863
+ end
2864
+
2865
+ context 'when entire field is excluded' do
2866
+
2867
+ let(:dictionary) do
2868
+ Dictionary.without(:description).first
2869
+ end
2870
+
2871
+ it 'does not load all translations' do
2872
+ expect(dictionary.description_translations.keys).to_not include('de', 'en')
2873
+ end
2874
+
2875
+ it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
2876
+ expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
2877
+ end
2878
+ end
2879
+
2880
+ context 'when a specific locale is excluded' do
2881
+
2882
+ let(:dictionary) do
2883
+ Dictionary.without(:'description.de').first
2884
+ end
2885
+
2886
+ it 'does not load excluded translations' do
2887
+ expect(dictionary.description_translations.keys).to_not include('de')
2888
+ expect(dictionary.description_translations.keys).to include('en')
2889
+ end
2890
+
2891
+ it 'returns nil for excluded translations' do
2892
+ I18n.locale = :en
2893
+ expect(dictionary.description).to eq('english-text')
2894
+ I18n.locale = :de
2895
+ expect(dictionary.description).to be_nil
2896
+ end
2897
+ end
2898
+ end
2806
2899
  end
2807
2900
 
2808
2901
  [ :or, :any_of ].each do |method|
@@ -2890,7 +2983,7 @@ describe Mongoid::Criteria do
2890
2983
  end
2891
2984
 
2892
2985
  it "returns the values" do
2893
- expect(plucked).to eq([ "Depeche Mode", "Tool", "Photek" ])
2986
+ expect(plucked).to contain_exactly("Depeche Mode", "Tool", "Photek")
2894
2987
  end
2895
2988
 
2896
2989
  context "when subsequently executing the criteria without a pluck" do
@@ -2955,14 +3048,14 @@ describe Mongoid::Criteria do
2955
3048
  end
2956
3049
  end
2957
3050
 
2958
- context "when plucking mult-fields" do
3051
+ context "when plucking multi-fields" do
2959
3052
 
2960
3053
  let(:plucked) do
2961
3054
  Band.where(:name.exists => true).pluck(:name, :likes)
2962
3055
  end
2963
3056
 
2964
3057
  it "returns the values" do
2965
- expect(plucked).to eq([ ["Depeche Mode", 3], ["Tool", 3], ["Photek", 1] ])
3058
+ expect(plucked).to contain_exactly(["Depeche Mode", 3], ["Tool", 3], ["Photek", 1])
2966
3059
  end
2967
3060
  end
2968
3061
 
@@ -2973,7 +3066,7 @@ describe Mongoid::Criteria do
2973
3066
  end
2974
3067
 
2975
3068
  it "returns the duplicates" do
2976
- expect(plucked).to eq([ 3, 3, 1 ])
3069
+ expect(plucked).to contain_exactly(3, 3, 1)
2977
3070
  end
2978
3071
  end
2979
3072
  end
@@ -3035,6 +3128,43 @@ describe Mongoid::Criteria do
3035
3128
  end
3036
3129
  end
3037
3130
  end
3131
+
3132
+ context 'when plucking a localized field' do
3133
+
3134
+ before do
3135
+ I18n.locale = :en
3136
+ d = Dictionary.create(description: 'english-text')
3137
+ I18n.locale = :de
3138
+ d.description = 'deutsch-text'
3139
+ d.save
3140
+ end
3141
+
3142
+ after do
3143
+ I18n.locale = :en
3144
+ end
3145
+
3146
+ context 'when plucking the entire field' do
3147
+
3148
+ let(:plucked) do
3149
+ Dictionary.all.pluck(:description)
3150
+ end
3151
+
3152
+ it 'returns all translations' do
3153
+ expect(plucked.first).to eq({'en' => 'english-text', 'de' => 'deutsch-text'})
3154
+ end
3155
+ end
3156
+
3157
+ context 'when plucking a specific locale' do
3158
+
3159
+ let(:plucked) do
3160
+ Dictionary.all.pluck(:'description.de')
3161
+ end
3162
+
3163
+ it 'returns the specific translations' do
3164
+ expect(plucked.first).to eq({'de' => 'deutsch-text'})
3165
+ end
3166
+ end
3167
+ end
3038
3168
  end
3039
3169
 
3040
3170
  describe "#respond_to?" do
@@ -3192,6 +3322,8 @@ describe Mongoid::Criteria do
3192
3322
  end
3193
3323
 
3194
3324
  describe "#max_scan" do
3325
+ max_server_version '4.0'
3326
+
3195
3327
  let!(:band) do
3196
3328
  Band.create(name: "Depeche Mode")
3197
3329
  end
@@ -3314,17 +3446,6 @@ describe Mongoid::Criteria do
3314
3446
  end
3315
3447
  end
3316
3448
 
3317
- context 'when the criteria contains a BSON::Regexp::Raw' do
3318
-
3319
- let(:criteria) do
3320
- Band.where(name: BSON::Regexp::Raw.new("^Depeche"))
3321
- end
3322
-
3323
- it "returns the matching documents" do
3324
- expect(criteria).to eq([ match ])
3325
- end
3326
- end
3327
-
3328
3449
  context "when the criteria is an exact fk array match" do
3329
3450
 
3330
3451
  let(:id_one) do
@@ -3347,7 +3468,7 @@ describe Mongoid::Criteria do
3347
3468
  context "when querying on a big decimal" do
3348
3469
 
3349
3470
  let(:sales) do
3350
- BigDecimal.new('0.1')
3471
+ BigDecimal('0.1')
3351
3472
  end
3352
3473
 
3353
3474
  let!(:band) do
@@ -3502,8 +3623,21 @@ describe Mongoid::Criteria do
3502
3623
 
3503
3624
  describe "#with" do
3504
3625
 
3505
- let!(:criteria) do
3506
- Band.where(name: "Depeche Mode").with(collection: "artists")
3626
+ let!(:criteria_and_collection) do
3627
+ collection = nil
3628
+ criteria = Band.where(name: "Depeche Mode").with(collection: "artists") do |crit|
3629
+ collection = crit.collection
3630
+ crit
3631
+ end
3632
+ [ criteria, collection ]
3633
+ end
3634
+
3635
+ let(:criteria) do
3636
+ criteria_and_collection[0]
3637
+ end
3638
+
3639
+ let(:collection) do
3640
+ criteria_and_collection[1]
3507
3641
  end
3508
3642
 
3509
3643
  it "retains the criteria selection" do
@@ -3511,7 +3645,7 @@ describe Mongoid::Criteria do
3511
3645
  end
3512
3646
 
3513
3647
  it "sets the persistence options" do
3514
- expect(criteria.persistence_options).to eq(collection: "artists")
3648
+ expect(collection.name).to eq("artists")
3515
3649
  end
3516
3650
  end
3517
3651
 
@@ -10,10 +10,17 @@ describe Mongoid::Document do
10
10
  Person.new
11
11
  end
12
12
 
13
- it "does not respond to _destroy" do
14
- expect(person).to_not respond_to(:_destroy)
13
+ it "defines a _destroy method" do
14
+ expect(Person.new).to respond_to(:_destroy)
15
15
  end
16
16
 
17
+ describe "#_destroy" do
18
+
19
+ it "default to false" do
20
+ expect(Person.new._destroy).to be false
21
+ end
22
+ end
23
+
17
24
  describe ".included" do
18
25
 
19
26
  let(:models) do
@@ -122,75 +129,6 @@ describe Mongoid::Document do
122
129
  end
123
130
  end
124
131
 
125
- describe "#cache_key" do
126
-
127
- let(:document) do
128
- Dokument.new
129
- end
130
-
131
- context "when the document is new" do
132
-
133
- it "has a new key name" do
134
- expect(document.cache_key).to eq("dokuments/new")
135
- end
136
- end
137
-
138
- context "when persisted" do
139
-
140
- before do
141
- document.save
142
- end
143
-
144
- context "with updated_at" do
145
-
146
- let!(:updated_at) do
147
- document.updated_at.utc.to_s(:nsec)
148
- end
149
-
150
- it "has the id and updated_at key name" do
151
- expect(document.cache_key).to eq("dokuments/#{document.id}-#{updated_at}")
152
- end
153
- end
154
-
155
- context "without updated_at, with Timestamps" do
156
-
157
- before do
158
- document.updated_at = nil
159
- end
160
-
161
- it "has the id key name" do
162
- expect(document.cache_key).to eq("dokuments/#{document.id}")
163
- end
164
- end
165
- end
166
-
167
- context "when model dont have Timestamps" do
168
-
169
- let(:artist) do
170
- Artist.create!
171
- end
172
-
173
- it "should have the id key name" do
174
- expect(artist.cache_key).to eq("artists/#{artist.id}")
175
- end
176
- end
177
-
178
- context "when model has Short Timestamps" do
179
-
180
- let(:agent) do
181
- ShortAgent.create!
182
- end
183
-
184
- let!(:updated_at) do
185
- agent.updated_at.utc.to_s(:nsec)
186
- end
187
-
188
- it "has the id and updated_at key name" do
189
- expect(agent.cache_key).to eq("short_agents/#{agent.id}-#{updated_at}")
190
- end
191
- end
192
- end
193
-
194
132
  describe "#identity" do
195
133
 
196
134
  let(:person) do
@@ -495,6 +433,60 @@ describe Mongoid::Document do
495
433
  end
496
434
  end
497
435
  end
436
+
437
+ context ':compact option' do
438
+
439
+ before do
440
+ # These tests require a specific set of defined attributes
441
+ # on the model
442
+ expect(church.as_json.keys.sort).to eq(%w(_id location name))
443
+ end
444
+
445
+ context 'there is a nil valued attribute' do
446
+ let(:church) do
447
+ Church.create!(name: 'St. Basil')
448
+ end
449
+
450
+ it 'returns non-nil fields and _id only' do
451
+ actual = church.as_json(compact: true)
452
+ expect(actual).to eq('_id' => church.id, 'name' => 'St. Basil')
453
+ end
454
+ end
455
+
456
+ context 'all attrbutes are nil valued' do
457
+ let(:church) do
458
+ Church.create!
459
+ end
460
+
461
+ it 'returns a hash with _id only' do
462
+ actual = church.as_json(compact: true)
463
+ expect(actual).to eq('_id' => church.id)
464
+ end
465
+ end
466
+
467
+ context 'there are no nil valued attributes' do
468
+ let(:church) do
469
+ Church.create!(name: 'St. Basil', location: {})
470
+ end
471
+
472
+ it 'returns all fields and _id' do
473
+ actual = church.as_json(compact: true)
474
+ expect(actual).to eq('_id' => church.id, 'name' => 'St. Basil',
475
+ 'location' => {})
476
+ end
477
+ end
478
+
479
+ context 'when option is specified as a truthy value' do
480
+ let(:church) do
481
+ Church.create!(name: 'St. Basil')
482
+ end
483
+
484
+ it 'returns non-nil fields and _id only' do
485
+ actual = church.as_json(compact: 1)
486
+ expect(actual).to eq('_id' => church.id, 'name' => 'St. Basil')
487
+ end
488
+ end
489
+ end
498
490
  end
499
491
 
500
492
  describe "#as_document" do
@@ -519,14 +511,26 @@ describe Mongoid::Document do
519
511
  expect(person.as_document).to have_key("name")
520
512
  end
521
513
 
514
+ it "includes embeds one attributes as a symbol" do
515
+ expect(person.as_document).to have_key(:name)
516
+ end
517
+
522
518
  it "includes embeds many attributes" do
523
519
  expect(person.as_document).to have_key("addresses")
524
520
  end
525
521
 
522
+ it "includes embeds many attributes as a symbol" do
523
+ expect(person.as_document).to have_key(:addresses)
524
+ end
525
+
526
526
  it "includes second level embeds many attributes" do
527
527
  expect(person.as_document["addresses"].first).to have_key("locations")
528
528
  end
529
529
 
530
+ it "includes second level embeds many attributes as a symbol" do
531
+ expect(person.as_document["addresses"].first).to have_key(:locations)
532
+ end
533
+
530
534
  context "with relation define store_as option in embeded_many" do
531
535
 
532
536
  let!(:phone) do
@@ -537,6 +541,10 @@ describe Mongoid::Document do
537
541
  expect(person.as_document).to have_key("mobile_phones")
538
542
  end
539
543
 
544
+ it 'includes the store_as key association as a symbol' do
545
+ expect(person.as_document).to have_key(:mobile_phones)
546
+ end
547
+
540
548
  it 'should not include the key of association' do
541
549
  expect(person.as_document).to_not have_key("phones")
542
550
  end
@@ -675,7 +683,7 @@ describe Mongoid::Document do
675
683
 
676
684
  it "freezes attributes" do
677
685
  expect(person.freeze).to eq(person)
678
- expect { person.title = "something" }.to raise_error
686
+ expect { person.title = "something" }.to raise_error(RuntimeError)
679
687
  end
680
688
  end
681
689
 
@@ -689,7 +697,7 @@ describe Mongoid::Document do
689
697
  person.freeze
690
698
  expect {
691
699
  person.title = "something"
692
- }.to raise_error
700
+ }.to raise_error(RuntimeError)
693
701
  end
694
702
  end
695
703
  end
@@ -1215,22 +1223,20 @@ describe Mongoid::Document do
1215
1223
 
1216
1224
  context "when marshalling the document" do
1217
1225
 
1218
- let(:person) do
1219
- Person.new.tap do |person|
1220
- person.addresses.extension
1221
- end
1226
+ let(:agency) do
1227
+ Agency.new
1222
1228
  end
1223
1229
 
1224
- let!(:account) do
1225
- person.create_account(name: "savings")
1230
+ let!(:agent) do
1231
+ agency.agents.build(title: "VIP")
1226
1232
  end
1227
1233
 
1228
1234
  describe Marshal, ".dump" do
1229
1235
 
1230
1236
  it "successfully dumps the document" do
1231
1237
  expect {
1232
- Marshal.dump(person)
1233
- Marshal.dump(account)
1238
+ Marshal.dump(agency)
1239
+ Marshal.dump(agent)
1234
1240
  }.not_to raise_error
1235
1241
  end
1236
1242
  end
@@ -1238,7 +1244,7 @@ describe Mongoid::Document do
1238
1244
  describe Marshal, ".load" do
1239
1245
 
1240
1246
  it "successfully loads the document" do
1241
- expect { Marshal.load(Marshal.dump(person)) }.not_to raise_error
1247
+ expect(Marshal.load(Marshal.dump(agency))).to eq(agency)
1242
1248
  end
1243
1249
  end
1244
1250
  end
@@ -1253,22 +1259,26 @@ describe Mongoid::Document do
1253
1259
 
1254
1260
  describe "#fetch" do
1255
1261
 
1256
- let!(:person) do
1257
- Person.new
1262
+ let(:agency) do
1263
+ Agency.new
1264
+ end
1265
+
1266
+ let(:agent) do
1267
+ agency.agents.build(title: "VIP", address: address)
1258
1268
  end
1259
1269
 
1260
- let!(:account) do
1261
- person.create_account(name: "savings")
1270
+ let(:address) do
1271
+ Address.new(city: 'Berlin')
1262
1272
  end
1263
1273
 
1264
1274
  it "stores the parent object" do
1265
- expect(cache.fetch("key") { person }).to eq(person)
1266
- expect(cache.fetch("key")).to eq(person)
1275
+ expect(cache.fetch("key") { agency }).to eq(agency)
1276
+ expect(cache.fetch("key")).to eq(agency)
1267
1277
  end
1268
1278
 
1269
1279
  it "stores the embedded object" do
1270
- expect(cache.fetch("key") { account }).to eq(account)
1271
- expect(cache.fetch("key")).to eq(account)
1280
+ expect(cache.fetch("key") { agent }).to eq(agent)
1281
+ expect(cache.fetch("key").address).to eq(agent.address)
1272
1282
  end
1273
1283
  end
1274
1284
  end