sodiumjs
Version:
A Functional Reactive Programming (FRP) library for JavaScript
163 lines (120 loc) • 3.94 kB
text/typescript
import {
StreamSink,
getTotalRegistrations,
Transaction,
CellLoop,
lambda3
} from '../../lib/Lib';
afterEach(() => {
if (getTotalRegistrations() != 0) {
throw new Error('listeners were not deregistered');
}
});
//this passes
test('multiple loop: stream in transaction', done => {
const cResult = Transaction.run(() => {
const s = new StreamSink<number>();
const c1 = new CellLoop<number>();
const c2 = new CellLoop<number>();
c1.loop(
s.snapshot3(c1, c2, (n1, n2, n3) => n1 * n2 * n3).hold(2)
);
c2.loop(
s.snapshot3(c1, c2, (n1, n2, n3) => n1 * n2 * n3).hold(2)
);
s.send(4);
return c1;
});
//need to delay the handler so it can call kill
const kill = cResult.listen(n => setTimeout(() => onValue(n), 0));
const onValue = n => {
expect(16).toBe(n);
kill();
done();
}
});
//this also passes
test('multiple loop: stream out of transaction', done => {
const s = new StreamSink<number>();
const cResult = Transaction.run(() => {
const c1 = new CellLoop<number>();
const c2 = new CellLoop<number>();
c1.loop(
s.snapshot3(c1, c2, (n1, n2, n3) => n1 * n2 * n3).hold(2)
);
c2.loop(
s.snapshot3(c1, c2, (n1, n2, n3) => n1 * n2 * n3).hold(2)
);
s.send(4);
return c1;
});
//need to delay the handler so it can call kill
const kill = cResult.listen(n => setTimeout(() => onValue(n), 0));
const onValue = n => {
expect(16).toBe(n);
kill();
done();
}
});
//very interestingly - this also passes
test('single loop: stream and send out of transaction', done => {
const s = new StreamSink<number>();
const cResult = Transaction.run(() => {
const c = new CellLoop<number>();
c.loop(
s.snapshot(c, (n1, n2) => n1 * n2).hold(2)
);
return c;
});
//need to delay the handler so it can call kill
const kill = cResult.listen(n => setTimeout(() => onValue(n), 0));
s.send(4);
const out = [];
const onValue = n => {
out.push(n);
if(out.length === 2) {
expect([2, 8]).toEqual(out);
kill();
done();
}
}
});
//this fails - even though all the above tests pass!
//still fails with the lambda and delay attempts
test('multiple loop w/ lambda: stream and send out of transaction', done => {
const s = new StreamSink<number>();
const cResult = Transaction.run(() => {
const c1 = new CellLoop<number>();
const c2 = new CellLoop<number>();
//As an attempted fix, put everything in lambdas
c1.loop(
s.snapshot3(c1, c2, lambda3((n1, n2, n3) => n1 * n2 * n3, [s, c1, c2])).hold(2)
);
c2.loop(
s.snapshot3(c1, c2, lambda3((n1, n2, n3) => n1 * n2 * n3, [s, c1, c2])).hold(2)
);
return c1;
});
//need to delay the handler so it can call kill
const kill = cResult.listen(n => setTimeout(() => onValue(n), 0))
//Uncomment this dummy listener for a "fix" (remember to kill it below too)
//const killDummy = s.listen(() => {});
//As an attempted fix - put it in another transaction, and delay that
setTimeout(
() => Transaction.run(() => {
s.send(4);
}),
0
);
//now we're getting the initial cell value too so we need to collect it
const out = [];
const onValue = n => {
out.push(n);
if(out.length == 2) {
expect([2, 16]).toEqual(out);
kill();
//killDummy();
done();
}
}
});