Skip to content

Commit 8da3bd2

Browse files
committed
Project testcase to run tsconfig file
1 parent 60f295f commit 8da3bd2

21 files changed

Lines changed: 189 additions & 50 deletions

File tree

src/compiler/program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ namespace ts {
1414

1515
export const version = "1.6.0";
1616

17-
export function findConfigFile(searchPath: string): string {
17+
export function findConfigFile(searchPath: string, moduleResolutionHost: ModuleResolutionHost): string {
1818
let fileName = "tsconfig.json";
1919
while (true) {
20-
if (sys.fileExists(fileName)) {
20+
if (moduleResolutionHost.fileExists(fileName)) {
2121
return fileName;
2222
}
2323
let parentPath = getDirectoryPath(searchPath);

src/compiler/tsc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ namespace ts {
188188
}
189189
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
190190
let searchPath = normalizePath(sys.getCurrentDirectory());
191-
configFileName = findConfigFile(searchPath);
191+
configFileName = findConfigFile(searchPath, sys);
192192
}
193193

194194
if (commandLine.fileNames.length === 0 && !configFileName) {

src/harness/harness.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ module Harness {
430430
args(): string[];
431431
getExecutingFilePath(): string;
432432
exit(exitCode?: number): void;
433+
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
433434
}
434435
export var IO: IO;
435436

@@ -466,7 +467,8 @@ module Harness {
466467
export const directoryExists: typeof IO.directoryExists = fso.FolderExists;
467468
export const fileExists: typeof IO.fileExists = fso.FileExists;
468469
export const log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine;
469-
470+
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude) => ts.sys.readDirectory(path, extension, exclude);
471+
470472
export function createDirectory(path: string) {
471473
if (directoryExists(path)) {
472474
fso.CreateFolder(path);
@@ -534,6 +536,8 @@ module Harness {
534536
export const fileExists: typeof IO.fileExists = fs.existsSync;
535537
export const log: typeof IO.log = s => console.log(s);
536538

539+
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude) => ts.sys.readDirectory(path, extension, exclude);
540+
537541
export function createDirectory(path: string) {
538542
if (!directoryExists(path)) {
539543
fs.mkdirSync(path);
@@ -732,6 +736,10 @@ module Harness {
732736
export function writeFile(path: string, contents: string) {
733737
Http.writeToServerSync(serverRoot + path, "WRITE", contents);
734738
}
739+
740+
export function readDirectory(path: string, extension?: string, exclude?: string[]) {
741+
return listFiles(path).filter(f => !extension || ts.fileExtensionIs(f, extension));
742+
}
735743
}
736744
}
737745

src/harness/projectsRunner.ts

Lines changed: 95 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
2525

2626
interface CompileProjectFilesResult {
2727
moduleKind: ts.ModuleKind;
28-
program: ts.Program;
28+
program?: ts.Program;
29+
compilerOptions?: ts.CompilerOptions,
2930
errors: ts.Diagnostic[];
30-
sourceMapData: ts.SourceMapData[];
31+
sourceMapData?: ts.SourceMapData[];
3132
}
3233

3334
interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
34-
outputFiles: BatchCompileProjectTestCaseEmittedFile[];
35-
nonSubfolderDiskFiles: number;
35+
outputFiles?: BatchCompileProjectTestCaseEmittedFile[];
3636
}
3737

3838
class ProjectRunner extends RunnerBase {
@@ -119,9 +119,10 @@ class ProjectRunner extends RunnerBase {
119119

120120
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
121121
getSourceFileText: (fileName: string) => string,
122-
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
122+
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
123+
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
123124

124-
let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
125+
let program = ts.createProgram(getInputFiles(), compilerOptions, createCompilerHost());
125126
let errors = ts.getPreEmitDiagnostics(program);
126127

127128
let emitResult = program.emit();
@@ -146,38 +147,6 @@ class ProjectRunner extends RunnerBase {
146147
sourceMapData
147148
};
148149

149-
function createCompilerOptions(): ts.CompilerOptions {
150-
// Set the special options that depend on other testcase options
151-
let compilerOptions: ts.CompilerOptions = {
152-
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
153-
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
154-
module: moduleKind,
155-
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
156-
};
157-
158-
// Set the values specified using json
159-
let optionNameMap: ts.Map<ts.CommandLineOption> = {};
160-
ts.forEach(ts.optionDeclarations, option => {
161-
optionNameMap[option.name] = option;
162-
});
163-
for (let name in testCase) {
164-
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
165-
let option = optionNameMap[name];
166-
let optType = option.type;
167-
let value = <any>testCase[name];
168-
if (typeof optType !== "string") {
169-
let key = value.toLowerCase();
170-
if (ts.hasProperty(optType, key)) {
171-
value = optType[key];
172-
}
173-
}
174-
compilerOptions[option.name] = value;
175-
}
176-
}
177-
178-
return compilerOptions;
179-
}
180-
181150
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile {
182151
let sourceFile: ts.SourceFile = undefined;
183152
if (fileName === Harness.Compiler.defaultLibFileName) {
@@ -212,23 +181,99 @@ class ProjectRunner extends RunnerBase {
212181
let nonSubfolderDiskFiles = 0;
213182

214183
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
184+
let compilerOptions = createCompilerOptions();
185+
let inputFiles = testCase.inputFiles;
186+
let configFileName: string;
187+
if (compilerOptions.project) {
188+
// Parse project
189+
configFileName = ts.normalizePath(ts.combinePaths(compilerOptions.project, "tsconfig.json"));
190+
assert(!inputFiles || inputFiles.length === 0, "cannot specify input files and project option together");
191+
}
192+
else if (!inputFiles || inputFiles.length === 0) {
193+
configFileName = ts.findConfigFile("", { fileExists, readFile: getSourceFileText });
194+
}
195+
196+
if (configFileName) {
197+
let result = ts.readConfigFile(configFileName, getSourceFileText);
198+
if (result.error) {
199+
return {
200+
moduleKind,
201+
errors: [result.error]
202+
};
203+
}
215204

216-
let projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
205+
let configObject = result.config;
206+
let configParseResult = ts.parseConfigFile(configObject, { fileExists, readFile: getSourceFileText, readDirectory }, ts.getDirectoryPath(configFileName));
207+
if (configParseResult.errors.length > 0) {
208+
return {
209+
moduleKind,
210+
errors: configParseResult.errors
211+
};
212+
}
213+
inputFiles = configParseResult.fileNames;
214+
compilerOptions = ts.extend(compilerOptions, configParseResult.options);
215+
}
216+
217+
let projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
217218
return {
218219
moduleKind,
219220
program: projectCompilerResult.program,
221+
compilerOptions,
220222
sourceMapData: projectCompilerResult.sourceMapData,
221223
outputFiles,
222224
errors: projectCompilerResult.errors,
223-
nonSubfolderDiskFiles,
224225
};
225226

227+
function createCompilerOptions(): ts.CompilerOptions {
228+
// Set the special options that depend on other testcase options
229+
let compilerOptions: ts.CompilerOptions = {
230+
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
231+
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
232+
module: moduleKind,
233+
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
234+
};
235+
236+
// Set the values specified using json
237+
let optionNameMap: ts.Map<ts.CommandLineOption> = {};
238+
ts.forEach(ts.optionDeclarations, option => {
239+
optionNameMap[option.name] = option;
240+
});
241+
for (let name in testCase) {
242+
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
243+
let option = optionNameMap[name];
244+
let optType = option.type;
245+
let value = <any>testCase[name];
246+
if (typeof optType !== "string") {
247+
let key = value.toLowerCase();
248+
if (ts.hasProperty(optType, key)) {
249+
value = optType[key];
250+
}
251+
}
252+
compilerOptions[option.name] = value;
253+
}
254+
}
255+
256+
return compilerOptions;
257+
}
258+
259+
function getFileNameInTheProjectTest(fileName: string): string {
260+
return ts.isRootedDiskPath(fileName)
261+
? fileName
262+
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName);
263+
}
264+
265+
function readDirectory(rootDir: string, extension: string, exclude: string[]): string[] {
266+
return Harness.IO.readDirectory(getFileNameInTheProjectTest(rootDir), extension, exclude);
267+
}
268+
269+
function fileExists(fileName: string): boolean {
270+
return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName));
271+
}
272+
226273
function getSourceFileText(fileName: string): string {
227274
let text: string = undefined;
228275
try {
229-
text = Harness.IO.readFile(ts.isRootedDiskPath(fileName)
230-
? fileName
231-
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
276+
text = Harness.IO.readFile(getFileNameInTheProjectTest(fileName));
232277
}
233278
catch (e) {
234279
// text doesn't get defined.
@@ -288,6 +333,9 @@ class ProjectRunner extends RunnerBase {
288333

289334
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
290335
let allInputFiles: { emittedFileName: string; code: string; }[] = [];
336+
if (!compilerResult.program) {
337+
return;
338+
}
291339
let compilerOptions = compilerResult.program.getCompilerOptions();
292340

293341
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
@@ -317,7 +365,8 @@ class ProjectRunner extends RunnerBase {
317365
}
318366
});
319367

320-
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile);
368+
// Dont allow config files since we are compiling existing source options
369+
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
321370

322371
function findOutpuDtsFile(fileName: string) {
323372
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
@@ -352,7 +401,7 @@ class ProjectRunner extends RunnerBase {
352401

353402
function getCompilerResolutionInfo() {
354403
let resolutionInfo: ProjectRunnerTestCaseResolutionInfo & ts.CompilerOptions = JSON.parse(JSON.stringify(testCase));
355-
resolutionInfo.resolvedInputFiles = ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName);
404+
resolutionInfo.resolvedInputFiles = ts.map(compilerResult.program ? compilerResult.program.getSourceFiles() : undefined, inputFile => inputFile.fileName);
356405
resolutionInfo.emittedFiles = ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName);
357406
return resolutionInfo;
358407
}
@@ -409,7 +458,7 @@ class ProjectRunner extends RunnerBase {
409458
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
410459
if (!compilerResult.errors.length && testCase.declaration) {
411460
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
412-
if (dTsCompileResult.errors.length) {
461+
if (dTsCompileResult && dTsCompileResult.errors.length) {
413462
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
414463
return getErrorsBaseline(dTsCompileResult);
415464
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare var test: number;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
var test = 10;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"scenario": "Verify project option",
3+
"projectRoot": "tests/cases/projects/projectOption/Test",
4+
"baselineCheck": true,
5+
"declaration": true,
6+
"resolvedInputFiles": [
7+
"lib.d.ts",
8+
"a.ts"
9+
],
10+
"emittedFiles": [
11+
"a.js",
12+
"a.d.ts"
13+
]
14+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare var test: number;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
var test = 10;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"scenario": "Verify project option",
3+
"projectRoot": "tests/cases/projects/projectOption/Test",
4+
"baselineCheck": true,
5+
"declaration": true,
6+
"resolvedInputFiles": [
7+
"lib.d.ts",
8+
"a.ts"
9+
],
10+
"emittedFiles": [
11+
"a.js",
12+
"a.d.ts"
13+
]
14+
}

0 commit comments

Comments
 (0)