Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ namespace ts {
return optionNameMapCache;
}

export function parseCommandLine(commandLine: string[]): ParsedCommandLine {
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
let options: CompilerOptions = {};
let fileNames: string[] = [];
let errors: Diagnostic[] = [];
Expand Down Expand Up @@ -343,7 +343,7 @@ namespace ts {
}

function parseResponseFile(fileName: string) {
let text = sys.readFile(fileName);
let text = readFile ? readFile(fileName) : sys.readFile(fileName);

if (!text) {
errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, fileName));
Expand Down Expand Up @@ -496,4 +496,4 @@ namespace ts {
return fileNames;
}
}
}
}
40 changes: 31 additions & 9 deletions src/harness/harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ module Harness {
listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[];
log(text: string): void;
getMemoryUsage?(): number;
args(): string[];
getExecutingFilePath(): string;
exit(exitCode?: number): void;
}
export var IO: IO;

Expand All @@ -446,7 +449,10 @@ module Harness {
} else {
fso = {};
}


export const args = () => ts.sys.args;
export const getExecutingFilePath = () => ts.sys.getExecutingFilePath();
export const exit = (exitCode: number) => ts.sys.exit(exitCode);
export const resolvePath = (path: string) => ts.sys.resolvePath(path);
export const getCurrentDirectory = () => ts.sys.getCurrentDirectory();
export const newLine = () => harnessNewLine;
Expand Down Expand Up @@ -517,6 +523,9 @@ module Harness {
export const getCurrentDirectory = () => ts.sys.getCurrentDirectory();
export const newLine = () => harnessNewLine;
export const useCaseSensitiveFileNames = () => ts.sys.useCaseSensitiveFileNames;
export const args = () => ts.sys.args;
export const getExecutingFilePath = () => ts.sys.getExecutingFilePath();
export const exit = (exitCode: number) => ts.sys.exit(exitCode);

export const readFile: typeof IO.readFile = path => ts.sys.readFile(path);
export const writeFile: typeof IO.writeFile = (path, content) => ts.sys.writeFile(path, content);
Expand Down Expand Up @@ -589,6 +598,10 @@ module Harness {
export const newLine = () => harnessNewLine;
export const useCaseSensitiveFileNames = () => false;
export const getCurrentDirectory = () => "";
export const args = () => <string[]>[];
export const getExecutingFilePath = () => "";
export const exit = (exitCode: number) => {};

let supportsCodePage = () => false;

module Http {
Expand Down Expand Up @@ -1331,8 +1344,8 @@ module Harness {
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
diagnostics.sort(ts.compareDiagnostics);
let outputLines: string[] = [];
// Count up all the errors we find so we don't miss any
let totalErrorsReported = 0;
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
let totalErrorsReportedInNonLibraryFiles = 0;

function outputErrorText(error: ts.Diagnostic) {
let message = ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine());
Expand All @@ -1343,8 +1356,15 @@ module Harness {
.filter(s => s.length > 0)
.map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
errLines.forEach(e => outputLines.push(e));

totalErrorsReported++;

// do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
// then they will be added twice thus triggering 'total errors' assertion with condition
// 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length

if (!error.file || !isLibraryFile(error.file.fileName)) {
totalErrorsReportedInNonLibraryFiles++;
}
}

// Report global errors
Expand Down Expand Up @@ -1428,7 +1448,9 @@ module Harness {
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
});

assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
// Verify we didn't miss any errors in total
assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");

return minimalDiagnosticsToString(diagnostics) +
Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n");
}
Expand Down Expand Up @@ -1805,11 +1827,11 @@ module Harness {
return filePath.indexOf(Harness.libFolder) === 0;
}

export function getDefaultLibraryFile(): { unitName: string, content: string } {
let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts";
export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } {
let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts";
return {
unitName: libFile,
content: IO.readFile(libFile)
content: io.readFile(libFile)
};
}

Expand Down
34 changes: 20 additions & 14 deletions src/harness/loggedIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ module Playback {
return run;
}

export interface PlaybackSystem extends ts.System, PlaybackControl { }
export interface PlaybackIO extends Harness.IO, PlaybackControl { }

function createEmptyLog(): IOLog {
return {
Expand Down Expand Up @@ -223,8 +223,8 @@ module Playback {
// console.log("Swallowed write operation during replay: " + name);
}

export function wrapSystem(underlying: ts.System): PlaybackSystem {
let wrapper: PlaybackSystem = <any>{};
export function wrapIO(underlying: Harness.IO): PlaybackIO {
let wrapper: PlaybackIO = <any>{};
initWrapper(wrapper, underlying);

wrapper.startReplayFromFile = logFn => {
Expand All @@ -239,18 +239,24 @@ module Playback {
recordLog = undefined;
}
};

Object.defineProperty(wrapper, "args", {
get() {
if (replayLog !== undefined) {
return replayLog.arguments;
} else if (recordLog !== undefined) {
recordLog.arguments = underlying.args;
}
return underlying.args;

wrapper.args = () => {
if (replayLog !== undefined) {
return replayLog.arguments;
} else if (recordLog !== undefined) {
recordLog.arguments = underlying.args();
}
});

return underlying.args();
}

wrapper.newLine = () => underlying.newLine();
wrapper.useCaseSensitiveFileNames = () => underlying.useCaseSensitiveFileNames();
wrapper.directoryName = (path): string => { throw new Error("NotSupported"); };
wrapper.createDirectory = path => { throw new Error("NotSupported"); };
wrapper.directoryExists = (path): boolean => { throw new Error("NotSupported"); };
wrapper.deleteFile = path => { throw new Error("NotSupported"); };
wrapper.listFiles = (path, filter, options): string[] => { throw new Error("NotSupported"); };
wrapper.log = text => underlying.log(text);

wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
(path) => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path: path }),
Expand Down
45 changes: 19 additions & 26 deletions src/harness/rwcRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,21 @@
/// <reference path="..\compiler\commandLineParser.ts"/>

module RWC {
function runWithIOLog(ioLog: IOLog, fn: () => void) {
let oldSys = ts.sys;
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
let oldIO = Harness.IO;

let wrappedSys = Playback.wrapSystem(ts.sys);
wrappedSys.startReplayFromData(ioLog);
ts.sys = wrappedSys;
let wrappedIO = Playback.wrapIO(oldIO);
wrappedIO.startReplayFromData(ioLog);
Harness.IO = wrappedIO;

try {
fn();
fn(oldIO);
} finally {
wrappedSys.endReplay();
ts.sys = oldSys;
wrappedIO.endReplay();
Harness.IO = oldIO;
}
}

let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts");
let defaultLib = {
unitName: ts.normalizePath(defaultLibPath),
content: Harness.IO.readFile(defaultLibPath)
};

export function runRWCTest(jsonPath: string) {
describe("Testing a RWC project: " + jsonPath, () => {
let inputFiles: { unitName: string; content: string; }[] = [];
Expand All @@ -38,7 +32,6 @@ module RWC {
let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
let currentDirectory: string;
let useCustomLibraryFile: boolean;

after(() => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Therefore we have to clean out large objects after the test is done.
Expand All @@ -63,19 +56,15 @@ module RWC {
currentDirectory = ioLog.currentDirectory;
useCustomLibraryFile = ioLog.useCustomLibraryFile;
runWithIOLog(ioLog, () => {
opts = ts.parseCommandLine(ioLog.arguments);
opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName));
assert.equal(opts.errors.length, 0);

// To provide test coverage of output javascript file,
// we will set noEmitOnError flag to be false.
opts.options.noEmitOnError = false;
});

if (!useCustomLibraryFile) {
inputFiles.push(defaultLib);
}

runWithIOLog(ioLog, () => {
runWithIOLog(ioLog, oldIO => {
harnessCompiler.reset();

// Load the files
Expand All @@ -87,7 +76,7 @@ module RWC {
let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
for (let fileRead of ioLog.filesRead) {
// Check if the file is already added into the set of input files.
const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path));
let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));

if (!Harness.isLibraryFile(fileRead.path)) {
Expand All @@ -106,6 +95,10 @@ module RWC {
if (useCustomLibraryFile) {
inputFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
else {
// set the flag to put default library to the beginning of the list
inputFiles.unshift(Harness.getDefaultLibraryFile(oldIO));
}
}
}
}
Expand All @@ -125,13 +118,13 @@ module RWC {
});

function getHarnessCompilerInputUnit(fileName: string) {
let unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName));
let unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
let content: string = null;
try {
content = ts.sys.readFile(unitName);
content = Harness.IO.readFile(unitName);
}
catch (e) {
content = ts.sys.readFile(fileName);
content = Harness.IO.readFile(fileName);
}
return { unitName, content };
}
Expand Down Expand Up @@ -194,7 +187,7 @@ module RWC {
}

return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
ts.sys.newLine + ts.sys.newLine +
Harness.IO.newLine() + Harness.IO.newLine() +
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
}, false, baselineOpts);
}
Expand Down