cequel 1.4.2 → 1.4.3
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +19 -12
- data/Rakefile +5 -1
- data/lib/cequel/record/data_set_builder.rb +9 -2
- data/lib/cequel/record/record_set.rb +16 -2
- data/lib/cequel/record/tasks.rb +6 -2
- data/lib/cequel/version.rb +1 -1
- data/spec/examples/metal/data_set_spec.rb +113 -106
- data/spec/examples/metal/keyspace_spec.rb +7 -15
- data/spec/examples/record/associations_spec.rb +30 -30
- data/spec/examples/record/callbacks_spec.rb +25 -25
- data/spec/examples/record/dirty_spec.rb +11 -10
- data/spec/examples/record/list_spec.rb +33 -33
- data/spec/examples/record/map_spec.rb +57 -41
- data/spec/examples/record/mass_assignment_spec.rb +5 -5
- data/spec/examples/record/naming_spec.rb +2 -2
- data/spec/examples/record/persistence_spec.rb +23 -23
- data/spec/examples/record/properties_spec.rb +19 -19
- data/spec/examples/record/record_set_spec.rb +155 -151
- data/spec/examples/record/schema_spec.rb +7 -7
- data/spec/examples/record/scoped_spec.rb +2 -2
- data/spec/examples/record/serialization_spec.rb +2 -2
- data/spec/examples/record/set_spec.rb +27 -23
- data/spec/examples/record/validations_spec.rb +13 -13
- data/spec/examples/schema/table_reader_spec.rb +85 -79
- data/spec/examples/schema/table_synchronizer_spec.rb +9 -9
- data/spec/examples/schema/table_updater_spec.rb +17 -17
- data/spec/examples/schema/table_writer_spec.rb +33 -33
- data/spec/examples/type_spec.rb +55 -55
- data/spec/support/helpers.rb +18 -10
- metadata +18 -5
- data/spec/shared/readable_dictionary.rb +0 -192
@@ -33,7 +33,7 @@ describe Cequel::Record::RecordSet do
|
|
33
33
|
|
34
34
|
model :PublishedPost do
|
35
35
|
key :blog_subdomain, :ascii
|
36
|
-
key :published_at, :timeuuid
|
36
|
+
key :published_at, :timeuuid, order: :desc
|
37
37
|
column :permalink, :ascii, index: true
|
38
38
|
end
|
39
39
|
|
@@ -128,23 +128,23 @@ describe Cequel::Record::RecordSet do
|
|
128
128
|
its(:subdomain) { should == 'blog-0' }
|
129
129
|
its(:name) { should == 'Blog 0' }
|
130
130
|
|
131
|
-
it {
|
132
|
-
it {
|
131
|
+
it { is_expected.to be_persisted }
|
132
|
+
it { is_expected.not_to be_transient }
|
133
133
|
|
134
134
|
it 'should cast argument to correct type' do
|
135
|
-
Blog.find('blog-0'.force_encoding('ASCII-8BIT')).
|
135
|
+
expect(Blog.find('blog-0'.force_encoding('ASCII-8BIT'))).to eq(blogs.first)
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should return multiple results as an array from vararg keys' do
|
139
|
-
Blog.find('blog-0', 'blog-1').
|
139
|
+
expect(Blog.find('blog-0', 'blog-1')).to eq(blogs.first(2))
|
140
140
|
end
|
141
141
|
|
142
142
|
it 'should return multiple results as an array from array of keys' do
|
143
|
-
Blog.find(['blog-0', 'blog-1']).
|
143
|
+
expect(Blog.find(['blog-0', 'blog-1'])).to eq(blogs.first(2))
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should return result in an array from one-element array of keys' do
|
147
|
-
Blog.find(['blog-1']).
|
147
|
+
expect(Blog.find(['blog-1'])).to eq([blogs[1]])
|
148
148
|
end
|
149
149
|
|
150
150
|
it 'should raise RecordNotFound if bad argument passed' do
|
@@ -161,14 +161,14 @@ describe Cequel::Record::RecordSet do
|
|
161
161
|
its(:permalink) { should == 'cequel0' }
|
162
162
|
its(:title) { should == 'Cequel 0' }
|
163
163
|
|
164
|
-
it {
|
165
|
-
it {
|
166
|
-
specify { Post.new.
|
167
|
-
specify { Post.new.
|
164
|
+
it { is_expected.to be_persisted }
|
165
|
+
it { is_expected.not_to be_transient }
|
166
|
+
specify { expect(Post.new).not_to be_persisted }
|
167
|
+
specify { expect(Post.new).to be_transient }
|
168
168
|
|
169
169
|
it 'should cast all keys to correct type' do
|
170
|
-
Post['cassandra'.force_encoding('ASCII-8BIT')].
|
171
|
-
find('cequel0'.force_encoding('ASCII-8BIT')).
|
170
|
+
expect(Post['cassandra'.force_encoding('ASCII-8BIT')].
|
171
|
+
find('cequel0'.force_encoding('ASCII-8BIT'))).to be
|
172
172
|
end
|
173
173
|
|
174
174
|
it 'should raise RecordNotFound if bad argument passed' do
|
@@ -177,16 +177,16 @@ describe Cequel::Record::RecordSet do
|
|
177
177
|
end
|
178
178
|
|
179
179
|
it 'should take vararg of values for single key' do
|
180
|
-
Post.find('cassandra', 'cequel0').
|
180
|
+
expect(Post.find('cassandra', 'cequel0')).to eq(posts.first)
|
181
181
|
end
|
182
182
|
|
183
183
|
it 'should take multiple values for key' do
|
184
|
-
Post.find('cassandra', ['cequel0', 'cequel1']).
|
184
|
+
expect(Post.find('cassandra', ['cequel0', 'cequel1'])).to eq(posts.first(2))
|
185
185
|
end
|
186
186
|
|
187
187
|
it 'should use Enumerable#find if block given' do
|
188
|
-
Post['cassandra'].find { |post| post.title.include?('1') }
|
189
|
-
.
|
188
|
+
expect(Post['cassandra'].find { |post| post.title.include?('1') })
|
189
|
+
.to eq(posts[1])
|
190
190
|
end
|
191
191
|
|
192
192
|
it 'should raise error if not enough key values specified' do
|
@@ -202,21 +202,21 @@ describe Cequel::Record::RecordSet do
|
|
202
202
|
|
203
203
|
it 'should not query the database' do
|
204
204
|
disallow_queries!
|
205
|
-
subject.subdomain.
|
205
|
+
expect(subject.subdomain).to eq('blog-0')
|
206
206
|
end
|
207
207
|
|
208
208
|
it 'should lazily query the database when attribute accessed' do
|
209
|
-
subject.name.
|
209
|
+
expect(subject.name).to eq('Blog 0')
|
210
210
|
end
|
211
211
|
|
212
212
|
it 'should get all eager-loadable attributes on first lazy load' do
|
213
213
|
subject.name
|
214
214
|
disallow_queries!
|
215
|
-
subject.description.
|
215
|
+
expect(subject.description).to eq('This is Blog number 0')
|
216
216
|
end
|
217
217
|
|
218
218
|
it 'should cast argument' do
|
219
|
-
subject.subdomain.encoding.name.
|
219
|
+
expect(subject.subdomain.encoding.name).to eq('US-ASCII')
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
@@ -226,31 +226,31 @@ describe Cequel::Record::RecordSet do
|
|
226
226
|
|
227
227
|
it 'should not query the database' do
|
228
228
|
expect(cequel).not_to receive(:execute)
|
229
|
-
subject.blog_subdomain.
|
230
|
-
subject.permalink.
|
229
|
+
expect(subject.blog_subdomain).to eq('cassandra')
|
230
|
+
expect(subject.permalink).to eq('cequel0')
|
231
231
|
end
|
232
232
|
|
233
233
|
it 'should cast all keys to the correct type' do
|
234
|
-
subject.blog_subdomain.encoding.name.
|
235
|
-
subject.permalink.encoding.name.
|
234
|
+
expect(subject.blog_subdomain.encoding.name).to eq('US-ASCII')
|
235
|
+
expect(subject.permalink.encoding.name).to eq('US-ASCII')
|
236
236
|
end
|
237
237
|
|
238
238
|
it 'should lazily query the database when attribute accessed' do
|
239
|
-
subject.title.
|
239
|
+
expect(subject.title).to eq('Cequel 0')
|
240
240
|
end
|
241
241
|
|
242
242
|
it 'should get all eager-loadable attributes on first lazy load' do
|
243
243
|
subject.title
|
244
244
|
expect(cequel).not_to receive(:execute)
|
245
|
-
subject.body.
|
245
|
+
expect(subject.body).to eq('Post number 0')
|
246
246
|
end
|
247
247
|
end
|
248
248
|
|
249
249
|
context 'partially specified compound primary key' do
|
250
250
|
let(:records) { posts }
|
251
251
|
it 'should create partial collection if not all keys specified' do
|
252
|
-
Post['cassandra'].find_each(:batch_size => 2).map(&:title).
|
253
|
-
|
252
|
+
expect(Post['cassandra'].find_each(:batch_size => 2).map(&:title)).
|
253
|
+
to eq((0...5).map { |i| "Cequel #{i}" })
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
@@ -261,7 +261,7 @@ describe Cequel::Record::RecordSet do
|
|
261
261
|
subject { Blog.values_at('blog-0', 'blog-1') }
|
262
262
|
|
263
263
|
it 'should return both specified records' do
|
264
|
-
subject.map(&:subdomain).
|
264
|
+
expect(subject.map(&:subdomain)).to match_array(%w(blog-0 blog-1))
|
265
265
|
end
|
266
266
|
|
267
267
|
it 'should not query the database' do
|
@@ -270,13 +270,14 @@ describe Cequel::Record::RecordSet do
|
|
270
270
|
end
|
271
271
|
|
272
272
|
it 'should load value lazily' do
|
273
|
-
subject.first.name.
|
273
|
+
expect(subject.first.name).to eq('Blog 0')
|
274
274
|
end
|
275
275
|
|
276
276
|
it 'should load values for all referenced records on first access' do
|
277
|
-
|
278
|
-
|
279
|
-
|
277
|
+
expect_statement_count 1 do
|
278
|
+
expect(subject.first.name).to eq('Blog 0')
|
279
|
+
expect(subject.last.name).to eq('Blog 1')
|
280
|
+
end
|
280
281
|
end
|
281
282
|
end
|
282
283
|
|
@@ -285,8 +286,8 @@ describe Cequel::Record::RecordSet do
|
|
285
286
|
subject { Post.values_at('cassandra', 'postgres') }
|
286
287
|
|
287
288
|
it 'should return scope to keys' do
|
288
|
-
subject.map { |post| post.title }.
|
289
|
-
map { |i| ["Cequel #{i}", "Sequel #{i}"] }.flatten
|
289
|
+
expect(subject.map { |post| post.title }).to match_array((0...5).
|
290
|
+
map { |i| ["Cequel #{i}", "Sequel #{i}"] }.flatten)
|
290
291
|
end
|
291
292
|
end
|
292
293
|
|
@@ -297,14 +298,15 @@ describe Cequel::Record::RecordSet do
|
|
297
298
|
|
298
299
|
it 'should return collection of unloaded models' do
|
299
300
|
disallow_queries!
|
300
|
-
subject.map(&:key_values).
|
301
|
-
|
301
|
+
expect(subject.map(&:key_values)).
|
302
|
+
to eq([['cassandra', 'cequel0'], ['orms', 'cequel0']])
|
302
303
|
end
|
303
304
|
|
304
305
|
it 'should lazy-load all records when properties of one accessed' do
|
305
|
-
|
306
|
-
|
307
|
-
|
306
|
+
expect_statement_count 1 do
|
307
|
+
expect(subject.first.title).to eq('Cequel 0')
|
308
|
+
expect(subject.second.title).to eq('Cequel ORM 0')
|
309
|
+
end
|
308
310
|
end
|
309
311
|
end
|
310
312
|
|
@@ -314,14 +316,15 @@ describe Cequel::Record::RecordSet do
|
|
314
316
|
|
315
317
|
it 'should combine partition key with each clustering column' do
|
316
318
|
disallow_queries!
|
317
|
-
subject.map(&:key_values).
|
318
|
-
|
319
|
+
expect(subject.map(&:key_values)).
|
320
|
+
to eq([['cassandra', 'cequel0'], ['cassandra', 'cequel1']])
|
319
321
|
end
|
320
322
|
|
321
323
|
it 'should lazily load all records when one record accessed' do
|
322
|
-
|
323
|
-
|
324
|
-
|
324
|
+
expect_statement_count 1 do
|
325
|
+
expect(subject.first.title).to eq('Cequel 0')
|
326
|
+
expect(subject.second.title).to eq('Cequel 1')
|
327
|
+
end
|
325
328
|
end
|
326
329
|
|
327
330
|
it 'should not allow collection columns to be selected' do
|
@@ -345,7 +348,7 @@ describe Cequel::Record::RecordSet do
|
|
345
348
|
let(:records) { blogs }
|
346
349
|
|
347
350
|
it 'should return all the records' do
|
348
|
-
Blog.all.map(&:subdomain).
|
351
|
+
expect(Blog.all.map(&:subdomain)).to match_array(subdomains)
|
349
352
|
end
|
350
353
|
end
|
351
354
|
|
@@ -353,14 +356,16 @@ describe Cequel::Record::RecordSet do
|
|
353
356
|
let(:records) { [posts, blogs, mongo_posts] }
|
354
357
|
|
355
358
|
it 'should respect :batch_size argument' do
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
+
expect_statement_count 2 do
|
360
|
+
expect(Blog.find_each(:batch_size => 2).map(&:subdomain)).
|
361
|
+
to match_array(subdomains)
|
362
|
+
end
|
359
363
|
end
|
360
364
|
|
361
365
|
it 'should iterate over all keys' do
|
362
|
-
Post.find_each(:batch_size => 2).map(&:title).
|
366
|
+
expect(Post.find_each(:batch_size => 2).map(&:title)).to match_array(
|
363
367
|
(0...5).flat_map { |i| ["Cequel #{i}", "Sequel #{i}", "Mongoid #{i}"] }
|
368
|
+
)
|
364
369
|
end
|
365
370
|
|
366
371
|
describe "hydration" do
|
@@ -387,8 +392,9 @@ describe Cequel::Record::RecordSet do
|
|
387
392
|
let!(:records) { [posts, blogs, mongo_posts] }
|
388
393
|
|
389
394
|
it 'should respect :batch_size argument' do
|
390
|
-
|
391
|
-
|
395
|
+
expect_statement_count 2 do
|
396
|
+
Blog.find_in_batches(:batch_size => 2){|a_batch| next }
|
397
|
+
end
|
392
398
|
end
|
393
399
|
|
394
400
|
it 'should iterate over all keys' do
|
@@ -400,7 +406,7 @@ describe Cequel::Record::RecordSet do
|
|
400
406
|
found_posts += recs
|
401
407
|
}
|
402
408
|
expect(found_posts).to include(*expected_posts)
|
403
|
-
expect(found_posts).to
|
409
|
+
expect(found_posts.length).to eq(expected_posts.size)
|
404
410
|
end
|
405
411
|
|
406
412
|
it 'should iterate over batches' do
|
@@ -436,21 +442,21 @@ describe Cequel::Record::RecordSet do
|
|
436
442
|
|
437
443
|
describe '#[]' do
|
438
444
|
it 'should return partial collection' do
|
439
|
-
Post['cassandra'].find_each(:batch_size => 2).map(&:title).
|
440
|
-
|
445
|
+
expect(Post['cassandra'].find_each(:batch_size => 2).map(&:title)).
|
446
|
+
to eq((0...5).map { |i| "Cequel #{i}" })
|
441
447
|
end
|
442
448
|
|
443
449
|
it 'should cast arguments correctly' do
|
444
|
-
Post['cassandra'.force_encoding('ASCII-8BIT')].
|
445
|
-
find_each(:batch_size => 2).map(&:title).
|
446
|
-
|
450
|
+
expect(Post['cassandra'.force_encoding('ASCII-8BIT')].
|
451
|
+
find_each(:batch_size => 2).map(&:title)).
|
452
|
+
to eq((0...5).map { |i| "Cequel #{i}" })
|
447
453
|
end
|
448
454
|
end
|
449
455
|
|
450
456
|
describe '#/' do
|
451
457
|
it 'should behave like #[]' do
|
452
|
-
(Post / 'cassandra').find_each(:batch_size => 2).map(&:title).
|
453
|
-
|
458
|
+
expect((Post / 'cassandra').find_each(:batch_size => 2).map(&:title)).
|
459
|
+
to eq((0...5).map { |i| "Cequel #{i}" })
|
454
460
|
end
|
455
461
|
end
|
456
462
|
|
@@ -458,18 +464,18 @@ describe Cequel::Record::RecordSet do
|
|
458
464
|
let(:records) { [posts, published_posts] }
|
459
465
|
|
460
466
|
it 'should return collection after given key' do
|
461
|
-
Post['cassandra'].after('cequel1').map(&:title).
|
462
|
-
|
467
|
+
expect(Post['cassandra'].after('cequel1').map(&:title)).
|
468
|
+
to eq((2...5).map { |i| "Cequel #{i}" })
|
463
469
|
end
|
464
470
|
|
465
471
|
it 'should cast argument' do
|
466
|
-
Post['cassandra'].after('cequel1'.force_encoding('ASCII-8BIT')).
|
467
|
-
map(&:title).
|
472
|
+
expect(Post['cassandra'].after('cequel1'.force_encoding('ASCII-8BIT')).
|
473
|
+
map(&:title)).to eq((2...5).map { |i| "Cequel #{i}" })
|
468
474
|
end
|
469
475
|
|
470
476
|
it 'should query Time range for Timeuuid key' do
|
471
|
-
PublishedPost['cassandra'].after(now - 3.minutes).map(&:permalink).
|
472
|
-
|
477
|
+
expect(PublishedPost['cassandra'].after(now - 3.minutes).map(&:permalink)).
|
478
|
+
to eq(%w(cequel4 cequel3 cequel2))
|
473
479
|
end
|
474
480
|
end
|
475
481
|
|
@@ -477,18 +483,18 @@ describe Cequel::Record::RecordSet do
|
|
477
483
|
let(:records) { [posts, published_posts] }
|
478
484
|
|
479
485
|
it 'should return collection starting with given key' do
|
480
|
-
Post['cassandra'].from('cequel1').map(&:title).
|
481
|
-
|
486
|
+
expect(Post['cassandra'].from('cequel1').map(&:title)).
|
487
|
+
to eq((1...5).map { |i| "Cequel #{i}" })
|
482
488
|
end
|
483
489
|
|
484
490
|
it 'should cast argument' do
|
485
|
-
Post['cassandra'].from('cequel1'.force_encoding('ASCII-8BIT')).
|
486
|
-
map(&:title).
|
491
|
+
expect(Post['cassandra'].from('cequel1'.force_encoding('ASCII-8BIT')).
|
492
|
+
map(&:title)).to eq((1...5).map { |i| "Cequel #{i}" })
|
487
493
|
end
|
488
494
|
|
489
495
|
it 'should query Time range for Timeuuid key' do
|
490
|
-
PublishedPost['cassandra'].from(now - 3.minutes).map(&:permalink).
|
491
|
-
|
496
|
+
expect(PublishedPost['cassandra'].from(now - 3.minutes).map(&:permalink)).
|
497
|
+
to eq(%w(cequel4 cequel3 cequel2 cequel1))
|
492
498
|
end
|
493
499
|
|
494
500
|
it 'should raise ArgumentError when called on partition key' do
|
@@ -501,18 +507,18 @@ describe Cequel::Record::RecordSet do
|
|
501
507
|
let(:records) { [posts, published_posts] }
|
502
508
|
|
503
509
|
it 'should return collection before given key' do
|
504
|
-
Post['cassandra'].before('cequel3').map(&:title).
|
505
|
-
|
510
|
+
expect(Post['cassandra'].before('cequel3').map(&:title)).
|
511
|
+
to eq((0...3).map { |i| "Cequel #{i}" })
|
506
512
|
end
|
507
513
|
|
508
514
|
it 'should query Time range for Timeuuid key' do
|
509
|
-
PublishedPost['cassandra'].before(now - 1.minute).map(&:permalink).
|
510
|
-
|
515
|
+
expect(PublishedPost['cassandra'].before(now - 1.minute).map(&:permalink)).
|
516
|
+
to eq(%w(cequel2 cequel1 cequel0))
|
511
517
|
end
|
512
518
|
|
513
519
|
it 'should cast argument' do
|
514
|
-
Post['cassandra'].before('cequel3'.force_encoding('ASCII-8BIT')).
|
515
|
-
map(&:title).
|
520
|
+
expect(Post['cassandra'].before('cequel3'.force_encoding('ASCII-8BIT')).
|
521
|
+
map(&:title)).to eq((0...3).map { |i| "Cequel #{i}" })
|
516
522
|
end
|
517
523
|
end
|
518
524
|
|
@@ -520,18 +526,18 @@ describe Cequel::Record::RecordSet do
|
|
520
526
|
let(:records) { [posts, published_posts] }
|
521
527
|
|
522
528
|
it 'should return collection up to given key' do
|
523
|
-
Post['cassandra'].upto('cequel3').map(&:title).
|
524
|
-
|
529
|
+
expect(Post['cassandra'].upto('cequel3').map(&:title)).
|
530
|
+
to eq((0..3).map { |i| "Cequel #{i}" })
|
525
531
|
end
|
526
532
|
|
527
533
|
it 'should cast argument' do
|
528
|
-
Post['cassandra'].upto('cequel3'.force_encoding('ASCII-8BIT')).
|
529
|
-
map(&:title).
|
534
|
+
expect(Post['cassandra'].upto('cequel3'.force_encoding('ASCII-8BIT')).
|
535
|
+
map(&:title)).to eq((0..3).map { |i| "Cequel #{i}" })
|
530
536
|
end
|
531
537
|
|
532
538
|
it 'should query Time range for Timeuuid key' do
|
533
|
-
PublishedPost['cassandra'].upto(now - 1.minute).map(&:permalink).
|
534
|
-
|
539
|
+
expect(PublishedPost['cassandra'].upto(now - 1.minute).map(&:permalink)).
|
540
|
+
to eq(%w(cequel3 cequel2 cequel1 cequel0))
|
535
541
|
end
|
536
542
|
end
|
537
543
|
|
@@ -539,68 +545,68 @@ describe Cequel::Record::RecordSet do
|
|
539
545
|
let(:records) { [posts, published_posts] }
|
540
546
|
|
541
547
|
it 'should return collection with inclusive upper bound' do
|
542
|
-
Post['cassandra'].in('cequel1'..'cequel3').map(&:title).
|
543
|
-
|
548
|
+
expect(Post['cassandra'].in('cequel1'..'cequel3').map(&:title)).
|
549
|
+
to eq((1..3).map { |i| "Cequel #{i}" })
|
544
550
|
end
|
545
551
|
|
546
552
|
it 'should cast arguments' do
|
547
|
-
Post['cassandra'].in('cequel1'.force_encoding('ASCII-8BIT')..
|
553
|
+
expect(Post['cassandra'].in('cequel1'.force_encoding('ASCII-8BIT')..
|
548
554
|
'cequel3'.force_encoding('ASCII-8BIT')).
|
549
|
-
map(&:title).
|
555
|
+
map(&:title)).to eq((1..3).map { |i| "Cequel #{i}" })
|
550
556
|
end
|
551
557
|
|
552
558
|
it 'should return collection with exclusive upper bound' do
|
553
|
-
Post['cassandra'].in('cequel1'...'cequel3').map(&:title).
|
554
|
-
|
559
|
+
expect(Post['cassandra'].in('cequel1'...'cequel3').map(&:title)).
|
560
|
+
to eq((1...3).map { |i| "Cequel #{i}" })
|
555
561
|
end
|
556
562
|
|
557
563
|
it 'should query Time range for Timeuuid key' do
|
558
|
-
PublishedPost['cassandra'].in((now - 3.minutes)..(now - 1.minute)).
|
559
|
-
map(&:permalink).
|
564
|
+
expect(PublishedPost['cassandra'].in((now - 3.minutes)..(now - 1.minute)).
|
565
|
+
map(&:permalink)).to eq(%w(cequel3 cequel2 cequel1))
|
560
566
|
end
|
561
567
|
|
562
568
|
it 'should query Time range for Timeuuid key with exclusive upper bound' do
|
563
|
-
PublishedPost['cassandra'].in((now - 3.minutes)...(now - 1.minute)).
|
564
|
-
map(&:permalink).
|
569
|
+
expect(PublishedPost['cassandra'].in((now - 3.minutes)...(now - 1.minute)).
|
570
|
+
map(&:permalink)).to eq(%w(cequel2 cequel1))
|
565
571
|
end
|
566
572
|
end
|
567
573
|
|
568
574
|
describe '#reverse' do
|
569
|
-
let(:records) { [
|
575
|
+
let(:records) { [published_posts, comments] }
|
570
576
|
|
571
577
|
it 'should not call the database' do
|
572
578
|
disallow_queries!
|
573
|
-
|
579
|
+
PublishedPost['cassandra'].reverse
|
574
580
|
end
|
575
581
|
|
576
582
|
it 'should return collection in reverse' do
|
577
|
-
|
578
|
-
|
583
|
+
expect(PublishedPost['cassandra'].reverse.map(&:permalink)).
|
584
|
+
to eq((0...5).map { |i| "cequel#{i}" })
|
579
585
|
end
|
580
586
|
|
581
587
|
it 'should batch iterate over collection in reverse' do
|
582
|
-
|
583
|
-
|
588
|
+
expect(PublishedPost['cassandra'].reverse.find_each(:batch_size => 2).map(&:permalink)).
|
589
|
+
to eq((0...5).map { |i| "cequel#{i}" })
|
584
590
|
end
|
585
591
|
|
586
592
|
it 'should raise an error if range key is a partition key' do
|
587
|
-
expect {
|
593
|
+
expect { PublishedPost.all.reverse }.to raise_error(Cequel::Record::IllegalQuery)
|
588
594
|
end
|
589
595
|
|
590
596
|
it 'should use the correct ordering column in deeply nested models' do
|
591
|
-
Comment['cassandra']['cequel0'].reverse.map(&:body).
|
592
|
-
|
597
|
+
expect(Comment['cassandra']['cequel0'].reverse.map(&:body)).
|
598
|
+
to eq((0...5).map { |i| "Comment #{i}" }.reverse)
|
593
599
|
end
|
594
600
|
end
|
595
601
|
|
596
602
|
describe 'last' do
|
597
603
|
it 'should return the last instance' do
|
598
|
-
Post['cassandra'].last.title.
|
604
|
+
expect(Post['cassandra'].last.title).to eq("Cequel 4")
|
599
605
|
end
|
600
606
|
|
601
607
|
it 'should return the last N instances if specified' do
|
602
|
-
Post['cassandra'].last(3).map(&:title).
|
603
|
-
|
608
|
+
expect(Post['cassandra'].last(3).map(&:title)).
|
609
|
+
to eq(["Cequel 2", "Cequel 3", "Cequel 4"])
|
604
610
|
end
|
605
611
|
end
|
606
612
|
|
@@ -609,16 +615,16 @@ describe Cequel::Record::RecordSet do
|
|
609
615
|
|
610
616
|
context 'with no arguments' do
|
611
617
|
it 'should return an arbitrary record' do
|
612
|
-
subdomains.
|
618
|
+
expect(subdomains).to include(Blog.first.subdomain)
|
613
619
|
end
|
614
620
|
end
|
615
621
|
|
616
622
|
context 'with a given size' do
|
617
623
|
subject { Blog.first(2) }
|
618
624
|
|
619
|
-
it {
|
620
|
-
|
621
|
-
specify { (subject.map(&:subdomain) & subdomains).
|
625
|
+
it { is_expected.to be_a(Array) }
|
626
|
+
its(:size) { should be(2) }
|
627
|
+
specify { expect((subject.map(&:subdomain) & subdomains).size).to be(2) }
|
622
628
|
end
|
623
629
|
end
|
624
630
|
|
@@ -626,7 +632,7 @@ describe Cequel::Record::RecordSet do
|
|
626
632
|
let(:records) { blogs }
|
627
633
|
|
628
634
|
it 'should return the number of records requested' do
|
629
|
-
Blog.limit(2).
|
635
|
+
expect(Blog.limit(2).length).to be(2)
|
630
636
|
end
|
631
637
|
end
|
632
638
|
|
@@ -636,8 +642,8 @@ describe Cequel::Record::RecordSet do
|
|
636
642
|
context 'with no block' do
|
637
643
|
subject { Blog.select(:subdomain, :name).first }
|
638
644
|
|
639
|
-
it {
|
640
|
-
it {
|
645
|
+
it { is_expected.to be_loaded(:name) }
|
646
|
+
it { is_expected.not_to be_loaded(:description) }
|
641
647
|
specify { expect { subject.name }.to_not raise_error }
|
642
648
|
specify { expect { subject.description }.
|
643
649
|
to raise_error(Cequel::Record::MissingAttributeError) }
|
@@ -645,8 +651,8 @@ describe Cequel::Record::RecordSet do
|
|
645
651
|
|
646
652
|
context 'with block' do
|
647
653
|
it 'should delegate to the Enumerable method' do
|
648
|
-
Blog.all.select { |p| p.subdomain[/\d+/].to_i.even? }.
|
649
|
-
map(&:subdomain).
|
654
|
+
expect(Blog.all.select { |p| p.subdomain[/\d+/].to_i.even? }.
|
655
|
+
map(&:subdomain)).to match_array(%w(blog-0 blog-2))
|
650
656
|
end
|
651
657
|
end
|
652
658
|
end
|
@@ -702,13 +708,13 @@ describe Cequel::Record::RecordSet do
|
|
702
708
|
|
703
709
|
context 'secondary indexed column' do
|
704
710
|
it 'should query for secondary indexed columns with two arguments' do
|
705
|
-
Post.where(:author_id, uuids.first).map(&:permalink).
|
706
|
-
|
711
|
+
expect(Post.where(:author_id, uuids.first).map(&:permalink)).
|
712
|
+
to eq(%w(cequel0 cequel2 cequel4))
|
707
713
|
end
|
708
714
|
|
709
715
|
it 'should query for secondary indexed columns with hash argument' do
|
710
|
-
Post.where(author_id: uuids.first).map(&:permalink).
|
711
|
-
|
716
|
+
expect(Post.where(author_id: uuids.first).map(&:permalink)).
|
717
|
+
to eq(%w(cequel0 cequel2 cequel4))
|
712
718
|
end
|
713
719
|
|
714
720
|
it 'should not allow multiple columns in the arguments' do
|
@@ -723,27 +729,25 @@ describe Cequel::Record::RecordSet do
|
|
723
729
|
end
|
724
730
|
|
725
731
|
it 'should cast argument for column' do
|
726
|
-
Post.where(:author_id, uuids.first.to_s).map(&:permalink).
|
727
|
-
|
732
|
+
expect(Post.where(:author_id, uuids.first.to_s).map(&:permalink)).
|
733
|
+
to eq(%w(cequel0 cequel2 cequel4))
|
728
734
|
end
|
729
735
|
end
|
730
736
|
|
731
737
|
context 'mixing keys and secondary-indexed columns' do
|
732
738
|
it 'should allow mixture in hash argument' do
|
733
|
-
Post.where(blog_subdomain: 'cassandra', author_id: uuids.first).
|
734
|
-
|
739
|
+
expect(Post.where(blog_subdomain: 'cassandra', author_id: uuids.first).
|
740
|
+
entries.length).to be(3)
|
735
741
|
end
|
736
742
|
|
737
743
|
it 'should allow mixture in chain with primary first' do
|
738
|
-
Post.where(blog_subdomain: 'cassandra')
|
739
|
-
.where(author_id: uuids.first)
|
740
|
-
.should have(3).entries
|
744
|
+
expect(Post.where(blog_subdomain: 'cassandra')
|
745
|
+
.where(author_id: uuids.first).entries.length).to be(3)
|
741
746
|
end
|
742
747
|
|
743
748
|
it 'should allow mixture in chain with secondary first' do
|
744
|
-
Post.where(author_id: uuids.first)
|
745
|
-
.where(blog_subdomain: 'cassandra')
|
746
|
-
.should have(3).entries
|
749
|
+
expect(Post.where(author_id: uuids.first)
|
750
|
+
.where(blog_subdomain: 'cassandra').entries.length).to be(3)
|
747
751
|
end
|
748
752
|
end
|
749
753
|
|
@@ -774,14 +778,14 @@ describe Cequel::Record::RecordSet do
|
|
774
778
|
let(:records) { blogs }
|
775
779
|
|
776
780
|
it 'should count records' do
|
777
|
-
Blog.count.
|
781
|
+
expect(Blog.count).to eq(3)
|
778
782
|
end
|
779
783
|
end
|
780
784
|
|
781
785
|
describe 'scope methods' do
|
782
786
|
it 'should delegate unknown methods to class singleton with current scope' do
|
783
|
-
Post['cassandra'].latest(3).map(&:permalink).
|
784
|
-
|
787
|
+
expect(Post['cassandra'].latest(3).map(&:permalink)).
|
788
|
+
to eq(%w(cequel4 cequel3 cequel2))
|
785
789
|
end
|
786
790
|
|
787
791
|
it 'should raise NoMethodError if undefined method called' do
|
@@ -794,23 +798,23 @@ describe Cequel::Record::RecordSet do
|
|
794
798
|
|
795
799
|
it 'should be able to update with no scoping' do
|
796
800
|
Post.update_all(title: 'Same Title')
|
797
|
-
Post.all.map(&:title).
|
801
|
+
expect(Post.all.map(&:title)).to eq(Array.new(posts.length) { 'Same Title' })
|
798
802
|
end
|
799
803
|
|
800
804
|
it 'should update posts with scoping' do
|
801
805
|
Post['cassandra'].update_all(title: 'Same Title')
|
802
|
-
Post['cassandra'].map(&:title).
|
803
|
-
|
804
|
-
Post['postgres'].map(&:title).
|
806
|
+
expect(Post['cassandra'].map(&:title)).
|
807
|
+
to eq(Array.new(cassandra_posts.length) { 'Same Title' })
|
808
|
+
expect(Post['postgres'].map(&:title)).to eq(postgres_posts.map(&:title))
|
805
809
|
end
|
806
810
|
|
807
811
|
it 'should update fully specified collection' do
|
808
812
|
Post['cassandra'].values_at('cequel0', 'cequel1', 'cequel2').
|
809
813
|
update_all(title: 'Same Title')
|
810
|
-
Post['cassandra'].values_at('cequel0', 'cequel1', 'cequel2').map(&:title).
|
811
|
-
|
812
|
-
Post['cassandra'].values_at('cequel3', 'cequel4').map(&:title).
|
813
|
-
|
814
|
+
expect(Post['cassandra'].values_at('cequel0', 'cequel1', 'cequel2').map(&:title)).
|
815
|
+
to eq(Array.new(3) { 'Same Title' })
|
816
|
+
expect(Post['cassandra'].values_at('cequel3', 'cequel4').map(&:title)).
|
817
|
+
to eq(cassandra_posts.drop(3).map(&:title))
|
814
818
|
end
|
815
819
|
end
|
816
820
|
|
@@ -819,19 +823,19 @@ describe Cequel::Record::RecordSet do
|
|
819
823
|
|
820
824
|
it 'should be able to delete with no scoping' do
|
821
825
|
Post.delete_all
|
822
|
-
Post.count.
|
826
|
+
expect(Post.count).to be_zero
|
823
827
|
end
|
824
828
|
|
825
829
|
it 'should be able to delete with scoping' do
|
826
830
|
Post['postgres'].delete_all
|
827
|
-
Post['postgres'].count.
|
828
|
-
Post['cassandra'].count.
|
831
|
+
expect(Post['postgres'].count).to be_zero
|
832
|
+
expect(Post['cassandra'].count).to eq(cassandra_posts.length)
|
829
833
|
end
|
830
834
|
|
831
835
|
it 'should be able to delete fully specified collection' do
|
832
836
|
Post['postgres'].values_at('sequel0', 'sequel1').delete_all
|
833
|
-
Post['postgres'].map(&:permalink).
|
834
|
-
|
837
|
+
expect(Post['postgres'].map(&:permalink)).
|
838
|
+
to eq(postgres_posts.drop(2).map(&:permalink))
|
835
839
|
end
|
836
840
|
end
|
837
841
|
|
@@ -840,19 +844,19 @@ describe Cequel::Record::RecordSet do
|
|
840
844
|
|
841
845
|
it 'should be able to delete with no scoping' do
|
842
846
|
Post.destroy_all
|
843
|
-
Post.count.
|
847
|
+
expect(Post.count).to be_zero
|
844
848
|
end
|
845
849
|
|
846
850
|
it 'should be able to delete with scoping' do
|
847
851
|
Post['postgres'].destroy_all
|
848
|
-
Post['postgres'].count.
|
849
|
-
Post['cassandra'].count.
|
852
|
+
expect(Post['postgres'].count).to be_zero
|
853
|
+
expect(Post['cassandra'].count).to eq(cassandra_posts.length)
|
850
854
|
end
|
851
855
|
|
852
856
|
it 'should be able to delete fully specified collection' do
|
853
857
|
Post['postgres'].values_at('sequel0', 'sequel1').destroy_all
|
854
|
-
Post['postgres'].map(&:permalink).
|
855
|
-
|
858
|
+
expect(Post['postgres'].map(&:permalink)).
|
859
|
+
to eq(postgres_posts.drop(2).map(&:permalink))
|
856
860
|
end
|
857
861
|
end
|
858
862
|
|