Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

Commit

Permalink
feat(loadHelpers): return promise from defer (#26)
Browse files Browse the repository at this point in the history
Permits defer to function within a sequence.

Co-authored-by: Mike Tobia <Francois-Esquire@users.noreply.github.com>
  • Loading branch information
drewcur and Francois-Esquire authored Aug 14, 2020
1 parent c229466 commit 0abff28
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 9 deletions.
64 changes: 56 additions & 8 deletions __tests__/loadHelpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,16 @@ describe('', () => {
});

describe('defer', () => {
let globalState;
const loadFunc = () => {
const data = globalState.x;
const loadFunc = jest.fn(() => {
const data = 'x data';
const status = data ? 'complete' : 'loading';
const promise = Promise.resolve('x data').then((res) => { globalState.x = res; });
const promise = Promise.resolve(data);

return { data, status, promise };
};
});

beforeEach(() => {
globalState = {};
loadFunc.mockClear();
});

it('should skip the load function and just return a loading response when on server', async () => {
Expand All @@ -50,19 +49,23 @@ describe('', () => {
let loadResponse = wrappedLoadFunc();
await Promise.all([loadResponse.promise]);
loadResponse = wrappedLoadFunc();
expect(loadFunc).not.toHaveBeenCalled();
expect(loadResponse.data).not.toBeDefined();
expect(loadResponse.status).toBe('loading');
expect(loadResponse.promise).not.toBeDefined();
expect(loadResponse.promise).toBeInstanceOf(Promise);
expect(loadResponse.promise).resolves.toBeUndefined();
});

it('should use the wrapped load function when not on the server', async () => {
const wrappedLoadFunc = defer(loadFunc);
let loadResponse = wrappedLoadFunc();
await Promise.all([loadResponse.promise]);
loadResponse = wrappedLoadFunc();
expect(loadFunc).toHaveBeenCalled();
expect(loadResponse.data).toBe('x data');
expect(loadResponse.status).toBe('complete');
expect(loadResponse.promise).toBeDefined();
expect(loadResponse.promise).toBeInstanceOf(Promise);
expect(loadResponse.promise).resolves.toEqual('x data');
});
});

Expand Down Expand Up @@ -207,5 +210,50 @@ describe('', () => {
await Promise.all(seqPromises);
expect(seq2).toHaveBeenCalledWith({ seq1: { seq1A: 'seq1A data', seq1B: 'seq1B data' } });
});

it('should work with deferred functions on the server', async () => {
enableSSR();
const seq1 = jest.fn(() => ({ status: 'loading', data: 'seq1 data', promise: Promise.resolve('seq1 data') }));
const seq2 = jest.fn(() => ({ status: 'loading', data: 'seq2 data', promise: Promise.resolve('seq2 data') }));
const seq3 = jest.fn(() => ({ status: 'loading', data: 'seq3 data', promise: Promise.resolve('seq3 data') }));

const sequenceFuncs = sequence([
{ key: 'seq1', handler: seq1 },
{ key: 'seq2', handler: defer(seq2) },
{ key: 'seq3', handler: defer(seq3) },
]);

const resultMap = mapValues(sequenceFuncs, value => value());

const seq2Resolve = await resultMap.seq2.promise;
expect(seq2).not.toHaveBeenCalled();
expect(seq2Resolve).toEqual({ seq1: 'seq1 data', seq2: undefined });

const seq3Resolve = await resultMap.seq3.promise;
expect(seq3).not.toHaveBeenCalled();
expect(seq3Resolve).toEqual({ seq1: 'seq1 data', seq2: undefined, seq3: undefined });
});

it('should work with deferred functions on the client', async () => {
const seq1 = jest.fn(() => ({ status: 'loading', data: 'seq1 data', promise: Promise.resolve('seq1 data') }));
const seq2 = jest.fn(() => ({ status: 'loading', data: 'seq2 data', promise: Promise.resolve('seq2 data') }));
const seq3 = jest.fn(() => ({ status: 'loading', data: 'seq3 data', promise: Promise.resolve('seq3 data') }));

const sequenceFuncs = sequence([
{ key: 'seq1', handler: seq1 },
{ key: 'seq2', handler: defer(seq2) },
{ key: 'seq3', handler: defer(seq3) },
]);

const resultMap = mapValues(sequenceFuncs, value => value());

const seq2Resolve = await resultMap.seq2.promise;
expect(seq2).toHaveBeenCalled();
expect(seq2Resolve).toEqual({ seq1: 'seq1 data', seq2: 'seq2 data' });

const seq3Resolve = await resultMap.seq3.promise;
expect(seq3).toHaveBeenCalled();
expect(seq3Resolve).toEqual({ seq1: 'seq1 data', seq2: 'seq2 data', seq3: 'seq3 data' });
});
});
});
2 changes: 1 addition & 1 deletion src/loadHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function defer(func) {
return func;
}

return () => ({ status: 'loading', noncritical: true });
return () => ({ status: 'loading', promise: Promise.resolve(), noncritical: true });
}

export function noncritical(func) {
Expand Down

0 comments on commit 0abff28

Please sign in to comment.