Files
privacy.sexy/tests/unit/infrastructure/Threading/AsyncSleep.spec.ts
undergroundwires 31f70913a2 Refactor to improve iterations
- Use function abstractions (such as map, reduce, filter etc.) over
  for-of loops to gain benefits of having less side effects and easier
  readability.
- Enable `downLevelIterations` for writing modern code with lazy evaluation.
- Refactor for of loops to named abstractions to clearly express their
  intentions without needing to analyse the loop itself.
- Add missing cases for changes that had no tests.
2022-01-04 21:45:22 +01:00

84 lines
2.3 KiB
TypeScript

import 'mocha';
import { expect } from 'chai';
import { sleep, SchedulerType, SchedulerCallbackType } from '@/infrastructure/Threading/AsyncSleep';
describe('AsyncSleep', () => {
describe('sleep', () => {
it('fulfills after delay', async () => {
// arrange
const delayInMs = 10;
const scheduler = new SchedulerMock();
// act
const promise = sleep(delayInMs, scheduler.mock);
const promiseState = watchPromiseState(promise);
scheduler.tickNext(delayInMs);
await flushPromiseResolutionQueue();
// assert
const actual = promiseState.isFulfilled();
expect(actual).to.equal(true);
});
it('pending before delay', async () => {
// arrange
const delayInMs = 10;
const scheduler = new SchedulerMock();
// act
const promise = sleep(delayInMs, scheduler.mock);
const promiseState = watchPromiseState(promise);
scheduler.tickNext(delayInMs / 5);
await flushPromiseResolutionQueue();
// assert
const actual = promiseState.isPending();
expect(actual).to.equal(true);
});
});
});
function flushPromiseResolutionQueue() {
return Promise.resolve();
}
class SchedulerMock {
public readonly mock: SchedulerType;
private currentTime = 0;
private scheduledActions = new Array<{time: number, action: SchedulerCallbackType}>();
constructor() {
this.mock = (callback: SchedulerCallbackType, ms: number) => {
this.scheduledActions.push({ time: this.currentTime + ms, action: callback });
};
}
public tickNext(ms: number) {
const newTime = this.currentTime + ms;
const dueActions = this.scheduledActions
.filter((action) => newTime >= action.time);
for (const action of dueActions) {
action.action();
}
this.scheduledActions = this.scheduledActions.filter((action) => !dueActions.includes(action));
}
}
function watchPromiseState<T>(promise: Promise<T>) {
let isPending = true;
let isRejected = false;
let isFulfilled = false;
promise.then(
() => {
isFulfilled = true;
isPending = false;
},
() => {
isRejected = true;
isPending = false;
},
);
return {
isFulfilled: () => isFulfilled,
isPending: () => isPending,
isRejected: () => isRejected,
};
}