mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Merge pull request #4488 from Microsoft/fixRWC
Move RWC runner to use Harness.IO instead of sys
This commit is contained in:
commit
4aec447dba
@ -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[] = [];
|
||||
@ -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));
|
||||
@ -496,4 +496,4 @@ namespace ts {
|
||||
return fileNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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 {
|
||||
@ -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());
|
||||
@ -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
|
||||
@ -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");
|
||||
}
|
||||
@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
@ -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 => {
|
||||
@ -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 }),
|
||||
|
||||
@ -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; }[] = [];
|
||||
@ -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.
|
||||
@ -63,7 +56,7 @@ 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,
|
||||
@ -71,11 +64,7 @@ module RWC {
|
||||
opts.options.noEmitOnError = false;
|
||||
});
|
||||
|
||||
if (!useCustomLibraryFile) {
|
||||
inputFiles.push(defaultLib);
|
||||
}
|
||||
|
||||
runWithIOLog(ioLog, () => {
|
||||
runWithIOLog(ioLog, oldIO => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
// Load the files
|
||||
@ -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)) {
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 };
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user