1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
require_relative '../../spec_helper'
describe 'Range#minmax' do
before(:each) do
@x = mock('x')
@y = mock('y')
@x.should_receive(:<=>).with(@y).any_number_of_times.and_return(-1) # x < y
@x.should_receive(:<=>).with(@x).any_number_of_times.and_return(0) # x == x
@y.should_receive(:<=>).with(@x).any_number_of_times.and_return(1) # y > x
@y.should_receive(:<=>).with(@y).any_number_of_times.and_return(0) # y == y
end
describe 'on an inclusive range' do
it 'should raise RangeError on an endless range without iterating the range' do
@x.should_not_receive(:succ)
range = (@x..)
-> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range')
end
it 'raises RangeError or ArgumentError on a beginless range' do
range = (..@x)
-> { range.minmax }.should raise_error(StandardError) { |e|
if RangeError === e
# error from #min
-> { raise e }.should raise_error(RangeError, 'cannot get the minimum of beginless range')
else
# error from #max
-> { raise e }.should raise_error(ArgumentError, 'comparison of NilClass with MockObject failed')
end
}
end
it 'should return beginning of range if beginning and end are equal without iterating the range' do
@x.should_not_receive(:succ)
(@x..@x).minmax.should == [@x, @x]
end
it 'should return nil pair if beginning is greater than end without iterating the range' do
@y.should_not_receive(:succ)
(@y..@x).minmax.should == [nil, nil]
end
it 'should return the minimum and maximum values for a non-numeric range without iterating the range' do
@x.should_not_receive(:succ)
(@x..@y).minmax.should == [@x, @y]
end
it 'should return the minimum and maximum values for a numeric range' do
(1..3).minmax.should == [1, 3]
end
it 'should return the minimum and maximum values for a numeric range without iterating the range' do
# We cannot set expectations on integers,
# so we "prevent" iteration by picking a value that would iterate until the spec times out.
range_end = Float::INFINITY
(1..range_end).minmax.should == [1, range_end]
end
it 'should return the minimum and maximum values according to the provided block by iterating the range' do
@x.should_receive(:succ).once.and_return(@y)
(@x..@y).minmax { |x, y| - (x <=> y) }.should == [@y, @x]
end
end
describe 'on an exclusive range' do
it 'should raise RangeError on an endless range' do
@x.should_not_receive(:succ)
range = (@x...)
-> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range')
end
it 'should raise RangeError on a beginless range' do
range = (...@x)
-> { range.minmax }.should raise_error(RangeError,
/cannot get the maximum of beginless range with custom comparison method|cannot get the minimum of beginless range/)
end
it 'should return nil pair if beginning and end are equal without iterating the range' do
@x.should_not_receive(:succ)
(@x...@x).minmax.should == [nil, nil]
end
it 'should return nil pair if beginning is greater than end without iterating the range' do
@y.should_not_receive(:succ)
(@y...@x).minmax.should == [nil, nil]
end
it 'should return the minimum and maximum values for a non-numeric range by iterating the range' do
@x.should_receive(:succ).once.and_return(@y)
(@x...@y).minmax.should == [@x, @x]
end
it 'should return the minimum and maximum values for a numeric range' do
(1...3).minmax.should == [1, 2]
end
it 'should return the minimum and maximum values for a numeric range without iterating the range' do
# We cannot set expectations on integers,
# so we "prevent" iteration by picking a value that would iterate until the spec times out.
range_end = bignum_value
(1...range_end).minmax.should == [1, range_end - 1]
end
it 'raises TypeError if the end value is not an integer' do
range = (0...Float::INFINITY)
-> { range.minmax }.should raise_error(TypeError, 'cannot exclude non Integer end value')
end
it 'should return the minimum and maximum values according to the provided block by iterating the range' do
@x.should_receive(:succ).once.and_return(@y)
(@x...@y).minmax { |x, y| - (x <=> y) }.should == [@x, @x]
end
end
end
|