import { Cancellation } from "../Cancellation"; import { CancellationAggregate } from "../CancellationAggregate"; import { delay, notImplemented } from "../safe"; import { test } from "./TestTraits"; test("standalone cancellation", async t => { let doCancel: (e: any) => void = notImplemented; const ct = new Cancellation(cancel => { doCancel = cancel; }); let counter = 0; const reason = "BILL"; t.true(ct.isSupported(), "Cancellation must be supported"); t.false(ct.isRequested(), "Cancellation shouldn't be requested"); ct.throwIfRequested(); t.pass("The exception shouldn't be thrown unless the cancellation is requested"); ct.register(() => counter++); t.equals(counter, 0, "counter should be zero"); ct.register(() => counter++).destroy(); doCancel(reason); t.true(ct.isRequested(), "Cancellation should be requested"); t.equals(counter, 1, "The registered callback should be triggered"); ct.register(() => counter++); t.equals(counter, 2, "The callback should be triggered immediately"); let msg; ct.register(e => msg = e); t.equals(msg, reason, "The cancellation reason should be passed to callback"); try { msg = null; ct.throwIfRequested(); t.fail("The exception should be thrown"); } catch (e) { msg = e; } t.equals(msg, reason, "The cancellation reason should be catched"); }); test("async cancellation", async t => { const ct = new Cancellation(cancel => { cancel("STOP!"); }); try { await delay(0, ct); t.fail("Should thow the exception"); } catch (e) { t.equals(e, "STOP!", "Should throw the cancellation reason"); } }); test("cancel with external event", async t => { const ct = new Cancellation(cancel => { setTimeout(x => cancel("STOP!"), 0); }); try { await delay(10000, ct); t.fail("Should thow the exception"); } catch (e) { t.equals(e, "STOP!", "Should throw the cancellation reason"); } }); test("operation normal flow", async t => { let htimeout; const ct = new Cancellation(cancel => { htimeout = setTimeout(() => cancel("STOP!"), 1000); }); try { await delay(0, ct); t.pass("Should pass"); } finally { clearTimeout(htimeout); } }); test("combine cancellations", t => { const ct1 = new Cancellation(cancel => { cancel("cancelled"); }); const ct2 = new Cancellation(() => {}); const cct1 = Cancellation.combine(Cancellation.none, ct1); t.equals(cct1, ct1, "Cancellation.combine should filter out Cancellation.none tokens"); const cct2 = Cancellation.combine(Cancellation.none, ct1, ct2); t.assert(cct2 instanceof CancellationAggregate, "Cancellation.combine should return CancellationAggregate"); t.true(cct2.isRequested(), "CancellationAggregate should return isRequested true if any of cancellations is requested"); });