1 |
|
2 | var co = require('..');
|
3 | var assert = require('assert');
|
4 |
|
5 | function get(val, err, error) {
|
6 | return function(done){
|
7 | if (error) throw error;
|
8 | setTimeout(function(){
|
9 | done(err, val);
|
10 | }, 10);
|
11 | }
|
12 | }
|
13 |
|
14 | describe('co(fn)', function(){
|
15 | it('should have the same receiver', function(done){
|
16 | var foo = { thread: co };
|
17 | foo.thread(function *(){
|
18 | this.should.equal(foo);
|
19 | })(done);
|
20 | })
|
21 |
|
22 | describe('with no yields', function(){
|
23 | it('should work', function(done){
|
24 | co(function *(){
|
25 |
|
26 | })(done);
|
27 | })
|
28 | })
|
29 |
|
30 | describe('with one yield', function(){
|
31 | it('should work', function(done){
|
32 | co(function *(){
|
33 | var a = yield get(1);
|
34 | a.should.equal(1);
|
35 | })(done);
|
36 | })
|
37 | })
|
38 |
|
39 | describe('with several yields', function(){
|
40 | it('should work', function(done){
|
41 | co(function *(){
|
42 | var a = yield get(1);
|
43 | var b = yield get(2);
|
44 | var c = yield get(3);
|
45 |
|
46 | [a,b,c].should.eql([1,2,3]);
|
47 | })(done);
|
48 | })
|
49 | })
|
50 |
|
51 | describe('with many arguments', function(){
|
52 | it('should return an array', function(done){
|
53 | function exec(cmd) {
|
54 | return function(done){
|
55 | done(null, 'stdout', 'stderr');
|
56 | }
|
57 | }
|
58 |
|
59 | co(function *(){
|
60 | var out = yield exec('something');
|
61 | out.should.eql(['stdout', 'stderr']);
|
62 | })(done);
|
63 | })
|
64 | })
|
65 |
|
66 | describe('when the function throws', function(){
|
67 | it('should be caught', function(done){
|
68 | co(function *(){
|
69 | try {
|
70 | var a = yield get(1, null, new Error('boom'));
|
71 | } catch (err) {
|
72 | err.message.should.equal('boom');
|
73 | }
|
74 | })(done);
|
75 | })
|
76 | })
|
77 |
|
78 | describe('when an error is passed', function(){
|
79 | it('should throw and resume', function(done){
|
80 | var error;
|
81 |
|
82 | co(function *(){
|
83 | try {
|
84 | yield get(1, new Error('boom'));
|
85 | } catch (err) {
|
86 | error = err;
|
87 | }
|
88 |
|
89 | assert('boom' == error.message);
|
90 | var ret = yield get(1);
|
91 | assert(1 == ret);
|
92 | })(done);
|
93 | })
|
94 | })
|
95 |
|
96 | describe('with nested co()s', function(){
|
97 | it('should work', function(done){
|
98 | var hit = [];
|
99 |
|
100 | co(function *(){
|
101 | var a = yield get(1);
|
102 | var b = yield get(2);
|
103 | var c = yield get(3);
|
104 | hit.push('one');
|
105 |
|
106 | [a,b,c].should.eql([1,2,3]);
|
107 |
|
108 | yield co(function *(){
|
109 | hit.push('two');
|
110 | var a = yield get(1);
|
111 | var b = yield get(2);
|
112 | var c = yield get(3);
|
113 |
|
114 | [a,b,c].should.eql([1,2,3]);
|
115 |
|
116 | yield co(function *(){
|
117 | hit.push('three');
|
118 | var a = yield get(1);
|
119 | var b = yield get(2);
|
120 | var c = yield get(3);
|
121 |
|
122 | [a,b,c].should.eql([1,2,3]);
|
123 | });
|
124 | });
|
125 |
|
126 | yield co(function *(){
|
127 | hit.push('four');
|
128 | var a = yield get(1);
|
129 | var b = yield get(2);
|
130 | var c = yield get(3);
|
131 |
|
132 | [a,b,c].should.eql([1,2,3]);
|
133 | });
|
134 |
|
135 | hit.should.eql(['one', 'two', 'three', 'four']);
|
136 | })(done);
|
137 | })
|
138 | })
|
139 |
|
140 | describe('return values', function(){
|
141 | describe('with a callback', function(){
|
142 | it('should be passed', function(done){
|
143 | var fn = co(function *(){
|
144 | return [
|
145 | yield get(1),
|
146 | yield get(2),
|
147 | yield get(3)
|
148 | ];
|
149 | });
|
150 |
|
151 | fn(function(err, res){
|
152 | if (err) return done(err);
|
153 | res.should.eql([1,2,3]);
|
154 | done();
|
155 | });
|
156 | })
|
157 | })
|
158 |
|
159 | describe('when nested', function(){
|
160 | it('should return the value', function(done){
|
161 | var fn = co(function *(){
|
162 | var other = yield co(function *(){
|
163 | return [
|
164 | yield get(4),
|
165 | yield get(5),
|
166 | yield get(6)
|
167 | ]
|
168 | });
|
169 |
|
170 | return [
|
171 | yield get(1),
|
172 | yield get(2),
|
173 | yield get(3)
|
174 | ].concat(other);
|
175 | });
|
176 |
|
177 | fn(function(err, res){
|
178 | if (err) return done(err);
|
179 | res.should.eql([1,2,3,4,5,6]);
|
180 | done();
|
181 | });
|
182 | })
|
183 | })
|
184 | })
|
185 |
|
186 | describe('when yielding neither a function nor a promise', function(){
|
187 | it('should throw', function(done){
|
188 | var errors = [];
|
189 |
|
190 | co(function *(){
|
191 | try {
|
192 | var a = yield 'something';
|
193 | } catch (err) {
|
194 | errors.push(err.message);
|
195 | }
|
196 |
|
197 | try {
|
198 | var a = yield 'something';
|
199 | } catch (err) {
|
200 | errors.push(err.message);
|
201 | }
|
202 |
|
203 | var msg = 'yield a function, promise, generator, or array';
|
204 | errors.should.eql([msg, msg]);
|
205 | })(done);
|
206 | })
|
207 | })
|
208 |
|
209 | describe('with errors', function(){
|
210 | it('should throw', function(done){
|
211 | var errors = [];
|
212 |
|
213 | co(function *(){
|
214 | try {
|
215 | var a = yield get(1, new Error('foo'));
|
216 | } catch (err) {
|
217 | errors.push(err.message);
|
218 | }
|
219 |
|
220 | try {
|
221 | var a = yield get(1, new Error('bar'));
|
222 | } catch (err) {
|
223 | errors.push(err.message);
|
224 | }
|
225 |
|
226 | errors.should.eql(['foo', 'bar']);
|
227 | })(done);
|
228 | })
|
229 |
|
230 | it('should catch errors on .send()', function(done){
|
231 | var errors = [];
|
232 |
|
233 | co(function *(){
|
234 | try {
|
235 | var a = yield get(1, null, new Error('foo'));
|
236 | } catch (err) {
|
237 | errors.push(err.message);
|
238 | }
|
239 |
|
240 | try {
|
241 | var a = yield get(1, null, new Error('bar'));
|
242 | } catch (err) {
|
243 | errors.push(err.message);
|
244 | }
|
245 |
|
246 | errors.should.eql(['foo', 'bar']);
|
247 | })(done);
|
248 | })
|
249 |
|
250 | it('should pass future errors to the callback', function(done){
|
251 | co(function *(){
|
252 | yield get(1);
|
253 | yield get(2, null, new Error('fail'));
|
254 | assert(false);
|
255 | yield get(3);
|
256 | })(function(err){
|
257 | err.message.should.equal('fail');
|
258 | done();
|
259 | });
|
260 | })
|
261 |
|
262 | it('should pass immediate errors to the callback', function(done){
|
263 | co(function *(){
|
264 | yield get(1);
|
265 | yield get(2, new Error('fail'));
|
266 | assert(false);
|
267 | yield get(3);
|
268 | })(function(err){
|
269 | err.message.should.equal('fail');
|
270 | done();
|
271 | });
|
272 | })
|
273 |
|
274 | it('should catch errors on the first invocation', function(done){
|
275 | co(function *(){
|
276 | throw new Error('fail');
|
277 | })(function(err){
|
278 | err.message.should.equal('fail');
|
279 | done();
|
280 | });
|
281 | })
|
282 | })
|
283 | })
|