promise.rb 0.1.0 → 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 +8 -8
- data/.travis.yml +10 -2
- data/Gemfile +1 -4
- data/Gemfile.devtools +2 -0
- data/lib/promise.rb +3 -2
- data/lib/promise/callback.rb +1 -0
- data/lib/promise/progress.rb +8 -3
- data/lib/promise/version.rb +1 -1
- data/spec/promise_spec.rb +215 -211
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDMwMDA0YTBhY2ZkMzE2MzVhNjBkMmQ4ZGRjN2M0MzRiODFkY2Q2OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDI1ZDlhYzFmM2ViMzkwYzI0YzJhMTM4MDg3YmFhMzhjZjQ2YTcyMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODExMWZlZjg3YWNmMGM2ZmZhMGI4M2I0OTJlMjJkN2VkOTY4M2E5NjIzZDlj
|
10
|
+
Nzk1Njc0NjQwNTUzMGJjMGJmZmJlOGNmNGI1YTFhZWZkNGMwNzM3ZjIzOGVm
|
11
|
+
ZjBkN2NjMzIxZGFiYTk4OTBmOGUyOWMwYzVkMjRlNzY4OTBmNzc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzBhMGVmODUzZTVmMTg2YjAwMDlmYmY5YTY5MTNlY2FiN2E5OWNiYWFkMzMx
|
14
|
+
YTY2MTU5YzBlYWYyZWI2ZjBhOWM5Y2IzMjI4MTFkMTdlNTEwMzFkNWEzYjg3
|
15
|
+
Zjg3NTAwZTc4NWNjODhiNGMyZjc4ZjJmNGFhMmE0ZmY4ZDZhZDk=
|
data/.travis.yml
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
|
-
|
5
|
-
|
4
|
+
- 2.0.0
|
5
|
+
- jruby-19mode
|
6
|
+
- rbx-19mode
|
7
|
+
- ruby-head
|
8
|
+
- jruby-head
|
9
|
+
matrix:
|
10
|
+
allow_failures:
|
11
|
+
- rvm: ruby-head
|
12
|
+
- rvm: jruby-head
|
13
|
+
script: bundle exec rake ci:metrics -t
|
data/Gemfile
CHANGED
@@ -2,12 +2,9 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
ruby '1.9.3'
|
6
|
-
|
7
5
|
gemspec
|
8
6
|
|
9
|
-
gem 'devtools', git: 'https://github.com/
|
10
|
-
ref: 'branch-detection2'
|
7
|
+
gem 'devtools', git: 'https://github.com/rom-rb/devtools.git'
|
11
8
|
gem 'fuubar', git: 'https://github.com/lgierth/fuubar.git',
|
12
9
|
ref: 'static-percentage'
|
13
10
|
gem 'awesome_print'
|
data/Gemfile.devtools
CHANGED
data/lib/promise.rb
CHANGED
@@ -6,7 +6,7 @@ require 'promise/callback'
|
|
6
6
|
require 'promise/progress'
|
7
7
|
|
8
8
|
class Promise
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :value, :reason
|
10
10
|
|
11
11
|
def initialize
|
12
12
|
@state = :pending
|
@@ -26,7 +26,8 @@ class Promise
|
|
26
26
|
@state == :rejected
|
27
27
|
end
|
28
28
|
|
29
|
-
def then(on_fulfill = nil, on_reject = nil)
|
29
|
+
def then(on_fulfill = nil, on_reject = nil, &block)
|
30
|
+
on_fulfill = block if block
|
30
31
|
next_promise = add_callbacks(on_fulfill, on_reject)
|
31
32
|
|
32
33
|
maybe_dispatch(@on_fulfill.last, @on_reject.last)
|
data/lib/promise/callback.rb
CHANGED
data/lib/promise/progress.rb
CHANGED
@@ -2,12 +2,17 @@
|
|
2
2
|
|
3
3
|
class Promise
|
4
4
|
module Progress
|
5
|
-
def
|
6
|
-
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@on_progress = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_progress(&block)
|
11
|
+
@on_progress << block
|
7
12
|
end
|
8
13
|
|
9
14
|
def progress(status)
|
10
|
-
if pending?
|
15
|
+
if pending?
|
11
16
|
@on_progress.each { |block| block.call(status) }
|
12
17
|
end
|
13
18
|
end
|
data/lib/promise/version.rb
CHANGED
data/spec/promise_spec.rb
CHANGED
@@ -10,288 +10,292 @@ describe Promise do
|
|
10
10
|
let(:reason) { double('reason') }
|
11
11
|
let(:other_reason) { double('other_reason') }
|
12
12
|
|
13
|
-
describe '
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
13
|
+
describe '3.1.1 pending' do
|
14
|
+
it 'transitions to fulfilled' do
|
15
|
+
subject.fulfill(value)
|
16
|
+
expect(subject).to be_fulfilled
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
19
|
+
it 'transitions to rejected' do
|
20
|
+
subject.reject(reason)
|
21
|
+
expect(subject).to be_rejected
|
24
22
|
end
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
describe '3.1.2 fulfilled' do
|
26
|
+
it 'does not transition to other states' do
|
27
|
+
subject.fulfill(value)
|
28
|
+
subject.reject(reason)
|
29
|
+
expect(subject).to be_fulfilled
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
it 'has an immutable value' do
|
33
|
+
subject.fulfill(value)
|
34
|
+
expect(subject.value).to eq(value)
|
36
35
|
|
37
|
-
|
38
|
-
|
36
|
+
subject.fulfill(other_value)
|
37
|
+
expect(subject.value).to eq(value)
|
39
38
|
|
40
|
-
|
41
|
-
end
|
39
|
+
expect(subject.value).to be_frozen
|
42
40
|
end
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
describe '3.1.3 rejected' do
|
44
|
+
it 'does not transition to other states' do
|
45
|
+
subject.reject(reason)
|
46
|
+
subject.fulfill(value)
|
47
|
+
expect(subject).to be_rejected
|
48
|
+
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
it 'has an immutable reason' do
|
51
|
+
subject.reject(reason)
|
52
|
+
expect(subject.reason).to eq(reason)
|
54
53
|
|
55
|
-
|
56
|
-
|
54
|
+
subject.reject(other_reason)
|
55
|
+
expect(subject.reason).to eq(reason)
|
57
56
|
|
58
|
-
|
59
|
-
end
|
57
|
+
expect(subject.reason).to be_frozen
|
60
58
|
end
|
61
59
|
end
|
62
60
|
|
63
|
-
describe '
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
subject.fulfill(value)
|
68
|
-
end
|
61
|
+
describe '3.2.1 on_fulfill' do
|
62
|
+
it 'is optional' do
|
63
|
+
subject.then
|
64
|
+
subject.fulfill(value)
|
69
65
|
end
|
66
|
+
end
|
70
67
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
68
|
+
describe '3.2.1 on_reject' do
|
69
|
+
it 'is optional' do
|
70
|
+
subject.then(proc { |_| })
|
71
|
+
subject.reject(reason)
|
76
72
|
end
|
73
|
+
end
|
77
74
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
subject.fulfill(value)
|
84
|
-
expect(state).to eq(:fulfilled)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'is called with fulfillment value' do
|
88
|
-
result = nil
|
89
|
-
subject.then(proc { |val| result = val })
|
75
|
+
describe '3.2.2 on_fulfill' do
|
76
|
+
it 'is called after promise is fulfilled' do
|
77
|
+
fulfilled = nil
|
78
|
+
subject.then(proc { |_| fulfilled = subject.fulfilled? })
|
90
79
|
|
91
|
-
|
92
|
-
|
93
|
-
|
80
|
+
subject.fulfill(value)
|
81
|
+
expect(fulfilled).to eq(true)
|
82
|
+
end
|
94
83
|
|
95
|
-
|
96
|
-
|
97
|
-
|
84
|
+
it 'is called with fulfillment value' do
|
85
|
+
result = nil
|
86
|
+
subject.then(proc { |val| result = val })
|
98
87
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
88
|
+
subject.fulfill(value)
|
89
|
+
expect(result).to eq(value)
|
90
|
+
end
|
103
91
|
|
104
|
-
|
105
|
-
|
106
|
-
|
92
|
+
it 'is called not more than once' do
|
93
|
+
called = 0
|
94
|
+
subject.then(proc { |_| called += 1 })
|
107
95
|
|
108
|
-
|
109
|
-
|
110
|
-
|
96
|
+
subject.fulfill(value)
|
97
|
+
subject.fulfill(value)
|
98
|
+
expect(called).to eq(1)
|
111
99
|
end
|
112
100
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
subject.then(nil, proc { |_| state = subject.state })
|
101
|
+
it 'is not called if on_reject has been called' do
|
102
|
+
called = false
|
103
|
+
subject.then(proc { |_| called = true })
|
117
104
|
|
118
|
-
|
119
|
-
|
120
|
-
|
105
|
+
subject.reject(reason)
|
106
|
+
expect(called).to eq(false)
|
107
|
+
end
|
121
108
|
|
122
|
-
|
123
|
-
|
124
|
-
|
109
|
+
it 'can be passed as a block' do
|
110
|
+
result = nil
|
111
|
+
subject.then { |val| result = val }
|
125
112
|
|
126
|
-
|
127
|
-
|
128
|
-
|
113
|
+
subject.fulfill(value)
|
114
|
+
expect(result).to eq(value)
|
115
|
+
end
|
116
|
+
end
|
129
117
|
|
130
|
-
|
131
|
-
|
132
|
-
|
118
|
+
describe '3.2.3 on_reject' do
|
119
|
+
it 'is called after promise is rejected' do
|
120
|
+
rejected = nil
|
121
|
+
subject.then(nil, proc { |_| rejected = subject.rejected? })
|
133
122
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
123
|
+
subject.reject(reason)
|
124
|
+
expect(rejected).to eq(true)
|
125
|
+
end
|
138
126
|
|
139
|
-
|
140
|
-
|
141
|
-
|
127
|
+
it 'is called with rejection reason' do
|
128
|
+
result = nil
|
129
|
+
subject.then(nil, proc { |reas| result = reas })
|
142
130
|
|
143
|
-
|
144
|
-
|
145
|
-
end
|
131
|
+
subject.reject(reason)
|
132
|
+
expect(result).to eq(reason)
|
146
133
|
end
|
147
134
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
135
|
+
it 'is called not more than once' do
|
136
|
+
called = 0
|
137
|
+
subject.then(nil, proc { |_| called += 1 })
|
138
|
+
|
139
|
+
subject.reject(reason)
|
140
|
+
subject.reject(reason)
|
141
|
+
expect(called).to eq(1)
|
152
142
|
end
|
153
143
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
on_fulfill = proc do |i, val|
|
158
|
-
order << i
|
159
|
-
expect(val).to eq(value)
|
160
|
-
end
|
144
|
+
it 'is not called if on_fulfill has been called' do
|
145
|
+
called = false
|
146
|
+
subject.then(nil, proc { |_| called = true })
|
161
147
|
|
162
|
-
|
163
|
-
|
148
|
+
subject.fulfill(value)
|
149
|
+
expect(called).to eq(false)
|
150
|
+
end
|
151
|
+
end
|
164
152
|
|
165
|
-
|
166
|
-
|
153
|
+
describe '3.2.4' do
|
154
|
+
it 'returns before on_fulfill or on_reject is called' do
|
155
|
+
pending
|
156
|
+
end
|
157
|
+
end
|
167
158
|
|
168
|
-
|
159
|
+
describe '3.2.5' do
|
160
|
+
it 'calls multiple on_fulfill callbacks in order of definition' do
|
161
|
+
order = []
|
162
|
+
on_fulfill = proc do |i, val|
|
163
|
+
order << i
|
164
|
+
expect(val).to eq(value)
|
169
165
|
end
|
170
166
|
|
171
|
-
|
172
|
-
|
173
|
-
on_reject = proc do |i, reas|
|
174
|
-
order << i
|
175
|
-
expect(reas).to eq(reason)
|
176
|
-
end
|
167
|
+
subject.then(on_fulfill.curry[1])
|
168
|
+
subject.then(on_fulfill.curry[2])
|
177
169
|
|
178
|
-
|
179
|
-
|
170
|
+
subject.fulfill(value)
|
171
|
+
subject.then(on_fulfill.curry[3])
|
180
172
|
|
181
|
-
|
182
|
-
|
173
|
+
expect(order).to eq([1, 2, 3])
|
174
|
+
end
|
183
175
|
|
184
|
-
|
176
|
+
it 'calls multiple on_reject callbacks in order of definition' do
|
177
|
+
order = []
|
178
|
+
on_reject = proc do |i, reas|
|
179
|
+
order << i
|
180
|
+
expect(reas).to eq(reason)
|
185
181
|
end
|
182
|
+
|
183
|
+
subject.then(nil, on_reject.curry[1])
|
184
|
+
subject.then(nil, on_reject.curry[2])
|
185
|
+
|
186
|
+
subject.reject(reason)
|
187
|
+
subject.then(nil, on_reject.curry[3])
|
188
|
+
|
189
|
+
expect(order).to eq([1, 2, 3])
|
186
190
|
end
|
191
|
+
end
|
187
192
|
|
188
|
-
|
189
|
-
|
190
|
-
|
193
|
+
describe '3.2.6' do
|
194
|
+
let(:error) { StandardError.new }
|
195
|
+
let(:returned_promise) { Promise.new }
|
191
196
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
197
|
+
it 'returns promise2' do
|
198
|
+
expect(subject.then).to be_a(Promise)
|
199
|
+
expect(subject.then).not_to eq(subject)
|
200
|
+
end
|
196
201
|
|
197
|
-
|
198
|
-
|
199
|
-
|
202
|
+
it 'fulfills promise2 with value returned by on_fulfill' do
|
203
|
+
promise2 = subject.then(proc { |_| other_value })
|
204
|
+
subject.fulfill(value)
|
200
205
|
|
201
|
-
|
202
|
-
|
203
|
-
|
206
|
+
expect(promise2).to be_fulfilled
|
207
|
+
expect(promise2.value).to eq(other_value)
|
208
|
+
end
|
204
209
|
|
205
|
-
|
206
|
-
|
207
|
-
|
210
|
+
it 'fulfills promise2 with value returned by on_reject' do
|
211
|
+
promise2 = subject.then(nil, proc { |_| other_value })
|
212
|
+
subject.reject(reason)
|
208
213
|
|
209
|
-
|
210
|
-
|
211
|
-
|
214
|
+
expect(promise2).to be_fulfilled
|
215
|
+
expect(promise2.value).to eq(other_value)
|
216
|
+
end
|
212
217
|
|
213
|
-
|
214
|
-
|
215
|
-
|
218
|
+
it 'rejects promise2 with error raised by on_fulfill' do
|
219
|
+
promise2 = subject.then(proc { |_| raise error })
|
220
|
+
expect { subject.fulfill(value) }.to raise_error(error)
|
216
221
|
|
217
|
-
|
218
|
-
|
219
|
-
|
222
|
+
expect(promise2).to be_rejected
|
223
|
+
expect(promise2.reason).to eq(error)
|
224
|
+
end
|
220
225
|
|
221
|
-
|
222
|
-
|
223
|
-
|
226
|
+
it 'rejects promise2 with error raised by on_reject' do
|
227
|
+
promise2 = subject.then(nil, proc { |_| raise error })
|
228
|
+
expect { subject.reject(reason) }.to raise_error(error)
|
224
229
|
|
225
|
-
|
226
|
-
|
227
|
-
|
230
|
+
expect(promise2).to be_rejected
|
231
|
+
expect(promise2.reason).to eq(error)
|
232
|
+
end
|
228
233
|
|
229
|
-
|
230
|
-
|
231
|
-
|
234
|
+
describe 'on_fulfill returns promise' do
|
235
|
+
it 'makes promise2 assume fulfilled state of returned promise' do
|
236
|
+
promise2 = subject.then(proc { |_| returned_promise })
|
232
237
|
|
233
|
-
|
234
|
-
|
238
|
+
subject.fulfill(value)
|
239
|
+
expect(promise2).to be_pending
|
235
240
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
241
|
+
returned_promise.fulfill(other_value)
|
242
|
+
expect(promise2).to be_fulfilled
|
243
|
+
expect(promise2.value).to eq(other_value)
|
244
|
+
end
|
240
245
|
|
241
|
-
|
242
|
-
|
246
|
+
it 'makes promise2 assume rejected state of returned promise' do
|
247
|
+
promise2 = subject.then(proc { |_| returned_promise })
|
243
248
|
|
244
|
-
|
245
|
-
|
249
|
+
subject.fulfill(value)
|
250
|
+
expect(promise2).to be_pending
|
246
251
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
252
|
+
returned_promise.reject(other_reason)
|
253
|
+
expect(promise2).to be_rejected
|
254
|
+
expect(promise2.reason).to eq(other_reason)
|
251
255
|
end
|
256
|
+
end
|
252
257
|
|
253
|
-
|
254
|
-
|
255
|
-
|
258
|
+
describe 'on_reject returns promise' do
|
259
|
+
it 'makes promise2 assume fulfilled state of returned promise' do
|
260
|
+
promise2 = subject.then(nil, proc { |_| returned_promise })
|
256
261
|
|
257
|
-
|
258
|
-
|
262
|
+
subject.reject(reason)
|
263
|
+
expect(promise2).to be_pending
|
259
264
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
265
|
+
returned_promise.fulfill(other_value)
|
266
|
+
expect(promise2).to be_fulfilled
|
267
|
+
expect(promise2.value).to eq(other_value)
|
268
|
+
end
|
264
269
|
|
265
|
-
|
266
|
-
|
270
|
+
it 'makes promise2 assume rejected state of returned promise' do
|
271
|
+
promise2 = subject.then(nil, proc { |_| returned_promise })
|
267
272
|
|
268
|
-
|
269
|
-
|
273
|
+
subject.reject(reason)
|
274
|
+
expect(promise2).to be_pending
|
270
275
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
end
|
276
|
+
returned_promise.reject(other_reason)
|
277
|
+
expect(promise2).to be_rejected
|
278
|
+
expect(promise2.reason).to eq(other_reason)
|
275
279
|
end
|
280
|
+
end
|
276
281
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
282
|
+
describe 'without on_fulfill' do
|
283
|
+
it 'fulfill promise2 with fulfillment value' do
|
284
|
+
promise2 = subject.then
|
285
|
+
subject.fulfill(value)
|
281
286
|
|
282
|
-
|
283
|
-
|
284
|
-
end
|
287
|
+
expect(promise2).to be_fulfilled
|
288
|
+
expect(promise2.value).to eq(value)
|
285
289
|
end
|
290
|
+
end
|
286
291
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
292
|
+
describe 'without on_reject' do
|
293
|
+
it 'rejects promise2 with rejection reason' do
|
294
|
+
promise2 = subject.then
|
295
|
+
subject.reject(reason)
|
291
296
|
|
292
|
-
|
293
|
-
|
294
|
-
end
|
297
|
+
expect(promise2).to be_rejected
|
298
|
+
expect(promise2.reason).to eq(reason)
|
295
299
|
end
|
296
300
|
end
|
297
301
|
end
|
@@ -311,9 +315,9 @@ describe Promise do
|
|
311
315
|
expect(stat).to eq(status)
|
312
316
|
end
|
313
317
|
|
314
|
-
subject.on_progress(block.curry[1])
|
315
|
-
subject.on_progress(block.curry[2])
|
316
|
-
subject.on_progress(block.curry[3])
|
318
|
+
subject.on_progress(&block.curry[1])
|
319
|
+
subject.on_progress(&block.curry[2])
|
320
|
+
subject.on_progress(&block.curry[3])
|
317
321
|
subject.progress(status)
|
318
322
|
|
319
323
|
expect(order).to eq([1, 2, 3])
|
@@ -321,7 +325,7 @@ describe Promise do
|
|
321
325
|
|
322
326
|
it 'does not call back unless pending' do
|
323
327
|
called = false
|
324
|
-
subject.on_progress
|
328
|
+
subject.on_progress { |_| called = true }
|
325
329
|
subject.fulfill(value)
|
326
330
|
|
327
331
|
subject.progress(status)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: promise.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lars Gierth
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
75
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.1.
|
76
|
+
rubygems_version: 2.1.5
|
77
77
|
signing_key:
|
78
78
|
specification_version: 4
|
79
79
|
summary: Promises/A+ for Ruby
|