diff --git a/lib/compose.test.ts b/lib/compose.test.ts index e85e070..eab6275 100644 --- a/lib/compose.test.ts +++ b/lib/compose.test.ts @@ -1,7 +1,7 @@ import { Promise } from '@emphori/promise'; import assert from 'node:assert'; import { describe, it } from 'node:test'; -import { Composition, UnaryComposableFunction, UnreachableFunctionWarning, compose, reject, resolve } from './compose.js'; +import { Composition, UnaryComposableFunction, UnreachableFunctionWarning, compose, reject, resolve, tap } from './compose.js'; describe('Maintaining safe compositions', () => { const composition1: Composition = @@ -174,6 +174,33 @@ describe('Scoping compositions', () => { }); }); +describe('resolve', () => { + it('should return a resolved Promise', () => { + return resolve('1').then((val): any => { + return assert.equal(val, '1'); + }); + }); +}); + +describe('reject', () => { + it('should return a rejected Promise', () => { + return reject('1').catch((val): any => { + return assert.equal(val, '1'); + }); + }); +}); + +describe('tap', () => { + const composition: Composition = + compose(safeTarget).then(tap(() => resolve('GoodbyeWorld'))); + + it('should not affect the return value of the Promise', () => { + return composition('Hello', 'World').then((val) => { + return assert.equal(val, 'HelloWorld'); + }); + }); +}); + /** * The block below confirms that compositions that will never fail are properly * typed. diff --git a/lib/compose.ts b/lib/compose.ts index 68c67b7..d559544 100644 --- a/lib/compose.ts +++ b/lib/compose.ts @@ -38,28 +38,38 @@ export interface Composition extends ComposableFun * @param fn - The function to compose */ export function compose(fn: ComposableFunction): Composition { - return Object.setPrototypeOf(function (this: C1, ...args: I1) { - return fn.apply(this, args); - }, compose); + return Object.setPrototypeOf(function (this: C1) { + return fn.apply(this, arguments as any as I1); + }, composable); } -Object.defineProperty(compose, 'then', { - value: function (this: any, fn: any): any { - const run = this; - return compose(function (...args) { - return run.apply(this, args).then((val: any) => fn.call(this, val)); - }); - }, -}); +function composable () {} -Object.defineProperty(compose, 'catch', { - value: function (this: any, fn: any): any { - const run = this; - return compose(function (...args) { - return run.apply(this, args).catch((val: any) => fn.call(this, val)); - }); - }, -}); +composable.then = function (this: any, fn: any): any { + const run = this; + return compose(function () { + return run.apply(this, arguments).then((val: any) => fn.call(this, val)); + }); +} + +composable.catch = function (this: any, fn: any): any { + const run = this; + return compose(function () { + return run.apply(this, arguments).catch((val: any) => fn.call(this, val)); + }); +} + +// export const resolve: typeof Promise.resolve = Promise.resolve.bind(Promise); +// export const reject: typeof Promise.reject = Promise.reject.bind(Promise); -export const resolve: typeof Promise.resolve = Promise.resolve.bind(Promise); -export const reject: typeof Promise.reject = Promise.reject.bind(Promise); +// export const resolve = (_: T) => Promise.resolve(_); +// export const reject = (_: T) => Promise.reject(_); + +export function resolve(_: T) { return Promise.resolve(_) } +export function reject(_: T) { return Promise.reject(_) } + +export function tap(fn: ComposableFunction) { + return function (this: C1, val: I1) { + return fn.call(this, val).then(() => val); + } +}