import { AssertionFailed } from './errors'; import { prettyPrint } from './prettyPrint/typeAware/prettyPrint'; import { typeOf } from 'typedescriptor'; import { error, Result, value } from 'defekt'; type Assertion = (actual: TValue, ...rest: TParams) => Result; const wrapAssertionForIterable = function ( assertion: Assertion ): Assertion | Map, TParams> { return (actual: TValue[] | Set | Map, ...params: TParams): Result => { for (const [ index, item ] of actual.entries()) { const result = assertion(item, ...params); if (result.hasError()) { return error( new AssertionFailed({ message: `Assertion failed for item ${prettyPrint(index)} of the ${typeOf(actual)}.\n${result.error.message}`, actual: result.error.data.actual, expected: result.error.data.expected, diff: result.error.data.diff }) ); } } return value(); }; }; type AsyncAssertion = (actual: TValue, ...rest: TParams) => Promise>; const wrapAsyncAssertionForIterable = function ( assertion: AsyncAssertion ): AsyncAssertion | Map, TParams> { return async (actual: TValue[] | Set | Map, ...params: TParams): Promise> => { for (const [ index, item ] of actual.entries()) { const result = await assertion(item, ...params); if (result.hasError()) { return error( new AssertionFailed({ message: `Assertion failed for item ${prettyPrint(index)} of the ${typeOf(actual)}.\n${result.error.message}`, actual: result.error.data.actual, expected: result.error.data.expected, diff: result.error.data.diff }) ); } } return value(); }; }; export { wrapAssertionForIterable, wrapAsyncAssertionForIterable };