UNPKG

@daisugi/daisugi

Version:

Daisugi is a minimalist functional middleware engine.

738 lines (514 loc) 15.3 kB
import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import { Daisugi, type DaisugiHandler, type DaisugiToolkit, } from '../daisugi.js'; interface Obj { sum: string; } describe('sequenceOf ', () => { describe('downstream', () => { describe('synchronous', () => { it('basic', () => { const { sequenceOf } = new Daisugi(); function a(arg1: string) { return `${arg1}1`; } function b(arg1: string) { return `${arg1}2`; } function c(arg1: string) { return `${arg1}3`; } const result = sequenceOf([a, b, c])(0); assert.strictEqual(result, '0123'); }); it('composing', () => { const { sequenceOf } = new Daisugi(); function a(arg1: string) { return `${arg1}1`; } function b(arg1: string) { return `${arg1}2`; } function c(arg1: string) { return `${arg1}3`; } function d(arg1: string) { return `${arg1}4`; } const result = sequenceOf([ a, sequenceOf([b, c]), d, ])(0); assert.strictEqual(result, '01234'); }); it('Daisugi.stopPropagationWith', () => { const { sequenceOf } = new Daisugi(); function a(arg1: string) { return `${arg1}1`; } function b(arg1: string) { return Daisugi.stopPropagationWith(`${arg1}2`); } function c(arg1: string) { return `${arg1}3`; } const result = sequenceOf([a, b, c])(0); assert.strictEqual(result, '012'); }); it('Daisugi.failWith', () => { const { sequenceOf } = new Daisugi(); function a(arg1: string) { return `${arg1}1`; } function b(arg1: string) { return Daisugi.failWith(`${arg1}2`); } function c(arg1: string) { return `${arg1}3`; } const result = sequenceOf([ a, sequenceOf([b, c]), c, ])(0); assert.strictEqual( result.getError().meta.value, '012', ); }); }); describe('asynchronous', () => { it('basic', async () => { const { sequenceOf } = new Daisugi(); async function a(arg1: string) { return `${arg1}1`; } async function b(arg1: string) { return `${arg1}2`; } async function c(arg1: string) { return `${arg1}3`; } const result = await sequenceOf([a, b, c])(0); assert.strictEqual(result, '0123'); }); }); }); describe('downstream/upstream', () => { describe('synchronous', () => { it('Daisugi.failWith', () => { const { sequenceOf } = new Daisugi(); const obj1 = { sum: 0 }; function a(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}1`; toolkit.next; arg1.sum = `${arg1.sum}5`; return arg1; } a.meta = { injectToolkit: true }; function b(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}2`; return toolkit.failWith(arg1); } b.meta = { injectToolkit: true }; function c(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}3`; toolkit.next; arg1.sum = `${arg1.sum}4`; return arg1; } c.meta = { injectToolkit: true }; const result = sequenceOf([ a, sequenceOf([b, c]), c, ])(obj1); assert.strictEqual(result.sum, '0125'); }); it('next with multiple arguments', () => { const { sequenceOf } = new Daisugi(); const obj1 = { sum: 0 }; const obj2 = { sum: 0 }; function a( arg1: Obj, arg2: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}1`; arg2.sum = `${arg2.sum}1`; toolkit.next; arg1.sum = `${arg1.sum}6`; } a.meta = { injectToolkit: true }; function b( arg1: Obj, arg2: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}2`; arg2.sum = `${arg2.sum}2`; toolkit.next; arg1.sum = `${arg1.sum}5`; } b.meta = { injectToolkit: true }; function c( arg1: Obj, arg2: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}3`; arg2.sum = `${arg2.sum}3`; toolkit.next; arg1.sum = `${arg1.sum}4`; } c.meta = { injectToolkit: true }; sequenceOf([a, b, c])(obj1, obj2); assert.strictEqual(obj1.sum, '0123456'); assert.strictEqual(obj2.sum, '0123'); }); it('nextWith', () => { const { sequenceOf } = new Daisugi(); function a(arg1: Obj, toolkit: DaisugiToolkit) { const result = toolkit.nextWith(`${arg1}1`); return `${result}5`; } a.meta = { injectToolkit: true }; function b(arg1: Obj, toolkit: DaisugiToolkit) { const result = toolkit.nextWith(`${arg1}2`); return `${result}4`; } b.meta = { injectToolkit: true }; function c(arg1: string) { return `${arg1}3`; } const result = sequenceOf([a, b, c])(0); assert.strictEqual(result, '012345'); }); it('nextWith with multiple arguments', () => { const { sequenceOf } = new Daisugi(); function a( arg1: Obj, arg2: Obj, toolkit: DaisugiToolkit, ) { const result = toolkit.nextWith( `${arg1}${arg2}`, 2, ); return `${result}6`; } a.meta = { injectToolkit: true }; function b( arg1: Obj, arg2: Obj, toolkit: DaisugiToolkit, ) { const result = toolkit.nextWith( `${arg1}${arg2}`, 3, ); return `${result}5`; } b.meta = { injectToolkit: true }; function c(arg1: Obj, arg2: Obj) { return `${arg1}${arg2}4`; } const result = sequenceOf([a, b, c])(0, 1); assert.strictEqual(result, '0123456'); }); it('multiple calls', () => { const { sequenceOf } = new Daisugi(); function a(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}1`; toolkit.next; return arg1; } a.meta = { injectToolkit: true }; function b(arg1: Obj) { arg1.sum = `${arg1.sum}2`; return arg1; } const handler = sequenceOf([a, b]); assert.strictEqual(handler({ sum: 0 }).sum, '012'); assert.strictEqual(handler({ sum: 0 }).sum, '012'); }); }); describe('asynchronous', () => { const { sequenceOf } = new Daisugi(); it('next', async () => { const obj1 = { sum: 0 }; async function a( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}1`; await toolkit.next; arg1.sum = `${arg1.sum}6`; } a.meta = { injectToolkit: true }; async function b( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}2`; await toolkit.next; arg1.sum = `${arg1.sum}5`; } b.meta = { injectToolkit: true }; async function c( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}3`; await toolkit.next; arg1.sum = `${arg1.sum}4`; } c.meta = { injectToolkit: true }; await sequenceOf([a, b, c])(obj1); assert.strictEqual(obj1.sum, '0123456'); }); it('nextWith', async () => { async function a( arg1: Obj, toolkit: DaisugiToolkit, ) { const result = await toolkit.nextWith(`${arg1}1`); return `${result}5`; } a.meta = { injectToolkit: true }; async function b( arg1: Obj, toolkit: DaisugiToolkit, ) { const result = await toolkit.nextWith(`${arg1}2`); return `${result}4`; } b.meta = { injectToolkit: true }; async function c(arg1: string) { return `${arg1}3`; } const result = await sequenceOf([a, b, c])(0); assert.strictEqual(result, '012345'); }); it('composing', async () => { const { sequenceOf } = new Daisugi(); const obj1 = { sum: 0 }; async function a( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}1`; await toolkit.next; arg1.sum = `${arg1.sum}8`; return arg1; } a.meta = { injectToolkit: true }; async function b( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}2`; await toolkit.next; arg1.sum = `${arg1.sum}5`; return arg1; } b.meta = { injectToolkit: true }; async function c( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}3`; await toolkit.next; arg1.sum = `${arg1.sum}4`; return arg1; } c.meta = { injectToolkit: true }; async function d( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}6`; await toolkit.next; arg1.sum = `${arg1.sum}7`; return arg1; } d.meta = { injectToolkit: true }; const result = await sequenceOf([ a, sequenceOf([b, c]), d, ])(obj1); assert.strictEqual(obj1.sum, '012345678'); assert.strictEqual(result.sum, '012345678'); }); }); describe('synchronous/asynchronous', () => { it('composing', async () => { const { sequenceOf } = new Daisugi(); const obj1 = { sum: 0 }; async function a( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}1`; await toolkit.next; arg1.sum = `${arg1.sum}8`; return arg1; } a.meta = { injectToolkit: true }; function b(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}2`; toolkit.next; arg1.sum = `${arg1.sum}5`; return arg1; } b.meta = { injectToolkit: true }; async function c( arg1: Obj, toolkit: DaisugiToolkit, ) { arg1.sum = `${arg1.sum}3`; await toolkit.next; arg1.sum = `${arg1.sum}4`; return arg1; } c.meta = { injectToolkit: true }; function d(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}6`; toolkit.next; arg1.sum = `${arg1.sum}7`; return arg1; } d.meta = { injectToolkit: true }; const result = await sequenceOf([ a, sequenceOf([b, c]), d, ])(obj1); // TODO: Need to be reviewed. assert.strictEqual(obj1.sum, '012356748'); assert.strictEqual(result.sum, '012356748'); }); }); }); }); describe('decorator', () => { it('basic', () => { function decorator(handler: DaisugiHandler) { return (arg1: string) => { return `${handler(arg1)}x`; }; } const { sequenceOf } = new Daisugi([decorator]); function a(arg1: string) { return `${arg1}1`; } function b(arg1: string) { return `${arg1}2`; } const result = sequenceOf([a, b])(0); assert.strictEqual(result, '01x2x'); }); it('synchronous/asynchronous', () => { function decorator(handler: DaisugiHandler) { return (arg1: Obj, toolkit: DaisugiToolkit) => { arg1.sum = `${arg1.sum}x`; handler(arg1, toolkit); arg1.sum = `${arg1.sum}y`; }; } const { sequenceOf } = new Daisugi([decorator]); const obj1 = { sum: 0 }; function a(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}1`; toolkit.next; arg1.sum = `${arg1.sum}6`; } a.meta = { injectToolkit: true }; function b(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}2`; toolkit.next; arg1.sum = `${arg1.sum}5`; } b.meta = { injectToolkit: true }; function c(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}3`; toolkit.next; arg1.sum = `${arg1.sum}4`; } c.meta = { injectToolkit: true }; sequenceOf([a, b, c])(obj1); assert.strictEqual(obj1.sum, '0x1x2x34y5y6y'); }); it('extend toolkit', () => { function decorator( handler: DaisugiHandler, toolkit: DaisugiToolkit, ) { toolkit.extended = (arg1: Obj) => { arg1.sum = `${arg1.sum}x`; toolkit.next; }; return (arg1: Obj, toolkit: DaisugiToolkit) => { handler(arg1, toolkit); }; } const { sequenceOf } = new Daisugi([decorator]); const obj1 = { sum: 0 }; function a(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}1`; toolkit.extended(arg1); } a.meta = { injectToolkit: true }; function b(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}2`; toolkit.extended(arg1); } b.meta = { injectToolkit: true }; function c(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}3`; toolkit.extended(arg1); } c.meta = { injectToolkit: true }; sequenceOf([a, b, c])(obj1); assert.strictEqual(obj1.sum, '01x2x3x'); }); it('use meta', () => { function decorator1(handler: DaisugiHandler) { return (arg1: Obj, toolkit: DaisugiToolkit) => { // @ts-expect-error arg1.sum = `${arg1.sum}${handler.meta.arg}`; handler(arg1, toolkit); }; } function decorator2(handler: DaisugiHandler) { return (arg1: Obj, toolkit: DaisugiToolkit) => { // @ts-expect-error arg1.sum = `${arg1.sum}${handler.meta.arg}-`; handler(arg1, toolkit); }; } const { sequenceOf } = new Daisugi([ decorator1, decorator2, ]); const obj1 = { sum: 0 }; function a(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}1`; toolkit.next; } a.meta = { injectToolkit: true, arg: 'x' }; function b(arg1: Obj, toolkit: DaisugiToolkit) { arg1.sum = `${arg1.sum}2`; toolkit.next; } b.meta = { injectToolkit: true, arg: 'y' }; sequenceOf([a, b])(obj1); assert.strictEqual(obj1.sum, '0x-x1y-y2'); }); });