Initial commit

This commit is contained in:
2021-03-14 11:09:02 +01:00
commit 21e364ee38
1046 changed files with 126647 additions and 0 deletions

3
node_modules/cps/.npmignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
cps.iml
npm-debug.log

19
node_modules/cps/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2013 Chiyan Chen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

348
node_modules/cps/README.md generated vendored Normal file
View File

@ -0,0 +1,348 @@
# cps
A CPS (Continuation Passing Style) library to ease the
event-driven/asynchronized coding style in node.js. There seems to be
enough node.js libs (e.g. async) doing the same thing, why yet
another? This lib is notably different from other libs in
exception handling. Using cps:
* Any "throw" statements in the procedures will be transformed to an
application of the callback onto the error object.
* A "rescue" function is provided, which can be used to catch such
exceptions pass through the callbacks.
This consistently recovers the try/catch functionality in continuation
passing style programming.
## Install
```text
npm install cps
```
## Terminologies
### Callback
We call a function of the following form a callback:
```javascript
function(err, res) {
// process the err and res
}
```
A callback is a function that takes two arguments, "err" and "res".
Semantically, a non-null "err" corresponds to a program exception;
while a null "err" corresponds to normal return without any
exceptions.
### Procedure
We call a function of the following form a procedure:
```javascript
function(arg1, arg2, ..., callback) {
// do some work with the arguments and then invoke the callback to continue
}
```
A procedure is a function that takes a callback as the last argument.
Semantically, a procedure does some work with the input arguments and
at some point, call the callback to continue. Note that a call to the
"callback" argument MUST always be a tail call. In particular, the
following is a procedure:
```javascript
function(callback) {
// do some work and then invoke the callback to continue
}
```
## API Document
* [seq](#seq)
* [pwhile](#pwhile)
* [peach](#peach)
* [pmap](#pmap)
* [pfor](#pfor)
* [rescue](#rescue)
* [parallel](#parallel)
<a name="seq"/>
### seq(array_of_procedures, callback)
Sequence a list of procedures. Note that the result of each procedure
is fed into the next procedure in the listed order.
__Example__
```javascript
var concatFile = function(f1, f2, resFile, cb) {
var contentOfA, contentOfB;
cps.seq([
function(_, cb) {
fs.readFile(f1, cb);
},
function(res, cb) {
contentOfA = res;
fs.readFile(f2, cb);
},
function(res, cb) {
contentOfB = res;
fs.writeFile(resFile, contentA + contentB, cb);
}
], cb);
};
```
<a name="pwhile">
### pwhile(bool_procedure, repeat_body_procedure, cb)
An asynchronized version of while loop.
__Example__
Consider a world in which arithmatic operations do not exists and must
be accomplished through alien technology. Then the Fibonacci function
needs to be written in the following way:
```javascript
var alienAdd = function(a, b, cb) {
setTimeout(function() {
cb(null, a + b);
}, 0);
};
var asyncFib = function(n, cb) {
if (n < 0) {
throw new Error('fib input error');
}
if (n == 0) {return cb(null, 1);}
if (n == 1) {return cb(null, 1);}
var a = 1,
b = 1,
i = 2;
cps.seq([
function(_, cb) {
cps.pwhile(
function(cb) {
cb(null, i <= n);
},
function(cb) {
cps.seq([
function(_, cb) {
alienAdd(a, b, cb);
},
function(res, cb) {
a = b;
b = res;
alienAdd(i, 1, cb);
},
function(res, cb) {
i = res;
cb();
}
], cb);
},
cb
);
},
function(_, cb) {
cb(null, b);
}
], cb);
};
```
<a name="peach"/>
### peach(arr, procedure_for_each_element, callback)
Apply a procedure on an array sequentially.
__Example__
Then in the same "arithmetic-less" world, print out the first 10 Fibonacci numbers.
```javascript
cps.peach(
[1,2,3,4,5,6,7,8,9,10],
function(el, cb) {
cps.seq([
function(_, cb) {
asyncFib(el, cb);
},
function(res, cb) {
console.log(res);
cb();
}
], cb);
},
cb
);
```
<a name="pmap" />
### pmap(arr, procedure_for_each_element, callback)
Apply a procedure on an array sequentially, and record the results in another array, which is pass to the callback.
__Example__
You can also map it out first and then log the result list.
```javascript
cps.seq([
function(_, cb) {
cps.pmap(
[1,2,3,4,5,6,7,8,9,10],
function(el, cb) {
asyncFib(el, cb);
},
cb
);
},
function(res, cb) {
console.log(res);
cb();
}
], cb);
```
<a name="pfor" />
### pfor(number_of_iterations, procedure_for_each_index, callback)
Apply a procedure on a sequence of consecutive indices, starting of 0.
__Example__
```javascript
var sum = 0;
cps.seq([
function(_, cb) {
console.log('here');
cps.pfor(10, function(i, cb) {
setTimeout(function() {
sum += i;
console.log(sum);
cb();
}, 1000);
}, cb);
},
function(_, cb) {
console.log(sum);
cb(null, 'ok');
}
], cb);
```
<a name="rescue"/>
### rescue(try_clause_procedure, catch_clause_procedure, callback)
An asyned version of try/catch. It take two procedures as arguments. If the first one fails, the second is executed to rescue.
__Example__
What if there's some invalid input? Let's catch it without disturbing the overall flow.
```javascript
cps.seq([
function(_, cb) {
cps.pmap(
[1,2,3,4,5,6,7,8,9,10, -1],
function(el, cb) {
cps.rescue({
'try': function(cb) { // try clause
asyncFib(el, cb);
},
'catch': function(err, cb) { // catch clause
console.log(err);
cb(null, -1);
},
'finally': function(cb) { // finally
console.log("always print this whether it's good or bad.");
cb();
}
}, cb);
},
cb
);
},
function(res, cb) {
console.log(res);
cb();
}
], cb);
```
<a name="parallel"/>
### parallel(array_of_procedures, callback)
Parallel a list of procedures. The top level callback is only called
after each parallel procedure finishes, regardless the procedure
succeeds or fails. The callback will never take a non-null error
parameter; the result parameter is an array of the following form:
```js
[
{"status": "ok", "data": res}, /* in case the procedure in the
corresponding position succeeds
with result res
*/
{"status": "error", "error": err} /* in case the procedure in the
corresponding position fails
with error err
*/
// ...
]
```
__Example__
See "thread b" being printed out before "thread a":
```javascript
var parallelTest = function(cb) {
cps.parallel([
function(cb) {
setTimeout(function() {
console.log('3');
cb(new Error('kaz'));
}, 3000);
},
function(cb) {
setTimeout(function() {
console.log('1');
cb(null, 'ok');
}, 2000);
},
function(cb) {
setTimeout(function() {
console.log('2');
cb(new Error('foobar'));
}, 1000);
}
], cb);
};
```
Running this procedure will yield the following output:
```text
2
1
3
[ { status: 'error', error: [Error: kaz] },
{ status: 'ok', data: 'ok' },
{ status: 'error', error: [Error: foobar] } ]
```

412
node_modules/cps/lib/cps.js generated vendored Normal file
View File

@ -0,0 +1,412 @@
var Tail = require('./tail');
module.exports = function() {
var procedure = function(fn) {
return function() {
var cb = arguments[arguments.length - 1];
try {
fn.apply(this, arguments);
} catch(e) {
handleError(e, cb);
}
};
};
var handleError = function(e, cb) {
cb(e);
};
var callback = function(cb, fn) {
var called = false;
return function(err) {
if (called) {
if (err) {
console.log(err);
if (err.stack) {
console.log(err.stack);
}
}
throw new Error('Continuation is being called more than once!');
}
called = true;
try {
if (err) {
handleError(err, cb);
} else {
fn.apply(this, arguments);
}
} catch(e) {
handleError(e, cb);
}
};
};
var _seq = procedure(function(procs, i, res, cb) {
if (i >= procs.length) {
return cb(null, res);
}
var proc = procs[i];
proc(res, callback(cb, function(err, res) {
// return _seq(procs, i+1, res, cb);
return Tail.run(function() {
_seq(procs, i+1, res, cb);
});
}));
});
var seq = function(procs, cb) {
return _seq(procs, 0, null, cb);
};
var rescue = procedure(function(procBundle, cb) {
var tryProc = procBundle['try'];
var catchProc = procBundle['catch'] || function(err, cb) {cb(err);};
var finallyProc = procBundle['finally'] || function(cb) {cb();};
var applyTry = procedure(function(cb) {
tryProc(cb);
});
var applyCatch = procedure(function(err, cb) {
catchProc(err, cb);
});
var applyFinallyOk = procedure(function(res0, cb) {
finallyProc(callback(cb, function(err, res) {
cb(null, res0);
}));
});
var applyFinallyError = procedure(function(err0, cb) {
finallyProc(callback(cb, function(err, res) {
cb(err0);
}));
});
applyTry(function(err, res) {
if (err) {
applyCatch(err, function(err, res) {
if (err) {
applyFinallyError(err, cb);
} else {
applyFinallyOk(res, cb);
}
});
} else {
applyFinallyOk(res, cb);
}
});
});
var pwhile = procedure(function(procBool, procBody, cb) {
seq([
function(_, cb) {
procBool(cb);
},
function(_, cb) {
if (_) {
seq([
function(_, cb) {
procBody(cb);
},
function(_, cb) {
pwhile(procBool, procBody, cb);
}
], cb);
} else {
cb();
}
}
], cb);
});
var peach = procedure(function(arr, proc, cb) {
var i = 0;
pwhile(
function(cb) {
cb(null, i < arr.length);
},
function(cb) {
seq([
function(_, cb) {
proc(arr[i], cb);
},
function(_, cb) {
i++;
cb();
}
], cb);
},
cb
)
});
var pfor = procedure(function(n, proc, cb) {
var i = 0;
pwhile(
function(cb) {
cb(null, i < n);
},
function(cb) {
seq([
function(_, cb) {
proc(i, cb);
},
function(_, cb) {
i++;
cb();
}
], cb);
},
cb
);
});
var pmap = procedure(function(arr, proc, cb) {
var l = [];
seq([
function(_, cb) {
peach(arr, function(e, cb) {
seq([
function(_, cb) {
proc(e, cb);
},
function(_, cb) {
l.push(_);
cb();
}
], cb);
}, cb);
},
function(_, cb) {
cb(null, l);
}
], cb);
});
var _parallel2 = procedure(function(proc1, proc2, cb) {
var state1 = 'start';
var state2 = 'start';
var res1;
var res2;
var err1;
var err2;
var applyProc1 = procedure(function(cb) {
proc1(cb);
});
var applyProc2 = procedure(function(cb) {
proc2(cb);
});
applyProc1(function(err, res) {Tail.run(function() {
if (err) {
state1 = 'error';
err1 = err;
switch(state2) {
case 'start':
break;
case 'done':
cb(null, [
{status: 'error', error: err1},
{status: 'ok', data: res2}
]);
break;
case 'error':
cb(null, [
{status: 'error', error: err1},
{status: 'error', error: err2}
]);
break;
default:
}
} else {
state1 = 'done';
res1 = res;
switch(state2) {
case 'start':
break;
case 'done':
cb(null, [
{status: 'ok', data: res1},
{status: 'ok', data: res2}
]);
break;
case 'error':
cb(null, [
{status: 'ok', data: res1},
{status: 'error', error: err2}
]);
break;
default:
}
}
})});
applyProc2(function(err, res) {Tail.run(function() {
if (err) {
state2 = 'error';
err2 = err;
switch(state1) {
case 'start':
break;
case 'done':
cb(null, [
{status: 'ok', data: res1},
{status: 'error', error: err2}
]);
break;
case 'error':
cb(null, [
{status: 'error', error: err1},
{status: 'error', error: err2}
]);
break;
default:
}
} else {
state2 = 'done';
res2 = res;
switch(state1) {
case 'start':
break;
case 'done':
cb(null, [
{status: 'ok', data: res1},
{status: 'ok', data: res2}
]);
break;
case 'error':
cb(null, [
{status: 'error', error: err1},
{status: 'ok', data: res2}
]);
break;
default:
}
}
})});
});
var _parallel = procedure(function(procs, i, cb) {
if (procs.length == 0) {
return cb();
}
if (i == procs.length - 1) {
return procs[i](function(err, res) {
if (err) {
cb(null, [{status: 'error', error: err}]);
} else {
cb(null, [{status: 'ok', data: res}]);
}
});
}
if (i < procs.length) {
_parallel2(
procs[i],
function(cb) {
_parallel(procs, i+1, cb);
},
callback(cb, function(err, res) {
cb(null, [res[0]].concat(res[1].data));
})
);
}
});
var parallel = procedure(function(procs, cb) {
_parallel(procs, 0, cb);
});
var noFail = function() {
var proc, handler, cb;
proc = arguments[0];
cb = arguments[arguments.length - 1];
if (arguments.length == 2) {
handler = function(err) {
console.log('ERROR caught by cps.noFail: ', err);
if (err.stack) {
console.log(err.stack);
}
};
} else if (arguments.length == 3) {
handler = arguments[1];
} else {
handleError(new Error('Incorrect number of arguments in calling cps.noFail.'), cb);
}
rescue({
'try': function(cb) {
proc(cb);
},
'catch': function(err, cb) {
handler(err);
cb();
}
}, cb);
};
var run = function(proc, cfg) {
cfg = cfg || {};
var cb = function(err, res) {
try {
if (err) {
if (cfg['error']) {
cfg['error'](err);
} else {
console.log('cps.run ERROR: ', err);
if (err.stack) {
console.log(err.stack);
}
}
} else {
if (cfg['ok']) {
cfg['ok'](res);
} else {
console.log('cps.run OK: ', res);
}
}
} catch(e) {
if (cfg['topLevelError']) {
cfg['topLevelError'](e);
} else {
console.log('cps.run TOP_LEVEL_ERROR: ', e);
}
} finally {
if (cfg['finally']) {
try {
cfg['finally']();
} catch(e) {
console.log('cps.run FINALLY_ERROR: ', e);
}
}
}
};
proc(cb);
};
return {
seq: seq,
peach: peach,
pwhile: pwhile,
pmap: pmap,
pfor: pfor,
rescue: rescue,
parallel: parallel,
noFail: noFail,
run: run
};
}();

30
node_modules/cps/lib/tail.js generated vendored Normal file
View File

@ -0,0 +1,30 @@
var Tail = function() {
this._q = [];
this._running = false;
};
Tail.prototype = {
run: function(fn) {
this._q.push(fn);
if (!this._running) {
this._run();
}
},
_run: function() {
while(true) {
var fn = this._q.shift();
if (fn) {
this._running = true;
fn();
} else {
this._running = false;
break;
}
}
}
};
module.exports = new Tail();

56
node_modules/cps/package.json generated vendored Normal file
View File

@ -0,0 +1,56 @@
{
"_from": "cps@*",
"_id": "cps@1.0.2",
"_inBundle": false,
"_integrity": "sha1-LNCyXYDxCQljfghWrZumNM4E/x0=",
"_location": "/cps",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "cps@*",
"name": "cps",
"escapedName": "cps",
"rawSpec": "*",
"saveSpec": null,
"fetchSpec": "*"
},
"_requiredBy": [
"/node-mysql"
],
"_resolved": "https://registry.npmjs.org/cps/-/cps-1.0.2.tgz",
"_shasum": "2cd0b25d80f10909637e0856ad9ba634ce04ff1d",
"_spec": "cps@*",
"_where": "E:\\IntellijProjects\\woam-antispam-bot\\node_modules\\node-mysql",
"author": {
"name": "Chiyan Chen"
},
"bugs": {
"url": "https://github.com/redblaze/cps/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "A continuation passing style library to help the coding of asynced programs in Javascript/Node.js.",
"homepage": "https://github.com/redblaze/cps#readme",
"jam": {
"main": "lib/cps.js",
"include": [
"lib/cps.js",
"README.md",
"LICENSE"
]
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/redblaze/cps/raw/master/LICENSE"
}
],
"main": "./lib/cps",
"name": "cps",
"repository": {
"type": "git",
"url": "git+https://github.com/redblaze/cps.git"
},
"version": "1.0.2"
}

51
node_modules/cps/test/fib.js generated vendored Normal file
View File

@ -0,0 +1,51 @@
var cps = require('../lib/cps.js');
var alienAdd = function(a, b, cb) {
setTimeout(function() {
cb(null, a + b);
}, 0);
};
var asyncFib = function(n, cb) {
if (n < 0) {
throw new Error('fib input error');
// return cb(new Error('fib input error'));
}
if (n == 0) {return cb(null, 1);}
if (n == 1) {return cb(null, 1);}
var a = 1,
b = 1,
i = 2;
cps.seq([
function(_, cb) {
cps.pwhile(
function(cb) {
cb(null, i <= n);
},
function(cb) {
cps.seq([
function(_, cb) {
alienAdd(a, b, cb);
},
function(res, cb) {
a = b;
b = res;
alienAdd(i, 1, cb);
},
function(res, cb) {
i = res;
cb();
}
], cb);
},
cb
);
},
function(_, cb) {
cb(null, b);
}
], cb);
};
module.exports = asyncFib;

417
node_modules/cps/test/test.js generated vendored Normal file
View File

@ -0,0 +1,417 @@
var cps = require('../lib/cps.js');
var fib = require('./fib');
var assert = require("assert");
describe('cps', function() {
describe('seq', function() {
it('should return 3 for 1+2', function(cb) {
var a, b;
cps.seq([
function(_, cb) {
setTimeout(function() {
cb(null, 1);
}, 0);
},
function(_, cb) {
a = _;
setTimeout(function() {
cb(null, 2);
}, 0);
},
function(_, cb) {
b = _;
cb(null, a + b);
},
function(_, cb) {
assert.equal(_, 3);
cb();
}
], cb);
});
});
describe('pwhile', function() {
it('should return 2 for fib(2)', function(cb) {
cps.seq([
function(_, cb) {
fib(5, cb);
},
function(_, cb) {
assert.equal(_, 8);
cb();
}
], cb);
});
it('should not fail for huge loops', function(cb) {
this.timeout(0);
var i;
cps.seq([
function(_, cb) {
i = 0;
cps.rescue({
'try': function(cb) {
cps.pwhile(
function(cb) {
cb(null, i < 10000);
},
function(cb) {
i++;
cb();
},
cb
)
},
'catch': function(e, cb) {
console.log('ERROR: ', e);
throw e;
}
}, cb);
},
function(_, cb) {
console.log('i is: ', i);
cb();
}
], cb);
});
});
describe('pfor', function() {
it('should return 45 for the sum of 0 through 9', function(cb) {
var sum = 0;
cps.seq([
function(_, cb) {
cps.pfor(10, function(i, cb) {
setTimeout(function() {
sum += i;
cb();
}, 0);
}, cb);
},
function(_, cb) {
assert.equal(sum, 45);
cb();
}
], cb);
});
});
describe('peach', function() {
it('should return 55 for the sum of 1 through 10', function(cb) {
var sum = 0;
cps.seq([
function(_, cb) {
cps.peach(
[1,2,3,4,5,6,7,8,9,10],
function(el, cb) {
sum += el;
cb();
},
cb
);
},
function(_, cb) {
assert.equal(sum, 55);
cb();
}
], cb);
});
});
describe('pmap', function() {
it('should return the list of squares of [1..10]', function(cb) {
cps.seq([
function(_, cb) {
cps.pmap(
[1,2,3,4,5,6,7,8,9,10],
function(el, cb) {
setTimeout(function() {
cb(null, el*el);
}, 0);
},
cb
);
},
function(_, cb) {
for (var i = 1; i <= 10; i++) {
assert.equal(_[i-1], i*i);
}
cb();
}
], cb);
});
});
describe('parallel', function() {
it('should work for 3 parallel threads', function(cb) {
this.timeout(0);
var output = [];
var start, end;
cps.seq([
function(_, cb) {
start = new Date();
cps.parallel([
function(cb) {
setTimeout(function() {
output.push(3);
cb(new Error('kaz'));
}, 3000);
},
function(cb) {
setTimeout(function() {
output.push(2);
cb(null, 'ok');
}, 2000);
},
function(cb) {
setTimeout(function() {
output.push(1);
cb(new Error('foobar'));
}, 1000);
}
], cb);
},
function(_, cb) {
end = new Date();
assert(end-start < 3100, 'parallel is taking too long to run');
for (var i = 1; i <= 3; i++) {
assert.equal(output[i-1], i);
}
assert.equal(_[0].status, 'error');
assert.equal(_[0].error.message, 'kaz');
assert.equal(_[1].status, 'ok');
assert.equal(_[1].data, 'ok');
assert.equal(_[2].status, 'error');
assert.equal(_[2].error.message, 'foobar');
cb();
}
], cb);
});
});
describe('noFail', function() {
it('should not fail on success', function(cb) {
cps.noFail(function(cb) {
cb(null, 1);
}, cb);
});
it('should not fail on failure', function(cb) {
cps.noFail(function(cb) {
cb(new Error('foobar'));
}, cb);
});
});
describe('rescue', function() {
it('should catch errors', function(cb) {
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
},
'catch': function(err, cb) {
cb(null, 'ok');
}
}, cb);
},
function(_, cb) {
assert.equal(_, 'ok');
cb();
}
], cb);
});
it('should be able to throw errors', function(cb) {
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
}
}, cb);
}
], function(err, res) {
try {
assert.equal(err.message, 'foobar');
cb();
} catch(e) {
cb(e);
}
});
});
it('should be able to rethrow errors', function(cb) {
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
},
'catch': function(err, cb) {
throw new Error('kaz');
}
}, cb);
}
], function(err, res) {
try {
assert.equal(err.message, 'kaz');
cb();
} catch(e) {
cb(e);
}
});
});
it('should execute finally clause on success', function(cb) {
var finallyDone = false;
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(null, 'ok');
}, 0);
},
'finally': function(cb) {
finallyDone = true;
cb();
}
}, cb);
},
function(_, cb) {
assert.equal(_, 'ok');
assert(finallyDone);
cb();
}
], cb);
});
it('should execute finally clause on exception being caught', function(cb) {
var finallyDone = false;
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
},
'catch': function(err, cb) {
cb(null, 'exception caught');
},
'finally': function(cb) {
finallyDone = true;
cb();
}
}, cb);
},
function(_, cb) {
assert.equal(_, 'exception caught');
assert(finallyDone);
cb();
}
], cb);
});
it('should execute finally clause on exception', function(cb) {
var finallyDone = false;
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
},
'finally': function(cb) {
finallyDone = true;
cb();
}
}, cb);
}
], function(err, res) {
try{
assert.equal(err.message, 'foobar');
assert(finallyDone);
cb();
} catch(e) {
cb(e);
}
});
});
it('should throw exception in finally clause on success', function(cb) {
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(null, 'ok');
}, 0);
},
'finally': function(cb) {
throw new Error('error in finally');
cb();
}
}, cb);
}
], function(err, res) {
try{
assert.equal(err.message, 'error in finally');
cb();
} catch(e) {
cb(e);
}
});
});
it('should throw exception in finally clause on exception', function(cb) {
cps.seq([
function(_, cb) {
cps.rescue({
'try': function(cb) {
setTimeout(function() {
cb(new Error('foobar'));
}, 0);
},
'finally': function(cb) {
throw new Error('error in finally');
cb();
}
}, cb);
}
], function(err, res) {
try{
assert.equal(err.message, 'error in finally');
cb();
} catch(e) {
cb(e);
}
});
});
});
});