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
|
require 'concurrent/atomic/fiber_local_var'
module Concurrent
RSpec.describe FiberLocalVar do
context '#initialize' do
it 'can set an initial value' do
v = described_class.new(14)
expect(v.value).to eq 14
end
it 'sets nil as a default initial value' do
v = described_class.new
expect(v.value).to be_nil
end
it 'sets the same initial value for all fibers' do
v = described_class.new(14)
f1 = in_fiber { v.value }
f2 = in_fiber { v.value }
expect(f1.resume).to eq 14
expect(f2.resume).to eq 14
end
it 'can set a block to be called to get the initial value' do
v = described_class.new { 14 }
expect(v.value).to eq 14
end
context 'when attempting to set both an initial value and a block' do
it do
expect { described_class.new(14) { 14 } }.to raise_error(ArgumentError)
end
end
end
context '#value' do
let(:v) { described_class.new(14) }
it 'returns the current value' do
expect(v.value).to eq 14
end
it 'returns the value after modification' do
v.value = 2
expect(v.value).to eq 2
end
context 'when using a block to initialize the value' do
it 'calls the block to initialize the value' do
block = proc { }
expect(block).to receive(:call)
v = described_class.new(&block)
v.value
end
it 'sets the block return value as the current value' do
value = 13
v = described_class.new { value += 1 }
v.value
expect(v.value).to be 14
end
it 'calls the block to initialize the value for each fiber' do
block = proc { }
expect(block).to receive(:call).twice
v = described_class.new(&block)
in_fiber { v.value }.resume
in_fiber { v.value }.resume
end
end
end
context '#value=' do
let(:v) { described_class.new(14) }
it 'sets a new value' do
v.value = 2
expect(v.value).to eq 2
end
it 'returns the new value' do
expect(v.value = 2).to eq 2
end
it 'does not modify the initial value for other fibers' do
v.value = 2
f = in_fiber { v.value }
expect(f.resume).to eq 14
end
it 'does not modify the value for other fibers' do
v.value = 3
f1 = in_fiber do
v.value = 1
Fiber.yield
v.value
end
f2 = in_fiber do
v.value = 2
Fiber.yield
v.value
end
f1.resume
f2.resume
expect(f1.resume).to eq 1
expect(f2.resume).to eq 2
end
end
end
end
|