pure_promise 0.0.1
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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.travis.yml +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +172 -0
- data/Rakefile +6 -0
- data/lib/pure_promise.rb +135 -0
- data/lib/pure_promise/callback.rb +19 -0
- data/lib/pure_promise/coercer.rb +59 -0
- data/pure_promise.gemspec +23 -0
- data/spec/pure_promise/callback_spec.rb +26 -0
- data/spec/pure_promise/coercer_spec.rb +118 -0
- data/spec/pure_promise_spec.rb +445 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/support/helper_macros.rb +37 -0
- data/spec/support/matchers.rb +47 -0
- data/spec/support/thenable.rb +44 -0
- metadata +113 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'pure_promise'
|
7
|
+
spec.version = '0.0.1'
|
8
|
+
spec.authors = ['Cameron Martin']
|
9
|
+
spec.email = ['cameronmartin123@gmail.com']
|
10
|
+
spec.summary = %q{Promises/A+ with a twist}
|
11
|
+
spec.description = %q{Promises/A+ with a twist. Resolves some of the inconsistencies and annoyances I've experienced with other promises libraries}
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
21
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
22
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
describe PurePromise::Callback do
|
2
|
+
|
3
|
+
let(:return_promise) { PurePromise.new }
|
4
|
+
|
5
|
+
describe '#call' do
|
6
|
+
|
7
|
+
it 'delegates to calling proc' do
|
8
|
+
promise = PurePromise.fulfill(:value)
|
9
|
+
callback = double('callback')
|
10
|
+
|
11
|
+
expect(callback).to receive(:call).with(:value).and_return(promise)
|
12
|
+
|
13
|
+
PurePromise::Callback.new(callback, return_promise).call(:value)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'rejects promise if callback errors' do
|
17
|
+
error = RuntimeError.new
|
18
|
+
callback = proc { raise error }
|
19
|
+
|
20
|
+
PurePromise::Callback.new(callback, return_promise).call(:value)
|
21
|
+
|
22
|
+
expect_rejection(return_promise, with: error)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
describe PurePromise::Coercer do
|
2
|
+
|
3
|
+
subject { PurePromise::Coercer.new(thenable, PurePromise) }
|
4
|
+
|
5
|
+
context 'with non-thenable' do
|
6
|
+
let(:thenable) { Object.new }
|
7
|
+
|
8
|
+
describe '.is_thenable?' do
|
9
|
+
it 'is false' do
|
10
|
+
expect(PurePromise::Coercer.is_thenable?(thenable)).to eq(false)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
it 'raises TypeError' do
|
16
|
+
expect { subject }.to raise_error(TypeError, 'Can only coerce a thenable')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with PurePromise' do
|
23
|
+
describe '#coerce' do
|
24
|
+
let(:thenable) { PurePromise.new }
|
25
|
+
|
26
|
+
it 'returns promise' do
|
27
|
+
expect(subject.coerce).to equal(thenable)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with conformant thenable' do
|
34
|
+
|
35
|
+
let(:thenable) { Thenable::Conformant.new }
|
36
|
+
|
37
|
+
describe '.is_thenable?' do
|
38
|
+
it 'is true' do
|
39
|
+
expect(PurePromise::Coercer.is_thenable?(thenable)).to eq(true)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#coerce' do
|
44
|
+
|
45
|
+
it 'returns a promise' do
|
46
|
+
expect(subject.coerce).to be_a(PurePromise)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'fulfills when callback passed to then is called' do
|
50
|
+
promise = subject.coerce
|
51
|
+
|
52
|
+
expect_fulfillment(promise, with: :value) do
|
53
|
+
thenable.fulfill(:value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'rejects when callback passed to then is called' do
|
58
|
+
promise = subject.coerce
|
59
|
+
|
60
|
+
expect_rejection(promise, with: :value) do
|
61
|
+
thenable.reject(:value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'ignores subsequent calls of reject callback' do
|
66
|
+
promise = subject.coerce
|
67
|
+
|
68
|
+
thenable.reject(:value)
|
69
|
+
thenable.reject(:other_value)
|
70
|
+
|
71
|
+
expect_rejection(promise, with: :value)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'ignores subsequent calls of fulfill callback' do
|
75
|
+
promise = subject.coerce
|
76
|
+
|
77
|
+
thenable.fulfill(:value)
|
78
|
+
thenable.fulfill(:other_value)
|
79
|
+
|
80
|
+
expect_fulfillment(promise, with: :value)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with early erroring thenable' do
|
87
|
+
let(:thenable) { Thenable::EarlyErroring.new(error) }
|
88
|
+
|
89
|
+
let(:error) { RuntimeError.new('Some error') }
|
90
|
+
|
91
|
+
describe '#coerce' do
|
92
|
+
it 'rejects promise with error' do
|
93
|
+
promise = subject.coerce
|
94
|
+
|
95
|
+
expect_rejection(promise, with: error)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with late erroring thenable' do
|
102
|
+
let(:thenable) { Thenable::LateErroring.new(:value, error) }
|
103
|
+
|
104
|
+
let(:error) { RuntimeError.new }
|
105
|
+
|
106
|
+
describe '#coerce' do
|
107
|
+
it 'rejects promise with error' do
|
108
|
+
promise = subject.coerce
|
109
|
+
|
110
|
+
expect_fulfillment(promise, with: :value)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,445 @@
|
|
1
|
+
describe PurePromise do
|
2
|
+
|
3
|
+
subject { PurePromise.new }
|
4
|
+
|
5
|
+
let(:fulfill_callback) { double('fulfill_callback').as_null_object }
|
6
|
+
let(:reject_callback) { double('reject_callback').as_null_object }
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'yields fullfill and reject methods if block given' do
|
10
|
+
expect do |b|
|
11
|
+
PurePromise.new(&b)
|
12
|
+
end.to yield_with_args(
|
13
|
+
a_bound_method_of(PurePromise.instance_method(:fulfill)),
|
14
|
+
a_bound_method_of(PurePromise.instance_method(:reject))
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'initializes as pending' do
|
19
|
+
expect_pending(PurePromise.new)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '.error' do
|
24
|
+
|
25
|
+
it 'rejects to a RuntimeError with no arguments' do
|
26
|
+
promise = PurePromise.error
|
27
|
+
|
28
|
+
expect_rejection(promise, with: an_error(RuntimeError).with_backtrace(caller))
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'rejects to a RuntimeError with message with single string argument' do
|
32
|
+
promise = PurePromise.error('error message')
|
33
|
+
|
34
|
+
expect_rejection(promise, with: an_error(RuntimeError, 'error message').with_backtrace(caller))
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'rejects to a specific error when given an Exception object' do
|
38
|
+
exception = TypeError.new('error message')
|
39
|
+
promise = PurePromise.error(exception)
|
40
|
+
|
41
|
+
expect_rejection(promise, with: an_error(TypeError, 'error message').with_backtrace(caller))
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'rejects to a specific error when given a exception class and string' do
|
45
|
+
promise = PurePromise.error(TypeError, 'error message')
|
46
|
+
|
47
|
+
expect_rejection(promise, with: an_error(TypeError, 'error message').with_backtrace(caller))
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'sets custom backtrace if given third argument' do
|
51
|
+
backtrace = ['something']
|
52
|
+
promise = PurePromise.error(TypeError, 'error message', backtrace)
|
53
|
+
|
54
|
+
expect_rejection(promise, with: an_error(TypeError, 'error message').with_backtrace(backtrace))
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# TODO: Test delegation of .fulfill and .reject
|
60
|
+
|
61
|
+
describe '#fulfill' do
|
62
|
+
it 'calls fulfill callback when promise transitions to fulfilled' do
|
63
|
+
expect_fulfillment(subject, with: :value) do
|
64
|
+
subject.fulfill(:value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'is fulfilled' do
|
69
|
+
subject.fulfill
|
70
|
+
expect_fulfillment(subject)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should raise error if fulfill twice' do
|
74
|
+
subject.fulfill
|
75
|
+
expect { subject.fulfill }.to raise_error(PurePromise::MutationError, 'You can only mutate pending promises')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should raise error if fulfilled after being rejected' do
|
79
|
+
subject.reject
|
80
|
+
expect { subject.fulfill }.to raise_error(PurePromise::MutationError, 'You can only mutate pending promises')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns self' do
|
84
|
+
expect(subject.fulfill).to eq(subject)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#reject' do
|
89
|
+
it 'calls reject callback when promise transitions to rejected' do
|
90
|
+
expect_rejection(subject, with: :value) do
|
91
|
+
subject.reject(:value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'is rejected' do
|
96
|
+
subject.reject
|
97
|
+
expect_rejection(subject)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should raise error if rejected twice' do
|
101
|
+
subject.reject
|
102
|
+
expect { subject.reject }.to raise_error(PurePromise::MutationError, 'You can only mutate pending promises')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should raise error if rejected after being fulfilled' do
|
106
|
+
subject.fulfill
|
107
|
+
expect { subject.reject }.to raise_error(PurePromise::MutationError, 'You can only mutate pending promises')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'returns self' do
|
111
|
+
expect(subject.reject).to eq(subject)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#resolve' do
|
116
|
+
|
117
|
+
it 'raises TypeError if argument is same as self' do
|
118
|
+
expect { subject.resolve(subject) }.to raise_error(TypeError, 'Promise cannot be resolved to itself')
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'raises TypeError if argument is not a promise' do
|
122
|
+
expect { subject.resolve(Object.new) }.to raise_error(TypeError, 'Argument is not a promise')
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when argument is a promise' do
|
126
|
+
let(:argument) { PurePromise.new }
|
127
|
+
|
128
|
+
it 'returns self when argument is pending' do
|
129
|
+
return_value = subject.resolve(argument)
|
130
|
+
|
131
|
+
expect(return_value).to eq(subject)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'fulfills subject if argument is fulfilled' do
|
135
|
+
argument.fulfill(:value)
|
136
|
+
subject.resolve(argument)
|
137
|
+
|
138
|
+
expect_fulfillment(subject, with: :value)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'rejects subject if argument is rejected' do
|
142
|
+
argument.reject(:value)
|
143
|
+
subject.resolve(argument)
|
144
|
+
|
145
|
+
expect_rejection(subject, with: :value)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'fulfills subject when argument is fulfilled' do
|
149
|
+
subject.resolve(argument)
|
150
|
+
argument.fulfill(:value)
|
151
|
+
|
152
|
+
expect_fulfillment(subject, with: :value)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'rejects subject when argument is rejected' do
|
156
|
+
subject.resolve(argument)
|
157
|
+
argument.reject(:value)
|
158
|
+
|
159
|
+
expect_rejection(subject, with: :value)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'when argument is a thenable' do
|
164
|
+
it 'fulfills when callback passed to then is called' do
|
165
|
+
thenable = Thenable::Conformant.new
|
166
|
+
|
167
|
+
subject.resolve(thenable)
|
168
|
+
|
169
|
+
expect_fulfillment(subject, with: :value) do
|
170
|
+
thenable.fulfill(:value)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'rejects when callback passed to then is called' do
|
175
|
+
thenable = Thenable::Conformant.new
|
176
|
+
|
177
|
+
subject.resolve(thenable)
|
178
|
+
|
179
|
+
expect_rejection(subject, with: :value) do
|
180
|
+
thenable.reject(:value)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
describe '#resolve_into' do
|
188
|
+
let(:argument) { PurePromise.new }
|
189
|
+
|
190
|
+
it 'returns self' do
|
191
|
+
return_value = subject.resolve_into(argument)
|
192
|
+
|
193
|
+
expect(return_value).to equal(subject)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'raises TypeError if argument is not a PurePromise' do
|
197
|
+
expect { subject.resolve_into(Object.new) }.to raise_error(TypeError, 'Argument must be of same type as self')
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'fulfills promise if self is fulfilled' do
|
201
|
+
subject.fulfill(:value)
|
202
|
+
|
203
|
+
expect(argument).to receive(:fulfill).with(:value)
|
204
|
+
subject.resolve_into(argument)
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'rejects promise if self is rejected' do
|
208
|
+
subject.reject(:value)
|
209
|
+
|
210
|
+
expect(argument).to receive(:reject).with(:value)
|
211
|
+
subject.resolve_into(argument)
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'fulfills promise when self is fulfilled' do
|
215
|
+
subject.resolve_into(argument)
|
216
|
+
|
217
|
+
expect_fulfillment(argument, with: :value) do
|
218
|
+
subject.fulfill(:value)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'rejects promise when self is rejected' do
|
223
|
+
subject.resolve_into(argument)
|
224
|
+
|
225
|
+
expect_rejection(argument, with: :value) do
|
226
|
+
subject.reject(:value)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#then' do
|
232
|
+
|
233
|
+
it 'is a promise' do
|
234
|
+
return_promise = subject.then(fulfill_callback, reject_callback)
|
235
|
+
expect(return_promise).to be_an_instance_of(subject.class)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'executes callbacks in order' do
|
239
|
+
callbacks = 2.times.map do
|
240
|
+
double('fulfill_callback').as_null_object
|
241
|
+
end.each do |callback|
|
242
|
+
subject.then(callback)
|
243
|
+
end
|
244
|
+
|
245
|
+
callbacks.each do |callback|
|
246
|
+
expect(callback).to receive(:call).and_return(PurePromise.fulfill).ordered
|
247
|
+
end
|
248
|
+
|
249
|
+
subject.fulfill
|
250
|
+
end
|
251
|
+
|
252
|
+
# TODO: Find a better way of testing this
|
253
|
+
it 'calls defer if fulfilled' do
|
254
|
+
subject.fulfill
|
255
|
+
expect(subject).to receive(:defer)
|
256
|
+
subject.then
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'calls defer if rejected' do
|
260
|
+
subject.reject
|
261
|
+
expect(subject).to receive(:defer)
|
262
|
+
subject.then
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'calls defer when fulfilled' do
|
266
|
+
subject.then
|
267
|
+
expect(subject).to receive(:defer)
|
268
|
+
subject.fulfill
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'calls defer when rejected' do
|
272
|
+
subject.then
|
273
|
+
expect(subject).to receive(:defer)
|
274
|
+
subject.reject
|
275
|
+
end
|
276
|
+
|
277
|
+
# REVIEW: Consider moving context 'if/when subject is fulfilled/rejected' into this level
|
278
|
+
|
279
|
+
context 'with no callbacks' do
|
280
|
+
|
281
|
+
before(:each) { @return_promise = subject.then }
|
282
|
+
|
283
|
+
it 'returns a promise that fulfills when subject fulfills' do
|
284
|
+
subject.fulfill(:value)
|
285
|
+
|
286
|
+
expect_fulfillment(@return_promise, with: :value)
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'returns a promise that rejects when subject rejects' do
|
290
|
+
subject.reject(:value)
|
291
|
+
|
292
|
+
expect_rejection(@return_promise, with: :value)
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
context 'with fulfill callback' do
|
298
|
+
|
299
|
+
it 'allows registering fulfill callback by passing a block' do
|
300
|
+
return_promise = subject.then do
|
301
|
+
PurePromise.fulfill(:value)
|
302
|
+
end
|
303
|
+
|
304
|
+
subject.fulfill
|
305
|
+
|
306
|
+
expect_fulfillment(return_promise, with: :value)
|
307
|
+
end
|
308
|
+
|
309
|
+
context 'when callback is registered while pending' do
|
310
|
+
|
311
|
+
it 'fullfills to the value that the return promise of the callback fullfills to' do
|
312
|
+
return_promise = subject.then(proc {
|
313
|
+
PurePromise.fulfill(:value)
|
314
|
+
})
|
315
|
+
|
316
|
+
subject.fulfill
|
317
|
+
|
318
|
+
expect_fulfillment(return_promise, with: :value)
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'rejects to the value that the return promise of the callback rejects to' do
|
323
|
+
return_promise = subject.then(proc {
|
324
|
+
PurePromise.reject(:value)
|
325
|
+
})
|
326
|
+
subject.fulfill
|
327
|
+
|
328
|
+
expect_rejection(return_promise, with: :value)
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
context 'when callback is registered after fulfillment' do
|
334
|
+
before(:each) { subject.fulfill }
|
335
|
+
|
336
|
+
it 'fullfills to the value that the return promise of the callback fullfills to' do
|
337
|
+
return_promise = subject.then(proc {
|
338
|
+
PurePromise.fulfill(:value)
|
339
|
+
})
|
340
|
+
|
341
|
+
expect_fulfillment(return_promise, with: :value)
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'rejects to the value that the return promise of the callback rejects to' do
|
345
|
+
return_promise = subject.then(proc {
|
346
|
+
PurePromise.reject(:value)
|
347
|
+
})
|
348
|
+
|
349
|
+
expect_rejection(return_promise, with: :value)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
context 'with reject callback' do
|
356
|
+
|
357
|
+
context 'when callback is registered while pending' do
|
358
|
+
|
359
|
+
it 'fullfills to the value that the return promise of the callback fullfills to' do
|
360
|
+
return_promise = subject.then(proc{}, proc {
|
361
|
+
PurePromise.fulfill(:value)
|
362
|
+
})
|
363
|
+
|
364
|
+
subject.reject
|
365
|
+
|
366
|
+
expect_fulfillment(return_promise, with: :value)
|
367
|
+
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'rejects to the value that the return promise of the callback rejects to' do
|
371
|
+
return_promise = subject.then(proc{}, proc {
|
372
|
+
PurePromise.reject(:value)
|
373
|
+
})
|
374
|
+
subject.reject
|
375
|
+
|
376
|
+
expect_rejection(return_promise, with: :value)
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
context 'when callback is registered after rejection' do
|
382
|
+
before(:each) { subject.reject }
|
383
|
+
|
384
|
+
it 'fullfills to the value that the return promise of the callback fullfills to' do
|
385
|
+
return_promise = subject.then(proc{}, proc {
|
386
|
+
PurePromise.fulfill(:value)
|
387
|
+
})
|
388
|
+
|
389
|
+
expect_fulfillment(return_promise, with: :value)
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'rejects to the value that the return promise of the callback rejects to' do
|
393
|
+
return_promise = subject.then(proc{}, proc {
|
394
|
+
PurePromise.reject(:value)
|
395
|
+
})
|
396
|
+
|
397
|
+
expect_rejection(return_promise, with: :value)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
describe '#catch' do
|
405
|
+
|
406
|
+
it 'is called on rejected promise' do
|
407
|
+
subject.reject(:value)
|
408
|
+
|
409
|
+
callback = proc { PurePromise.fulfill }
|
410
|
+
|
411
|
+
expect(callback).to receive(:call).with(:value).and_call_original
|
412
|
+
|
413
|
+
subject.catch(&callback)
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'returns a promise that fulfills with original' do
|
417
|
+
promise = subject.catch { PurePromise.fulfill }
|
418
|
+
|
419
|
+
expect_fulfillment(promise, with: :value) do
|
420
|
+
subject.fulfill(:value)
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
context 'with no callbacks' do
|
425
|
+
|
426
|
+
before(:each) { @return_promise = subject.catch }
|
427
|
+
|
428
|
+
it 'returns a promise that fulfills when subject fulfills' do
|
429
|
+
subject.fulfill(:value)
|
430
|
+
|
431
|
+
expect_fulfillment(@return_promise, with: :value)
|
432
|
+
end
|
433
|
+
|
434
|
+
it 'returns a promise that rejects when subject rejects' do
|
435
|
+
subject.reject(:value)
|
436
|
+
|
437
|
+
expect_rejection(@return_promise, with: :value)
|
438
|
+
end
|
439
|
+
|
440
|
+
end
|
441
|
+
|
442
|
+
|
443
|
+
end
|
444
|
+
|
445
|
+
end
|