mongo 2.1.2 → 2.2.0.rc0

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 (140) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +10 -3
  5. data/Rakefile +1 -7
  6. data/lib/csasl/csasl.bundle +0 -0
  7. data/lib/mongo/auth/user/view.rb +1 -1
  8. data/lib/mongo/bulk_write.rb +7 -1
  9. data/lib/mongo/client.rb +17 -15
  10. data/lib/mongo/cluster.rb +4 -2
  11. data/lib/mongo/collection.rb +36 -2
  12. data/lib/mongo/collection/view.rb +24 -21
  13. data/lib/mongo/collection/view/aggregation.rb +5 -42
  14. data/lib/mongo/collection/view/builder.rb +20 -0
  15. data/lib/mongo/collection/view/builder/aggregation.rb +98 -0
  16. data/lib/mongo/collection/view/builder/find_command.rb +111 -0
  17. data/lib/mongo/collection/view/builder/flags.rb +62 -0
  18. data/lib/mongo/collection/view/builder/map_reduce.rb +134 -0
  19. data/lib/mongo/collection/view/builder/modifiers.rb +80 -0
  20. data/lib/mongo/collection/view/builder/op_query.rb +83 -0
  21. data/lib/mongo/collection/view/explainable.rb +15 -0
  22. data/lib/mongo/collection/view/immutable.rb +5 -12
  23. data/lib/mongo/collection/view/iterable.rb +24 -2
  24. data/lib/mongo/collection/view/map_reduce.rb +18 -27
  25. data/lib/mongo/collection/view/readable.rb +70 -112
  26. data/lib/mongo/collection/view/writable.rb +23 -7
  27. data/lib/mongo/cursor.rb +76 -25
  28. data/lib/mongo/cursor/builder.rb +18 -0
  29. data/lib/mongo/cursor/builder/get_more_command.rb +71 -0
  30. data/lib/mongo/cursor/builder/kill_cursors_command.rb +62 -0
  31. data/lib/mongo/cursor/builder/op_get_more.rb +61 -0
  32. data/lib/mongo/cursor/builder/op_kill_cursors.rb +56 -0
  33. data/lib/mongo/database.rb +2 -2
  34. data/lib/mongo/database/view.rb +9 -5
  35. data/lib/mongo/dbref.rb +3 -3
  36. data/lib/mongo/error.rb +1 -0
  37. data/lib/mongo/error/invalid_write_concern.rb +35 -0
  38. data/lib/mongo/grid/file/chunk.rb +2 -2
  39. data/lib/mongo/index/view.rb +5 -2
  40. data/lib/mongo/operation.rb +1 -0
  41. data/lib/mongo/operation/commands.rb +2 -0
  42. data/lib/mongo/operation/commands/aggregate.rb +39 -45
  43. data/lib/mongo/operation/commands/aggregate/result.rb +54 -68
  44. data/lib/mongo/operation/commands/collections_info.rb +38 -36
  45. data/lib/mongo/operation/commands/collections_info/result.rb +17 -15
  46. data/lib/mongo/operation/commands/command.rb +24 -22
  47. data/lib/mongo/operation/commands/find.rb +27 -0
  48. data/lib/mongo/operation/commands/find/result.rb +62 -0
  49. data/lib/mongo/operation/commands/get_more.rb +27 -0
  50. data/lib/mongo/operation/commands/get_more/result.rb +62 -0
  51. data/lib/mongo/operation/commands/indexes.rb +41 -39
  52. data/lib/mongo/operation/commands/list_collections.rb +25 -31
  53. data/lib/mongo/operation/commands/list_collections/result.rb +63 -81
  54. data/lib/mongo/operation/commands/list_indexes.rb +27 -35
  55. data/lib/mongo/operation/commands/list_indexes/result.rb +67 -85
  56. data/lib/mongo/operation/commands/map_reduce.rb +29 -37
  57. data/lib/mongo/operation/commands/map_reduce/result.rb +85 -88
  58. data/lib/mongo/operation/commands/parallel_scan.rb +29 -33
  59. data/lib/mongo/operation/commands/parallel_scan/result.rb +34 -42
  60. data/lib/mongo/operation/commands/user_query.rb +40 -38
  61. data/lib/mongo/operation/commands/users_info.rb +24 -29
  62. data/lib/mongo/operation/commands/users_info/result.rb +13 -11
  63. data/lib/mongo/operation/object_id_generator.rb +36 -0
  64. data/lib/mongo/operation/result.rb +30 -0
  65. data/lib/mongo/operation/specifiable.rb +35 -1
  66. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -3
  67. data/lib/mongo/operation/write/bulk/delete/result.rb +18 -25
  68. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +2 -2
  69. data/lib/mongo/operation/write/command/delete.rb +3 -2
  70. data/lib/mongo/operation/write/command/insert.rb +4 -2
  71. data/lib/mongo/operation/write/command/update.rb +6 -3
  72. data/lib/mongo/operation/write/gle.rb +2 -1
  73. data/lib/mongo/operation/write/idable.rb +19 -2
  74. data/lib/mongo/options/mapper.rb +22 -0
  75. data/lib/mongo/protocol/bit_vector.rb +3 -3
  76. data/lib/mongo/protocol/delete.rb +15 -5
  77. data/lib/mongo/protocol/get_more.rb +10 -5
  78. data/lib/mongo/protocol/insert.rb +1 -6
  79. data/lib/mongo/protocol/kill_cursors.rb +14 -1
  80. data/lib/mongo/protocol/message.rb +32 -8
  81. data/lib/mongo/protocol/serializers.rb +15 -16
  82. data/lib/mongo/protocol/update.rb +35 -12
  83. data/lib/mongo/server/connectable.rb +3 -1
  84. data/lib/mongo/server/connection.rb +5 -5
  85. data/lib/mongo/server/description.rb +8 -2
  86. data/lib/mongo/server/description/features.rb +2 -1
  87. data/lib/mongo/server/monitor.rb +1 -12
  88. data/lib/mongo/server/monitor/connection.rb +30 -26
  89. data/lib/mongo/server_selector/selectable.rb +21 -4
  90. data/lib/mongo/uri.rb +2 -0
  91. data/lib/mongo/version.rb +1 -1
  92. data/lib/mongo/write_concern.rb +21 -6
  93. data/mongo.gemspec +1 -2
  94. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +13 -0
  95. data/spec/mongo/bulk_write_spec.rb +58 -0
  96. data/spec/mongo/client_spec.rb +6 -4
  97. data/spec/mongo/collection/view/builder/find_command_spec.rb +167 -0
  98. data/spec/mongo/collection/view/builder/flags_spec.rb +106 -0
  99. data/spec/mongo/collection/view/builder/modifiers_spec.rb +210 -0
  100. data/spec/mongo/collection/view/builder/op_query_spec.rb +154 -0
  101. data/spec/mongo/collection/view/explainable_spec.rb +1 -2
  102. data/spec/mongo/collection/view/immutable_spec.rb +3 -52
  103. data/spec/mongo/collection/view/map_reduce_spec.rb +12 -12
  104. data/spec/mongo/collection/view/readable_spec.rb +86 -80
  105. data/spec/mongo/collection/view_spec.rb +109 -703
  106. data/spec/mongo/collection_spec.rb +594 -11
  107. data/spec/mongo/command_monitoring_spec.rb +40 -27
  108. data/spec/mongo/cursor/builder/get_more_command_spec.rb +160 -0
  109. data/spec/mongo/cursor/builder/op_get_more_spec.rb +52 -0
  110. data/spec/mongo/cursor_spec.rb +10 -60
  111. data/spec/mongo/database_spec.rb +24 -3
  112. data/spec/mongo/dbref_spec.rb +4 -4
  113. data/spec/mongo/grid/file/chunk_spec.rb +1 -1
  114. data/spec/mongo/grid/fs_bucket_spec.rb +3 -3
  115. data/spec/mongo/index/view_spec.rb +41 -0
  116. data/spec/mongo/operation/{aggregate → commands/aggregate}/result_spec.rb +1 -1
  117. data/spec/mongo/operation/commands/aggregate_spec.rb +1 -1
  118. data/spec/mongo/operation/commands/collections_info_spec.rb +1 -1
  119. data/spec/mongo/operation/commands/command_spec.rb +1 -1
  120. data/spec/mongo/operation/commands/indexes_spec.rb +1 -1
  121. data/spec/mongo/operation/commands/map_reduce_spec.rb +1 -1
  122. data/spec/mongo/operation/write/command/delete_spec.rb +25 -0
  123. data/spec/mongo/operation/write/command/insert_spec.rb +25 -0
  124. data/spec/mongo/operation/write/command/update_spec.rb +25 -0
  125. data/spec/mongo/protocol/delete_spec.rb +4 -4
  126. data/spec/mongo/protocol/get_more_spec.rb +4 -4
  127. data/spec/mongo/protocol/insert_spec.rb +3 -3
  128. data/spec/mongo/protocol/kill_cursors_spec.rb +3 -3
  129. data/spec/mongo/protocol/query_spec.rb +7 -7
  130. data/spec/mongo/protocol/update_spec.rb +5 -5
  131. data/spec/mongo/server/description/features_spec.rb +25 -0
  132. data/spec/mongo/write_concern_spec.rb +126 -0
  133. data/spec/spec_helper.rb +9 -19
  134. data/spec/support/command_monitoring.rb +8 -0
  135. data/spec/support/command_monitoring/find.yml +53 -4
  136. data/spec/support/matchers.rb +1 -1
  137. data/spec/support/shared/protocol.rb +5 -5
  138. data/spec/support/travis.rb +1 -1
  139. metadata +43 -10
  140. metadata.gz.sig +0 -0
@@ -25,8 +25,7 @@ describe Mongo::Collection::View::Explainable do
25
25
  end
26
26
 
27
27
  it 'executes an explain' do
28
- expect(explain[:cursor] == 'BasicCursor' ||
29
- explain[:queryPlanner]).to be_truthy
28
+ expect(explain[:cursor] == 'BasicCursor' || explain[:queryPlanner]).to be_truthy
30
29
  end
31
30
  end
32
31
  end
@@ -20,10 +20,10 @@ describe Mongo::Collection::View::Immutable do
20
20
 
21
21
  describe '#configure' do
22
22
 
23
- context 'when the options has a modifiers document' do
23
+ context 'when the options have modifiers' do
24
24
 
25
25
  let(:options) do
26
- { modifiers: { :$maxTimeMS => 500 } }
26
+ { :max_time_ms => 500 }
27
27
  end
28
28
 
29
29
  let(:new_view) do
@@ -43,56 +43,7 @@ describe Mongo::Collection::View::Immutable do
43
43
  end
44
44
 
45
45
  it 'sets the option' do
46
- expect(new_view.projection).to eq(_id: 1)
47
- end
48
-
49
- it 'creates a new modifiers document' do
50
- expect(view.modifiers).not_to be(new_view.modifiers)
51
- end
52
- end
53
- end
54
-
55
- describe '#configure_modifier' do
56
-
57
- let(:new_view) do
58
- view.sort('x' => Mongo::Index::ASCENDING)
59
- end
60
-
61
- context 'when the options does not have a modifiers document' do
62
-
63
- it 'returns a new view' do
64
- expect(view).not_to be(new_view)
65
- end
66
-
67
- it 'returns a new view with the modifiers document containing the option' do
68
- expect(new_view.modifiers[:$orderby]).to eq({ 'x' => Mongo::Index::ASCENDING })
69
- end
70
- end
71
-
72
- context 'when the options has a modifiers document' do
73
-
74
- let(:options) do
75
- { modifiers: { :$maxTimeMS => 500 } }
76
- end
77
-
78
- it 'returns a new view' do
79
- expect(view).not_to be(new_view)
80
- end
81
-
82
- it 'creates a new options hash' do
83
- expect(view.options).not_to be(new_view.options)
84
- end
85
-
86
- it 'keeps the fields already in the options hash and merges in the new one' do
87
- expect(new_view.modifiers[:$maxTimeMS]).to eq(500)
88
- end
89
-
90
- it 'sets the new value in the new view modifier document' do
91
- expect(new_view.modifiers[:$orderby]).to eq('x' => Mongo::Index::ASCENDING)
92
- end
93
-
94
- it 'returns that value when the corresponding option method is called' do
95
- expect(new_view.sort).to eq({ 'x' => Mongo::Index::ASCENDING })
46
+ expect(new_view.projection).to eq('_id' => 1)
96
47
  end
97
48
 
98
49
  it 'creates a new modifiers document' do
@@ -186,7 +186,7 @@ describe Mongo::Collection::View::MapReduce do
186
186
  context 'when the selector is basic' do
187
187
 
188
188
  let(:selector) do
189
- { name: 'Berlin' }
189
+ { 'name' => 'Berlin' }
190
190
  end
191
191
 
192
192
  it 'applies the selector to the map/reduce' do
@@ -203,7 +203,7 @@ describe Mongo::Collection::View::MapReduce do
203
203
  context 'when the selector is advanced' do
204
204
 
205
205
  let(:selector) do
206
- { :$query => { name: 'Berlin' }}
206
+ { :$query => { 'name' => 'Berlin' }}
207
207
  end
208
208
 
209
209
  it 'applies the selector to the map/reduce' do
@@ -213,7 +213,7 @@ describe Mongo::Collection::View::MapReduce do
213
213
  end
214
214
 
215
215
  it 'includes the selector in the operation spec' do
216
- expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(BSON::Document.new(selector[:$query]))
216
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(selector[:$query])
217
217
  end
218
218
  end
219
219
  end
@@ -273,7 +273,7 @@ describe Mongo::Collection::View::MapReduce do
273
273
  describe '#out' do
274
274
 
275
275
  let(:location) do
276
- { replace: 'testing' }
276
+ { 'replace' => 'testing' }
277
277
  end
278
278
 
279
279
  let(:new_map_reduce) do
@@ -285,20 +285,20 @@ describe Mongo::Collection::View::MapReduce do
285
285
  end
286
286
 
287
287
  it 'includes the out value in the operation spec' do
288
- expect(new_map_reduce.send(:map_reduce_spec)[:selector][:out]).to be(location)
288
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(location)
289
289
  end
290
290
 
291
291
  context 'when out is not defined' do
292
292
 
293
293
  it 'defaults to inline' do
294
- expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(inline: 1)
294
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq('inline' => 1)
295
295
  end
296
296
  end
297
297
 
298
298
  context 'when out is specified in the options' do
299
299
 
300
300
  let(:location) do
301
- { replace: 'testing' }
301
+ { 'replace' => 'testing' }
302
302
  end
303
303
 
304
304
  let(:options) do
@@ -310,14 +310,14 @@ describe Mongo::Collection::View::MapReduce do
310
310
  end
311
311
 
312
312
  it 'includes the out value in the operation spec' do
313
- expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to be(location)
313
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(location)
314
314
  end
315
315
  end
316
316
 
317
317
  context 'when out is not inline' do
318
318
 
319
319
  let(:location) do
320
- { replace: 'testing' }
320
+ { 'replace' => 'testing' }
321
321
  end
322
322
 
323
323
  let(:options) do
@@ -325,7 +325,7 @@ describe Mongo::Collection::View::MapReduce do
325
325
  end
326
326
 
327
327
  it 'does not allow the operation on a secondary' do
328
- expect(map_reduce.send(:secondary_ok?)).to be(false)
328
+ expect(map_reduce.send(:secondary_ok?)).to be false
329
329
  end
330
330
 
331
331
  context 'when the context is not a valid server for writing' do
@@ -350,7 +350,7 @@ describe Mongo::Collection::View::MapReduce do
350
350
  describe '#scope' do
351
351
 
352
352
  let(:object) do
353
- { value: 'testing' }
353
+ { 'value' => 'testing' }
354
354
  end
355
355
 
356
356
  let(:new_map_reduce) do
@@ -362,7 +362,7 @@ describe Mongo::Collection::View::MapReduce do
362
362
  end
363
363
 
364
364
  it 'includes the scope object in the operation spec' do
365
- expect(new_map_reduce.send(:map_reduce_spec)[:selector][:scope]).to be(object)
365
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:scope]).to eq(object)
366
366
  end
367
367
  end
368
368
 
@@ -18,6 +18,40 @@ describe Mongo::Collection::View::Readable do
18
18
  authorized_collection.delete_many
19
19
  end
20
20
 
21
+ shared_examples_for 'a read concern aware operation' do
22
+
23
+ context 'when a read concern is provided', if: find_command_enabled? do
24
+
25
+ let(:new_view) do
26
+ Mongo::Collection::View.new(new_collection, selector, options)
27
+ end
28
+
29
+ context 'when the read concern is valid' do
30
+
31
+ let(:new_collection) do
32
+ authorized_collection.with(read_concern: { level: 'local' })
33
+ end
34
+
35
+ it 'sends the read concern' do
36
+ expect { result }.to_not raise_error
37
+ end
38
+ end
39
+
40
+ context 'when the read concern is not valid' do
41
+
42
+ let(:new_collection) do
43
+ authorized_collection.with(read_concern: { level: 'na' })
44
+ end
45
+
46
+ it 'raises an exception' do
47
+ expect {
48
+ result
49
+ }.to raise_error(Mongo::Error::OperationFailure)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
21
55
  describe '#allow_partial_results' do
22
56
 
23
57
  let(:new_view) do
@@ -25,7 +59,7 @@ describe Mongo::Collection::View::Readable do
25
59
  end
26
60
 
27
61
  it 'sets the flag' do
28
- expect(new_view.send(:flags)).to include(:partial)
62
+ expect(new_view.options[:allow_partial_results]).to be true
29
63
  end
30
64
 
31
65
  it 'returns a new View' do
@@ -60,6 +94,15 @@ describe Mongo::Collection::View::Readable do
60
94
  view.aggregate(pipeline)
61
95
  end
62
96
 
97
+ context 'when incorporating read concern' do
98
+
99
+ let(:result) do
100
+ new_view.aggregate(pipeline, options).to_a
101
+ end
102
+
103
+ it_behaves_like 'a read concern aware operation'
104
+ end
105
+
63
106
  context 'when not iterating the aggregation' do
64
107
 
65
108
  it 'returns the aggregation object' do
@@ -127,6 +170,15 @@ describe Mongo::Collection::View::Readable do
127
170
  view.map_reduce(map, reduce)
128
171
  end
129
172
 
173
+ context 'when incorporating read concern' do
174
+
175
+ let(:result) do
176
+ new_view.map_reduce(map, reduce, options).to_a
177
+ end
178
+
179
+ it_behaves_like 'a read concern aware operation'
180
+ end
181
+
130
182
  context 'when not iterating the map/reduce' do
131
183
 
132
184
  it 'returns the map/reduce object' do
@@ -218,6 +270,19 @@ describe Mongo::Collection::View::Readable do
218
270
  authorized_collection.delete_many
219
271
  end
220
272
 
273
+ let(:result) do
274
+ view.count(options)
275
+ end
276
+
277
+ context 'when incorporating read concern' do
278
+
279
+ let(:result) do
280
+ new_view.count(options)
281
+ end
282
+
283
+ it_behaves_like 'a read concern aware operation'
284
+ end
285
+
221
286
  context 'when a selector is provided' do
222
287
 
223
288
  let(:selector) do
@@ -257,6 +322,15 @@ describe Mongo::Collection::View::Readable do
257
322
 
258
323
  describe '#distinct' do
259
324
 
325
+ context 'when incorporating read concern' do
326
+
327
+ let(:result) do
328
+ new_view.distinct(:field, options)
329
+ end
330
+
331
+ it_behaves_like 'a read concern aware operation'
332
+ end
333
+
260
334
  context 'when a selector is provided' do
261
335
 
262
336
  let(:selector) do
@@ -498,7 +572,7 @@ describe Mongo::Collection::View::Readable do
498
572
  end
499
573
 
500
574
  it 'sets the flag' do
501
- expect(new_view.send(:flags)).to include(:no_cursor_timeout)
575
+ expect(new_view.options[:no_cursor_timeout]).to be true
502
576
  end
503
577
 
504
578
  it 'returns a new View' do
@@ -518,6 +592,10 @@ describe Mongo::Collection::View::Readable do
518
592
  { 'y' => 1 }
519
593
  end
520
594
 
595
+ before do
596
+ authorized_collection.insert_one(y: 'value', a: 'other_value')
597
+ end
598
+
521
599
  it 'sets the projection' do
522
600
  new_view = view.projection(new_projection)
523
601
  expect(new_view.projection).to eq(new_projection)
@@ -526,6 +604,10 @@ describe Mongo::Collection::View::Readable do
526
604
  it 'returns a new View' do
527
605
  expect(view.projection(new_projection)).not_to be(view)
528
606
  end
607
+
608
+ it 'returns only that field on the collection' do
609
+ expect(view.projection(new_projection).first.keys).to match_array(['_id', 'y'])
610
+ end
529
611
  end
530
612
 
531
613
  context 'when projection is not specified' do
@@ -636,13 +718,13 @@ describe Mongo::Collection::View::Readable do
636
718
  describe '#modifiers' do
637
719
 
638
720
  let(:options) do
639
- { :modifiers => { :$orderby => Mongo::Index::ASCENDING } }
721
+ { :modifiers => { '$orderby' => 1 } }
640
722
  end
641
723
 
642
724
  context 'when a modifiers document is specified' do
643
725
 
644
726
  let(:new_modifiers) do
645
- { :modifiers => { :$orderby => Mongo::Index::DESCENDING } }
727
+ { '$orderby' => -1 }
646
728
  end
647
729
 
648
730
  it 'sets the new_modifiers document' do
@@ -770,81 +852,5 @@ describe Mongo::Collection::View::Readable do
770
852
  expect(view.sort).to eq(options[:sort])
771
853
  end
772
854
  end
773
-
774
- context 'when an option is a cursor flag' do
775
-
776
- let(:query_spec_options) do
777
- view.send(:query_spec)[:options]
778
- end
779
-
780
- context 'when allow_partial_results is set as an option' do
781
-
782
- let(:options) do
783
- { :allow_partial_results => true }
784
- end
785
-
786
- it 'sets the cursor flag' do
787
- expect(query_spec_options[:flags]).to eq([:partial])
788
- end
789
-
790
- context 'when allow_partial_results is also called as a method' do
791
-
792
- before do
793
- view.allow_partial_results
794
- end
795
-
796
- it 'sets only one cursor flag' do
797
- expect(query_spec_options[:flags]).to eq([:partial])
798
- end
799
- end
800
- end
801
-
802
- context 'when oplog_replay is set as an option' do
803
-
804
- let(:options) do
805
- { :oplog_replay => true }
806
- end
807
-
808
- it 'sets the cursor flag' do
809
- expect(query_spec_options[:flags]).to eq([:oplog_replay])
810
- end
811
- end
812
-
813
- context 'when no_cursor_timeout is set as an option' do
814
-
815
- let(:options) do
816
- { :no_cursor_timeout => true }
817
- end
818
-
819
- it 'sets the cursor flag' do
820
- expect(query_spec_options[:flags]).to eq([:no_cursor_timeout])
821
- end
822
- end
823
-
824
- context 'when cursor_type is set as an option' do
825
-
826
- context 'when :tailable is the cursor type' do
827
-
828
- let(:options) do
829
- { :cursor_type => :tailable }
830
- end
831
-
832
- it 'sets the cursor flag' do
833
- expect(query_spec_options[:flags]).to eq([:tailable_cursor])
834
- end
835
- end
836
-
837
- context 'when :tailable_await is the cursor type' do
838
-
839
- let(:options) do
840
- { :cursor_type => :tailable_await }
841
- end
842
-
843
- it 'sets the cursor flags' do
844
- expect(query_spec_options[:flags]).to eq([:await_data, :tailable_cursor])
845
- end
846
- end
847
- end
848
- end
849
855
  end
850
856
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection::View do
4
4
 
5
- let(:selector) do
5
+ let(:filter) do
6
6
  {}
7
7
  end
8
8
 
@@ -11,187 +11,13 @@ describe Mongo::Collection::View do
11
11
  end
12
12
 
13
13
  let(:view) do
14
- described_class.new(authorized_collection, selector, options)
14
+ described_class.new(authorized_collection, filter, options)
15
15
  end
16
16
 
17
17
  after do
18
18
  authorized_collection.delete_many
19
19
  end
20
20
 
21
- context 'when query modifiers are provided' do
22
-
23
- context 'when a selector has a query modifier' do
24
-
25
- let(:options) do
26
- {}
27
- end
28
-
29
- let(:expected_modifiers) do
30
- BSON::Document.new(selector)
31
- end
32
-
33
- let(:parsed_selector) do
34
- {}
35
- end
36
-
37
- let(:query_selector) do
38
- BSON::Document.new(selector)
39
- end
40
-
41
- context 'when the $query key is a string' do
42
-
43
- let(:selector) do
44
- { "$query" => { a: 1 }, :$someMod => 100 }
45
- end
46
-
47
- let(:expected_modifiers) do
48
- BSON::Document.new(selector)
49
- end
50
-
51
- it 'sets the modifiers' do
52
- expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
53
- end
54
-
55
- it 'removes the modifiers from the selector' do
56
- expect(view.selector).to eq(parsed_selector)
57
- end
58
-
59
- it 'creates the correct query selector' do
60
- expect(view.send(:query_spec)[:selector]).to eq(query_selector)
61
- end
62
-
63
- end
64
-
65
- context 'when the $query key is a symbol' do
66
-
67
- let(:selector) do
68
- { :$query => { a: 1 }, :$someMod => 100 }
69
- end
70
-
71
- let(:expected_modifiers) do
72
- BSON::Document.new(selector)
73
- end
74
-
75
- it 'sets the modifiers' do
76
- expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
77
- end
78
-
79
- it 'removes the modifiers from the selector' do
80
- expect(view.selector).to eq(parsed_selector)
81
- end
82
-
83
- it 'creates the correct query selector' do
84
- expect(view.send(:query_spec)[:selector]).to eq(query_selector)
85
- end
86
- end
87
- end
88
-
89
- context 'when a modifiers document is provided in the options' do
90
-
91
- let(:selector) do
92
- { a: 1 }
93
- end
94
-
95
- let(:options) do
96
- { :modifiers => { :$someMod => 100 } }
97
- end
98
-
99
- let(:expected_modifiers) do
100
- options[:modifiers]
101
- end
102
-
103
- let(:parsed_selector) do
104
- { a: 1 }
105
- end
106
-
107
- let(:query_selector) do
108
- BSON::Document.new(:$query => { a: 1 }, :$someMod => 100)
109
- end
110
-
111
- it 'sets the modifiers' do
112
- expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
113
- end
114
-
115
- it 'removes the modifiers from the selector' do
116
- expect(view.selector).to eq(parsed_selector)
117
- end
118
-
119
- it 'creates the correct query selector' do
120
- expect(view.send(:query_spec)[:selector]).to eq(query_selector)
121
- end
122
-
123
- context 'when modifiers and options are both provided' do
124
-
125
- let(:selector) do
126
- { a: 1 }
127
- end
128
-
129
- let(:options) do
130
- { :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$orderby => { a: Mongo::Index::DESCENDING } } }
131
- end
132
-
133
- let(:expected_modifiers) do
134
- { :$orderby => options[:sort] }
135
- end
136
-
137
- let(:parsed_selector) do
138
- { a: 1 }
139
- end
140
-
141
- let(:query_selector) do
142
- BSON::Document.new(:$query => selector, :$orderby => { a: Mongo::Index::ASCENDING })
143
- end
144
-
145
- it 'sets the modifiers' do
146
- expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
147
- end
148
-
149
- it 'removes the modifiers from the selector' do
150
- expect(view.selector).to eq(parsed_selector)
151
- end
152
-
153
- it 'creates the correct query selector' do
154
- expect(view.send(:query_spec)[:selector]).to eq(query_selector)
155
- end
156
- end
157
-
158
- context 'when modifiers, options and a query modifier are provided' do
159
-
160
- let(:selector) do
161
- { b: 2, :$query => { a: 1 }, :$someMod => 100 }
162
- end
163
-
164
- let(:options) do
165
- { :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$someMod => true, :$orderby => { a: Mongo::Index::DESCENDING } } }
166
- end
167
-
168
- let(:expected_modifiers) do
169
- { :$query => { a: 1 }, :$orderby => { a: Mongo::Index::ASCENDING }, :$someMod => 100 }
170
- end
171
-
172
- let(:parsed_selector) do
173
- { b: 2 }
174
- end
175
-
176
- let(:query_selector) do
177
- BSON::Document.new(:$query => { a: 1 }, :$someMod => 100, :$orderby => { a: Mongo::Index::ASCENDING })
178
- end
179
-
180
- it 'sets the modifiers' do
181
- expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
182
- end
183
-
184
- it 'removes the modifiers from the selector' do
185
- expect(view.selector).to eq(parsed_selector)
186
- end
187
-
188
- it 'creates the correct query selector' do
189
- expect(view.send(:query_spec)[:selector]).to eq(query_selector)
190
- end
191
- end
192
- end
193
- end
194
-
195
21
  describe '#==' do
196
22
 
197
23
  context 'when the other object is not a collection view' do
@@ -203,10 +29,10 @@ describe Mongo::Collection::View do
203
29
  end
204
30
  end
205
31
 
206
- context 'when the views have the same collection, selector, and options' do
32
+ context 'when the views have the same collection, filter, and options' do
207
33
 
208
34
  let(:other) do
209
- described_class.new(authorized_collection, selector, options)
35
+ described_class.new(authorized_collection, filter, options)
210
36
  end
211
37
 
212
38
  it 'returns true' do
@@ -221,7 +47,7 @@ describe Mongo::Collection::View do
221
47
  end
222
48
 
223
49
  let(:other) do
224
- described_class.new(other_collection, selector, options)
50
+ described_class.new(other_collection, filter, options)
225
51
  end
226
52
 
227
53
  it 'returns false' do
@@ -229,14 +55,14 @@ describe Mongo::Collection::View do
229
55
  end
230
56
  end
231
57
 
232
- context 'when two views have a different selector' do
58
+ context 'when two views have a different filter' do
233
59
 
234
- let(:other_selector) do
60
+ let(:other_filter) do
235
61
  { 'name' => 'Emily' }
236
62
  end
237
63
 
238
64
  let(:other) do
239
- described_class.new(authorized_collection, other_selector, options)
65
+ described_class.new(authorized_collection, other_filter, options)
240
66
  end
241
67
 
242
68
  it 'returns false' do
@@ -251,7 +77,7 @@ describe Mongo::Collection::View do
251
77
  end
252
78
 
253
79
  let(:other) do
254
- described_class.new(authorized_collection, selector, other_options)
80
+ described_class.new(authorized_collection, filter, other_options)
255
81
  end
256
82
 
257
83
  it 'returns false' do
@@ -270,8 +96,8 @@ describe Mongo::Collection::View do
270
96
  expect(view.options).not_to be(view_clone.options)
271
97
  end
272
98
 
273
- it 'dups the selector' do
274
- expect(view.selector).not_to be(view_clone.selector)
99
+ it 'dups the filter' do
100
+ expect(view.filter).not_to be(view_clone.filter)
275
101
  end
276
102
 
277
103
  it 'references the same collection' do
@@ -293,487 +119,6 @@ describe Mongo::Collection::View do
293
119
  authorized_collection.delete_many
294
120
  end
295
121
 
296
- context 'when sending the initial query' do
297
-
298
- let(:returned) do
299
- view.to_a
300
- end
301
-
302
- let(:query_spec) do
303
- view.send(:query_spec)
304
- end
305
-
306
- context 'when limit is specified' do
307
-
308
- let(:options) do
309
- { :limit => 5 }
310
- end
311
-
312
- let(:returned) do
313
- view.to_a
314
- end
315
-
316
- it 'sets the limit on the initial query' do
317
- expect(query_spec[:options][:limit]).to eq(options[:limit])
318
- end
319
-
320
- it 'returns limited documents' do
321
- expect(returned.count).to eq(5)
322
- end
323
-
324
- it 'iterates over all of the documents' do
325
- returned.each do |doc|
326
- expect(doc).to have_key('field')
327
- end
328
- end
329
- end
330
-
331
- context 'when batch size is specified' do
332
-
333
- let(:options) do
334
- { :batch_size => 5 }
335
- end
336
-
337
- let(:returned) do
338
- view.to_a
339
- end
340
-
341
- it 'sets the batch size on the initial query' do
342
- expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
343
- end
344
-
345
- it 'returns all the documents' do
346
- expect(returned.count).to eq(10)
347
- end
348
-
349
- it 'iterates over all of the documents' do
350
- returned.each do |doc|
351
- expect(doc).to have_key('field')
352
- end
353
- end
354
- end
355
-
356
- context 'when no limit is specified' do
357
-
358
- it 'does not set a limit on the initial query' do
359
- expect(query_spec[:options][:limit]).to be_nil
360
- end
361
-
362
- it 'returns all the documents' do
363
- expect(returned.count).to eq(10)
364
- end
365
-
366
- it 'iterates over all of the documents' do
367
- returned.each do |doc|
368
- expect(doc).to have_key('field')
369
- end
370
- end
371
- end
372
-
373
- context 'when batch size is greater than limit' do
374
-
375
- let(:options) do
376
- { :batch_size => 5, :limit => 3 }
377
- end
378
-
379
- let(:returned) do
380
- view.to_a
381
- end
382
-
383
- it 'sets the limit on the initial query' do
384
- expect(query_spec[:options][:limit]).to eq(options[:limit])
385
- end
386
-
387
- it 'returns the limit of documents' do
388
- expect(returned.count).to eq(3)
389
- end
390
-
391
- it 'iterates over all of the documents' do
392
- returned.each do |doc|
393
- expect(doc).to have_key('field')
394
- end
395
- end
396
- end
397
-
398
- context 'when limit is greater than batch size' do
399
-
400
- let(:options) do
401
- { :limit => 5, :batch_size => 3 }
402
- end
403
-
404
- let(:returned) do
405
- view.to_a
406
- end
407
-
408
- it 'sets the batch size on the initial query' do
409
- expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
410
- end
411
-
412
- it 'sets the limit on the initial query' do
413
- expect(query_spec[:options][:limit]).to eq(options[:limit])
414
- end
415
-
416
- it 'returns the limit of documents' do
417
- expect(returned.count).to eq(5)
418
- end
419
-
420
- it 'iterates over all of the documents' do
421
- returned.each do |doc|
422
- expect(doc).to have_key('field')
423
- end
424
- end
425
- end
426
-
427
- context 'when the selector has special fields' do
428
-
429
- context 'when a snapshot option is specified' do
430
-
431
- let(:options) do
432
- { :snapshot => true }
433
- end
434
-
435
- before do
436
- expect(view).to receive(:special_selector).and_call_original
437
- end
438
-
439
- it 'creates a special query selector' do
440
- expect(query_spec[:selector][:$snapshot]).to eq(options[:snapshot])
441
- end
442
-
443
- it 'iterates over all of the documents' do
444
- returned.each do |doc|
445
- expect(doc).to have_key('field')
446
- end
447
- end
448
- end
449
-
450
- context 'when a max_scan option is provided' do
451
-
452
- let(:options) do
453
- { :max_scan => 100 }
454
- end
455
-
456
- before do
457
- expect(view).to receive(:special_selector).and_call_original
458
- end
459
-
460
- it 'creates a special query selector' do
461
- expect(query_spec[:selector][:$maxScan]).to eq(options[:max_scan])
462
- end
463
-
464
- it 'iterates over all of the documents' do
465
- returned.each do |doc|
466
- expect(doc).to have_key('field')
467
- end
468
- end
469
- end
470
-
471
- context 'when a max_time_ms option is provided' do
472
-
473
- let(:options) do
474
- { :max_time_ms => 100 }
475
- end
476
-
477
- before do
478
- expect(view).to receive(:special_selector).and_call_original
479
- end
480
-
481
- it 'creates a special query selector' do
482
- expect(query_spec[:selector][:$maxTimeMS]).to eq(options[:max_time_ms])
483
- end
484
-
485
- it 'iterates over all of the documents' do
486
- returned.each do |doc|
487
- expect(doc).to have_key('field')
488
- end
489
- end
490
- end
491
-
492
- context 'when a show_disk_loc option is provided' do
493
-
494
- let(:options) do
495
- { :show_disk_loc => true }
496
- end
497
-
498
- before do
499
- expect(view).to receive(:special_selector).and_call_original
500
- end
501
-
502
- it 'creates a special query selector' do
503
- expect(query_spec[:selector][:$showDiskLoc]).to eq(options[:show_disk_loc])
504
- end
505
-
506
- it 'iterates over all of the documents' do
507
- returned.each do |doc|
508
- expect(doc).to have_key('field')
509
- end
510
- end
511
- end
512
- end
513
-
514
- context 'when sorting' do
515
-
516
- let(:options) do
517
- { :sort => {'x' => Mongo::Index::ASCENDING }}
518
- end
519
-
520
- before do
521
- expect(view).to receive(:special_selector).and_call_original
522
- end
523
-
524
- it 'creates a special query selector' do
525
- expect(query_spec[:selector][:$orderby]).to eq(options[:sort])
526
- end
527
-
528
- it 'iterates over all of the documents' do
529
- returned.each do |doc|
530
- expect(doc).to have_key('field')
531
- end
532
- end
533
- end
534
-
535
- context 'when providing a hint' do
536
-
537
- context 'when the hint is bad' do
538
-
539
- let(:options) do
540
- { :hint => { 'x' => Mongo::Index::ASCENDING }}
541
- end
542
-
543
- before do
544
- expect(view).to receive(:special_selector).and_call_original
545
- end
546
-
547
- it 'creates a special query selector' do
548
- expect(query_spec[:selector][:$hint]).to eq(options[:hint])
549
- end
550
- end
551
- end
552
-
553
- context 'when providing a comment' do
554
-
555
- let(:options) do
556
- { :comment => 'query1' }
557
- end
558
-
559
- before do
560
- expect(view).to receive(:special_selector).and_call_original
561
- end
562
-
563
- it 'creates a special query selector' do
564
- expect(query_spec[:selector][:$comment]).to eq(options[:comment])
565
- end
566
-
567
- it 'iterates over all of the documents' do
568
- returned.each do |doc|
569
- expect(doc).to have_key('field')
570
- end
571
- end
572
- end
573
-
574
- context 'when the cluster is sharded', if: sharded? do
575
-
576
- before do
577
- expect(view).to receive(:special_selector).and_call_original
578
- end
579
-
580
- it 'iterates over all of the documents' do
581
- view.each do |doc|
582
- expect(doc).to have_key('field')
583
- end
584
- end
585
-
586
- context 'when there is a read preference' do
587
-
588
- let(:collection) do
589
- authorized_collection.with(read: { mode: :secondary})
590
- end
591
-
592
- let(:view) do
593
- described_class.new(collection, selector, options)
594
- end
595
-
596
- let(:formatted_read_pref) do
597
- BSON::Document.new(Mongo::ServerSelector.get(mode: :secondary).to_mongos)
598
- end
599
-
600
- it 'adds the formatted read preference to the selector' do
601
- expect(view.send(:query_spec)[:selector][:$readPreference]).to eq(formatted_read_pref)
602
- end
603
- end
604
-
605
- context 'when the read preference is primary' do
606
-
607
- let(:collection) do
608
- authorized_collection.with(read: { mode: :primary})
609
- end
610
-
611
- let(:view) do
612
- described_class.new(collection, selector, options)
613
- end
614
-
615
- it 'does not add the formatted read preference to the selector' do
616
- expect(view.send(:query_spec)[:selector][:$readPreference]).to be(nil)
617
- end
618
- end
619
- end
620
-
621
- context 'when a modifier document is provided' do
622
-
623
- let(:options) do
624
- { :modifiers => {
625
- :$orderby => {'x' => Mongo::Index::ASCENDING }
626
- }
627
- }
628
- end
629
-
630
- before do
631
- expect(view).to receive(:special_selector).and_call_original
632
- end
633
-
634
- it 'creates a special query selector' do
635
- expect(query_spec[:selector][:$orderby]).to eq(options[:modifiers][:$orderby])
636
- end
637
-
638
- it 'iterates over all of the documents' do
639
- view.each do |doc|
640
- expect(doc).to have_key('field')
641
- end
642
- end
643
-
644
- context 'when $explain is specified' do
645
- let(:options) do
646
- { :modifiers => {
647
- :$explain => 1
648
- }
649
- }
650
- end
651
-
652
- let(:explain) do
653
- view.to_a.first
654
- end
655
-
656
- it 'executes an explain' do
657
- expect(explain['cursor'] == 'BasicCursor' ||
658
- explain['queryPlanner']).to be_truthy
659
- end
660
-
661
- end
662
-
663
- context 'when an option is also provided' do
664
-
665
- context 'when $orderby and sort are specified' do
666
-
667
- let(:options) do
668
- { :modifiers => {
669
- :$orderby => { 'x' => Mongo::Index::ASCENDING }
670
- },
671
- :sort => { 'x' => Mongo::Index::DESCENDING }
672
- }
673
- end
674
-
675
- it 'overrides the modifier value with the option value' do
676
- expect(query_spec[:selector][:$orderby]).to eq(options[:sort])
677
- end
678
- end
679
-
680
- context 'when $comment and comment are specified' do
681
-
682
- let(:options) do
683
- { :modifiers => {
684
- :$comment => 'query1'
685
- },
686
- :comment => 'query2'
687
- }
688
- end
689
-
690
- it 'overrides the modifier value with the option value' do
691
- expect(query_spec[:selector][:$comment]).to eq(options[:comment])
692
- end
693
- end
694
-
695
- context 'when $hint and hint are specified' do
696
-
697
- let(:options) do
698
- { :modifiers => {
699
- :$hint => 'x'
700
- },
701
- :hint => 'y'
702
- }
703
- end
704
-
705
- it 'overrides the modifier value with the option value' do
706
- expect(query_spec[:selector][:$hint]).to eq(options[:hint])
707
- end
708
-
709
- end
710
-
711
- context 'when $maxScan and max_scan are specified' do
712
-
713
- let(:options) do
714
- { :modifiers => {
715
- :$maxScan => 4
716
- },
717
- :max_scan => 5
718
- }
719
- end
720
-
721
- it 'overrides the modifier value with the option value' do
722
- expect(query_spec[:selector][:$maxScan]).to eq(options[:max_scan])
723
- end
724
- end
725
-
726
- context 'when $maxTimeMS and max_time_ms are specified' do
727
-
728
- let(:options) do
729
- { :modifiers => {
730
- :$maxTimeMS => 100
731
- },
732
- :max_time_ms => 200
733
- }
734
- end
735
-
736
- it 'overrides the modifier value with the option value' do
737
- expect(query_spec[:selector][:$maxTimeMS]).to eq(options[:max_time_ms])
738
- end
739
- end
740
-
741
- context 'when $query and a selector are specified' do
742
-
743
- let(:selector) do
744
- { 'y' => 1 }
745
- end
746
-
747
- let(:options) do
748
- { :modifiers => {
749
- :$query => { 'field' => 1 }
750
- }
751
- }
752
- end
753
-
754
- it 'overrides the modifier value with the option value' do
755
- expect(query_spec[:selector][:$query]).to eq(options[:modifiers][:$query])
756
- end
757
- end
758
- end
759
- end
760
- end
761
-
762
- context 'when there are no special fields' do
763
-
764
- before do
765
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
766
- expect(spec[:selector]).to eq(selector)
767
- end.and_call_original
768
- end
769
-
770
- it 'creates a normal query spec' do
771
- view.each do |doc|
772
- expect(doc).to have_key('field')
773
- end
774
- end
775
- end
776
-
777
122
  context 'when a block is not provided' do
778
123
 
779
124
  let(:enumerator) do
@@ -793,14 +138,17 @@ describe Mongo::Collection::View do
793
138
  { :batch_size => 1 }
794
139
  end
795
140
 
141
+ let(:cursor) do
142
+ view.instance_variable_get(:@cursor)
143
+ end
144
+
796
145
  before do
797
- e = view.to_enum
798
- e.next
799
- cursor = view.instance_variable_get(:@cursor)
800
- expect(cursor).to receive(:kill_cursors).and_call_original
146
+ view.to_enum.next
147
+ cursor.instance_variable_set(:@cursor_id, 1) unless find_command_enabled?
801
148
  end
802
149
 
803
150
  it 'sends a kill cursors command for the cursor' do
151
+ expect(cursor).to receive(:kill_cursors).and_call_original
804
152
  view.close_query
805
153
  end
806
154
  end
@@ -809,10 +157,10 @@ describe Mongo::Collection::View do
809
157
  describe '#hash' do
810
158
 
811
159
  let(:other) do
812
- described_class.new(authorized_collection, selector, options)
160
+ described_class.new(authorized_collection, filter, options)
813
161
  end
814
162
 
815
- it 'returns a unique value based on collection, selector, options' do
163
+ it 'returns a unique value based on collection, filter, options' do
816
164
  expect(view.hash).to eq(other.hash)
817
165
  end
818
166
 
@@ -823,7 +171,7 @@ describe Mongo::Collection::View do
823
171
  end
824
172
 
825
173
  let(:other) do
826
- described_class.new(other_collection, selector, options)
174
+ described_class.new(other_collection, filter, options)
827
175
  end
828
176
 
829
177
  it 'returns different hash values' do
@@ -831,14 +179,14 @@ describe Mongo::Collection::View do
831
179
  end
832
180
  end
833
181
 
834
- context 'when two views only have different selectors' do
182
+ context 'when two views only have different filter' do
835
183
 
836
- let(:other_selector) do
184
+ let(:other_filter) do
837
185
  { 'name' => 'Emily' }
838
186
  end
839
187
 
840
188
  let(:other) do
841
- described_class.new(authorized_collection, other_selector, options)
189
+ described_class.new(authorized_collection, other_filter, options)
842
190
  end
843
191
 
844
192
  it 'returns different hash values' do
@@ -853,7 +201,7 @@ describe Mongo::Collection::View do
853
201
  end
854
202
 
855
203
  let(:other) do
856
- described_class.new(authorized_collection, selector, other_options)
204
+ described_class.new(authorized_collection, filter, other_options)
857
205
  end
858
206
 
859
207
  it 'returns different hash values' do
@@ -864,53 +212,111 @@ describe Mongo::Collection::View do
864
212
 
865
213
  describe '#initialize' do
866
214
 
867
- let(:options) do
868
- { :limit => 5 }
869
- end
215
+ context 'when the filter is not a valid document' do
870
216
 
871
- it 'sets the collection' do
872
- expect(view.collection).to eq(authorized_collection)
873
- end
217
+ let(:filter) do
218
+ 'y'
219
+ end
874
220
 
875
- it 'sets the selector' do
876
- expect(view.selector).to eq(selector)
221
+ let(:options) do
222
+ { limit: 5 }
223
+ end
224
+
225
+ it 'raises an error' do
226
+ expect do
227
+ view
228
+ end.to raise_error(Mongo::Error::InvalidDocument)
229
+ end
877
230
  end
878
231
 
879
- it 'dups the selector' do
880
- expect(view.selector).not_to be(selector)
232
+ context 'when the filter and options are standard' do
233
+
234
+ let(:filter) do
235
+ { 'name' => 'test' }
236
+ end
237
+
238
+ let(:options) do
239
+ { 'sort' => { 'name' => 1 }}
240
+ end
241
+
242
+ it 'parses a standard filter' do
243
+ expect(view.filter).to eq(filter)
244
+ end
245
+
246
+ it 'parses standard options' do
247
+ expect(view.options).to eq(options)
248
+ end
881
249
  end
882
250
 
883
- it 'sets the options' do
884
- expect(view.options).to eq(options)
251
+ context 'when the filter contains modifiers' do
252
+
253
+ let(:filter) do
254
+ { :$query => { :name => 'test' }, :$comment => 'testing' }
255
+ end
256
+
257
+ let(:options) do
258
+ { :sort => { name: 1 }}
259
+ end
260
+
261
+ it 'parses a standard filter' do
262
+ expect(view.filter).to eq('name' => 'test')
263
+ end
264
+
265
+ it 'parses standard options' do
266
+ expect(view.options).to eq('sort' => { 'name' => 1 }, 'comment' => 'testing')
267
+ end
885
268
  end
886
269
 
887
- it 'dups the options' do
888
- expect(view.options).not_to be(options)
270
+ context 'when the options contain modifiers' do
271
+
272
+ let(:filter) do
273
+ { 'name' => 'test' }
274
+ end
275
+
276
+ let(:options) do
277
+ { :sort => { name: 1 }, :modifiers => { :$comment => 'testing'}}
278
+ end
279
+
280
+ it 'parses a standard filter' do
281
+ expect(view.filter).to eq('name' => 'test')
282
+ end
283
+
284
+ it 'parses standard options' do
285
+ expect(view.options).to eq('sort' => { 'name' => 1 }, 'comment' => 'testing')
286
+ end
889
287
  end
890
288
 
891
- context 'when the selector is not a valid document' do
289
+ context 'when the filter and options both contain modifiers' do
892
290
 
893
- let(:selector) do
894
- 'y'
291
+ let(:filter) do
292
+ { :$query => { 'name' => 'test' }, :$hint => { name: 1 }}
895
293
  end
896
294
 
897
- it 'raises an error' do
898
- expect do
899
- view
900
- end.to raise_error(Mongo::Error::InvalidDocument)
295
+ let(:options) do
296
+ { :sort => { name: 1 }, :modifiers => { :$comment => 'testing' }}
297
+ end
298
+
299
+ it 'parses a standard filter' do
300
+ expect(view.filter).to eq('name' => 'test')
301
+ end
302
+
303
+ it 'parses standard options' do
304
+ expect(view.options).to eq(
305
+ 'sort' => { 'name' => 1 }, 'comment' => 'testing', 'hint' => { 'name' => 1 }
306
+ )
901
307
  end
902
308
  end
903
309
  end
904
310
 
905
311
  describe '#inspect' do
906
312
 
907
- context 'when there is a namespace, selector, and options' do
313
+ context 'when there is a namespace, filter, and options' do
908
314
 
909
315
  let(:options) do
910
- { :limit => 5 }
316
+ { 'limit' => 5 }
911
317
  end
912
318
 
913
- let(:selector) do
319
+ let(:filter) do
914
320
  { 'name' => 'Emily' }
915
321
  end
916
322
 
@@ -922,8 +328,8 @@ describe Mongo::Collection::View do
922
328
  expect(view.inspect).to match(/.*#{authorized_collection.namespace}.*/)
923
329
  end
924
330
 
925
- it 'returns a string containing the selector' do
926
- expect(view.inspect).to match(/.*#{selector.inspect}.*/)
331
+ it 'returns a string containing the filter' do
332
+ expect(view.inspect).to match(/.*#{filter.inspect}.*/)
927
333
  end
928
334
 
929
335
  it 'returns a string containing the options' do