ranked-model 0.4.0 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module RankedModel
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.7"
3
3
  end
data/ranked-model.gemspec CHANGED
@@ -9,17 +9,18 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Matthew Beale"]
10
10
  s.email = ["matt.beale@madhatted.com"]
11
11
  s.homepage = "https://github.com/mixonic/ranked-model"
12
- s.summary = %q{An acts_as_sortable replacement built for Rails 3 & 4}
13
- s.description = %q{ranked-model is a modern row sorting library built for Rails 3 & 4. It uses ARel aggressively and is better optimized than most other libraries.}
12
+ s.summary = %q{An acts_as_sortable replacement built for Rails 4.2+}
13
+ s.description = %q{ranked-model is a modern row sorting library built for Rails 4.2+. It uses ARel aggressively and is better optimized than most other libraries.}
14
14
  s.license = 'MIT'
15
15
 
16
- s.add_dependency "activerecord", ">= 3.1.12"
17
- s.add_development_dependency "rspec", "~> 2.13.0"
18
- s.add_development_dependency "sqlite3", "~> 1.3.7"
19
- s.add_development_dependency "genspec", "~> 0.2.8"
20
- s.add_development_dependency "mocha", "~> 0.14.0"
21
- s.add_development_dependency "database_cleaner", "~> 1.2.0"
16
+ s.add_dependency "activerecord", ">= 4.2"
17
+ s.add_development_dependency "rspec", "~> 3"
18
+ s.add_development_dependency "rspec-its"
19
+ s.add_development_dependency "mocha"
20
+ s.add_development_dependency "database_cleaner", "~> 1.7.0"
22
21
  s.add_development_dependency "rake", "~> 10.1.0"
22
+ s.add_development_dependency "appraisal"
23
+ s.add_development_dependency "pry"
23
24
 
24
25
  s.files = `git ls-files`.split("\n")
25
26
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'ColumnDefaultDuck' do
4
+
5
+ it "should raise an error if we try to initialise ranked_model on a column with a default value" do
6
+ expect {
7
+ class ColumnDefaultDuck < ActiveRecord::Base
8
+ include RankedModel
9
+ ranks :size, :with_same => :pond
10
+ end
11
+ }.to raise_error(RankedModel::NonNilColumnDefault, 'Your ranked model column "size" must not have a default value in the database.')
12
+ end
13
+
14
+ it "should not raise an error if we don't have a database connection when checking for default value" do
15
+ begin
16
+ ActiveRecord::Base.remove_connection
17
+
18
+ expect {
19
+ class ColumnDefaultDuck < ActiveRecord::Base
20
+ include RankedModel
21
+ ranks :size, :with_same => :pond
22
+ end
23
+ }.not_to raise_error
24
+ ensure
25
+ ActiveRecord::Base.establish_connection(ENV['DB'].to_sym)
26
+ end
27
+ end
28
+
29
+ end
@@ -8,14 +8,18 @@ describe Duck do
8
8
 
9
9
  subject { @duck }
10
10
 
11
- it { subject.respond_to?(:row_position).should be_true }
12
- it { subject.respond_to?(:row_position=).should be_true }
13
- it { subject.respond_to?(:size_position).should be_true }
14
- it { subject.respond_to?(:size_position=).should be_true }
15
- it { subject.respond_to?(:age_position).should be_true }
16
- it { subject.respond_to?(:age_position=).should be_true }
17
- it { subject.respond_to?(:landing_order_position).should be_true }
18
- it { subject.respond_to?(:landing_order_position=).should be_true }
11
+ it { expect(subject).to respond_to(:row_position) }
12
+ it { expect(subject).to respond_to(:row_position=) }
13
+ it { expect(subject).to respond_to(:row_rank) }
14
+ it { expect(subject).to respond_to(:size_position) }
15
+ it { expect(subject).to respond_to(:size_position=) }
16
+ it { expect(subject).to respond_to(:size_rank) }
17
+ it { expect(subject).to respond_to(:age_position) }
18
+ it { expect(subject).to respond_to(:age_position=) }
19
+ it { expect(subject).to respond_to(:age_rank) }
20
+ it { expect(subject).to respond_to(:landing_order_position) }
21
+ it { expect(subject).to respond_to(:landing_order_position=) }
22
+ it { expect(subject).to respond_to(:landing_order_rank) }
19
23
 
20
24
  end
21
25
 
@@ -44,9 +48,9 @@ describe Duck do
44
48
  }
45
49
  @ducks.each { |name, duck|
46
50
  duck.reload
47
- duck.update_attribute :row_position, 0
48
- duck.update_attribute :size_position, 0
49
- duck.update_attribute :age_position, 0
51
+ duck.update :row_position => 0
52
+ duck.update :size_position => 0
53
+ duck.update :age_position => 0
50
54
  duck.save!
51
55
  }
52
56
  @ducks.each {|name, duck| duck.reload }
@@ -55,8 +59,8 @@ describe Duck do
55
59
  describe "sorting by size on in_shin_pond" do
56
60
 
57
61
  before {
58
- @ducks[:quacky].update_attribute :size_position, 0
59
- @ducks[:wingy].update_attribute :size_position, 2
62
+ @ducks[:quacky].update :size_position => 0
63
+ @ducks[:wingy].update :size_position => 2
60
64
  }
61
65
 
62
66
  subject { Duck.in_shin_pond.rank(:size).to_a }
@@ -72,8 +76,8 @@ describe Duck do
72
76
  describe "sorting by age on Shin pond" do
73
77
 
74
78
  before {
75
- @ducks[:feathers].update_attribute :age_position, 0
76
- @ducks[:wingy].update_attribute :age_position, 0
79
+ @ducks[:feathers].update :age_position => 0
80
+ @ducks[:wingy].update :age_position => 0
77
81
  }
78
82
 
79
83
  subject { Duck.where(:pond => 'Shin').rank(:age).to_a }
@@ -89,10 +93,10 @@ describe Duck do
89
93
  describe "sorting by row" do
90
94
 
91
95
  before {
92
- @ducks[:beaky].update_attribute :row_position, 0
93
- @ducks[:webby].update_attribute :row_position, 2
94
- @ducks[:waddly].update_attribute :row_position, 2
95
- @ducks[:wingy].update_attribute :row_position, 6
96
+ @ducks[:beaky].update :row_position => 0
97
+ @ducks[:webby].update :row_position => 2
98
+ @ducks[:waddly].update :row_position => 2
99
+ @ducks[:wingy].update :row_position => 6
96
100
  }
97
101
 
98
102
  subject { Duck.rank(:row).to_a }
@@ -108,13 +112,13 @@ describe Duck do
108
112
  describe "mixed sorting by" do
109
113
 
110
114
  before {
111
- @ducks[:quacky].update_attribute :size_position, 0
112
- @ducks[:beaky].update_attribute :row_position, 0
113
- @ducks[:webby].update_attribute :row_position, 2
114
- @ducks[:wingy].update_attribute :size_position, 1
115
- @ducks[:waddly].update_attribute :row_position, 2
116
- @ducks[:wingy].update_attribute :row_position, 6
117
- @ducks[:webby].update_attribute :row_position, 6
115
+ @ducks[:quacky].update :size_position => 0
116
+ @ducks[:beaky].update :row_position => 0
117
+ @ducks[:webby].update :row_position => 2
118
+ @ducks[:wingy].update :size_position => 1
119
+ @ducks[:waddly].update :row_position => 2
120
+ @ducks[:wingy].update :row_position => 6
121
+ @ducks[:webby].update :row_position => 6
118
122
  }
119
123
 
120
124
  describe "row" do
@@ -148,9 +152,9 @@ describe Duck do
148
152
  it "doesn't change ranking" do
149
153
  # puts Duck.rank(:age).collect {|duck| "#{duck.name} #{duck.age}" }
150
154
  duck = Duck.rank(:age)[2]
151
- ->{
152
- duck.update_attribute :name, 'New Name'
153
- }.should_not change(duck.reload, :age)
155
+ expect(->{
156
+ duck.update :name => 'New Name'
157
+ }).to_not change(duck.reload, :age)
154
158
  # puts Duck.rank(:age).collect {|duck| "#{duck.name} #{duck.age}" }
155
159
  end
156
160
 
@@ -161,7 +165,7 @@ describe Duck do
161
165
  it "marks record as changed" do
162
166
  duck = Duck.rank(:age)[2]
163
167
  duck.age_position = 1
164
- duck.changed?.should be_true
168
+ expect(duck.changed?).to be true
165
169
  end
166
170
 
167
171
  end
@@ -172,7 +176,7 @@ describe Duck do
172
176
 
173
177
  it "doesnt set empty string" do
174
178
  subject.age_position = ''
175
- subject.age_position.should be_nil
179
+ expect(subject.age_position).to be_nil
176
180
  end
177
181
 
178
182
  end
@@ -183,7 +187,7 @@ describe Duck do
183
187
 
184
188
  before {
185
189
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
186
- @ducks[:wingy].update_attribute :row_position, 2
190
+ @ducks[:wingy].update :row_position => 2
187
191
  }
188
192
 
189
193
  context {
@@ -198,9 +202,9 @@ describe Duck do
198
202
 
199
203
  subject { Duck.rank(:row).collect {|duck| duck.id } }
200
204
 
201
- it { subject[0..1].should == @ordered[0..1] }
205
+ it { expect(subject[0..1]).to eq(@ordered[0..1]) }
202
206
 
203
- it { subject[3..subject.length].should == @ordered[2..@ordered.length] }
207
+ it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
204
208
 
205
209
  }
206
210
 
@@ -210,7 +214,7 @@ describe Duck do
210
214
 
211
215
  before {
212
216
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
213
- @ducks[:wingy].update_attribute :row_position, 0
217
+ @ducks[:wingy].update :row_position => 0
214
218
  }
215
219
 
216
220
  context {
@@ -233,7 +237,38 @@ describe Duck do
233
237
 
234
238
  subject { Duck.rank(:row).collect {|duck| duck.id } }
235
239
 
236
- it { subject[1..subject.length].should == @ordered }
240
+ it { expect(subject[1..subject.length]).to eq(@ordered) }
241
+
242
+ }
243
+
244
+ end
245
+
246
+ describe "second to last" do
247
+
248
+ before {
249
+ [:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
250
+ Duck.where(id: @ducks[name].id).update_all(row: RankedModel::MAX_RANK_VALUE - i)
251
+ @ducks[name].reload
252
+ end
253
+ }
254
+
255
+ context {
256
+
257
+ before { @ducks[:wingy].update :row_position => (@ducks.size - 2) }
258
+
259
+ subject { Duck.ranker(:row).with(Duck.new).current_at_position(@ducks.size - 2).instance }
260
+
261
+ its(:id) { should == @ducks[:wingy].id }
262
+
263
+ }
264
+
265
+ context {
266
+
267
+ before { @ducks[:wingy].update :row_position => :down }
268
+
269
+ subject { Duck.ranker(:row).with(Duck.new).current_at_position(@ducks.size - 2).instance }
270
+
271
+ its(:id) { should == @ducks[:wingy].id }
237
272
 
238
273
  }
239
274
 
@@ -243,7 +278,7 @@ describe Duck do
243
278
 
244
279
  before {
245
280
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
246
- @ducks[:wingy].update_attribute :row_position, (@ducks.size - 1)
281
+ @ducks[:wingy].update :row_position => (@ducks.size - 1)
247
282
  }
248
283
 
249
284
  context {
@@ -274,7 +309,7 @@ describe Duck do
274
309
 
275
310
  subject { Duck.rank(:row).collect {|duck| duck.id } }
276
311
 
277
- it { subject[0..-2].should == @ordered }
312
+ it { expect(subject[0..-2]).to eq(@ordered) }
278
313
 
279
314
  }
280
315
 
@@ -284,7 +319,7 @@ describe Duck do
284
319
 
285
320
  before {
286
321
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
287
- @ducks[:wingy].update_attribute :row_position, :last
322
+ @ducks[:wingy].update :row_position => :last
288
323
  }
289
324
 
290
325
  context {
@@ -315,7 +350,7 @@ describe Duck do
315
350
 
316
351
  subject { Duck.rank(:row).collect {|duck| duck.id } }
317
352
 
318
- it { subject[0..-2].should == @ordered }
353
+ it { expect(subject[0..-2]).to eq(@ordered) }
319
354
 
320
355
  }
321
356
 
@@ -325,7 +360,7 @@ describe Duck do
325
360
 
326
361
  before {
327
362
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
328
- @ducks[:wingy].update_attribute :row_position, 'last'
363
+ @ducks[:wingy].update :row_position => 'last'
329
364
  }
330
365
 
331
366
  context {
@@ -356,7 +391,7 @@ describe Duck do
356
391
 
357
392
  subject { Duck.rank(:row).collect {|duck| duck.id } }
358
393
 
359
- it { subject[0..-2].should == @ordered }
394
+ it { expect(subject[0..-2]).to eq(@ordered) }
360
395
 
361
396
  }
362
397
 
@@ -368,7 +403,7 @@ describe Duck do
368
403
 
369
404
  before {
370
405
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
371
- @ducks[:wingy].update_attribute :row_position, :down
406
+ @ducks[:wingy].update :row_position => :down
372
407
  }
373
408
 
374
409
  context {
@@ -383,9 +418,9 @@ describe Duck do
383
418
 
384
419
  subject { Duck.rank(:row).collect { |duck| duck.id } }
385
420
 
386
- it { subject[0..3].should == @ordered[0..3] }
421
+ it { expect(subject[0..3]).to eq(@ordered[0..3]) }
387
422
 
388
- it { subject[5..subject.length].should == @ordered[4..@ordered.length] }
423
+ it { expect(subject[5..subject.length]).to eq(@ordered[4..@ordered.length]) }
389
424
 
390
425
  }
391
426
 
@@ -395,7 +430,7 @@ describe Duck do
395
430
 
396
431
  before {
397
432
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:quacky].id).collect { |duck| duck.id }
398
- @ducks[:quacky].update_attribute :row_position, :down
433
+ @ducks[:quacky].update :row_position => :down
399
434
  }
400
435
 
401
436
  context {
@@ -410,7 +445,7 @@ describe Duck do
410
445
 
411
446
  subject { Duck.rank(:row).collect { |duck| duck.id } }
412
447
 
413
- it { subject[0..-2].should eq(@ordered) }
448
+ it { expect(subject[0..-2]).to eq(@ordered) }
414
449
 
415
450
  }
416
451
 
@@ -420,7 +455,7 @@ describe Duck do
420
455
 
421
456
  before {
422
457
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:feathers].id).collect { |duck| duck.id }
423
- @ducks[:feathers].update_attribute :row_position, :down
458
+ @ducks[:feathers].update :row_position => :down
424
459
  }
425
460
 
426
461
  context {
@@ -435,7 +470,7 @@ describe Duck do
435
470
 
436
471
  subject { Duck.rank(:row).collect { |duck| duck.id } }
437
472
 
438
- it { subject[0..-2].should eq(@ordered) }
473
+ it { expect(subject[0..-2]).to eq(@ordered) }
439
474
 
440
475
  }
441
476
 
@@ -449,7 +484,7 @@ describe Duck do
449
484
 
450
485
  before {
451
486
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
452
- @ducks[:wingy].update_attribute :row_position, 'down'
487
+ @ducks[:wingy].update :row_position => 'down'
453
488
  }
454
489
 
455
490
  context {
@@ -464,9 +499,9 @@ describe Duck do
464
499
 
465
500
  subject { Duck.rank(:row).collect { |duck| duck.id } }
466
501
 
467
- it { subject[0..3].should == @ordered[0..3] }
502
+ it { expect(subject[0..3]).to eq(@ordered[0..3]) }
468
503
 
469
- it { subject[5..subject.length].should == @ordered[4..@ordered.length] }
504
+ it { expect(subject[5..subject.length]).to eq(@ordered[4..@ordered.length]) }
470
505
 
471
506
  }
472
507
 
@@ -476,7 +511,7 @@ describe Duck do
476
511
 
477
512
  before {
478
513
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:quacky].id).collect { |duck| duck.id }
479
- @ducks[:quacky].update_attribute :row_position, 'down'
514
+ @ducks[:quacky].update :row_position => 'down'
480
515
  }
481
516
 
482
517
  context {
@@ -491,7 +526,7 @@ describe Duck do
491
526
 
492
527
  subject { Duck.rank(:row).collect { |duck| duck.id } }
493
528
 
494
- it { subject[0..-2].should eq(@ordered) }
529
+ it { expect(subject[0..-2]).to eq(@ordered) }
495
530
 
496
531
  }
497
532
 
@@ -501,7 +536,7 @@ describe Duck do
501
536
 
502
537
  before {
503
538
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:feathers].id).collect { |duck| duck.id }
504
- @ducks[:feathers].update_attribute :row_position, 'down'
539
+ @ducks[:feathers].update :row_position => 'down'
505
540
  }
506
541
 
507
542
  context {
@@ -516,7 +551,7 @@ describe Duck do
516
551
 
517
552
  subject { Duck.rank(:row).collect { |duck| duck.id } }
518
553
 
519
- it { subject[0..-2].should eq(@ordered) }
554
+ it { expect(subject[0..-2]).to eq(@ordered) }
520
555
 
521
556
  }
522
557
 
@@ -530,7 +565,7 @@ describe Duck do
530
565
 
531
566
  before {
532
567
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
533
- @ducks[:wingy].update_attribute :row_position, :up
568
+ @ducks[:wingy].update :row_position => :up
534
569
  }
535
570
 
536
571
  context {
@@ -545,9 +580,9 @@ describe Duck do
545
580
 
546
581
  subject { Duck.rank(:row).collect { |duck| duck.id } }
547
582
 
548
- it { subject[0..1].should == @ordered[0..1] }
583
+ it { expect(subject[0..1]).to eq(@ordered[0..1]) }
549
584
 
550
- it { subject[3..subject.length].should == @ordered[2..@ordered.length] }
585
+ it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
551
586
 
552
587
  }
553
588
 
@@ -557,7 +592,7 @@ describe Duck do
557
592
 
558
593
  before {
559
594
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:beaky].id).collect { |duck| duck.id }
560
- @ducks[:beaky].update_attribute :row_position, :up
595
+ @ducks[:beaky].update :row_position => :up
561
596
  }
562
597
 
563
598
  context {
@@ -572,7 +607,7 @@ describe Duck do
572
607
 
573
608
  subject { Duck.rank(:row).collect { |duck| duck.id } }
574
609
 
575
- it { subject[1..subject.length].should eq(@ordered) }
610
+ it { expect(subject[1..subject.length]).to eq(@ordered) }
576
611
 
577
612
  }
578
613
 
@@ -582,7 +617,7 @@ describe Duck do
582
617
 
583
618
  before {
584
619
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:waddly].id).collect { |duck| duck.id }
585
- @ducks[:waddly].update_attribute :row_position, :up
620
+ @ducks[:waddly].update :row_position => :up
586
621
  }
587
622
 
588
623
  context {
@@ -597,12 +632,41 @@ describe Duck do
597
632
 
598
633
  subject { Duck.rank(:row).collect { |duck| duck.id } }
599
634
 
600
- it { subject[1..subject.length].should eq(@ordered) }
635
+ it { expect(subject[1..subject.length]).to eq(@ordered) }
636
+
637
+ }
638
+
639
+ end
640
+
641
+ context "from position without gaps with rebalance" do
642
+
643
+ before {
644
+ [:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
645
+ Duck.where(id: @ducks[name].id).update_all(row: i)
646
+ @ducks[name].reload
647
+ end
648
+ @ducks[:wingy].update :row_position => :up
649
+ }
650
+
651
+ context {
652
+
653
+ subject { Duck.ranker(:row).with(Duck.new).current_at_position(1).instance }
654
+
655
+ its(:id) { should == @ducks[:wingy].id }
656
+
657
+ }
658
+
659
+ context {
660
+
661
+ subject { Duck.ranker(:row).with(Duck.new).current_at_position(2).instance }
662
+
663
+ its(:id) { should == @ducks[:feathers].id }
601
664
 
602
665
  }
603
666
 
604
667
  end
605
668
 
669
+
606
670
  end
607
671
 
608
672
  describe "up with string" do
@@ -611,7 +675,7 @@ describe Duck do
611
675
 
612
676
  before {
613
677
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
614
- @ducks[:wingy].update_attribute :row_position, 'up'
678
+ @ducks[:wingy].update :row_position => 'up'
615
679
  }
616
680
 
617
681
  context {
@@ -626,9 +690,9 @@ describe Duck do
626
690
 
627
691
  subject { Duck.rank(:row).collect { |duck| duck.id } }
628
692
 
629
- it { subject[0..1].should == @ordered[0..1] }
693
+ it { expect(subject[0..1]).to eq(@ordered[0..1]) }
630
694
 
631
- it { subject[3..subject.length].should == @ordered[2..@ordered.length] }
695
+ it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
632
696
 
633
697
  }
634
698
 
@@ -638,7 +702,7 @@ describe Duck do
638
702
 
639
703
  before {
640
704
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:beaky].id).collect { |duck| duck.id }
641
- @ducks[:beaky].update_attribute :row_position, 'up'
705
+ @ducks[:beaky].update :row_position => 'up'
642
706
  }
643
707
 
644
708
  context {
@@ -653,7 +717,7 @@ describe Duck do
653
717
 
654
718
  subject { Duck.rank(:row).collect { |duck| duck.id } }
655
719
 
656
- it { subject[1..subject.length].should eq(@ordered) }
720
+ it { expect(subject[1..subject.length]).to eq(@ordered) }
657
721
 
658
722
  }
659
723
 
@@ -663,7 +727,7 @@ describe Duck do
663
727
 
664
728
  before {
665
729
  @ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:waddly].id).collect { |duck| duck.id }
666
- @ducks[:waddly].update_attribute :row_position, 'up'
730
+ @ducks[:waddly].update :row_position => 'up'
667
731
  }
668
732
 
669
733
  context {
@@ -678,7 +742,7 @@ describe Duck do
678
742
 
679
743
  subject { Duck.rank(:row).collect { |duck| duck.id } }
680
744
 
681
- it { subject[1..subject.length].should eq(@ordered) }
745
+ it { expect(subject[1..subject.length]).to eq(@ordered) }
682
746
 
683
747
  }
684
748
 
@@ -688,6 +752,71 @@ describe Duck do
688
752
 
689
753
  end
690
754
 
755
+ describe "fetching rank for an instance" do
756
+ before {
757
+ [:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
758
+ Duck.where(id: @ducks[name].id).update_all(row: RankedModel::MAX_RANK_VALUE - i)
759
+ @ducks[name].reload
760
+ end
761
+ }
762
+
763
+ context {
764
+ subject { Duck.find_by(id: @ducks[:beaky]).row_rank }
765
+
766
+ it { should == 0 }
767
+ }
768
+
769
+ context {
770
+ subject { Duck.find_by(id: @ducks[:wingy]).row_rank }
771
+
772
+ it { should == 3 }
773
+ }
774
+
775
+ context {
776
+ subject { Duck.find_by(id: @ducks[:quacky]).row_rank }
777
+
778
+ it { should == 5 }
779
+ }
780
+ end
781
+
782
+ describe "when moving between ponds should work when rebalancing" do
783
+ before do
784
+ [:feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
785
+ Duck.where(id: @ducks[name].id)
786
+ .update_all(age: RankedModel::MIN_RANK_VALUE + i, pond: "Boyden")
787
+ end
788
+
789
+ @ducks[:quacky].update!(age_position: 2, pond: "Boyden")
790
+ end
791
+
792
+ it 'rebalances ranks correctly' do
793
+ expect(@ducks[:feathers].reload.age_rank).to eq 0
794
+ expect(@ducks[:quacky].reload.age_rank).to eq 2
795
+ expect(@ducks[:beaky].reload.age_rank).to eq 5
796
+ end
797
+
798
+ context 'when attempting to update position to a non-unique value' do
799
+ before do
800
+ @duck_one = Duck.create(landing_order: RankedModel::MIN_RANK_VALUE,
801
+ lake_id: 42, flock_id: 42)
802
+ # Duck one's landing order will be rebalanced to -715_827_883.
803
+ # Given a unique index on [:landing_order, :lake_id, :flock_id] we
804
+ # verify that the operation succeeds despite the value already being
805
+ # occupied by duck two.
806
+ @duck_two = Duck.create(landing_order: -715_827_883,
807
+ lake_id: 42, flock_id: 42)
808
+ end
809
+
810
+ it 'rebalances ranks correctly' do
811
+ @ducks[:quacky].update!(landing_order_position: :first,
812
+ lake_id: 42, flock_id: 42)
813
+ expect(@ducks[:quacky].reload.landing_order_rank).to eq 0
814
+ expect(@duck_one.reload.landing_order_rank).to eq 1
815
+ expect(@duck_two.reload.landing_order_rank).to eq 2
816
+ end
817
+ end
818
+ end
819
+
691
820
  end
692
821
 
693
822
  describe Duck do
@@ -721,7 +850,7 @@ describe Duck do
721
850
  }
722
851
  @ducks.each { |name, duck|
723
852
  duck.reload
724
- duck.update_attribute :landing_order_position, 0
853
+ duck.update :landing_order_position => 0
725
854
  duck.save!
726
855
  }
727
856
  @ducks.each {|name, duck| duck.reload }
@@ -730,8 +859,8 @@ describe Duck do
730
859
  describe "sorting by landing_order" do
731
860
 
732
861
  before {
733
- @ducks[:quacky].update_attribute :landing_order_position, 0
734
- @ducks[:wingy].update_attribute :landing_order_position, 1
862
+ @ducks[:quacky].update :landing_order_position => 0
863
+ @ducks[:wingy].update :landing_order_position => 1
735
864
  }
736
865
 
737
866
  subject { Duck.in_lake_and_flock(0,0).rank(:landing_order).to_a }
@@ -755,15 +884,15 @@ describe Duck do
755
884
 
756
885
  @previous_ranks = @untouchable_ranks.call
757
886
 
758
- @ducks[:quacky].update_attribute :landing_order_position, 0
759
- @ducks[:wingy].update_attribute :landing_order_position, 1
760
- @ducks[:feathers].update_attribute :landing_order_position, 0
761
- @ducks[:wingy].update_attribute :landing_order_position, 1
887
+ @ducks[:quacky].update :landing_order_position => 0
888
+ @ducks[:wingy].update :landing_order_position => 1
889
+ @ducks[:feathers].update :landing_order_position => 0
890
+ @ducks[:wingy].update :landing_order_position => 1
762
891
  }
763
892
 
764
893
  subject { @untouchable_ranks.call }
765
894
 
766
- it { should == @previous_ranks }
895
+ it { is_expected.to eq(@previous_ranks) }
767
896
 
768
897
  end
769
898