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,102 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
share_examples_for :obligation do
|
4
|
-
|
5
|
-
context '#state' do
|
6
|
-
|
7
|
-
it 'is :pending when first created' do
|
8
|
-
f = pending_subject
|
9
|
-
f.state.should == :pending
|
10
|
-
f.should be_pending
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'is :fulfilled when the handler completes' do
|
14
|
-
f = fulfilled_subject
|
15
|
-
f.state.should == :fulfilled
|
16
|
-
f.should be_fulfilled
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'is :rejected when the handler raises an exception' do
|
20
|
-
f = rejected_subject
|
21
|
-
f.state.should == :rejected
|
22
|
-
f.should be_rejected
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context '#value' do
|
27
|
-
|
28
|
-
let!(:supports_timeout) { pending_subject.method(:value).arity != 0 }
|
29
|
-
|
30
|
-
it 'returns nil when reaching the optional timeout value' do
|
31
|
-
if supports_timeout
|
32
|
-
f = pending_subject
|
33
|
-
f.value(0).should be_nil
|
34
|
-
f.should be_pending
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'returns immediately when timeout is zero' do
|
39
|
-
if supports_timeout
|
40
|
-
Concurrent.should_not_receive(:timeout).with(any_args())
|
41
|
-
f = pending_subject
|
42
|
-
f.value(0).should be_nil
|
43
|
-
f.should be_pending
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'returns the value when fulfilled before timeout' do
|
48
|
-
if supports_timeout
|
49
|
-
f = pending_subject
|
50
|
-
f.value(10).should be_true
|
51
|
-
f.should be_fulfilled
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'returns nil when timeout reached' do
|
56
|
-
if supports_timeout
|
57
|
-
f = pending_subject
|
58
|
-
f.value(0.1).should be_nil
|
59
|
-
f.should be_pending
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'is nil when :pending' do
|
64
|
-
if supports_timeout
|
65
|
-
expected = pending_subject.value(0)
|
66
|
-
expected.should be_nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'blocks the caller when :pending and timeout is nil' do
|
71
|
-
f = pending_subject
|
72
|
-
f.value.should be_true
|
73
|
-
f.should be_fulfilled
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'is nil when :rejected' do
|
77
|
-
expected = rejected_subject.value
|
78
|
-
expected.should be_nil
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'is set to the return value of the block when :fulfilled' do
|
82
|
-
expected = fulfilled_subject.value
|
83
|
-
expected.should eq fulfilled_value
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
context '#reason' do
|
88
|
-
|
89
|
-
it 'is nil when :pending' do
|
90
|
-
pending_subject.reason.should be_nil
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'is nil when :fulfilled' do
|
94
|
-
fulfilled_subject.reason.should be_nil
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'is set to error object of the exception when :rejected' do
|
98
|
-
rejected_subject.reason.should be_a(Exception)
|
99
|
-
rejected_subject.reason.to_s.should =~ /#{rejected_reason}/
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,282 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe Obligation do
|
6
|
-
|
7
|
-
let (:obligation_class) do
|
8
|
-
|
9
|
-
Class.new do
|
10
|
-
include Obligation
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
init_mutex
|
14
|
-
end
|
15
|
-
|
16
|
-
public :state=, :compare_and_set_state, :if_state, :mutex
|
17
|
-
attr_writer :value, :reason
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
let (:obligation) { obligation_class.new }
|
22
|
-
let (:event) { double 'event' }
|
23
|
-
|
24
|
-
share_examples_for :incomplete do
|
25
|
-
it 'should be not completed' do
|
26
|
-
obligation.should_not be_completed
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should be incomplete' do
|
30
|
-
obligation.should be_incomplete
|
31
|
-
end
|
32
|
-
|
33
|
-
methods = [:value, :value!, :no_error!]
|
34
|
-
methods.each do |method|
|
35
|
-
describe "##{method}" do
|
36
|
-
|
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
|
40
|
-
|
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)
|
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)
|
51
|
-
|
52
|
-
obligation.send(method, 5)
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'unscheduled' do
|
60
|
-
before(:each) { obligation.state = :unscheduled }
|
61
|
-
it_should_behave_like :incomplete
|
62
|
-
end
|
63
|
-
|
64
|
-
context 'pending' do
|
65
|
-
before(:each) { obligation.state = :pending }
|
66
|
-
it_should_behave_like :incomplete
|
67
|
-
end
|
68
|
-
|
69
|
-
context 'fulfilled' do
|
70
|
-
|
71
|
-
before(:each) do
|
72
|
-
obligation.state = :fulfilled
|
73
|
-
obligation.send(:value=, 42)
|
74
|
-
obligation.stub(:event).and_return(event)
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should be completed' do
|
78
|
-
obligation.should be_completed
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should be not incomplete' do
|
82
|
-
obligation.should_not be_incomplete
|
83
|
-
end
|
84
|
-
|
85
|
-
describe '#value' do
|
86
|
-
|
87
|
-
it 'should return immediately if timeout is zero' do
|
88
|
-
obligation.value(0).should eq 42
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'should return immediately if timeout is not set' do
|
92
|
-
event.should_not_receive(:wait)
|
93
|
-
|
94
|
-
obligation.value.should eq 42
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should return immediately if timeout is not zero' do
|
98
|
-
event.should_not_receive(:wait)
|
99
|
-
|
100
|
-
obligation.value(5).should eq 42
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
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
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'rejected' do
|
148
|
-
|
149
|
-
before(:each) do
|
150
|
-
obligation.state = :rejected
|
151
|
-
obligation.stub(:event).and_return(event)
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'should be completed' do
|
155
|
-
obligation.should be_completed
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'should be not incomplete' do
|
159
|
-
obligation.should_not be_incomplete
|
160
|
-
end
|
161
|
-
|
162
|
-
|
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
|
182
|
-
|
183
|
-
end
|
184
|
-
|
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
|
204
|
-
|
205
|
-
end
|
206
|
-
|
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
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
end
|
230
|
-
|
231
|
-
describe '#compare_and_set_state' do
|
232
|
-
|
233
|
-
before(:each) { obligation.state = :unscheduled }
|
234
|
-
|
235
|
-
context 'unexpected state' do
|
236
|
-
it 'should return false if state is not the expected one' do
|
237
|
-
obligation.compare_and_set_state(:pending, :rejected).should be_false
|
238
|
-
end
|
239
|
-
|
240
|
-
it 'should not change the state if current is not the expected one' do
|
241
|
-
obligation.compare_and_set_state(:pending, :rejected)
|
242
|
-
obligation.state.should eq :unscheduled
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
context 'expected state' do
|
247
|
-
it 'should return true if state is the expected one' do
|
248
|
-
obligation.compare_and_set_state(:pending, :unscheduled).should be_true
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'should not change the state if current is not the expected one' do
|
252
|
-
obligation.compare_and_set_state(:pending, :unscheduled)
|
253
|
-
obligation.state.should eq :pending
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
describe '#if_state' do
|
260
|
-
|
261
|
-
before(:each) { obligation.state = :unscheduled }
|
262
|
-
|
263
|
-
it 'should raise without block' do
|
264
|
-
expect { obligation.if_state(:pending) }.to raise_error(ArgumentError)
|
265
|
-
end
|
266
|
-
|
267
|
-
it 'should return false if state is not expected' do
|
268
|
-
obligation.if_state(:pending, :rejected) { 42 }.should be_false
|
269
|
-
end
|
270
|
-
|
271
|
-
it 'should the block value if state is expected' do
|
272
|
-
obligation.if_state(:rejected, :unscheduled) { 42 }.should eq 42
|
273
|
-
end
|
274
|
-
|
275
|
-
it 'should execute the block within the mutex' do
|
276
|
-
obligation.if_state(:unscheduled) { obligation.mutex.should be_locked }
|
277
|
-
end
|
278
|
-
|
279
|
-
end
|
280
|
-
|
281
|
-
end
|
282
|
-
end
|
@@ -1,177 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
share_examples_for :observable do
|
4
|
-
|
5
|
-
let(:observer_set) do
|
6
|
-
subject.instance_variable_get(:@observers)
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:observer_class) do
|
10
|
-
Class.new do
|
11
|
-
def initialize(&block)
|
12
|
-
@block = block
|
13
|
-
end
|
14
|
-
def update(*args)
|
15
|
-
@block.call(*args) if @block
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:observer){ observer_class.new }
|
21
|
-
|
22
|
-
let!(:observer_func){ :notify }
|
23
|
-
|
24
|
-
let(:observer_with_func_class) do
|
25
|
-
Class.new do
|
26
|
-
def initialize(&block)
|
27
|
-
@block = block
|
28
|
-
end
|
29
|
-
def notify(*args)
|
30
|
-
@block.call(*args) if @block
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
let(:observer_with_func){ observer_with_func_class.new }
|
36
|
-
|
37
|
-
context '#add_observer' do
|
38
|
-
|
39
|
-
it 'adds an observer if called before first notification' do
|
40
|
-
observer_set.should_receive(:add_observer).with(any_args)
|
41
|
-
subject.add_observer(observer)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'adds an observer with :func if called before first notification' do
|
45
|
-
observer_set.should_receive(:add_observer).with(observer_with_func, :notify)
|
46
|
-
subject.add_observer(observer_with_func, observer_func)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'creates an observer from a block if called before first notification' do
|
50
|
-
block = proc{ nil }
|
51
|
-
observer_set.should_receive(:add_observer).with(any_args)
|
52
|
-
subject.add_observer(&block)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'raises an exception if not given an observer or a block' do
|
56
|
-
expect {
|
57
|
-
subject.add_observer
|
58
|
-
}.to raise_error(ArgumentError)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'raises an exception when given both an observer and a block' do
|
62
|
-
expect {
|
63
|
-
subject.add_observer(observer){ nil }
|
64
|
-
}.to raise_error(ArgumentError)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context '#delete_observer' do
|
69
|
-
|
70
|
-
it 'deletes the given observer if called before first notification' do
|
71
|
-
subject.count_observers.should eq 0
|
72
|
-
subject.add_observer(observer)
|
73
|
-
subject.count_observers.should eq 1
|
74
|
-
subject.delete_observer(observer)
|
75
|
-
subject.count_observers.should eq 0
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'returns the removed observer if found in the observer set' do
|
79
|
-
subject.add_observer(observer)
|
80
|
-
subject.delete_observer(observer).should eq observer
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'returns the given observer even when not found in the observer set' do
|
84
|
-
subject.delete_observer(observer).should eq observer
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
context '#delete_observers' do
|
89
|
-
|
90
|
-
it 'deletes all observers when called before first notification' do
|
91
|
-
5.times{ subject.add_observer(observer_class.new) }
|
92
|
-
subject.count_observers.should eq 5
|
93
|
-
subject.delete_observers
|
94
|
-
subject.count_observers.should eq 0
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'returns self' do
|
98
|
-
subject.delete_observers.should eq subject
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context '#count_observers' do
|
103
|
-
|
104
|
-
it 'returns zero for a new observable object' do
|
105
|
-
subject.count_observers.should eq 0
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'returns a count of registered observers if called before first notification' do
|
109
|
-
5.times{ subject.add_observer(observer_class.new) }
|
110
|
-
subject.count_observers.should eq 5
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'returns zero after #delete_observers has been called' do
|
114
|
-
5.times{ subject.add_observer(observer_class.new) }
|
115
|
-
subject.delete_observers
|
116
|
-
subject.count_observers.should eq 0
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'first notification' do
|
121
|
-
|
122
|
-
it 'calls the #update method on all observers without a specified :func' do
|
123
|
-
latch = Concurrent::CountDownLatch.new(5)
|
124
|
-
5.times do
|
125
|
-
subject.add_observer(observer_class.new{ latch.count_down })
|
126
|
-
end
|
127
|
-
trigger_observable(subject)
|
128
|
-
latch.count.should eq 0
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'calls the appropriate function on all observers which specified a :func' do
|
132
|
-
latch = Concurrent::CountDownLatch.new(5)
|
133
|
-
5.times do
|
134
|
-
obs = observer_with_func_class.new{ latch.count_down }
|
135
|
-
subject.add_observer(obs, observer_func)
|
136
|
-
end
|
137
|
-
trigger_observable(subject)
|
138
|
-
latch.wait(1)
|
139
|
-
latch.count.should eq 0
|
140
|
-
end
|
141
|
-
|
142
|
-
it 'calls the proc for all observers added as a block' do
|
143
|
-
latch = Concurrent::CountDownLatch.new(5)
|
144
|
-
5.times do
|
145
|
-
subject.add_observer{ latch.count_down }
|
146
|
-
end
|
147
|
-
trigger_observable(subject)
|
148
|
-
latch.wait(1)
|
149
|
-
latch.count.should eq 0
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'does not notify any observers removed with #delete_observer' do
|
153
|
-
latch = Concurrent::CountDownLatch.new(5)
|
154
|
-
|
155
|
-
obs = observer_class.new{ latch.count_down }
|
156
|
-
subject.add_observer(obs)
|
157
|
-
subject.delete_observer(obs)
|
158
|
-
|
159
|
-
trigger_observable(subject)
|
160
|
-
latch.wait(1)
|
161
|
-
latch.count.should eq 5
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'does not notify any observers after #delete_observers called' do
|
165
|
-
latch = Concurrent::CountDownLatch.new(5)
|
166
|
-
5.times do
|
167
|
-
subject.add_observer(observer_class.new{ latch.count_down })
|
168
|
-
end
|
169
|
-
|
170
|
-
subject.delete_observers
|
171
|
-
|
172
|
-
trigger_observable(subject)
|
173
|
-
latch.wait(1)
|
174
|
-
latch.count.should eq 5
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|