plexus-csp
Version:
A Go-inspired async library based on ES6 generators
449 lines (404 loc) • 11.5 kB
JavaScript
var csp = require('../../dist/index');
var t = function(val) {
var out = csp.defer();
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx0) {
while (1) switch ($ctx0.next) {
case 0:
$ctx0.next = 2;
return null;
case 2:
out.resolve(val);
case 3:
case "end":
return $ctx0.stop();
}
}, this);
}));
return out;
};
describe('the join function', function() {
it('transforms an array of deferreds into a deferred array', function(done) {
csp.go(wrapGenerator.mark(function() {
var a;
return wrapGenerator(function($ctx1) {
while (1) switch ($ctx1.next) {
case 0:
a = csp.join([t(1), t(2), t(3)]);
expect(typeof a.then).toEqual('function');
$ctx1.next = 4;
return a;
case 4:
$ctx1.t0 = $ctx1.sent;
expect($ctx1.t0).toEqual([1,2,3]);
done();
case 7:
case "end":
return $ctx1.stop();
}
}, this);
}));
});
});
describe('the lift function', function() {
it('lifts an ordinary function to a function on deferreds', function(done) {
csp.go(wrapGenerator.mark(function() {
var a;
return wrapGenerator(function($ctx2) {
while (1) switch ($ctx2.next) {
case 0:
a = csp.lift(Array)(t(1), t(2), t(3));
expect(typeof a.then).toEqual('function');
$ctx2.next = 4;
return a;
case 4:
$ctx2.t1 = $ctx2.sent;
expect($ctx2.t1).toEqual([1,2,3]);
done();
case 7:
case "end":
return $ctx2.stop();
}
}, this);
}));
});
it('handles a passed in object context correctly', function(done) {
var obj = {
val: 287,
fun: function(x) { return this.val + x; }
};
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx3) {
while (1) switch ($ctx3.next) {
case 0:
$ctx3.next = 2;
return csp.lift(obj.fun, obj)(t(314));
case 2:
$ctx3.t2 = $ctx3.sent;
expect($ctx3.t2).toEqual(601);
done();
case 5:
case "end":
return $ctx3.stop();
}
}, this);
}));
});
});
describe('the chain function', function() {
var fn = function() {
var args = Array.prototype.slice.call(arguments);
return csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx4) {
while (1) switch ($ctx4.next) {
case 0:
$ctx4.rval = '#' + args.join('#') + '#';
delete $ctx4.thrown;
$ctx4.next = 4;
break;
case 4:
case "end":
return $ctx4.stop();
}
}, this);
}));
};
it('when given only an initial value, returns it unchanged', function(done) {
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx5) {
while (1) switch ($ctx5.next) {
case 0:
$ctx5.next = 2;
return csp.chain(5);
case 2:
$ctx5.t3 = $ctx5.sent;
expect($ctx5.t3).toEqual(5);
done();
case 5:
case "end":
return $ctx5.stop();
}
}, this);
}));
});
it('when given a single form, applies it', function(done) {
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx6) {
while (1) switch ($ctx6.next) {
case 0:
$ctx6.next = 2;
return csp.chain(5, fn);
case 2:
$ctx6.t4 = $ctx6.sent;
expect($ctx6.t4).toEqual('#5#');
$ctx6.next = 6;
return csp.chain(5, ['toString', 2]);
case 6:
$ctx6.t5 = $ctx6.sent;
expect($ctx6.t5).toEqual('101');
$ctx6.next = 10;
return csp.chain(5, [fn, [], 7, 11]);
case 10:
$ctx6.t6 = $ctx6.sent;
expect($ctx6.t6).toEqual('#5#7#11#');
$ctx6.next = 14;
return csp.chain(5, [fn, 3]);
case 14:
$ctx6.t7 = $ctx6.sent;
expect($ctx6.t7).toEqual('#3#5#');
$ctx6.next = 18;
return csp.chain(5, [fn, [2,3]]);
case 18:
$ctx6.t8 = $ctx6.sent;
expect($ctx6.t8).toEqual('#2#3#5#');
$ctx6.next = 22;
return csp.chain(5, [fn, 3, 7, 11]);
case 22:
$ctx6.t9 = $ctx6.sent;
expect($ctx6.t9).toEqual('#3#5#7#11#');
$ctx6.next = 26;
return csp.chain(5, [fn, [2, 3], 7, 11]);
case 26:
$ctx6.t10 = $ctx6.sent;
expect($ctx6.t10).toEqual('#2#3#5#7#11#');
done();
case 29:
case "end":
return $ctx6.stop();
}
}, this);
}));
});
it('when given multiple forms, applies them in order', function(done) {
var toInt = function(s) { return parseInt(s); };
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx7) {
while (1) switch ($ctx7.next) {
case 0:
$ctx7.next = 2;
return csp.chain(5,
[fn, [2, 3], 7, 11],
['split', '#'],
['slice', 1, 6],
['map', toInt]);
case 2:
$ctx7.t11 = $ctx7.sent;
expect($ctx7.t11).toEqual([2, 3, 5, 7, 11]);
done();
case 5:
case "end":
return $ctx7.stop();
}
}, this);
}));
});
it('interprets non-form arguments as replacement values', function(done) {
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx8) {
while (1) switch ($ctx8.next) {
case 0:
$ctx8.next = 2;
return csp.chain(5, [fn, 3, 7], 'hello', [fn, 2, 9]);
case 2:
$ctx8.t12 = $ctx8.sent;
expect($ctx8.t12).toEqual('#2#hello#9#');
done();
case 5:
case "end":
return $ctx8.stop();
}
}, this);
}));
});
});
describe('the sleep function', function() {
it('delays execution for approximately the specified time', function(done) {
csp.go(wrapGenerator.mark(function() {
var d, t;
return wrapGenerator(function($ctx9) {
while (1) switch ($ctx9.next) {
case 0:
d = 17;
t = Date.now();
$ctx9.next = 4;
return csp.sleep(d);
case 4:
expect(Math.abs(Date.now() - t - d)).toBeLessThan(2);
done();
case 6:
case "end":
return $ctx9.stop();
}
}, this);
}));
});
});
describe('the ncallback function returns a callback that', function() {
var result, cb;
beforeEach(function() {
result = csp.defer();
cb = csp.ncallback(result);
});
it('when called with no error, resolves its deferred', function(done) {
cb(null, 5);
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx10) {
while (1) switch ($ctx10.next) {
case 0:
$ctx10.next = 2;
return result;
case 2:
$ctx10.t13 = $ctx10.sent;
expect($ctx10.t13).toEqual(5);
done();
case 5:
case "end":
return $ctx10.stop();
}
}, this);
}));
});
it('when called with an error, rejects its deferred', function(done) {
cb('Nope!');
csp.go(wrapGenerator.mark(function() {
var thrown;
return wrapGenerator(function($ctx11) {
while (1) switch ($ctx11.next) {
case 0:
thrown = {};
$ctx11.pushTry(7, null, null);
$ctx11.next = 4;
return result;
case 4:
$ctx11.popCatch(7);
$ctx11.next = 11;
break;
case 7:
$ctx11.popCatch(7);
$ctx11.t14 = $ctx11.thrown;
delete $ctx11.thrown;
thrown = $ctx11.t14;
case 11:
expect(thrown.message).toEqual('Nope!');
done();
case 13:
case "end":
return $ctx11.stop();
}
}, this);
}));
});
});
describe('the nbind function returns a wrapper that', function() {
var obj = {
value: 5,
method: function(x, cb) {
if (x != this.value)
cb('expecting a ' + this.value);
else
cb(null, 'thanks for the ' + this.value);
}
};
var wrapper = csp.nbind(obj.method, obj);
it('upon success resolves the deferred it returns', function(done) {
var val = obj.value;
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx12) {
while (1) switch ($ctx12.next) {
case 0:
$ctx12.next = 2;
return wrapper(val);
case 2:
$ctx12.t15 = $ctx12.sent;
$ctx12.t16 = 'thanks for the ' + val;
expect($ctx12.t15).toEqual($ctx12.t16);
done();
case 6:
case "end":
return $ctx12.stop();
}
}, this);
}));
});
it('upon success rejects the deferred it returns', function(done) {
var val = obj.value + 1;
csp.go(wrapGenerator.mark(function() {
var thrown;
return wrapGenerator(function($ctx13) {
while (1) switch ($ctx13.next) {
case 0:
thrown = {};
$ctx13.pushTry(7, null, null);
$ctx13.next = 4;
return wrapper(val);
case 4:
$ctx13.popCatch(7);
$ctx13.next = 11;
break;
case 7:
$ctx13.popCatch(7);
$ctx13.t17 = $ctx13.thrown;
delete $ctx13.thrown;
thrown = $ctx13.t17;
case 11:
expect(thrown.message).toEqual('expecting a ' + obj.value);
done();
case 13:
case "end":
return $ctx13.stop();
}
}, this);
}));
});
});
describe('the nodeify function', function() {
var result;
beforeEach(function() {
result = csp.defer();
});
describe('when given a callback', function() {
var outcome;
beforeEach(function() {
outcome = null;
csp.nodeify(result, function(err, val) {
outcome = err ? { err: err } : { val: val };
});
});
it('calls it with no error upon deferred resolution', function(done) {
result.resolve('Hello callback!');
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx14) {
while (1) switch ($ctx14.next) {
case 0:
expect(outcome).toEqual({ val: 'Hello callback!' });
done();
case 2:
case "end":
return $ctx14.stop();
}
}, this);
}));
});
it('calls it with an error upon deferred rejection', function(done) {
result.reject('O noes!');
csp.go(wrapGenerator.mark(function() {
return wrapGenerator(function($ctx15) {
while (1) switch ($ctx15.next) {
case 0:
expect(outcome).toEqual({ err: 'O noes!' });
done();
case 2:
case "end":
return $ctx15.stop();
}
}, this);
}));
});
});
describe('when given no callback', function() {
it('simply returns its argument', function() {
expect(csp.nodeify(result)).toBe(result);
});
});
});
;