Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -166,6 +166,7 @@ describe('index', () => {
"uint8ArrayToMnemonic",
"unitMap",
"valueToBytes",
"waitFor",
"wrapError",
]
`);
Expand Down
1 change: 1 addition & 0 deletions src/node.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,6 +173,7 @@ describe('node', () => {
"uint8ArrayToMnemonic",
"unitMap",
"valueToBytes",
"waitFor",
"wrapError",
"writeFile",
"writeJsonFile",
Expand Down
41 changes: 40 additions & 1 deletion src/time.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import { Duration, inMilliseconds, timeSince } from '.';
import { Duration, inMilliseconds, timeSince, waitFor } from '.';

describe('time utilities', () => {
describe('Duration', () => {
Expand DownExpand Up@@ -63,3 +63,42 @@ describe('time utilities', () => {
});
});
});

describe('waitFor', () => {
beforeEach(() => {
jest.useFakeTimers();
});

afterEach(() => {
jest.useRealTimers();
});

it('resolves once the given duration has elapsed', async () => {
const onResolved = jest.fn();
const promise = waitFor(Duration.Second).then(onResolved);

await Promise.resolve();
jest.advanceTimersByTime(Duration.Second - 1);
await Promise.resolve();
expect(onResolved).not.toHaveBeenCalled();

jest.advanceTimersByTime(1);
await promise;
expect(onResolved).toHaveBeenCalledTimes(1);
});

it('resolves with undefined for a zero duration', async () => {
const promise = waitFor(0);
jest.advanceTimersByTime(0);
expect(await promise).toBeUndefined();
});

it('rejects for a negative or non-integer duration', async () => {
await expect(waitFor(-1)).rejects.toThrow(
'"milliseconds" must be a non-negative integer. Received: "-1".',
);
await expect(waitFor(1.5)).rejects.toThrow(
'"milliseconds" must be a non-negative integer. Received: "1.5".',
);
});
});
15 changes: 15 additions & 0 deletions src/time.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,3 +71,18 @@ export function timeSince(timestamp: number): number {
assertIsNonNegativeInteger(timestamp, 'timestamp');
return Date.now() - timestamp;
}

/**
* Waits for the given number of milliseconds.
*
* This is a promisified `setTimeout`, useful for pausing execution in an async
* function. Combine it with {@link inMilliseconds} to wait for a different
* {@link Duration}, for example `waitFor(inMilliseconds(2, Duration.Second))`.
*
* @param milliseconds - The number of milliseconds to wait.
* @returns A promise that resolves once the given duration has elapsed.
*/
export async function waitFor(milliseconds: number): Promise<void> {
assertIsNonNegativeInteger(milliseconds, 'milliseconds');
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}