blob: 0580b4cbc391062cdeb27341e3a3fbcb21999a86 [file] [log] [blame]
/* 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();