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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
require_relative 'concern/dereferenceable_shared'
require_relative 'concern/obligation_shared'
require_relative 'concern/observable_shared'
RSpec.shared_examples :ivar do
it_should_behave_like :obligation
it_should_behave_like :dereferenceable
it_should_behave_like :observable
context 'initialization' do
it 'sets the state to incomplete' do
expect(subject).to be_incomplete
end
end
context '#set' do
it 'sets the state to be fulfilled' do
subject.set(14)
expect(subject).to be_fulfilled
end
it 'sets the value' do
subject.set(14)
expect(subject.value).to eq 14
end
it 'raises an exception if set more than once' do
subject.set(14)
expect {subject.set(2)}.to raise_error(Concurrent::MultipleAssignmentError)
expect(subject.value).to eq 14
end
it 'returns self' do
expect(subject.set(42)).to eq subject
end
it 'fulfils when given a block which executes successfully' do
subject.set{ 42 }
expect(subject.value).to eq 42
end
it 'rejects when given a block which raises an exception' do
expected = ArgumentError.new
subject.set{ raise expected }
expect(subject.reason).to eq expected
end
it 'raises an exception when given a value and a block' do
expect {
subject.set(42){ :guide }
}.to raise_error(ArgumentError)
end
it 'raises an exception when given neither a value nor a block' do
expect {
subject.set
}.to raise_error(ArgumentError)
end
end
context '#fail' do
it 'sets the state to be rejected' do
subject.fail
expect(subject).to be_rejected
end
it 'sets the value to be nil' do
subject.fail
expect(subject.value).to be_nil
end
it 'sets the reason to the given exception' do
expected = ArgumentError.new
subject.fail(expected)
expect(subject.reason).to eq expected
end
it 'raises an exception if set more than once' do
subject.fail
expect {subject.fail}.to raise_error(Concurrent::MultipleAssignmentError)
expect(subject.value).to be_nil
end
it 'defaults the reason to a StandardError' do
subject.fail
expect(subject.reason).to be_a StandardError
end
it 'returns self' do
expect(subject.fail).to eq subject
end
end
describe '#try_set' do
context 'when unset' do
it 'assigns the value' do
subject.try_set(32)
expect(subject.value).to eq 32
end
it 'assigns the block result' do
subject.try_set{ 32 }
expect(subject.value).to eq 32
end
it 'returns true' do
expect(subject.try_set('hi')).to eq true
end
end
context 'when fulfilled' do
before(:each) { subject.set(27) }
it 'does not assign the value' do
subject.try_set(88)
expect(subject.value).to eq 27
end
it 'does not assign the block result' do
subject.try_set{ 88 }
expect(subject.value).to eq 27
end
it 'returns false' do
expect(subject.try_set('hello')).to eq false
end
end
context 'when rejected' do
before(:each) { subject.fail }
it 'does not assign the value' do
subject.try_set(88)
expect(subject).to be_rejected
end
it 'does not assign the block result' do
subject.try_set{ 88 }
expect(subject).to be_rejected
end
it 'has a nil value' do
expect(subject.value).to be_nil
end
it 'returns false' do
expect(subject.try_set('hello')).to eq false
end
end
end
end
|