forked from FabienChaynes/mongoid-scroll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollection_view_spec.rb
165 lines (159 loc) · 8.11 KB
/
collection_view_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
require 'spec_helper'
if Object.const_defined?(:Mongo)
describe Mongo::Collection::View do
[Mongoid::Scroll::Cursor, Mongoid::Scroll::Base64EncodedCursor].each do |cursor_type|
context cursor_type do
context 'scrollable' do
subject do
Mongoid.default_client['feed_items'].find
end
it ':scroll' do
expect(subject).to respond_to(:scroll)
end
end
context 'with multiple sort fields' do
subject do
Mongoid.default_client['feed_items'].find.sort(name: 1, value: -1)
end
it 'raises Mongoid::Scroll::Errors::MultipleSortFieldsError' do
expect { subject.scroll(cursor_type) }.to raise_error Mongoid::Scroll::Errors::MultipleSortFieldsError,
/You're attempting to scroll over data with a sort order that includes multiple fields: name, value./
end
end
context 'with different sort fields between the cursor and the criteria' do
subject do
Mongoid.default_client['feed_items'].find.sort(name: -1)
end
it 'raises Mongoid::Scroll::Errors::MismatchedSortFieldsError' do
record = Feed::Item.create!
cursor = cursor_type.from_record(record, field: record.fields['a_string'])
expect(cursor).to be_a cursor_type
error_string = /You're attempting to scroll over data with a sort order that differs between the cursor and the original criteria: field_name, direction./
expect { subject.scroll(cursor, field_type: String) }.to raise_error Mongoid::Scroll::Errors::MismatchedSortFieldsError, error_string
end
end
context 'with no sort' do
subject do
Mongoid.default_client['feed_items'].find
end
it 'adds a default sort by _id' do
expect(subject.scroll(cursor_type).sort).to eq('_id' => 1)
end
end
context 'with data' do
before :each do
10.times do |i|
Mongoid.default_client['feed_items'].insert_one(
a_string: i.to_s,
a_integer: i,
a_datetime: DateTime.mongoize(DateTime.new(2013, i + 1, 21, 1, 42, 3, 'UTC')),
a_date: Date.mongoize(Date.new(2013, i + 1, 21)),
a_time: Time.mongoize(Time.at(Time.now.to_i + i))
)
end
end
context 'default' do
it 'scrolls all' do
records = []
Mongoid.default_client['feed_items'].find.scroll(cursor_type) do |record, _next_cursor|
records << record
end
expect(records.size).to eq 10
expect(records).to eq Mongoid.default_client['feed_items'].find.to_a
end
end
{ a_string: String, a_integer: Integer, a_date: Date, a_datetime: DateTime }.each_pair do |field_name, field_type|
context field_type do
it 'scrolls all with a block' do
records = []
Mongoid.default_client['feed_items'].find.sort(field_name => 1).scroll(cursor_type, field_type: field_type) do |record, _next_cursor|
records << record
end
expect(records.size).to eq 10
expect(records).to eq Mongoid.default_client['feed_items'].find.to_a
end
it 'scrolls all with a break' do
records = []
cursor = nil
Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(5).scroll(cursor_type, field_type: field_type) do |record, next_cursor|
records << record
cursor = next_cursor
expect(cursor).to be_a cursor_type
end
expect(records.size).to eq 5
Mongoid.default_client['feed_items'].find.sort(field_name => 1).scroll(cursor, field_type: field_type) do |record, next_cursor|
records << record
cursor = next_cursor
expect(cursor).to be_a cursor_type
end
expect(records.size).to eq 10
expect(records).to eq Mongoid.default_client['feed_items'].find.to_a
end
it 'scrolls in descending order' do
records = []
Mongoid.default_client['feed_items'].find.sort(field_name => -1).limit(3).scroll(cursor_type, field_type: field_type, field_name: field_name) do |record, _next_cursor|
records << record
end
expect(records.size).to eq 3
expect(records).to eq Mongoid.default_client['feed_items'].find.sort(field_name => -1).limit(3).to_a
end
it 'map' do
record = Mongoid.default_client['feed_items'].find.limit(3).scroll(cursor_type, field_type: field_type, field_name: field_name).map { |r| r }.last
cursor = cursor_type.from_record(record, field_type: field_type, field_name: field_name)
expect(cursor).to_not be nil
expect(cursor.value).to eq record[field_name.to_s]
expect(cursor.tiebreak_id).to eq record['_id']
end
it 'can scroll back with the previous cursor' do
cursor = nil
first_previous_cursor = nil
second_previous_cursor = nil
Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(cursor_type, field_type: field_type) do |_, next_cursor|
cursor = next_cursor
end
Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(cursor, field_type: field_type) do |_, next_cursor, previous_cursor|
cursor = next_cursor
first_previous_cursor = previous_cursor
end
Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(cursor, field_type: field_type) do |_, _, previous_cursor|
second_previous_cursor = previous_cursor
end
records = Mongoid.default_client['feed_items'].find.sort(field_name => 1)
expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(first_previous_cursor, field_type: field_type).to_a).to eq(records.limit(2).to_a)
expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(second_previous_cursor, field_type: field_type).to_a).to eq(records.skip(2).limit(2).to_a)
end
end
end
end
context 'with overlapping data', if: MongoDB.mmapv1? do
before :each do
3.times { Feed::Item.create! a_integer: 5 }
Feed::Item.first.update_attributes!(name: Array(1000).join('a'))
end
it 'natural order is different from order by id' do
# natural order isn't necessarily going to be the same as _id order
# if a document is updated and grows in size, it may need to be relocated and
# thus cause the natural order to change
expect(Feed::Item.order_by('$natural' => 1).to_a).to_not eq Feed::Item.order_by(_id: 1).to_a
end
[{ a_integer: 1 }, { a_integer: -1 }].each do |sort_order|
it "scrolls by #{sort_order}" do
records = []
cursor = nil
Mongoid.default_client['feed_items'].find.sort(sort_order).limit(2).scroll(cursor_type) do |record, next_cursor|
records << record
cursor = next_cursor
end
expect(records.size).to eq 2
Mongoid.default_client['feed_items'].find.sort(sort_order).scroll(cursor) do |record, _next_cursor|
records << record
end
expect(records.size).to eq 3
expect(records).to eq Mongoid.default_client['feed_items'].find.sort(sort_order.merge(_id: sort_order[:a_integer])).to_a
end
end
end
end
end
end
end