mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #3863 from Microsoft/tslintHarnessCode
Update harness code for TSLint rules
This commit is contained in:
commit
32a040b487
19
Jakefile.js
19
Jakefile.js
@ -113,7 +113,7 @@ var languageServiceLibrarySources = [
|
||||
return path.join(serverDirectory, f);
|
||||
}).concat(servicesSources);
|
||||
|
||||
var harnessSources = [
|
||||
var harnessCoreSources = [
|
||||
"harness.ts",
|
||||
"sourceMapRecorder.ts",
|
||||
"harnessLanguageService.ts",
|
||||
@ -129,7 +129,9 @@ var harnessSources = [
|
||||
"runner.ts"
|
||||
].map(function (f) {
|
||||
return path.join(harnessDirectory, f);
|
||||
}).concat([
|
||||
});
|
||||
|
||||
var harnessSources = harnessCoreSources.concat([
|
||||
"incrementalParser.ts",
|
||||
"jsDocParsing.ts",
|
||||
"services/colorization.ts",
|
||||
@ -730,12 +732,13 @@ task("update-sublime", ["local", serverFile], function() {
|
||||
// run this task automatically
|
||||
desc("Runs tslint on the compiler sources");
|
||||
task("lint", [], function() {
|
||||
for(var i in compilerSources) {
|
||||
var f = compilerSources[i];
|
||||
function success(f) { return function() { console.log('SUCCESS: No linter errors in ' + f + '\n'); }};
|
||||
function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }};
|
||||
|
||||
var lintTargets = compilerSources.concat(harnessCoreSources);
|
||||
for(var i in lintTargets) {
|
||||
var f = lintTargets[i];
|
||||
var cmd = 'tslint -f ' + f;
|
||||
exec(cmd,
|
||||
function() { console.log('SUCCESS: No linter errors'); },
|
||||
function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n');
|
||||
});
|
||||
exec(cmd, success(f), failure(f));
|
||||
}
|
||||
}, { async: true });
|
||||
|
||||
@ -42,27 +42,26 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
describe('compiler tests for ' + fileName, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
var justName: string;
|
||||
var content: string;
|
||||
var testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; }
|
||||
let justName: string;
|
||||
let content: string;
|
||||
let testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; };
|
||||
|
||||
var units: Harness.TestCaseParser.TestUnitData[];
|
||||
var tcSettings: Harness.TestCaseParser.CompilerSetting[];
|
||||
var createNewInstance: boolean;
|
||||
let units: Harness.TestCaseParser.TestUnitData[];
|
||||
let tcSettings: Harness.TestCaseParser.CompilerSetting[];
|
||||
|
||||
var lastUnit: Harness.TestCaseParser.TestUnitData;
|
||||
var rootDir: string;
|
||||
let lastUnit: Harness.TestCaseParser.TestUnitData;
|
||||
let rootDir: string;
|
||||
|
||||
var result: Harness.Compiler.CompilerResult;
|
||||
var program: ts.Program;
|
||||
var options: ts.CompilerOptions;
|
||||
let result: Harness.Compiler.CompilerResult;
|
||||
let program: ts.Program;
|
||||
let options: ts.CompilerOptions;
|
||||
// equivalent to the files that will be passed on the command line
|
||||
var toBeCompiled: { unitName: string; content: string }[];
|
||||
let toBeCompiled: { unitName: string; content: string }[];
|
||||
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
|
||||
var otherFiles: { unitName: string; content: string }[];
|
||||
var harnessCompiler: Harness.Compiler.HarnessCompiler;
|
||||
let otherFiles: { unitName: string; content: string }[];
|
||||
let harnessCompiler: Harness.Compiler.HarnessCompiler;
|
||||
|
||||
var createNewInstance = false;
|
||||
let createNewInstance = false;
|
||||
|
||||
before(() => {
|
||||
justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path.
|
||||
@ -105,7 +104,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
/* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need
|
||||
a fresh compiler instance for themselves and then create a fresh one for the next test. Would be nice to get dev fixes
|
||||
eventually to remove this limitation. */
|
||||
for (var i = 0; i < tcSettings.length; ++i) {
|
||||
for (let i = 0; i < tcSettings.length; ++i) {
|
||||
// noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings
|
||||
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) {
|
||||
harnessCompiler = Harness.Compiler.getCompiler();
|
||||
@ -162,7 +161,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
it('Correct sourcemap content for ' + fileName, () => {
|
||||
if (options.sourceMap || options.inlineSourceMap) {
|
||||
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => {
|
||||
var record = result.getSourceMapRecord();
|
||||
let record = result.getSourceMapRecord();
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
return null;
|
||||
@ -180,18 +179,18 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
// check js output
|
||||
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => {
|
||||
var tsCode = '';
|
||||
var tsSources = otherFiles.concat(toBeCompiled);
|
||||
let tsCode = '';
|
||||
let tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += '//// [' + fileName + '] ////\r\n\r\n';
|
||||
}
|
||||
for (var i = 0; i < tsSources.length; i++) {
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n';
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : '');
|
||||
}
|
||||
|
||||
var jsCode = '';
|
||||
for (var i = 0; i < result.files.length; i++) {
|
||||
let jsCode = '';
|
||||
for (let i = 0; i < result.files.length; i++) {
|
||||
jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n';
|
||||
jsCode += getByteOrderMarkText(result.files[i]);
|
||||
jsCode += result.files[i].code;
|
||||
@ -199,14 +198,14 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
if (result.declFilesCode.length > 0) {
|
||||
jsCode += '\r\n\r\n';
|
||||
for (var i = 0; i < result.declFilesCode.length; i++) {
|
||||
for (let i = 0; i < result.declFilesCode.length; i++) {
|
||||
jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n';
|
||||
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
|
||||
jsCode += result.declFilesCode[i].code;
|
||||
}
|
||||
}
|
||||
|
||||
var declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
||||
let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
}, options);
|
||||
|
||||
@ -244,8 +243,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
var sourceMapCode = '';
|
||||
for (var i = 0; i < result.sourceMaps.length; i++) {
|
||||
let sourceMapCode = '';
|
||||
for (let i = 0; i < result.sourceMaps.length; i++) {
|
||||
sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n';
|
||||
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
|
||||
sourceMapCode += result.sourceMaps[i].code;
|
||||
@ -293,7 +292,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
var e1: Error, e2: Error;
|
||||
let e1: Error, e2: Error;
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine:*/ false);
|
||||
}
|
||||
@ -335,20 +334,20 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
allFiles.forEach(file => {
|
||||
var codeLines = file.content.split('\n');
|
||||
let codeLines = file.content.split('\n');
|
||||
typeWriterResults[file.unitName].forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
}
|
||||
|
||||
var typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||
var formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||
let typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||
let formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||
if (!typeMap[file.unitName]) {
|
||||
typeMap[file.unitName] = {};
|
||||
}
|
||||
|
||||
var typeInfo = [formattedLine];
|
||||
var existingTypeInfo = typeMap[file.unitName][result.line];
|
||||
let typeInfo = [formattedLine];
|
||||
let existingTypeInfo = typeMap[file.unitName][result.line];
|
||||
if (existingTypeInfo) {
|
||||
typeInfo = existingTypeInfo.concat(typeInfo);
|
||||
}
|
||||
@ -356,11 +355,11 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
typeLines.push('=== ' + file.unitName + ' ===\r\n');
|
||||
for (var i = 0; i < codeLines.length; i++) {
|
||||
var currentCodeLine = codeLines[i];
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
let currentCodeLine = codeLines[i];
|
||||
typeLines.push(currentCodeLine + '\r\n');
|
||||
if (typeMap[file.unitName]) {
|
||||
var typeInfo = typeMap[file.unitName][i];
|
||||
let typeInfo = typeMap[file.unitName][i];
|
||||
if (typeInfo) {
|
||||
typeInfo.forEach(ty => {
|
||||
typeLines.push('>' + ty + '\r\n');
|
||||
@ -388,13 +387,13 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
public initializeTests() {
|
||||
describe(this.testSuiteName + ' tests', () => {
|
||||
describe("Setup compiler for compiler baselines", () => {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler();
|
||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
||||
this.parseOptions();
|
||||
});
|
||||
|
||||
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
||||
if (this.tests.length === 0) {
|
||||
var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
|
||||
let testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
|
||||
testFiles.forEach(fn => {
|
||||
fn = fn.replace(/\\/g, "/");
|
||||
this.checkTestCodeOutput(fn);
|
||||
@ -405,7 +404,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
describe("Cleanup after compiler baselines", () => {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler();
|
||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -417,8 +416,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
this.decl = false;
|
||||
this.output = false;
|
||||
|
||||
var opts = this.options.split(',');
|
||||
for (var i = 0; i < opts.length; i++) {
|
||||
let opts = this.options.split(',');
|
||||
for (let i = 0; i < opts.length; i++) {
|
||||
switch (opts[i]) {
|
||||
case 'error':
|
||||
this.errors = true;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -35,40 +35,40 @@ class FourSlashRunner extends RunnerBase {
|
||||
this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false });
|
||||
}
|
||||
|
||||
describe(this.testSuiteName + ' tests', () => {
|
||||
describe(this.testSuiteName + ' tests', () => {
|
||||
this.tests.forEach((fn: string) => {
|
||||
describe(fn, () => {
|
||||
fn = ts.normalizeSlashes(fn);
|
||||
var justName = fn.replace(/^.*[\\\/]/, '');
|
||||
|
||||
let justName = fn.replace(/^.*[\\\/]/, '');
|
||||
|
||||
// Convert to relative path
|
||||
var testIndex = fn.indexOf('tests/');
|
||||
let testIndex = fn.indexOf('tests/');
|
||||
if (testIndex >= 0) fn = fn.substr(testIndex);
|
||||
|
||||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
|
||||
it(this.testSuiteName + ' test ' + justName + ' runs correctly',() => {
|
||||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
|
||||
it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => {
|
||||
FourSlash.runFourSlashTest(this.basePath, this.testType, fn);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Generate Tao XML', () => {
|
||||
var invalidReasons: any = {};
|
||||
let invalidReasons: any = {};
|
||||
FourSlash.xmlData.forEach(xml => {
|
||||
if (xml.invalidReason !== null) {
|
||||
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
|
||||
}
|
||||
});
|
||||
var invalidReport: { reason: string; count: number }[] = [];
|
||||
for (var reason in invalidReasons) {
|
||||
let invalidReport: { reason: string; count: number }[] = [];
|
||||
for (let reason in invalidReasons) {
|
||||
if (invalidReasons.hasOwnProperty(reason)) {
|
||||
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
|
||||
}
|
||||
}
|
||||
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
|
||||
|
||||
var lines: string[] = [];
|
||||
let lines: string[] = [];
|
||||
lines.push('<!-- Blocked Test Report');
|
||||
invalidReport.forEach((reasonAndCount) => {
|
||||
lines.push(reasonAndCount.count + ' tests blocked by ' + reasonAndCount.reason);
|
||||
|
||||
@ -33,8 +33,6 @@ declare var __dirname: string; // Node-specific
|
||||
var global = <any>Function("return this").call(null);
|
||||
|
||||
module Utils {
|
||||
var global = <any>Function("return this").call(null);
|
||||
|
||||
// Setup some globals based on the current environment
|
||||
export const enum ExecutionEnvironment {
|
||||
Node,
|
||||
@ -54,17 +52,17 @@ module Utils {
|
||||
}
|
||||
}
|
||||
|
||||
export var currentExecutionEnvironment = getExecutionEnvironment();
|
||||
export let currentExecutionEnvironment = getExecutionEnvironment();
|
||||
|
||||
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
|
||||
var environment = getExecutionEnvironment();
|
||||
let environment = getExecutionEnvironment();
|
||||
switch (environment) {
|
||||
case ExecutionEnvironment.CScript:
|
||||
case ExecutionEnvironment.Browser:
|
||||
eval(fileContents);
|
||||
break;
|
||||
case ExecutionEnvironment.Node:
|
||||
var vm = require('vm');
|
||||
let vm = require('vm');
|
||||
if (nodeContext) {
|
||||
vm.runInNewContext(fileContents, nodeContext, fileName);
|
||||
} else {
|
||||
@ -81,7 +79,7 @@ module Utils {
|
||||
// Split up the input file by line
|
||||
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
|
||||
// we have to use string-based splitting instead and try to figure out the delimiting chars
|
||||
var lines = content.split('\r\n');
|
||||
let lines = content.split('\r\n');
|
||||
if (lines.length === 1) {
|
||||
lines = content.split('\n');
|
||||
|
||||
@ -98,8 +96,9 @@ module Utils {
|
||||
path = "tests/" + path;
|
||||
}
|
||||
|
||||
let content: string = undefined;
|
||||
try {
|
||||
var content = ts.sys.readFile(Harness.userSpecifiedRoot + path);
|
||||
content = ts.sys.readFile(Harness.userSpecifiedRoot + path);
|
||||
}
|
||||
catch (err) {
|
||||
return undefined;
|
||||
@ -109,11 +108,11 @@ module Utils {
|
||||
}
|
||||
|
||||
export function memoize<T extends Function>(f: T): T {
|
||||
var cache: { [idx: string]: any } = {};
|
||||
let cache: { [idx: string]: any } = {};
|
||||
|
||||
return <any>(function () {
|
||||
var key = Array.prototype.join.call(arguments);
|
||||
var cachedResult = cache[key];
|
||||
let key = Array.prototype.join.call(arguments);
|
||||
let cachedResult = cache[key];
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
} else {
|
||||
@ -140,7 +139,7 @@ module Utils {
|
||||
});
|
||||
|
||||
// Make sure each of the children is in order.
|
||||
var currentPos = 0;
|
||||
let currentPos = 0;
|
||||
ts.forEachChild(node,
|
||||
child => {
|
||||
assert.isFalse(child.pos < currentPos, "child.pos < currentPos");
|
||||
@ -151,22 +150,22 @@ module Utils {
|
||||
assert.isFalse(array.end > node.end, "array.end > node.end");
|
||||
assert.isFalse(array.pos < currentPos, "array.pos < currentPos");
|
||||
|
||||
for (var i = 0, n = array.length; i < n; i++) {
|
||||
for (let i = 0, n = array.length; i < n; i++) {
|
||||
assert.isFalse(array[i].pos < currentPos, "array[i].pos < currentPos");
|
||||
currentPos = array[i].end
|
||||
currentPos = array[i].end;
|
||||
}
|
||||
|
||||
currentPos = array.end;
|
||||
});
|
||||
|
||||
var childNodesAndArrays: any[] = [];
|
||||
ts.forEachChild(node, child => { childNodesAndArrays.push(child) }, array => { childNodesAndArrays.push(array) });
|
||||
let childNodesAndArrays: any[] = [];
|
||||
ts.forEachChild(node, child => { childNodesAndArrays.push(child); }, array => { childNodesAndArrays.push(array); });
|
||||
|
||||
for (var childName in node) {
|
||||
for (let childName in node) {
|
||||
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator") {
|
||||
continue;
|
||||
}
|
||||
var child = (<any>node)[childName];
|
||||
let child = (<any>node)[childName];
|
||||
if (isNodeOrArray(child)) {
|
||||
assert.isFalse(childNodesAndArrays.indexOf(child) < 0,
|
||||
"Missing child when forEach'ing over node: " + (<any>ts).SyntaxKind[node.kind] + "-" + childName);
|
||||
@ -194,7 +193,7 @@ module Utils {
|
||||
}
|
||||
|
||||
export function sourceFileToJSON(file: ts.Node): string {
|
||||
return JSON.stringify(file,(k, v) => {
|
||||
return JSON.stringify(file, (k, v) => {
|
||||
return isNodeOrArray(v) ? serializeNode(v) : v;
|
||||
}, " ");
|
||||
|
||||
@ -203,7 +202,7 @@ module Utils {
|
||||
return k;
|
||||
}
|
||||
|
||||
return (<any>ts).SyntaxKind[k]
|
||||
return (<any>ts).SyntaxKind[k];
|
||||
}
|
||||
|
||||
function getFlagName(flags: any, f: number): any {
|
||||
@ -211,7 +210,7 @@ module Utils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var result = "";
|
||||
let result = "";
|
||||
ts.forEach(Object.getOwnPropertyNames(flags), (v: any) => {
|
||||
if (isFinite(v)) {
|
||||
v = +v;
|
||||
@ -234,7 +233,7 @@ module Utils {
|
||||
function getParserContextFlagName(f: number) { return getFlagName((<any>ts).ParserContextFlags, f); }
|
||||
|
||||
function serializeNode(n: ts.Node): any {
|
||||
var o: any = { kind: getKindName(n.kind) };
|
||||
let o: any = { kind: getKindName(n.kind) };
|
||||
if (ts.containsParseError(n)) {
|
||||
o.containsParseError = true;
|
||||
}
|
||||
@ -268,7 +267,7 @@ module Utils {
|
||||
// Clear the flag that are produced by aggregating child values.. That is ephemeral
|
||||
// data we don't care about in the dump. We only care what the parser set directly
|
||||
// on the ast.
|
||||
var value = n.parserContextFlags & ts.ParserContextFlags.ParserGeneratedFlags;
|
||||
let value = n.parserContextFlags & ts.ParserContextFlags.ParserGeneratedFlags;
|
||||
if (value) {
|
||||
o[propertyName] = getParserContextFlagName(value);
|
||||
}
|
||||
@ -313,9 +312,9 @@ module Utils {
|
||||
|
||||
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
|
||||
|
||||
for (var i = 0, n = array1.length; i < n; i++) {
|
||||
var d1 = array1[i];
|
||||
var d2 = array2[i];
|
||||
for (let i = 0, n = array1.length; i < n; i++) {
|
||||
let d1 = array1[i];
|
||||
let d2 = array2[i];
|
||||
|
||||
assert.equal(d1.start, d2.start, "d1.start !== d2.start");
|
||||
assert.equal(d1.length, d2.length, "d1.length !== d2.length");
|
||||
@ -346,14 +345,14 @@ module Utils {
|
||||
|
||||
ts.forEachChild(node1,
|
||||
child1 => {
|
||||
var childName = findChildName(node1, child1);
|
||||
var child2: ts.Node = (<any>node2)[childName];
|
||||
let childName = findChildName(node1, child1);
|
||||
let child2: ts.Node = (<any>node2)[childName];
|
||||
|
||||
assertStructuralEquals(child1, child2);
|
||||
},
|
||||
(array1: ts.NodeArray<ts.Node>) => {
|
||||
var childName = findChildName(node1, array1);
|
||||
var array2: ts.NodeArray<ts.Node> = (<any>node2)[childName];
|
||||
let childName = findChildName(node1, array1);
|
||||
let array2: ts.NodeArray<ts.Node> = (<any>node2)[childName];
|
||||
|
||||
assertArrayStructuralEquals(array1, array2);
|
||||
});
|
||||
@ -370,13 +369,13 @@ module Utils {
|
||||
assert.equal(array1.end, array2.end, "array1.end !== array2.end");
|
||||
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
|
||||
|
||||
for (var i = 0, n = array1.length; i < n; i++) {
|
||||
for (let i = 0, n = array1.length; i < n; i++) {
|
||||
assertStructuralEquals(array1[i], array2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function findChildName(parent: any, child: any) {
|
||||
for (var name in parent) {
|
||||
for (let name in parent) {
|
||||
if (parent.hasOwnProperty(name) && parent[name] === child) {
|
||||
return name;
|
||||
}
|
||||
@ -393,8 +392,8 @@ module Harness.Path {
|
||||
|
||||
export function filePath(fullPath: string) {
|
||||
fullPath = ts.normalizeSlashes(fullPath);
|
||||
var components = fullPath.split("/");
|
||||
var path: string[] = components.slice(0, components.length - 1);
|
||||
let components = fullPath.split("/");
|
||||
let path: string[] = components.slice(0, components.length - 1);
|
||||
return path.join("/") + "/";
|
||||
}
|
||||
}
|
||||
@ -422,19 +421,19 @@ module Harness {
|
||||
}
|
||||
|
||||
export module CScript {
|
||||
var fso: any;
|
||||
let fso: any;
|
||||
if (global.ActiveXObject) {
|
||||
fso = new global.ActiveXObject("Scripting.FileSystemObject");
|
||||
} else {
|
||||
fso = {};
|
||||
}
|
||||
|
||||
export var readFile: typeof IO.readFile = ts.sys.readFile;
|
||||
export var writeFile: typeof IO.writeFile = ts.sys.writeFile;
|
||||
export var directoryName: typeof IO.directoryName = fso.GetParentFolderName;
|
||||
export var directoryExists: typeof IO.directoryExists = fso.FolderExists;
|
||||
export var fileExists: typeof IO.fileExists = fso.FileExists;
|
||||
export var log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine;
|
||||
export let readFile: typeof IO.readFile = ts.sys.readFile;
|
||||
export let writeFile: typeof IO.writeFile = ts.sys.writeFile;
|
||||
export let directoryName: typeof IO.directoryName = fso.GetParentFolderName;
|
||||
export let directoryExists: typeof IO.directoryExists = fso.FolderExists;
|
||||
export let fileExists: typeof IO.fileExists = fso.FileExists;
|
||||
export let log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine;
|
||||
|
||||
export function createDirectory(path: string) {
|
||||
if (directoryExists(path)) {
|
||||
@ -448,11 +447,11 @@ module Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export var listFiles: typeof IO.listFiles = (path, spec?, options?) => {
|
||||
export let listFiles: typeof IO.listFiles = (path, spec?, options?) => {
|
||||
options = options || <{ recursive?: boolean; }>{};
|
||||
function filesInFolder(folder: any, root: string): string[] {
|
||||
var paths: string[] = [];
|
||||
var fc: any;
|
||||
let paths: string[] = [];
|
||||
let fc: any;
|
||||
|
||||
if (options.recursive) {
|
||||
fc = new Enumerator(folder.subfolders);
|
||||
@ -473,17 +472,16 @@ module Harness {
|
||||
return paths;
|
||||
}
|
||||
|
||||
var folder: any = fso.GetFolder(path);
|
||||
var paths: string[] = [];
|
||||
let folder: any = fso.GetFolder(path);
|
||||
let paths: string[] = [];
|
||||
|
||||
return filesInFolder(folder, path);
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export module Node {
|
||||
declare var require: any;
|
||||
var fs: any, pathModule: any;
|
||||
declare let require: any;
|
||||
let fs: any, pathModule: any;
|
||||
if (require) {
|
||||
fs = require('fs');
|
||||
pathModule = require('path');
|
||||
@ -491,10 +489,10 @@ module Harness {
|
||||
fs = pathModule = {};
|
||||
}
|
||||
|
||||
export var readFile: typeof IO.readFile = ts.sys.readFile;
|
||||
export var writeFile: typeof IO.writeFile = ts.sys.writeFile;
|
||||
export var fileExists: typeof IO.fileExists = fs.existsSync;
|
||||
export var log: typeof IO.log = console.log;
|
||||
export let readFile: typeof IO.readFile = ts.sys.readFile;
|
||||
export let writeFile: typeof IO.writeFile = ts.sys.writeFile;
|
||||
export let fileExists: typeof IO.fileExists = fs.existsSync;
|
||||
export let log: typeof IO.log = console.log;
|
||||
|
||||
export function createDirectory(path: string) {
|
||||
if (!directoryExists(path)) {
|
||||
@ -514,7 +512,7 @@ module Harness {
|
||||
}
|
||||
|
||||
export function directoryName(path: string) {
|
||||
var dirPath = pathModule.dirname(path);
|
||||
let dirPath = pathModule.dirname(path);
|
||||
|
||||
// Node will just continue to repeat the root path, rather than return null
|
||||
if (dirPath === path) {
|
||||
@ -524,16 +522,16 @@ module Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export var listFiles: typeof IO.listFiles = (path, spec?, options?) => {
|
||||
export let listFiles: typeof IO.listFiles = (path, spec?, options?) => {
|
||||
options = options || <{ recursive?: boolean; }>{};
|
||||
|
||||
function filesInFolder(folder: string): string[] {
|
||||
var paths: string[] = [];
|
||||
let paths: string[] = [];
|
||||
|
||||
var files = fs.readdirSync(folder);
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var pathToFile = pathModule.join(folder, files[i]);
|
||||
var stat = fs.statSync(pathToFile);
|
||||
let files = fs.readdirSync(folder);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let pathToFile = pathModule.join(folder, files[i]);
|
||||
let stat = fs.statSync(pathToFile);
|
||||
if (options.recursive && stat.isDirectory()) {
|
||||
paths = paths.concat(filesInFolder(pathToFile));
|
||||
}
|
||||
@ -546,23 +544,23 @@ module Harness {
|
||||
}
|
||||
|
||||
return filesInFolder(path);
|
||||
}
|
||||
};
|
||||
|
||||
export var getMemoryUsage: typeof IO.getMemoryUsage = () => {
|
||||
export let getMemoryUsage: typeof IO.getMemoryUsage = () => {
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
}
|
||||
return process.memoryUsage().heapUsed;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export module Network {
|
||||
var serverRoot = "http://localhost:8888/";
|
||||
let serverRoot = "http://localhost:8888/";
|
||||
|
||||
// Unused?
|
||||
var newLine = '\r\n';
|
||||
var currentDirectory = () => '';
|
||||
var supportsCodePage = () => false;
|
||||
let newLine = '\r\n';
|
||||
let currentDirectory = () => '';
|
||||
let supportsCodePage = () => false;
|
||||
|
||||
module Http {
|
||||
function waitForXHR(xhr: XMLHttpRequest) {
|
||||
@ -572,7 +570,7 @@ module Harness {
|
||||
|
||||
/// Ask the server to use node's path.resolve to resolve the given path
|
||||
function getResolvedPathFromServer(path: string) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
let xhr = new XMLHttpRequest();
|
||||
try {
|
||||
xhr.open("GET", path + "?resolve", false);
|
||||
xhr.send();
|
||||
@ -591,7 +589,7 @@ module Harness {
|
||||
|
||||
/// Ask the server for the contents of the file at the given URL via a simple GET request
|
||||
export function getFileFromServerSync(url: string): XHRResponse {
|
||||
var xhr = new XMLHttpRequest();
|
||||
let xhr = new XMLHttpRequest();
|
||||
try {
|
||||
xhr.open("GET", url, false);
|
||||
xhr.send();
|
||||
@ -605,10 +603,10 @@ module Harness {
|
||||
|
||||
/// Submit a POST request to the server to do the given action (ex WRITE, DELETE) on the provided URL
|
||||
export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse {
|
||||
var xhr = new XMLHttpRequest();
|
||||
let xhr = new XMLHttpRequest();
|
||||
try {
|
||||
var action = '?action=' + action;
|
||||
xhr.open('POST', url + action, false);
|
||||
let actionMsg = '?action=' + action;
|
||||
xhr.open('POST', url + actionMsg, false);
|
||||
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
|
||||
xhr.send(contents);
|
||||
}
|
||||
@ -633,7 +631,7 @@ module Harness {
|
||||
}
|
||||
|
||||
function directoryNameImpl(path: string) {
|
||||
var dirPath = path;
|
||||
let dirPath = path;
|
||||
// root of the server
|
||||
if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) {
|
||||
dirPath = null;
|
||||
@ -646,22 +644,22 @@ module Harness {
|
||||
if (dirPath.match(/.*\/$/)) {
|
||||
dirPath = dirPath.substring(0, dirPath.length - 2);
|
||||
}
|
||||
var dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
|
||||
dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
return dirPath;
|
||||
}
|
||||
export var directoryName: typeof IO.directoryName = Utils.memoize(directoryNameImpl);
|
||||
export let directoryName: typeof IO.directoryName = Utils.memoize(directoryNameImpl);
|
||||
|
||||
export function fileExists(path: string): boolean {
|
||||
var response = Http.getFileFromServerSync(serverRoot + path);
|
||||
let response = Http.getFileFromServerSync(serverRoot + path);
|
||||
return response.status === 200;
|
||||
}
|
||||
|
||||
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
|
||||
var response = Http.getFileFromServerSync(serverRoot + path);
|
||||
let response = Http.getFileFromServerSync(serverRoot + path);
|
||||
if (response.status === 200) {
|
||||
var results = response.responseText.split(',');
|
||||
let results = response.responseText.split(',');
|
||||
if (spec) {
|
||||
return results.filter(file => spec.test(file));
|
||||
} else {
|
||||
@ -672,12 +670,12 @@ module Harness {
|
||||
return [''];
|
||||
}
|
||||
};
|
||||
export var listFiles = Utils.memoize(_listFilesImpl);
|
||||
export let listFiles = Utils.memoize(_listFilesImpl);
|
||||
|
||||
export var log = console.log;
|
||||
export let log = console.log;
|
||||
|
||||
export function readFile(file: string) {
|
||||
var response = Http.getFileFromServerSync(serverRoot + file);
|
||||
let response = Http.getFileFromServerSync(serverRoot + file);
|
||||
if (response.status === 200) {
|
||||
return response.responseText;
|
||||
} else {
|
||||
@ -706,9 +704,9 @@ module Harness {
|
||||
}
|
||||
|
||||
module Harness {
|
||||
var tcServicesFileName = "typescriptServices.js";
|
||||
let tcServicesFileName = "typescriptServices.js";
|
||||
|
||||
export var libFolder: string;
|
||||
export let libFolder: string;
|
||||
switch (Utils.getExecutionEnvironment()) {
|
||||
case Utils.ExecutionEnvironment.CScript:
|
||||
libFolder = "built/local/";
|
||||
@ -725,7 +723,7 @@ module Harness {
|
||||
default:
|
||||
throw new Error('Unknown context');
|
||||
}
|
||||
export var tcServicesFile = IO.readFile(tcServicesFileName);
|
||||
export let tcServicesFile = IO.readFile(tcServicesFileName);
|
||||
|
||||
export interface SourceMapEmitterCallback {
|
||||
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
|
||||
@ -777,7 +775,7 @@ module Harness {
|
||||
|
||||
/** create file gets the whole path to create, so this works as expected with the --out parameter */
|
||||
public writeFile(s: string, contents: string, writeByteOrderMark: boolean): void {
|
||||
var writer: ITextWriter;
|
||||
let writer: ITextWriter;
|
||||
if (this.fileCollection[s]) {
|
||||
writer = <ITextWriter>this.fileCollection[s];
|
||||
}
|
||||
@ -795,10 +793,10 @@ module Harness {
|
||||
public reset() { this.fileCollection = {}; }
|
||||
|
||||
public toArray(): { fileName: string; file: WriterAggregator; }[] {
|
||||
var result: { fileName: string; file: WriterAggregator; }[] = [];
|
||||
for (var p in this.fileCollection) {
|
||||
let result: { fileName: string; file: WriterAggregator; }[] = [];
|
||||
for (let p in this.fileCollection) {
|
||||
if (this.fileCollection.hasOwnProperty(p)) {
|
||||
var current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
||||
let current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
||||
if (current.lines.length > 0) {
|
||||
if (p.indexOf('.d.ts') !== -1) { current.lines.unshift(['////[', Path.getFileName(p), ']'].join('')); }
|
||||
result.push({ fileName: p, file: this.fileCollection[p] });
|
||||
@ -813,11 +811,11 @@ module Harness {
|
||||
fileName: string,
|
||||
sourceText: string,
|
||||
languageVersion: ts.ScriptTarget) {
|
||||
// We'll only assert invariants outside of light mode.
|
||||
// We'll only assert inletiants outside of light mode.
|
||||
const shouldAssertInvariants = !Harness.lightMode;
|
||||
|
||||
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
|
||||
var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
||||
// Only set the parent nodes if we're asserting inletiants. We don't need them otherwise.
|
||||
let result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
||||
|
||||
if (shouldAssertInvariants) {
|
||||
Utils.assertInvariants(result, /*parent:*/ undefined);
|
||||
@ -829,13 +827,13 @@ module Harness {
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
|
||||
export var defaultLibFileName = 'lib.d.ts';
|
||||
export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultLibFileName = 'lib.d.ts';
|
||||
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
|
||||
// Cache these between executions so we don't have to re-parse them for every test
|
||||
export var fourslashFileName = 'fourslash.ts';
|
||||
export var fourslashSourceFile: ts.SourceFile;
|
||||
export let fourslashFileName = 'fourslash.ts';
|
||||
export let fourslashSourceFile: ts.SourceFile;
|
||||
|
||||
export function getCanonicalFileName(fileName: string): string {
|
||||
return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
@ -855,13 +853,13 @@ module Harness {
|
||||
return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
var filemap: { [fileName: string]: ts.SourceFile; } = {};
|
||||
var getCurrentDirectory = currentDirectory === undefined ? ts.sys.getCurrentDirectory : () => currentDirectory;
|
||||
let filemap: { [fileName: string]: ts.SourceFile; } = {};
|
||||
let getCurrentDirectory = currentDirectory === undefined ? ts.sys.getCurrentDirectory : () => currentDirectory;
|
||||
|
||||
// Register input files
|
||||
function register(file: { unitName: string; content: string; }) {
|
||||
if (file.content !== undefined) {
|
||||
var fileName = ts.normalizePath(file.unitName);
|
||||
let fileName = ts.normalizePath(file.unitName);
|
||||
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
|
||||
}
|
||||
};
|
||||
@ -880,11 +878,11 @@ module Harness {
|
||||
return filemap[getCanonicalFileName(fn)];
|
||||
}
|
||||
else if (currentDirectory) {
|
||||
var canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
||||
let canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
||||
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
||||
}
|
||||
else if (fn === fourslashFileName) {
|
||||
var tsFn = 'tests/cases/fourslash/' + fourslashFileName;
|
||||
let tsFn = 'tests/cases/fourslash/' + fourslashFileName;
|
||||
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||
return fourslashSourceFile;
|
||||
}
|
||||
@ -980,27 +978,27 @@ module Harness {
|
||||
|
||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
||||
// Treat them as library files, so include them in build, but not in baselines.
|
||||
var includeBuiltFiles: { unitName: string; content: string }[] = [];
|
||||
let includeBuiltFiles: { unitName: string; content: string }[] = [];
|
||||
|
||||
var useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
|
||||
let useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
|
||||
this.settings.forEach(setCompilerOptionForSetting);
|
||||
|
||||
var fileOutputs: GeneratedFile[] = [];
|
||||
let fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||
let programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||
|
||||
var compilerHost = createCompilerHost(
|
||||
let compilerHost = createCompilerHost(
|
||||
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
|
||||
var program = ts.createProgram(programFiles, options, compilerHost);
|
||||
let program = ts.createProgram(programFiles, options, compilerHost);
|
||||
|
||||
var emitResult = program.emit();
|
||||
let emitResult = program.emit();
|
||||
|
||||
var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
let errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
this.lastErrors = errors;
|
||||
|
||||
var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
let result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
onComplete(result, program);
|
||||
|
||||
// reset what newline means in case the last test changed it
|
||||
@ -1193,12 +1191,12 @@ module Harness {
|
||||
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
|
||||
}
|
||||
|
||||
let declInputFiles: { unitName: string; content: string }[] = [];
|
||||
let declOtherFiles: { unitName: string; content: string }[] = [];
|
||||
let declResult: Harness.Compiler.CompilerResult;
|
||||
|
||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
var declInputFiles: { unitName: string; content: string }[] = [];
|
||||
var declOtherFiles: { unitName: string; content: string }[] = [];
|
||||
var declResult: Harness.Compiler.CompilerResult;
|
||||
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; },
|
||||
@ -1212,20 +1210,20 @@ module Harness {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
else if (isTS(file.unitName)) {
|
||||
var declFile = findResultCodeFile(file.unitName);
|
||||
let declFile = findResultCodeFile(file.unitName);
|
||||
if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
}
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
var sourceFile = result.program.getSourceFile(fileName);
|
||||
let sourceFile = result.program.getSourceFile(fileName);
|
||||
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
||||
// Is this file going to be emitted separately
|
||||
var sourceFileName: string;
|
||||
let sourceFileName: string;
|
||||
if (ts.isExternalModule(sourceFile) || !options.out) {
|
||||
if (options.outDir) {
|
||||
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
||||
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
|
||||
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
|
||||
}
|
||||
@ -1238,7 +1236,7 @@ module Harness {
|
||||
sourceFileName = options.out;
|
||||
}
|
||||
|
||||
var dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
let dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
|
||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||
}
|
||||
@ -1251,7 +1249,7 @@ module Harness {
|
||||
}
|
||||
|
||||
function normalizeLineEndings(text: string, lineEnding: string): string {
|
||||
var normalized = text.replace(/\r\n?/g, '\n');
|
||||
let normalized = text.replace(/\r\n?/g, '\n');
|
||||
if (lineEnding !== '\n') {
|
||||
normalized = normalized.replace(/\n/g, lineEnding);
|
||||
}
|
||||
@ -1260,10 +1258,10 @@ module Harness {
|
||||
|
||||
export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) {
|
||||
// This is basically copied from tsc.ts's reportError to replicate what tsc does
|
||||
var errorOutput = "";
|
||||
let errorOutput = "";
|
||||
ts.forEach(diagnostics, diagnostic => {
|
||||
if (diagnostic.file) {
|
||||
var lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
let lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): ";
|
||||
}
|
||||
|
||||
@ -1275,14 +1273,14 @@ module Harness {
|
||||
|
||||
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
|
||||
diagnostics.sort(ts.compareDiagnostics);
|
||||
var outputLines: string[] = [];
|
||||
let outputLines: string[] = [];
|
||||
// Count up all the errors we find so we don't miss any
|
||||
var totalErrorsReported = 0;
|
||||
let totalErrorsReported = 0;
|
||||
|
||||
function outputErrorText(error: ts.Diagnostic) {
|
||||
var message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine);
|
||||
let message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine);
|
||||
|
||||
var errLines = RunnerBase.removeFullPaths(message)
|
||||
let errLines = RunnerBase.removeFullPaths(message)
|
||||
.split('\n')
|
||||
.map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s)
|
||||
.filter(s => s.length > 0)
|
||||
@ -1293,14 +1291,14 @@ module Harness {
|
||||
}
|
||||
|
||||
// Report global errors
|
||||
var globalErrors = diagnostics.filter(err => !err.file);
|
||||
let globalErrors = diagnostics.filter(err => !err.file);
|
||||
globalErrors.forEach(outputErrorText);
|
||||
|
||||
// 'merge' the lines of each input file with any errors associated with it
|
||||
inputFiles.filter(f => f.content !== undefined).forEach(inputFile => {
|
||||
// Filter down to the errors in the file
|
||||
var fileErrors = diagnostics.filter(e => {
|
||||
var errFn = e.file;
|
||||
let fileErrors = diagnostics.filter(e => {
|
||||
let errFn = e.file;
|
||||
return errFn && errFn.fileName === inputFile.unitName;
|
||||
});
|
||||
|
||||
@ -1309,13 +1307,13 @@ module Harness {
|
||||
outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ====');
|
||||
|
||||
// Make sure we emit something for every error
|
||||
var markedErrorCount = 0;
|
||||
let markedErrorCount = 0;
|
||||
// For each line, emit the line followed by any error squiggles matching this line
|
||||
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
|
||||
// we have to string-based splitting instead and try to figure out the delimiting chars
|
||||
|
||||
var lineStarts = ts.computeLineStarts(inputFile.content);
|
||||
var lines = inputFile.content.split('\n');
|
||||
let lineStarts = ts.computeLineStarts(inputFile.content);
|
||||
let lines = inputFile.content.split('\n');
|
||||
if (lines.length === 1) {
|
||||
lines = lines[0].split("\r");
|
||||
}
|
||||
@ -1325,8 +1323,8 @@ module Harness {
|
||||
line = line.substr(0, line.length - 1);
|
||||
}
|
||||
|
||||
var thisLineStart = lineStarts[lineIndex];
|
||||
var nextLineStart: number;
|
||||
let thisLineStart = lineStarts[lineIndex];
|
||||
let nextLineStart: number;
|
||||
// On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly
|
||||
if (lineIndex === lines.length - 1) {
|
||||
nextLineStart = inputFile.content.length;
|
||||
@ -1340,11 +1338,11 @@ module Harness {
|
||||
let end = ts.textSpanEnd(err);
|
||||
if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
||||
// How many characters from the start of this line the error starts at (could be positive or negative)
|
||||
var relativeOffset = err.start - thisLineStart;
|
||||
let relativeOffset = err.start - thisLineStart;
|
||||
// How many characters of the error are on this line (might be longer than this line in reality)
|
||||
var length = (end - err.start) - Math.max(0, thisLineStart - err.start);
|
||||
let length = (end - err.start) - Math.max(0, thisLineStart - err.start);
|
||||
// Calculate the start of the squiggle
|
||||
var squiggleStart = Math.max(0, relativeOffset);
|
||||
let squiggleStart = Math.max(0, relativeOffset);
|
||||
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
||||
outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~'));
|
||||
|
||||
@ -1364,11 +1362,11 @@ module Harness {
|
||||
assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName);
|
||||
});
|
||||
|
||||
var numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||
});
|
||||
|
||||
var numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
// Count an error generated from tests262-harness folder.This should only apply for test262
|
||||
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
||||
});
|
||||
@ -1385,7 +1383,7 @@ module Harness {
|
||||
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
|
||||
|
||||
// Emit them
|
||||
var result = '';
|
||||
let result = '';
|
||||
for (let outputFile of outputFiles) {
|
||||
// Some extra spacing if this isn't the first file
|
||||
if (result.length) {
|
||||
@ -1401,13 +1399,13 @@ module Harness {
|
||||
return result;
|
||||
|
||||
function cleanName(fn: string) {
|
||||
var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
|
||||
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
|
||||
return fn.substr(lastSlash + 1).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
|
||||
var harnessCompiler: HarnessCompiler;
|
||||
let harnessCompiler: HarnessCompiler;
|
||||
|
||||
/** Returns the singleton harness compiler instance for generating and running tests.
|
||||
If required a fresh compiler instance will be created, otherwise the existing singleton will be re-used.
|
||||
@ -1420,8 +1418,6 @@ module Harness {
|
||||
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
throw new Error('compileString NYI');
|
||||
//var harnessCompiler = Harness.Compiler.getCompiler(Harness.Compiler.CompilerInstance.RunTime);
|
||||
//harnessCompiler.compileString(code, unitName, callback);
|
||||
}
|
||||
|
||||
export interface GeneratedFile {
|
||||
@ -1513,10 +1509,10 @@ module Harness {
|
||||
}
|
||||
|
||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
||||
let optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
||||
|
||||
// List of allowed metadata names
|
||||
var fileMetadataNames = ["filename", "comments", "declaration", "module",
|
||||
let fileMetadataNames = ["filename", "comments", "declaration", "module",
|
||||
"nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror",
|
||||
"noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom",
|
||||
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
|
||||
@ -1527,9 +1523,9 @@ module Harness {
|
||||
|
||||
function extractCompilerSettings(content: string): CompilerSetting[] {
|
||||
|
||||
var opts: CompilerSetting[] = [];
|
||||
let opts: CompilerSetting[] = [];
|
||||
|
||||
var match: RegExpExecArray;
|
||||
let match: RegExpExecArray;
|
||||
while ((match = optionRegex.exec(content)) != null) {
|
||||
opts.push({ flag: match[1], value: match[2] });
|
||||
}
|
||||
@ -1539,26 +1535,26 @@ module Harness {
|
||||
|
||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||
export function makeUnitsFromTest(code: string, fileName: string): { settings: CompilerSetting[]; testUnitData: TestUnitData[]; } {
|
||||
var settings = extractCompilerSettings(code);
|
||||
let settings = extractCompilerSettings(code);
|
||||
|
||||
// List of all the subfiles we've parsed out
|
||||
var testUnitData: TestUnitData[] = [];
|
||||
let testUnitData: TestUnitData[] = [];
|
||||
|
||||
var lines = Utils.splitContentByNewlines(code);
|
||||
let lines = Utils.splitContentByNewlines(code);
|
||||
|
||||
// Stuff related to the subfile we're parsing
|
||||
var currentFileContent: string = null;
|
||||
var currentFileOptions: any = {};
|
||||
var currentFileName: any = null;
|
||||
var refs: string[] = [];
|
||||
let currentFileContent: string = null;
|
||||
let currentFileOptions: any = {};
|
||||
let currentFileName: any = null;
|
||||
let refs: string[] = [];
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
var testMetaData = optionRegex.exec(line);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
let testMetaData = optionRegex.exec(line);
|
||||
if (testMetaData) {
|
||||
// Comment line, check for global/file @options and record them
|
||||
optionRegex.lastIndex = 0;
|
||||
var metaDataName = testMetaData[1].toLowerCase();
|
||||
let metaDataName = testMetaData[1].toLowerCase();
|
||||
if (metaDataName === "filename") {
|
||||
currentFileOptions[testMetaData[1]] = testMetaData[2];
|
||||
} else {
|
||||
@ -1568,8 +1564,7 @@ module Harness {
|
||||
// New metadata statement after having collected some code to go with the previous metadata
|
||||
if (currentFileName) {
|
||||
// Store result file
|
||||
var newTestFile =
|
||||
{
|
||||
let newTestFile = {
|
||||
content: currentFileContent,
|
||||
name: currentFileName,
|
||||
fileOptions: currentFileOptions,
|
||||
@ -1604,7 +1599,7 @@ module Harness {
|
||||
currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName);
|
||||
|
||||
// EOF, push whatever remains
|
||||
var newTestFile2 = {
|
||||
let newTestFile2 = {
|
||||
content: currentFileContent || '',
|
||||
name: currentFileName,
|
||||
fileOptions: currentFileOptions,
|
||||
@ -1651,7 +1646,7 @@ module Harness {
|
||||
}
|
||||
}
|
||||
|
||||
var fileCache: { [idx: string]: boolean } = {};
|
||||
let fileCache: { [idx: string]: boolean } = {};
|
||||
function generateActual(actualFileName: string, generateContent: () => string): string {
|
||||
// For now this is written using TypeScript, because sys is not available when running old test cases.
|
||||
// But we need to move to sys once we have
|
||||
@ -1662,7 +1657,7 @@ module Harness {
|
||||
return;
|
||||
}
|
||||
|
||||
var parentDirectory = IO.directoryName(dirName);
|
||||
let parentDirectory = IO.directoryName(dirName);
|
||||
if (parentDirectory != "") {
|
||||
createDirectoryStructure(parentDirectory);
|
||||
}
|
||||
@ -1678,7 +1673,7 @@ module Harness {
|
||||
IO.deleteFile(actualFileName);
|
||||
}
|
||||
|
||||
var actual = generateContent();
|
||||
let actual = generateContent();
|
||||
|
||||
if (actual === undefined) {
|
||||
throw new Error('The generated content was "undefined". Return "null" if no baselining is required."');
|
||||
@ -1701,13 +1696,13 @@ module Harness {
|
||||
return;
|
||||
}
|
||||
|
||||
var refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
|
||||
if (actual === null) {
|
||||
actual = '<no content>';
|
||||
}
|
||||
|
||||
var expected = '<no content>';
|
||||
let expected = '<no content>';
|
||||
if (IO.fileExists(refFileName)) {
|
||||
expected = IO.readFile(refFileName);
|
||||
}
|
||||
@ -1716,10 +1711,10 @@ module Harness {
|
||||
}
|
||||
|
||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
||||
var encoded_actual = (new Buffer(actual)).toString('utf8')
|
||||
let encoded_actual = (new Buffer(actual)).toString('utf8');
|
||||
if (expected != encoded_actual) {
|
||||
// Overwrite & issue error
|
||||
var errMsg = 'The baseline file ' + relativeFileName + ' has changed';
|
||||
let errMsg = 'The baseline file ' + relativeFileName + ' has changed';
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
@ -1731,17 +1726,17 @@ module Harness {
|
||||
runImmediately = false,
|
||||
opts?: BaselineOptions): void {
|
||||
|
||||
var actual = <string>undefined;
|
||||
var actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
let actual = <string>undefined;
|
||||
let actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
|
||||
if (runImmediately) {
|
||||
actual = generateActual(actualFileName, generateContent);
|
||||
var comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
let comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||
} else {
|
||||
actual = generateActual(actualFileName, generateContent);
|
||||
|
||||
var comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
let comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||
}
|
||||
}
|
||||
@ -1756,11 +1751,11 @@ module Harness {
|
||||
}
|
||||
|
||||
export function getDefaultLibraryFile(): { unitName: string, content: string } {
|
||||
var libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts";
|
||||
let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts";
|
||||
return {
|
||||
unitName: libFile,
|
||||
content: IO.readFile(libFile)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (Error) (<any>Error).stackTraceLimit = 1;
|
||||
|
||||
@ -26,9 +26,9 @@ module Harness.LanguageService {
|
||||
|
||||
public editContent(start: number, end: number, newText: string): void {
|
||||
// Apply edits
|
||||
var prefix = this.content.substring(0, start);
|
||||
var middle = newText;
|
||||
var suffix = this.content.substring(end);
|
||||
let prefix = this.content.substring(0, start);
|
||||
let middle = newText;
|
||||
let suffix = this.content.substring(end);
|
||||
this.setContent(prefix + middle + suffix);
|
||||
|
||||
// Store edit range + new length of script
|
||||
@ -48,10 +48,10 @@ module Harness.LanguageService {
|
||||
return ts.unchangedTextChangeRange;
|
||||
}
|
||||
|
||||
var initialEditRangeIndex = this.editRanges.length - (this.version - startVersion);
|
||||
var lastEditRangeIndex = this.editRanges.length - (this.version - endVersion);
|
||||
let initialEditRangeIndex = this.editRanges.length - (this.version - startVersion);
|
||||
let lastEditRangeIndex = this.editRanges.length - (this.version - endVersion);
|
||||
|
||||
var entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex);
|
||||
let entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex);
|
||||
return ts.collapseTextChangeRangesAcrossMultipleVersions(entries.map(e => e.textChangeRange));
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ module Harness.LanguageService {
|
||||
}
|
||||
|
||||
public getChangeRange(oldScript: ts.IScriptSnapshot): ts.TextChangeRange {
|
||||
var oldShim = <ScriptSnapshot>oldScript;
|
||||
let oldShim = <ScriptSnapshot>oldScript;
|
||||
return this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version);
|
||||
}
|
||||
}
|
||||
@ -92,9 +92,9 @@ module Harness.LanguageService {
|
||||
}
|
||||
|
||||
public getChangeRange(oldScript: ts.ScriptSnapshotShim): string {
|
||||
var oldShim = <ScriptSnapshotProxy>oldScript;
|
||||
let oldShim = <ScriptSnapshotProxy>oldScript;
|
||||
|
||||
var range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot);
|
||||
let range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot);
|
||||
if (range === null) {
|
||||
return null;
|
||||
}
|
||||
@ -130,8 +130,8 @@ module Harness.LanguageService {
|
||||
}
|
||||
|
||||
public getFilenames(): string[] {
|
||||
var fileNames: string[] = [];
|
||||
ts.forEachKey(this.fileNameToScript,(fileName) => { fileNames.push(fileName); });
|
||||
let fileNames: string[] = [];
|
||||
ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); });
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ module Harness.LanguageService {
|
||||
}
|
||||
|
||||
public editScript(fileName: string, start: number, end: number, newText: string) {
|
||||
var script = this.getScriptInfo(fileName);
|
||||
let script = this.getScriptInfo(fileName);
|
||||
if (script !== null) {
|
||||
script.editContent(start, end, newText);
|
||||
return;
|
||||
@ -161,7 +161,7 @@ module Harness.LanguageService {
|
||||
* @param col 0 based index
|
||||
*/
|
||||
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
|
||||
var script: ScriptInfo = this.fileNameToScript[fileName];
|
||||
let script: ScriptInfo = this.fileNameToScript[fileName];
|
||||
assert.isNotNull(script);
|
||||
|
||||
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
|
||||
@ -176,11 +176,11 @@ module Harness.LanguageService {
|
||||
getDefaultLibFileName(): string { return ""; }
|
||||
getScriptFileNames(): string[] { return this.getFilenames(); }
|
||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
||||
var script = this.getScriptInfo(fileName);
|
||||
let script = this.getScriptInfo(fileName);
|
||||
return script ? new ScriptSnapshot(script) : undefined;
|
||||
}
|
||||
getScriptVersion(fileName: string): string {
|
||||
var script = this.getScriptInfo(fileName);
|
||||
let script = this.getScriptInfo(fileName);
|
||||
return script ? script.version.toString() : undefined;
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ module Harness.LanguageService {
|
||||
getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); }
|
||||
getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); }
|
||||
getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim {
|
||||
var nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||
let nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
|
||||
}
|
||||
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
|
||||
@ -242,13 +242,13 @@ module Harness.LanguageService {
|
||||
throw new Error("NYI");
|
||||
}
|
||||
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
|
||||
var result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n');
|
||||
var entries: ts.ClassificationInfo[] = [];
|
||||
var i = 0;
|
||||
var position = 0;
|
||||
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n');
|
||||
let entries: ts.ClassificationInfo[] = [];
|
||||
let i = 0;
|
||||
let position = 0;
|
||||
|
||||
for (; i < result.length - 1; i += 2) {
|
||||
var t = entries[i / 2] = {
|
||||
let t = entries[i / 2] = {
|
||||
length: parseInt(result[i]),
|
||||
classification: parseInt(result[i + 1])
|
||||
};
|
||||
@ -256,7 +256,7 @@ module Harness.LanguageService {
|
||||
assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length);
|
||||
position += t.length;
|
||||
}
|
||||
var finalLexState = parseInt(result[result.length - 1]);
|
||||
let finalLexState = parseInt(result[result.length - 1]);
|
||||
|
||||
assert.equal(position, text.length, "Expected cumulative length of all entries to match the length of the source. expected: " + text.length + ", but got: " + position);
|
||||
|
||||
@ -268,7 +268,7 @@ module Harness.LanguageService {
|
||||
}
|
||||
|
||||
function unwrapJSONCallResult(result: string): any {
|
||||
var parsedResult = JSON.parse(result);
|
||||
let parsedResult = JSON.parse(result);
|
||||
if (parsedResult.error) {
|
||||
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
||||
}
|
||||
@ -282,7 +282,7 @@ module Harness.LanguageService {
|
||||
constructor(private shim: ts.LanguageServiceShim) {
|
||||
}
|
||||
private unwrappJSONCallResult(result: string): any {
|
||||
var parsedResult = JSON.parse(result);
|
||||
let parsedResult = JSON.parse(result);
|
||||
if (parsedResult.error) {
|
||||
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
||||
}
|
||||
@ -404,16 +404,16 @@ module Harness.LanguageService {
|
||||
getLanguageService(): ts.LanguageService { return new LanguageServiceShimProxy(this.factory.createLanguageServiceShim(this.host)); }
|
||||
getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo {
|
||||
var shimResult: {
|
||||
let shimResult: {
|
||||
referencedFiles: ts.IFileReference[];
|
||||
importedFiles: ts.IFileReference[];
|
||||
isLibFile: boolean;
|
||||
};
|
||||
|
||||
var coreServicesShim = this.factory.createCoreServicesShim(this.host);
|
||||
let coreServicesShim = this.factory.createCoreServicesShim(this.host);
|
||||
shimResult = unwrapJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents)));
|
||||
|
||||
var convertResult: ts.PreProcessedFileInfo = {
|
||||
let convertResult: ts.PreProcessedFileInfo = {
|
||||
referencedFiles: [],
|
||||
importedFiles: [],
|
||||
isLibFile: shimResult.isLibFile
|
||||
@ -496,7 +496,7 @@ module Harness.LanguageService {
|
||||
fileName = Harness.Compiler.defaultLibFileName;
|
||||
}
|
||||
|
||||
var snapshot = this.host.getScriptSnapshot(fileName);
|
||||
let snapshot = this.host.getScriptSnapshot(fileName);
|
||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
|
||||
@ -574,13 +574,13 @@ module Harness.LanguageService {
|
||||
private client: ts.server.SessionClient;
|
||||
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
|
||||
// This is the main host that tests use to direct tests
|
||||
var clientHost = new SessionClientHost(cancellationToken, options);
|
||||
var client = new ts.server.SessionClient(clientHost);
|
||||
let clientHost = new SessionClientHost(cancellationToken, options);
|
||||
let client = new ts.server.SessionClient(clientHost);
|
||||
|
||||
// This host is just a proxy for the clientHost, it uses the client
|
||||
// host to answer server queries about files on disk
|
||||
var serverHost = new SessionServerHost(clientHost);
|
||||
var server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost);
|
||||
let serverHost = new SessionServerHost(clientHost);
|
||||
let server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost);
|
||||
|
||||
// Fake the connection between the client and the server
|
||||
serverHost.writeMessage = client.onMessage.bind(client);
|
||||
|
||||
@ -70,9 +70,9 @@ interface PlaybackControl {
|
||||
}
|
||||
|
||||
module Playback {
|
||||
var recordLog: IOLog = undefined;
|
||||
var replayLog: IOLog = undefined;
|
||||
var recordLogFileNameBase = '';
|
||||
let recordLog: IOLog = undefined;
|
||||
let replayLog: IOLog = undefined;
|
||||
let recordLogFileNameBase = '';
|
||||
|
||||
interface Memoized<T> {
|
||||
(s: string): T;
|
||||
@ -80,8 +80,8 @@ module Playback {
|
||||
}
|
||||
|
||||
function memoize<T>(func: (s: string) => T): Memoized<T> {
|
||||
var lookup: { [s: string]: T } = {};
|
||||
var run: Memoized<T> = <Memoized<T>>((s: string) => {
|
||||
let lookup: { [s: string]: T } = {};
|
||||
let run: Memoized<T> = <Memoized<T>>((s: string) => {
|
||||
if (lookup.hasOwnProperty(s)) return lookup[s];
|
||||
return lookup[s] = func(s);
|
||||
});
|
||||
@ -161,10 +161,10 @@ module Playback {
|
||||
}
|
||||
|
||||
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T {
|
||||
var predicate = (entry: { result?: T }) => {
|
||||
let predicate = (entry: { result?: T }) => {
|
||||
return Object.getOwnPropertyNames(expectedFields).every((name) => (<any>entry)[name] === (<any>expectedFields)[name]);
|
||||
};
|
||||
var results = logArray.filter(entry => predicate(entry));
|
||||
let results = logArray.filter(entry => predicate(entry));
|
||||
if (results.length === 0) {
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue;
|
||||
@ -176,17 +176,17 @@ module Playback {
|
||||
}
|
||||
|
||||
function findResultByPath<T>(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T {
|
||||
var normalizedName = ts.normalizeSlashes(expectedPath).toLowerCase();
|
||||
let normalizedName = ts.normalizeSlashes(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
for (var i = 0; i < logArray.length; i++) {
|
||||
for (let i = 0; i < logArray.length; i++) {
|
||||
if (ts.normalizeSlashes(logArray[i].path).toLowerCase() === normalizedName) {
|
||||
return logArray[i].result;
|
||||
}
|
||||
}
|
||||
// Fallback, try to resolve the target paths as well
|
||||
if (replayLog.pathsResolved.length > 0) {
|
||||
var normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase();
|
||||
for (var i = 0; i < logArray.length; i++) {
|
||||
let normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase();
|
||||
for (let i = 0; i < logArray.length; i++) {
|
||||
if (wrapper.resolvePath(logArray[i].path).toLowerCase() === normalizedResolvedName) {
|
||||
return logArray[i].result;
|
||||
}
|
||||
@ -200,9 +200,9 @@ module Playback {
|
||||
}
|
||||
}
|
||||
|
||||
var pathEquivCache: any = {};
|
||||
let pathEquivCache: any = {};
|
||||
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
|
||||
var key = left + '-~~-' + right;
|
||||
let key = left + '-~~-' + right;
|
||||
function areSame(a: string, b: string) {
|
||||
return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase();
|
||||
}
|
||||
@ -219,11 +219,11 @@ module Playback {
|
||||
}
|
||||
|
||||
function noOpReplay(name: string) {
|
||||
//console.log("Swallowed write operation during replay: " + name);
|
||||
// console.log("Swallowed write operation during replay: " + name);
|
||||
}
|
||||
|
||||
export function wrapSystem(underlying: ts.System): PlaybackSystem {
|
||||
var wrapper: PlaybackSystem = <any>{};
|
||||
let wrapper: PlaybackSystem = <any>{};
|
||||
initWrapper(wrapper, underlying);
|
||||
|
||||
wrapper.startReplayFromFile = logFn => {
|
||||
@ -231,8 +231,8 @@ module Playback {
|
||||
};
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
var i = 0;
|
||||
var fn = () => recordLogFileNameBase + i + '.json';
|
||||
let i = 0;
|
||||
let fn = () => recordLogFileNameBase + i + '.json';
|
||||
while (underlying.fileExists(fn())) i++;
|
||||
underlying.writeFile(fn(), JSON.stringify(recordLog));
|
||||
recordLog = undefined;
|
||||
@ -289,8 +289,8 @@ module Playback {
|
||||
|
||||
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
||||
(path) => {
|
||||
var result = underlying.readFile(path);
|
||||
var logEntry = { path: path, codepage: 0, result: { contents: result, codepage: 0 } };
|
||||
let result = underlying.readFile(path);
|
||||
let logEntry = { path: path, codepage: 0, result: { contents: result, codepage: 0 } };
|
||||
recordLog.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
|
||||
@ -46,7 +46,7 @@ interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
|
||||
class ProjectRunner extends RunnerBase {
|
||||
public initializeTests() {
|
||||
if (this.tests.length === 0) {
|
||||
var testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true });
|
||||
let testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true });
|
||||
testFiles.forEach(fn => {
|
||||
fn = fn.replace(/\\/g, "/");
|
||||
this.runProjectTestCase(fn);
|
||||
@ -58,10 +58,11 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
private runProjectTestCase(testCaseFileName: string) {
|
||||
var testCase: ProjectRunnerTestCase;
|
||||
let testCase: ProjectRunnerTestCase;
|
||||
|
||||
let testFileText: string = null;
|
||||
try {
|
||||
var testFileText = ts.sys.readFile(testCaseFileName);
|
||||
testFileText = ts.sys.readFile(testCaseFileName);
|
||||
}
|
||||
catch (e) {
|
||||
assert(false, "Unable to open testcase file: " + testCaseFileName + ": " + e.message);
|
||||
@ -73,7 +74,7 @@ class ProjectRunner extends RunnerBase {
|
||||
catch (e) {
|
||||
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
}
|
||||
var testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, "");
|
||||
let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, "");
|
||||
|
||||
function moduleNameToString(moduleKind: ts.ModuleKind) {
|
||||
return moduleKind === ts.ModuleKind.AMD
|
||||
@ -97,9 +98,9 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function cleanProjectUrl(url: string) {
|
||||
var diskProjectPath = ts.normalizeSlashes(ts.sys.resolvePath(testCase.projectRoot));
|
||||
var projectRootUrl = "file:///" + diskProjectPath;
|
||||
var normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot);
|
||||
let diskProjectPath = ts.normalizeSlashes(ts.sys.resolvePath(testCase.projectRoot));
|
||||
let projectRootUrl = "file:///" + diskProjectPath;
|
||||
let normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot);
|
||||
diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot));
|
||||
projectRootUrl = projectRootUrl.substr(0, projectRootUrl.lastIndexOf(normalizedProjectRoot));
|
||||
if (url && url.length) {
|
||||
@ -124,21 +125,21 @@ class ProjectRunner extends RunnerBase {
|
||||
return ts.sys.resolvePath(testCase.projectRoot);
|
||||
}
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: ()=> string[],
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
|
||||
getSourceFileText: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
|
||||
|
||||
var program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
|
||||
var errors = ts.getPreEmitDiagnostics(program);
|
||||
let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
|
||||
let errors = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
var emitResult = program.emit();
|
||||
let emitResult = program.emit();
|
||||
errors = ts.concatenate(errors, emitResult.diagnostics);
|
||||
var sourceMapData = emitResult.sourceMaps;
|
||||
let sourceMapData = emitResult.sourceMaps;
|
||||
|
||||
// Clean up source map data that will be used in baselining
|
||||
if (sourceMapData) {
|
||||
for (var i = 0; i < sourceMapData.length; i++) {
|
||||
for (var j = 0; j < sourceMapData[i].sourceMapSources.length; j++) {
|
||||
for (let i = 0; i < sourceMapData.length; i++) {
|
||||
for (let j = 0; j < sourceMapData[i].sourceMapSources.length; j++) {
|
||||
sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]);
|
||||
}
|
||||
sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL);
|
||||
@ -168,12 +169,12 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile {
|
||||
var sourceFile: ts.SourceFile = undefined;
|
||||
let sourceFile: ts.SourceFile = undefined;
|
||||
if (fileName === Harness.Compiler.defaultLibFileName) {
|
||||
sourceFile = languageVersion === ts.ScriptTarget.ES6 ? Harness.Compiler.defaultES6LibSourceFile : Harness.Compiler.defaultLibSourceFile;
|
||||
}
|
||||
else {
|
||||
var text = getSourceFileText(fileName);
|
||||
let text = getSourceFileText(fileName);
|
||||
if (text !== undefined) {
|
||||
sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion);
|
||||
}
|
||||
@ -196,11 +197,11 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult{
|
||||
var nonSubfolderDiskFiles = 0;
|
||||
let nonSubfolderDiskFiles = 0;
|
||||
|
||||
var outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
|
||||
var projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
|
||||
let projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
|
||||
return {
|
||||
moduleKind,
|
||||
program: projectCompilerResult.program,
|
||||
@ -211,8 +212,9 @@ class ProjectRunner extends RunnerBase {
|
||||
};
|
||||
|
||||
function getSourceFileText(fileName: string): string {
|
||||
let text: string = undefined;
|
||||
try {
|
||||
var text = ts.sys.readFile(ts.isRootedDiskPath(fileName)
|
||||
text = ts.sys.readFile(ts.isRootedDiskPath(fileName)
|
||||
? fileName
|
||||
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
|
||||
}
|
||||
@ -223,11 +225,11 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
var diskFileName = ts.isRootedDiskPath(fileName)
|
||||
let diskFileName = ts.isRootedDiskPath(fileName)
|
||||
? fileName
|
||||
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName);
|
||||
|
||||
var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName,
|
||||
let diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName,
|
||||
getCurrentDirectory(), Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
||||
if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") {
|
||||
// If the generated output file resides in the parent folder or is rooted path,
|
||||
@ -240,22 +242,22 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
if (Harness.Compiler.isJS(fileName)) {
|
||||
// Make sure if there is URl we have it cleaned up
|
||||
var indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
|
||||
let indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
|
||||
if (indexOfSourceMapUrl !== -1) {
|
||||
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
|
||||
}
|
||||
}
|
||||
else if (Harness.Compiler.isJSMap(fileName)) {
|
||||
// Make sure sources list is cleaned
|
||||
var sourceMapData = JSON.parse(data);
|
||||
for (var i = 0; i < sourceMapData.sources.length; i++) {
|
||||
let sourceMapData = JSON.parse(data);
|
||||
for (let i = 0; i < sourceMapData.sources.length; i++) {
|
||||
sourceMapData.sources[i] = cleanProjectUrl(sourceMapData.sources[i]);
|
||||
}
|
||||
sourceMapData.sourceRoot = cleanProjectUrl(sourceMapData.sourceRoot);
|
||||
data = JSON.stringify(sourceMapData);
|
||||
}
|
||||
|
||||
var outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind);
|
||||
let outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind);
|
||||
// Actual writing of file as in tc.ts
|
||||
function ensureDirectoryStructure(directoryname: string) {
|
||||
if (directoryname) {
|
||||
@ -273,36 +275,37 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
|
||||
var allInputFiles: { emittedFileName: string; code: string; }[] = [];
|
||||
var compilerOptions = compilerResult.program.getCompilerOptions();
|
||||
let allInputFiles: { emittedFileName: string; code: string; }[] = [];
|
||||
let compilerOptions = compilerResult.program.getCompilerOptions();
|
||||
|
||||
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
|
||||
if (Harness.Compiler.isDTS(sourceFile.fileName)) {
|
||||
allInputFiles.unshift({ emittedFileName: sourceFile.fileName, code: sourceFile.text });
|
||||
}
|
||||
else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) {
|
||||
let emitOutputFilePathWithoutExtension: string = undefined;
|
||||
if (compilerOptions.outDir) {
|
||||
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory());
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), "");
|
||||
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath));
|
||||
emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath));
|
||||
}
|
||||
else {
|
||||
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
|
||||
emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
|
||||
}
|
||||
|
||||
var outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
||||
let outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
||||
allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName));
|
||||
}
|
||||
else {
|
||||
var outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts";
|
||||
var outputDtsFile = findOutpuDtsFile(outputDtsFileName);
|
||||
let outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts";
|
||||
let outputDtsFile = findOutpuDtsFile(outputDtsFileName);
|
||||
if (!ts.contains(allInputFiles, outputDtsFile)) {
|
||||
allInputFiles.unshift(outputDtsFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile);
|
||||
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile);
|
||||
|
||||
function findOutpuDtsFile(fileName: string) {
|
||||
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
|
||||
@ -319,7 +322,7 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
var inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
let inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
sourceFile => sourceFile.fileName !== "lib.d.ts"),
|
||||
sourceFile => {
|
||||
return { unitName: sourceFile.fileName, content: sourceFile.text };
|
||||
@ -328,13 +331,15 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
var name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName;
|
||||
let name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName;
|
||||
|
||||
describe('Projects tests', () => {
|
||||
describe(name, () => {
|
||||
function verifyCompilerResults(moduleKind: ts.ModuleKind) {
|
||||
let compilerResult: BatchCompileProjectTestCaseResult;
|
||||
|
||||
function getCompilerResolutionInfo() {
|
||||
var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
|
||||
let resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
|
||||
scenario: testCase.scenario,
|
||||
projectRoot: testCase.projectRoot,
|
||||
inputFiles: testCase.inputFiles,
|
||||
@ -357,8 +362,6 @@ class ProjectRunner extends RunnerBase {
|
||||
return resolutionInfo;
|
||||
}
|
||||
|
||||
var compilerResult: BatchCompileProjectTestCaseResult;
|
||||
|
||||
it(name + ": " + moduleNameToString(moduleKind) , () => {
|
||||
// Compile using node
|
||||
compilerResult = batchCompilerProjectTestCase(moduleKind);
|
||||
@ -410,7 +413,7 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
if (!compilerResult.errors.length && testCase.declaration) {
|
||||
var dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||
if (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);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
@ -20,26 +20,26 @@
|
||||
/// <reference path='rwcRunner.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
|
||||
let runners: RunnerBase[] = [];
|
||||
let iterations: number = 1;
|
||||
|
||||
function runTests(runners: RunnerBase[]) {
|
||||
for (var i = iterations; i > 0; i--) {
|
||||
for (var j = 0; j < runners.length; j++) {
|
||||
for (let i = iterations; i > 0; i--) {
|
||||
for (let j = 0; j < runners.length; j++) {
|
||||
runners[j].initializeTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var runners: RunnerBase[] = [];
|
||||
var iterations: number = 1;
|
||||
|
||||
// users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options
|
||||
var mytestconfig = 'mytest.config';
|
||||
var testconfig = 'test.config';
|
||||
var testConfigFile =
|
||||
let mytestconfig = 'mytest.config';
|
||||
let testconfig = 'test.config';
|
||||
let testConfigFile =
|
||||
Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) :
|
||||
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');
|
||||
|
||||
if (testConfigFile !== '') {
|
||||
var testConfig = JSON.parse(testConfigFile);
|
||||
let testConfig = JSON.parse(testConfigFile);
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
}
|
||||
@ -99,7 +99,7 @@ if (runners.length === 0) {
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
//runners.push(new GeneratedFourslashRunner());
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
|
||||
ts.sys.newLine = '\r\n';
|
||||
|
||||
@ -24,17 +24,17 @@ class RunnerBase {
|
||||
|
||||
/** Replaces instances of full paths with fileNames only */
|
||||
static removeFullPaths(path: string) {
|
||||
var fixedPath = path;
|
||||
let fixedPath = path;
|
||||
|
||||
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
|
||||
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
|
||||
var fullPathList = fixedPath.match(fullPath);
|
||||
let fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
|
||||
let fullPathList = fixedPath.match(fullPath);
|
||||
if (fullPathList) {
|
||||
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));
|
||||
}
|
||||
|
||||
// when running in the browser the 'full path' is the host name, shows up in error baselines
|
||||
var localHost = /http:\/localhost:\d+/g;
|
||||
let localHost = /http:\/localhost:\d+/g;
|
||||
fixedPath = fixedPath.replace(localHost, '');
|
||||
return fixedPath;
|
||||
}
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
|
||||
module RWC {
|
||||
function runWithIOLog(ioLog: IOLog, fn: () => void) {
|
||||
var oldSys = ts.sys;
|
||||
let oldSys = ts.sys;
|
||||
|
||||
var wrappedSys = Playback.wrapSystem(ts.sys);
|
||||
let wrappedSys = Playback.wrapSystem(ts.sys);
|
||||
wrappedSys.startReplayFromData(ioLog);
|
||||
ts.sys = wrappedSys;
|
||||
|
||||
@ -21,17 +21,17 @@ module RWC {
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
var inputFiles: { unitName: string; content: string; }[] = [];
|
||||
var otherFiles: { unitName: string; content: string; }[] = [];
|
||||
var compilerResult: Harness.Compiler.CompilerResult;
|
||||
var compilerOptions: ts.CompilerOptions;
|
||||
var baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
let inputFiles: { unitName: string; content: string; }[] = [];
|
||||
let otherFiles: { unitName: string; content: string; }[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
let baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: 'rwc',
|
||||
Baselinefolder: 'internal/baselines'
|
||||
};
|
||||
var baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
var currentDirectory: string;
|
||||
var useCustomLibraryFile: boolean;
|
||||
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.
|
||||
@ -50,10 +50,10 @@ module RWC {
|
||||
});
|
||||
|
||||
it('can compile', () => {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler();
|
||||
var opts: ts.ParsedCommandLine;
|
||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
||||
let opts: ts.ParsedCommandLine;
|
||||
|
||||
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
let ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||
runWithIOLog(ioLog, () => {
|
||||
@ -77,7 +77,7 @@ module RWC {
|
||||
for (let fileRead of ioLog.filesRead) {
|
||||
// Check if the file is already added into the set of input files.
|
||||
var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
|
||||
var inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath);
|
||||
let inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath);
|
||||
|
||||
if (!Harness.isLibraryFile(fileRead.path)) {
|
||||
if (inInputList) {
|
||||
@ -117,9 +117,10 @@ module RWC {
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
var unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName));
|
||||
let unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName));
|
||||
let content: string = null;
|
||||
try {
|
||||
var content = ts.sys.readFile(unitName);
|
||||
content = ts.sys.readFile(unitName);
|
||||
}
|
||||
catch (e) {
|
||||
// Leave content undefined.
|
||||
@ -155,13 +156,13 @@ module RWC {
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
//it('has correct source map record', () => {
|
||||
// if (compilerOptions.sourceMap) {
|
||||
// Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
|
||||
// return compilerResult.getSourceMapRecord();
|
||||
// }, false, baselineOpts);
|
||||
// }
|
||||
//});
|
||||
/*it('has correct source map record', () => {
|
||||
if (compilerOptions.sourceMap) {
|
||||
Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
|
||||
return compilerResult.getSourceMapRecord();
|
||||
}, false, baselineOpts);
|
||||
}
|
||||
});*/
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
|
||||
@ -178,7 +179,7 @@ module RWC {
|
||||
it('has the expected errors in generated declaration files', () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => {
|
||||
var declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||
let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
return null;
|
||||
@ -204,8 +205,8 @@ class RWCRunner extends RunnerBase {
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
var testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||
for (var i = 0; i < testList.length; i++) {
|
||||
let testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||
for (let i = 0; i < testList.length; i++) {
|
||||
this.runTest(testList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
@ -23,12 +23,12 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
module SourceMapDecoder {
|
||||
var sourceMapMappings: string;
|
||||
var sourceMapNames: string[];
|
||||
var decodingIndex: number;
|
||||
var prevNameIndex: number;
|
||||
var decodeOfEncodedMapping: ts.SourceMapSpan;
|
||||
var errorDecodeOfEncodedMapping: string;
|
||||
let sourceMapMappings: string;
|
||||
let sourceMapNames: string[];
|
||||
let decodingIndex: number;
|
||||
let prevNameIndex: number;
|
||||
let decodeOfEncodedMapping: ts.SourceMapSpan;
|
||||
let errorDecodeOfEncodedMapping: string;
|
||||
|
||||
export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapData) {
|
||||
sourceMapMappings = sourceMapData.sourceMapMappings;
|
||||
@ -82,9 +82,9 @@ module Harness.SourceMapRecoder {
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(sourceMapMappings.charAt(decodingIndex));
|
||||
}
|
||||
|
||||
var moreDigits = true;
|
||||
var shiftCount = 0;
|
||||
var value = 0;
|
||||
let moreDigits = true;
|
||||
let shiftCount = 0;
|
||||
let value = 0;
|
||||
|
||||
for (; moreDigits; decodingIndex++) {
|
||||
if (createErrorIfCondition(decodingIndex >= sourceMapMappings.length, "Error in decoding base64VLQFormatDecode, past the mapping string")) {
|
||||
@ -92,7 +92,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
// 6 digit number
|
||||
var currentByte = base64FormatDecode();
|
||||
let currentByte = base64FormatDecode();
|
||||
|
||||
// If msb is set, we still have more bits to continue
|
||||
moreDigits = (currentByte & 32) !== 0;
|
||||
@ -143,7 +143,7 @@ module Harness.SourceMapRecoder {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
|
||||
// 2. Relative sourceIndex
|
||||
// 2. Relative sourceIndex
|
||||
decodeOfEncodedMapping.sourceIndex += base64VLQFormatDecode();
|
||||
// Incorrect sourceIndex dont support this map
|
||||
if (createErrorIfCondition(decodeOfEncodedMapping.sourceIndex < 0, "Invalid sourceIndex found")) {
|
||||
@ -165,7 +165,7 @@ module Harness.SourceMapRecoder {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
|
||||
// 4. Relative sourceColumn 0 based
|
||||
// 4. Relative sourceColumn 0 based
|
||||
decodeOfEncodedMapping.sourceColumn += base64VLQFormatDecode();
|
||||
// Incorrect sourceColumn dont support this map
|
||||
if (createErrorIfCondition(decodeOfEncodedMapping.sourceColumn < 1, "Invalid sourceLine found")) {
|
||||
@ -203,19 +203,19 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
module SourceMapSpanWriter {
|
||||
var sourceMapRecoder: Compiler.WriterAggregator;
|
||||
var sourceMapSources: string[];
|
||||
var sourceMapNames: string[];
|
||||
let sourceMapRecoder: Compiler.WriterAggregator;
|
||||
let sourceMapSources: string[];
|
||||
let sourceMapNames: string[];
|
||||
|
||||
var jsFile: Compiler.GeneratedFile;
|
||||
var jsLineMap: number[];
|
||||
var tsCode: string;
|
||||
var tsLineMap: number[];
|
||||
let jsFile: Compiler.GeneratedFile;
|
||||
let jsLineMap: number[];
|
||||
let tsCode: string;
|
||||
let tsLineMap: number[];
|
||||
|
||||
var spansOnSingleLine: SourceMapSpanWithDecodeErrors[];
|
||||
var prevWrittenSourcePos: number;
|
||||
var prevWrittenJsLine: number;
|
||||
var spanMarkerContinues: boolean;
|
||||
let spansOnSingleLine: SourceMapSpanWithDecodeErrors[];
|
||||
let prevWrittenSourcePos: number;
|
||||
let prevWrittenJsLine: number;
|
||||
let spanMarkerContinues: boolean;
|
||||
|
||||
export function intializeSourceMapSpanWriter(sourceMapRecordWriter: Compiler.WriterAggregator, sourceMapData: ts.SourceMapData, currentJsFile: Compiler.GeneratedFile) {
|
||||
sourceMapRecoder = sourceMapRecordWriter;
|
||||
@ -244,7 +244,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
function getSourceMapSpanString(mapEntry: ts.SourceMapSpan, getAbsentNameIndex?: boolean) {
|
||||
var mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
|
||||
let mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
|
||||
if (mapEntry.nameIndex >= 0 && mapEntry.nameIndex < sourceMapNames.length) {
|
||||
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
|
||||
}
|
||||
@ -259,8 +259,8 @@ module Harness.SourceMapRecoder {
|
||||
|
||||
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
||||
// verify the decoded span is same as the new span
|
||||
var decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
var decodedErrors: string[];
|
||||
let decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
let decodedErrors: string[];
|
||||
if (decodeResult.error
|
||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|
||||
@ -278,7 +278,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) {
|
||||
// On different line from the one that we have been recording till now,
|
||||
// On different line from the one that we have been recording till now,
|
||||
writeRecordedSpans();
|
||||
spansOnSingleLine = [{ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors }];
|
||||
}
|
||||
@ -317,8 +317,8 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
function getTextOfLine(line: number, lineMap: number[], code: string) {
|
||||
var startPos = lineMap[line];
|
||||
var endPos = lineMap[line + 1];
|
||||
let startPos = lineMap[line];
|
||||
let endPos = lineMap[line + 1];
|
||||
return code.substring(startPos, endPos);
|
||||
}
|
||||
|
||||
@ -329,14 +329,16 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
function writeRecordedSpans() {
|
||||
let markerIds: string[] = [];
|
||||
|
||||
function getMarkerId(markerIndex: number) {
|
||||
var markerId = "";
|
||||
let markerId = "";
|
||||
if (spanMarkerContinues) {
|
||||
assert.isTrue(markerIndex === 0);
|
||||
markerId = "1->";
|
||||
}
|
||||
else {
|
||||
var markerId = "" + (markerIndex + 1);
|
||||
markerId = "" + (markerIndex + 1);
|
||||
if (markerId.length < 2) {
|
||||
markerId = markerId + " ";
|
||||
}
|
||||
@ -345,10 +347,10 @@ module Harness.SourceMapRecoder {
|
||||
return markerId;
|
||||
}
|
||||
|
||||
var prevEmittedCol: number;
|
||||
let prevEmittedCol: number;
|
||||
function iterateSpans(fn: (currentSpan: SourceMapSpanWithDecodeErrors, index: number) => void) {
|
||||
prevEmittedCol = 1;
|
||||
for (var i = 0; i < spansOnSingleLine.length; i++) {
|
||||
for (let i = 0; i < spansOnSingleLine.length; i++) {
|
||||
fn(spansOnSingleLine[i], i);
|
||||
prevEmittedCol = spansOnSingleLine[i].sourceMapSpan.emittedColumn;
|
||||
}
|
||||
@ -356,18 +358,18 @@ module Harness.SourceMapRecoder {
|
||||
|
||||
function writeSourceMapIndent(indentLength: number, indentPrefix: string) {
|
||||
sourceMapRecoder.Write(indentPrefix);
|
||||
for (var i = 1; i < indentLength; i++) {
|
||||
for (let i = 1; i < indentLength; i++) {
|
||||
sourceMapRecoder.Write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) {
|
||||
var markerId = getMarkerId(index);
|
||||
let markerId = getMarkerId(index);
|
||||
markerIds.push(markerId);
|
||||
|
||||
writeSourceMapIndent(prevEmittedCol, markerId);
|
||||
|
||||
for (var i = prevEmittedCol; i < endColumn; i++) {
|
||||
for (let i = prevEmittedCol; i < endColumn; i++) {
|
||||
sourceMapRecoder.Write("^");
|
||||
}
|
||||
if (endContinues) {
|
||||
@ -378,8 +380,8 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
|
||||
var sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1);
|
||||
var sourceText = "";
|
||||
let sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1);
|
||||
let sourceText = "";
|
||||
if (prevWrittenSourcePos < sourcePos) {
|
||||
// Position that goes forward, get text
|
||||
sourceText = tsCode.substring(prevWrittenSourcePos, sourcePos);
|
||||
@ -387,14 +389,14 @@ module Harness.SourceMapRecoder {
|
||||
|
||||
if (currentSpan.decodeErrors) {
|
||||
// If there are decode errors, write
|
||||
for (var i = 0; i < currentSpan.decodeErrors.length; i++) {
|
||||
for (let i = 0; i < currentSpan.decodeErrors.length; i++) {
|
||||
writeSourceMapIndent(prevEmittedCol, markerIds[index]);
|
||||
sourceMapRecoder.WriteLine(currentSpan.decodeErrors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var tsCodeLineMap = ts.computeLineStarts(sourceText);
|
||||
for (var i = 0; i < tsCodeLineMap.length; i++) {
|
||||
let tsCodeLineMap = ts.computeLineStarts(sourceText);
|
||||
for (let i = 0; i < tsCodeLineMap.length; i++) {
|
||||
writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >");
|
||||
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
|
||||
if (i === tsCodeLineMap.length - 1) {
|
||||
@ -410,16 +412,15 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
if (spansOnSingleLine.length) {
|
||||
var currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
|
||||
let currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
|
||||
|
||||
// Write js line
|
||||
writeJsFileLines(currentJsLine);
|
||||
|
||||
// Emit markers
|
||||
var markerIds: string[] = [];
|
||||
iterateSpans(writeSourceMapMarker);
|
||||
|
||||
var jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
|
||||
let jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
|
||||
if (prevEmittedCol < jsFileText.length) {
|
||||
// There is remaining text on this line that will be part of next source span so write marker that continues
|
||||
writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
||||
@ -437,16 +438,16 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) {
|
||||
var sourceMapRecoder = new Compiler.WriterAggregator();
|
||||
let sourceMapRecoder = new Compiler.WriterAggregator();
|
||||
|
||||
for (var i = 0; i < sourceMapDataList.length; i++) {
|
||||
var sourceMapData = sourceMapDataList[i];
|
||||
var prevSourceFile: ts.SourceFile = null;
|
||||
for (let i = 0; i < sourceMapDataList.length; i++) {
|
||||
let sourceMapData = sourceMapDataList[i];
|
||||
let prevSourceFile: ts.SourceFile = null;
|
||||
|
||||
SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]);
|
||||
for (var j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
||||
var decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
||||
var currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
||||
let decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
||||
let currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
prevSourceFile = currentSourceFile;
|
||||
@ -455,7 +456,7 @@ module Harness.SourceMapRecoder {
|
||||
SourceMapSpanWriter.recordSourceMapSpan(decodedSourceMapping);
|
||||
}
|
||||
}
|
||||
SourceMapSpanWriter.close();// If the last spans werent emitted, emit them
|
||||
SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them
|
||||
}
|
||||
sourceMapRecoder.Close();
|
||||
return sourceMapRecoder.lines.join('\r\n');
|
||||
|
||||
@ -27,7 +27,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
describe('test262 test for ' + filePath, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
var testState: {
|
||||
let testState: {
|
||||
filename: string;
|
||||
compilerResult: Harness.Compiler.CompilerResult;
|
||||
inputFiles: { unitName: string; content: string }[];
|
||||
@ -35,11 +35,11 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
};
|
||||
|
||||
before(() => {
|
||||
var content = Harness.IO.readFile(filePath);
|
||||
var testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test";
|
||||
var testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||
let content = Harness.IO.readFile(filePath);
|
||||
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test";
|
||||
let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||
|
||||
var inputFiles = testCaseContent.testUnitData.map(unit => {
|
||||
let inputFiles = testCaseContent.testUnitData.map(unit => {
|
||||
return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content };
|
||||
});
|
||||
|
||||
@ -63,14 +63,14 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => {
|
||||
var files = testState.compilerResult.files.filter(f=> f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||
let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||
return Harness.Compiler.collateOutputs(files);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', testState.filename + '.errors.txt', () => {
|
||||
var errors = testState.compilerResult.errors;
|
||||
let errors = testState.compilerResult.errors;
|
||||
if (errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@ -79,14 +79,14 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it('satisfies invariants', () => {
|
||||
var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
it('satisfies inletiants', () => {
|
||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
||||
});
|
||||
|
||||
it('has the expected AST',() => {
|
||||
Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt',() => {
|
||||
var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
it('has the expected AST', () => {
|
||||
Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => {
|
||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
@ -96,7 +96,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
public initializeTests() {
|
||||
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
||||
if (this.tests.length === 0) {
|
||||
var testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true });
|
||||
let testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true });
|
||||
testFiles.forEach(fn => {
|
||||
this.runTest(ts.normalizePath(fn));
|
||||
});
|
||||
@ -105,4 +105,4 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
this.tests.forEach(test => this.runTest(test));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ class TypeWriterWalker {
|
||||
private checker: ts.TypeChecker;
|
||||
|
||||
constructor(private program: ts.Program, fullTypeCheck: boolean) {
|
||||
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
|
||||
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
|
||||
// they are consistent.
|
||||
this.checker = fullTypeCheck
|
||||
? program.getDiagnosticsProducingTypeChecker()
|
||||
@ -21,7 +21,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
public getTypeAndSymbols(fileName: string): TypeWriterResult[] {
|
||||
var sourceFile = this.program.getSourceFile(fileName);
|
||||
let sourceFile = this.program.getSourceFile(fileName);
|
||||
this.currentSourceFile = sourceFile;
|
||||
this.results = [];
|
||||
this.visitNode(sourceFile);
|
||||
@ -37,19 +37,19 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
private logTypeAndSymbol(node: ts.Node): void {
|
||||
var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||
let actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
let lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
let sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||
|
||||
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
|
||||
// var type = this.checker.getTypeAtLocation(node);
|
||||
var type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
|
||||
// let type = this.checker.getTypeAtLocation(node);
|
||||
let type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
|
||||
|
||||
ts.Debug.assert(type !== undefined, "type doesn't exist");
|
||||
var symbol = this.checker.getSymbolAtLocation(node);
|
||||
let symbol = this.checker.getSymbolAtLocation(node);
|
||||
|
||||
var typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation);
|
||||
var symbolString: string;
|
||||
let typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation);
|
||||
let symbolString: string;
|
||||
if (symbol) {
|
||||
symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent);
|
||||
if (symbol.declarations) {
|
||||
@ -57,7 +57,7 @@ class TypeWriterWalker {
|
||||
symbolString += ", ";
|
||||
let declSourceFile = declaration.getSourceFile();
|
||||
let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
|
||||
symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })`
|
||||
symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })`;
|
||||
}
|
||||
}
|
||||
symbolString += ")";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user