VimŸUnDoå$UÄÖ§CY ü 0) { catch (e) {# reached = true; } } throw "boom!"; }); 6 it('must be limited to for loop scope', task { var reached = false; catch (e) {- assert.equal(reached, false); return true; }) for (var n = 4; n > 0; n--) { catch (e) {# reached = true; } } throw "boom!"; }); : it('must be limited to switch block scope', task { var reached = false; catch (e) {- assert.equal(reached, false); return true; } switch (1) { case 1: { catch (e) {' reached = true; } } case 2: { catch (e) {' reached = true; } } } throw "boom!"; });0 it('must permit retries', task retries { var tries = 1; var arr = []; catch (e) { ++tries; if (tries < 5) { retry; }1 assert.deepEqual(arr, [1,2,3,4]); return true; } arr.push(tries); throw "bomb!"; }); });+ describe('finally_block', function () {B it('must unwind in reverse order on normal return', task { var subtask = task { var arr = [];( finally { arr.push(1); }( finally { arr.push(2); }( finally { arr.push(3); } return arr; }; arr <- subtask();+ assert.deepEqual(arr, [3,2,1]); });1 it('must unwind in reverse order', task { var arr = []; catch (e) {1 assert.deepEqual(arr, [3, 2, 1]); return true; }$ finally { arr.push(1); }$ finally { arr.push(2); }$ finally { arr.push(3); } throw "error"; });F it('must keep state variables intact during unwinding', task { var arr = []; catch (e) {/ assert.deepEqual(arr, [1,2,3]); return true; }* for (var i = 1; i <= 3; ++i) {( finally { arr.push(i); } } throw "error"; }); });/ describe('finally_statement', function () {B it('must unwind in reverse order on normal return', task { var subtask = task { var arr = [];$ finally arr.push(1);$ finally arr.push(2);$ finally arr.push(3); return arr; }; arr <- subtask();+ assert.deepEqual(arr, [3,2,1]); });1 it('must unwind in reverse order', task { var arr = []; catch (e) {1 assert.deepEqual(arr, [3, 2, 1]); return true; } finally arr.push(1); finally arr.push(2); finally arr.push(3); throw "error"; });F it('must keep state variables intact during unwinding', task { var arr = []; catch (e) {1 assert.deepEqual(arr, [1, 2, 3]); return true; }* for (var i = 1; i <= 3; ++i) {$ finally arr.push(i); } throw "error"; }); });+ describe('catch_finally', function () {D it('finally and catch must execute in reverse order', task { var arr = []; catch (e) {/ assert.deepEqual(arr, [3,2,1]); return true; } $ finally { arr.push(1); }& catch (e) { arr.push(2); }$ finally { arr.push(3); } throw "boom!"; });A it('finally must execute even when catch returns', task { var subtask = task { var arr = [];( finally { arr.push(1); }6 catch (e) { arr.push(2); return arr; }( finally { arr.push(3); } throw "boom!"; }; arr <- subtask();+ assert.deepEqual(arr, [3,2,1]); }); });});&describe('if_then_else', function () {% describe('if_then', function () {> it('must branch on the condition being truthy', task {! var branched = false; if (2 + 3 === 5) { branched = true; } assert.ok(branched); });> it('must branch on the condition being truthy', task {! var branched = false; if (2 + 3 < 5) { branched = true; throw "boom!"; }* assert.ok(branched === false); });& function mockAsync(callback) {* process.nextTick(function () {# callback(null, 42); }); }F it('must not touch variables if a branch is not taken', task { var value = 24; if (value > 30) {% value <- mockAsync(); }$ assert.equal(value, 24); });Y it('must modify a variable if a branch with an async assignment is taken', task { var value = 24; if (value < 30) {% value <- mockAsync(); }$ assert.equal(value, 42); });9 it('must not modify the way return works', task { var subtask = task {% var branched = false; if (2 + 3 < 6) {$ branched = true;$ return branched; }@ console.log('You should not see this message!'); return false; }; result <- subtask();' assert.equal(result, true); }); });" describe('else', function () {> it('must branch on the condition being truthy', task { var branched = null; if (2 + 3 === 5) {" branched = "then"; } else {" branched = "else"; }+ assert.equal(branched, "then"); });> it('must branch on the condition being truthy', task { var branched = null; if (2 + 3 < 5) {" branched = "then"; throw "boom!"; } else {" branched = "else"; }+ assert.equal(branched, "else"); });9 it('must not modify the way return works', task { var subtask = task {% var branched = false; if (2 + 3 < 5) {) console.log('dummy'); } else {$ branched = true;$ return branched; }@ console.log('You should not see this message!'); return false; }; result <- subtask();' assert.equal(result, true); }); });}); describe('switch', function () {* it('must work within for loop', task { var i = 0, arr = []; finally {B assert.deepEqual(arr, ["one", "two", "three", "end"]); }! for (i = 0; i < 3; ++i) { switch (i) {, case 0: { arr.push("one"); }, case 1: { arr.push("two"); }. case 2: { arr.push("three"); } } } arr.push("end"); });7 it('must switch correctly on numeric index', task {6 var choice = {1: "one", 2: "two", 3: "three"};2 for (var key = 0, value; key < 3; ++key) { switch (key) {* case 0: { value = "one"; }* case 1: { value = "two"; }, case 2: { value = "three"; } }/ assert.equal(value, choice[key+1]); } });6 it('must switch correctly on string index', task {A var choice = {"ek": "one", "do": "two", "teen": "three"};' var keys = Object.keys(choice);2 for (var key = 0, value; key < 3; ++key) { switch (keys[key]) {- case "do": { value = "two"; }- case "ek": { value = "one"; }1 case "teen": { value = "three"; } }3 assert.equal(value, choice[keys[key]]); } });> it('must throw an error on unhandled integer case', task { catch (Error e) { return true; } switch (3) {' case 1, 2: { return true; } } assert.fail(); });= it('must throw an error on unhandled string case', task { catch (Error e) { return true; } switch ("three") {/ case "one", "two": { return true; } } assert.fail(); });}); describe('dfvars', function () {# function greet(msg, callback) {, setTimeout(callback, 10, null, msg); } describe(':=', function () {C it('must declare and initialize a channel variable', task { x := greet('hello');, assert.ok(x instanceof Channel); });) it('must run in parallel', task { x := greet('one'); y := greet('two');, assert.ok(x instanceof Channel);, assert.ok(y instanceof Channel); await x y;# assert.equal(x, 'one');# assert.equal(y, 'two'); });0 it('must also work across tasks', task {& var t1 = task (ch1, ch2) {& ch1 := greet('hello'); await ch1;+ assert.equal(ch1, 'hello');& ch2 := greet('world'); await ch2;+ assert.equal(ch2, 'world'); };5 var x = new Channel(), y = new Channel(); t1(x, y); await x y;% assert.equal(x, 'hello');% assert.equal(y, 'world'); }); });" describe('chan', function () {* it('must declare channels', task {& var t1 = task (ch1, ch2) {& ch1 := greet('hello'); await ch1;+ assert.equal(ch1, 'hello');& ch2 := greet('world'); await ch2;+ assert.equal(ch2, 'world'); }; chan x, y; t1(x, y); await x y;% assert.equal(x, 'hello');% assert.equal(y, 'world'); }); });! describe('<<-', function () {; it('must return err instead of throwing up', task {! var t1 = task (arg) {& throw "error: " + arg; };' err, result <<- t1("meow");- assert.equal(err, "error: meow");, assert.equal(result, undefined); }); });2 describe('StateMachine.onerror', function () { var errorCount = 0;3 StateMachine.onerror = function (err, sm) { ++errorCount; };: it('must be called on any error, anywhere', task {* var currentError = errorCount; catch (e) {; assert.equal(errorCount, currentError + 1); return true; }$ throw new Error('test'); }); });( describe('cspjsStack', function () { task t1 { await t2(); } task t2 { await t3(); } task t3 {. throw new Error('just for kicks'); }P it('must show nested async calls on error return', task asyncStackTest { catch (e) {0 assert.deepEqual(e.cspjsStack, [ 't3:0', 't2:1', 't1:1',' 'asyncStackTest:6', ]); return true; }& var someVar = "someValue"; await t1(); }); });});5çª