Skip to content

Commit

Permalink
feat(utils/compose): adds create argument to compose; improves typings
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed May 12, 2019
1 parent 2edc4f5 commit a051a63
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 22 deletions.
11 changes: 9 additions & 2 deletions src/utils/compose.ts
@@ -1,6 +1,13 @@
import { asNew } from '~/helpers';

export default function compose(
...fns: Array<(value: any) => any>
): (value: any) => any {
...fns: Array<<T>(promise: Promise<T>, create?: boolean) => Promise<T>>
): <T>(promise: Promise<T>, create?: boolean) => Promise<T> {
const fn = trunk(...fns);
return (promise, create) => fn(asNew(promise, create));
}

export function trunk(...fns: Array<(value: any) => any>): (value: any) => any {
if (fns.length === 0) return (arg: any) => arg;
if (fns.length === 1) return fns[0];

Expand Down
86 changes: 66 additions & 20 deletions test/utils/compose.test.ts
@@ -1,23 +1,69 @@
import compose from '~/utils/compose';
import compose, { trunk } from '~/utils/compose';
import status from '~/compose/status';
import timed from '~/compose/timed';

test(`Doesn't throw on empty`, () => {
expect(() => compose()).not.toThrow();
});
test(`Returns function`, () => {
expect(typeof compose()).toBe('function');
});
test(`Works for 0 args`, () => {
expect(compose()(100)).toBe(100);
});
test(`Works for 1 arg`, () => {
expect(compose((x) => x * 2)(100)).toBe(200);
describe(`compose`, () => {
test(`no fn`, async () => {
const promise = Promise.resolve(1);
const fn = compose();

expect(fn(promise)).toBe(promise);
await expect(fn(promise)).resolves.toBe(1);

expect(fn(promise, true)).not.toBe(promise);
await expect(fn(promise, true)).resolves.toBe(1);
});
test(`single fn`, async () => {
const promise = Promise.resolve(1);
const fn = compose(status);

expect(fn(promise)).toBe(promise);
expect(fn(promise)).toHaveProperty('status');
await expect(fn(promise)).resolves.toBe(1);

expect(fn(promise, true)).not.toBe(promise);
expect(fn(promise, true)).toHaveProperty('status');
await expect(fn(promise, true)).resolves.toBe(1);
});
test(`multiple fns`, async () => {
const promise = Promise.resolve(1);
const fn = compose(
status,
timed
);

expect(fn(promise)).toBe(promise);
expect(fn(promise)).toHaveProperty('status');
expect(fn(promise)).toHaveProperty('time');
await expect(fn(promise)).resolves.toBe(1);

expect(fn(promise, true)).not.toBe(promise);
expect(fn(promise, true)).toHaveProperty('status');
expect(fn(promise)).toHaveProperty('time');
await expect(fn(promise, true)).resolves.toBe(1);
});
});
test(`Executes in order`, () => {
const fns = [
(x: number) => x / 2,
(x: number) => x / 5,
(x: number) => x * 6,
(x: number) => x / 3
];
expect(compose(...fns)(100)).toBe(20);

describe(`trunk`, () => {
test(`Doesn't throw on empty`, () => {
expect(() => trunk()).not.toThrow();
});
test(`Returns function`, () => {
expect(typeof trunk()).toBe('function');
});
test(`Works for 0 args`, () => {
expect(trunk()(100)).toBe(100);
});
test(`Works for 1 arg`, () => {
expect(trunk((x) => x * 2)(100)).toBe(200);
});
test(`Executes in order`, () => {
const fns = [
(x: number) => x / 2,
(x: number) => x / 5,
(x: number) => x * 6,
(x: number) => x / 3
];
expect(trunk(...fns)(100)).toBe(20);
});
});

0 comments on commit a051a63

Please sign in to comment.