Files
privacy.sexy/tests/unit/shared/TestCases/AbsentTests.ts
undergroundwires 949fac1a7c Refactor to enforce strictNullChecks
This commit applies `strictNullChecks` to the entire codebase to improve
maintainability and type safety. Key changes include:

- Remove some explicit null-checks where unnecessary.
- Add necessary null-checks.
- Refactor static factory functions for a more functional approach.
- Improve some test names and contexts for better debugging.
- Add unit tests for any additional logic introduced.
- Refactor `createPositionFromRegexFullMatch` to its own function as the
  logic is reused.
- Prefer `find` prefix on functions that may return `undefined` and
  `get` prefix for those that always return a value.
2023-11-12 22:54:00 +01:00

194 lines
7.1 KiB
TypeScript

import { it } from 'vitest';
export function itEachAbsentStringValue(
runner: (absentValue: string | null) => void,
options: { excludeUndefined: true, excludeNull?: false }
): void;
export function itEachAbsentStringValue(
runner: (absentValue: string | undefined) => void,
options: { excludeUndefined?: false, excludeNull: true }
): void;
export function itEachAbsentStringValue(
runner: (absentValue: string) => void,
options: { excludeUndefined: true, excludeNull: true }
): void;
export function itEachAbsentStringValue(
runner: (absentValue: string | null | undefined) => void,
options?: { excludeUndefined?: false, excludeNull?: false },
): void;
export function itEachAbsentStringValue(
runner: ((absentValue: string) => void)
| ((absentValue: string | null) => void)
| ((absentValue: string | undefined) => void)
| ((absentValue: string | null | undefined) => void),
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): void {
// Using `as any` due to limitation of TypeScript, this may be fixed in future versions.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
itEachAbsentTestCase(getAbsentStringTestCases(options as any), runner);
}
export function itEachAbsentCollectionValue<T>(
runner: (absentValue: T[] | null) => void,
options: { excludeUndefined: true, excludeNull?: false }
): void;
export function itEachAbsentCollectionValue<T>(
runner: (absentValue: T[] | undefined) => void,
options: { excludeUndefined?: false, excludeNull: true }
): void;
export function itEachAbsentCollectionValue<T>(
runner: (absentValue: T[]) => void,
options: { excludeUndefined: true, excludeNull: true }
): void;
export function itEachAbsentCollectionValue<T>(
runner: (absentValue: T[] | null | undefined) => void,
options?: { excludeUndefined?: false, excludeNull?: false },
): void;
export function itEachAbsentCollectionValue<T>(
runner: ((absentValue: T[]) => void)
| ((absentValue: T[] | null) => void)
| ((absentValue: T[] | undefined) => void)
| ((absentValue: T[] | null | undefined) => void),
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): void {
// Using `as any` due to limitation of TypeScript, this may be fixed in future versions.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
itEachAbsentTestCase(getAbsentCollectionTestCases<T>(options as any), runner);
}
export function itEachAbsentObjectValue(
runner: (absentValue: null) => void,
options: { excludeUndefined: true, excludeNull?: false },
): void;
export function itEachAbsentObjectValue(
runner: (absentValue: undefined) => void,
options: { excludeUndefined?: false, excludeNull: true },
): void;
export function itEachAbsentObjectValue(
runner: (absentValue: undefined | null) => void,
options?: { excludeUndefined?: false, excludeNull?: false } | AbsentTestCaseOptions,
): void;
export function itEachAbsentObjectValue(
runner: ((absentValue: null) => void)
| ((absentValue: undefined) => void)
| ((absentValue: null | undefined) => void),
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): void {
itEachAbsentTestCase(getAbsentObjectTestCases(options), runner);
}
export function itEachAbsentTestCase<T>(
testCases: readonly AbsentTestCase<T>[],
runner: (absentValue: T) => void,
): void {
for (const testCase of testCases) {
it(`given "${testCase.valueName}"`, () => {
runner(testCase.absentValue);
});
}
}
interface AbsentTestCaseOptions {
readonly excludeUndefined?: boolean;
readonly excludeNull?: boolean;
}
const DefaultAbsentTestCaseOptions: AbsentTestCaseOptions = {
excludeUndefined: false,
excludeNull: false,
};
interface AbsentTestCase<T> {
readonly valueName: string;
readonly absentValue: T;
}
export function getAbsentObjectTestCases(
options: { excludeUndefined: true, excludeNull?: false },
): ReadonlyArray<AbsentTestCase<null>>;
export function getAbsentObjectTestCases(
options: { excludeUndefined?: false, excludeNull: true },
): ReadonlyArray<AbsentTestCase<undefined>>;
export function getAbsentObjectTestCases(
options: { excludeUndefined: true, excludeNull: true },
): ReadonlyArray<never>;
export function getAbsentObjectTestCases(
options?: { excludeUndefined?: false, excludeNull?: false } | AbsentTestCaseOptions,
): ReadonlyArray<AbsentTestCase<null> | AbsentTestCase<undefined>>;
export function getAbsentObjectTestCases(
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): ReadonlyArray<AbsentTestCase<null> | AbsentTestCase<undefined>> {
const results: Array<AbsentTestCase<null> | AbsentTestCase<undefined>> = [];
if (!options.excludeNull) {
results.push({
valueName: 'null',
absentValue: null,
});
}
if (!options.excludeUndefined) {
results.push({
valueName: 'undefined',
absentValue: undefined,
});
}
return results;
}
export function getAbsentStringTestCases(
options?: { excludeUndefined: false, excludeNull: false },
): ReadonlyArray<AbsentTestCase<string> | AbsentTestCase<null> | AbsentTestCase<undefined>>;
export function getAbsentStringTestCases(
options: { excludeUndefined: true, excludeNull?: false }
): ReadonlyArray<AbsentTestCase<string> | AbsentTestCase<null>>;
export function getAbsentStringTestCases(
options: { excludeUndefined?: false, excludeNull: true }
): ReadonlyArray<AbsentTestCase<string> | AbsentTestCase<undefined>>;
export function getAbsentStringTestCases(
options: { excludeUndefined: true, excludeNull: true }
): ReadonlyArray<AbsentTestCase<string>>;
export function getAbsentStringTestCases(
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): ReadonlyArray<AbsentTestCase<string> | AbsentTestCase<null> | AbsentTestCase<undefined>> {
const results: Array<(
AbsentTestCase<string> | AbsentTestCase<null> | AbsentTestCase<undefined>
)> = [];
results.push({
valueName: 'empty',
absentValue: '',
});
const objectTestCases = getAbsentObjectTestCases(options);
results.push(...objectTestCases);
return results;
}
export function getAbsentCollectionTestCases<T>(
options?: { excludeUndefined: false, excludeNull: false },
): ReadonlyArray<AbsentTestCase<T[]> | AbsentTestCase<null> | AbsentTestCase<undefined>>;
export function getAbsentCollectionTestCases<T>(
options: { excludeUndefined: true, excludeNull?: false }
): ReadonlyArray<AbsentTestCase<T[]> | AbsentTestCase<null>>;
export function getAbsentCollectionTestCases<T>(
options: { excludeUndefined?: false, excludeNull: true }
): ReadonlyArray<AbsentTestCase<T[]> | AbsentTestCase<undefined>>;
export function getAbsentCollectionTestCases<T>(
options: { excludeUndefined: true, excludeNull: true }
): ReadonlyArray<AbsentTestCase<T[]>>;
export function getAbsentCollectionTestCases<T>(
options: AbsentTestCaseOptions = DefaultAbsentTestCaseOptions,
): ReadonlyArray<AbsentTestCase<T[]> | AbsentTestCase<null> | AbsentTestCase<undefined>> {
const results: Array<AbsentTestCase<T[]> | AbsentTestCase<null> | AbsentTestCase<undefined>> = [];
const objectTestCases = getAbsentObjectTestCases(options);
results.push(...objectTestCases);
results.push({
valueName: 'empty',
absentValue: [],
});
return results;
}