mongoid-scroll 0.3.6 → 1.0.0
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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +36 -0
- data/.github/workflows/danger.yml +17 -0
- data/.rubocop_todo.yml +24 -19
- data/CHANGELOG.md +14 -0
- data/Gemfile +10 -16
- data/LICENSE.md +1 -1
- data/README.md +59 -46
- data/RELEASING.md +4 -4
- data/UPGRADING.md +14 -0
- data/examples/mongoid_scroll_feed.rb +2 -8
- data/lib/config/locales/en.yml +8 -0
- data/lib/mongo/scrollable.rb +8 -3
- data/lib/mongoid/criteria/scrollable/cursors.rb +18 -0
- data/lib/mongoid/criteria/scrollable/fields.rb +21 -0
- data/lib/mongoid/criteria/scrollable.rb +13 -12
- data/lib/mongoid/scroll/base64_encoded_cursor.rb +40 -0
- data/lib/mongoid/scroll/base_cursor.rb +123 -0
- data/lib/mongoid/scroll/cursor.rb +24 -87
- data/lib/mongoid/scroll/errors/base.rb +1 -1
- data/lib/mongoid/scroll/errors/invalid_base64_cursor_error.rb +11 -0
- data/lib/mongoid/scroll/errors/invalid_base_cursor_error.rb +8 -0
- data/lib/mongoid/scroll/errors/invalid_cursor_error.rb +1 -1
- data/lib/mongoid/scroll/errors/mismatched_sort_fields_error.rb +15 -0
- data/lib/mongoid/scroll/errors.rb +3 -0
- data/lib/mongoid/scroll/version.rb +1 -1
- data/lib/mongoid-scroll.rb +4 -1
- data/spec/mongo/collection_view_spec.rb +122 -105
- data/spec/mongoid/base64_encoded_cursor_spec.rb +233 -0
- data/spec/mongoid/criteria_spec.rb +236 -197
- data/spec/mongoid/{scroll_cursor_spec.rb → cursor_spec.rb} +48 -12
- data/spec/spec_helper.rb +1 -1
- data/spec/support/feed/item.rb +1 -1
- metadata +19 -13
- data/.travis.yml +0 -35
- data/examples/moped_scroll_feed.rb +0 -45
- data/lib/moped/scrollable.rb +0 -38
- data/spec/moped/query_spec.rb +0 -126
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::Scroll::Base64EncodedCursor do
|
4
|
+
context 'new' do
|
5
|
+
context 'an empty cursor' do
|
6
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6bnVsbCwiZmllbGRfdHlwZSI6IlN0cmluZyIsImZpZWxkX25hbWUiOiJhX3N0cmluZyIsImRpcmVjdGlvbiI6MSwiaW5jbHVkZV9jdXJyZW50IjpmYWxzZSwidGllYnJlYWtfaWQiOm51bGx9' }
|
7
|
+
subject do
|
8
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
9
|
+
end
|
10
|
+
its(:tiebreak_id) { should be_nil }
|
11
|
+
its(:value) { should be_nil }
|
12
|
+
its(:criteria) { should eq({}) }
|
13
|
+
its(:to_s) { should eq(base64_string) }
|
14
|
+
end
|
15
|
+
context 'a string field cursor' do
|
16
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6ImEgc3RyaW5nIiwiZmllbGRfdHlwZSI6IlN0cmluZyIsImZpZWxkX25hbWUiOiJhX3N0cmluZyIsImRpcmVjdGlvbiI6MSwiaW5jbHVkZV9jdXJyZW50IjpmYWxzZSwidGllYnJlYWtfaWQiOiI2NDA2M2RmODA5NDQzNDE3YzdkMmIxMDIifQ==' }
|
17
|
+
let(:a_value) { 'a string' }
|
18
|
+
let(:tiebreak_id) { BSON::ObjectId.from_string('64063df809443417c7d2b102') }
|
19
|
+
let(:criteria) do
|
20
|
+
{
|
21
|
+
'$or' => [
|
22
|
+
{ 'a_string' => { '$gt' => a_value } },
|
23
|
+
{ 'a_string' => a_value, '_id' => { '$gt' => tiebreak_id } }
|
24
|
+
]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
subject do
|
28
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
29
|
+
end
|
30
|
+
its(:value) { should eq a_value }
|
31
|
+
its(:tiebreak_id) { tiebreak_id }
|
32
|
+
its(:value) { should eq a_value }
|
33
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
34
|
+
its(:criteria) { should eq(criteria) }
|
35
|
+
its(:to_s) { should eq(base64_string) }
|
36
|
+
end
|
37
|
+
context 'an id field cursor' do
|
38
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6IjY0MDY0NTg0MDk0NDM0MjgxZmE3MWFiMiIsImZpZWxkX3R5cGUiOiJCU09OOjpPYmplY3RJZCIsImZpZWxkX25hbWUiOiJpZCIsImRpcmVjdGlvbiI6MSwiaW5jbHVkZV9jdXJyZW50IjpmYWxzZSwidGllYnJlYWtfaWQiOiI2NDA2NDU4NDA5NDQzNDI4MWZhNzFhYjIifQ==' }
|
39
|
+
let(:a_value) { BSON::ObjectId('64064584094434281fa71ab2') }
|
40
|
+
let(:tiebreak_id) { a_value }
|
41
|
+
let(:criteria) do
|
42
|
+
{
|
43
|
+
'$or' => [
|
44
|
+
{ 'id' => { '$gt' => a_value } },
|
45
|
+
{ 'id' => a_value, '_id' => { '$gt' => tiebreak_id } }
|
46
|
+
]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
subject do
|
50
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
51
|
+
end
|
52
|
+
its(:value) { should eq a_value }
|
53
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
54
|
+
its(:criteria) { should eq(criteria) }
|
55
|
+
its(:to_s) { should eq(base64_string) }
|
56
|
+
end
|
57
|
+
context 'an integer field cursor' do
|
58
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6MTAsImZpZWxkX3R5cGUiOiJJbnRlZ2VyIiwiZmllbGRfbmFtZSI6ImFfaW50ZWdlciIsImRpcmVjdGlvbiI6MSwiaW5jbHVkZV9jdXJyZW50IjpmYWxzZSwidGllYnJlYWtfaWQiOiI2NDA2M2RmODA5NDQzNDE3YzdkMmIxMDgifQ==' }
|
59
|
+
let(:a_value) { 10 }
|
60
|
+
let(:tiebreak_id) { BSON::ObjectId('64063df809443417c7d2b108') }
|
61
|
+
let(:criteria) do
|
62
|
+
{
|
63
|
+
'$or' => [
|
64
|
+
{ 'a_integer' => { '$gt' => 10 } },
|
65
|
+
{ 'a_integer' => 10, '_id' => { '$gt' => tiebreak_id } }
|
66
|
+
]
|
67
|
+
}
|
68
|
+
end
|
69
|
+
subject do
|
70
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
71
|
+
end
|
72
|
+
its(:value) { should eq a_value }
|
73
|
+
its(:tiebreak_id) { tiebreak_id }
|
74
|
+
its(:value) { should eq a_value }
|
75
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
76
|
+
its(:criteria) { should eq(criteria) }
|
77
|
+
its(:to_s) { should eq(base64_string) }
|
78
|
+
end
|
79
|
+
context 'a date/time field cursor' do
|
80
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6MTM4NzU5MDEyMywiZmllbGRfdHlwZSI6IkRhdGVUaW1lIiwiZmllbGRfbmFtZSI6ImFfZGF0ZXRpbWUiLCJkaXJlY3Rpb24iOjEsImluY2x1ZGVfY3VycmVudCI6ZmFsc2UsInRpZWJyZWFrX2lkIjoiNjQwNjQzYTcwOTQ0MzQyMzlmMmRiZjg2In0=' }
|
81
|
+
let(:a_value) { DateTime.new(2013, 12, 21, 1, 42, 3, 'UTC') }
|
82
|
+
let(:tiebreak_id) { BSON::ObjectId('640643a7094434239f2dbf86') }
|
83
|
+
let(:criteria) do
|
84
|
+
{
|
85
|
+
'$or' => [
|
86
|
+
{ 'a_datetime' => { '$gt' => a_value.utc } },
|
87
|
+
{ 'a_datetime' => a_value.utc, '_id' => { '$gt' => tiebreak_id } }
|
88
|
+
]
|
89
|
+
}
|
90
|
+
end
|
91
|
+
subject do
|
92
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
93
|
+
end
|
94
|
+
its(:value) { should eq a_value }
|
95
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
96
|
+
its(:criteria) { should eq(criteria) }
|
97
|
+
its(:to_s) { should eq(base64_string) }
|
98
|
+
end
|
99
|
+
context 'a date field cursor' do
|
100
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6MTM4NzU4NDAwMCwiZmllbGRfdHlwZSI6IkRhdGUiLCJmaWVsZF9uYW1lIjoiYV9kYXRlIiwiZGlyZWN0aW9uIjoxLCJpbmNsdWRlX2N1cnJlbnQiOmZhbHNlLCJ0aWVicmVha19pZCI6IjY0MDY0MmM5MDk0NDM0MjEyYzRkNDQyMCJ9' }
|
101
|
+
let(:tiebreak_id) { BSON::ObjectId('640642c9094434212c4d4420') }
|
102
|
+
let(:a_value) { Date.new(2013, 12, 21) }
|
103
|
+
let(:criteria) do
|
104
|
+
{
|
105
|
+
'$or' => [
|
106
|
+
{ 'a_date' => { '$gt' => a_value.to_datetime.utc } },
|
107
|
+
{ 'a_date' => a_value.to_datetime.utc, '_id' => { '$gt' => tiebreak_id } }
|
108
|
+
]
|
109
|
+
}
|
110
|
+
end
|
111
|
+
subject do
|
112
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
113
|
+
end
|
114
|
+
its(:value) { should eq a_value }
|
115
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
116
|
+
its(:criteria) { should eq(criteria) }
|
117
|
+
its(:to_s) { should eq(base64_string) }
|
118
|
+
end
|
119
|
+
context 'a time field cursor' do
|
120
|
+
let(:base64_string) { 'eyJ2YWx1ZSI6MTM4NzYwNTcyMywiZmllbGRfdHlwZSI6IlRpbWUiLCJmaWVsZF9uYW1lIjoiYV90aW1lIiwiZGlyZWN0aW9uIjoxLCJpbmNsdWRlX2N1cnJlbnQiOmZhbHNlLCJ0aWVicmVha19pZCI6IjY0MDYzZDRhMDk0NDM0MTY2YmQwNTNlZCJ9' }
|
121
|
+
let(:item_id) { BSON::ObjectId('640636f209443407333b46d4') }
|
122
|
+
let(:a_value) { Time.new(2013, 12, 21, 6, 2, 3, '+00:00').utc }
|
123
|
+
let(:tiebreak_id) { BSON::ObjectId('64063d4a094434166bd053ed') }
|
124
|
+
let(:criteria) do
|
125
|
+
{
|
126
|
+
'$or' => [
|
127
|
+
{ 'a_time' => { '$gt' => a_value } },
|
128
|
+
{ 'a_time' => a_value, '_id' => { '$gt' => tiebreak_id } }
|
129
|
+
]
|
130
|
+
}
|
131
|
+
end
|
132
|
+
subject do
|
133
|
+
Mongoid::Scroll::Base64EncodedCursor.new base64_string
|
134
|
+
end
|
135
|
+
its(:value) { should eq a_value }
|
136
|
+
its(:tiebreak_id) { tiebreak_id }
|
137
|
+
its(:tiebreak_id) { should eq tiebreak_id }
|
138
|
+
its(:criteria) { should eq(criteria) }
|
139
|
+
its(:to_s) { should eq(base64_string) }
|
140
|
+
end
|
141
|
+
context 'an invalid field cursor' do
|
142
|
+
it 'raises ArgumentError' do
|
143
|
+
expect do
|
144
|
+
Mongoid::Scroll::Base64EncodedCursor.new 'invalid', {}
|
145
|
+
end.to raise_error Mongoid::Scroll::Errors::InvalidBase64CursorError
|
146
|
+
end
|
147
|
+
end
|
148
|
+
context 'an invalid cursor' do
|
149
|
+
it 'raises a Mongoid::Scroll::Errors::InvalidBase64CursorError with an invalid Base64 string' do
|
150
|
+
expect { Mongoid::Scroll::Base64EncodedCursor.new 'invalid' }.to raise_error Mongoid::Scroll::Errors::InvalidBase64CursorError, /The cursor supplied is invalid: invalid./
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'raises a Mongoid::Scroll::Errors::InvalidBase64CursorError with an invalid JSON string' do
|
154
|
+
expect { Mongoid::Scroll::Base64EncodedCursor.new 'aW52YWxpZA==' }.to raise_error Mongoid::Scroll::Errors::InvalidBase64CursorError, /The cursor supplied is invalid: aW52YWxpZA==./
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
context 'from_record' do
|
159
|
+
context 'a string field cursor' do
|
160
|
+
let(:field_type) { String }
|
161
|
+
let(:field_value) { 'a string' }
|
162
|
+
let(:field_name) { 'a_string' }
|
163
|
+
let(:feed_item) { Feed::Item.create!(field_name => field_value) }
|
164
|
+
subject do
|
165
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
166
|
+
end
|
167
|
+
its(:value) { should eq field_value }
|
168
|
+
its(:field_name) { should eq field_name }
|
169
|
+
its(:field_type) { should eq field_type.to_s }
|
170
|
+
end
|
171
|
+
context 'an id field cursor' do
|
172
|
+
let(:field_type) { BSON::ObjectId }
|
173
|
+
let(:field_name) { 'id' }
|
174
|
+
let(:feed_item) { Feed::Item.create! }
|
175
|
+
subject do
|
176
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
177
|
+
end
|
178
|
+
its(:value) { should eq feed_item._id }
|
179
|
+
its(:field_type) { should eq field_type.to_s }
|
180
|
+
end
|
181
|
+
context 'an integer field cursor' do
|
182
|
+
let(:field_type) { Integer }
|
183
|
+
let(:field_value) { 10 }
|
184
|
+
let(:field_name) { 'a_integer' }
|
185
|
+
let(:feed_item) { Feed::Item.create!(field_name => field_value) }
|
186
|
+
subject do
|
187
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
188
|
+
end
|
189
|
+
its(:value) { should eq field_value }
|
190
|
+
its(:field_type) { should eq field_type.to_s }
|
191
|
+
end
|
192
|
+
context 'a date/time field cursor' do
|
193
|
+
let(:field_type) { DateTime }
|
194
|
+
let(:field_value) { DateTime.new(2013, 12, 21, 1, 42, 3, 'UTC') }
|
195
|
+
let(:field_name) { 'a_datetime' }
|
196
|
+
let(:feed_item) { Feed::Item.create!(field_name => field_value) }
|
197
|
+
subject do
|
198
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
199
|
+
end
|
200
|
+
its(:value) { should eq field_value }
|
201
|
+
its(:field_type) { should eq field_type.to_s }
|
202
|
+
end
|
203
|
+
context 'a date field cursor' do
|
204
|
+
let(:field_type) { Date }
|
205
|
+
let(:field_value) { Date.new(2013, 12, 21) }
|
206
|
+
let(:field_name) { 'a_date' }
|
207
|
+
let(:feed_item) { Feed::Item.create!(field_name => field_value) }
|
208
|
+
subject do
|
209
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
210
|
+
end
|
211
|
+
its(:value) { should eq field_value }
|
212
|
+
end
|
213
|
+
context 'a time field cursor' do
|
214
|
+
let(:field_type) { Time }
|
215
|
+
let(:field_value) { Time.new(2013, 12, 21, 1, 2, 3) }
|
216
|
+
let(:field_name) { 'a_time' }
|
217
|
+
let(:feed_item) { Feed::Item.create!(field_name => field_value) }
|
218
|
+
subject do
|
219
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: field_name, field_type: field_type
|
220
|
+
end
|
221
|
+
its(:value) { should eq field_value }
|
222
|
+
its(:field_type) { should eq field_type.to_s }
|
223
|
+
end
|
224
|
+
context 'an array field cursor' do
|
225
|
+
let(:feed_item) { Feed::Item.create!(a_array: %w[x y]) }
|
226
|
+
it 'is not supported' do
|
227
|
+
expect do
|
228
|
+
Mongoid::Scroll::Base64EncodedCursor.from_record feed_item, field_name: 'a_array', field_type: Array
|
229
|
+
end.to raise_error Mongoid::Scroll::Errors::UnsupportedFieldTypeError, /The type of the field 'a_array' is not supported: Array./
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|