mongoid 5.4.1 → 6.0.0.beta

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 (264) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/config/locales/en.yml +23 -16
  5. data/lib/mongoid.rb +4 -9
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/modifiers.rb +8 -12
  8. data/lib/mongoid/attributes.rb +9 -11
  9. data/lib/mongoid/attributes/dynamic.rb +5 -6
  10. data/lib/mongoid/attributes/nested.rb +1 -1
  11. data/lib/mongoid/attributes/processing.rb +4 -0
  12. data/lib/mongoid/attributes/readonly.rb +22 -0
  13. data/lib/mongoid/cacheable.rb +36 -0
  14. data/lib/mongoid/changeable.rb +37 -1
  15. data/lib/mongoid/clients.rb +0 -63
  16. data/lib/mongoid/clients/factory.rb +0 -2
  17. data/lib/mongoid/clients/options.rb +54 -249
  18. data/lib/mongoid/clients/storage_options.rb +1 -69
  19. data/lib/mongoid/composable.rb +26 -2
  20. data/lib/mongoid/config.rb +1 -1
  21. data/lib/mongoid/config/options.rb +1 -1
  22. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -0
  23. data/lib/mongoid/contextual/atomic.rb +6 -9
  24. data/lib/mongoid/contextual/geo_near.rb +2 -3
  25. data/lib/mongoid/contextual/map_reduce.rb +97 -24
  26. data/lib/mongoid/contextual/memory.rb +7 -4
  27. data/lib/mongoid/contextual/mongo.rb +63 -54
  28. data/lib/mongoid/contextual/none.rb +2 -2
  29. data/lib/mongoid/copyable.rb +19 -19
  30. data/lib/mongoid/criteria.rb +5 -4
  31. data/lib/mongoid/criteria/findable.rb +2 -3
  32. data/lib/mongoid/criteria/includable.rb +63 -16
  33. data/lib/mongoid/criteria/marshalable.rb +2 -2
  34. data/lib/mongoid/criteria/modifiable.rb +17 -1
  35. data/lib/mongoid/criteria/options.rb +25 -0
  36. data/lib/mongoid/criteria/queryable.rb +86 -0
  37. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  38. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  39. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  40. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  41. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  42. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  43. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  44. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  45. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  47. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  48. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  49. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +45 -0
  50. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  51. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  52. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  53. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  54. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  55. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  56. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  57. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  58. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  59. data/lib/mongoid/criteria/queryable/optional.rb +411 -0
  60. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  61. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  62. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  63. data/lib/mongoid/criteria/queryable/selector.rb +196 -0
  64. data/lib/mongoid/criteria/queryable/smash.rb +103 -0
  65. data/lib/mongoid/document.rb +9 -23
  66. data/lib/mongoid/errors.rb +2 -1
  67. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  68. data/lib/mongoid/errors/delete_restriction.rb +2 -2
  69. data/lib/mongoid/errors/invalid_field.rb +2 -2
  70. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  71. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  72. data/lib/mongoid/errors/inverse_not_found.rb +1 -1
  73. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  74. data/lib/mongoid/evolvable.rb +1 -1
  75. data/lib/mongoid/extensions.rb +0 -5
  76. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  77. data/lib/mongoid/extensions/date.rb +4 -1
  78. data/lib/mongoid/extensions/hash.rb +2 -3
  79. data/lib/mongoid/extensions/object.rb +2 -2
  80. data/lib/mongoid/extensions/string.rb +4 -3
  81. data/lib/mongoid/extensions/time.rb +5 -2
  82. data/lib/mongoid/factory.rb +1 -0
  83. data/lib/mongoid/fields/foreign_key.rb +2 -2
  84. data/lib/mongoid/fields/localized.rb +3 -8
  85. data/lib/mongoid/fields/validators/macro.rb +18 -0
  86. data/lib/mongoid/findable.rb +3 -3
  87. data/lib/mongoid/indexable.rb +17 -16
  88. data/lib/mongoid/indexable/specification.rb +1 -1
  89. data/lib/mongoid/indexable/validators/options.rb +1 -2
  90. data/lib/mongoid/interceptable.rb +6 -17
  91. data/lib/mongoid/loggable.rb +1 -1
  92. data/lib/mongoid/matchable.rb +3 -10
  93. data/lib/mongoid/matchable/gt.rb +2 -0
  94. data/lib/mongoid/matchable/gte.rb +2 -0
  95. data/lib/mongoid/matchable/lt.rb +2 -0
  96. data/lib/mongoid/matchable/lte.rb +2 -0
  97. data/lib/mongoid/persistable.rb +6 -5
  98. data/lib/mongoid/persistable/creatable.rb +2 -0
  99. data/lib/mongoid/persistable/deletable.rb +7 -3
  100. data/lib/mongoid/persistable/settable.rb +3 -16
  101. data/lib/mongoid/persistable/updatable.rb +10 -12
  102. data/lib/mongoid/persistence_context.rb +216 -0
  103. data/lib/mongoid/query_cache.rb +5 -30
  104. data/lib/mongoid/relations/accessors.rb +6 -2
  105. data/lib/mongoid/relations/auto_save.rb +12 -4
  106. data/lib/mongoid/relations/bindings/embedded/in.rb +4 -0
  107. data/lib/mongoid/relations/bindings/embedded/many.rb +8 -1
  108. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -0
  109. data/lib/mongoid/relations/bindings/referenced/many.rb +4 -0
  110. data/lib/mongoid/relations/builders.rb +2 -2
  111. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  112. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  113. data/lib/mongoid/relations/conversions.rb +1 -1
  114. data/lib/mongoid/relations/counter_cache.rb +28 -18
  115. data/lib/mongoid/relations/eager.rb +19 -7
  116. data/lib/mongoid/relations/eager/base.rb +5 -5
  117. data/lib/mongoid/relations/embedded/batchable.rb +9 -33
  118. data/lib/mongoid/relations/embedded/in.rb +16 -2
  119. data/lib/mongoid/relations/embedded/many.rb +23 -8
  120. data/lib/mongoid/relations/embedded/one.rb +17 -2
  121. data/lib/mongoid/relations/macros.rb +9 -2
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/nested_builder.rb +1 -1
  124. data/lib/mongoid/relations/options.rb +2 -2
  125. data/lib/mongoid/relations/proxy.rb +2 -33
  126. data/lib/mongoid/relations/referenced/in.rb +23 -11
  127. data/lib/mongoid/relations/referenced/many.rb +24 -16
  128. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  129. data/lib/mongoid/relations/referenced/one.rb +17 -1
  130. data/lib/mongoid/relations/reflections.rb +3 -5
  131. data/lib/mongoid/relations/touchable.rb +1 -1
  132. data/lib/mongoid/reloadable.rb +1 -1
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +2 -3
  135. data/lib/mongoid/tasks/database.rb +1 -2
  136. data/lib/mongoid/threaded.rb +4 -4
  137. data/lib/mongoid/traversable.rb +1 -1
  138. data/lib/mongoid/validatable.rb +1 -1
  139. data/lib/mongoid/validatable/macros.rb +2 -4
  140. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  141. data/lib/mongoid/version.rb +1 -1
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -7
  143. data/spec/app/models/album.rb +5 -1
  144. data/spec/app/models/artist.rb +21 -0
  145. data/spec/app/models/band.rb +0 -1
  146. data/spec/app/models/church.rb +0 -2
  147. data/spec/app/models/ordered_post.rb +5 -0
  148. data/spec/app/models/oscar.rb +1 -2
  149. data/spec/app/models/person.rb +3 -1
  150. data/spec/app/models/post.rb +0 -1
  151. data/spec/app/models/princess.rb +2 -0
  152. data/spec/app/models/record.rb +1 -0
  153. data/spec/app/models/thing.rb +1 -1
  154. data/spec/config/mongoid.yml +1 -5
  155. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  156. data/spec/mongoid/atomic_spec.rb +17 -17
  157. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  158. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  159. data/spec/mongoid/attributes_spec.rb +63 -0
  160. data/spec/mongoid/cacheable_spec.rb +112 -0
  161. data/spec/mongoid/changeable_spec.rb +58 -0
  162. data/spec/mongoid/clients/factory_spec.rb +3 -11
  163. data/spec/mongoid/clients/options_spec.rb +378 -96
  164. data/spec/mongoid/clients_spec.rb +207 -170
  165. data/spec/mongoid/composable_spec.rb +7 -0
  166. data/spec/mongoid/config_spec.rb +41 -21
  167. data/spec/mongoid/contextual/atomic_spec.rb +77 -343
  168. data/spec/mongoid/contextual/map_reduce_spec.rb +119 -111
  169. data/spec/mongoid/contextual/memory_spec.rb +56 -316
  170. data/spec/mongoid/contextual/mongo_spec.rb +104 -378
  171. data/spec/mongoid/copyable_spec.rb +8 -15
  172. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  173. data/spec/mongoid/criteria/options_spec.rb +29 -0
  174. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  175. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  176. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  177. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  178. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  179. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  180. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  181. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  182. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  183. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  184. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  185. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  186. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  187. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  188. data/spec/mongoid/{extensions/origin/regexp_raw_spec.rb → criteria/queryable/extensions/regexp_spec.rb} +21 -20
  189. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  190. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  191. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  192. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  193. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  194. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  195. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  196. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  197. data/spec/mongoid/criteria/queryable/optional_spec.rb +1786 -0
  198. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  199. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  200. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  201. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4159 -0
  202. data/spec/mongoid/criteria/queryable/selector_spec.rb +778 -0
  203. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  204. data/spec/mongoid/criteria_spec.rb +45 -63
  205. data/spec/mongoid/document_spec.rb +21 -88
  206. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  207. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  208. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  209. data/spec/mongoid/extensions/date_spec.rb +2 -6
  210. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  211. data/spec/mongoid/extensions/float_spec.rb +8 -1
  212. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  213. data/spec/mongoid/extensions/object_spec.rb +11 -0
  214. data/spec/mongoid/extensions/string_spec.rb +21 -0
  215. data/spec/mongoid/extensions/time_spec.rb +4 -8
  216. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  217. data/spec/mongoid/fields/localized_spec.rb +0 -91
  218. data/spec/mongoid/findable_spec.rb +46 -1
  219. data/spec/mongoid/indexable_spec.rb +6 -46
  220. data/spec/mongoid/interceptable_spec.rb +49 -10
  221. data/spec/mongoid/matchable/gt_spec.rb +11 -0
  222. data/spec/mongoid/matchable/gte_spec.rb +10 -0
  223. data/spec/mongoid/matchable/lt_spec.rb +11 -0
  224. data/spec/mongoid/matchable/lte_spec.rb +11 -0
  225. data/spec/mongoid/matchable_spec.rb +1 -51
  226. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  227. data/spec/mongoid/persistable/deletable_spec.rb +1 -1
  228. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  229. data/spec/mongoid/persistable/savable_spec.rb +30 -30
  230. data/spec/mongoid/persistable/settable_spec.rb +0 -185
  231. data/spec/mongoid/persistable/updatable_spec.rb +166 -5
  232. data/spec/mongoid/persistence_context_spec.rb +654 -0
  233. data/spec/mongoid/positional_spec.rb +10 -10
  234. data/spec/mongoid/query_cache_spec.rb +89 -65
  235. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  236. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  237. data/spec/mongoid/relations/builders_spec.rb +37 -10
  238. data/spec/mongoid/relations/counter_cache_spec.rb +64 -15
  239. data/spec/mongoid/relations/cyclic_spec.rb +0 -22
  240. data/spec/mongoid/relations/embedded/many_spec.rb +9 -41
  241. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  242. data/spec/mongoid/relations/macros_spec.rb +395 -7
  243. data/spec/mongoid/relations/proxy_spec.rb +3 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +6 -29
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +6 -29
  247. data/spec/mongoid/relations/reflections_spec.rb +9 -9
  248. data/spec/mongoid/reloadable_spec.rb +51 -0
  249. data/spec/mongoid/scopable_spec.rb +0 -12
  250. data/spec/mongoid/serializable_spec.rb +0 -50
  251. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  252. data/spec/mongoid/validatable/uniqueness_spec.rb +16 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +10 -10
  255. metadata +536 -479
  256. metadata.gz.sig +0 -0
  257. data/lib/mongoid/clients/thread_options.rb +0 -19
  258. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +0 -20
  259. data/lib/mongoid/extensions/decimal128.rb +0 -39
  260. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  261. data/lib/mongoid/matchable/regexp.rb +0 -27
  262. data/spec/app/models/post_genre.rb +0 -6
  263. data/spec/mongoid/extensions/decimal128_spec.rb +0 -44
  264. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
@@ -0,0 +1,360 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Queryable::Options do
4
+
5
+ describe "#__deep_copy__" do
6
+
7
+ let(:sort) do
8
+ [[ :name, :asc ]]
9
+ end
10
+
11
+ let(:options) do
12
+ described_class.new
13
+ end
14
+
15
+ before do
16
+ options[:sort] = sort
17
+ end
18
+
19
+ let(:cloned) do
20
+ options.__deep_copy__
21
+ end
22
+
23
+ it "returns an equal copy" do
24
+ expect(cloned).to eq(options)
25
+ end
26
+
27
+ it "performs a deep copy" do
28
+ expect(cloned[:sort]).to_not equal(sort)
29
+ end
30
+ end
31
+
32
+ describe "#fields" do
33
+
34
+ let(:options) do
35
+ described_class.new
36
+ end
37
+
38
+ context "when field options exist" do
39
+
40
+ before do
41
+ options[:fields] = { name: 1 }
42
+ end
43
+
44
+ it "returns the field options" do
45
+ expect(options.fields).to eq({ "name" => 1 })
46
+ end
47
+ end
48
+
49
+ context "when field options do not exist" do
50
+
51
+ it "returns nil" do
52
+ expect(options.fields).to be_nil
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "#limit" do
58
+
59
+ let(:options) do
60
+ described_class.new
61
+ end
62
+
63
+ context "when limit options exist" do
64
+
65
+ before do
66
+ options[:limit] = 20
67
+ end
68
+
69
+ it "returns the limit options" do
70
+ expect(options.limit).to eq(20)
71
+ end
72
+ end
73
+
74
+ context "when limit options do not exist" do
75
+
76
+ it "returns nil" do
77
+ expect(options.limit).to be_nil
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "#skip" do
83
+
84
+ let(:options) do
85
+ described_class.new
86
+ end
87
+
88
+ context "when skip options exist" do
89
+
90
+ before do
91
+ options[:skip] = 100
92
+ end
93
+
94
+ it "returns the skip options" do
95
+ expect(options.skip).to eq(100)
96
+ end
97
+ end
98
+
99
+ context "when skip options do not exist" do
100
+
101
+ it "returns nil" do
102
+ expect(options.skip).to be_nil
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "#sort" do
108
+
109
+ let(:options) do
110
+ described_class.new
111
+ end
112
+
113
+ context "when sort options exist" do
114
+
115
+ before do
116
+ options[:sort] = { name: 1 }
117
+ end
118
+
119
+ it "returns the sort options" do
120
+ expect(options.sort).to eq({ "name" => 1 })
121
+ end
122
+ end
123
+
124
+ context "when sort options do not exist" do
125
+
126
+ it "returns nil" do
127
+ expect(options.sort).to be_nil
128
+ end
129
+ end
130
+ end
131
+
132
+ [ :store, :[]= ].each do |method|
133
+
134
+ describe "##{method}" do
135
+
136
+ context "when aliases are provided" do
137
+
138
+ context "when the alias has no serializer" do
139
+
140
+ let(:options) do
141
+ described_class.new({ "id" => "_id" })
142
+ end
143
+
144
+ before do
145
+ options.send(method, :sort, { :id => 1 })
146
+ end
147
+
148
+ it "stores the field in the options by database name" do
149
+ expect(options[:sort]).to eq({ "_id" => 1 })
150
+ end
151
+ end
152
+ end
153
+
154
+ context "when no serializers are provided" do
155
+
156
+ let(:options) do
157
+ described_class.new
158
+ end
159
+
160
+ context "when provided a standard object" do
161
+
162
+ context "when the keys are strings" do
163
+
164
+ it "does not serialize values" do
165
+ expect(options.send(method, "limit", "5")).to eq("5")
166
+ end
167
+ end
168
+
169
+ context "when the keys are symbols" do
170
+
171
+ it "does not serialize values" do
172
+ expect(options.send(method, :limit, "5")).to eq("5")
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ context "when serializers are provided" do
179
+
180
+ context "when the serializer is not localized" do
181
+
182
+ before(:all) do
183
+ class Field
184
+ def localized?
185
+ false
186
+ end
187
+ end
188
+ end
189
+
190
+ after(:all) do
191
+ Object.send(:remove_const, :Field)
192
+ end
193
+
194
+ let(:options) do
195
+ described_class.new({}, { "key" => Field.new })
196
+ end
197
+
198
+ context "when the criterion is simple" do
199
+
200
+ before do
201
+ options.send(method, :limit, 1)
202
+ end
203
+
204
+ it "does not localize the keys" do
205
+ expect(options[:limit]).to eq(1)
206
+ end
207
+ end
208
+
209
+ context "when the criterion is complex" do
210
+
211
+ before do
212
+ options.send(method, :sort, { :key => 1 })
213
+ end
214
+
215
+ it "does not localize the keys" do
216
+ expect(options[:sort]).to eq({ "key" => 1 })
217
+ end
218
+ end
219
+ end
220
+
221
+ context "when the serializer is localized" do
222
+
223
+ before(:all) do
224
+ class Field
225
+ def localized?
226
+ true
227
+ end
228
+ end
229
+ end
230
+
231
+ after(:all) do
232
+ Object.send(:remove_const, :Field)
233
+ ::I18n.locale = :en
234
+ end
235
+
236
+ let(:options) do
237
+ described_class.new({}, { "key" => Field.new })
238
+ end
239
+
240
+ before do
241
+ ::I18n.locale = :de
242
+ end
243
+
244
+ context "when the criterion is simple" do
245
+
246
+ before do
247
+ options.send(method, :limit, 1)
248
+ end
249
+
250
+ it "does not localize the keys" do
251
+ expect(options[:limit]).to eq(1)
252
+ end
253
+ end
254
+
255
+ context "when the criterion is complex" do
256
+
257
+ before do
258
+ options.send(method, :sort, { :key => 1 })
259
+ end
260
+
261
+ it "does not localize the keys" do
262
+ expect(options[:sort]).to eq({ "key.de" => 1 })
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
269
+
270
+ describe "#to_pipeline" do
271
+
272
+ let(:options) do
273
+ described_class.new
274
+ end
275
+
276
+ context "when no options exist" do
277
+
278
+ let(:pipeline) do
279
+ options.to_pipeline
280
+ end
281
+
282
+ it "returns an empty array" do
283
+ expect(pipeline).to be_empty
284
+ end
285
+ end
286
+
287
+ context "when multiple options exist" do
288
+
289
+ before do
290
+ options[:fields] = { "name" => 1 }
291
+ options[:skip] = 10
292
+ options[:limit] = 10
293
+ options[:sort] = { "name" => 1 }
294
+ end
295
+
296
+ let(:pipeline) do
297
+ options.to_pipeline
298
+ end
299
+
300
+ it "converts the option to a $sort" do
301
+ expect(pipeline).to eq([
302
+ { "$skip" => 10 },
303
+ { "$limit" => 10 },
304
+ { "$sort" => { "name" => 1 }}
305
+ ])
306
+ end
307
+ end
308
+
309
+ context "when a sort exists" do
310
+
311
+ before do
312
+ options[:sort] = { "name" => 1 }
313
+ end
314
+
315
+ let(:pipeline) do
316
+ options.to_pipeline
317
+ end
318
+
319
+ it "converts the option to a $sort" do
320
+ expect(pipeline).to eq([
321
+ { "$sort" => { "name" => 1 }}
322
+ ])
323
+ end
324
+ end
325
+
326
+ context "when a limit exists" do
327
+
328
+ before do
329
+ options[:limit] = 10
330
+ end
331
+
332
+ let(:pipeline) do
333
+ options.to_pipeline
334
+ end
335
+
336
+ it "converts the option to a $sort" do
337
+ expect(pipeline).to eq([
338
+ { "$limit" => 10 }
339
+ ])
340
+ end
341
+ end
342
+
343
+ context "when a skip exists" do
344
+
345
+ before do
346
+ options[:skip] = 10
347
+ end
348
+
349
+ let(:pipeline) do
350
+ options.to_pipeline
351
+ end
352
+
353
+ it "converts the option to a $sort" do
354
+ expect(pipeline).to eq([
355
+ { "$skip" => 10 }
356
+ ])
357
+ end
358
+ end
359
+ end
360
+ end
@@ -0,0 +1,200 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Queryable::Pipeline do
4
+
5
+ describe "#__deep_copy" do
6
+
7
+ let(:project) do
8
+ { "$project" => { "name" => 1 }}
9
+ end
10
+
11
+ let(:pipeline) do
12
+ described_class.new
13
+ end
14
+
15
+ before do
16
+ pipeline.push(project)
17
+ end
18
+
19
+ let(:copied) do
20
+ pipeline.__deep_copy__
21
+ end
22
+
23
+ it "clones all the objects in the pipeline" do
24
+ expect(copied.first).to_not equal(project)
25
+ end
26
+
27
+ it "clones the pipeline" do
28
+ expect(copied).to_not equal(pipeline)
29
+ end
30
+ end
31
+
32
+ describe "#group" do
33
+
34
+ context "when the expression fields are not aliased" do
35
+
36
+ let(:pipeline) do
37
+ described_class.new
38
+ end
39
+
40
+ context "when using full notation" do
41
+
42
+ before do
43
+ pipeline.group(count: { "$sum" => 1 }, max: { "$max" => "likes" })
44
+ end
45
+
46
+ it "adds the group operation to the pipeline" do
47
+ expect(pipeline).to eq([
48
+ { "$group" => { "count" => { "$sum" => 1 }, "max" => { "$max" => "likes" }}}
49
+ ])
50
+ end
51
+ end
52
+
53
+ context "when using symbol shortcuts" do
54
+
55
+ before do
56
+ pipeline.group(:count.sum => 1, :max.max => "likes")
57
+ end
58
+
59
+ it "adds the group operation to the pipeline" do
60
+ expect(pipeline).to eq([
61
+ { "$group" => { "count" => { "$sum" => 1 }, "max" => { "$max" => "likes" }}}
62
+ ])
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#initialize" do
69
+
70
+ context "when provided aliases" do
71
+
72
+ let(:aliases) do
73
+ { "id" => "_id" }
74
+ end
75
+
76
+ let(:pipeline) do
77
+ described_class.new(aliases)
78
+ end
79
+
80
+ it "sets the aliases" do
81
+ expect(pipeline.aliases).to eq(aliases)
82
+ end
83
+ end
84
+
85
+ context "when not provided aliases" do
86
+
87
+ let(:pipeline) do
88
+ described_class.new
89
+ end
90
+
91
+ it "sets the aliases to an empty hash" do
92
+ expect(pipeline.aliases).to be_empty
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "#project" do
98
+
99
+ let(:pipeline) do
100
+ described_class.new("id" => "_id")
101
+ end
102
+
103
+ context "when the field is not aliased" do
104
+
105
+ before do
106
+ pipeline.project(name: 1)
107
+ end
108
+
109
+ it "sets the aliased projection" do
110
+ expect(pipeline).to eq([
111
+ { "$project" => { "name" => 1 }}
112
+ ])
113
+ end
114
+ end
115
+
116
+ context "when the field is aliased" do
117
+
118
+ before do
119
+ pipeline.project(id: 1)
120
+ end
121
+
122
+ it "sets the aliased projection" do
123
+ expect(pipeline).to eq([
124
+ { "$project" => { "_id" => 1 }}
125
+ ])
126
+ end
127
+ end
128
+ end
129
+
130
+ describe "#unwind" do
131
+
132
+ let(:pipeline) do
133
+ described_class.new("alias" => "a")
134
+ end
135
+
136
+ context "when provided a symbol" do
137
+
138
+ context "when the symbol begins with $" do
139
+
140
+ before do
141
+ pipeline.unwind(:$author)
142
+ end
143
+
144
+ it "converts the symbol to a string" do
145
+ expect(pipeline).to eq([{ "$unwind" => "$author" }])
146
+ end
147
+ end
148
+
149
+ context "when the symbol does not begin with $" do
150
+
151
+ before do
152
+ pipeline.unwind(:author)
153
+ end
154
+
155
+ it "converts the symbol to a string and prepends $" do
156
+ expect(pipeline).to eq([{ "$unwind" => "$author" }])
157
+ end
158
+ end
159
+ end
160
+
161
+ context "when provided a string" do
162
+
163
+ context "when the string begins with $" do
164
+
165
+ before do
166
+ pipeline.unwind("$author")
167
+ end
168
+
169
+ it "sets the string" do
170
+ expect(pipeline).to eq([{ "$unwind" => "$author" }])
171
+ end
172
+ end
173
+
174
+ context "when the string does not begin with $" do
175
+
176
+ before do
177
+ pipeline.unwind(:author)
178
+ end
179
+
180
+ it "prepends $ to the string" do
181
+ expect(pipeline).to eq([{ "$unwind" => "$author" }])
182
+ end
183
+ end
184
+ end
185
+
186
+ context "when provided a string alias" do
187
+
188
+ context "when the string does not begin with $" do
189
+
190
+ before do
191
+ pipeline.unwind(:alias)
192
+ end
193
+
194
+ it "prepends $ to the string" do
195
+ expect(pipeline).to eq([{ "$unwind" => "$a" }])
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end