interface IComparerTestCase { readonly name: string; readonly first: readonly T[]; readonly second: readonly T[]; readonly expected: boolean; } export class ComparerTestScenario { private readonly testCases: Array> = []; public addEmptyArrays(expectedResult: boolean) { return this.addTestCase({ name: 'empty array', first: [], second: [], expected: expectedResult, }, true); } public addSameItemsWithSameOrder(expectedResult: boolean) { return this.addTestCase({ name: 'same items with same order', first: [1, 2, 3], second: [1, 2, 3], expected: expectedResult, }, true); } public addSameItemsWithDifferentOrder(expectedResult: boolean) { return this.addTestCase({ name: 'same items with different order', first: [1, 2, 3], second: [2, 3, 1], expected: expectedResult, }, true); } public addDifferentItemsWithSameLength(expectedResult: boolean) { return this.addTestCase({ name: 'different items with same length', first: [1, 2, 3], second: [4, 5, 6], expected: expectedResult, }, true); } public addDifferentItemsWithDifferentLength(expectedResult: boolean) { return this.addTestCase({ name: 'different items with different length', first: [1, 2], second: [3, 4, 5], expected: expectedResult, }, true); } public forEachCase(handler: (testCase: IComparerTestCase) => void) { for (const testCase of this.testCases) { handler(testCase); } } private addTestCase(testCase: IComparerTestCase, addReversed: boolean) { this.testCases.push(testCase); if (addReversed) { this.testCases.push({ name: `${testCase.name} (reversed)`, first: testCase.second, second: testCase.first, expected: testCase.expected, }); } return this; } }