Skip to content

Commit aff034f

Browse files
committed
AtomicMarkableReference: clean up test styling
1 parent b80bfee commit aff034f

File tree

1 file changed

+97
-68
lines changed

1 file changed

+97
-68
lines changed
Lines changed: 97 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,133 @@
11
describe Concurrent::Edge::AtomicMarkableReference do
2-
# use a number outside JRuby's fixnum cache range, to ensure identity is
3-
# preserved
42
subject { described_class.new 1000, true }
53

6-
specify :test_construct do
7-
expect(subject.value).to eq 1000
8-
expect(subject.marked?).to eq true
9-
end
4+
describe '.initialize' do
5+
it 'constructs the object' do
6+
expect(subject.value).to eq 1000
7+
expect(subject.marked?).to eq true
8+
end
9+
10+
it 'has sane defaults' do
11+
amr = described_class.new
1012

11-
specify :test_set do
12-
val, mark = subject.set 1001, true
13+
expect(amr.value).to eq nil
14+
expect(amr.marked?).to eq false
15+
end
16+
end
1317

14-
expect(subject.value).to eq 1001
15-
expect(subject.marked?).to eq true
18+
describe '#set' do
19+
it 'sets the value and mark' do
20+
val, mark = subject.set 1001, true
1621

17-
expect(val).to eq 1001
18-
expect(mark).to eq true
22+
expect(subject.value).to eq 1001
23+
expect(subject.marked?).to eq true
24+
expect(val).to eq 1001
25+
expect(mark).to eq true
26+
end
1927
end
2028

21-
specify :test_update do
22-
val, mark = subject.update { |v, m| [v + 1, !m] }
29+
describe '#try_update' do
30+
it 'updates the value and mark' do
31+
val, mark = subject.try_update { |v, m| [v + 1, !m] }
2332

24-
expect(subject.value).to eq 1001
25-
expect(subject.marked?).to eq false
33+
expect(subject.value).to eq 1001
34+
expect(val).to eq 1001
35+
expect(mark).to eq false
36+
end
2637

27-
expect(val).to eq 1001
28-
expect(mark).to eq false
38+
it 'raises ConcurrentUpdateError when attempting to set inside of block' do
39+
expect do
40+
subject.try_update do |v, m|
41+
subject.set(1001, false)
42+
[v + 1, !m]
43+
end
44+
end.to raise_error Concurrent::ConcurrentUpdateError
45+
end
2946
end
3047

31-
specify :test_try_update do
32-
val, mark = subject.try_update { |v, m| [v + 1, !m] }
48+
describe '#update' do
49+
it 'updates the value and mark' do
50+
val, mark = subject.update { |v, m| [v + 1, !m] }
3351

34-
expect(subject.value).to eq 1001
52+
expect(subject.value).to eq 1001
53+
expect(subject.marked?).to eq false
3554

36-
expect(val).to eq 1001
37-
expect(mark).to eq false
38-
end
55+
expect(val).to eq 1001
56+
expect(mark).to eq false
57+
end
3958

40-
specify :test_try_update_fails do
41-
expect do
42-
# assigning within block exploits implementation detail for test
43-
subject.try_update do |v, m|
59+
it 'retries until update succeeds' do
60+
tries = 0
61+
62+
subject.update do |v, m|
63+
tries += 1
4464
subject.set(1001, false)
4565
[v + 1, !m]
4666
end
47-
end.to raise_error Concurrent::ConcurrentUpdateError
48-
end
49-
50-
specify :test_update_retries do
51-
tries = 0
5267

53-
# assigning within block exploits implementation detail for test
54-
subject.update do |v, m|
55-
tries += 1
56-
subject.set(1001, false)
57-
[v + 1, !m]
68+
expect(tries).to eq 2
5869
end
59-
60-
expect(tries).to eq 2
61-
end
62-
63-
specify :test_numeric_cas do
64-
# non-idempotent Float (JRuby, Rubinius, MRI < 2.0.0 or 32-bit)
65-
subject.set(1.0 + 0.1, true)
66-
expect(subject.compare_and_set(1.0 + 0.1, 1.2, true, false))
67-
.to be_truthy, "CAS failed for (#{1.0 + 0.1}, true) => (1.2, false)"
68-
69-
# Bignum
70-
subject.set(2**100, false)
71-
expect(subject.compare_and_set(2**100, 2**99, false, true))
72-
.to be_truthy, "CAS failed for (#{2**100}, false) => (0, true)"
73-
74-
# Rational
75-
require 'rational' unless ''.respond_to? :to_r
76-
subject.set(Rational(1, 3), true)
77-
expect(subject.compare_and_set(Rational(1, 3), Rational(3, 1), true, false))
78-
.to be_truthy, "CAS failed for (#{Rational(1, 3)}, true) => (0, false)"
79-
80-
# Complex
81-
require 'complex' unless ''.respond_to? :to_c
82-
subject.set(Complex(1, 2), false)
83-
expect(subject.compare_and_set(Complex(1, 2), Complex(1, 3), false, true))
84-
.to be_truthy, "CAS failed for (#{Complex(1, 2)}, false) => (0, false)"
8570
end
8671

8772
describe '#compare_and_set' do
88-
context 'objects have the same identity' do
89-
it 'is successful' do
73+
context 'when objects have the same identity' do
74+
it 'sets the value and mark' do
9075
arr = [1, 2, 3]
9176
subject.set(arr, true)
9277
expect(subject.compare_and_set(arr, 1.2, true, false)).to be_truthy
9378
end
9479
end
9580

96-
context 'objects have the different identity' do
97-
it 'is not successful' do
81+
context 'when objects have the different identity' do
82+
it 'it does not set the value or mark' do
9883
subject.set([1, 2, 3], true)
9984
expect(subject.compare_and_set([1, 2, 3], 1.2, true, false))
10085
.to be_falsey
10186
end
87+
88+
context 'when comparing Numeric objects' do
89+
context 'Non-idepotent Float' do
90+
it 'sets the value and mark' do
91+
subject.set(1.0 + 0.1, true)
92+
expect(subject.compare_and_set(1.0 + 0.1, 1.2, true, false))
93+
.to be_truthy
94+
end
95+
end
96+
97+
context 'BigNum' do
98+
it 'sets the value and mark' do
99+
subject.set(2**100, false)
100+
expect(subject.compare_and_set(2**100, 2**99, false, true))
101+
.to be_truthy
102+
end
103+
end
104+
105+
context 'Rational' do
106+
it 'sets the value and mark' do
107+
require 'rational' unless ''.respond_to? :to_r
108+
subject.set(Rational(1, 3), true)
109+
comp = subject.compare_and_set(Rational(1, 3),
110+
Rational(3, 1),
111+
true,
112+
false)
113+
expect(comp).to be_truthy
114+
end
115+
end
116+
end
117+
118+
context 'Rational' do
119+
it 'is successful' do
120+
# Complex
121+
require 'complex' unless ''.respond_to? :to_c
122+
subject.set(Complex(1, 2), false)
123+
comp = subject.compare_and_set(Complex(1, 2),
124+
Complex(1, 3),
125+
false,
126+
true)
127+
expect(comp)
128+
.to be_truthy
129+
end
130+
end
102131
end
103132
end
104133
end

0 commit comments

Comments
 (0)