|
| 1 | +import { readdirSync, readFileSync } from 'node:fs'; |
| 2 | +import { dirname, join } from 'node:path'; |
| 3 | +import { fileURLToPath } from 'node:url'; |
| 4 | +import { expect, test } from 'vitest'; |
| 5 | +import { INTERACTOR_OPERATIONS } from './interactor-operation-catalog.ts'; |
| 6 | + |
| 7 | +const sourceDir = dirname(fileURLToPath(import.meta.url)); |
| 8 | +const conformanceImport = "from './interactor-operation-conformance.fixtures.ts'"; |
| 9 | +const conformanceRow = /\boperation: '(\w+)'/g; |
| 10 | + |
| 11 | +/** Every `[test file, operation]` pair a module's conformance table names. */ |
| 12 | +const conformed: readonly (readonly [file: string, operation: string])[] = readdirSync(sourceDir) |
| 13 | + .filter((name) => name.endsWith('-runtime.test.ts')) |
| 14 | + .flatMap((file) => { |
| 15 | + const source = readFileSync(join(sourceDir, file), 'utf8'); |
| 16 | + if (!source.includes(conformanceImport)) return []; |
| 17 | + return [...source.matchAll(conformanceRow)].map((match) => [file, match[1] as string] as const); |
| 18 | + }); |
| 19 | +const registered: readonly string[] = INTERACTOR_OPERATIONS.map(({ operation }) => operation); |
| 20 | + |
| 21 | +test('every interactor catalog operation has exactly one conformance table naming it', () => { |
| 22 | + const claimants = (operation: string) => |
| 23 | + conformed.filter(([, claimed]) => claimed === operation).map(([file]) => file); |
| 24 | + |
| 25 | + expect( |
| 26 | + registered.filter((operation) => claimants(operation).length === 0), |
| 27 | + 'catalog operations with no conformance row', |
| 28 | + ).toEqual([]); |
| 29 | + expect( |
| 30 | + registered |
| 31 | + .filter((operation) => claimants(operation).length > 1) |
| 32 | + .map((operation) => `${operation}: ${claimants(operation).join(', ')}`), |
| 33 | + 'catalog operations conformed by more than one module', |
| 34 | + ).toEqual([]); |
| 35 | +}); |
| 36 | + |
| 37 | +test('every operation a conformance table names is registered in the interactor catalog', () => { |
| 38 | + expect( |
| 39 | + conformed |
| 40 | + .filter(([, operation]) => !registered.includes(operation)) |
| 41 | + .map(([file, operation]) => `${file}: ${operation}`), |
| 42 | + 'conformance rows the catalog does not register', |
| 43 | + ).toEqual([]); |
| 44 | +}); |
0 commit comments