quasqui
Version:
The meta-framework suite designed from scratch for frontend-focused modern web development.
173 lines (125 loc) • 4.47 kB
text/typescript
import { enable, disable } from 'farrow-pipeline/asyncHooks.node';
import {
createWaterfall,
createAsyncWaterfall,
createContext,
createContainer,
isWaterfall,
isAsyncWaterfall,
} from '../src';
import { sleep } from './helpers';
describe('waterfall', () => {
it('base usage', () => {
const waterfall = createWaterfall<{ count: number }>();
waterfall.use(({ count }) => ({ count: count + 1 }));
waterfall.use(a => a);
waterfall.use(a => a);
expect(waterfall.run({ count: 0 })).toStrictEqual({ count: 1 });
});
it('should support async waterfall', async () => {
const waterfall = createAsyncWaterfall<{ count: number }>();
waterfall.use(async ({ count }) => ({ count: count + 1 }));
waterfall.use(a => a);
waterfall.use(a => a);
expect(await waterfall.run({ count: 0 })).toStrictEqual({ count: 1 });
});
it('should support hook in async waterfall', async () => {
const waterfall = createAsyncWaterfall<number>();
const Count = createContext({ count: 10 });
const incre = async () => {
await sleep(0);
Count.set({ count: Count.assert().count + 1 });
};
const list: { count: number }[] = [];
waterfall.use(async count => {
const before = Count.get();
await incre();
const after = Count.get();
list.push(before, after);
return count + Count.get().count;
});
waterfall.use(async count => {
await sleep(0);
await incre();
return count + Count.get().count;
});
const container = createContainer({ count: Count });
enable();
const result = await waterfall.run(10, { container });
disable();
expect(result).toBe(33);
expect(list).toStrictEqual([{ count: 10 }, { count: 11 }]);
});
describe('sync', () => {
it('should support waterfall.use(anotherWaterfall) if their type is matched', () => {
const StepContext = createContext(1);
const waterfall0 = createWaterfall<number>();
const waterfall1 = createWaterfall<number>();
const steps = [] as number[];
waterfall0.use(input => {
const step = StepContext.use();
return input + step.value++;
});
waterfall0.use(waterfall1);
waterfall1.use(input => {
const step = StepContext.use();
steps.push(step.value);
return input + step.value;
});
const result0 = waterfall1.run(0);
const result1 = waterfall0.run(0);
expect(result0).toEqual(1);
expect(result1).toEqual(3);
expect(steps).toEqual([1, 2]);
});
it('should throw error when add illegal brook', () => {
const waterfall = createWaterfall<number>();
expect(() => waterfall.use({} as any)).toThrowError();
});
it('isWaterfall', () => {
const waterfall = createWaterfall();
expect(isWaterfall(waterfall)).toBeTruthy();
expect(isWaterfall({})).toBeFalsy();
expect(isWaterfall('test')).toBeFalsy();
expect(isWaterfall(null)).toBeFalsy();
});
});
describe('async', () => {
it('should support waterfall.use(anotherWaterfall) if their type is matched', async () => {
const StepContext = createContext(1);
const waterfall0 = createAsyncWaterfall<number>();
const waterfall1 = createAsyncWaterfall<number>();
const steps = [] as number[];
waterfall0.use(async input => {
await sleep(0);
const step = StepContext.use();
return input + step.value++;
});
waterfall0.use(waterfall1);
waterfall1.use(async input => {
const step = StepContext.use();
steps.push(step.value);
await sleep(0);
return input + step.value;
});
enable();
const result0 = await waterfall1.run(0);
const result1 = await waterfall0.run(0);
disable();
expect(result0).toEqual(1);
expect(result1).toEqual(3);
expect(steps).toEqual([1, 2]);
});
it('should throw error when add illegal brook', () => {
const waterfall = createAsyncWaterfall<number>();
expect(() => waterfall.use({} as any)).toThrowError();
});
it('isAsyncWaterfall', () => {
const waterfall = createAsyncWaterfall();
expect(isAsyncWaterfall(waterfall)).toBeTruthy();
expect(isAsyncWaterfall({})).toBeFalsy();
expect(isAsyncWaterfall('test')).toBeFalsy();
expect(isAsyncWaterfall(null)).toBeFalsy();
});
});
});