Skip to content

Commit

Permalink
Merge 43e2dd4 into 096fddf
Browse files Browse the repository at this point in the history
  • Loading branch information
ufocoder committed Jan 28, 2020
2 parents 096fddf + 43e2dd4 commit 91514c4
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 15 deletions.
111 changes: 111 additions & 0 deletions __tests__/services/service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import {
applyDataTransformer,
applyErrorTransformer,
resolveServiceMap,
resolveDataResults,
resolveDataResultPromises,
resolveDataResultRecord,
resolveDataResultPromiseRecord,
PromiseRemoteDataResultMap,
} from '../../services/service';

Expand Down Expand Up @@ -170,4 +174,111 @@ describe('Service `service`', () => {
);
});
});

describe('Method `resolveDataResults`', () => {
test('process when data are failed', () => {
expect(resolveDataResults([failure('error'), failure('error')])).toEqual(failure(['error', 'error']));
});

test('process when data are mixed', () => {
expect(resolveDataResults([success('data'), failure('error')])).toEqual(failure(['error']));
});

test('process when data are success', () => {
expect(resolveDataResults([success('data-foo'), success('data-bar')])).toEqual(
success(['data-foo', 'data-bar'])
);
});
});

describe('Method `resolveDataResultPromises`', () => {
test('process when data are failed', async () => {
expect(
await resolveDataResultPromises([Promise.resolve(failure('error')), Promise.resolve(failure('error'))])
).toEqual(failure(['error', 'error']));
});

test('process when data are mixed', async () => {
expect(
await resolveDataResultPromises([Promise.resolve(success('data')), Promise.resolve(failure('error'))])
).toEqual(failure(['error']));
});

test('process when data are success', async () => {
expect(
await resolveDataResultPromises([
Promise.resolve(success('data-foo')),
Promise.resolve(success('data-bar')),
])
).toEqual(success(['data-foo', 'data-bar']));
});
});

describe('Method `resolveDataResultRecord`', () => {
test('process when data are failed', () => {
expect(
resolveDataResultRecord({
a: failure('error'),
b: failure('error'),
})
).toEqual(failure(['error', 'error']));
});

test('process when data are mixed', () => {
expect(
resolveDataResultRecord({
a: success('data'),
b: failure('error'),
})
).toEqual(failure(['error']));
});

test('process when data are success', () => {
expect(
resolveDataResultRecord({
a: success('data-foo'),
b: success('data-bar'),
})
).toEqual(
success({
a: 'data-foo',
b: 'data-bar',
})
);
});
});

describe('Method `resolveDataResultPromiseRecord`', () => {
test('process when data are failed', async () => {
expect(
await resolveDataResultPromiseRecord({
a: Promise.resolve(failure('error')),
b: Promise.resolve(failure('error')),
})
).toEqual(failure(['error', 'error']));
});

test('process when data are mixed', async () => {
expect(
await resolveDataResultPromiseRecord({
a: Promise.resolve(success('data')),
b: Promise.resolve(failure('error')),
})
).toEqual(failure(['error']));
});

test('process when data are success', async () => {
expect(
await resolveDataResultPromiseRecord({
a: Promise.resolve(success('data-foo')),
b: Promise.resolve(success('data-bar')),
})
).toEqual(
success({
a: 'data-foo',
b: 'data-bar',
})
);
});
});
});
73 changes: 58 additions & 15 deletions services/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,65 @@ export function mapFailure<S = any, F = any, R = any>(
}

export type PromiseRemoteDataResultMap<T, F> = { [P in keyof T]: Promise<RemoteDataResult<T[P], F>> };

export function resolveDataResults<T, F>(remoteDataResults: Array<RemoteDataResult<T, F>>): RemoteDataResult<T[], F[]> {
if (isSuccessAll(remoteDataResults)) {
return success(_.map(remoteDataResults, (remoteDataResult) => remoteDataResult.data));
}

return failure(
_.compact(
_.map(remoteDataResults, (remoteDataResult) =>
isFailure(remoteDataResult) ? remoteDataResult.error : undefined
)
)
);
}

export async function resolveDataResultPromises<T, F>(
remoteDataResultPromises: Array<Promise<RemoteDataResult<T, F>>>
): Promise<RemoteDataResult<T[], F[]>> {
const remoteDataResults = (await Promise.all(remoteDataResultPromises)) as Array<RemoteDataResult<T, F>>;

return resolveDataResults(remoteDataResults);
}

function createKeysMapTransformer<K = any>(keys: Array<K>) {
return <S = any, R = any>(data: S): R =>
keys.reduce((transformed, key, index) => {
transformed[key] = data[index];
return transformed;
}, {} as any);
}

export function resolveDataResultRecord<K, T, F>(
remoteDataResultRecord: Record<string, RemoteDataResult<T, F>>
): RemoteDataResult<Record<string, T>, F[]> {
const keys = Object.keys(remoteDataResultRecord);
const remoteDataResults = Object.values(remoteDataResultRecord) as Array<RemoteDataResult<any>>;

return mapSuccess(resolveDataResults(remoteDataResults), createKeysMapTransformer(keys));
}

export async function resolveDataResultPromiseRecord<K, T, F>(
remoteDataResultRecord: Record<string, Promise<RemoteDataResult<T, F>>>
): Promise<RemoteDataResult<Record<string, T>, F[]>> {
const keys = Object.keys(remoteDataResultRecord);
const remoteDataResults = (await Promise.all(Object.values(remoteDataResultRecord))) as Array<
RemoteDataResult<any>
>;
const result = mapSuccess(resolveDataResults(remoteDataResults), createKeysMapTransformer(keys));

return Promise.resolve(result);
}

export async function resolveServiceMap<I, F>(
promisesMap: PromiseRemoteDataResultMap<I, F>
): Promise<RemoteDataResult<I, F[]>> {
const keys = _.keys(promisesMap);
const values = _.values(promisesMap);

const responses = (await Promise.all(values)) as Array<RemoteDataResult<any>>;

if (isSuccessAll(responses)) {
return success(
_.zipObject(
keys,
_.map(responses, (response) => response.data)
) as I
);
} else {
return failure(_.compact(_.map(responses, (response) => (isFailure(response) ? response.error : undefined))));
}
const keys = Object.keys(promisesMap);
const responses = (await Promise.all(Object.values(promisesMap))) as Array<RemoteDataResult<any>>;
const remoteDataResult = resolveDataResults(responses);
const result = mapSuccess(remoteDataResult, createKeysMapTransformer(keys));

return Promise.resolve(result);
}

0 comments on commit 91514c4

Please sign in to comment.