| /* Copyright 2018 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| import * as program from 'commander'; |
| import * as path from 'path'; |
| import Project from 'ts-simple-ast'; |
| import { |
| ObjectLiteralExpression, |
| QuoteKind, |
| VariableDeclarationKind, |
| } from 'ts-simple-ast'; |
| |
| program |
| .option( |
| '--app_dir <app directory>', 'The place of app directory', |
| '../src/app/') |
| .option( |
| '--output <output filename>', 'The file will be placed under <app_dir>', |
| 'test-list.resource.ts') |
| .parse(process.argv); |
| |
| function main() { |
| const appDir = program.app_dir; |
| const outputPath = path.join(appDir, program.output); |
| |
| const testsDir = path.join(appDir, 'tests'); |
| |
| const project = new Project(); |
| |
| project.manipulationSettings.set({ |
| quoteKind: QuoteKind.Single, |
| }); |
| |
| project.addExistingSourceFiles(path.join(testsDir, '**', '*.ts')); |
| |
| const testFiles = project.getSourceFiles(); |
| |
| let outputFile = project.addExistingSourceFileIfExists(outputPath); |
| if (outputFile === undefined) { |
| outputFile = project.createSourceFile(outputPath); |
| } |
| |
| // remove everything first. |
| outputFile.removeText(); |
| outputFile.addImportDeclaration({ |
| defaultImport: '{TestResource}', |
| moduleSpecifier: './interfaces/test-resource' |
| }); |
| |
| const variable = outputFile.addVariableStatement({ |
| declarationKind: VariableDeclarationKind.Const, |
| declarations: [{ |
| name: 'TEST_COMPONENTS: {[testName: string]: TestResource}', |
| initializer: '{}', |
| }] |
| }); |
| const expression = |
| variable.getDeclarations()[0].getInitializer() as ObjectLiteralExpression; |
| |
| function exportsToTestResource(exports: any[]): {[key: string]: any} { |
| const result: {[key: string]: any} = {}; |
| for (let exp of exports) { |
| if (exp.getName().endsWith('Component')) { |
| result.className = exp.getName(); |
| } else if (exp.getName().endsWith('_ARGS_SPEC')) { |
| result.argsSpec = exp.getName(); |
| } |
| } |
| return result; |
| } |
| |
| for (const testFile of testFiles) { |
| let testPath = testFile.getFilePath(); |
| |
| const exports = testFile.getExportSymbols(); |
| const testResource = exportsToTestResource(exports); |
| |
| console.assert( |
| testResource.className, `${testPath} doesn't export any test case.`); |
| |
| const className = testResource.className; |
| const argsSpecName = testResource.argsSpec; |
| |
| console.log(`Adding ${className}...`); |
| |
| /* remove extension from testPath */ |
| const parsedTestPath = path.parse(testPath); |
| parsedTestPath.ext = 'ignored'; |
| parsedTestPath.base = parsedTestPath.name; |
| |
| testPath = path.format(parsedTestPath); |
| |
| let importArgsSpec = argsSpecName ? `, ${argsSpecName}` : ''; |
| outputFile.addImportDeclaration({ |
| defaultImport: `{${className}${importArgsSpec}}`, |
| moduleSpecifier: './' + path.relative(appDir, testPath), |
| }); |
| |
| const testName = className.substring(0, className.indexOf('Component')); |
| const property = expression.addPropertyAssignment({ |
| name: testName, |
| initializer: '{}', |
| }); |
| const init = property.getInitializerOrThrow() as ObjectLiteralExpression; |
| init.addPropertyAssignment({ |
| name: 'component', |
| initializer: className, |
| }); |
| init.addPropertyAssignment({ |
| name: 'argsSpec', |
| initializer: argsSpecName ? argsSpecName : '[]' |
| }); |
| } |
| |
| outputFile.addExportDeclaration({namedExports: ['TEST_COMPONENTS']}); |
| |
| /* Add header, this must be done after all previous code are generated. */ |
| const header = `\ |
| /* Copyright 2018 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| // This file is generated by generate-test-list.ts\n`; |
| outputFile.insertText(0, header); |
| |
| outputFile.formatText({ |
| insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: false, |
| indentSize: 2, |
| }); |
| |
| project.saveSync(); |
| } |
| |
| main(); |