concurrent-ruby 0.6.1 → 0.7.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/concurrent.rb +3 -4
- data/lib/concurrent/atomic.rb +46 -0
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
- data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
- data/lib/concurrent/atomic_reference/jruby.rb +8 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
- data/lib/concurrent/atomic_reference/rbx.rb +16 -0
- data/lib/concurrent/atomic_reference/ruby.rb +16 -0
- data/lib/concurrent/atomics.rb +1 -1
- data/lib/concurrent/configuration.rb +1 -1
- data/lib/concurrent/supervisor.rb +1 -1
- data/lib/concurrent/timer_task.rb +0 -36
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.so +0 -0
- data/lib/extension_helper.rb +9 -0
- metadata +16 -148
- data/lib/concurrent/actor/actor.rb +0 -270
- data/lib/concurrent/actor/postable.rb +0 -102
- data/lib/concurrent/actors.rb +0 -2
- data/lib/concurrent/atomic/atomic.rb +0 -48
- data/lib/concurrent/runnable.rb +0 -90
- data/lib/concurrent/stoppable.rb +0 -20
- data/spec/concurrent/actor/actor_spec.rb +0 -376
- data/spec/concurrent/actor/postable_shared.rb +0 -218
- data/spec/concurrent/actress_spec.rb +0 -211
- data/spec/concurrent/agent_spec.rb +0 -500
- data/spec/concurrent/async_spec.rb +0 -352
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
- data/spec/concurrent/atomic/atomic_spec.rb +0 -133
- data/spec/concurrent/atomic/condition_spec.rb +0 -171
- data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
- data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
- data/spec/concurrent/atomic/event_spec.rb +0 -200
- data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
- data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
- data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
- data/spec/concurrent/channel/channel_spec.rb +0 -39
- data/spec/concurrent/channel/probe_spec.rb +0 -77
- data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
- data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
- data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
- data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
- data/spec/concurrent/configuration_spec.rb +0 -69
- data/spec/concurrent/dataflow_spec.rb +0 -242
- data/spec/concurrent/delay_spec.rb +0 -91
- data/spec/concurrent/dereferenceable_shared.rb +0 -146
- data/spec/concurrent/exchanger_spec.rb +0 -66
- data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
- data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
- data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
- data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
- data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
- data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
- data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
- data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
- data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
- data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
- data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
- data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
- data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
- data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
- data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
- data/spec/concurrent/executor/thread_pool_shared.rb +0 -269
- data/spec/concurrent/executor/timer_set_spec.rb +0 -183
- data/spec/concurrent/future_spec.rb +0 -329
- data/spec/concurrent/ivar_spec.rb +0 -215
- data/spec/concurrent/mvar_spec.rb +0 -380
- data/spec/concurrent/obligation_shared.rb +0 -102
- data/spec/concurrent/obligation_spec.rb +0 -282
- data/spec/concurrent/observable_shared.rb +0 -177
- data/spec/concurrent/observable_spec.rb +0 -56
- data/spec/concurrent/options_parser_spec.rb +0 -71
- data/spec/concurrent/promise_spec.rb +0 -367
- data/spec/concurrent/runnable_shared.rb +0 -68
- data/spec/concurrent/runnable_spec.rb +0 -235
- data/spec/concurrent/scheduled_task_spec.rb +0 -340
- data/spec/concurrent/stoppable_shared.rb +0 -37
- data/spec/concurrent/supervisor_spec.rb +0 -1149
- data/spec/concurrent/timer_task_spec.rb +0 -256
- data/spec/concurrent/tvar_spec.rb +0 -137
- data/spec/concurrent/utility/processor_count_spec.rb +0 -20
- data/spec/concurrent/utility/timeout_spec.rb +0 -50
- data/spec/concurrent/utility/timer_spec.rb +0 -52
- data/spec/spec_helper.rb +0 -41
- data/spec/support/example_group_extensions.rb +0 -52
- data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe Observable do
|
6
|
-
|
7
|
-
let (:described_class) do
|
8
|
-
Class.new do
|
9
|
-
include Concurrent::Observable
|
10
|
-
public :observers, :observers=
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:observer_set) { double(:observer_set) }
|
15
|
-
subject { described_class.new }
|
16
|
-
|
17
|
-
before(:each) do
|
18
|
-
subject.observers = observer_set
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'does not initialize set by by default' do
|
22
|
-
described_class.new.observers.should be_nil
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'uses the given observer set' do
|
26
|
-
expected = CopyOnWriteObserverSet.new
|
27
|
-
subject.observers = expected
|
28
|
-
subject.observers.should eql expected
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'delegates #add_observer' do
|
32
|
-
observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
|
33
|
-
subject.add_observer(:observer).should eq :observer
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'delegates #with_observer' do
|
37
|
-
observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
|
38
|
-
subject.with_observer(:observer).should eq subject
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'delegates #delete_observer' do
|
42
|
-
observer_set.should_receive(:delete_observer).with(:observer)
|
43
|
-
subject.delete_observer(:observer)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'delegates #delete_observers' do
|
47
|
-
observer_set.should_receive(:delete_observers).with(no_args)
|
48
|
-
subject.delete_observers
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'delegates #count_observers' do
|
52
|
-
observer_set.should_receive(:count_observers).with(no_args)
|
53
|
-
subject.count_observers
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe OptionsParser do
|
6
|
-
|
7
|
-
let(:executor){ ImmediateExecutor.new }
|
8
|
-
|
9
|
-
let(:task_pool){ ImmediateExecutor.new }
|
10
|
-
let(:operation_pool){ ImmediateExecutor.new }
|
11
|
-
|
12
|
-
context '#get_executor_from' do
|
13
|
-
|
14
|
-
it 'returns the given :executor' do
|
15
|
-
OptionsParser::get_executor_from(executor: executor).should eq executor
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'returns the global operation pool when :operation is true' do
|
19
|
-
Concurrent.configuration.should_receive(:global_operation_pool).
|
20
|
-
and_return(:operation_pool)
|
21
|
-
OptionsParser::get_executor_from(operation: true)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'returns the global task pool when :operation is false' do
|
25
|
-
Concurrent.configuration.should_receive(:global_task_pool).
|
26
|
-
and_return(:task_pool)
|
27
|
-
OptionsParser::get_executor_from(operation: false)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'returns the global operation pool when :task is false' do
|
31
|
-
Concurrent.configuration.should_receive(:global_operation_pool).
|
32
|
-
and_return(:operation_pool)
|
33
|
-
OptionsParser::get_executor_from(task: false)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'returns the global task pool when :task is true' do
|
37
|
-
Concurrent.configuration.should_receive(:global_task_pool).
|
38
|
-
and_return(:task_pool)
|
39
|
-
OptionsParser::get_executor_from(task: true)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'returns the global task pool when :executor is nil' do
|
43
|
-
Concurrent.configuration.should_receive(:global_task_pool).
|
44
|
-
and_return(:task_pool)
|
45
|
-
OptionsParser::get_executor_from(executor: nil)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'returns the global task pool when no option is given' do
|
49
|
-
Concurrent.configuration.should_receive(:global_task_pool).
|
50
|
-
and_return(:task_pool)
|
51
|
-
OptionsParser::get_executor_from
|
52
|
-
end
|
53
|
-
|
54
|
-
specify ':executor overrides :operation' do
|
55
|
-
OptionsParser::get_executor_from(executor: executor, operation: true).
|
56
|
-
should eq executor
|
57
|
-
end
|
58
|
-
|
59
|
-
specify ':executor overrides :task' do
|
60
|
-
OptionsParser::get_executor_from(executor: executor, task: true).
|
61
|
-
should eq executor
|
62
|
-
end
|
63
|
-
|
64
|
-
specify ':operation overrides :task' do
|
65
|
-
Concurrent.configuration.should_receive(:global_operation_pool).
|
66
|
-
and_return(:operation_pool)
|
67
|
-
OptionsParser::get_executor_from(operation: true, task: true)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,367 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'obligation_shared'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
|
6
|
-
describe Promise do
|
7
|
-
|
8
|
-
let(:executor) { PerThreadExecutor.new }
|
9
|
-
|
10
|
-
let(:empty_root) { Promise.new(executor: executor){ nil } }
|
11
|
-
let!(:fulfilled_value) { 10 }
|
12
|
-
let!(:rejected_reason) { StandardError.new('mojo jojo') }
|
13
|
-
|
14
|
-
let(:pending_subject) do
|
15
|
-
Promise.new(executor: executor){ sleep(0.3); fulfilled_value }.execute
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:fulfilled_subject) do
|
19
|
-
Promise.fulfill(fulfilled_value, executor: executor)
|
20
|
-
end
|
21
|
-
|
22
|
-
let(:rejected_subject) do
|
23
|
-
Promise.reject(rejected_reason, executor: executor)
|
24
|
-
end
|
25
|
-
|
26
|
-
it_should_behave_like :obligation
|
27
|
-
|
28
|
-
it 'includes Dereferenceable' do
|
29
|
-
promise = Promise.new{ nil }
|
30
|
-
promise.should be_a(Dereferenceable)
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'initializers' do
|
34
|
-
describe '.fulfill' do
|
35
|
-
|
36
|
-
subject { Promise.fulfill(10) }
|
37
|
-
|
38
|
-
it 'should return a Promise' do
|
39
|
-
subject.should be_a Promise
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should return a fulfilled Promise' do
|
43
|
-
subject.should be_fulfilled
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should return a Promise with set value' do
|
47
|
-
subject.value.should eq 10
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '.reject' do
|
52
|
-
|
53
|
-
let(:reason) { ArgumentError.new }
|
54
|
-
subject { Promise.reject(reason) }
|
55
|
-
|
56
|
-
it 'should return a Promise' do
|
57
|
-
subject.should be_a Promise
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should return a rejected Promise' do
|
61
|
-
subject.should be_rejected
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should return a Promise with set reason' do
|
65
|
-
subject.reason.should be reason
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe '.new' do
|
70
|
-
it 'should return an unscheduled Promise' do
|
71
|
-
p = Promise.new(executor: executor){ nil }
|
72
|
-
p.should be_unscheduled
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '.execute' do
|
77
|
-
it 'creates a new Promise' do
|
78
|
-
p = Promise.execute(executor: executor){ nil }
|
79
|
-
p.should be_a(Promise)
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'passes the block to the new Promise' do
|
83
|
-
p = Promise.execute(executor: executor){ 20 }
|
84
|
-
sleep(0.1)
|
85
|
-
p.value.should eq 20
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'calls #execute on the new Promise' do
|
89
|
-
p = double('promise')
|
90
|
-
Promise.stub(:new).with({executor: executor}).and_return(p)
|
91
|
-
p.should_receive(:execute).with(no_args)
|
92
|
-
Promise.execute(executor: executor){ nil }
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context '#execute' do
|
98
|
-
|
99
|
-
context 'unscheduled' do
|
100
|
-
|
101
|
-
it 'sets the promise to :pending' do
|
102
|
-
p = Promise.new(executor: executor){ sleep(0.1) }.execute
|
103
|
-
p.should be_pending
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'posts the block given in construction' do
|
107
|
-
executor.should_receive(:post).with(any_args)
|
108
|
-
Promise.new(executor: executor){ nil }.execute
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'pending' do
|
113
|
-
|
114
|
-
it 'sets the promise to :pending' do
|
115
|
-
p = pending_subject.execute
|
116
|
-
p.should be_pending
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'does not posts again' do
|
120
|
-
executor.should_receive(:post).with(any_args).once
|
121
|
-
pending_subject.execute
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe 'with children' do
|
126
|
-
|
127
|
-
let(:root) { Promise.new(executor: executor){ sleep(0.1); nil } }
|
128
|
-
let(:c1) { root.then { sleep(0.1); nil } }
|
129
|
-
let(:c2) { root.then { sleep(0.1); nil } }
|
130
|
-
let(:c2_1) { c2.then { sleep(0.1); nil } }
|
131
|
-
|
132
|
-
context 'when called on the root' do
|
133
|
-
it 'should set all promises to :pending' do
|
134
|
-
root.execute
|
135
|
-
|
136
|
-
c1.should be_pending
|
137
|
-
c2.should be_pending
|
138
|
-
c2_1.should be_pending
|
139
|
-
[root, c1, c2, c2_1].each { |p| p.should be_pending }
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context 'when called on a child' do
|
144
|
-
it 'should set all promises to :pending' do
|
145
|
-
c2_1.execute
|
146
|
-
|
147
|
-
[root, c1, c2, c2_1].each { |p| p.should be_pending }
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe '#then' do
|
154
|
-
|
155
|
-
it 'returns a new promise when a block is passed' do
|
156
|
-
child = empty_root.then { nil }
|
157
|
-
child.should be_a Promise
|
158
|
-
child.should_not be empty_root
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'returns a new promise when a rescuer is passed' do
|
162
|
-
child = empty_root.then(Proc.new{})
|
163
|
-
child.should be_a Promise
|
164
|
-
child.should_not be empty_root
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'returns a new promise when a block and rescuer are passed' do
|
168
|
-
child = empty_root.then(Proc.new{}) { nil }
|
169
|
-
child.should be_a Promise
|
170
|
-
child.should_not be empty_root
|
171
|
-
end
|
172
|
-
|
173
|
-
it 'should have block or rescuers' do
|
174
|
-
expect { empty_root.then }.to raise_error(ArgumentError)
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'unscheduled' do
|
178
|
-
|
179
|
-
let(:p1) { Promise.new(executor: executor){nil} }
|
180
|
-
let(:child) { p1.then{} }
|
181
|
-
|
182
|
-
it 'returns a new promise' do
|
183
|
-
child.should be_a Promise
|
184
|
-
p1.should_not be child
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'returns an unscheduled promise' do
|
188
|
-
child.should be_unscheduled
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
context 'pending' do
|
193
|
-
|
194
|
-
let(:child) { pending_subject.then{} }
|
195
|
-
|
196
|
-
it 'returns a new promise' do
|
197
|
-
child.should be_a Promise
|
198
|
-
pending_subject.should_not be child
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'returns a pending promise' do
|
202
|
-
child.should be_pending
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
context 'fulfilled' do
|
207
|
-
it 'returns a new Promise' do
|
208
|
-
p1 = fulfilled_subject
|
209
|
-
p2 = p1.then{}
|
210
|
-
p2.should be_a(Promise)
|
211
|
-
p1.should_not eq p2
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'notifies fulfillment to new child' do
|
215
|
-
child = fulfilled_subject.then(Proc.new{ 7 }) { |v| v + 5 }
|
216
|
-
child.value.should eq fulfilled_value + 5
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context 'rejected' do
|
221
|
-
it 'returns a new Promise when :rejected' do
|
222
|
-
p1 = rejected_subject
|
223
|
-
p2 = p1.then{}
|
224
|
-
p2.should be_a(Promise)
|
225
|
-
p1.should_not eq p2
|
226
|
-
end
|
227
|
-
|
228
|
-
it 'notifies rejection to new child' do
|
229
|
-
child = rejected_subject.then(Proc.new{ 7 }) { |v| v + 5 }
|
230
|
-
child.value.should eq 7
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'can be called more than once' do
|
235
|
-
p = pending_subject
|
236
|
-
p1 = p.then{}
|
237
|
-
p2 = p.then{}
|
238
|
-
p1.should_not be p2
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
describe 'on_success' do
|
243
|
-
it 'should have a block' do
|
244
|
-
expect { empty_root.on_success }.to raise_error(ArgumentError)
|
245
|
-
end
|
246
|
-
|
247
|
-
it 'returns a new promise' do
|
248
|
-
child = empty_root.on_success { nil }
|
249
|
-
child.should be_a Promise
|
250
|
-
child.should_not be empty_root
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
context '#rescue' do
|
255
|
-
|
256
|
-
it 'returns a new promise' do
|
257
|
-
child = empty_root.rescue { nil }
|
258
|
-
child.should be_a Promise
|
259
|
-
child.should_not be empty_root
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
context 'fulfillment' do
|
264
|
-
|
265
|
-
it 'passes the result of each block to all its children' do
|
266
|
-
expected = nil
|
267
|
-
Promise.new(executor: executor){ 20 }.then{ |result| expected = result }.execute
|
268
|
-
sleep(0.1)
|
269
|
-
expected.should eq 20
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'sets the promise value to the result if its block' do
|
273
|
-
root = Promise.new(executor: executor){ 20 }
|
274
|
-
p = root.then{ |result| result * 2}.execute
|
275
|
-
sleep(0.1)
|
276
|
-
root.value.should eq 20
|
277
|
-
p.value.should eq 40
|
278
|
-
end
|
279
|
-
|
280
|
-
it 'sets the promise state to :fulfilled if the block completes' do
|
281
|
-
p = Promise.new(executor: executor){ 10 * 2 }.then{|result| result * 2}.execute
|
282
|
-
sleep(0.1)
|
283
|
-
p.should be_fulfilled
|
284
|
-
end
|
285
|
-
|
286
|
-
it 'passes the last result through when a promise has no block' do
|
287
|
-
expected = nil
|
288
|
-
Promise.new(executor: executor){ 20 }.then(Proc.new{}).then{|result| expected = result}.execute
|
289
|
-
sleep(0.1)
|
290
|
-
expected.should eq 20
|
291
|
-
end
|
292
|
-
|
293
|
-
it 'uses result as fulfillment value when a promise has no block' do
|
294
|
-
p = Promise.new(executor: executor){ 20 }.then(Proc.new{}).execute
|
295
|
-
sleep(0.1)
|
296
|
-
p.value.should eq 20
|
297
|
-
end
|
298
|
-
|
299
|
-
it 'can manage long chain' do
|
300
|
-
root = Promise.new(executor: executor){ 20 }
|
301
|
-
p1 = root.then { |b| b * 3 }
|
302
|
-
p2 = root.then { |c| c + 2 }
|
303
|
-
p3 = p1.then { |d| d + 7 }
|
304
|
-
|
305
|
-
root.execute
|
306
|
-
sleep(0.1)
|
307
|
-
|
308
|
-
root.value.should eq 20
|
309
|
-
p1.value.should eq 60
|
310
|
-
p2.value.should eq 22
|
311
|
-
p3.value.should eq 67
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
context 'rejection' do
|
316
|
-
|
317
|
-
it 'passes the reason to all its children' do
|
318
|
-
expected = nil
|
319
|
-
Promise.new(executor: executor){ raise ArgumentError }.then(Proc.new{ |reason| expected = reason }).execute
|
320
|
-
sleep(0.1)
|
321
|
-
expected.should be_a ArgumentError
|
322
|
-
end
|
323
|
-
|
324
|
-
it 'sets the promise value to the result if its block' do
|
325
|
-
root = Promise.new(executor: executor){ raise ArgumentError }
|
326
|
-
p = root.then(Proc.new{ |reason| 42 }).execute
|
327
|
-
sleep(0.1)
|
328
|
-
p.value.should eq 42
|
329
|
-
end
|
330
|
-
|
331
|
-
it 'sets the promise state to :rejected if the block completes' do
|
332
|
-
p = Promise.new(executor: executor){ raise ArgumentError }.execute
|
333
|
-
sleep(0.1)
|
334
|
-
p.should be_rejected
|
335
|
-
end
|
336
|
-
|
337
|
-
it 'uses reason as rejection reason when a promise has no rescue callable' do
|
338
|
-
p = Promise.new(executor: ImmediateExecutor.new){ raise ArgumentError }.then{ |val| val }.execute
|
339
|
-
sleep(0.1)
|
340
|
-
p.should be_rejected
|
341
|
-
p.reason.should be_a ArgumentError
|
342
|
-
end
|
343
|
-
|
344
|
-
end
|
345
|
-
|
346
|
-
context 'aliases' do
|
347
|
-
|
348
|
-
it 'aliases #realized? for #fulfilled?' do
|
349
|
-
fulfilled_subject.should be_realized
|
350
|
-
end
|
351
|
-
|
352
|
-
it 'aliases #deref for #value' do
|
353
|
-
fulfilled_subject.deref.should eq fulfilled_value
|
354
|
-
end
|
355
|
-
|
356
|
-
it 'aliases #catch for #rescue' do
|
357
|
-
child = rejected_subject.catch { 7 }
|
358
|
-
child.value.should eq 7
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'aliases #on_error for #rescue' do
|
362
|
-
child = rejected_subject.on_error { 7 }
|
363
|
-
child.value.should eq 7
|
364
|
-
end
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|