Skip to content
Merged
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
16 changes: 5 additions & 11 deletions packages/utils/src/promisebuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ function allPromises<U = unknown>(collection: Array<U | PromiseLike<U>>): Promis
}

export interface PromiseBuffer<T> {
length(): number;
// exposes the internal array so tests can assert on the state of it.
// XXX: this really should not be public api.
$: Array<PromiseLike<T>>;
add(taskProducer: () => PromiseLike<T>): PromiseLike<T>;
remove(task: PromiseLike<T>): PromiseLike<T>;
drain(timeout?: number): PromiseLike<boolean>;
}

Expand All @@ -36,10 +37,6 @@ export interface PromiseBuffer<T> {
export function makePromiseBuffer<T>(limit?: number): PromiseBuffer<T> {
const buffer: Array<PromiseLike<T>> = [];

function length(): number {
return buffer.length;
}

function isReady(): boolean {
return limit === undefined || buffer.length < limit;
}
Expand Down Expand Up @@ -113,12 +110,9 @@ export function makePromiseBuffer<T>(limit?: number): PromiseBuffer<T> {
});
}

const promiseBuffer: PromiseBuffer<T> = {
length,
return {
$: buffer,
add,
remove,
drain,
};

return promiseBuffer;
}
22 changes: 11 additions & 11 deletions packages/utils/test/promisebuffer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('PromiseBuffer', () => {
const buffer = makePromiseBuffer();
const p = jest.fn(() => new SyncPromise(resolve => setTimeout(resolve)));
void buffer.add(p);
expect(buffer.length()).toEqual(1);
expect(buffer.$.length).toEqual(1);
});

test('with limit', () => {
Expand All @@ -20,7 +20,7 @@ describe('PromiseBuffer', () => {
const producer2 = jest.fn(() => new SyncPromise(resolve => setTimeout(resolve)));
expect(buffer.add(producer1)).toEqual(task1);
void expect(buffer.add(producer2)).rejects.toThrowError();
expect(buffer.length()).toEqual(1);
expect(buffer.$.length).toEqual(1);
expect(producer1).toHaveBeenCalled();
expect(producer2).not.toHaveBeenCalled();
});
Expand All @@ -32,51 +32,51 @@ describe('PromiseBuffer', () => {
for (let i = 0; i < 5; i++) {
void buffer.add(() => new SyncPromise(resolve => setTimeout(resolve)));
}
expect(buffer.length()).toEqual(5);
expect(buffer.$.length).toEqual(5);
const result = await buffer.drain();
expect(result).toEqual(true);
expect(buffer.length()).toEqual(0);
expect(buffer.$.length).toEqual(0);
});

test('with timeout', async () => {
const buffer = makePromiseBuffer();
for (let i = 0; i < 5; i++) {
void buffer.add(() => new SyncPromise(resolve => setTimeout(resolve, 100)));
}
expect(buffer.length()).toEqual(5);
expect(buffer.$.length).toEqual(5);
const result = await buffer.drain(50);
expect(result).toEqual(false);
});

test('on empty buffer', async () => {
const buffer = makePromiseBuffer();
expect(buffer.length()).toEqual(0);
expect(buffer.$.length).toEqual(0);
const result = await buffer.drain();
expect(result).toEqual(true);
expect(buffer.length()).toEqual(0);
expect(buffer.$.length).toEqual(0);
});
});

test('resolved promises should not show up in buffer length', async () => {
const buffer = makePromiseBuffer();
const producer = () => new SyncPromise(resolve => setTimeout(resolve));
const task = buffer.add(producer);
expect(buffer.length()).toEqual(1);
expect(buffer.$.length).toEqual(1);
await task;
expect(buffer.length()).toEqual(0);
expect(buffer.$.length).toEqual(0);
});

test('rejected promises should not show up in buffer length', async () => {
const buffer = makePromiseBuffer();
const producer = () => new SyncPromise((_, reject) => setTimeout(reject));
const task = buffer.add(producer);
expect(buffer.length()).toEqual(1);
expect(buffer.$.length).toEqual(1);
try {
await task;
} catch (_) {
// no-empty
}
expect(buffer.length()).toEqual(0);
expect(buffer.$.length).toEqual(0);
});

test('resolved task should give an access to the return value', async () => {
Expand Down