mongo 2.1.2 → 2.2.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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