Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
(await listTodos(wrapper)).map(t => ({ label: t.label, checked: t.checked, loading: t.loading }))
)
).toEqual(sortTodos(expectedTodos().map(t => ({ label: t.label, checked: t.checked, loading: false }))));
}
)
.beforeEach(async () => {
cleanup();
})
));
});
// Helpers
const TodoListCommands = fc.commands([
fc.string().map(label => new AddItemCommand(label)),
fc.nat().map(pos => new ToggleItemCommand(pos)),
fc.nat().map(pos => new RemoveItemCommand(pos))
]);
type ApiTodoItem = { id: string; label: string; checked: boolean };
const mockApi = (s: fc.Scheduler, initialTodos: ApiTodoItem[], allFailures: fc.Stream) => {
let lastIdx = 0;
let allTodos = [...initialTodos];
const fetchAllTodos = s.scheduleFunction(async function fetchAllTodos(): Promise<{
status: 'success';
response: ApiTodoItem[];
}> {
return { status: 'success', response: allTodos.slice() };
});
it("finalizer should execute in all cases", () =>
fc.assert(
fc.asyncProperty(
fc.nat(30),
fc.nat(30),
fc.nat(30),
fc.nat(90),
arbEitherIO(fc.string(), fc.nat()),
(acqDelay, useDelay, relDelay, interruptDelay, useResult) =>
expectExit(
io.chain(makeRef(0),
(cell) => {
const action = io.bracket(
io.delay(cell.update((n) => n + 1), acqDelay),
() => io.delay(cell.update((n) => n - 1), relDelay),
() => io.delay(useResult, useDelay));
return io.chain(
io.fork(action),
(child) => io.applySecond(io.delay(child.interrupt, interruptDelay), cell.get)
);
}),
done(0)
it("- last set wins", () =>
fc.assert(
fc.asyncProperty(
fc.nat(),
fc.array(fc.nat(), 1, 10),
(initial, sets) =>
eqvIO(
io.chain(makeRef(initial),
(r) => io.applySecond(array.traverse(io.instances)(sets, (v) => r.set(v)), r.get)),
io.chain(makeRef(initial),
(r) => io.applySecond(r.set(sets[sets.length - 1]), r.get))
)
)
)
);
it("elements are always consumed completely in the order they are produced -- blocking", () =>
fc.assert(
fc.asyncProperty(
fc.array(fc.tuple(fc.string(), fc.nat(20), fc.nat(20))),
fc.nat(5),
fc.nat(100),
fc.nat(100),
(ops, queueSize, delayWrite, delayRead) =>
io.runToPromise(Do(io.instances)
.bind("q", boundedQueue(queueSize))
.bindL("writeFiber",
({q}) =>
pipe(
array.traverse(io.instances)(ops, ([v, d]) =>
io.delay(q.offer(v), d)),
io.liftDelay(delayWrite),
io.fork
)
)
.bindL("readFiber",
({q}) =>
it("elements are always consumed completely in the order they are produced", () =>
fc.assert(
fc.asyncProperty(
fc.array(fc.tuple(fc.string(), fc.nat(20), fc.nat(20))),
fc.nat(100),
fc.nat(100),
(ops, delayWrite, delayRead) =>
io.runToPromise(Do(io.instances)
.bind("q", unboundedQueue())
.bindL("writeFiber",
({q}) =>
pipe(
array.traverse(io.instances)(ops, ([v, d]) =>
io.delay(q.offer(v), d)),
io.liftDelay(delayWrite),
io.fork
)
)
.bindL("readFiber",
({q}) =>
pipe(
it("finalizer should execute in all cases", () =>
fc.assert(
fc.asyncProperty(
fc.nat(30),
fc.nat(30),
fc.nat(30),
fc.nat(90),
arbEitherIO(fc.string(), fc.nat()),
(acqDelay, useDelay, relDelay, interruptDelay, useResult) =>
expectExit(
io.chain(makeRef(0),
(cell) => {
const action = io.bracket(
io.delay(cell.update((n) => n + 1), acqDelay),
() => io.delay(cell.update((n) => n - 1), relDelay),
() => io.delay(useResult, useDelay));
return io.chain(
io.fork(action),
(child) => io.applySecond(io.delay(child.interrupt, interruptDelay), cell.get)
);
}),
it("- duplicated sets are equivalent", () =>
fc.assert(
fc.asyncProperty(
fc.nat(),
fc.nat(),
fc.nat(1000),
(initial, value, count) =>
eqvIO(
io.chain(makeRef(initial),
(cell) => io.applySecond(cell.set(value), cell.get)),
io.chain(makeRef(initial),
(cell) =>
io.applySecond(
array.traverse(io.instances)(repeat(value, count + 1), (v) => cell.set(v)),
cell.get)
)
)
)
)
);
it("uninterruptible fibers are not interruptible", () =>
fc.assert(
fc.asyncProperty(
fc.nat(50),
(delay) =>
expectExit(
io.chain(
makeDeferred(),
(latch) =>
io.chain(makeRef(false),
(cell) =>
io.chain(
io.fork(
io.uninterruptible(io.applySecond(latch.wait, cell.set(true)))
),
(child) =>
io.applySecond(
io.fork(io.shiftAsyncBefore(child.interrupt)),
io.applySecond(
io.delay(latch.done(undefined), delay),