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