concurrent-ruby 0.1.1 → 0.2.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 +48 -1
- data/lib/concurrent.rb +8 -1
- data/lib/concurrent/agent.rb +19 -40
- data/lib/concurrent/cached_thread_pool.rb +10 -11
- data/lib/concurrent/defer.rb +8 -12
- data/lib/concurrent/executor.rb +95 -0
- data/lib/concurrent/fixed_thread_pool.rb +12 -6
- data/lib/concurrent/functions.rb +120 -0
- data/lib/concurrent/future.rb +8 -20
- data/lib/concurrent/global_thread_pool.rb +13 -0
- data/lib/concurrent/goroutine.rb +5 -1
- data/lib/concurrent/null_thread_pool.rb +22 -0
- data/lib/concurrent/obligation.rb +10 -64
- data/lib/concurrent/promise.rb +38 -60
- data/lib/concurrent/reactor.rb +166 -0
- data/lib/concurrent/reactor/drb_async_demux.rb +83 -0
- data/lib/concurrent/reactor/tcp_sync_demux.rb +131 -0
- data/lib/concurrent/supervisor.rb +100 -0
- data/lib/concurrent/thread_pool.rb +16 -5
- data/lib/concurrent/utilities.rb +8 -0
- data/lib/concurrent/version.rb +1 -1
- data/md/defer.md +4 -4
- data/md/executor.md +187 -0
- data/md/promise.md +2 -0
- data/md/thread_pool.md +27 -0
- data/spec/concurrent/agent_spec.rb +8 -27
- data/spec/concurrent/cached_thread_pool_spec.rb +14 -1
- data/spec/concurrent/defer_spec.rb +17 -21
- data/spec/concurrent/event_machine_defer_proxy_spec.rb +159 -149
- data/spec/concurrent/executor_spec.rb +200 -0
- data/spec/concurrent/fixed_thread_pool_spec.rb +2 -3
- data/spec/concurrent/functions_spec.rb +217 -0
- data/spec/concurrent/future_spec.rb +4 -11
- data/spec/concurrent/global_thread_pool_spec.rb +38 -0
- data/spec/concurrent/goroutine_spec.rb +15 -0
- data/spec/concurrent/null_thread_pool_spec.rb +54 -0
- data/spec/concurrent/obligation_shared.rb +127 -116
- data/spec/concurrent/promise_spec.rb +16 -14
- data/spec/concurrent/reactor/drb_async_demux_spec.rb +196 -0
- data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +410 -0
- data/spec/concurrent/reactor_spec.rb +364 -0
- data/spec/concurrent/supervisor_spec.rb +258 -0
- data/spec/concurrent/thread_pool_shared.rb +156 -161
- data/spec/concurrent/utilities_spec.rb +30 -1
- data/spec/spec_helper.rb +13 -0
- metadata +38 -9
@@ -41,7 +41,7 @@ module Concurrent
|
|
41
41
|
context '#kill' do
|
42
42
|
|
43
43
|
it 'kills all threads' do
|
44
|
-
Thread.should_receive(:kill).
|
44
|
+
Thread.should_receive(:kill).at_least(5).times
|
45
45
|
pool = FixedThreadPool.new(5)
|
46
46
|
pool.kill
|
47
47
|
sleep(0.1)
|
@@ -74,10 +74,9 @@ module Concurrent
|
|
74
74
|
it 'restarts threads that experience exception' do
|
75
75
|
pool = FixedThreadPool.new(5)
|
76
76
|
3.times{ pool << proc{ raise StandardError } }
|
77
|
-
sleep(
|
77
|
+
sleep(5)
|
78
78
|
pool.size.should eq 5
|
79
79
|
pool.status.should_not include(nil)
|
80
|
-
#pool.status.include?(nil).should be_false
|
81
80
|
end
|
82
81
|
end
|
83
82
|
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
|
5
|
+
describe 'functions' do
|
6
|
+
|
7
|
+
context '#post' do
|
8
|
+
|
9
|
+
it 'calls #post when supported by the object' do
|
10
|
+
object = Class.new{
|
11
|
+
def post() nil; end
|
12
|
+
}.new
|
13
|
+
object.should_receive(:post).with(no_args())
|
14
|
+
post(object){ nil }
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises an exception when not supported by the object' do
|
18
|
+
object = Class.new{ }.new
|
19
|
+
lambda {
|
20
|
+
post(object){ nil }
|
21
|
+
}.should raise_error(ArgumentError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context '#deref' do
|
26
|
+
|
27
|
+
it 'returns the value of the #deref function' do
|
28
|
+
object = Class.new{
|
29
|
+
def deref() nil; end
|
30
|
+
}.new
|
31
|
+
object.should_receive(:deref).with(nil)
|
32
|
+
deref(object, nil){ nil }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns the value of the #value function' do
|
36
|
+
object = Class.new{
|
37
|
+
def value() nil; end
|
38
|
+
}.new
|
39
|
+
object.should_receive(:value).with(nil)
|
40
|
+
deref(object, nil){ nil }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises an exception when not supported by the object' do
|
44
|
+
object = Class.new{ }.new
|
45
|
+
lambda {
|
46
|
+
deref(object, nil){ nil }
|
47
|
+
}.should raise_error(ArgumentError)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context '#pending?' do
|
52
|
+
|
53
|
+
it 'returns the value of the #pending? function' do
|
54
|
+
object = Class.new{
|
55
|
+
def pending?() nil; end
|
56
|
+
}.new
|
57
|
+
object.should_receive(:pending?).with(no_args())
|
58
|
+
pending?(object){ nil }
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'raises an exception when not supported by the object' do
|
62
|
+
object = Class.new{ }.new
|
63
|
+
lambda {
|
64
|
+
pending?(object){ nil }
|
65
|
+
}.should raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context '#fulfilled?' do
|
70
|
+
|
71
|
+
it 'returns the value of the #fulfilled? function' do
|
72
|
+
object = Class.new{
|
73
|
+
def fulfilled?() nil; end
|
74
|
+
}.new
|
75
|
+
object.should_receive(:fulfilled?).with(no_args())
|
76
|
+
fulfilled?(object){ nil }
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns the value of the #realized? function' do
|
80
|
+
object = Class.new{
|
81
|
+
def realized?() nil; end
|
82
|
+
}.new
|
83
|
+
object.should_receive(:realized?).with(no_args())
|
84
|
+
fulfilled?(object){ nil }
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'raises an exception when not supported by the object' do
|
88
|
+
object = Class.new{ }.new
|
89
|
+
lambda {
|
90
|
+
fulfilled?(object){ nil }
|
91
|
+
}.should raise_error(ArgumentError)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context '#realized?' do
|
96
|
+
|
97
|
+
it 'returns the value of the #realized? function' do
|
98
|
+
object = Class.new{
|
99
|
+
def realized?() nil; end
|
100
|
+
}.new
|
101
|
+
object.should_receive(:realized?).with(no_args())
|
102
|
+
realized?(object){ nil }
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns the value of the #fulfilled? function' do
|
106
|
+
object = Class.new{
|
107
|
+
def fulfilled?() nil; end
|
108
|
+
}.new
|
109
|
+
object.should_receive(:fulfilled?).with(no_args())
|
110
|
+
realized?(object){ nil }
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'raises an exception when not supported by the object' do
|
114
|
+
object = Class.new{ }.new
|
115
|
+
lambda {
|
116
|
+
realized?(object){ nil }
|
117
|
+
}.should raise_error(ArgumentError)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context '#rejected?' do
|
122
|
+
|
123
|
+
it 'returns the value of the #rejected? function' do
|
124
|
+
object = Class.new{
|
125
|
+
def rejected?() nil; end
|
126
|
+
}.new
|
127
|
+
object.should_receive(:rejected?).with(no_args())
|
128
|
+
rejected?(object){ nil }
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'raises an exception when not supported by the object' do
|
132
|
+
object = Class.new{ }.new
|
133
|
+
lambda {
|
134
|
+
rejected?(object){ nil }
|
135
|
+
}.should raise_error(ArgumentError)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe Agent do
|
141
|
+
|
142
|
+
before(:each) do
|
143
|
+
Agent.thread_pool = FixedThreadPool.new(1)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'aliases #<< for Agent#post' do
|
147
|
+
subject = Agent.new(0)
|
148
|
+
subject << proc{ 100 }
|
149
|
+
sleep(0.1)
|
150
|
+
subject.value.should eq 100
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'aliases Kernel#agent for Agent.new' do
|
154
|
+
agent(10).should be_a(Agent)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'aliases Kernel#deref for #deref' do
|
158
|
+
deref(Agent.new(10)).should eq 10
|
159
|
+
deref(Agent.new(10), 10).should eq 10
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'aliases Kernel:post for Agent#post' do
|
163
|
+
subject = Agent.new(0)
|
164
|
+
post(subject){ 100 }
|
165
|
+
sleep(0.1)
|
166
|
+
subject.value.should eq 100
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe Defer do
|
171
|
+
|
172
|
+
before(:each) do
|
173
|
+
Defer.thread_pool = FixedThreadPool.new(1)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'aliases Kernel#defer' do
|
177
|
+
defer{ nil }.should be_a(Defer)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe Executor do
|
182
|
+
|
183
|
+
it 'aliases Kernel#executor' do
|
184
|
+
ex = executor('executor'){ nil }
|
185
|
+
ex.should be_a(Executor::ExecutionContext)
|
186
|
+
ex.kill
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe Future do
|
191
|
+
|
192
|
+
before(:each) do
|
193
|
+
Future.thread_pool = FixedThreadPool.new(1)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'aliases Kernel#future for Future.new' do
|
197
|
+
future().should be_a(Future)
|
198
|
+
future(){ nil }.should be_a(Future)
|
199
|
+
future(1, 2, 3).should be_a(Future)
|
200
|
+
future(1, 2, 3){ nil }.should be_a(Future)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe Promise do
|
205
|
+
|
206
|
+
before(:each) do
|
207
|
+
Promise.thread_pool = FixedThreadPool.new(1)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'aliases Kernel#promise for Promise.new' do
|
211
|
+
promise().should be_a(Promise)
|
212
|
+
promise(){ nil }.should be_a(Promise)
|
213
|
+
promise(1, 2, 3).should be_a(Promise)
|
214
|
+
promise(1, 2, 3){ nil }.should be_a(Promise)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -9,7 +9,7 @@ module Concurrent
|
|
9
9
|
let!(:rejected_reason) { StandardError.new('mojo jojo') }
|
10
10
|
|
11
11
|
let(:pending_subject) do
|
12
|
-
Future.new{ sleep(
|
12
|
+
Future.new{ sleep(3); fulfilled_value }
|
13
13
|
end
|
14
14
|
|
15
15
|
let(:fulfilled_subject) do
|
@@ -21,10 +21,10 @@ module Concurrent
|
|
21
21
|
end
|
22
22
|
|
23
23
|
before(:each) do
|
24
|
-
|
24
|
+
Future.thread_pool = FixedThreadPool.new(1)
|
25
25
|
end
|
26
26
|
|
27
|
-
it_should_behave_like Obligation
|
27
|
+
it_should_behave_like Concurrent::Obligation
|
28
28
|
|
29
29
|
context 'behavior' do
|
30
30
|
|
@@ -40,7 +40,7 @@ module Concurrent
|
|
40
40
|
context '#initialize' do
|
41
41
|
|
42
42
|
it 'spawns a new thread when a block is given' do
|
43
|
-
|
43
|
+
Future.thread_pool.should_receive(:post).once.with(any_args())
|
44
44
|
Future.new{ nil }
|
45
45
|
end
|
46
46
|
|
@@ -102,13 +102,6 @@ module Concurrent
|
|
102
102
|
it 'aliases #deref for #value' do
|
103
103
|
fulfilled_subject.deref.should eq fulfilled_value
|
104
104
|
end
|
105
|
-
|
106
|
-
it 'aliases Kernel#future for Future.new' do
|
107
|
-
future().should be_a(Future)
|
108
|
-
future(){ nil }.should be_a(Future)
|
109
|
-
future(1, 2, 3).should be_a(Future)
|
110
|
-
future(1, 2, 3){ nil }.should be_a(Future)
|
111
|
-
end
|
112
105
|
end
|
113
106
|
end
|
114
107
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
|
5
|
+
describe UsesGlobalThreadPool do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
$GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'defaults to the global thread pool' do
|
12
|
+
clazz = Class.new{ include UsesGlobalThreadPool }
|
13
|
+
clazz.thread_pool.should eq $GLOBAL_THREAD_POOL
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets and gets the thread pool for the class' do
|
17
|
+
pool = NullThreadPool.new
|
18
|
+
clazz = Class.new{ include UsesGlobalThreadPool }
|
19
|
+
|
20
|
+
clazz.thread_pool = pool
|
21
|
+
clazz.thread_pool.should eq pool
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'gives each class its own thread pool' do
|
25
|
+
clazz1 = Class.new{ include UsesGlobalThreadPool }
|
26
|
+
clazz2 = Class.new{ include UsesGlobalThreadPool }
|
27
|
+
clazz3 = Class.new{ include UsesGlobalThreadPool }
|
28
|
+
|
29
|
+
clazz1.thread_pool = FixedThreadPool.new(1)
|
30
|
+
clazz2.thread_pool = CachedThreadPool.new
|
31
|
+
clazz3.thread_pool = NullThreadPool.new
|
32
|
+
|
33
|
+
clazz1.thread_pool.should_not eq clazz2.thread_pool
|
34
|
+
clazz2.thread_pool.should_not eq clazz3.thread_pool
|
35
|
+
clazz3.thread_pool.should_not eq clazz1.thread_pool
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -48,5 +48,20 @@ module Concurrent
|
|
48
48
|
sleep(0.1)
|
49
49
|
@expected.should eq [1,2,3]
|
50
50
|
end
|
51
|
+
|
52
|
+
it 'accepts an alternate thread pool as the first argument' do
|
53
|
+
pool = Concurrent::FixedThreadPool.new(2)
|
54
|
+
pool.should_receive(:post).with(no_args())
|
55
|
+
go(pool){ sleep(0.1) }
|
56
|
+
sleep(0.2)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'passes all other arguments to the block when a thread pool is given' do
|
60
|
+
@expected = nil
|
61
|
+
pool = Concurrent::FixedThreadPool.new(2)
|
62
|
+
go(pool, 1, 2, 3){|a, b, c| @expected = [c, b, a] }
|
63
|
+
sleep(0.1)
|
64
|
+
@expected.should eq [3, 2, 1]
|
65
|
+
end
|
51
66
|
end
|
52
67
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'concurrent/goroutine'
|
4
|
+
|
5
|
+
module Concurrent
|
6
|
+
|
7
|
+
describe NullThreadPool do
|
8
|
+
|
9
|
+
subject { NullThreadPool.new }
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
$GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
context '#post' do
|
16
|
+
|
17
|
+
it 'proxies a call without arguments' do
|
18
|
+
Thread.should_receive(:new).with(no_args())
|
19
|
+
$GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
|
20
|
+
subject.post{ nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'proxies a call with arguments' do
|
24
|
+
Thread.should_receive(:new).with(1,2,3)
|
25
|
+
$GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
|
26
|
+
subject.post(1,2,3){ nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'aliases #<<' do
|
30
|
+
Thread.should_receive(:new).with(no_args())
|
31
|
+
$GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
|
32
|
+
subject << proc{ nil }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'operation' do
|
37
|
+
|
38
|
+
context 'goroutine' do
|
39
|
+
|
40
|
+
it 'gets a new thread' do
|
41
|
+
$GLOBAL_THREAD_POOL = subject
|
42
|
+
|
43
|
+
t = Thread.new{ nil }
|
44
|
+
|
45
|
+
Thread.should_receive(:new).with(no_args()).and_return(t)
|
46
|
+
go{ nil }
|
47
|
+
|
48
|
+
Thread.should_receive(:new).with(1,2,3).and_return(t)
|
49
|
+
go(1,2,3){ nil }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -1,121 +1,132 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
3
|
+
share_examples_for Concurrent::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
|
+
it 'blocks the caller when :pending and timeout is nil' do
|
29
|
+
f = pending_subject
|
30
|
+
sleep(0.1)
|
31
|
+
f.value.should be_true
|
32
|
+
f.should be_fulfilled
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns nil when reaching the optional timeout value' do
|
36
|
+
f = pending_subject
|
37
|
+
sleep(0.1)
|
38
|
+
f.value(0).should be_nil
|
39
|
+
f.should be_pending
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns immediately when timeout is zero' do
|
43
|
+
Timeout.should_not_receive(:timeout).with(any_args())
|
44
|
+
f = pending_subject
|
45
|
+
sleep(0.1)
|
46
|
+
f.value(0).should be_nil
|
47
|
+
f.should be_pending
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns the value when fulfilled before timeout' do
|
51
|
+
f = pending_subject
|
52
|
+
sleep(0.1)
|
53
|
+
f.value(10).should be_true
|
54
|
+
f.should be_fulfilled
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns nil when timeout reached' do
|
58
|
+
f = pending_subject
|
59
|
+
sleep(0.1)
|
60
|
+
f.value(0.1).should be_nil
|
61
|
+
f.should be_pending
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is nil when :pending' do
|
65
|
+
expected = pending_subject.value(0)
|
66
|
+
expected.should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'is nil when :rejected' do
|
70
|
+
expected = rejected_subject.value
|
71
|
+
expected.should be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'is set to the return value of the block when :fulfilled' do
|
75
|
+
expected = fulfilled_subject.value
|
76
|
+
expected.should eq fulfilled_value
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context '#reason' do
|
81
|
+
|
82
|
+
it 'is nil when :pending' do
|
83
|
+
pending_subject.reason.should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'is nil when :fulfilled' do
|
87
|
+
fulfilled_subject.reason.should be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'is set to error object of the exception when :rejected' do
|
91
|
+
rejected_subject.reason.should be_a(Exception)
|
92
|
+
rejected_subject.reason.to_s.should =~ /#{rejected_reason}/
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'Kernel aliases' do
|
97
|
+
|
98
|
+
it 'aliases Kernel#deref for #deref' do
|
99
|
+
deref(fulfilled_subject).should eq fulfilled_value
|
100
|
+
deref(fulfilled_subject, 0).should eq fulfilled_value
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'aliases Kernel#pending? for #pending?' do
|
104
|
+
#NOTE: was structured like others but was incorrectly failing
|
105
|
+
# on fulfilled_subject
|
106
|
+
fulfilled_subject.should_receive(:pending?).once
|
107
|
+
pending?(fulfilled_subject)
|
108
|
+
pending_subject.should_receive(:pending?).once
|
109
|
+
pending?(pending_subject)
|
110
|
+
rejected_subject.should_receive(:pending?).once
|
111
|
+
pending?(rejected_subject)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'aliases Kernel#fulfilled? for #fulfilled?' do
|
115
|
+
fulfilled?(fulfilled_subject).should be_true
|
116
|
+
fulfilled?(pending_subject).should be_false
|
117
|
+
fulfilled?(rejected_subject).should be_false
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'aliases Kernel#realized? for #realized?' do
|
121
|
+
realized?(fulfilled_subject).should be_true
|
122
|
+
realized?(pending_subject).should be_false
|
123
|
+
realized?(rejected_subject).should be_false
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'aliases Kernel#rejected? for #rejected?' do
|
127
|
+
rejected?(rejected_subject).should be_true
|
128
|
+
rejected?(fulfilled_subject).should be_false
|
129
|
+
rejected?(pending_subject).should be_false
|
119
130
|
end
|
120
131
|
end
|
121
132
|
end
|