Lint unit tests via harnessSources in Jakefile.js

This commit is contained in:
Nathan Shively-Sanders 2016-05-24 10:17:16 -07:00
parent 92d465d01f
commit 3d841b20a7
18 changed files with 925 additions and 913 deletions

View File

@ -974,7 +974,7 @@ var servicesLintTargets = [
return path.join(servicesDirectory, s);
});
var lintTargets = compilerSources
.concat(harnessCoreSources)
.concat(harnessSources)
// Other harness sources
.concat(["instrumenter.ts"].map(function(f) { return path.join(harnessDirectory, f) }))
.concat(serverCoreSources)

View File

@ -7,7 +7,7 @@ namespace ts {
}
function createDefaultServerHost(fileMap: Map<File>): server.ServerHost {
let existingDirectories: Map<boolean> = {};
const existingDirectories: Map<boolean> = {};
forEachValue(fileMap, v => {
let dir = getDirectoryPath(v.name);
let previous: string;
@ -67,7 +67,7 @@ namespace ts {
}
function createProject(rootFile: string, serverHost: server.ServerHost): { project: server.Project, rootScriptInfo: server.ScriptInfo } {
let logger: server.Logger = {
const logger: server.Logger = {
close() { },
isVerbose: () => false,
loggingEnabled: () => false,
@ -78,9 +78,9 @@ namespace ts {
msg: (s: string, type?: string) => { }
};
let projectService = new server.ProjectService(serverHost, logger);
let rootScriptInfo = projectService.openFile(rootFile, /* openedByClient */true);
let project = projectService.createInferredProject(rootScriptInfo);
const projectService = new server.ProjectService(serverHost, logger);
const rootScriptInfo = projectService.openFile(rootFile, /* openedByClient */true);
const project = projectService.createInferredProject(rootScriptInfo);
project.setProjectOptions({ files: [rootScriptInfo.fileName], compilerOptions: { module: ts.ModuleKind.AMD } });
return {
project,
@ -90,24 +90,24 @@ namespace ts {
describe("Caching in LSHost", () => {
it("works using legacy resolution logic", () => {
let root: File = {
const root: File = {
name: "c:/d/f0.ts",
content: `import {x} from "f1"`
};
let imported: File = {
const imported: File = {
name: "c:/f1.ts",
content: `foo()`
};
let serverHost = createDefaultServerHost({ [root.name]: root, [imported.name]: imported });
let { project, rootScriptInfo } = createProject(root.name, serverHost);
const serverHost = createDefaultServerHost({ [root.name]: root, [imported.name]: imported });
const { project, rootScriptInfo } = createProject(root.name, serverHost);
// ensure that imported file was found
let diags = project.compilerService.languageService.getSemanticDiagnostics(imported.name);
assert.equal(diags.length, 1);
let originalFileExists = serverHost.fileExists;
const originalFileExists = serverHost.fileExists;
{
// patch fileExists to make sure that disk is not touched
serverHost.fileExists = (fileName): boolean => {
@ -115,7 +115,7 @@ namespace ts {
return false;
};
let newContent = `import {x} from "f1"
const newContent = `import {x} from "f1"
var x: string = 1;`;
rootScriptInfo.editContent(0, rootScriptInfo.content.length, newContent);
// trigger synchronization to make sure that import will be fetched from the cache
@ -133,7 +133,7 @@ namespace ts {
assert.isTrue(fileName.indexOf("/f2.") !== -1);
return originalFileExists.call(serverHost, fileName);
};
let newContent = `import {x} from "f2"`;
const newContent = `import {x} from "f2"`;
rootScriptInfo.editContent(0, rootScriptInfo.content.length, newContent);
try {
@ -157,7 +157,7 @@ namespace ts {
return originalFileExists.call(serverHost, fileName);
};
let newContent = `import {x} from "f1"`;
const newContent = `import {x} from "f1"`;
rootScriptInfo.editContent(0, rootScriptInfo.content.length, newContent);
project.compilerService.languageService.getSemanticDiagnostics(imported.name);
assert.isTrue(fileExistsCalled);
@ -165,7 +165,7 @@ namespace ts {
// setting compiler options discards module resolution cache
fileExistsCalled = false;
let opts = ts.clone(project.projectOptions);
const opts = ts.clone(project.projectOptions);
opts.compilerOptions = ts.clone(opts.compilerOptions);
opts.compilerOptions.target = ts.ScriptTarget.ES5;
project.setProjectOptions(opts);
@ -176,19 +176,19 @@ namespace ts {
});
it("loads missing files from disk", () => {
let root: File = {
const root: File = {
name: `c:/foo.ts`,
content: `import {x} from "bar"`
};
let imported: File = {
const imported: File = {
name: `c:/bar.d.ts`,
content: `export var y = 1`
};
let fileMap: Map<File> = { [root.name]: root };
let serverHost = createDefaultServerHost(fileMap);
let originalFileExists = serverHost.fileExists;
const fileMap: Map<File> = { [root.name]: root };
const serverHost = createDefaultServerHost(fileMap);
const originalFileExists = serverHost.fileExists;
let fileExistsCalledForBar = false;
serverHost.fileExists = fileName => {
@ -202,7 +202,7 @@ namespace ts {
return originalFileExists.call(serverHost, fileName);
};
let { project, rootScriptInfo } = createProject(root.name, serverHost);
const { project, rootScriptInfo } = createProject(root.name, serverHost);
let diags = project.compilerService.languageService.getSemanticDiagnostics(root.name);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
@ -219,4 +219,4 @@ namespace ts {
assert.isTrue(diags.length === 0);
});
});
}
}

View File

@ -2,7 +2,7 @@
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
namespace ts {
describe('parseCommandLine', () => {
describe("parseCommandLine", () => {
function assertParseResult(commandLine: string[], expectedParsedCommandLine: ts.ParsedCommandLine) {
const parsed = ts.parseCommandLine(commandLine);
@ -13,9 +13,9 @@ namespace ts {
const parsedErrors = parsed.errors;
const expectedErrors = expectedParsedCommandLine.errors;
assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
for (let i = 0; i < parsedErrors.length; ++i) {
for (let i = 0; i < parsedErrors.length; i++) {
const parsedError = parsedErrors[i];
const expectedError = expectedErrors[i];
const expectedError = expectedErrors[i];
assert.equal(parsedError.code, expectedError.code);
assert.equal(parsedError.category, expectedError.category);
assert.equal(parsedError.messageText, expectedError.messageText);
@ -24,9 +24,9 @@ namespace ts {
const parsedFileNames = parsed.fileNames;
const expectedFileNames = expectedParsedCommandLine.fileNames;
assert.isTrue(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
for (let i = 0; i < parsedFileNames.length; ++i) {
for (let i = 0; i < parsedFileNames.length; i++) {
const parsedFileName = parsedFileNames[i];
const expectedFileName = expectedFileNames[i];
const expectedFileName = expectedFileNames[i];
assert.equal(parsedFileName, expectedFileName);
}
}
@ -113,7 +113,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,

View File

@ -2,25 +2,25 @@
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
namespace ts {
describe('convertCompilerOptionsFromJson', () => {
describe("convertCompilerOptionsFromJson", () => {
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json["compilerOptions"], "/apath/", configFileName);
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
for (let i = 0; i < actualErrors.length; ++i) {
for (let i = 0; i < actualErrors.length; i++) {
const actualError = actualErrors[i];
const expectedError = expectedErrors[i];
const expectedError = expectedErrors[i];
assert.equal(actualError.code, expectedError.code);
assert.equal(actualError.category, expectedError.category);
assert.equal(actualError.messageText, expectedError.messageText);
}
}
// tsconfig.json tests
it("Convert correctly format tsconfig.json to compiler-options ", () => {
assertCompilerOptions(
@ -448,7 +448,7 @@ namespace ts {
}
}, "jsconfig.json",
{
compilerOptions:
compilerOptions:
{
allowJs: true
},
@ -467,7 +467,7 @@ namespace ts {
it("Convert default jsconfig.json to compiler-options ", () => {
assertCompilerOptions({}, "jsconfig.json",
{
compilerOptions:
compilerOptions:
{
allowJs: true
},

View File

@ -1,10 +1,10 @@
/// <reference path="..\..\..\src\harness\harness.ts" />
module ts {
describe('convertToBase64', () => {
namespace ts {
describe("convertToBase64", () => {
function runTest(input: string): void {
var actual = ts.convertToBase64(input);
var expected = new Buffer(input).toString("base64");
const actual = ts.convertToBase64(input);
const expected = new Buffer(input).toString("base64");
assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')");
}

View File

@ -2,18 +2,18 @@
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
namespace ts {
describe('convertTypingOptionsFromJson', () => {
describe("convertTypingOptionsFromJson", () => {
function assertTypingOptions(json: any, configFileName: string, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) {
const { options: actualTypingOptions, errors: actualErrors } = convertTypingOptionsFromJson(json["typingOptions"], "/apath/", configFileName);
const parsedTypingOptions = JSON.stringify(actualTypingOptions);
const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions);
assert.equal(parsedTypingOptions, expectedTypingOptions);
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
for (let i = 0; i < actualErrors.length; ++i) {
for (let i = 0; i < actualErrors.length; i++) {
const actualError = actualErrors[i];
const expectedError = expectedErrors[i];
const expectedError = expectedErrors[i];
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
}
@ -41,7 +41,7 @@ namespace ts {
errors: <Diagnostic[]>[]
});
});
it("Convert incorrect format tsconfig.json to typing-options ", () => {
assertTypingOptions(
{

File diff suppressed because it is too large Load Diff

View File

@ -3,20 +3,20 @@
/// <reference path="..\..\..\src\compiler\parser.ts" />
/// <reference path="..\..\..\src\harness\harness.ts" />
module ts {
namespace ts {
describe("JSDocParsing", () => {
describe("TypeExpressions", () => {
function parsesCorrectly(content: string, expected: string) {
let typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content);
const typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content);
assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0);
let result = Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type);
const result = Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type);
assert.equal(result, expected);
}
function parsesIncorrectly(content: string) {
let type = ts.parseJSDocTypeExpressionForTests(content);
const type = ts.parseJSDocTypeExpressionForTests(content);
assert.isTrue(!type || type.diagnostics.length > 0);
}
@ -50,7 +50,7 @@ module ts {
"pos": 2,
"end": 8
}
}`)
}`);
});
it("nullableType2", () => {
@ -64,7 +64,7 @@ module ts {
"pos": 1,
"end": 7
}
}`)
}`);
});
it("nonNullableType", () => {
@ -78,7 +78,7 @@ module ts {
"pos": 2,
"end": 8
}
}`)
}`);
});
it("nonNullableType2", () => {
@ -92,7 +92,7 @@ module ts {
"pos": 1,
"end": 7
}
}`)
}`);
});
it("recordType1", () => {
@ -106,7 +106,7 @@ module ts {
"pos": 2,
"end": 2
}
}`)
}`);
});
it("recordType2", () => {
@ -131,7 +131,7 @@ module ts {
"pos": 2,
"end": 5
}
}`)
}`);
});
it("recordType3", () => {
@ -161,7 +161,7 @@ module ts {
"pos": 2,
"end": 13
}
}`)
}`);
});
it("recordType4", () => {
@ -197,7 +197,7 @@ module ts {
"pos": 2,
"end": 10
}
}`)
}`);
});
it("recordType5", () => {
@ -238,7 +238,7 @@ module ts {
"pos": 2,
"end": 18
}
}`)
}`);
});
it("recordType6", () => {
@ -279,7 +279,7 @@ module ts {
"pos": 2,
"end": 18
}
}`)
}`);
});
it("recordType7", () => {
@ -325,7 +325,7 @@ module ts {
"pos": 2,
"end": 26
}
}`)
}`);
});
it("recordType8", () => {
@ -351,7 +351,7 @@ module ts {
"pos": 2,
"end": 10
}
}`)
}`);
});
it("unionType", () => {
@ -987,15 +987,15 @@ module ts {
describe("DocComments", () => {
function parsesCorrectly(content: string, expected: string) {
let comment = parseIsolatedJSDocComment(content);
const comment = parseIsolatedJSDocComment(content);
if (!comment) {
Debug.fail('Comment failed to parse entirely');
Debug.fail("Comment failed to parse entirely");
}
if (comment.diagnostics.length > 0) {
Debug.fail('Comment has at least one diagnostic: ' + comment.diagnostics[0].messageText);
Debug.fail("Comment has at least one diagnostic: " + comment.diagnostics[0].messageText);
}
let result = JSON.stringify(comment.jsDocComment, (k, v) => {
const result = JSON.stringify(comment.jsDocComment, (k, v) => {
return v && v.pos !== undefined
? JSON.parse(Utils.sourceFileToJSON(v))
: v;
@ -1003,8 +1003,8 @@ module ts {
if (result !== expected) {
// Turn on a human-readable diff
if (typeof require !== 'undefined') {
require('chai').config.showDiff = true;
if (typeof require !== "undefined") {
require("chai").config.showDiff = true;
chai.expect(JSON.parse(result)).equal(JSON.parse(expected));
}
else {
@ -1014,7 +1014,7 @@ module ts {
}
function parsesIncorrectly(content: string) {
let type = parseIsolatedJSDocComment(content);
const type = parseIsolatedJSDocComment(content);
assert.isTrue(!type || type.diagnostics.length > 0);
}
@ -1034,7 +1034,7 @@ module ts {
it("multipleTypes", () => {
parsesIncorrectly(
`/**
* @type {number}
* @type {number}
* @type {string}
*/`);
});
@ -1071,7 +1071,7 @@ module ts {
it("paramWithoutTypeOrName", () => {
parsesIncorrectly(
`/**
* @param
* @param
*/`);
});
});
@ -2218,4 +2218,4 @@ module ts {
});
});
});
}
}

View File

@ -2,32 +2,34 @@
/// <reference path='..\..\..\src\harness\harness.ts' />
declare namespace chai.assert {
/* tslint:disable no-unused-variable */
function deepEqual(actual: any, expected: any): void;
/* tslint:enable no-unused-variable */
}
module ts {
namespace ts {
function diagnosticToString(diagnostic: Diagnostic) {
let output = "";
if (diagnostic.file) {
let loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
const loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
output += `${diagnostic.file.fileName}(${loc.line + 1},${loc.character + 1}): `;
}
let category = DiagnosticCategory[diagnostic.category].toLowerCase();
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
output += `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine)}${sys.newLine}`;
return output;
}
interface File {
name: string
content?: string
name: string;
content?: string;
}
function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ModuleResolutionHost {
let map = arrayToMap(files, f => f.name);
const map = arrayToMap(files, f => f.name);
if (hasDirectoryExists) {
const directories: Map<string> = {};
@ -35,7 +37,7 @@ module ts {
let name = getDirectoryPath(f.name);
while (true) {
directories[name] = name;
let baseName = getDirectoryPath(name);
const baseName = getDirectoryPath(name);
if (baseName === name) {
break;
}
@ -44,14 +46,14 @@ module ts {
}
return {
readFile,
directoryExists: path => {
return hasProperty(directories, path);
directoryExists: path => {
return hasProperty(directories, path);
},
fileExists: path => {
assert.isTrue(hasProperty(directories, getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
return hasProperty(map, path);
}
}
};
}
else {
return { readFile, fileExists: path => hasProperty(map, path), };
@ -61,31 +63,24 @@ module ts {
}
}
function splitPath(path: string): { dir: string; rel: string } {
let index = path.indexOf(directorySeparator);
return index === -1
? { dir: path, rel: undefined }
: { dir: path.substr(0, index), rel: path.substr(index + 1) };
}
describe("Node module resolution - relative paths", () => {
function testLoadAsFile(containingFileName: string, moduleFileNameNoExt: string, moduleName: string): void {
for (let ext of supportedTypeScriptExtensions) {
for (const ext of supportedTypeScriptExtensions) {
test(ext, /*hasDirectoryExists*/ false);
test(ext, /*hasDirectoryExists*/ true);
}
function test(ext: string, hasDirectoryExists: boolean) {
let containingFile = { name: containingFileName }
let moduleFile = { name: moduleFileNameNoExt + ext }
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
const containingFile = { name: containingFileName };
const moduleFile = { name: moduleFileNameNoExt + ext };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
let failedLookupLocations: string[] = [];
let dir = getDirectoryPath(containingFileName);
for (let e of supportedTypeScriptExtensions) {
const failedLookupLocations: string[] = [];
const dir = getDirectoryPath(containingFileName);
for (const e of supportedTypeScriptExtensions) {
if (e === ext) {
break;
}
@ -120,10 +115,10 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: containingFileName };
let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
let moduleFile = { name: moduleFileName };
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
const containingFile = { name: containingFileName };
const packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
const moduleFile = { name: moduleFileName };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
// expect three failed lookup location - attempt to load module as file with all supported extensions
@ -143,14 +138,14 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: "/a/b.ts" };
let packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
let moduleFile = { name: "/a/b.d.ts" };
const containingFile = { name: "/a/b.ts" };
const packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
const moduleFile = { name: "/a/b.d.ts" };
let indexPath = "/node_modules/b/index.d.ts";
let indexFile = { name: indexPath }
const indexPath = "/node_modules/b/index.d.ts";
const indexFile = { name: indexPath };
let resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
}
@ -160,7 +155,9 @@ module ts {
testTypingsIgnored(["a", "b"]);
testTypingsIgnored({ "a": "b" });
testTypingsIgnored(true);
/* tslint:disable no-null-keyword */
testTypingsIgnored(null);
/* tslint:enable no-null-keyword */
testTypingsIgnored(undefined);
});
@ -169,10 +166,10 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: "/a/b/c.ts" };
let packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
let indexFile = { name: "/a/b/foo/index.d.ts" };
let resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
const containingFile = { name: "/a/b/c.ts" };
const packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
const indexFile = { name: "/a/b/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
assert.deepEqual(resolution.failedLookupLocations, [
@ -192,9 +189,9 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: "/a/b/c/d/e.ts" };
let moduleFile = { name: "/a/b/node_modules/foo.ts" };
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.deepEqual(resolution.failedLookupLocations, [
"/a/b/c/d/node_modules/foo.ts",
@ -225,7 +222,7 @@ module ts {
"/a/b/c/node_modules/@types/foo/index.ts",
"/a/b/c/node_modules/@types/foo/index.tsx",
"/a/b/c/node_modules/@types/foo/index.d.ts",
])
]);
}
});
@ -234,9 +231,9 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: "/a/b/c/d/e.ts" };
let moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
}
@ -247,9 +244,9 @@ module ts {
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
let moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
const containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
const moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
assert.deepEqual(resolution.failedLookupLocations, [
@ -311,7 +308,7 @@ module ts {
const options: CompilerOptions = { module: ModuleKind.CommonJS };
const host: CompilerHost = {
getSourceFile: (fileName: string, languageVersion: ScriptTarget) => {
let path = normalizePath(combinePaths(currentDirectory, fileName));
const path = normalizePath(combinePaths(currentDirectory, fileName));
return hasProperty(files, path) ? createSourceFile(fileName, files[path], languageVersion) : undefined;
},
getDefaultLibFileName: () => "lib.d.ts",
@ -321,7 +318,7 @@ module ts {
getNewLine: () => "\r\n",
useCaseSensitiveFileNames: () => false,
fileExists: fileName => {
let path = normalizePath(combinePaths(currentDirectory, fileName));
const path = normalizePath(combinePaths(currentDirectory, fileName));
return hasProperty(files, path);
},
readFile: (fileName): string => { throw new Error("NotImplemented"); }
@ -359,13 +356,13 @@ export = C;
};
test(files, "/a/b/c/first/second", ["class_a.ts"], 3, ["../../../c/third/class_c.ts"]);
});
it("should find modules in node_modules", () => {
const files: Map<string> = {
"/parent/node_modules/mod/index.d.ts": "export var x",
"/parent/app/myapp.ts": `import {x} from "mod"`
};
test(files, "/parent/app",["myapp.ts"], 2, []);
test(files, "/parent/app", ["myapp.ts"], 2, []);
});
it("should find file referenced via absolute and relative names", () => {
@ -376,14 +373,14 @@ export = C;
test(files, "/a/b", ["c.ts", "/a/b/b.ts"], 2, []);
});
});
describe("Files with different casing", () => {
const library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5);
function test(files: Map<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
if (!useCaseSensitiveFileNames) {
let f: Map<string> = {};
for (let fileName in files) {
const f: Map<string> = {};
for (const fileName in files) {
f[getCanonicalFileName(fileName)] = files[fileName];
}
files = f;
@ -394,7 +391,7 @@ export = C;
if (fileName === "lib.d.ts") {
return library;
}
let path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
return hasProperty(files, path) ? createSourceFile(fileName, files[path], languageVersion) : undefined;
},
getDefaultLibFileName: () => "lib.d.ts",
@ -404,7 +401,7 @@ export = C;
getNewLine: () => "\r\n",
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
fileExists: fileName => {
let path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
return hasProperty(files, path);
},
readFile: (fileName): string => { throw new Error("NotImplemented"); }
@ -412,7 +409,7 @@ export = C;
const program = createProgram(rootFiles, options, host);
const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics().concat(program.getOptionsDiagnostics()));
assert.equal(diagnostics.length, diagnosticCodes.length, `Incorrect number of expected diagnostics, expected ${diagnosticCodes.length}, got '${map(diagnostics, diagnosticToString).join("\r\n")}'`);
for (let i = 0; i < diagnosticCodes.length; ++i) {
for (let i = 0; i < diagnosticCodes.length; i++) {
assert.equal(diagnostics[i].code, diagnosticCodes[i], `Expected diagnostic code ${diagnosticCodes[i]}, got '${diagnostics[i].code}': '${diagnostics[i].messageText}'`);
}
}
@ -422,7 +419,7 @@ export = C;
"/a/b/c.ts": `/// <reference path="d.ts"/>`,
"/a/b/d.ts": "var x"
};
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /* useCaseSensitiveFileNames */ false, ["c.ts", "/a/b/d.ts"], []);
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []);
});
it("should fail when two files used in program differ only in casing (tripleslash references)", () => {
@ -430,7 +427,7 @@ export = C;
"/a/b/c.ts": `/// <reference path="D.ts"/>`,
"/a/b/d.ts": "var x"
};
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /* useCaseSensitiveFileNames */ false, ["c.ts", "d.ts"], [1149]);
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]);
});
it("should fail when two files used in program differ only in casing (imports)", () => {
@ -438,7 +435,7 @@ export = C;
"/a/b/c.ts": `import {x} from "D"`,
"/a/b/d.ts": "export var x"
};
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /* useCaseSensitiveFileNames */ false, ["c.ts", "d.ts"], [1149]);
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]);
});
it("should fail when two files used in program differ only in casing (imports, relative module names)", () => {
@ -446,7 +443,7 @@ export = C;
"moduleA.ts": `import {x} from "./ModuleB"`,
"moduleB.ts": "export var x"
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /* useCaseSensitiveFileNames */ false, ["moduleA.ts", "moduleB.ts"], [1149]);
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]);
});
it("should fail when two files exist on disk that differs only in casing", () => {
@ -455,7 +452,7 @@ export = C;
"/a/b/D.ts": "export var x",
"/a/b/d.ts": "export var y"
};
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /* useCaseSensitiveFileNames */ true, ["c.ts", "d.ts"], [1149]);
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]);
});
it("should fail when module name in 'require' calls has inconsistent casing", () => {
@ -464,7 +461,7 @@ export = C;
"moduleB.ts": `import a = require("./moduleC")`,
"moduleC.ts": "export var x"
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /* useCaseSensitiveFileNames */ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]);
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]);
});
it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => {
@ -477,7 +474,7 @@ import a = require("./moduleA.ts");
import b = require("./moduleB.ts");
`
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], [1149]);
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]);
});
it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => {
const files: Map<string> = {
@ -489,8 +486,8 @@ import a = require("./moduleA.ts");
import b = require("./moduleB.ts");
`
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], []);
})
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []);
});
});
describe("baseUrl augmented module resolution", () => {
@ -528,7 +525,7 @@ import b = require("./moduleB.ts");
}
// add failure tests
});
it("node + baseUrl", () => {
test(/*hasDirectoryExists*/ false);
test(/*hasDirectoryExists*/ true);
@ -538,7 +535,7 @@ import b = require("./moduleB.ts");
const m1: File = { name: "/root/m1.ts" }; // load file as module
const m2: File = { name: "/root/m2/index.d.ts" }; // load folder as module
const m3: File = { name: "/root/m3/package.json", content: JSON.stringify({ typings: "dist/typings.d.ts" }) };
const m3Typings: File = { name: "/root/m3/dist/typings.d.ts" };
const m3Typings: File = { name: "/root/m3/dist/typings.d.ts" };
const m4: File = { name: "/root/node_modules/m4.ts" }; // fallback to node
const options: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs, baseUrl: "/root" };
@ -548,13 +545,13 @@ import b = require("./moduleB.ts");
check("m2", main, m2);
check("m3", main, m3Typings);
check("m4", main, m4);
function check(name: string, caller: File, expected: File) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
}
}
}
});
it("classic + baseUrl", () => {
@ -571,14 +568,14 @@ import b = require("./moduleB.ts");
check("m1", main, m1);
check("m2", main, m2);
function check(name: string, caller: File, expected: File) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
}
}
})
}
});
it("node + baseUrl + path mappings", () => {
test(/*hasDirectoryExists*/ false);
@ -586,16 +583,16 @@ import b = require("./moduleB.ts");
function test(hasDirectoryExists: boolean) {
const main: File = { name: "/root/folder1/main.ts" };
const file1: File = { name: "/root/folder1/file1.ts" };
const file2: File = { name: "/root/generated/folder1/file2.ts" } // load remapped file as module
const file3: File = { name: "/root/generated/folder2/file3/index.d.ts" } // load folder a module
const file2: File = { name: "/root/generated/folder1/file2.ts" }; // load remapped file as module
const file3: File = { name: "/root/generated/folder2/file3/index.d.ts" }; // load folder a module
const file4Typings: File = { name: "/root/generated/folder2/file4/package.json", content: JSON.stringify({ typings: "dist/types.d.ts" })};
const file4: File = { name: "/root/generated/folder2/file4/dist/types.d.ts" }; // load file pointed by typings
const file5: File = { name: "/root/someanotherfolder/file5/index.d.ts" } // load remapped module from folder
const file5: File = { name: "/root/someanotherfolder/file5/index.d.ts" }; // load remapped module from folder
const file6: File = { name: "/root/node_modules/file6.ts" }; // fallback to node
const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3, file4, file4Typings, file5, file6);
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.NodeJs,
baseUrl: "/root",
@ -723,12 +720,12 @@ import b = require("./moduleB.ts");
function test(hasDirectoryExists: boolean) {
const main: File = { name: "/root/folder1/main.ts" };
const file1: File = { name: "/root/folder1/file1.ts" };
const file2: File = { name: "/root/generated/folder1/file2.ts" };
const file3: File = { name: "/folder1/file3.ts" }; // fallback to classic
const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3);
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.Classic,
baseUrl: "/root",
@ -776,17 +773,17 @@ import b = require("./moduleB.ts");
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
}
}
})
});
it ("node + rootDirs", () => {
test(/*hasDirectoryExists*/ false);
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
let file1: File = { name: "/root/folder1/file1.ts" };
let file1_1: File = { name: "/root/folder1/file1_1/index.d.ts" };
let file2: File = { name: "/root/generated/folder1/file2.ts" };
let file3: File = { name: "/root/generated/folder2/file3.ts" };
const file1: File = { name: "/root/folder1/file1.ts" };
const file1_1: File = { name: "/root/folder1/file1_1/index.d.ts" };
const file2: File = { name: "/root/generated/folder1/file2.ts" };
const file3: File = { name: "/root/generated/folder2/file3.ts" };
const host = createModuleResolutionHost(hasDirectoryExists, file1, file1_1, file2, file3);
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.NodeJs,
@ -848,7 +845,7 @@ import b = require("./moduleB.ts");
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations,expectedFailedLookups);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
}
}
});
@ -857,10 +854,10 @@ import b = require("./moduleB.ts");
test(/*hasDirectoryExists*/ false);
function test(hasDirectoryExists: boolean) {
let file1: File = { name: "/root/folder1/file1.ts" };
let file2: File = { name: "/root/generated/folder1/file2.ts" };
let file3: File = { name: "/root/generated/folder2/file3.ts" };
let file4: File = { name: "/folder1/file1_1.ts" };
const file1: File = { name: "/root/folder1/file1.ts" };
const file2: File = { name: "/root/generated/folder1/file2.ts" };
const file3: File = { name: "/root/generated/folder2/file3.ts" };
const file4: File = { name: "/folder1/file1_1.ts" };
const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3, file4);
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.Classic,
@ -904,7 +901,7 @@ import b = require("./moduleB.ts");
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations,expectedFailedLookups);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
}
}
});
@ -914,12 +911,12 @@ import b = require("./moduleB.ts");
test(/*hasDirectoryExists*/ true);
function test(hasDirectoryExists: boolean) {
const app: File = { name: "/root/src/app.ts" }
const app: File = { name: "/root/src/app.ts" };
const libsPackage: File = { name: "/root/src/libs/guid/package.json", content: JSON.stringify({ typings: "dist/guid.d.ts" }) };
const libsTypings: File = { name: "/root/src/libs/guid/dist/guid.d.ts" };
const host = createModuleResolutionHost(hasDirectoryExists, app, libsPackage, libsTypings);
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.NodeJs,
const options: CompilerOptions = {
moduleResolution: ModuleResolutionKind.NodeJs,
baseUrl: "/root",
paths: {
"libs/guid": [ "src/libs/guid" ]
@ -935,7 +932,7 @@ import b = require("./moduleB.ts");
"/root/src/libs/guid.d.ts",
]);
}
})
});
});
function notImplemented(name: string): () => any {
@ -957,7 +954,7 @@ import b = require("./moduleB.ts");
describe("Type reference directive resolution: ", () => {
function test(typesRoot: string, typeDirective: string, primary: boolean, initialFile: File, targetFile: File, ...otherFiles: File[]) {
const host = createModuleResolutionHost(false, ...[initialFile, targetFile].concat(...otherFiles));
const host = createModuleResolutionHost(/*hasDirectoryExists*/ false, ...[initialFile, targetFile].concat(...otherFiles));
const result = resolveTypeReferenceDirective(typeDirective, initialFile.name, {typesRoot}, host);
assert(result.resolvedTypeReferenceDirective.resolvedFileName !== undefined, "expected type directive to be resolved");
assert.equal(result.resolvedTypeReferenceDirective.resolvedFileName, targetFile.name, "unexpected result of type reference resolution");
@ -966,63 +963,63 @@ import b = require("./moduleB.ts");
it("Can be resolved from primary location", () => {
{
const f1 = { name: "/root/src/app.ts" }
const f2 = { name: "/root/src/types/lib/index.d.ts" };
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/types/lib/index.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/types/lib/typings/lib.d.ts" };
const package = { name: "/root/src/types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
const package = { name: "/root/src/types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package);
}
{
const f1 = { name: "/root/src/app.ts" }
const f2 = { name: "/root/src/node_modules/lib/index.d.ts" };
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/node_modules/lib/index.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/node_modules/lib/typings/lib.d.ts" };
const package = { name: "/root/src/node_modules/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
const package = { name: "/root/src/node_modules/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package);
}
{
const f1 = { name: "/root/src/app.ts" }
const f2 = { name: "/root/src/node_modules/@types/lib/index.d.ts" };
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/node_modules/@types/lib/index.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/src/node_modules/@types/lib/typings/lib.d.ts" };
const package = { name: "/root/src/node_modules/@types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
const package = { name: "/root/src/node_modules/@types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package);
}
});
it("Can be resolved from secondary location", () => {
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/node_modules/lib.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/node_modules/lib/index.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/node_modules/lib/typings/lib.d.ts" };
const package = { name: "/root/node_modules/lib/package.json", content: JSON.stringify({typings: "typings/lib.d.ts"}) };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/node_modules/@types/lib/index.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2);
}
{
const f1 = { name: "/root/src/app.ts" }
const f1 = { name: "/root/src/app.ts" };
const f2 = { name: "/root/node_modules/@types/lib/typings/lib.d.ts" };
const package = { name: "/root/node_modules/@types/lib/package.json", content: JSON.stringify({typings: "typings/lib.d.ts"}) };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
@ -1032,17 +1029,17 @@ import b = require("./moduleB.ts");
{
const f1 = { name: "/root/src/a/b/c/app.ts" };
const f2 = { name: "/root/src/types/lib/index.d.ts" };
const f3 = { name: "/root/src/a/b/node_modules/lib.d.ts" }
const f3 = { name: "/root/src/a/b/node_modules/lib.d.ts" };
test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, f3);
}
})
});
it("Reused program keeps errors", () => {
const f1 = { name: "/root/src/a/b/c/d/e/app.ts", content: `/// <reference types="lib"/>` };
const f2 = { name: "/root/src/a/b/c/d/node_modules/lib/index.d.ts", content: `declare var x: number;` };
const f3 = { name: "/root/src/a/b/c/d/f/g/app.ts", content: `/// <reference types="lib"/>` };
const f4 = { name: "/root/src/a/b/c/d/f/node_modules/lib/index.d.ts", content: `declare var x: number;` };
const files = [f1, f2, f3, f4];
const names = map(files, f => f.name);
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName);
const compilerHost: CompilerHost = {
@ -1062,11 +1059,13 @@ import b = require("./moduleB.ts");
const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics();
assert.equal(diagnostics1.length, 1, "expected one diagnostic");
/* tslint:disable no-unused-variable */
const program2 = createProgram(names, {}, compilerHost, program1);
/* tslint:enable no-unused-variable */
assert.isTrue(program1.structureIsReused);
const diagnostics2 = program1.getFileProcessingDiagnostics().getDiagnostics();
assert.equal(diagnostics2.length, 1, "expected one diagnostic");
assert.equal(diagnostics1[0].messageText, diagnostics2[0].messageText, "expected one diagnostic");
})
});
});
}
}

View File

@ -2,7 +2,7 @@
/// <reference path='..\..\..\src\harness\harness.ts' />
/// <reference path="..\..\..\src\harness\harnessLanguageService.ts" />
module ts {
namespace ts {
const enum ChangedPart {
references = 1 << 0,
@ -10,7 +10,7 @@ module ts {
program = 1 << 2
}
let newLine = "\r\n";
const newLine = "\r\n";
interface SourceFileWithText extends SourceFile {
sourceText?: SourceText;
@ -18,7 +18,7 @@ module ts {
interface NamedSourceText {
name: string;
text: SourceText
text: SourceText;
}
interface ProgramWithSourceTexts extends Program {
@ -72,9 +72,9 @@ module ts {
}
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
var oldText = <SourceText>oldSnapshot;
var oldSpan: TextSpan;
var newLength: number;
const oldText = <SourceText>oldSnapshot;
let oldSpan: TextSpan;
let newLength: number;
switch (oldText.changedPart ^ this.changedPart) {
case ChangedPart.references:
oldSpan = createTextSpan(0, oldText.references.length);
@ -82,7 +82,7 @@ module ts {
break;
case ChangedPart.importsAndExports:
oldSpan = createTextSpan(oldText.references.length, oldText.importsAndExports.length);
newLength = this.importsAndExports.length
newLength = this.importsAndExports.length;
break;
case ChangedPart.program:
oldSpan = createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length);
@ -97,19 +97,19 @@ module ts {
}
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget): CompilerHost {
let files: Map<SourceFileWithText> = {};
for (let t of texts) {
let file = <SourceFileWithText>createSourceFile(t.name, t.text.getFullText(), target);
const files: Map<SourceFileWithText> = {};
for (const t of texts) {
const file = <SourceFileWithText>createSourceFile(t.name, t.text.getFullText(), target);
file.sourceText = t.text;
files[t.name] = file;
}
return {
getSourceFile(fileName): SourceFile {
return files[fileName];
},
getDefaultLibFileName(): string {
return "lib.d.ts"
return "lib.d.ts";
},
writeFile(file, text) {
throw new Error("NYI");
@ -128,31 +128,31 @@ module ts {
},
fileExists: fileName => hasProperty(files, fileName),
readFile: fileName => {
let file = lookUp(files, fileName);
const file = lookUp(files, fileName);
return file && file.text;
}
}
};
}
function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions): Program {
var host = createTestCompilerHost(texts, options.target);
let program = <ProgramWithSourceTexts>createProgram(rootNames, options, host);
const host = createTestCompilerHost(texts, options.target);
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host);
program.sourceTexts = texts;
return program;
}
function updateProgram(oldProgram: Program, rootNames: string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void) {
var texts: NamedSourceText[] = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
const texts: NamedSourceText[] = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
updater(texts);
var host = createTestCompilerHost(texts, options.target);
var program = <ProgramWithSourceTexts>createProgram(rootNames, options, host, oldProgram);
const host = createTestCompilerHost(texts, options.target);
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host, oldProgram);
program.sourceTexts = texts;
return program;
}
function getSizeOfMap(map: Map<any>): number {
let size = 0;
for (let id in map) {
for (const id in map) {
if (hasProperty(map, id)) {
size++;
}
@ -172,20 +172,20 @@ module ts {
assert.isTrue(expected.primary === actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`);
}
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original:T) => void): void {
let file = program.getSourceFile(fileName);
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original: T) => void): void {
const file = program.getSourceFile(fileName);
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
const cache = getCache(file)
const cache = getCache(file);
if (expectedContent === undefined) {
assert.isTrue(cache === undefined, `expected ${caption} to be undefined`);
}
else {
assert.isTrue(cache !== undefined, `expected ${caption} to be set`);
let actualCacheSize = getSizeOfMap(cache);
let expectedSize = getSizeOfMap(expectedContent);
const actualCacheSize = getSizeOfMap(cache);
const expectedSize = getSizeOfMap(expectedContent);
assert.isTrue(actualCacheSize === expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`);
for (let id in expectedContent) {
for (const id in expectedContent) {
if (hasProperty(expectedContent, id)) {
if (expectedContent[id]) {
@ -210,45 +210,46 @@ module ts {
}
describe("Reuse program structure", () => {
let target = ScriptTarget.Latest;
let files = [
/* tslint:disable no-unused-variable */
const target = ScriptTarget.Latest;
const files = [
{ name: "a.ts", text: SourceText.New(
`
/// <reference path='b.ts'/>
/// <reference path='non-existing-file.ts'/>
/// <reference types="typerefs" />
`, "",`var x = 1`) },
`, "", `var x = 1`) },
{ name: "b.ts", text: SourceText.New(`/// <reference path='c.ts'/>`, "", `var y = 2`) },
{ name: "c.ts", text: SourceText.New("", "", `var z = 1;`) },
{ name: "types/typerefs/index.d.ts", text: SourceText.New("", "", `declare let z: number;`) },
]
];
it("successful if change does not affect imports", () => {
var program_1 = newProgram(files, ["a.ts"], { target });
var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
const program_1 = newProgram(files, ["a.ts"], { target });
const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
files[0].text = files[0].text.updateProgram("var x = 100");
});
assert.isTrue(program_1.structureIsReused);
let program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts"))
let program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts"))
const program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts"));
const program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts"));
assert.equal(program1Diagnostics.length, program2Diagnostics.length);
});
it("successful if change does not affect type reference directives", () => {
var program_1 = newProgram(files, ["a.ts"], { target });
var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
const program_1 = newProgram(files, ["a.ts"], { target });
const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
files[0].text = files[0].text.updateProgram("var x = 100");
});
assert.isTrue(program_1.structureIsReused);
let program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts"))
let program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts"))
const program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts"));
const program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts"));
assert.equal(program1Diagnostics.length, program2Diagnostics.length);
});
it("fails if change affects tripleslash references", () => {
var program_1 = newProgram(files, ["a.ts"], { target });
var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
let newReferences = `/// <reference path='b.ts'/>
const program_1 = newProgram(files, ["a.ts"], { target });
const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
const newReferences = `/// <reference path='b.ts'/>
/// <reference path='c.ts'/>
`;
files[0].text = files[0].text.updateReferences(newReferences);
@ -257,17 +258,17 @@ module ts {
});
it("fails if change affects imports", () => {
var program_1 = newProgram(files, ["a.ts"], { target });
var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
const program_1 = newProgram(files, ["a.ts"], { target });
const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
files[2].text = files[2].text.updateImportsAndExports("import x from 'b'");
});
assert.isTrue(!program_1.structureIsReused);
});
it("fails if change affects type directives", () => {
var program_1 = newProgram(files, ["a.ts"], { target });
var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
let newReferences = `
const program_1 = newProgram(files, ["a.ts"], { target });
const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => {
const newReferences = `
/// <reference path='b.ts'/>
/// <reference path='non-existing-file.ts'/>
/// <reference types="typerefs1" />`;
@ -277,35 +278,35 @@ module ts {
});
it("fails if module kind changes", () => {
var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS });
var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0);
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS });
const program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0);
assert.isTrue(!program_1.structureIsReused);
});
it("fails if rootdir changes", () => {
var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, files => void 0);
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
const program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, files => void 0);
assert.isTrue(!program_1.structureIsReused);
});
it("fails if config path changes", () => {
var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" });
var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, files => void 0);
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" });
const program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, files => void 0);
assert.isTrue(!program_1.structureIsReused);
});
it("resolution cache follows imports", () => {
let files = [
const files = [
{ name: "a.ts", text: SourceText.New("", "import {_} from 'b'", "var x = 1") },
{ name: "b.ts", text: SourceText.New("", "", "var y = 2") },
];
var options: CompilerOptions = { target };
const options: CompilerOptions = { target };
var program_1 = newProgram(files, ["a.ts"], options);
const program_1 = newProgram(files, ["a.ts"], options);
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
checkResolvedModulesCache(program_1, "b.ts", undefined);
var program_2 = updateProgram(program_1, ["a.ts"], options, files => {
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
files[0].text = files[0].text.updateProgram("var x = 2");
});
assert.isTrue(program_1.structureIsReused);
@ -315,14 +316,14 @@ module ts {
checkResolvedModulesCache(program_1, "b.ts", undefined);
// imports has changed - program is not reused
var program_3 = updateProgram(program_2, ["a.ts"], options, files => {
const program_3 = updateProgram(program_2, ["a.ts"], options, files => {
files[0].text = files[0].text.updateImportsAndExports("");
});
assert.isTrue(!program_2.structureIsReused);
checkResolvedModulesCache(program_3, "a.ts", undefined);
var program_4 = updateProgram(program_3, ["a.ts"], options, files => {
let newImports = `import x from 'b'
const program_4 = updateProgram(program_3, ["a.ts"], options, files => {
const newImports = `import x from 'b'
import y from 'c'
`;
files[0].text = files[0].text.updateImportsAndExports(newImports);
@ -332,17 +333,17 @@ module ts {
});
it("resolved type directives cache follows type directives", () => {
let files = [
const files = [
{ name: "/a.ts", text: SourceText.New("/// <reference types='typedefs'/>", "", "var x = $") },
{ name: "/types/typedefs/index.d.ts", text: SourceText.New("", "", "declare var $: number") },
];
var options: CompilerOptions = { target, typesRoot: "/" };
const options: CompilerOptions = { target, typesRoot: "/" };
var program_1 = newProgram(files, ["/a.ts"], options);
const program_1 = newProgram(files, ["/a.ts"], options);
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
var program_2 = updateProgram(program_1, ["/a.ts"], options, files => {
const program_2 = updateProgram(program_1, ["/a.ts"], options, files => {
files[0].text = files[0].text.updateProgram("var x = 2");
});
assert.isTrue(program_1.structureIsReused);
@ -352,15 +353,15 @@ module ts {
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
// type reference directives has changed - program is not reused
var program_3 = updateProgram(program_2, ["/a.ts"], options, files => {
const program_3 = updateProgram(program_2, ["/a.ts"], options, files => {
files[0].text = files[0].text.updateReferences("");
});
assert.isTrue(!program_2.structureIsReused);
checkResolvedTypeDirectivesCache(program_3, "/a.ts", undefined);
var program_4 = updateProgram(program_3, ["/a.ts"], options, files => {
let newReferences = `/// <reference types="typedefs"/>
const program_4 = updateProgram(program_3, ["/a.ts"], options, files => {
const newReferences = `/// <reference types="typedefs"/>
/// <reference types="typedefs2"/>
`;
files[0].text = files[0].text.updateReferences(newReferences);
@ -368,11 +369,12 @@ module ts {
assert.isTrue(!program_3.structureIsReused);
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
});
/* tslint:enable no-unused-variable */
});
describe("host is optional", () => {
it("should work if host is not provided", () => {
createProgram([], {});
})
});
});
}
}

View File

@ -7,15 +7,15 @@ interface ClassificationEntry {
position?: number;
}
describe('Colorization', function () {
describe("Colorization", function () {
// Use the shim adapter to ensure test coverage of the shim layer for the classifier
var languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false);
var classifier = languageServiceAdapter.getClassifier();
const languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false);
const classifier = languageServiceAdapter.getClassifier();
function getEntryAtPosition(result: ts.ClassificationResult, position: number) {
var entryPosition = 0;
for (var i = 0, n = result.entries.length; i < n; i++) {
var entry = result.entries[i];
let entryPosition = 0;
for (let i = 0, n = result.entries.length; i < n; i++) {
const entry = result.entries[i];
if (entryPosition === position) {
return entry;
}
@ -32,7 +32,6 @@ describe('Colorization', function () {
function identifier(text: string, position?: number) { return createClassification(text, ts.TokenClass.Identifier, position); }
function numberLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.NumberLiteral, position); }
function stringLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.StringLiteral, position); }
function regExpLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.RegExpLiteral, position); }
function finalEndOfLineState(value: number): ClassificationEntry { return { value: value, classification: undefined, position: 0 }; }
function createClassification(text: string, tokenClass: ts.TokenClass, position?: number): ClassificationEntry {
return {
@ -43,19 +42,19 @@ describe('Colorization', function () {
}
function testLexicalClassification(text: string, initialEndOfLineState: ts.EndOfLineState, ...expectedEntries: ClassificationEntry[]): void {
var result = classifier.getClassificationsForLine(text, initialEndOfLineState, /*syntacticClassifierAbsent*/ false);
const result = classifier.getClassificationsForLine(text, initialEndOfLineState, /*syntacticClassifierAbsent*/ false);
for (var i = 0, n = expectedEntries.length; i < n; i++) {
var expectedEntry = expectedEntries[i];
for (let i = 0, n = expectedEntries.length; i < n; i++) {
const expectedEntry = expectedEntries[i];
if (expectedEntry.classification === undefined) {
assert.equal(result.finalLexState, expectedEntry.value, "final endOfLineState does not match expected.");
}
else {
var actualEntryPosition = expectedEntry.position !== undefined ? expectedEntry.position : text.indexOf(expectedEntry.value);
const actualEntryPosition = expectedEntry.position !== undefined ? expectedEntry.position : text.indexOf(expectedEntry.value);
assert(actualEntryPosition >= 0, "token: '" + expectedEntry.value + "' does not exit in text: '" + text + "'.");
var actualEntry = getEntryAtPosition(result, actualEntryPosition);
const actualEntry = getEntryAtPosition(result, actualEntryPosition);
assert(actualEntry, "Could not find classification entry for '" + expectedEntry.value + "' at position: " + actualEntryPosition);
assert.equal(actualEntry.classification, expectedEntry.classification, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedEntry.classification] + ", Actual: " + ts.TokenClass[actualEntry.classification]);
@ -292,7 +291,7 @@ describe('Colorization', function () {
stringLiteral("..."),
finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate));
});
it("classifies the entire line of an unterminated multiline template middle/end",() => {
it("classifies the entire line of an unterminated multiline template middle/end", () => {
testLexicalClassification("...",
ts.EndOfLineState.InTemplateMiddleOrTail,
stringLiteral("..."),
@ -320,7 +319,7 @@ describe('Colorization', function () {
stringLiteral("}...`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies a template middle and propagates the end of line state",() => {
it("classifies a template middle and propagates the end of line state", () => {
testLexicalClassification("${ 1 + 1 }...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("${"),
@ -331,8 +330,8 @@ describe('Colorization', function () {
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies substitution expressions with curly braces appropriately", () => {
var pos = 0;
var lastLength = 0;
let pos = 0;
let lastLength = 0;
testLexicalClassification("...${ () => { } } ${ { x: `1` } }...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
@ -354,7 +353,7 @@ describe('Colorization', function () {
// Adjusts 'pos' by accounting for the length of each portion of the string,
// but only return the last given string
function track(...vals: string[]): string {
for (var i = 0, n = vals.length; i < n; i++) {
for (let i = 0, n = vals.length; i < n; i++) {
pos += lastLength;
lastLength = vals[i].length;
}
@ -446,4 +445,4 @@ class D { }\r\n\
finalEndOfLineState(ts.EndOfLineState.None));
});
});
});
});

View File

@ -1,79 +1,81 @@
///<reference path='..\..\..\..\src\harness\harness.ts' />
describe("DocumentRegistry", () => {
/* tslint:disable no-unused-variable */
it("documents are shared between projects", () => {
var documentRegistry = ts.createDocumentRegistry();
var defaultCompilerOptions = ts.getDefaultCompilerOptions();
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
assert(f1 === f2, "DocumentRegistry should return the same document for the same name");
});
it("documents are refreshed when settings in compilation settings affect syntax", () => {
var documentRegistry = ts.createDocumentRegistry();
var compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES5, module: ts.ModuleKind.AMD };
const documentRegistry = ts.createDocumentRegistry();
const compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES5, module: ts.ModuleKind.AMD };
// change compilation setting that doesn't affect parsing - should have the same document
compilerOptions.declaration = true;
var f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
compilerOptions.declaration = false;
var f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
assert(f1 === f2, "Expected to have the same document instance");
// change value of compilation setting that is used during production of AST - new document is required
compilerOptions.target = ts.ScriptTarget.ES3;
var f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
assert(f1 !== f3, "Changed target: Expected to have different instances of document");
compilerOptions.preserveConstEnums = true;
var f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
assert(f3 === f4, "Changed preserveConstEnums: Expected to have the same instance of the document");
compilerOptions.module = ts.ModuleKind.System;
var f5 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f5 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
assert(f4 !== f5, "Changed module: Expected to have different instances of the document");
});
it("Acquiring document gets correct version 1", () => {
var documentRegistry = ts.createDocumentRegistry();
var defaultCompilerOptions = ts.getDefaultCompilerOptions();
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
// Simulate one LS getting the document.
var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
const f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
// Simulate another LS getting the document at another version.
var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "2");
const f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "2");
assert(f2.version === "2");
});
it("Acquiring document gets correct version 2", () => {
var documentRegistry = ts.createDocumentRegistry();
var defaultCompilerOptions = ts.getDefaultCompilerOptions();
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
var contents = "var x = 1;"
var snapshot = ts.ScriptSnapshot.fromString(contents);
const contents = "var x = 1;";
const snapshot = ts.ScriptSnapshot.fromString(contents);
// Always treat any change as a full change.
snapshot.getChangeRange = old => ts.createTextChangeRange(ts.createTextSpan(0, contents.length), contents.length);
// Simulate one LS getting the document.
var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
const f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
// Simulate another LS getting that document.
var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
const f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
// Now LS1 updates their document.
var f3 = documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "2");
const f3 = documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "2");
// Now LS2 tries to update their document.
var f4 = documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "3");
// Now LS2 tries to update their document.
const f4 = documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "3");
});
});
/* tslint:enable no-unused-variable */
});

View File

@ -1,10 +1,10 @@
/// <reference path="..\..\..\..\src\harness\external\mocha.d.ts" />
/// <reference path="..\..\..\..\src\services\patternMatcher.ts" />
describe('PatternMatcher', function () {
describe("PatternMatcher", function () {
describe("BreakIntoCharacterSpans", function () {
it("EmptyIdentifier", () => {
verifyBreakIntoCharacterSpans("")
verifyBreakIntoCharacterSpans("");
});
it("SimpleIdentifier", () => {
@ -96,35 +96,35 @@ describe('PatternMatcher', function () {
describe("SingleWordPattern", () => {
it("PreferCaseSensitiveExact", () => {
var match = getFirstMatch("Foo", "Foo");
const match = getFirstMatch("Foo", "Foo");
assert.equal(ts.PatternMatchKind.exact, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveExactInsensitive", () => {
var match = getFirstMatch("foo", "Foo");
const match = getFirstMatch("foo", "Foo");
assert.equal(ts.PatternMatchKind.exact, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitivePrefix", () => {
var match = getFirstMatch("Foo", "Fo");
const match = getFirstMatch("Foo", "Fo");
assert.equal(ts.PatternMatchKind.prefix, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitivePrefixCaseInsensitive", () => {
var match = getFirstMatch("Foo", "fo");
const match = getFirstMatch("Foo", "fo");
assert.equal(ts.PatternMatchKind.prefix, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveCamelCaseMatchSimple", () => {
var match = getFirstMatch("FogBar", "FB");
const match = getFirstMatch("FogBar", "FB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
@ -132,156 +132,156 @@ describe('PatternMatcher', function () {
});
it("PreferCaseSensitiveCamelCaseMatchPartialPattern", () => {
var match = getFirstMatch("FogBar", "FoB");
const match = getFirstMatch("FogBar", "FoB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveCamelCaseMatchToLongPattern1", () => {
var match = getFirstMatch("FogBar", "FBB");
const match = getFirstMatch("FogBar", "FBB");
assert.isTrue(match === undefined);
});
it("PreferCaseSensitiveCamelCaseMatchToLongPattern2", () => {
var match = getFirstMatch("FogBar", "FoooB");
const match = getFirstMatch("FogBar", "FoooB");
assert.isTrue(match === undefined);
});
it("CamelCaseMatchPartiallyUnmatched", () => {
var match = getFirstMatch("FogBarBaz", "FZ");
const match = getFirstMatch("FogBarBaz", "FZ");
assert.isTrue(match === undefined);
});
it("CamelCaseMatchCompletelyUnmatched", () => {
var match = getFirstMatch("FogBarBaz", "ZZ");
const match = getFirstMatch("FogBarBaz", "ZZ");
assert.isTrue(match === undefined);
});
it("TwoUppercaseCharacters", () => {
var match = getFirstMatch("SimpleUIElement", "SiUI");
const match = getFirstMatch("SimpleUIElement", "SiUI");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveLowercasePattern", () => {
var match = getFirstMatch("FogBar", "b");
const match = getFirstMatch("FogBar", "b");
assert.equal(ts.PatternMatchKind.substring, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveLowercasePattern2", () => {
var match = getFirstMatch("FogBar", "fB");
const match = getFirstMatch("FogBar", "fB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveTryUnderscoredName", () => {
var match = getFirstMatch("_fogBar", "_fB");
const match = getFirstMatch("_fogBar", "_fB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveTryUnderscoredName2", () => {
var match = getFirstMatch("_fogBar", "fB");
const match = getFirstMatch("_fogBar", "fB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveTryUnderscoredNameInsensitive", () => {
var match = getFirstMatch("_FogBar", "_fB");
const match = getFirstMatch("_FogBar", "_fB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveMiddleUnderscore", () => {
var match = getFirstMatch("Fog_Bar", "FB");
const match = getFirstMatch("Fog_Bar", "FB");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveMiddleUnderscore2", () => {
var match = getFirstMatch("Fog_Bar", "F_B");
const match = getFirstMatch("Fog_Bar", "F_B");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("PreferCaseSensitiveMiddleUnderscore3", () => {
var match = getFirstMatch("Fog_Bar", "F__B");
const match = getFirstMatch("Fog_Bar", "F__B");
assert.isTrue(undefined === match);
});
it("PreferCaseSensitiveMiddleUnderscore4", () => {
var match = getFirstMatch("Fog_Bar", "f_B");
const match = getFirstMatch("Fog_Bar", "f_B");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveMiddleUnderscore5", () => {
var match = getFirstMatch("Fog_Bar", "F_b");
const match = getFirstMatch("Fog_Bar", "F_b");
assert.equal(ts.PatternMatchKind.camelCase, match.kind);
assert.equal(false, match.isCaseSensitive);
});
it("PreferCaseSensitiveRelativeWeights1", () => {
var match1 = getFirstMatch("FogBarBaz", "FB");
var match2 = getFirstMatch("FooFlobBaz", "FB");
const match1 = getFirstMatch("FogBarBaz", "FB");
const match2 = getFirstMatch("FooFlobBaz", "FB");
// We should prefer something that starts at the beginning if possible
assertInRange(match1.camelCaseWeight, match2.camelCaseWeight + 1, 1 << 30);
});
it("PreferCaseSensitiveRelativeWeights2", () => {
var match1 = getFirstMatch("BazBarFooFooFoo", "FFF");
var match2 = getFirstMatch("BazFogBarFooFoo", "FFF");
const match1 = getFirstMatch("BazBarFooFooFoo", "FFF");
const match2 = getFirstMatch("BazFogBarFooFoo", "FFF");
// Contiguous things should also be preferred
assertInRange(match1.camelCaseWeight, match2.camelCaseWeight + 1, 1 << 30);
});
it("PreferCaseSensitiveRelativeWeights3", () => {
var match1 = getFirstMatch("FogBarFooFoo", "FFF");
var match2 = getFirstMatch("BarFooFooFoo", "FFF");
const match1 = getFirstMatch("FogBarFooFoo", "FFF");
const match2 = getFirstMatch("BarFooFooFoo", "FFF");
// The weight of being first should be greater than the weight of being contiguous
assertInRange(match1.camelCaseWeight, match2.camelCaseWeight + 1, 1 << 30);
});
it("AllLowerPattern1", () => {
var match = getFirstMatch("FogBarChangedEventArgs", "changedeventargs");
const match = getFirstMatch("FogBarChangedEventArgs", "changedeventargs");
assert.isTrue(undefined !== match);
});
it("AllLowerPattern2", () => {
var match = getFirstMatch("FogBarChangedEventArgs", "changedeventarrrgh");
const match = getFirstMatch("FogBarChangedEventArgs", "changedeventarrrgh");
assert.isTrue(undefined === match);
});
it("AllLowerPattern3", () => {
var match = getFirstMatch("ABCDEFGH", "bcd");
const match = getFirstMatch("ABCDEFGH", "bcd");
assert.isTrue(undefined !== match);
});
it("AllLowerPattern4", () => {
var match = getFirstMatch("AbcdefghijEfgHij", "efghij");
const match = getFirstMatch("AbcdefghijEfgHij", "efghij");
assert.isTrue(undefined === match);
});
@ -289,144 +289,144 @@ describe('PatternMatcher', function () {
describe("MultiWordPattern", () => {
it("ExactWithLowercase", () => {
var matches = getAllMatches("AddMetadataReference", "addmetadatareference");
const matches = getAllMatches("AddMetadataReference", "addmetadatareference");
assertContainsKind(ts.PatternMatchKind.exact, matches);
});
it("SingleLowercasedSearchWord1", () => {
var matches = getAllMatches("AddMetadataReference", "add");
const matches = getAllMatches("AddMetadataReference", "add");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
});
it("SingleLowercasedSearchWord2", () => {
var matches = getAllMatches("AddMetadataReference", "metadata");
const matches = getAllMatches("AddMetadataReference", "metadata");
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("SingleUppercaseSearchWord1", () => {
var matches = getAllMatches("AddMetadataReference", "Add");
const matches = getAllMatches("AddMetadataReference", "Add");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
});
it("SingleUppercaseSearchWord2", () => {
var matches = getAllMatches("AddMetadataReference", "Metadata");
const matches = getAllMatches("AddMetadataReference", "Metadata");
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("SingleUppercaseSearchLetter1", () => {
var matches = getAllMatches("AddMetadataReference", "A");
const matches = getAllMatches("AddMetadataReference", "A");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
});
it("SingleUppercaseSearchLetter2", () => {
var matches = getAllMatches("AddMetadataReference", "M");
const matches = getAllMatches("AddMetadataReference", "M");
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("TwoLowercaseWords", () => {
var matches = getAllMatches("AddMetadataReference", "add metadata");
const matches = getAllMatches("AddMetadataReference", "add metadata");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("TwoLowercaseWords", () => {
var matches = getAllMatches("AddMetadataReference", "A M");
const matches = getAllMatches("AddMetadataReference", "A M");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("TwoLowercaseWords", () => {
var matches = getAllMatches("AddMetadataReference", "AM");
const matches = getAllMatches("AddMetadataReference", "AM");
assertContainsKind(ts.PatternMatchKind.camelCase, matches);
});
it("TwoLowercaseWords", () => {
var matches = getAllMatches("AddMetadataReference", "ref Metadata")
const matches = getAllMatches("AddMetadataReference", "ref Metadata");
assertArrayEquals(ts.map(matches, m => m.kind), [ts.PatternMatchKind.substring, ts.PatternMatchKind.substring]);
});
it("TwoLowercaseWords", () => {
var matches = getAllMatches("AddMetadataReference", "ref M")
const matches = getAllMatches("AddMetadataReference", "ref M");
assertArrayEquals(ts.map(matches, m => m.kind), [ts.PatternMatchKind.substring, ts.PatternMatchKind.substring]);
});
it("MixedCamelCase", () => {
var matches = getAllMatches("AddMetadataReference", "AMRe");
const matches = getAllMatches("AddMetadataReference", "AMRe");
assertContainsKind(ts.PatternMatchKind.camelCase, matches);
});
it("BlankPattern", () => {
var matches = getAllMatches("AddMetadataReference", "");
const matches = getAllMatches("AddMetadataReference", "");
assert.isTrue(matches === undefined);
});
it("WhitespaceOnlyPattern", () => {
var matches = getAllMatches("AddMetadataReference", " ");
const matches = getAllMatches("AddMetadataReference", " ");
assert.isTrue(matches === undefined);
});
it("EachWordSeparately1", () => {
var matches = getAllMatches("AddMetadataReference", "add Meta");
const matches = getAllMatches("AddMetadataReference", "add Meta");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("EachWordSeparately2", () => {
var matches = getAllMatches("AddMetadataReference", "Add meta");
const matches = getAllMatches("AddMetadataReference", "Add meta");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("EachWordSeparately3", () => {
var matches = getAllMatches("AddMetadataReference", "Add Meta");
const matches = getAllMatches("AddMetadataReference", "Add Meta");
assertContainsKind(ts.PatternMatchKind.prefix, matches);
assertContainsKind(ts.PatternMatchKind.substring, matches);
});
it("MixedCasing", () => {
var matches = getAllMatches("AddMetadataReference", "mEta");
const matches = getAllMatches("AddMetadataReference", "mEta");
assert.isTrue(matches === undefined);
});
it("MixedCasing2", () => {
var matches = getAllMatches("AddMetadataReference", "Data");
const matches = getAllMatches("AddMetadataReference", "Data");
assert.isTrue(matches === undefined);
});
it("AsteriskSplit", () => {
var matches = getAllMatches("GetKeyWord", "K*W");
const matches = getAllMatches("GetKeyWord", "K*W");
assertArrayEquals(ts.map(matches, m => m.kind), [ts.PatternMatchKind.substring, ts.PatternMatchKind.substring]);
});
it("LowercaseSubstring1", () => {
var matches = getAllMatches("Operator", "a");
const matches = getAllMatches("Operator", "a");
assert.isTrue(matches === undefined);
});
it("LowercaseSubstring2", () => {
var matches = getAllMatches("FooAttribute", "a");
const matches = getAllMatches("FooAttribute", "a");
assertContainsKind(ts.PatternMatchKind.substring, matches);
assert.isFalse(matches[0].isCaseSensitive);
});
@ -434,49 +434,49 @@ describe('PatternMatcher', function () {
describe("DottedPattern", () => {
it("DottedPattern1", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "B.Q");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "B.Q");
assert.equal(ts.PatternMatchKind.prefix, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("DottedPattern2", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "C.Q");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "C.Q");
assert.isTrue(match === undefined);
});
it("DottedPattern3", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "B.B.Q");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "B.B.Q");
assert.equal(ts.PatternMatchKind.prefix, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("DottedPattern4", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "Baz.Quux");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "Baz.Quux");
assert.equal(ts.PatternMatchKind.exact, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("DottedPattern5", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "F.B.B.Quux");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "F.B.B.Quux");
assert.equal(ts.PatternMatchKind.exact, match.kind);
assert.equal(true, match.isCaseSensitive);
});
it("DottedPattern6", () => {
var match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "F.F.B.B.Quux");
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "F.F.B.B.Quux");
assert.isTrue(match === undefined);
});
it("DottedPattern7", () => {
var match = getFirstMatch("UIElement", "UIElement");
var match = getFirstMatch("GetKeyword", "UIElement");
let match = getFirstMatch("UIElement", "UIElement");
match = getFirstMatch("GetKeyword", "UIElement");
assert.isTrue(match === undefined);
});
});
function getFirstMatch(candidate: string, pattern: string): ts.PatternMatch {
var matches = ts.createPatternMatcher(pattern).getMatchesForLastSegmentOfPattern(candidate);
const matches = ts.createPatternMatcher(pattern).getMatchesForLastSegmentOfPattern(candidate);
return matches ? matches[0] : undefined;
}
@ -485,7 +485,7 @@ describe('PatternMatcher', function () {
}
function getFirstMatchForDottedPattern(dottedContainer: string, candidate: string, pattern: string): ts.PatternMatch {
var matches = ts.createPatternMatcher(pattern).getMatches(dottedContainer.split("."), candidate);
const matches = ts.createPatternMatcher(pattern).getMatches(dottedContainer.split("."), candidate);
return matches ? matches[0] : undefined;
}
@ -503,7 +503,7 @@ describe('PatternMatcher', function () {
function assertArrayEquals<T>(array1: T[], array2: T[]) {
assert.equal(array1.length, array2.length);
for (var i = 0, n = array1.length; i < n; i++) {
for (let i = 0, n = array1.length; i < n; i++) {
assert.equal(array1[i], array2[i]);
}
}
@ -524,4 +524,4 @@ describe('PatternMatcher', function () {
function assertContainsKind(kind: ts.PatternMatchKind, results: ts.PatternMatch[]) {
assert.isTrue(ts.forEach(results, r => r.kind === kind));
}
});
});

View File

@ -2,12 +2,14 @@
/// <reference path="..\..\..\..\src\harness\harnessLanguageService.ts" />
declare namespace chai.assert {
/* tslint:disable no-unused-variable */
function deepEqual(actual: any, expected: any): void;
/* tslint:enable no-unused-variable */
}
describe('PreProcessFile:', function () {
describe("PreProcessFile:", function () {
function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
var resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
const resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
assert.equal(resultPreProcess.isLibFile, expectedPreProcess.isLibFile, "Pre-processed file has different value for isLibFile. Expected: " + expectedPreProcess.isLibFile + ". Actual: " + resultPreProcess.isLibFile);
@ -27,20 +29,20 @@ describe('PreProcessFile:', function () {
}
assert.equal(actual.length, expected.length, `[${kind}] Actual array's length does not match expected length. Expected files: ${JSON.stringify(expected)}, actual files: ${JSON.stringify(actual)}`);
for (var i = 0; i < expected.length; ++i) {
var actualReference = actual[i];
var expectedReference = expected[i];
for (let i = 0; i < expected.length; i++) {
const actualReference = actual[i];
const expectedReference = expected[i];
assert.equal(actualReference.fileName, expectedReference.fileName, `[${kind}] actual file path does not match expected. Expected: "${expectedReference.fileName}". Actual: "${actualReference.fileName}".`);
assert.equal(actualReference.pos, expectedReference.pos, `[${kind}] actual file start position does not match expected. Expected: "${expectedReference.pos}". Actual: "${actualReference.pos}".`);
assert.equal(actualReference.end, expectedReference.end, `[${kind}] actual file end pos does not match expected. Expected: "${expectedReference.end}". Actual: "${actualReference.end}".`);
}
}
describe("Test preProcessFiles,", function () {
it("Correctly return referenced files from triple slash", function () {
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
/* readImports */true,
/* detectJavaScriptImports */ false,
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 37 }, { fileName: "refFile2.ts", pos: 38, end: 73 },
{ fileName: "refFile3.ts", pos: 74, end: 109 }, { fileName: "..\\refFile4d.ts", pos: 110, end: 150 }],
@ -53,8 +55,8 @@ describe('PreProcessFile:', function () {
it("Do not return reference path because of invalid triple-slash syntax", function () {
test("///<reference path\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\">" + "\n" + "///<referencepath=\"refFile3.ts\" />" + "\n" + "///<reference pat= \"refFile4d.ts\" />",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
importedFiles: <ts.FileReference[]>[],
@ -66,8 +68,8 @@ describe('PreProcessFile:', function () {
it("Correctly return imported files", function () {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
@ -80,8 +82,8 @@ describe('PreProcessFile:', function () {
it("Do not return imported files if readImportFiles argument is false", function () {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/* readImports */ false,
/* detectJavaScriptImports */ false,
/*readImportFile*/ false,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
@ -93,8 +95,8 @@ describe('PreProcessFile:', function () {
it("Do not return import path because of invalid import syntax", function () {
test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
@ -106,8 +108,8 @@ describe('PreProcessFile:', function () {
it("Correctly return referenced files and import files", function () {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }, { fileName: "refFile2.ts", pos: 36, end: 71 }],
typeReferenceDirectives: [],
@ -119,15 +121,15 @@ describe('PreProcessFile:', function () {
it("Correctly return referenced files and import files even with some invalid syntax", function () {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path \"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }],
typeReferenceDirectives: [],
importedFiles: [{ fileName: "r1.ts", pos: 91, end: 96 }, { fileName: "r3.ts", pos: 148, end: 153 }],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly return ES6 imports", function () {
@ -138,8 +140,8 @@ describe('PreProcessFile:', function () {
"import {a as A} from \"m5\";" + "\n" +
"import {a as A, b, c as C} from \"m6\";" + "\n" +
"import def , {a, b, c as C} from \"m7\";" + "\n",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -154,7 +156,7 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly return ES6 exports", function () {
@ -162,8 +164,8 @@ describe('PreProcessFile:', function () {
"export {a} from \"m2\";" + "\n" +
"export {a as A} from \"m3\";" + "\n" +
"export {a as A, b, c as C} from \"m4\";" + "\n",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -175,32 +177,32 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly return ambient external modules", () => {
test(`
declare module A {}
declare module "B" {}
function foo() {
}
`,
/* readImports */ true,
/* detectJavaScriptImports */ false,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
importedFiles: [],
ambientExternalModules: ["B"],
isLibFile: false
})
});
});
it("Correctly handles export import declarations", function () {
test("export import a = require(\"m1\");",
/* readImports */true,
/* detectJavaScriptImports */ false,
/*readImportFile*/true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -209,7 +211,7 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly handles export require calls in JavaScript files", function () {
test(`
@ -218,8 +220,8 @@ describe('PreProcessFile:', function () {
foo(require('m3'));
var z = { f: require('m4') }
`,
/* readImports */true,
/* detectJavaScriptImports */ true,
/*readImportFile*/true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -231,15 +233,15 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", function () {
test(`
define(["mod1", "mod2"], (m1, m2) => {
});
`,
/* readImports */true,
/* detectJavaScriptImports */ true,
/*readImportFile*/true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -249,15 +251,15 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", function () {
test(`
define("mod", ["mod1", "mod2"], (m1, m2) => {
});
`,
/* readImports */true,
/* detectJavaScriptImports */ true,
/*readImportFile*/true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
typeReferenceDirectives: [],
@ -267,16 +269,16 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 1", () => {
test(`
declare module "../Observable" {
interface I {}
}
export {}
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -287,49 +289,49 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 2", () => {
test(`
declare module "../Observable" {
interface I {}
}
import * as x from "m";
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
importedFiles: [
{ "fileName": "m", "pos": 135, "end": 136 },
{ "fileName": "m", "pos": 123, "end": 124 },
{ "fileName": "../Observable", "pos": 28, "end": 41 }
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 3", () => {
test(`
declare module "../Observable" {
interface I {}
}
import m = require("m");
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
typeReferenceDirectives: [],
importedFiles: [
{ "fileName": "m", "pos": 135, "end": 136 },
{ "fileName": "m", "pos": 123, "end": 124 },
{ "fileName": "../Observable", "pos": 28, "end": 41 }
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 4", () => {
test(`
@ -338,7 +340,7 @@ describe('PreProcessFile:', function () {
}
namespace N {}
export = N;
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -349,7 +351,7 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 5", () => {
test(`
@ -358,7 +360,7 @@ describe('PreProcessFile:', function () {
}
namespace N {}
export import IN = N;
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -369,7 +371,7 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it("correctly handles augmentations in external modules - 6", () => {
test(`
@ -377,7 +379,7 @@ describe('PreProcessFile:', function () {
interface I {}
}
export let x = 1;
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -388,7 +390,7 @@ describe('PreProcessFile:', function () {
],
ambientExternalModules: undefined,
isLibFile: false
})
});
});
it ("correctly handles augmentations in ambient external modules - 1", () => {
test(`
@ -398,7 +400,7 @@ describe('PreProcessFile:', function () {
interface I {}
}
}
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -422,7 +424,7 @@ describe('PreProcessFile:', function () {
interface I {}
}
}
`,
`,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
@ -458,7 +460,7 @@ describe('PreProcessFile:', function () {
ambientExternalModules: undefined,
isLibFile: false
});
})
});
});
});

View File

@ -111,23 +111,31 @@ namespace ts.server {
}
const req: protocol.Request = {
command: name,
seq: i++,
seq: i,
type: "command"
};
i++;
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.seq = i;
i++;
req.arguments = {};
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.seq = i;
i++;
/* tslint:disable no-null-keyword */
req.arguments = null;
/* tslint:enable no-null-keyword */
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.seq = i;
i++;
req.arguments = "";
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.seq = i;
i++;
req.arguments = 0;
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.seq = i;
i++;
req.arguments = [];
session.onMessage(JSON.stringify(req));
}
@ -448,4 +456,4 @@ namespace ts.server {
session.consumeQueue();
});
});
}
}

View File

@ -1,90 +1,90 @@
/// <reference path="..\..\..\src\harness\harness.ts" />
module ts {
namespace ts {
describe("Transpile", () => {
interface TranspileTestSettings {
options?: TranspileOptions;
expectedOutput?: string;
expectedDiagnosticCodes?: number[];
}
function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) {
if(!expectedDiagnosticCodes) {
if (!expectedDiagnosticCodes) {
return;
}
for (let i = 0; i < expectedDiagnosticCodes.length; i++) {
assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`);
}
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
}
function test(input: string, testSettings: TranspileTestSettings): void {
let transpileOptions: TranspileOptions = testSettings.options || {};
const transpileOptions: TranspileOptions = testSettings.options || {};
if (!transpileOptions.compilerOptions) {
transpileOptions.compilerOptions = {};
}
if(transpileOptions.compilerOptions.newLine === undefined) {
if (transpileOptions.compilerOptions.newLine === undefined) { //
// use \r\n as default new line
transpileOptions.compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed;
}
let canUseOldTranspile = !transpileOptions.renamedDependencies;
const canUseOldTranspile = !transpileOptions.renamedDependencies;
transpileOptions.reportDiagnostics = true;
let transpileModuleResult = transpileModule(input, transpileOptions);
const transpileModuleResult = transpileModule(input, transpileOptions);
checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes);
if (testSettings.expectedOutput !== undefined) {
assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput);
}
if (canUseOldTranspile) {
let diagnostics: Diagnostic[] = [];
let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName);
const diagnostics: Diagnostic[] = [];
const transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName);
checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes);
if (testSettings.expectedOutput) {
assert.equal(transpileResult, testSettings.expectedOutput);
}
}
// check source maps
if (!transpileOptions.compilerOptions) {
transpileOptions.compilerOptions = {};
}
if (!transpileOptions.fileName) {
transpileOptions.fileName = transpileOptions.compilerOptions.jsx ? "file.tsx" : "file.ts";
}
transpileOptions.compilerOptions.sourceMap = true;
let transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions);
const transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions);
assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined);
let expectedSourceMapFileName = removeFileExtension(getBaseFileName(normalizeSlashes(transpileOptions.fileName))) + ".js.map";
let expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`;
const expectedSourceMapFileName = removeFileExtension(getBaseFileName(normalizeSlashes(transpileOptions.fileName))) + ".js.map";
const expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`;
if (testSettings.expectedOutput !== undefined) {
assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine);
}
else {
// expected output is not set, just verify that output text has sourceMappingURL as a last line
let output = transpileModuleResultWithSourceMap.outputText;
const output = transpileModuleResultWithSourceMap.outputText;
assert.isTrue(output.length >= expectedSourceMappingUrlLine.length);
if (output.length === expectedSourceMappingUrlLine.length) {
assert.equal(output, expectedSourceMappingUrlLine);
}
else {
let suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine
const suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine;
assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1);
}
}
}
}
it("Generates no diagnostics with valid inputs", () => {
// No errors
test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
@ -92,7 +92,7 @@ module ts {
it("Generates no diagnostics for missing file references", () => {
test(`/// <reference path="file2.ts" />
var x = 0;`,
var x = 0;`,
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
@ -112,23 +112,23 @@ var x = 0;`,
});
it("Generates module output", () => {
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.AMD } },
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.AMD } },
expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n "use strict";\r\n var x = 0;\r\n});\r\n`
});
});
it("Uses correct newLine character", () => {
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } },
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } },
expectedOutput: `"use strict";\nvar x = 0;\n`
});
});
it("Sets module name", () => {
let output =
const output =
`System.register("NamedModule", [], function(exports_1, context_1) {\n` +
` "use strict";\n` +
` var __moduleName = context_1 && context_1.id;\n` +
@ -140,11 +140,11 @@ var x = 0;`,
` }\n` +
` }\n` +
`});\n`;
test("var x = 1;",
{
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" },
test("var x = 1;",
{
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" },
expectedOutput: output
})
});
});
it("No extra errors for file without extension", () => {
@ -152,11 +152,11 @@ var x = 0;`,
});
it("Rename dependencies - System", () => {
let input =
const input =
`import {foo} from "SomeName";\n` +
`declare function use(a: any);\n` +
`use(foo);`
let output =
`use(foo);`;
const output =
`System.register(["SomeOtherName"], function(exports_1, context_1) {\n` +
` "use strict";\n` +
` var __moduleName = context_1 && context_1.id;\n` +
@ -170,39 +170,39 @@ var x = 0;`,
` use(SomeName_1.foo);\n` +
` }\n` +
` }\n` +
`});\n`
`});\n`;
test(input,
{
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
test(input,
{
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
expectedOutput: output
});
});
it("Rename dependencies - AMD", () => {
let input =
const input =
`import {foo} from "SomeName";\n` +
`declare function use(a: any);\n` +
`use(foo);`
let output =
`use(foo);`;
const output =
`define(["require", "exports", "SomeOtherName"], function (require, exports, SomeName_1) {\n` +
` "use strict";\n` +
` use(SomeName_1.foo);\n` +
`});\n`;
test(input,
{
options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
test(input,
{
options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
expectedOutput: output
});
});
it("Rename dependencies - UMD", () => {
let input =
const input =
`import {foo} from "SomeName";\n` +
`declare function use(a: any);\n` +
`use(foo);`
let output =
`use(foo);`;
const output =
`(function (factory) {\n` +
` if (typeof module === 'object' && typeof module.exports === 'object') {\n` +
` var v = factory(require, exports); if (v !== undefined) module.exports = v;\n` +
@ -216,15 +216,15 @@ var x = 0;`,
` use(SomeName_1.foo);\n` +
`});\n`;
test(input,
{
options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
test(input,
{
options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } },
expectedOutput: output
});
});
it("Transpile with emit decorators and emit metadata", () => {
let input =
const input =
`import {db} from './db';\n` +
`function someDecorator(target) {\n` +
` return target;\n` +
@ -237,29 +237,29 @@ var x = 0;`,
` this.db.doSomething(); \n` +
` }\n` +
`}\n` +
`export {MyClass}; \n`
let output =
`export {MyClass}; \n`;
const output =
`"use strict";\n` +
`var db_1 = require(\'./db\');\n` +
`var db_1 = require(\'./db\');\n` +
`function someDecorator(target) {\n` +
` return target;\n` +
`}\n` +
`var MyClass = (function () {\n` +
` function MyClass(db) {\n` +
` this.db = db;\n` +
` this.db.doSomething();\n` +
` }\n` +
` MyClass = __decorate([\n` +
` someDecorator, \n` +
` __metadata(\'design:paramtypes\', [(typeof (_a = typeof db_1.db !== \'undefined\' && db_1.db) === \'function\' && _a) || Object])\n` +
` ], MyClass);\n` +
` return MyClass;\n` +
` var _a;\n` +
`}());\n` +
`}\n` +
`var MyClass = (function () {\n` +
` function MyClass(db) {\n` +
` this.db = db;\n` +
` this.db.doSomething();\n` +
` }\n` +
` MyClass = __decorate([\n` +
` someDecorator, \n` +
` __metadata(\'design:paramtypes\', [(typeof (_a = typeof db_1.db !== \'undefined\' && db_1.db) === \'function\' && _a) || Object])\n` +
` ], MyClass);\n` +
` return MyClass;\n` +
` var _a;\n` +
`}());\n` +
`exports.MyClass = MyClass;\n`;
test(input,
{
test(input,
{
options: {
compilerOptions: {
module: ModuleKind.CommonJS,
@ -269,7 +269,7 @@ var x = 0;`,
experimentalDecorators: true,
target: ScriptTarget.ES5,
}
},
},
expectedOutput: output
});
});
@ -279,12 +279,12 @@ var x = 0;`,
});
it("transpile file as 'tsx' if 'jsx' is specified", () => {
let input = `var x = <div/>`;
let output = `"use strict";\nvar x = React.createElement("div", null);\n`;
const input = `var x = <div/>`;
const output = `"use strict";\nvar x = React.createElement("div", null);\n`;
test(input, {
expectedOutput: output,
options: { compilerOptions: { jsx: JsxEmit.React, newLine: NewLineKind.LineFeed } }
})
});
});
it("transpile .js files", () => {
@ -295,7 +295,7 @@ var x = 0;`,
options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true },
expectedDiagnosticCodes: []
});
})
});
it("Supports urls in file name", () => {
test("var x", { expectedOutput: `"use strict";\r\nvar x;\r\n`, options: { fileName: "http://somewhere/directory//directory2/file.ts" } });

View File

@ -2,21 +2,21 @@
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
namespace ts {
describe('parseConfigFileTextToJson', () => {
describe("parseConfigFileTextToJson", () => {
function assertParseResult(jsonText: string, expectedConfigObject: { config?: any; error?: Diagnostic }) {
let parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
assert.equal(JSON.stringify(parsed), JSON.stringify(expectedConfigObject));
}
function assertParseError(jsonText: string) {
let parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
assert.isTrue(undefined === parsed.config);
assert.isTrue(undefined !== parsed.error);
}
function assertParseErrorWithExcludesKeyword(jsonText: string) {
let parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
let parsedCommand = ts.parseJsonConfigFileContent(parsed, ts.sys, "tests/cases/unittests");
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
const parsedCommand = ts.parseJsonConfigFileContent(parsed, ts.sys, "tests/cases/unittests");
assert.isTrue(undefined !== parsedCommand.errors);
}
@ -156,7 +156,7 @@ namespace ts {
"/apath",
["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"],
["/apath/test.ts"]
)
);
});
it("allow dotted files and folders when explicitly requested", () => {
@ -168,7 +168,7 @@ namespace ts {
"/apath",
["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"],
["/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"]
)
);
});
it("always exclude outDir", () => {
@ -190,7 +190,7 @@ namespace ts {
const expectedFiles = ["/b.ts"];
assertParseFileList(tsconfigWithoutExclude, "tsconfig.json", rootDir, allFiles, expectedFiles);
assertParseFileList(tsconfigWithExclude, "tsconfig.json", rootDir, allFiles, expectedFiles);
})
});
it("implicitly exclude common package folders", () => {
assertParseFileList(
@ -199,7 +199,7 @@ namespace ts {
"/",
["/node_modules/a.ts", "/bower_components/b.ts", "/jspm_packages/c.ts", "/d.ts", "/folder/e.ts"],
["/d.ts", "/folder/e.ts"]
)
})
);
});
});
}

View File

@ -12,9 +12,9 @@ namespace ts {
}
function validateEdit(lineIndex: server.LineIndex, sourceText: string, position: number, deleteLength: number, insertString: string): void {
let checkText = editFlat(position, deleteLength, insertString, sourceText);
let snapshot = lineIndex.edit(position, deleteLength, insertString);
let editedText = snapshot.getText(0, snapshot.getLength());
const checkText = editFlat(position, deleteLength, insertString, sourceText);
const snapshot = lineIndex.edit(position, deleteLength, insertString);
const editedText = snapshot.getText(0, snapshot.getLength());
assert.equal(editedText, checkText);
}
@ -23,7 +23,7 @@ namespace ts {
let validateEditAtLineCharIndex: (line: number, char: number, deleteLength: number, insertString: string) => void;
before(() => {
let testContent = `/// <reference path="z.ts" />
const testContent = `/// <reference path="z.ts" />
var x = 10;
var y = { zebra: 12, giraffe: "ell" };
z.a;
@ -34,14 +34,14 @@ k=y;
var p:Point=new Point();
var q:Point=<Point>p;`;
let { lines } = server.LineIndex.linesFromText(testContent);
const { lines } = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let lineIndex = new server.LineIndex();
const lineIndex = new server.LineIndex();
lineIndex.load(lines);
validateEditAtLineCharIndex = (line: number, char: number, deleteLength: number, insertString: string) => {
let position = lineColToPosition(lineIndex, line, char);
const position = lineColToPosition(lineIndex, line, char);
validateEdit(lineIndex, testContent, position, deleteLength, insertString);
};
});
@ -91,7 +91,7 @@ and grew 1cm per day`;
({ lines, lineMap } = server.LineIndex.linesFromText(testContent));
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let lineIndex = new server.LineIndex();
const lineIndex = new server.LineIndex();
lineIndex.load(lines);
validateEditAtPosition = (position: number, deleteLength: number, insertString: string) => {
@ -195,9 +195,9 @@ and grew 1cm per day`;
before(() => {
// Use scanner.ts, decent size, does not change frequently
let testFileName = "src/compiler/scanner.ts";
const testFileName = "src/compiler/scanner.ts";
testContent = Harness.IO.readFile(testFileName);
let totalChars = testContent.length;
const totalChars = testContent.length;
assert.isTrue(totalChars > 0, "Failed to read test file.");
({ lines, lineMap } = server.LineIndex.linesFromText(testContent));
@ -246,41 +246,41 @@ and grew 1cm per day`;
it("Range (average length 1/4 file size)", () => {
for (let i = 0; i < iterationCount; i++) {
let s2 = lineIndex.getText(rsa[i], la[i]);
let s1 = testContent.substring(rsa[i], rsa[i] + la[i]);
const s2 = lineIndex.getText(rsa[i], la[i]);
const s1 = testContent.substring(rsa[i], rsa[i] + la[i]);
assert.equal(s1, s2);
}
});
it("Range (average length 4 chars)", () => {
for (let j = 0; j < iterationCount; j++) {
let s2 = lineIndex.getText(rsa[j], las[j]);
let s1 = testContent.substring(rsa[j], rsa[j] + las[j]);
const s2 = lineIndex.getText(rsa[j], las[j]);
const s1 = testContent.substring(rsa[j], rsa[j] + las[j]);
assert.equal(s1, s2);
}
});
it("Edit (average length 4)", () => {
for (let i = 0; i < iterationCount; i++) {
let insertString = testContent.substring(rsa[100000 - i], rsa[100000 - i] + las[100000 - i]);
let snapshot = lineIndex.edit(rsa[i], las[i], insertString);
let checkText = editFlat(rsa[i], las[i], insertString, testContent);
let snapText = snapshot.getText(0, checkText.length);
const insertString = testContent.substring(rsa[100000 - i], rsa[100000 - i] + las[100000 - i]);
const snapshot = lineIndex.edit(rsa[i], las[i], insertString);
const checkText = editFlat(rsa[i], las[i], insertString, testContent);
const snapText = snapshot.getText(0, checkText.length);
assert.equal(checkText, snapText);
}
});
it("Edit ScriptVersionCache ", () => {
let svc = server.ScriptVersionCache.fromString(<server.ServerHost>ts.sys, testContent);
const svc = server.ScriptVersionCache.fromString(<server.ServerHost>ts.sys, testContent);
let checkText = testContent;
for (let i = 0; i < iterationCount; i++) {
let insertString = testContent.substring(rsa[i], rsa[i] + las[i]);
const insertString = testContent.substring(rsa[i], rsa[i] + las[i]);
svc.edit(ersa[i], elas[i], insertString);
checkText = editFlat(ersa[i], elas[i], insertString, checkText);
if (0 == (i % 4)) {
let snap = svc.getSnapshot();
let snapText = snap.getText(0, checkText.length);
const snap = svc.getSnapshot();
const snapText = snap.getText(0, checkText.length);
assert.equal(checkText, snapText);
}
}
@ -288,18 +288,18 @@ and grew 1cm per day`;
it("Edit (average length 1/4th file size)", () => {
for (let i = 0; i < iterationCount; i++) {
let insertString = testContent.substring(rsa[100000 - i], rsa[100000 - i] + la[100000 - i]);
let snapshot = lineIndex.edit(rsa[i], la[i], insertString);
let checkText = editFlat(rsa[i], la[i], insertString, testContent);
let snapText = snapshot.getText(0, checkText.length);
const insertString = testContent.substring(rsa[100000 - i], rsa[100000 - i] + la[100000 - i]);
const snapshot = lineIndex.edit(rsa[i], la[i], insertString);
const checkText = editFlat(rsa[i], la[i], insertString, testContent);
const snapText = snapshot.getText(0, checkText.length);
assert.equal(checkText, snapText);
}
});
it("Line/offset from pos", () => {
for (let i = 0; i < iterationCount; i++) {
let lp = lineIndex.charOffsetToLineNumberAndPos(rsa[i]);
let lac = ts.computeLineAndCharacterOfPosition(lineMap, rsa[i]);
const lp = lineIndex.charOffsetToLineNumberAndPos(rsa[i]);
const lac = ts.computeLineAndCharacterOfPosition(lineMap, rsa[i]);
assert.equal(lac.line + 1, lp.line, "Line number mismatch " + (lac.line + 1) + " " + lp.line + " " + i);
assert.equal(lac.character, (lp.offset), "Charachter offset mismatch " + lac.character + " " + lp.offset + " " + i);
}
@ -308,12 +308,12 @@ and grew 1cm per day`;
it("Start pos from line", () => {
for (let i = 0; i < iterationCount; i++) {
for (let j = 0, llen = lines.length; j < llen; j++) {
let lineInfo = lineIndex.lineNumberToInfo(j + 1);
let lineIndexOffset = lineInfo.offset;
let lineMapOffset = lineMap[j];
const lineInfo = lineIndex.lineNumberToInfo(j + 1);
const lineIndexOffset = lineInfo.offset;
const lineMapOffset = lineMap[j];
assert.equal(lineIndexOffset, lineMapOffset);
}
}
});
});
}
}