UNPKG

@typed/test

Version:
99 lines (83 loc) 3.01 kB
import { join, relative } from 'path' import { collectByKey } from '../common/collectByKey' import { chain } from '../common/flatten' import { TestMetadata } from '../types' export function generateTestBundle( cwd: string, fileDirectory: string, port: number, timeout: number, metadata: TestMetadata[], ): string { const stats: Stats = { numberOfTests: 0, testToTestNumber: {} } const metadataByFilePath = collectByKey(x => x.filePath, metadata) const filePaths = Object.keys(metadataByFilePath) const relativePath = relative(fileDirectory, __dirname) const importStatements = filePaths.map(filePath => buildImportStatement(fileDirectory, stats, filePath, metadataByFilePath[filePath]), ) return [ importStatements.join(`\n`), createTestsWithMetadata(stats.testToTestNumber, metadata), createApi(cwd, relativePath, port, timeout), createTestRun(relativePath), `\n`, ].join(`\n`) } function createTestRun(relativePath: string): string { return [ `import { run } from '${join(relativePath, 'runTestsAndReport')}'`, `\n`, `run(TypedTest)`, ].join(`\n`) } function createApi(cwd: string, relativePath: string, port: number, timeout: number): string { return [ `const retrieveMetadata = () => Promise.resolve(TYPED_TEST_METADATA)`, `import { reportResults, logger } from '${join(relativePath, 'api')}'`, `import { runTests } from '${join(relativePath, '../common/runTests')}'`, `const TypedTest = Object.freeze({ cwd: '${cwd}', retrieveMetadata, reportResults, runTests, logger, TIMEOUT: ${timeout}, PORT: ${port} })`, `export = TypedTest`, ].join(`\n`) } function createTestsWithMetadata( testToTestNumber: Record<string, number>, metadata: TestMetadata[], ): string { const tests = metadata.map(m => { const testNames = findTestNames(m).map(x => `test${testToTestNumber[x]}`) return `\n Object.assign({}, ${JSON.stringify(m)}, { tests: [${testNames.join(', ')}] })` }) return `const TYPED_TEST_METADATA = [` + tests.join(',') + `\n]\n\n` } function findTestNames({ exportNames, filePath }: TestMetadata): string[] { return exportNames.map(x => `${filePath}/${x}`) } type Stats = { numberOfTests: number; testToTestNumber: Record<string, number> } function buildImportStatement( fileDirectory: string, stats: Stats, filePath: string, metadata: TestMetadata[], ): string { const exportNames = chain(x => x.exportNames, metadata) const importSpecifiers: string[] = [] for (const exportName of exportNames) { const testName = `${filePath}/${exportName}` const testNum = stats.numberOfTests const specifier = ` ${exportName} as test${testNum}` stats.testToTestNumber[testName] = testNum stats.numberOfTests++ importSpecifiers.push(specifier) } const moduleSpecificer = relative(fileDirectory, filePath.replace(/\.ts(x)?$/, '')) return `import {${importSpecifiers.join(',')} } from '${moduleSpecificer}'` }