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
|
require 'spec_helper'
describe Immutable do
describe '.list' do
context 'with no arguments' do
it 'always returns the same instance' do
L.empty.should equal(L.empty)
end
it 'returns an empty list' do
L.empty.should be_empty
end
end
context 'with a number of items' do
it 'always returns a different instance' do
L['A', 'B', 'C'].should_not equal(L['A', 'B', 'C'])
end
it 'is the same as repeatedly using #cons' do
L['A', 'B', 'C'].should eql(L.empty.cons('C').cons('B').cons('A'))
end
end
end
describe '.stream' do
context 'with no block' do
it 'returns an empty list' do
Immutable.stream.should eql(L.empty)
end
end
context 'with a block' do
let(:list) { count = 0; Immutable.stream { count += 1 }}
it 'repeatedly calls the block' do
list.take(5).should eql(L[1, 2, 3, 4, 5])
end
end
end
describe '.interval' do
context 'for numbers' do
it 'is equivalent to a list with explicit values' do
Immutable.interval(98, 102).should eql(L[98, 99, 100, 101, 102])
end
end
context 'for strings' do
it 'is equivalent to a list with explicit values' do
Immutable.interval('A', 'AA').should eql(L['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA'])
end
end
end
describe '.repeat' do
it 'returns an infinite list with specified value for each element' do
Immutable.repeat('A').take(5).should eql(L['A', 'A', 'A', 'A', 'A'])
end
end
describe '.replicate' do
it 'returns a list with the specified value repeated the specified number of times' do
Immutable.replicate(5, 'A').should eql(L['A', 'A', 'A', 'A', 'A'])
end
end
describe '.iterate' do
it 'returns an infinite list where the first item is calculated by applying the block on the initial argument, the second item by applying the function on the previous result and so on' do
Immutable.iterate(1) { |item| item * 2 }.take(10).should eql(L[1, 2, 4, 8, 16, 32, 64, 128, 256, 512])
end
end
describe '.enumerate' do
let(:enum) do
Enumerator.new do |yielder|
yielder << 1
yielder << 2
yielder << 3
raise 'list fully realized'
end
end
let(:list) { Immutable.enumerate(enum) }
it 'returns a list based on the values yielded from the enumerator' do
expect(list.take(2)).to eq L[1, 2]
end
it 'realizes values as they are needed' do
# this example shows that Lists are not as lazy as they could be
# if Lists were fully lazy, you would have to take(4) to hit the exception
expect { list.take(3).to_a }.to raise_exception(RuntimeError)
end
end
describe '[]' do
it 'takes a variable number of items and returns a list' do
list = Immutable::List[1,2,3]
list.should be_kind_of(Immutable::List)
list.size.should be(3)
list.to_a.should == [1,2,3]
end
it 'returns an empty list when called without arguments' do
L[].should be_kind_of(Immutable::List)
L[].should be_empty
end
end
end
|