import { it } from 'vitest'; export function itEachAbsentStringValue( runner: (absentValue: string) => void, options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): void { itEachAbsentTestCase(getAbsentStringTestCases(options), runner); } export function itEachAbsentObjectValue( runner: (absentValue: AbsentObjectType) => void, options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): void { itEachAbsentTestCase(getAbsentObjectTestCases(options), runner); } export function itEachAbsentCollectionValue( runner: (absentValue: []) => void, options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): void { itEachAbsentTestCase(getAbsentCollectionTestCases(options), runner); } export function itEachAbsentTestCase( testCases: readonly IAbsentTestCase[], runner: (absentValue: T) => void, ): void { for (const testCase of testCases) { it(`given "${testCase.valueName}"`, () => { runner(testCase.absentValue); }); } } export function getAbsentObjectTestCases( options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): IAbsentTestCase[] { return [ { valueName: 'null', absentValue: null, }, ...(options.excludeUndefined ? [] : [ { valueName: 'undefined', absentValue: undefined, }, ]), ]; } export function getAbsentStringTestCases( options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): IAbsentStringCase[] { return [ { valueName: 'empty', absentValue: '', }, ...getAbsentObjectTestCases(options), ]; } export function getAbsentCollectionTestCases( options: IAbsentTestCaseOptions = DefaultAbsentTestCaseOptions, ): readonly IAbsentCollectionCase[] { return [ ...getAbsentObjectTestCases(options), { valueName: 'empty', absentValue: new Array(), }, ]; } const DefaultAbsentTestCaseOptions: IAbsentTestCaseOptions = { excludeUndefined: false, }; interface IAbsentTestCaseOptions { readonly excludeUndefined: boolean; } type AbsentObjectType = undefined | null; interface IAbsentTestCase { readonly valueName: string; readonly absentValue: T; } // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IAbsentStringCase extends IAbsentTestCase { // Marker interface } // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IAbsentCollectionCase extends IAbsentTestCase { // Marker interface }