Commit 96e1bac3 authored by Alex Kalderimis's avatar Alex Kalderimis

Remove tests of private members

These are tested by their behavior
parent 66444cd3
......@@ -323,6 +323,14 @@ module RelativePositioning
end
end
def context(object, ignoring: nil)
return unless object
c = ItemContext.new(object, range)
c.ignoring = ignoring
c
end
private
def gap_too_small?(pos_a, pos_b)
......@@ -383,14 +391,6 @@ module RelativePositioning
end
end
def context(object, ignoring: nil)
return unless object
c = ItemContext.new(object, range)
c.ignoring = ignoring
c
end
# This method takes two integer values (positions) and
# calculates the position between them. The range is huge as
# the maximum integer value is 2147483647.
......@@ -463,7 +463,7 @@ module RelativePositioning
private
# @api private
def gap_size(object, gaps:, at_end:, starting_from:)
def gap_size(context, gaps:, at_end:, starting_from:)
total_width = IDEAL_DISTANCE * gaps
size = if at_end && starting_from + total_width >= MAX_POSITION
(MAX_POSITION - starting_from) / gaps
......@@ -473,23 +473,17 @@ module RelativePositioning
IDEAL_DISTANCE
end
# Shift max elements leftwards if there isn't enough space
return [size, starting_from] if size >= MIN_GAP
order = at_end ? :desc : :asc
terminus = object
.send(:relative_siblings) # rubocop:disable GitlabSecurity/PublicSend
.where('relative_position IS NOT NULL')
.order(relative_position: order)
.first
if at_end
terminus.move_sequence_before(true)
max_relative_position = terminus.reset.relative_position
terminus = context.max_sibling
terminus.shift_left
max_relative_position = terminus.relative_position
[[(MAX_POSITION - max_relative_position) / gaps, IDEAL_DISTANCE].min, max_relative_position]
else
terminus.move_sequence_after(true)
min_relative_position = terminus.reset.relative_position
terminus = min_sibling
terminus.shift_right
min_relative_position = terminus.relative_position
[[(min_relative_position - MIN_POSITION) / gaps, IDEAL_DISTANCE].min, min_relative_position]
end
end
......@@ -507,8 +501,10 @@ module RelativePositioning
objects = objects.reject(&:relative_position)
return 0 if objects.empty?
representative = objects.first
number_of_gaps = objects.size # 1 to the nearest neighbour, and one between each
mover = Mover.new(START_POSITION, (MIN_POSITION..MAX_POSITION))
representative = mover.context(objects.first)
position = if at_end
representative.max_relative_position
else
......
......@@ -17,6 +17,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do
describe '.move_nulls_to_end' do
let(:item3) { create_item }
let(:sibling_query) { item1.class.relative_positioning_query_base(item1) }
it 'moves items with null relative_position to the end' do
item1.update!(relative_position: 1000)
......@@ -28,10 +29,9 @@ RSpec.shared_examples 'a class that supports relative positioning' do
expect(items.sort_by(&:relative_position)).to eq(items)
expect(item1.relative_position).to be(1000)
expect(item1.prev_relative_position).to be_nil
expect(item1.next_relative_position).to eq(item2.relative_position)
expect(item2.next_relative_position).to eq(item3.relative_position)
expect(item3.next_relative_position).to be_nil
expect(sibling_query.where(relative_position: nil)).not_to exist
expect(sibling_query.reorder(:relative_position, :id)).to eq([item1, item2, item3])
end
it 'preserves relative position' do
......@@ -120,6 +120,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do
describe '.move_nulls_to_start' do
let(:item3) { create_item }
let(:sibling_query) { item1.class.relative_positioning_query_base(item1) }
it 'moves items with null relative_position to the start' do
item1.update!(relative_position: nil)
......@@ -131,10 +132,8 @@ RSpec.shared_examples 'a class that supports relative positioning' do
items.map(&:reload)
expect(items.sort_by(&:relative_position)).to eq(items)
expect(item1.prev_relative_position).to eq nil
expect(item1.next_relative_position).to eq item2.relative_position
expect(item2.next_relative_position).to eq item3.relative_position
expect(item3.next_relative_position).to eq nil
expect(sibling_query.where(relative_position: nil)).not_to exist
expect(sibling_query.reorder(:relative_position, :id)).to eq(items)
expect(item3.relative_position).to be(1000)
end
......@@ -194,194 +193,6 @@ RSpec.shared_examples 'a class that supports relative positioning' do
end
end
describe '#max_relative_position' do
it 'returns maximum position' do
expect(item1.max_relative_position).to eq item2.relative_position
end
end
describe '#prev_relative_position' do
it 'returns previous position if there is an item above' do
item1.update!(relative_position: 5)
item2.update!(relative_position: 15)
expect(item2.prev_relative_position).to eq item1.relative_position
end
it 'returns nil if there is no item above' do
expect(item1.prev_relative_position).to eq nil
end
end
describe '#next_relative_position' do
it 'returns next position if there is an item below' do
item1.update!(relative_position: 5)
item2.update!(relative_position: 15)
expect(item1.next_relative_position).to eq item2.relative_position
end
it 'returns nil if there is no item below' do
expect(item2.next_relative_position).to eq nil
end
end
describe '#find_next_gap_before' do
context 'there is no gap' do
let(:items) { create_items_with_positions(run_at_start) }
it 'returns nil' do
items.each do |item|
expect(item.send(:find_next_gap_before)).to be_nil
end
end
end
context 'there is a sequence ending at MAX_POSITION' do
let(:items) { create_items_with_positions(run_at_end) }
let(:gaps) do
items.map { |item| item.send(:find_next_gap_before) }
end
it 'can find the gap at the start for any item in the sequence' do
gap = { start: items.first.relative_position, end: RelativePositioning::MIN_POSITION }
expect(gaps).to all(eq(gap))
end
it 'respects lower bounds' do
gap = { start: items.first.relative_position, end: 10 }
new_item.update!(relative_position: 10)
expect(gaps).to all(eq(gap))
end
end
specify do
item1.update!(relative_position: 5)
(0..10).each do |pos|
item2.update!(relative_position: pos)
gap = item2.send(:find_next_gap_before)
expect(gap[:start]).to be <= item2.relative_position
expect((gap[:end] - gap[:start]).abs).to be >= RelativePositioning::MIN_GAP
expect(gap[:start]).to be_valid_position
expect(gap[:end]).to be_valid_position
end
end
it 'deals with there not being any items to the left' do
create_items_with_positions([1, 2, 3])
new_item.update!(relative_position: 0)
expect(new_item.send(:find_next_gap_before)).to eq(start: 0, end: RelativePositioning::MIN_POSITION)
end
it 'finds the next gap to the left, skipping adjacent values' do
create_items_with_positions([1, 9, 10])
new_item.update!(relative_position: 11)
expect(new_item.send(:find_next_gap_before)).to eq(start: 9, end: 1)
end
it 'finds the next gap to the left' do
create_items_with_positions([2, 10])
new_item.update!(relative_position: 15)
expect(new_item.send(:find_next_gap_before)).to eq(start: 15, end: 10)
new_item.update!(relative_position: 11)
expect(new_item.send(:find_next_gap_before)).to eq(start: 10, end: 2)
new_item.update!(relative_position: 9)
expect(new_item.send(:find_next_gap_before)).to eq(start: 9, end: 2)
new_item.update!(relative_position: 5)
expect(new_item.send(:find_next_gap_before)).to eq(start: 5, end: 2)
end
end
describe '#find_next_gap_after' do
context 'there is no gap' do
let(:items) { create_items_with_positions(run_at_end) }
it 'returns nil' do
items.each do |item|
expect(item.send(:find_next_gap_after)).to be_nil
end
end
end
context 'there is a sequence starting at MIN_POSITION' do
let(:items) { create_items_with_positions(run_at_start) }
let(:gaps) do
items.map { |item| item.send(:find_next_gap_after) }
end
it 'can find the gap at the end for any item in the sequence' do
gap = { start: items.last.relative_position, end: RelativePositioning::MAX_POSITION }
expect(gaps).to all(eq(gap))
end
it 'respects upper bounds' do
gap = { start: items.last.relative_position, end: 10 }
new_item.update!(relative_position: 10)
expect(gaps).to all(eq(gap))
end
end
specify do
item1.update!(relative_position: 5)
(0..10).each do |pos|
item2.update!(relative_position: pos)
gap = item2.send(:find_next_gap_after)
expect(gap[:start]).to be >= item2.relative_position
expect((gap[:end] - gap[:start]).abs).to be >= RelativePositioning::MIN_GAP
expect(gap[:start]).to be_valid_position
expect(gap[:end]).to be_valid_position
end
end
it 'deals with there not being any items to the right' do
create_items_with_positions([1, 2, 3])
new_item.update!(relative_position: 5)
expect(new_item.send(:find_next_gap_after)).to eq(start: 5, end: RelativePositioning::MAX_POSITION)
end
it 'finds the next gap to the right, skipping adjacent values' do
create_items_with_positions([1, 2, 10])
new_item.update!(relative_position: 0)
expect(new_item.send(:find_next_gap_after)).to eq(start: 2, end: 10)
end
it 'finds the next gap to the right' do
create_items_with_positions([2, 10])
new_item.update!(relative_position: 0)
expect(new_item.send(:find_next_gap_after)).to eq(start: 0, end: 2)
new_item.update!(relative_position: 1)
expect(new_item.send(:find_next_gap_after)).to eq(start: 2, end: 10)
new_item.update!(relative_position: 3)
expect(new_item.send(:find_next_gap_after)).to eq(start: 3, end: 10)
new_item.update!(relative_position: 5)
expect(new_item.send(:find_next_gap_after)).to eq(start: 5, end: 10)
end
end
describe '#move_before' do
let(:item3) { create(factory, default_params) }
......@@ -446,36 +257,39 @@ RSpec.shared_examples 'a class that supports relative positioning' do
end
context 'leap-frogging to the left' do
let(:item3) { create(factory, default_params) }
let(:start) { RelativePositioning::START_POSITION }
before do
start = RelativePositioning::START_POSITION
item1.update!(relative_position: start - RelativePositioning::IDEAL_DISTANCE * 0)
item2.update!(relative_position: start - RelativePositioning::IDEAL_DISTANCE * 1)
item3.update!(relative_position: start - RelativePositioning::IDEAL_DISTANCE * 2)
end
let(:item3) { create(factory, default_params) }
def leap_frog(steps)
a = item1
b = item2
def leap_frog
a, b = [item1.reset, item2.reset].sort_by(&:relative_position)
steps.times do |i|
a.move_before(b)
a.save!
a, b = b, a
end
b.move_before(a)
b.save!
end
it 'can leap-frog STEPS - 1 times before needing to rebalance' do
# This is less efficient than going right, due to the flooring of
# integer division
expect { leap_frog(RelativePositioning::STEPS - 1) }
.not_to change { item3.reload.relative_position }
it 'can leap-frog STEPS times before needing to rebalance' do
expect { RelativePositioning::STEPS.times { leap_frog } }
.to change { item3.reload.relative_position }.by(0)
.and change { item1.reload.relative_position }.by(be < 0)
.and change { item2.reload.relative_position }.by(be < 0)
expect { leap_frog }
.to change { item3.reload.relative_position }.by(be < 0)
end
it 'rebalances after leap-frogging STEPS times' do
expect { leap_frog(RelativePositioning::STEPS) }
.to change { item3.reload.relative_position }
context 'there is no space to the left' do
let(:start) { RelativePositioning::MIN_POSITION + (2 * RelativePositioning::IDEAL_DISTANCE) }
it 'rebalances to the right' do
expect { RelativePositioning::STEPS.succ.times { leap_frog } }
.not_to change { item3.reload.relative_position }
end
end
end
end
......@@ -538,25 +352,25 @@ RSpec.shared_examples 'a class that supports relative positioning' do
let(:item3) { create(factory, default_params) }
def leap_frog(steps)
a = item1
b = item2
def leap_frog
a, b = [item1.reset, item2.reset].sort_by(&:relative_position)
steps.times do |i|
a.move_after(b)
a.save!
a, b = b, a
end
a.move_after(b)
a.save!
end
it 'can leap-frog STEPS times before needing to rebalance' do
expect { leap_frog(RelativePositioning::STEPS) }
.not_to change { item3.reload.relative_position }
end
it 'rebalances after STEPS jumps' do
RelativePositioning::STEPS.pred.times do
expect { leap_frog }
.to change { item3.reload.relative_position }.by(0)
.and change { item1.reset.relative_position }.by(be >= 0)
.and change { item2.reset.relative_position }.by(be >= 0)
end
it 'rebalances after leap-frogging STEPS+1 times' do
expect { leap_frog(RelativePositioning::STEPS + 1) }
.to change { item3.reload.relative_position }
expect { leap_frog }
.to change { item3.reload.relative_position }.by(0)
.and change { item1.reset.relative_position }.by(be < 0)
.and change { item2.reset.relative_position }.by(be < 0)
end
end
end
......@@ -802,63 +616,6 @@ RSpec.shared_examples 'a class that supports relative positioning' do
end
end
describe '#move_sequence_before' do
it 'moves the whole sequence of items to the middle of the nearest gap' do
items = create_items_with_positions([90, 100, 101, 102])
items.last.move_sequence_before
items.last.save!
positions = items.map { |item| item.reload.relative_position }
expect(positions).to eq([90, 95, 96, 102])
end
it 'raises an error if there is no space' do
items = create_items_with_positions(run_at_start)
expect { items.last.move_sequence_before }.to raise_error(RelativePositioning::NoSpaceLeft)
end
it 'finds a gap if there are unused positions' do
items = create_items_with_positions([100, 101, 102])
items.last.move_sequence_before
items.last.save!
positions = items.map { |item| item.reload.relative_position }
expect(positions.last - positions.second).to be > RelativePositioning::MIN_GAP
end
end
describe '#move_sequence_after' do
it 'moves the whole sequence of items to the middle of the nearest gap' do
items = create_items_with_positions([100, 101, 102, 110])
items.first.move_sequence_after
items.first.save!
positions = items.map { |item| item.reload.relative_position }
expect(positions).to eq([100, 105, 106, 110])
end
it 'finds a gap if there are unused positions' do
items = create_items_with_positions([100, 101, 102])
items.first.move_sequence_after
items.first.save!
positions = items.map { |item| item.reload.relative_position }
expect(positions.second - positions.first).to be > RelativePositioning::MIN_GAP
end
it 'raises an error if there is no space' do
items = create_items_with_positions(run_at_end)
expect { items.first.move_sequence_after }.to raise_error(RelativePositioning::NoSpaceLeft)
end
end
def be_valid_position
be_between(RelativePositioning::MIN_POSITION, RelativePositioning::MAX_POSITION)
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment