Software /
code /
prosody
Comparison
spec/util_promise_spec.lua @ 9456:d54a0e129af8
util.promise: ES6-like API for promises
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 10 Oct 2018 17:45:19 +0100 |
child | 9457:d01cff2f7a26 |
comparison
equal
deleted
inserted
replaced
9455:c62c983b8be3 | 9456:d54a0e129af8 |
---|---|
1 local promise = require "util.promise"; | |
2 | |
3 describe("util.promise", function () | |
4 describe("new()", function () | |
5 it("returns a promise object", function () | |
6 assert(promise.new()); | |
7 end); | |
8 end); | |
9 it("notifies immediately for fulfilled promises", function () | |
10 local p = promise.new(function (resolve) | |
11 resolve("foo"); | |
12 end); | |
13 local cb = spy.new(function (v) | |
14 assert.equal("foo", v); | |
15 end); | |
16 p:next(cb); | |
17 assert.spy(cb).was_called(1); | |
18 end); | |
19 it("notifies on fulfilment of pending promises", function () | |
20 local r; | |
21 local p = promise.new(function (resolve) | |
22 r = resolve; | |
23 end); | |
24 local cb = spy.new(function (v) | |
25 assert.equal("foo", v); | |
26 end); | |
27 p:next(cb); | |
28 assert.spy(cb).was_called(0); | |
29 r("foo"); | |
30 assert.spy(cb).was_called(1); | |
31 end); | |
32 it("allows chaining :next() calls", function () | |
33 local r; | |
34 local result; | |
35 local p = promise.new(function (resolve) | |
36 r = resolve; | |
37 end); | |
38 local cb1 = spy.new(function (v) | |
39 assert.equal("foo", v); | |
40 return "bar"; | |
41 end); | |
42 local cb2 = spy.new(function (v) | |
43 assert.equal("bar", v); | |
44 result = v; | |
45 end); | |
46 p:next(cb1):next(cb2); | |
47 assert.spy(cb1).was_called(0); | |
48 assert.spy(cb2).was_called(0); | |
49 r("foo"); | |
50 assert.spy(cb1).was_called(1); | |
51 assert.spy(cb2).was_called(1); | |
52 assert.equal("bar", result); | |
53 end); | |
54 it("supports multiple :next() calls on the same promise", function () | |
55 local r; | |
56 local result; | |
57 local p = promise.new(function (resolve) | |
58 r = resolve; | |
59 end); | |
60 local cb1 = spy.new(function (v) | |
61 assert.equal("foo", v); | |
62 result = v; | |
63 end); | |
64 local cb2 = spy.new(function (v) | |
65 assert.equal("foo", v); | |
66 result = v; | |
67 end); | |
68 p:next(cb1); | |
69 p:next(cb2); | |
70 assert.spy(cb1).was_called(0); | |
71 assert.spy(cb2).was_called(0); | |
72 r("foo"); | |
73 assert.spy(cb1).was_called(1); | |
74 assert.spy(cb2).was_called(1); | |
75 assert.equal("foo", result); | |
76 end); | |
77 it("automatically rejects on error", function () | |
78 local r; | |
79 local p = promise.new(function (resolve) | |
80 r = resolve; | |
81 error("oh no"); | |
82 end); | |
83 local cb = spy.new(function () end); | |
84 local err_cb = spy.new(function (v) | |
85 assert.equal("oh no", v); | |
86 end); | |
87 p:next(cb, err_cb); | |
88 assert.spy(cb).was_called(0); | |
89 assert.spy(err_cb).was_called(1); | |
90 r("foo"); | |
91 assert.spy(cb).was_called(0); | |
92 assert.spy(err_cb).was_called(1); | |
93 end); | |
94 it("supports reject()", function () | |
95 local r, result; | |
96 local p = promise.new(function (resolve, reject) | |
97 r = reject; | |
98 end); | |
99 local cb = spy.new(function () end); | |
100 local err_cb = spy.new(function (v) | |
101 result = v; | |
102 assert.equal("oh doh", v); | |
103 end); | |
104 p:next(cb, err_cb); | |
105 assert.spy(cb).was_called(0); | |
106 assert.spy(err_cb).was_called(0); | |
107 r("oh doh"); | |
108 assert.spy(cb).was_called(0); | |
109 assert.spy(err_cb).was_called(1); | |
110 assert.equal("oh doh", result); | |
111 end); | |
112 it("supports chaining of rejected promises", function () | |
113 local r, result; | |
114 local p = promise.new(function (resolve, reject) | |
115 r = reject; | |
116 end); | |
117 local cb = spy.new(function () end); | |
118 local err_cb = spy.new(function (v) | |
119 result = v; | |
120 assert.equal("oh doh", v); | |
121 return "ok" | |
122 end); | |
123 local cb2 = spy.new(function (v) | |
124 result = v; | |
125 end); | |
126 local err_cb2 = spy.new(function (v) end); | |
127 p:next(cb, err_cb):next(cb2, err_cb2) | |
128 assert.spy(cb).was_called(0); | |
129 assert.spy(err_cb).was_called(0); | |
130 assert.spy(cb2).was_called(0); | |
131 assert.spy(err_cb2).was_called(0); | |
132 r("oh doh"); | |
133 assert.spy(cb).was_called(0); | |
134 assert.spy(err_cb).was_called(1); | |
135 assert.spy(cb2).was_called(1); | |
136 assert.spy(err_cb2).was_called(0); | |
137 assert.equal("ok", result); | |
138 end); | |
139 | |
140 describe("race()", function () | |
141 it("works with fulfilled promises", function () | |
142 local p1, p2 = promise.resolve("yep"), promise.resolve("nope"); | |
143 local p = promise.race({ p1, p2 }); | |
144 local result; | |
145 p:next(function (v) | |
146 result = v; | |
147 end); | |
148 assert.equal("yep", result); | |
149 end); | |
150 it("works with pending promises", function () | |
151 local r1, r2; | |
152 local p1, p2 = promise.new(function (resolve) r1 = resolve end), promise.new(function (resolve) r2 = resolve end); | |
153 local p = promise.race({ p1, p2 }); | |
154 | |
155 local result; | |
156 local cb = spy.new(function (v) | |
157 result = v; | |
158 end); | |
159 p:next(cb); | |
160 assert.spy(cb).was_called(0); | |
161 r2("yep"); | |
162 r1("nope"); | |
163 assert.spy(cb).was_called(1); | |
164 assert.equal("yep", result); | |
165 end); | |
166 end); | |
167 describe("all()", function () | |
168 it("works with fulfilled promises", function () | |
169 local p1, p2 = promise.resolve("yep"), promise.resolve("nope"); | |
170 local p = promise.all({ p1, p2 }); | |
171 local result; | |
172 p:next(function (v) | |
173 result = v; | |
174 end); | |
175 assert.same({ "yep", "nope" }, result); | |
176 end); | |
177 it("works with pending promises", function () | |
178 local r1, r2; | |
179 local p1, p2 = promise.new(function (resolve) r1 = resolve end), promise.new(function (resolve) r2 = resolve end); | |
180 local p = promise.all({ p1, p2 }); | |
181 | |
182 local result; | |
183 local cb = spy.new(function (v) | |
184 result = v; | |
185 end); | |
186 p:next(cb); | |
187 assert.spy(cb).was_called(0); | |
188 r2("yep"); | |
189 assert.spy(cb).was_called(0); | |
190 r1("nope"); | |
191 assert.spy(cb).was_called(1); | |
192 assert.same({ "nope", "yep" }, result); | |
193 end); | |
194 it("rejects if any promise rejects", function () | |
195 local r1, r2; | |
196 local p1 = promise.new(function (resolve, reject) r1 = reject end); | |
197 local p2 = promise.new(function (resolve, reject) r2 = reject end); | |
198 local p = promise.all({ p1, p2 }); | |
199 | |
200 local result; | |
201 local cb = spy.new(function (v) | |
202 result = v; | |
203 end); | |
204 local cb_err = spy.new(function (v) | |
205 result = v; | |
206 end); | |
207 p:next(cb, cb_err); | |
208 assert.spy(cb).was_called(0); | |
209 assert.spy(cb_err).was_called(0); | |
210 r2("fail"); | |
211 assert.spy(cb).was_called(0); | |
212 assert.spy(cb_err).was_called(1); | |
213 r1("nope"); | |
214 assert.spy(cb).was_called(0); | |
215 assert.spy(cb_err).was_called(1); | |
216 assert.equal("fail", result); | |
217 end); | |
218 end); | |
219 describe("catch()", function () | |
220 it("works", function () | |
221 local result; | |
222 local p = promise.new(function (resolve) | |
223 error({ foo = true }); | |
224 end); | |
225 local cb1 = spy.new(function (v) | |
226 result = v; | |
227 end); | |
228 assert.spy(cb1).was_called(0); | |
229 p:catch(cb1); | |
230 assert.spy(cb1).was_called(1); | |
231 assert.same({ foo = true }, result); | |
232 end); | |
233 end); | |
234 it("promises may be resolved by other promises", function () | |
235 local r1, r2; | |
236 local p1, p2 = promise.new(function (resolve) r1 = resolve end), promise.new(function (resolve) r2 = resolve end); | |
237 | |
238 local result; | |
239 local cb = spy.new(function (v) | |
240 result = v; | |
241 end); | |
242 p1:next(cb); | |
243 assert.spy(cb).was_called(0); | |
244 | |
245 r1(p2); | |
246 assert.spy(cb).was_called(0); | |
247 r2("yep"); | |
248 assert.spy(cb).was_called(1); | |
249 assert.equal("yep", result); | |
250 end); | |
251 describe("reject()", function () | |
252 it("returns a rejected promise", function () | |
253 local p = promise.reject("foo"); | |
254 local cb = spy.new(function (v) | |
255 result = v; | |
256 end); | |
257 p:next(cb); | |
258 assert.spy(cb).was_called(1); | |
259 assert.spy(cb).was_called_with("foo"); | |
260 end); | |
261 end); | |
262 end); |