@@ -6,22 +6,20 @@ module Concurrent
66
77 describe ThreadLocalVar do
88
9- subject { ThreadLocalVar . new }
10-
119 context '#initialize' do
1210
1311 it 'can set an initial value' do
14- v = ThreadLocalVar . new ( 14 )
12+ v = described_class . new ( 14 )
1513 expect ( v . value ) . to eq 14
1614 end
1715
1816 it 'sets nil as a default initial value' do
19- v = ThreadLocalVar . new
17+ v = described_class . new
2018 expect ( v . value ) . to be_nil
2119 end
2220
2321 it 'sets the same initial value for all threads' do
24- v = ThreadLocalVar . new ( 14 )
22+ v = described_class . new ( 14 )
2523 t1 = Thread . new { v . value }
2624 t2 = Thread . new { v . value }
2725 expect ( t1 . value ) . to eq 14
@@ -30,51 +28,88 @@ module Concurrent
3028
3129 if Concurrent . on_jruby?
3230 it 'extends JavaThreadLocalVar' do
33- expect ( subject . class . ancestors ) . to include ( Concurrent ::JavaThreadLocalVar )
31+ expect ( described_class . ancestors ) . to include ( Concurrent ::JavaThreadLocalVar )
3432 end
3533 else
3634 it 'extends RubyThreadLocalVar' do
37- expect ( subject . class . ancestors ) . to include ( Concurrent ::RubyThreadLocalVar )
35+ expect ( described_class . ancestors ) . to include ( Concurrent ::RubyThreadLocalVar )
36+ end
37+ end
38+
39+ it 'can set a block to be called to get the initial value' do
40+ v = described_class . new { 14 }
41+ expect ( v . value ) . to eq 14
42+ end
43+
44+ context 'when attempting to set both an initial value and a block' do
45+ it do
46+ expect { described_class . new ( 14 ) { 14 } } . to raise_error ( ArgumentError )
3847 end
3948 end
4049 end
4150
4251 context '#value' do
52+ let ( :v ) { described_class . new ( 14 ) }
4353
4454 it 'returns the current value' do
45- v = ThreadLocalVar . new ( 14 )
4655 expect ( v . value ) . to eq 14
4756 end
4857
4958 it 'returns the value after modification' do
50- v = ThreadLocalVar . new ( 14 )
5159 v . value = 2
5260 expect ( v . value ) . to eq 2
5361 end
62+
63+ context 'when using a block to initialize the value' do
64+ it 'calls the block to initialize the value' do
65+ block = proc { }
66+
67+ expect ( block ) . to receive ( :call )
68+
69+ v = described_class . new ( &block )
70+ v . value
71+ end
72+
73+ it 'sets the block return value as the current value' do
74+ value = 13
75+
76+ v = described_class . new { value += 1 }
77+
78+ v . value
79+ expect ( v . value ) . to be 14
80+ end
81+
82+ it 'calls the block to initialize the value for each thread' do
83+ block = proc { }
84+
85+ expect ( block ) . to receive ( :call ) . twice
86+
87+ v = described_class . new ( &block )
88+ Thread . new { v . value } . join
89+ Thread . new { v . value } . join
90+ end
91+ end
5492 end
5593
5694 context '#value=' do
95+ let ( :v ) { described_class . new ( 14 ) }
5796
5897 it 'sets a new value' do
59- v = ThreadLocalVar . new ( 14 )
6098 v . value = 2
6199 expect ( v . value ) . to eq 2
62100 end
63101
64102 it 'returns the new value' do
65- v = ThreadLocalVar . new ( 14 )
66103 expect ( v . value = 2 ) . to eq 2
67104 end
68105
69106 it 'does not modify the initial value for other threads' do
70- v = ThreadLocalVar . new ( 14 )
71107 v . value = 2
72108 t = Thread . new { v . value }
73109 expect ( t . value ) . to eq 14
74110 end
75111
76112 it 'does not modify the value for other threads' do
77- v = ThreadLocalVar . new ( 14 )
78113 v . value = 2
79114
80115 b1 = CountDownLatch . new ( 2 )
0 commit comments