Project testcase to run tsconfig file

This commit is contained in:
Sheetal Nandi 2015-09-15 15:53:44 -07:00
parent 60f295f27a
commit 8da3bd2ffd
21 changed files with 189 additions and 50 deletions

View file

@ -14,10 +14,10 @@ namespace ts {
export const version = "1.6.0";
export function findConfigFile(searchPath: string): string {
export function findConfigFile(searchPath: string, moduleResolutionHost: ModuleResolutionHost): string {
let fileName = "tsconfig.json";
while (true) {
if (sys.fileExists(fileName)) {
if (moduleResolutionHost.fileExists(fileName)) {
return fileName;
}
let parentPath = getDirectoryPath(searchPath);

View file

@ -188,7 +188,7 @@ namespace ts {
}
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
let searchPath = normalizePath(sys.getCurrentDirectory());
configFileName = findConfigFile(searchPath);
configFileName = findConfigFile(searchPath, sys);
}
if (commandLine.fileNames.length === 0 && !configFileName) {

View file

@ -430,6 +430,7 @@ module Harness {
args(): string[];
getExecutingFilePath(): string;
exit(exitCode?: number): void;
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
}
export var IO: IO;
@ -466,7 +467,8 @@ module Harness {
export const directoryExists: typeof IO.directoryExists = fso.FolderExists;
export const fileExists: typeof IO.fileExists = fso.FileExists;
export const log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine;
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude) => ts.sys.readDirectory(path, extension, exclude);
export function createDirectory(path: string) {
if (directoryExists(path)) {
fso.CreateFolder(path);
@ -534,6 +536,8 @@ module Harness {
export const fileExists: typeof IO.fileExists = fs.existsSync;
export const log: typeof IO.log = s => console.log(s);
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude) => ts.sys.readDirectory(path, extension, exclude);
export function createDirectory(path: string) {
if (!directoryExists(path)) {
fs.mkdirSync(path);
@ -732,6 +736,10 @@ module Harness {
export function writeFile(path: string, contents: string) {
Http.writeToServerSync(serverRoot + path, "WRITE", contents);
}
export function readDirectory(path: string, extension?: string, exclude?: string[]) {
return listFiles(path).filter(f => !extension || ts.fileExtensionIs(f, extension));
}
}
}

View file

@ -25,14 +25,14 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
interface CompileProjectFilesResult {
moduleKind: ts.ModuleKind;
program: ts.Program;
program?: ts.Program;
compilerOptions?: ts.CompilerOptions,
errors: ts.Diagnostic[];
sourceMapData: ts.SourceMapData[];
sourceMapData?: ts.SourceMapData[];
}
interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
outputFiles: BatchCompileProjectTestCaseEmittedFile[];
nonSubfolderDiskFiles: number;
outputFiles?: BatchCompileProjectTestCaseEmittedFile[];
}
class ProjectRunner extends RunnerBase {
@ -119,9 +119,10 @@ class ProjectRunner extends RunnerBase {
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
getSourceFileText: (fileName: string) => string,
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
let program = ts.createProgram(getInputFiles(), compilerOptions, createCompilerHost());
let errors = ts.getPreEmitDiagnostics(program);
let emitResult = program.emit();
@ -146,38 +147,6 @@ class ProjectRunner extends RunnerBase {
sourceMapData
};
function createCompilerOptions(): ts.CompilerOptions {
// Set the special options that depend on other testcase options
let compilerOptions: ts.CompilerOptions = {
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind,
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
};
// Set the values specified using json
let optionNameMap: ts.Map<ts.CommandLineOption> = {};
ts.forEach(ts.optionDeclarations, option => {
optionNameMap[option.name] = option;
});
for (let name in testCase) {
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
let option = optionNameMap[name];
let optType = option.type;
let value = <any>testCase[name];
if (typeof optType !== "string") {
let key = value.toLowerCase();
if (ts.hasProperty(optType, key)) {
value = optType[key];
}
}
compilerOptions[option.name] = value;
}
}
return compilerOptions;
}
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile {
let sourceFile: ts.SourceFile = undefined;
if (fileName === Harness.Compiler.defaultLibFileName) {
@ -212,23 +181,99 @@ class ProjectRunner extends RunnerBase {
let nonSubfolderDiskFiles = 0;
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
let compilerOptions = createCompilerOptions();
let inputFiles = testCase.inputFiles;
let configFileName: string;
if (compilerOptions.project) {
// Parse project
configFileName = ts.normalizePath(ts.combinePaths(compilerOptions.project, "tsconfig.json"));
assert(!inputFiles || inputFiles.length === 0, "cannot specify input files and project option together");
}
else if (!inputFiles || inputFiles.length === 0) {
configFileName = ts.findConfigFile("", { fileExists, readFile: getSourceFileText });
}
let projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
if (configFileName) {
let result = ts.readConfigFile(configFileName, getSourceFileText);
if (result.error) {
return {
moduleKind,
errors: [result.error]
};
}
let configObject = result.config;
let configParseResult = ts.parseConfigFile(configObject, { fileExists, readFile: getSourceFileText, readDirectory }, ts.getDirectoryPath(configFileName));
if (configParseResult.errors.length > 0) {
return {
moduleKind,
errors: configParseResult.errors
};
}
inputFiles = configParseResult.fileNames;
compilerOptions = ts.extend(compilerOptions, configParseResult.options);
}
let projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
return {
moduleKind,
program: projectCompilerResult.program,
compilerOptions,
sourceMapData: projectCompilerResult.sourceMapData,
outputFiles,
errors: projectCompilerResult.errors,
nonSubfolderDiskFiles,
};
function createCompilerOptions(): ts.CompilerOptions {
// Set the special options that depend on other testcase options
let compilerOptions: ts.CompilerOptions = {
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind,
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
};
// Set the values specified using json
let optionNameMap: ts.Map<ts.CommandLineOption> = {};
ts.forEach(ts.optionDeclarations, option => {
optionNameMap[option.name] = option;
});
for (let name in testCase) {
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
let option = optionNameMap[name];
let optType = option.type;
let value = <any>testCase[name];
if (typeof optType !== "string") {
let key = value.toLowerCase();
if (ts.hasProperty(optType, key)) {
value = optType[key];
}
}
compilerOptions[option.name] = value;
}
}
return compilerOptions;
}
function getFileNameInTheProjectTest(fileName: string): string {
return ts.isRootedDiskPath(fileName)
? fileName
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName);
}
function readDirectory(rootDir: string, extension: string, exclude: string[]): string[] {
return Harness.IO.readDirectory(getFileNameInTheProjectTest(rootDir), extension, exclude);
}
function fileExists(fileName: string): boolean {
return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName));
}
function getSourceFileText(fileName: string): string {
let text: string = undefined;
try {
text = Harness.IO.readFile(ts.isRootedDiskPath(fileName)
? fileName
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
text = Harness.IO.readFile(getFileNameInTheProjectTest(fileName));
}
catch (e) {
// text doesn't get defined.
@ -288,6 +333,9 @@ class ProjectRunner extends RunnerBase {
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
let allInputFiles: { emittedFileName: string; code: string; }[] = [];
if (!compilerResult.program) {
return;
}
let compilerOptions = compilerResult.program.getCompilerOptions();
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
@ -317,7 +365,8 @@ class ProjectRunner extends RunnerBase {
}
});
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile);
// Dont allow config files since we are compiling existing source options
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
function findOutpuDtsFile(fileName: string) {
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
@ -352,7 +401,7 @@ class ProjectRunner extends RunnerBase {
function getCompilerResolutionInfo() {
let resolutionInfo: ProjectRunnerTestCaseResolutionInfo & ts.CompilerOptions = JSON.parse(JSON.stringify(testCase));
resolutionInfo.resolvedInputFiles = ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName);
resolutionInfo.resolvedInputFiles = ts.map(compilerResult.program ? compilerResult.program.getSourceFiles() : undefined, inputFile => inputFile.fileName);
resolutionInfo.emittedFiles = ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName);
return resolutionInfo;
}
@ -409,7 +458,7 @@ class ProjectRunner extends RunnerBase {
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
if (!compilerResult.errors.length && testCase.declaration) {
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
if (dTsCompileResult.errors.length) {
if (dTsCompileResult && dTsCompileResult.errors.length) {
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
return getErrorsBaseline(dTsCompileResult);
});

View file

@ -0,0 +1 @@
declare var test: number;

View file

@ -0,0 +1 @@
var test = 10;

View file

@ -0,0 +1,14 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption/Test",
"baselineCheck": true,
"declaration": true,
"resolvedInputFiles": [
"lib.d.ts",
"a.ts"
],
"emittedFiles": [
"a.js",
"a.d.ts"
]
}

View file

@ -0,0 +1 @@
declare var test: number;

View file

@ -0,0 +1 @@
var test = 10;

View file

@ -0,0 +1,14 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption/Test",
"baselineCheck": true,
"declaration": true,
"resolvedInputFiles": [
"lib.d.ts",
"a.ts"
],
"emittedFiles": [
"a.js",
"a.d.ts"
]
}

View file

@ -0,0 +1 @@
declare var test: number;

View file

@ -0,0 +1 @@
var test = 10;

View file

@ -0,0 +1,15 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption",
"baselineCheck": true,
"declaration": true,
"project": "Test",
"resolvedInputFiles": [
"lib.d.ts",
"Test/a.ts"
],
"emittedFiles": [
"Test/a.js",
"Test/a.d.ts"
]
}

View file

@ -0,0 +1 @@
declare var test: number;

View file

@ -0,0 +1 @@
var test = 10;

View file

@ -0,0 +1,15 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption",
"baselineCheck": true,
"declaration": true,
"project": "Test",
"resolvedInputFiles": [
"lib.d.ts",
"Test/a.ts"
],
"emittedFiles": [
"Test/a.js",
"Test/a.d.ts"
]
}

View file

@ -0,0 +1,6 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption/Test",
"baselineCheck": true,
"declaration": true
}

View file

@ -0,0 +1,7 @@
{
"scenario": "Verify project option",
"projectRoot": "tests/cases/projects/projectOption",
"baselineCheck": true,
"declaration": true,
"project": "Test"
}

View file

@ -0,0 +1 @@
var test = 10;

View file

@ -0,0 +1 @@
var test = 10; // Shouldnt get compiled so shouldnt error

View file

@ -0,0 +1 @@
{ "files": [ "a.ts" ] }