concurrent-ruby 0.6.0.pre.2 → 0.6.0
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 +3 -8
- data/lib/concurrent.rb +2 -0
- data/lib/concurrent/actor/actor.rb +3 -3
- data/lib/concurrent/actor/postable.rb +1 -1
- data/lib/concurrent/actors.rb +0 -3
- data/lib/concurrent/actress.rb +75 -0
- data/lib/concurrent/actress/ad_hoc.rb +14 -0
- data/lib/concurrent/actress/context.rb +96 -0
- data/lib/concurrent/actress/core.rb +204 -0
- data/lib/concurrent/actress/core_delegations.rb +37 -0
- data/lib/concurrent/actress/doc.md +53 -0
- data/lib/concurrent/actress/envelope.rb +25 -0
- data/lib/concurrent/actress/errors.rb +14 -0
- data/lib/concurrent/actress/reference.rb +64 -0
- data/lib/concurrent/actress/type_check.rb +48 -0
- data/lib/concurrent/agent.rb +20 -11
- data/lib/concurrent/async.rb +54 -25
- data/lib/concurrent/atomic/atomic.rb +48 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +13 -13
- data/lib/concurrent/atomic/atomic_fixnum.rb +9 -17
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +7 -4
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +16 -14
- data/lib/concurrent/atomic/event.rb +11 -16
- data/lib/concurrent/atomics.rb +1 -0
- data/lib/concurrent/channel/channel.rb +4 -2
- data/lib/concurrent/collection/blocking_ring_buffer.rb +1 -1
- data/lib/concurrent/configuration.rb +59 -47
- data/lib/concurrent/delay.rb +28 -12
- data/lib/concurrent/dereferenceable.rb +6 -6
- data/lib/concurrent/errors.rb +30 -0
- data/lib/concurrent/executor/executor.rb +11 -4
- data/lib/concurrent/executor/immediate_executor.rb +1 -0
- data/lib/concurrent/executor/java_thread_pool_executor.rb +4 -0
- data/lib/concurrent/executor/one_by_one.rb +24 -12
- data/lib/concurrent/executor/per_thread_executor.rb +1 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +2 -1
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +7 -2
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +3 -0
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +0 -2
- data/lib/concurrent/ivar.rb +31 -6
- data/lib/concurrent/logging.rb +17 -0
- data/lib/concurrent/mvar.rb +45 -0
- data/lib/concurrent/obligation.rb +61 -20
- data/lib/concurrent/observable.rb +7 -0
- data/lib/concurrent/promise.rb +1 -0
- data/lib/concurrent/runnable.rb +2 -2
- data/lib/concurrent/supervisor.rb +1 -2
- data/lib/concurrent/timer_task.rb +17 -13
- data/lib/concurrent/tvar.rb +113 -73
- data/lib/concurrent/utility/processor_count.rb +141 -116
- data/lib/concurrent/utility/timeout.rb +4 -5
- data/lib/concurrent/version.rb +1 -1
- data/spec/concurrent/actor/postable_shared.rb +1 -1
- data/spec/concurrent/actress_spec.rb +191 -0
- data/spec/concurrent/async_spec.rb +35 -3
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +1 -1
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +1 -1
- data/spec/concurrent/atomic/atomic_spec.rb +133 -0
- data/spec/concurrent/atomic/count_down_latch_spec.rb +1 -1
- data/spec/concurrent/collection/priority_queue_spec.rb +1 -1
- data/spec/concurrent/configuration_spec.rb +5 -2
- data/spec/concurrent/delay_spec.rb +14 -0
- data/spec/concurrent/exchanger_spec.rb +4 -9
- data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +1 -1
- data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +1 -1
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +1 -1
- data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +1 -1
- data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +4 -4
- data/spec/concurrent/ivar_spec.rb +2 -2
- data/spec/concurrent/obligation_spec.rb +113 -24
- data/spec/concurrent/observable_shared.rb +4 -0
- data/spec/concurrent/observable_spec.rb +8 -3
- data/spec/concurrent/runnable_spec.rb +2 -2
- data/spec/concurrent/scheduled_task_spec.rb +1 -0
- data/spec/concurrent/supervisor_spec.rb +26 -11
- data/spec/concurrent/timer_task_spec.rb +36 -35
- data/spec/concurrent/tvar_spec.rb +1 -1
- data/spec/concurrent/utility/timer_spec.rb +8 -8
- data/spec/spec_helper.rb +8 -18
- data/spec/support/example_group_extensions.rb +48 -0
- metadata +23 -16
- data/lib/concurrent/actor/actor_context.rb +0 -77
- data/lib/concurrent/actor/actor_ref.rb +0 -67
- data/lib/concurrent/actor/simple_actor_ref.rb +0 -94
- data/lib/concurrent_ruby_ext.bundle +0 -0
- data/spec/concurrent/actor/actor_context_spec.rb +0 -29
- data/spec/concurrent/actor/actor_ref_shared.rb +0 -263
- data/spec/concurrent/actor/simple_actor_ref_spec.rb +0 -135
- data/spec/support/functions.rb +0 -25
@@ -10,6 +10,9 @@ module Concurrent
|
|
10
10
|
Class.new do
|
11
11
|
include Concurrent::Async
|
12
12
|
attr_accessor :accessor
|
13
|
+
def initialize
|
14
|
+
init_mutex
|
15
|
+
end
|
13
16
|
def echo(msg)
|
14
17
|
msg
|
15
18
|
end
|
@@ -103,7 +106,7 @@ module Concurrent
|
|
103
106
|
context 'executor' do
|
104
107
|
|
105
108
|
it 'returns the default executor when #executor= has never been called' do
|
106
|
-
Concurrent.configuration.should_receive(:
|
109
|
+
Concurrent.configuration.should_receive(:global_operation_pool).
|
107
110
|
and_return(ImmediateExecutor.new)
|
108
111
|
subject = async_class.new
|
109
112
|
subject.async.echo(:foo)
|
@@ -117,10 +120,10 @@ module Concurrent
|
|
117
120
|
subject.async.echo(:foo)
|
118
121
|
end
|
119
122
|
|
120
|
-
it 'raises an exception if #executor= is called
|
123
|
+
it 'raises an exception if #executor= is called after initialization complete' do
|
121
124
|
executor = ImmediateExecutor.new
|
122
125
|
subject = async_class.new
|
123
|
-
subject.
|
126
|
+
subject.async.echo(:foo)
|
124
127
|
expect {
|
125
128
|
subject.executor = executor
|
126
129
|
}.to raise_error(ArgumentError)
|
@@ -303,6 +306,7 @@ module Concurrent
|
|
303
306
|
object = Class.new {
|
304
307
|
include Concurrent::Async
|
305
308
|
attr_reader :bucket
|
309
|
+
def initialize() init_mutex; end
|
306
310
|
def gather(seconds, first, *rest)
|
307
311
|
sleep(seconds)
|
308
312
|
(@bucket ||= []).concat([first])
|
@@ -315,6 +319,34 @@ module Concurrent
|
|
315
319
|
object.await.gather(0, :c, :d)
|
316
320
|
object.bucket.should eq [:a, :b, :c, :d]
|
317
321
|
end
|
322
|
+
|
323
|
+
context 'raises an InitializationError' do
|
324
|
+
|
325
|
+
let(:async_class) do
|
326
|
+
Class.new do
|
327
|
+
include Concurrent::Async
|
328
|
+
def echo(msg) msg; end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'when #async is called before #init_mutex' do
|
333
|
+
expect {
|
334
|
+
async_class.new.async.echo(:foo)
|
335
|
+
}.to raise_error(Concurrent::InitializationError)
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'when #await is called before #init_mutex' do
|
339
|
+
expect {
|
340
|
+
async_class.new.async.echo(:foo)
|
341
|
+
}.to raise_error(Concurrent::InitializationError)
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'when #executor= is called before #init_mutex' do
|
345
|
+
expect {
|
346
|
+
async_class.new.executor = Concurrent::ImmediateExecutor.new
|
347
|
+
}.to raise_error(Concurrent::InitializationError)
|
348
|
+
end
|
349
|
+
end
|
318
350
|
end
|
319
351
|
end
|
320
352
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
share_examples_for :atomic do
|
4
|
+
|
5
|
+
context 'construction' do
|
6
|
+
|
7
|
+
it 'sets the initial value' do
|
8
|
+
described_class.new(:foo).value.should eq :foo
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'defaults the initial value to nil' do
|
12
|
+
described_class.new.value.should eq nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context '#value' do
|
17
|
+
|
18
|
+
it 'returns the current value' do
|
19
|
+
counter = described_class.new(:foo)
|
20
|
+
counter.value.should eq :foo
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context '#value=' do
|
25
|
+
|
26
|
+
it 'sets the #value to the given object' do
|
27
|
+
atomic = described_class.new(:foo)
|
28
|
+
atomic.value = :bar
|
29
|
+
atomic.value.should eq :bar
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns the new value' do
|
33
|
+
atomic = described_class.new(:foo)
|
34
|
+
(atomic.value = :bar).should eq :bar
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context '#modify' do
|
39
|
+
|
40
|
+
it 'yields the current value' do
|
41
|
+
atomic = described_class.new(:foo)
|
42
|
+
current = []
|
43
|
+
atomic.modify { |value| current << value }
|
44
|
+
current.should eq [:foo]
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'stores the value returned from the yield' do
|
48
|
+
atomic = described_class.new(:foo)
|
49
|
+
atomic.modify { |value| :bar }
|
50
|
+
atomic.value.should eq :bar
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns the new value' do
|
54
|
+
atomic = described_class.new(:foo)
|
55
|
+
atomic.modify{ |value| :bar }.should eq :bar
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#compare_and_set' do
|
60
|
+
|
61
|
+
it 'returns false if the value is not found' do
|
62
|
+
described_class.new(:foo).compare_and_set(:bar, :foo).should eq false
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns true if the value is found' do
|
66
|
+
described_class.new(:foo).compare_and_set(:foo, :bar).should eq true
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'sets if the value is found' do
|
70
|
+
f = described_class.new(:foo)
|
71
|
+
f.compare_and_set(:foo, :bar)
|
72
|
+
f.value.should eq :bar
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'does not set if the value is not found' do
|
76
|
+
f = described_class.new(:foo)
|
77
|
+
f.compare_and_set(:bar, :baz)
|
78
|
+
f.value.should eq :foo
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module Concurrent
|
84
|
+
|
85
|
+
describe MutexAtomic do
|
86
|
+
|
87
|
+
it_should_behave_like :atomic
|
88
|
+
|
89
|
+
specify 'construction is synchronized' do
|
90
|
+
mutex = double('mutex')
|
91
|
+
Mutex.should_receive(:new).once.with(no_args).and_return(mutex)
|
92
|
+
described_class.new
|
93
|
+
end
|
94
|
+
|
95
|
+
specify 'value is synchronized' do
|
96
|
+
mutex = double('mutex')
|
97
|
+
Mutex.stub(:new).with(no_args).and_return(mutex)
|
98
|
+
mutex.should_receive(:lock)
|
99
|
+
mutex.should_receive(:unlock)
|
100
|
+
described_class.new.value
|
101
|
+
end
|
102
|
+
|
103
|
+
specify 'value= is synchronized' do
|
104
|
+
mutex = double('mutex')
|
105
|
+
Mutex.stub(:new).with(no_args).and_return(mutex)
|
106
|
+
mutex.should_receive(:lock)
|
107
|
+
mutex.should_receive(:unlock)
|
108
|
+
described_class.new.value = 10
|
109
|
+
end
|
110
|
+
|
111
|
+
specify 'modify is synchronized' do
|
112
|
+
mutex = double('mutex')
|
113
|
+
Mutex.stub(:new).with(no_args).and_return(mutex)
|
114
|
+
mutex.should_receive(:lock)
|
115
|
+
mutex.should_receive(:unlock)
|
116
|
+
described_class.new(:foo).modify { |value| value }
|
117
|
+
end
|
118
|
+
|
119
|
+
specify 'compare_and_set is synchronized' do
|
120
|
+
mutex = double('mutex')
|
121
|
+
Mutex.stub(:new).with(no_args).and_return(mutex)
|
122
|
+
mutex.should_receive(:lock)
|
123
|
+
mutex.should_receive(:unlock)
|
124
|
+
described_class.new(14).compare_and_set(14, 2)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe Atomic do
|
129
|
+
it 'inherits from MutexAtomic' do
|
130
|
+
Atomic.ancestors.should include(MutexAtomic)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Concurrent
|
4
4
|
|
5
5
|
describe Configuration do
|
6
|
+
with_full_reset
|
6
7
|
|
7
8
|
it 'creates a global timer pool' do
|
8
9
|
Concurrent.configuration.global_timer_set.should_not be_nil
|
@@ -24,11 +25,12 @@ module Concurrent
|
|
24
25
|
Concurrent.configuration.global_task_pool.should eq executor
|
25
26
|
end
|
26
27
|
|
27
|
-
specify 'writer raises an exception if called
|
28
|
+
specify 'writer raises an exception if called after initialization' do
|
28
29
|
executor = ImmediateExecutor.new
|
29
30
|
Concurrent.configure do |config|
|
30
31
|
config.global_task_pool = executor
|
31
32
|
end
|
33
|
+
Concurrent.configuration.global_task_pool
|
32
34
|
expect {
|
33
35
|
Concurrent.configure do |config|
|
34
36
|
config.global_task_pool = executor
|
@@ -52,11 +54,12 @@ module Concurrent
|
|
52
54
|
Concurrent.configuration.global_operation_pool.should eq executor
|
53
55
|
end
|
54
56
|
|
55
|
-
specify 'writer raises an exception if called
|
57
|
+
specify 'writer raises an exception if called after initialization' do
|
56
58
|
executor = ImmediateExecutor.new
|
57
59
|
Concurrent.configure do |config|
|
58
60
|
config.global_operation_pool = executor
|
59
61
|
end
|
62
|
+
Concurrent.configuration.global_operation_pool
|
60
63
|
expect {
|
61
64
|
Concurrent.configure do |config|
|
62
65
|
config.global_operation_pool = executor
|
@@ -53,6 +53,20 @@ module Concurrent
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
|
57
|
+
context '#reconfigure' do
|
58
|
+
it 'returns value of block used in reconfiguration' do
|
59
|
+
Delay.new { nil }.tap { |d| d.reconfigure { true } }.value.should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns false when process completed?' do
|
63
|
+
d = Delay.new { 1 }
|
64
|
+
d.reconfigure { 2 }.should be_true
|
65
|
+
d.value.should be 2
|
66
|
+
d.reconfigure { 3 }.should be_false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
56
70
|
context '#value' do
|
57
71
|
|
58
72
|
let(:task){ proc{ nil } }
|
@@ -50,20 +50,15 @@ module Concurrent
|
|
50
50
|
context 'with timeout' do
|
51
51
|
it 'should block until timeout' do
|
52
52
|
|
53
|
-
latch = Concurrent::CountDownLatch.new(1)
|
54
53
|
value = 0
|
55
54
|
start = Time.now.to_f
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
latch.count_down
|
56
|
+
future = Concurrent::Future.execute do
|
57
|
+
exchanger.exchange(2, 0.2)
|
60
58
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
|
60
|
+
future.value.should be_nil
|
64
61
|
(Time.now.to_f - start).should >= 0.2
|
65
|
-
t.status.should be_false
|
66
|
-
value.should be_nil
|
67
62
|
end
|
68
63
|
end
|
69
64
|
end
|
@@ -119,20 +119,20 @@ module Concurrent
|
|
119
119
|
|
120
120
|
specify 'a #post task is never executed when the queue is at capacity' do
|
121
121
|
executed = Concurrent::AtomicFixnum.new(0)
|
122
|
-
|
122
|
+
1000.times do
|
123
123
|
subject.post{ executed.increment }
|
124
124
|
end
|
125
125
|
sleep(0.1)
|
126
|
-
executed.value.should <
|
126
|
+
executed.value.should < 1000
|
127
127
|
end
|
128
128
|
|
129
129
|
specify 'a #<< task is never executed when the queue is at capacity' do
|
130
130
|
executed = Concurrent::AtomicFixnum.new(0)
|
131
|
-
|
131
|
+
1000.times do
|
132
132
|
subject << proc { executed.increment }
|
133
133
|
end
|
134
134
|
sleep(0.1)
|
135
|
-
executed.value.should <
|
135
|
+
executed.value.should < 1000
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
@@ -108,7 +108,7 @@ module Concurrent
|
|
108
108
|
it 'raises an exception if set more than once' do
|
109
109
|
i = IVar.new
|
110
110
|
i.set(14)
|
111
|
-
expect {i.set(2)}.to raise_error(MultipleAssignmentError)
|
111
|
+
expect {i.set(2)}.to raise_error(Concurrent::MultipleAssignmentError)
|
112
112
|
i.value.should eq 14
|
113
113
|
end
|
114
114
|
|
@@ -135,7 +135,7 @@ module Concurrent
|
|
135
135
|
it 'raises an exception if set more than once' do
|
136
136
|
i = IVar.new
|
137
137
|
i.fail
|
138
|
-
expect {i.fail}.to raise_error(MultipleAssignmentError)
|
138
|
+
expect {i.fail}.to raise_error(Concurrent::MultipleAssignmentError)
|
139
139
|
i.value.should be_nil
|
140
140
|
end
|
141
141
|
|
@@ -30,24 +30,28 @@ module Concurrent
|
|
30
30
|
obligation.should be_incomplete
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
methods = [:value, :value!, :no_error!]
|
34
|
+
methods.each do |method|
|
35
|
+
describe "##{method}" do
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
it 'should return immediately if timeout is zero' do
|
38
|
+
obligation.send(method, 0).should(method == :no_error! ? eq(obligation) : be_nil)
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
it 'should block on the event if timeout is not set' do
|
42
|
+
obligation.stub(:event).and_return(event)
|
43
|
+
event.should_receive(:wait).with(nil)
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
+
obligation.send method
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should block on the event if timeout is not zero' do
|
49
|
+
obligation.stub(:event).and_return(event)
|
50
|
+
event.should_receive(:wait).with(5)
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
event.should_receive(:wait).with(5)
|
52
|
+
obligation.send(method, 5)
|
53
|
+
end
|
49
54
|
|
50
|
-
obligation.value(5)
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
@@ -98,6 +102,45 @@ module Concurrent
|
|
98
102
|
|
99
103
|
end
|
100
104
|
|
105
|
+
describe '#value!' do
|
106
|
+
|
107
|
+
it 'should return immediately if timeout is zero' do
|
108
|
+
obligation.value!(0).should eq 42
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should return immediately if timeout is not set' do
|
112
|
+
event.should_not_receive(:wait)
|
113
|
+
|
114
|
+
obligation.value!.should eq 42
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should return immediately if timeout is not zero' do
|
118
|
+
event.should_not_receive(:wait)
|
119
|
+
|
120
|
+
obligation.value!(5).should eq 42
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#no_error!' do
|
126
|
+
|
127
|
+
it 'should return immediately if timeout is zero' do
|
128
|
+
obligation.no_error!(0).should eq obligation
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should return immediately if timeout is not set' do
|
132
|
+
event.should_not_receive(:wait)
|
133
|
+
|
134
|
+
obligation.no_error!.should eq obligation
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should return immediately if timeout is not zero' do
|
138
|
+
event.should_not_receive(:wait)
|
139
|
+
|
140
|
+
obligation.no_error!(5).should eq obligation
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
101
144
|
|
102
145
|
end
|
103
146
|
|
@@ -115,26 +158,72 @@ module Concurrent
|
|
115
158
|
it 'should be not incomplete' do
|
116
159
|
obligation.should_not be_incomplete
|
117
160
|
end
|
118
|
-
end
|
119
161
|
|
120
|
-
describe '#value' do
|
121
162
|
|
122
|
-
|
123
|
-
|
163
|
+
describe '#value' do
|
164
|
+
|
165
|
+
it 'should return immediately if timeout is zero' do
|
166
|
+
event.should_not_receive(:wait)
|
167
|
+
|
168
|
+
obligation.value(0).should be_nil
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should return immediately if timeout is not set' do
|
172
|
+
event.should_not_receive(:wait)
|
173
|
+
|
174
|
+
obligation.value.should be_nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should return immediately if timeout is not zero' do
|
178
|
+
event.should_not_receive(:wait)
|
179
|
+
|
180
|
+
obligation.value(5).should be_nil
|
181
|
+
end
|
124
182
|
|
125
|
-
obligation.value(0).should be_nil
|
126
183
|
end
|
127
184
|
|
128
|
-
|
129
|
-
|
185
|
+
describe '#value!' do
|
186
|
+
|
187
|
+
it 'should return immediately if timeout is zero' do
|
188
|
+
event.should_not_receive(:wait)
|
189
|
+
|
190
|
+
-> { obligation.value!(0) }.should raise_error
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should return immediately if timeout is not set' do
|
194
|
+
event.should_not_receive(:wait)
|
195
|
+
|
196
|
+
-> { obligation.value! }.should raise_error
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should return immediately if timeout is not zero' do
|
200
|
+
event.should_not_receive(:wait)
|
201
|
+
|
202
|
+
-> { obligation.value!(5) }.should raise_error
|
203
|
+
end
|
130
204
|
|
131
|
-
obligation.value.should be_nil
|
132
205
|
end
|
133
206
|
|
134
|
-
|
135
|
-
|
207
|
+
describe '#no_error!' do
|
208
|
+
|
209
|
+
it 'should return immediately if timeout is zero' do
|
210
|
+
event.should_not_receive(:wait)
|
211
|
+
|
212
|
+
-> { obligation.no_error!(0) }.should raise_error
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should return immediately if timeout is not set' do
|
216
|
+
event.should_not_receive(:wait)
|
217
|
+
|
218
|
+
-> { obligation.no_error! }.should raise_error
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should return immediately if timeout is not zero' do
|
222
|
+
event.should_not_receive(:wait)
|
223
|
+
|
224
|
+
-> { obligation.no_error!(5) }.should raise_error
|
225
|
+
end
|
136
226
|
|
137
|
-
obligation.value(5).should be_nil
|
138
227
|
end
|
139
228
|
|
140
229
|
end
|