Move unittests into harness

This commit is contained in:
Wesley Wigham
2016-07-11 17:42:52 -07:00
parent fb20df0568
commit cfe3aadeb3
112 changed files with 49 additions and 50 deletions

View File

@@ -70,24 +70,24 @@
"../server/session.ts",
"../server/client.ts",
"../server/editorServices.ts",
"../../tests/cases/unittests/incrementalParser.ts",
"../../tests/cases/unittests/jsDocParsing.ts",
"../../tests/cases/unittests/services/colorization.ts",
"../../tests/cases/unittests/services/documentRegistry.ts",
"../../tests/cases/unittests/services/preProcessFile.ts",
"../../tests/cases/unittests/services/patternMatcher.ts",
"../../tests/cases/unittests/session.ts",
"../../tests/cases/unittests/versionCache.ts",
"../../tests/cases/unittests/convertToBase64.ts",
"../../tests/cases/unittests/transpile.ts",
"../../tests/cases/unittests/reuseProgramStructure.ts",
"../../tests/cases/unittests/cachingInServerLSHost.ts",
"../../tests/cases/unittests/moduleResolution.ts",
"../../tests/cases/unittests/tsconfigParsing.ts",
"../../tests/cases/unittests/commandLineParsing.ts",
"../../tests/cases/unittests/convertCompilerOptionsFromJson.ts",
"../../tests/cases/unittests/convertTypingOptionsFromJson.ts",
"../../tests/cases/unittests/tsserverProjectSystem.ts",
"../../tests/cases/unittests/matchFiles.ts"
"./unittests/incrementalParser.ts",
"./unittests/jsDocParsing.ts",
"./unittests/services/colorization.ts",
"./unittests/services/documentRegistry.ts",
"./unittests/services/preProcessFile.ts",
"./unittests/services/patternMatcher.ts",
"./unittests/session.ts",
"./unittests/versionCache.ts",
"./unittests/convertToBase64.ts",
"./unittests/transpile.ts",
"./unittests/reuseProgramStructure.ts",
"./unittests/cachingInServerLSHost.ts",
"./unittests/moduleResolution.ts",
"./unittests/tsconfigParsing.ts",
"./unittests/commandLineParsing.ts",
"./unittests/convertCompilerOptionsFromJson.ts",
"./unittests/convertTypingOptionsFromJson.ts",
"./unittests/tsserverProjectSystem.ts",
"./unittests/matchFiles.ts"
]
}

View File

@@ -0,0 +1,229 @@
/// <reference path="..\harness.ts" />
namespace ts {
interface File {
name: string;
content: string;
}
function createDefaultServerHost(fileMap: Map<File>): server.ServerHost {
const existingDirectories: Map<boolean> = {};
forEachValue(fileMap, v => {
let dir = getDirectoryPath(v.name);
let previous: string;
do {
existingDirectories[dir] = true;
previous = dir;
dir = getDirectoryPath(dir);
} while (dir !== previous);
});
return {
args: <string[]>[],
newLine: "\r\n",
useCaseSensitiveFileNames: false,
write: (s: string) => {
},
readFile: (path: string, encoding?: string): string => {
return hasProperty(fileMap, path) && fileMap[path].content;
},
writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => {
throw new Error("NYI");
},
resolvePath: (path: string): string => {
throw new Error("NYI");
},
fileExists: (path: string): boolean => {
return hasProperty(fileMap, path);
},
directoryExists: (path: string): boolean => {
return hasProperty(existingDirectories, path);
},
createDirectory: (path: string) => {
},
getExecutingFilePath: (): string => {
return "";
},
getCurrentDirectory: (): string => {
return "";
},
getDirectories: (path: string) => [],
readDirectory: (path: string, extension?: string[], exclude?: string[], include?: string[]): string[] => {
throw new Error("NYI");
},
exit: (exitCode?: number) => {
},
watchFile: (path, callback) => {
return {
close: () => { }
};
},
watchDirectory: (path, callback, recursive?) => {
return {
close: () => { }
};
},
setTimeout,
clearTimeout
};
}
function createProject(rootFile: string, serverHost: server.ServerHost): { project: server.Project, rootScriptInfo: server.ScriptInfo } {
const logger: server.Logger = {
close() { },
isVerbose: () => false,
loggingEnabled: () => false,
perftrc: (s: string) => { },
info: (s: string) => { },
startGroup: () => { },
endGroup: () => { },
msg: (s: string, type?: string) => { }
};
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,
rootScriptInfo
};
}
describe("Caching in LSHost", () => {
it("works using legacy resolution logic", () => {
const root: File = {
name: "c:/d/f0.ts",
content: `import {x} from "f1"`
};
const imported: File = {
name: "c:/f1.ts",
content: `foo()`
};
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 content = rootScriptInfo.getText();
const originalFileExists = serverHost.fileExists;
{
// patch fileExists to make sure that disk is not touched
serverHost.fileExists = (fileName): boolean => {
assert.isTrue(false, "fileExists should not be called");
return false;
};
const newContent = `import {x} from "f1"
var x: string = 1;`;
rootScriptInfo.editContent(0, content.length, newContent);
content = newContent;
// trigger synchronization to make sure that import will be fetched from the cache
diags = project.compilerService.languageService.getSemanticDiagnostics(imported.name);
// ensure file has correct number of errors after edit
assert.equal(diags.length, 1);
}
{
let fileExistsIsCalled = false;
serverHost.fileExists = (fileName): boolean => {
if (fileName === "lib.d.ts") {
return false;
}
fileExistsIsCalled = true;
assert.isTrue(fileName.indexOf("/f2.") !== -1);
return originalFileExists.call(serverHost, fileName);
};
const newContent = `import {x} from "f2"`;
rootScriptInfo.editContent(0, content.length, newContent);
content = newContent;
try {
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
project.compilerService.languageService.getSemanticDiagnostics(imported.name);
assert.isTrue(false, `should not find file '${imported.name}'`);
}
catch (e) {
assert.isTrue(e.message.indexOf(`Could not find file: '${imported.name}'.`) === 0);
}
assert.isTrue(fileExistsIsCalled);
}
{
let fileExistsCalled = false;
serverHost.fileExists = (fileName): boolean => {
if (fileName === "lib.d.ts") {
return false;
}
fileExistsCalled = true;
assert.isTrue(fileName.indexOf("/f1.") !== -1);
return originalFileExists.call(serverHost, fileName);
};
const newContent = `import {x} from "f1"`;
rootScriptInfo.editContent(0, content.length, newContent);
content = newContent;
project.compilerService.languageService.getSemanticDiagnostics(imported.name);
assert.isTrue(fileExistsCalled);
// setting compiler options discards module resolution cache
fileExistsCalled = false;
const opts = ts.clone(project.projectOptions);
opts.compilerOptions = ts.clone(opts.compilerOptions);
opts.compilerOptions.target = ts.ScriptTarget.ES5;
project.setProjectOptions(opts);
project.compilerService.languageService.getSemanticDiagnostics(imported.name);
assert.isTrue(fileExistsCalled);
}
});
it("loads missing files from disk", () => {
const root: File = {
name: `c:/foo.ts`,
content: `import {x} from "bar"`
};
const imported: File = {
name: `c:/bar.d.ts`,
content: `export var y = 1`
};
const fileMap: Map<File> = { [root.name]: root };
const serverHost = createDefaultServerHost(fileMap);
const originalFileExists = serverHost.fileExists;
let fileExistsCalledForBar = false;
serverHost.fileExists = fileName => {
if (fileName === "lib.d.ts") {
return false;
}
if (!fileExistsCalledForBar) {
fileExistsCalledForBar = fileName.indexOf("/bar.") !== -1;
}
return originalFileExists.call(serverHost, fileName);
};
const { project, rootScriptInfo } = createProject(root.name, serverHost);
const content = rootScriptInfo.getText();
let diags = project.compilerService.languageService.getSemanticDiagnostics(root.name);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
assert.isTrue(diags.length === 1, "one diagnostic expected");
assert.isTrue(typeof diags[0].messageText === "string" && ((<string>diags[0].messageText).indexOf("Cannot find module") === 0), "should be 'cannot find module' message");
// assert that import will success once file appear on disk
fileMap[imported.name] = imported;
fileExistsCalledForBar = false;
rootScriptInfo.editContent(0, content.length, `import {y} from "bar"`);
diags = project.compilerService.languageService.getSemanticDiagnostics(root.name);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
assert.isTrue(diags.length === 0);
});
});
}

View File

@@ -0,0 +1,342 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
describe("parseCommandLine", () => {
function assertParseResult(commandLine: string[], expectedParsedCommandLine: ts.ParsedCommandLine) {
const parsed = ts.parseCommandLine(commandLine);
const parsedCompilerOptions = JSON.stringify(parsed.options);
const expectedCompilerOptions = JSON.stringify(expectedParsedCommandLine.options);
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
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++) {
const parsedError = parsedErrors[i];
const expectedError = expectedErrors[i];
assert.equal(parsedError.code, expectedError.code);
assert.equal(parsedError.category, expectedError.category);
assert.equal(parsedError.messageText, expectedError.messageText);
}
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++) {
const parsedFileName = parsedFileNames[i];
const expectedFileName = expectedFileNames[i];
assert.equal(parsedFileName, expectedFileName);
}
}
it("Parse single option of library flag ", () => {
// --lib es6 0.ts
assertParseResult(["--lib", "es6", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: {
lib: ["lib.es2015.d.ts"]
}
});
});
it("Parse multiple options of library flags ", () => {
// --lib es5,es2015.symbol.wellknown 0.ts
assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: {
lib: ["lib.es5.d.ts", "lib.es2015.symbol.wellknown.d.ts"]
}
});
});
it("Parse invalid option of library flags ", () => {
// --lib es5,invalidOption 0.ts
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {
lib: ["lib.es5.d.ts"]
}
});
});
it("Parse empty options of --jsx ", () => {
// 0.ts --jsx
assertParseResult(["0.ts", "--jsx"],
{
errors: [{
messageText: "Compiler option 'jsx' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {}
});
});
it("Parse empty options of --module ", () => {
// 0.ts --
assertParseResult(["0.ts", "--module"],
{
errors: [{
messageText: "Compiler option 'module' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}, {
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,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {}
});
});
it("Parse empty options of --newLine ", () => {
// 0.ts --newLine
assertParseResult(["0.ts", "--newLine"],
{
errors: [{
messageText: "Compiler option 'newLine' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {}
});
});
it("Parse empty options of --target ", () => {
// 0.ts --target
assertParseResult(["0.ts", "--target"],
{
errors: [{
messageText: "Compiler option 'target' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--target' option must be: 'es3', 'es5', '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,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {}
});
});
it("Parse empty options of --moduleResolution ", () => {
// 0.ts --moduleResolution
assertParseResult(["0.ts", "--moduleResolution"],
{
errors: [{
messageText: "Compiler option 'moduleResolution' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {}
});
});
it("Parse empty options of --lib ", () => {
// 0.ts --lib
assertParseResult(["0.ts", "--lib"],
{
errors: [{
messageText: "Compiler option 'lib' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {
lib: []
}
});
});
it("Parse empty string of --lib ", () => {
// 0.ts --lib
// This test is an error because the empty string is falsey
assertParseResult(["0.ts", "--lib", ""],
{
errors: [{
messageText: "Compiler option 'lib' expects an argument.",
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["0.ts"],
options: {
lib: []
}
});
});
it("Parse immediately following command line argument of --lib ", () => {
// 0.ts --lib
assertParseResult(["0.ts", "--lib", "--sourcemap"],
{
errors: [],
fileNames: ["0.ts"],
options: {
lib: [],
sourceMap: true
}
});
});
it("Parse --lib option with extra comma ", () => {
// --lib es5, es7 0.ts
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["es7", "0.ts"],
options: {
lib: ["lib.es5.d.ts"]
}
});
});
it("Parse --lib option with trailing white-space ", () => {
// --lib es5, es7 0.ts
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
start: undefined,
length: undefined,
}],
fileNames: ["es7", "0.ts"],
options: {
lib: ["lib.es5.d.ts"]
}
});
});
it("Parse multiple compiler flags with input files at the end", () => {
// --lib es5,es2015.symbol.wellknown --target es5 0.ts
assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "--target", "es5", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: {
lib: ["lib.es5.d.ts", "lib.es2015.symbol.wellknown.d.ts"],
target: ts.ScriptTarget.ES5,
}
});
});
it("Parse multiple compiler flags with input files in the middle", () => {
// --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown
assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,es2015.symbol.wellknown"],
{
errors: [],
fileNames: ["0.ts"],
options: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES5,
lib: ["lib.es5.d.ts", "lib.es2015.symbol.wellknown.d.ts"],
}
});
});
it("Parse multiple library compiler flags ", () => {
// --module commonjs --target es5 --lib es5 0.ts --library es2015.array,es2015.symbol.wellknown
assertParseResult(["--module", "commonjs", "--target", "es5", "--lib", "es5", "0.ts", "--lib", "es2015.core, es2015.symbol.wellknown "],
{
errors: [],
fileNames: ["0.ts"],
options: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES5,
lib: ["lib.es2015.core.d.ts", "lib.es2015.symbol.wellknown.d.ts"],
}
});
});
});
}

View File

@@ -0,0 +1,479 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
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++) {
const actualError = actualErrors[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(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": ["es5", "es2015.core", "es2015.symbol"]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
},
errors: <Diagnostic[]>[]
}
);
});
it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"allowJs": false,
"lib": ["es5", "es2015.core", "es2015.symbol"]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
allowJs: false,
lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
},
errors: <Diagnostic[]>[]
}
);
});
it("Convert incorrect option of jsx to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"jsx": ""
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert incorrect option of module to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert incorrect option of newLine to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"newLine": "",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert incorrect option of target to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"target": "",
"noImplicitAny": false,
"sourceMap": false,
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
noImplicitAny: false,
sourceMap: false,
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert incorrect option of module-resolution to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"moduleResolution": "",
"noImplicitAny": false,
"sourceMap": false,
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
noImplicitAny: false,
sourceMap: false,
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert incorrect option of libs to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": ["es5", "es2015.core", "incorrectLib"]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts"]
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert empty string option of libs to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": ["es5", ""]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: ["lib.es5.d.ts"]
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert empty string option of libs to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": [""]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: []
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert trailing-whitespace string option of libs to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": [" "]
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: []
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
}
);
});
it("Convert empty option of libs to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": []
}
}, "tsconfig.json",
{
compilerOptions: <CompilerOptions>{
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: []
},
errors: []
}
);
});
it("Convert incorrectly format tsconfig.json to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"modu": "commonjs",
}
}, "tsconfig.json",
{
compilerOptions: {},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Unknown compiler option 'modu'.",
code: Diagnostics.Unknown_compiler_option_0.code,
category: Diagnostics.Unknown_compiler_option_0.category
}]
}
);
});
it("Convert default tsconfig.json to compiler-options ", () => {
assertCompilerOptions({}, "tsconfig.json",
{
compilerOptions: {} as CompilerOptions,
errors: <Diagnostic[]>[]
}
);
});
// jsconfig.json
it("Convert correctly format jsconfig.json to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"lib": ["es5", "es2015.core", "es2015.symbol"]
}
}, "jsconfig.json",
{
compilerOptions: <CompilerOptions>{
allowJs: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
},
errors: <Diagnostic[]>[]
}
);
});
it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"allowJs": false,
"lib": ["es5", "es2015.core", "es2015.symbol"]
}
}, "jsconfig.json",
{
compilerOptions: <CompilerOptions>{
allowJs: false,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
sourceMap: false,
lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
},
errors: <Diagnostic[]>[]
}
);
});
it("Convert incorrectly format jsconfig.json to compiler-options ", () => {
assertCompilerOptions(
{
"compilerOptions": {
"modu": "commonjs",
}
}, "jsconfig.json",
{
compilerOptions:
{
allowJs: true
},
errors: [{
file: undefined,
start: 0,
length: 0,
messageText: "Unknown compiler option 'modu'.",
code: Diagnostics.Unknown_compiler_option_0.code,
category: Diagnostics.Unknown_compiler_option_0.category
}]
}
);
});
it("Convert default jsconfig.json to compiler-options ", () => {
assertCompilerOptions({}, "jsconfig.json",
{
compilerOptions:
{
allowJs: true
},
errors: <Diagnostic[]>[]
}
);
});
});
}

View File

@@ -0,0 +1,35 @@
/// <reference path="..\harness.ts" />
namespace ts {
describe("convertToBase64", () => {
function runTest(input: string): void {
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')");
}
if (Buffer) {
it("Converts ASCII charaters correctly", () => {
runTest(" !\"#$ %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
});
it("Converts escape sequences correctly", () => {
runTest("\t\n\r\\\"\'\u0062");
});
it("Converts simple unicode characters correctly", () => {
runTest("ΠΣ ٵپ औठ ⺐⺠");
});
it("Converts simple code snippet correctly", () => {
runTest(`/// <reference path="file.ts" />
var x: string = "string";
console.log(x);`);
});
it("Converts simple code snippet with unicode characters correctly", () => {
runTest(`var Π = 3.1415; console.log(Π);`);
});
}
});
}

View File

@@ -0,0 +1,187 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
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++) {
const actualError = actualErrors[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)}.`);
}
}
// tsconfig.json
it("Convert correctly format tsconfig.json to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovery": true,
"include": ["0.d.ts", "1.d.ts"],
"exclude": ["0.js", "1.js"]
}
},
"tsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: true,
include: ["0.d.ts", "1.d.ts"],
exclude: ["0.js", "1.js"]
},
errors: <Diagnostic[]>[]
});
});
it("Convert incorrect format tsconfig.json to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovy": true,
}
}, "tsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: false,
include: [],
exclude: []
},
errors: [
{
category: Diagnostics.Unknown_typing_option_0.category,
code: Diagnostics.Unknown_typing_option_0.code,
file: undefined,
start: 0,
length: 0,
messageText: undefined
}
]
});
});
it("Convert default tsconfig.json to typing-options ", () => {
assertTypingOptions({}, "tsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: false,
include: [],
exclude: []
},
errors: <Diagnostic[]>[]
});
});
it("Convert tsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovery": true
}
}, "tsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: true,
include: [],
exclude: []
},
errors: <Diagnostic[]>[]
});
});
// jsconfig.json
it("Convert jsconfig.json to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovery": false,
"include": ["0.d.ts"],
"exclude": ["0.js"]
}
}, "jsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: false,
include: ["0.d.ts"],
exclude: ["0.js"]
},
errors: <Diagnostic[]>[]
});
});
it("Convert default jsconfig.json to typing-options ", () => {
assertTypingOptions({ }, "jsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: true,
include: [],
exclude: []
},
errors: <Diagnostic[]>[]
});
});
it("Convert incorrect format jsconfig.json to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovy": true,
}
}, "jsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: true,
include: [],
exclude: []
},
errors: [
{
category: Diagnostics.Unknown_compiler_option_0.category,
code: Diagnostics.Unknown_typing_option_0.code,
file: undefined,
start: 0,
length: 0,
messageText: undefined
}
]
});
});
it("Convert jsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
assertTypingOptions(
{
"typingOptions":
{
"enableAutoDiscovery": false
}
}, "jsconfig.json",
{
typingOptions:
{
enableAutoDiscovery: false,
include: [],
exclude: []
},
errors: <Diagnostic[]>[]
});
});
});
}

View File

@@ -0,0 +1,830 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\parser.ts" />
namespace ts {
ts.disableIncrementalParsing = false;
function withChange(text: IScriptSnapshot, start: number, length: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } {
const contents = text.getText(0, text.getLength());
const newContents = contents.substr(0, start) + newText + contents.substring(start + length);
return { text: ScriptSnapshot.fromString(newContents), textChangeRange: createTextChangeRange(createTextSpan(start, length), newText.length) };
}
function withInsert(text: IScriptSnapshot, start: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } {
return withChange(text, start, 0, newText);
}
function withDelete(text: IScriptSnapshot, start: number, length: number): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } {
return withChange(text, start, length, "");
}
function createTree(text: IScriptSnapshot, version: string) {
return createLanguageServiceSourceFile(/*fileName:*/ "", text, ScriptTarget.Latest, version, /*setNodeParents:*/ true);
}
function assertSameDiagnostics(file1: SourceFile, file2: SourceFile) {
const diagnostics1 = file1.parseDiagnostics;
const diagnostics2 = file2.parseDiagnostics;
assert.equal(diagnostics1.length, diagnostics2.length, "diagnostics1.length !== diagnostics2.length");
for (let i = 0, n = diagnostics1.length; i < n; i++) {
const d1 = diagnostics1[i];
const d2 = diagnostics2[i];
assert.equal(d1.file, file1, "d1.file !== file1");
assert.equal(d2.file, file2, "d2.file !== file2");
assert.equal(d1.start, d2.start, "d1.start !== d2.start");
assert.equal(d1.length, d2.length, "d1.length !== d2.length");
assert.equal(d1.messageText, d2.messageText, "d1.messageText !== d2.messageText");
assert.equal(d1.category, d2.category, "d1.category !== d2.category");
assert.equal(d1.code, d2.code, "d1.code !== d2.code");
}
}
// NOTE: 'reusedElements' is the expected count of elements reused from the old tree to the new
// tree. It may change as we tweak the parser. If the count increases then that should always
// be a good thing. If it decreases, that's not great (less reusability), but that may be
// unavoidable. If it does decrease an investigation should be done to make sure that things
// are still ok and we're still appropriately reusing most of the tree.
function compareTrees(oldText: IScriptSnapshot, newText: IScriptSnapshot, textChangeRange: TextChangeRange, expectedReusedElements: number, oldTree?: SourceFile): SourceFile {
oldTree = oldTree || createTree(oldText, /*version:*/ ".");
Utils.assertInvariants(oldTree, /*parent:*/ undefined);
// Create a tree for the new text, in a non-incremental fashion.
const newTree = createTree(newText, oldTree.version + ".");
Utils.assertInvariants(newTree, /*parent:*/ undefined);
// Create a tree for the new text, in an incremental fashion.
const incrementalNewTree = updateLanguageServiceSourceFile(oldTree, newText, oldTree.version + ".", textChangeRange);
Utils.assertInvariants(incrementalNewTree, /*parent:*/ undefined);
// We should get the same tree when doign a full or incremental parse.
Utils.assertStructuralEquals(newTree, incrementalNewTree);
// We should also get the exact same set of diagnostics.
assertSameDiagnostics(newTree, incrementalNewTree);
// There should be no reused nodes between two trees that are fully parsed.
assert.isTrue(reusedElements(oldTree, newTree) === 0);
assert.equal(newTree.fileName, incrementalNewTree.fileName, "newTree.fileName !== incrementalNewTree.fileName");
assert.equal(newTree.text, incrementalNewTree.text, "newTree.text !== incrementalNewTree.text");
if (expectedReusedElements !== -1) {
const actualReusedCount = reusedElements(oldTree, incrementalNewTree);
assert.equal(actualReusedCount, expectedReusedElements, actualReusedCount + " !== " + expectedReusedElements);
}
return incrementalNewTree;
}
function reusedElements(oldNode: SourceFile, newNode: SourceFile): number {
const allOldElements = collectElements(oldNode);
const allNewElements = collectElements(newNode);
return filter(allOldElements, v => contains(allNewElements, v)).length;
}
function collectElements(node: Node) {
const result: Node[] = [];
visit(node);
return result;
function visit(node: Node) {
result.push(node);
forEachChild(node, visit);
}
}
function deleteCode(source: string, index: number, toDelete: string) {
const repeat = toDelete.length;
let oldTree = createTree(ScriptSnapshot.fromString(source), /*version:*/ ".");
for (let i = 0; i < repeat; i++) {
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, 1);
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree);
source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength());
oldTree = newTree;
}
}
function insertCode(source: string, index: number, toInsert: string) {
const repeat = toInsert.length;
let oldTree = createTree(ScriptSnapshot.fromString(source), /*version:*/ ".");
for (let i = 0; i < repeat; i++) {
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + i, toInsert.charAt(i));
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree);
source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength());
oldTree = newTree;
}
}
describe("Incremental", () => {
it("Inserting into method", () => {
const source = "class C {\r\n" +
" public foo1() { }\r\n" +
" public foo2() {\r\n" +
" return 1;\r\n" +
" }\r\n" +
" public foo3() { }\r\n" +
"}";
const oldText = ScriptSnapshot.fromString(source);
const semicolonIndex = source.indexOf(";");
const newTextAndChange = withInsert(oldText, semicolonIndex, " + 1");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it("Deleting from method", () => {
const source = "class C {\r\n" +
" public foo1() { }\r\n" +
" public foo2() {\r\n" +
" return 1 + 1;\r\n" +
" }\r\n" +
" public foo3() { }\r\n" +
"}";
const index = source.indexOf("+ 1");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, "+ 1".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it("Regular expression 1", () => {
const source = "class C { public foo1() { /; } public foo2() { return 1;} public foo3() { } }";
const semicolonIndex = source.indexOf(";}");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, semicolonIndex, "/");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Regular expression 2", () => {
const source = "class C { public foo1() { ; } public foo2() { return 1/;} public foo3() { } }";
const semicolonIndex = source.indexOf(";");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, semicolonIndex, "/");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Comment 1", () => {
const source = "class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }";
const semicolonIndex = source.indexOf(";");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, semicolonIndex, "/");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Comment 2", () => {
const source = "class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "//");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Comment 3", () => {
const source = "//class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, 2);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Comment 4", () => {
const source = "class C { public foo1() { /; } public foo2() { */ return 1; } public foo3() { } }";
const index = source.indexOf(";");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index, "*");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Parameter 1", () => {
// Should be able to reuse all the parameters.
const source = "class C {\r\n" +
" public foo2(a, b, c, d) {\r\n" +
" return 1;\r\n" +
" }\r\n" +
"}";
const semicolonIndex = source.indexOf(";");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, semicolonIndex, " + 1");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it("Type member 1", () => {
// Should be able to reuse most of the type members.
const source = "interface I { a: number; b: string; (c): d; new (e): f; g(): h }";
const index = source.indexOf(": string");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index, "?");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 14);
});
it("Enum element 1", () => {
// Should be able to reuse most of the enum elements.
const source = "enum E { a = 1, b = 1 << 1, c = 3, e = 4, f = 5, g = 7, h = 8, i = 9, j = 10 }";
const index = source.indexOf("<<");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, 2, "+");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 24);
});
it("Strict mode 1", () => {
const source = "foo1();\r\nfoo1();\r\nfoo1();\r\package();";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "'strict';\r\n");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Strict mode 2", () => {
const source = "foo1();\r\nfoo1();\r\nfoo1();\r\package();";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "'use strict';\r\n");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Strict mode 3", () => {
const source = "'strict';\r\nfoo1();\r\nfoo1();\r\nfoo1();\r\npackage();";
const index = source.indexOf("f");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, index);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Strict mode 4", () => {
const source = "'use strict';\r\nfoo1();\r\nfoo1();\r\nfoo1();\r\npackage();";
const index = source.indexOf("f");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, index);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Strict mode 5", () => {
const source = "'use blahhh';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n";
const index = source.indexOf("b");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, 6, "strict");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 27);
});
it("Strict mode 6", () => {
const source = "'use strict';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n";
const index = source.indexOf("s");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, 6, "blahhh");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 27);
});
it("Strict mode 7", () => {
const source = "'use blahhh';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n";
const index = source.indexOf("f");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, index);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 24);
});
it("Parenthesized expression to arrow function 1", () => {
const source = "var v = (a, b, c, d, e)";
const index = source.indexOf("a");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 1, ":");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Parenthesized expression to arrow function 2", () => {
const source = "var v = (a, b) = c";
const index = source.indexOf("= c") + 1;
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index, ">");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Arrow function to parenthesized expression 1", () => {
const source = "var v = (a:, b, c, d, e)";
const index = source.indexOf(":");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, 1);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Arrow function to parenthesized expression 2", () => {
const source = "var v = (a, b) => c";
const index = source.indexOf(">");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, 1);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Speculative generic lookahead 1", () => {
const source = "var v = F<b>e";
const index = source.indexOf("b");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 1, ",x");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1);
});
it("Speculative generic lookahead 2", () => {
const source = "var v = F<a,b>e";
const index = source.indexOf("b");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 1, ",x");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1);
});
it("Speculative generic lookahead 3", () => {
const source = "var v = F<a,b,c>e";
const index = source.indexOf("b");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 1, ",x");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1);
});
it("Speculative generic lookahead 4", () => {
const source = "var v = F<a,b,c,d>e";
const index = source.indexOf("b");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 1, ",x");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1);
});
it("Assertion to arrow function", () => {
const source = "var v = <T>(a);";
const index = source.indexOf(";");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index, " => 1");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Arrow function to assertion", () => {
const source = "var v = <T>(a) => 1;";
const index = source.indexOf(" =>");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, " => 1".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Contextual shift to shift-equals", () => {
const source = "var v = 1 >> = 2";
const index = source.indexOf(">> =");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index + 2, 1);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Contextual shift-equals to shift", () => {
const source = "var v = 1 >>= 2";
const index = source.indexOf(">>=");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index + 2, " ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Contextual shift to generic invocation", () => {
const source = "var v = T>>(2)";
const index = source.indexOf("T");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, index, "Foo<Bar<");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Test generic invocation to contextual shift", () => {
const source = "var v = Foo<Bar<T>>(2)";
const index = source.indexOf("Foo<Bar<");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, "Foo<Bar<".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Contextual shift to generic type and initializer", () => {
const source = "var v = T>>=2;";
const index = source.indexOf("=");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, "= ".length, ": Foo<Bar<");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Generic type and initializer to contextual shift", () => {
const source = "var v : Foo<Bar<T>>=2;";
const index = source.indexOf(":");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, ": Foo<Bar<".length, "= ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Arithmetic operator to type argument list", () => {
const source = "var v = new Dictionary<A, B>0";
const index = source.indexOf("0");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, index, 1, "()");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Type argument list to arithmetic operator", () => {
const source = "var v = new Dictionary<A, B>()";
const index = source.indexOf("()");
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, index, 2);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Yield context 1", () => {
// We're changing from a non-generator to a genarator. We can't reuse statement nodes.
const source = "function foo() {\r\nyield(foo1);\r\n}";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("foo");
const newTextAndChange = withInsert(oldText, index, "*");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Yield context 2", () => {
// We're changing from a generator to a non-genarator. We can't reuse statement nodes.
const source = "function *foo() {\r\nyield(foo1);\r\n}";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("*");
const newTextAndChange = withDelete(oldText, index, "*".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Delete semicolon", () => {
const source = "export class Foo {\r\n}\r\n\r\nexport var foo = new Foo();\r\n\r\n export function test(foo: Foo) {\r\n return true;\r\n }\r\n";
const oldText = ScriptSnapshot.fromString(source);
const index = source.lastIndexOf(";");
const newTextAndChange = withDelete(oldText, index, 1);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 14);
});
it("Edit after empty type parameter list", () => {
const source = "class Dictionary<> { }\r\nvar y;\r\n";
const oldText = ScriptSnapshot.fromString(source);
const index = source.length;
const newTextAndChange = withInsert(oldText, index, "var x;");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 2);
});
it("Delete parameter after comment", () => {
const source = "function fn(/* comment! */ a: number, c) { }";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("a:");
const newTextAndChange = withDelete(oldText, index, "a: number,".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Modifier added to accessor", () => {
const source =
"class C {\
set Bar(bar:string) {}\
}\
var o2 = { set Foo(val:number) { } };";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("set");
const newTextAndChange = withInsert(oldText, index, "public ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 14);
});
it("Insert parameter ahead of parameter", () => {
const source =
"alert(100);\
\
class OverloadedMonster {\
constructor();\
constructor(name) { }\
}";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("100");
const newTextAndChange = withInsert(oldText, index, "'1', ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7);
});
it("Insert declare modifier before module", () => {
const source =
"module mAmbient {\
module m3 { }\
}";
const oldText = ScriptSnapshot.fromString(source);
const index = 0;
const newTextAndChange = withInsert(oldText, index, "declare ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3);
});
it("Insert function above arrow function with comment", () => {
const source =
"\
() =>\
// do something\
0;";
const oldText = ScriptSnapshot.fromString(source);
const index = 0;
const newTextAndChange = withInsert(oldText, index, "function Foo() { }");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Finish incomplete regular expression", () => {
const source = "while (true) /3; return;";
const oldText = ScriptSnapshot.fromString(source);
const index = source.length - 1;
const newTextAndChange = withInsert(oldText, index, "/");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Regular expression to divide operation", () => {
const source = "return;\r\nwhile (true) /3/g;";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("while");
const newTextAndChange = withDelete(oldText, index, "while ".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Divide operation to regular expression", () => {
const source = "return;\r\n(true) /3/g;";
const oldText = ScriptSnapshot.fromString(source);
const index = source.indexOf("(");
const newTextAndChange = withInsert(oldText, index, "while ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Unterminated comment after keyword converted to identifier", () => {
// 'public' as a keyword should be incrementally unusable (because it has an
// unterminated comment). When we convert it to an identifier, that shouldn't
// change anything, and we should still get the same errors.
const source = "return; a.public /*";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7);
});
it("Class to interface", () => {
const source = "class A { public M1() { } public M2() { } public M3() { } p1 = 0; p2 = 0; p3 = 0 }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "class".length, "interface");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Interface to class", () => {
const source = "interface A { M1?(); M2?(); M3?(); p1?; p2?; p3? }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "interface".length, "class");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Surrounding function declarations with block", () => {
const source = "declare function F1() { } export function F2() { } declare export function F3() { }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "{");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Removing block around function declarations", () => {
const source = "{ declare function F1() { } export function F2() { } declare export function F3() { }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, "{".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Moving methods from class to object literal", () => {
const source = "class C { public A() { } public B() { } public C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "class C".length, "var v =");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Moving methods from object literal to class", () => {
const source = "var v = { public A() { } public B() { } public C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Moving methods from object literal to class in strict mode", () => {
const source = "\"use strict\"; var v = { public A() { } public B() { } public C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 14, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Do not move constructors from class to object-literal.", () => {
const source = "class C { public constructor() { } public constructor() { } public constructor() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "class C".length, "var v =");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Do not move methods called \"constructor\" from object literal to class", () => {
const source = "var v = { public constructor() { } public constructor() { } public constructor() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Moving index signatures from class to interface", () => {
const source = "class C { public [a: number]: string; public [a: number]: string; public [a: number]: string }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "class".length, "interface");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it("Moving index signatures from class to interface in strict mode", () => {
const source = "\"use strict\"; class C { public [a: number]: string; public [a: number]: string; public [a: number]: string }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 14, "class".length, "interface");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it("Moving index signatures from interface to class", () => {
const source = "interface C { public [a: number]: string; public [a: number]: string; public [a: number]: string }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "interface".length, "class");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it("Moving index signatures from interface to class in strict mode", () => {
const source = "\"use strict\"; interface C { public [a: number]: string; public [a: number]: string; public [a: number]: string }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 14, "interface".length, "class");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it("Moving accessors from class to object literal", () => {
const source = "class C { public get A() { } public get B() { } public get C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "class C".length, "var v =");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Moving accessors from object literal to class", () => {
const source = "var v = { public get A() { } public get B() { } public get C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Moving accessors from object literal to class in strict mode", () => {
const source = "\"use strict\"; var v = { public get A() { } public get B() { } public get C() { } }";
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withChange(oldText, 14, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
// Simulated typing tests.
it("Type extends clause 1", () => {
const source = "interface IFoo<T> { }\r\ninterface Array<T> extends IFoo<T> { }";
const index = source.indexOf("extends");
deleteCode(source, index, "extends IFoo<T>");
});
it("Type after incomplete enum 1", () => {
const source = "function foo() {\r\n" +
" function getOccurrencesAtPosition() {\r\n" +
" switch (node) {\r\n" +
" enum \r\n" +
" }\r\n" +
" \r\n" +
" return undefined;\r\n" +
" \r\n" +
" function keywordToReferenceEntry() {\r\n" +
" }\r\n" +
" }\r\n" +
" \r\n" +
" return {\r\n" +
" getEmitOutput: (fileName): Bar => null,\r\n" +
" };\r\n" +
" }";
const index = source.indexOf("enum ") + "enum ".length;
insertCode(source, index, "Fo");
});
});
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,396 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\..\harness\harnessLanguageService.ts" />
namespace ts {
const enum ChangedPart {
references = 1 << 0,
importsAndExports = 1 << 1,
program = 1 << 2
}
const newLine = "\r\n";
interface SourceFileWithText extends SourceFile {
sourceText?: SourceText;
}
interface NamedSourceText {
name: string;
text: SourceText;
}
interface ProgramWithSourceTexts extends Program {
sourceTexts?: NamedSourceText[];
}
class SourceText implements IScriptSnapshot {
private fullText: string;
constructor(private references: string,
private importsAndExports: string,
private program: string,
private changedPart: ChangedPart = 0,
private version = 0) {
}
static New(references: string, importsAndExports: string, program: string): SourceText {
Debug.assert(references !== undefined);
Debug.assert(importsAndExports !== undefined);
Debug.assert(program !== undefined);
return new SourceText(references + newLine, importsAndExports + newLine, program || "");
}
public getVersion(): number {
return this.version;
}
public updateReferences(newReferences: string): SourceText {
Debug.assert(newReferences !== undefined);
return new SourceText(newReferences + newLine, this.importsAndExports, this.program, this.changedPart | ChangedPart.references, this.version + 1);
}
public updateImportsAndExports(newImportsAndExports: string): SourceText {
Debug.assert(newImportsAndExports !== undefined);
return new SourceText(this.references, newImportsAndExports + newLine, this.program, this.changedPart | ChangedPart.importsAndExports, this.version + 1);
}
public updateProgram(newProgram: string): SourceText {
Debug.assert(newProgram !== undefined);
return new SourceText(this.references, this.importsAndExports, newProgram, this.changedPart | ChangedPart.program, this.version + 1);
}
public getFullText() {
return this.fullText || (this.fullText = this.references + this.importsAndExports + this.program);
}
public getText(start: number, end: number): string {
return this.getFullText().substring(start, end);
}
getLength(): number {
return this.getFullText().length;
}
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
const oldText = <SourceText>oldSnapshot;
let oldSpan: TextSpan;
let newLength: number;
switch (oldText.changedPart ^ this.changedPart) {
case ChangedPart.references:
oldSpan = createTextSpan(0, oldText.references.length);
newLength = this.references.length;
break;
case ChangedPart.importsAndExports:
oldSpan = createTextSpan(oldText.references.length, oldText.importsAndExports.length);
newLength = this.importsAndExports.length;
break;
case ChangedPart.program:
oldSpan = createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length);
newLength = this.program.length;
break;
default:
Debug.assert(false, "Unexpected change");
}
return createTextChangeRange(oldSpan, newLength);
}
}
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget): CompilerHost {
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";
},
writeFile(file, text) {
throw new Error("NYI");
},
getCurrentDirectory(): string {
return "";
},
getDirectories(path: string): string[] {
return [];
},
getCanonicalFileName(fileName): string {
return sys && sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
},
useCaseSensitiveFileNames(): boolean {
return sys && sys.useCaseSensitiveFileNames;
},
getNewLine(): string {
return sys ? sys.newLine : newLine;
},
fileExists: fileName => hasProperty(files, fileName),
readFile: fileName => {
const file = lookUp(files, fileName);
return file && file.text;
}
};
}
function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions): Program {
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) {
const texts: NamedSourceText[] = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
updater(texts);
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 (const id in map) {
if (hasProperty(map, id)) {
size++;
}
}
return size;
}
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): void {
assert.isTrue(actual !== undefined);
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): void {
assert.isTrue(actual !== undefined);
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
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 {
const file = program.getSourceFile(fileName);
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
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`);
const actualCacheSize = getSizeOfMap(cache);
const expectedSize = getSizeOfMap(expectedContent);
assert.isTrue(actualCacheSize === expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`);
for (const id in expectedContent) {
if (hasProperty(expectedContent, id)) {
if (expectedContent[id]) {
const expected = expectedContent[id];
const actual = cache[id];
entryChecker(expected, actual);
}
}
else {
assert.isTrue(cache[id] === undefined);
}
}
}
}
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule>): void {
checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule);
}
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map<ResolvedTypeReferenceDirective>): void {
checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective);
}
describe("Reuse program structure", () => {
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`) },
{ 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", () => {
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);
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", () => {
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);
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", () => {
const program_1 = newProgram(files, ["a.ts"], { target });
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);
});
assert.isTrue(!program_1.structureIsReused);
});
it("fails if change affects type references", () => {
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
updateProgram(program_1, ["a.ts"], { types: ["b"] }, files => {
});
assert.isTrue(!program_1.structureIsReused);
});
it("succeeds if change doesn't affect type references", () => {
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
updateProgram(program_1, ["a.ts"], { types: ["a"] }, files => {
});
assert.isTrue(program_1.structureIsReused);
});
it("fails if change affects imports", () => {
const program_1 = newProgram(files, ["a.ts"], { target });
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", () => {
const program_1 = newProgram(files, ["a.ts"], { target });
updateProgram(program_1, ["a.ts"], { target }, files => {
const newReferences = `
/// <reference path='b.ts'/>
/// <reference path='non-existing-file.ts'/>
/// <reference types="typerefs1" />`;
files[0].text = files[0].text.updateReferences(newReferences);
});
assert.isTrue(!program_1.structureIsReused);
});
it("fails if module kind changes", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS });
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0);
assert.isTrue(!program_1.structureIsReused);
});
it("fails if rootdir changes", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
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", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" });
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", () => {
const files = [
{ name: "a.ts", text: SourceText.New("", "import {_} from 'b'", "var x = 1") },
{ name: "b.ts", text: SourceText.New("", "", "var y = 2") },
];
const options: CompilerOptions = { target };
const program_1 = newProgram(files, ["a.ts"], options);
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
checkResolvedModulesCache(program_1, "b.ts", undefined);
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);
// content of resolution cache should not change
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
checkResolvedModulesCache(program_1, "b.ts", undefined);
// imports has changed - program is not reused
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);
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);
});
assert.isTrue(!program_3.structureIsReused);
checkResolvedModulesCache(program_4, "a.ts", { "b": { resolvedFileName: "b.ts" }, "c": undefined });
});
it("resolved type directives cache follows type directives", () => {
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") },
];
const options: CompilerOptions = { target, typeRoots: ["/types"] };
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);
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);
// content of resolution cache should not change
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
// type reference directives has changed - program is not reused
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);
updateProgram(program_3, ["/a.ts"], options, files => {
const newReferences = `/// <reference types="typedefs"/>
/// <reference types="typedefs2"/>
`;
files[0].text = files[0].text.updateReferences(newReferences);
});
assert.isTrue(!program_3.structureIsReused);
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
});
});
describe("host is optional", () => {
it("should work if host is not provided", () => {
createProgram([], {});
});
});
}

View File

@@ -0,0 +1,447 @@
/// <reference path="..\..\harnessLanguageService.ts" />
interface ClassificationEntry {
value: any;
classification: ts.TokenClass;
position?: number;
}
describe("Colorization", function () {
// Use the shim adapter to ensure test coverage of the shim layer for the classifier
const languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false);
const classifier = languageServiceAdapter.getClassifier();
function getEntryAtPosition(result: ts.ClassificationResult, position: number) {
let entryPosition = 0;
for (let i = 0, n = result.entries.length; i < n; i++) {
const entry = result.entries[i];
if (entryPosition === position) {
return entry;
}
entryPosition += entry.length;
}
return undefined;
}
function punctuation(text: string, position?: number) { return createClassification(text, ts.TokenClass.Punctuation, position); }
function keyword(text: string, position?: number) { return createClassification(text, ts.TokenClass.Keyword, position); }
function operator(text: string, position?: number) { return createClassification(text, ts.TokenClass.Operator, position); }
function comment(text: string, position?: number) { return createClassification(text, ts.TokenClass.Comment, position); }
function whitespace(text: string, position?: number) { return createClassification(text, ts.TokenClass.Whitespace, position); }
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 finalEndOfLineState(value: number): ClassificationEntry { return { value: value, classification: undefined, position: 0 }; }
function createClassification(text: string, tokenClass: ts.TokenClass, position?: number): ClassificationEntry {
return {
value: text,
classification: tokenClass,
position: position,
};
}
function testLexicalClassification(text: string, initialEndOfLineState: ts.EndOfLineState, ...expectedEntries: ClassificationEntry[]): void {
const result = classifier.getClassificationsForLine(text, initialEndOfLineState, /*syntacticClassifierAbsent*/ false);
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 {
const actualEntryPosition = expectedEntry.position !== undefined ? expectedEntry.position : text.indexOf(expectedEntry.value);
assert(actualEntryPosition >= 0, "token: '" + expectedEntry.value + "' does not exit in text: '" + text + "'.");
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]);
assert.equal(actualEntry.length, expectedEntry.value.length, "Classification length does not match expected. Expected: " + ts.TokenClass[expectedEntry.value.length] + ", Actual: " + ts.TokenClass[actualEntry.length]);
}
}
}
describe("test getClassifications", function () {
it("Returns correct token classes", function () {
testLexicalClassification("var x: string = \"foo\"; //Hello",
ts.EndOfLineState.None,
keyword("var"),
whitespace(" "),
identifier("x"),
punctuation(":"),
keyword("string"),
operator("="),
stringLiteral("\"foo\""),
comment("//Hello"),
punctuation(";"));
});
it("correctly classifies a comment after a divide operator", function () {
testLexicalClassification("1 / 2 // comment",
ts.EndOfLineState.None,
numberLiteral("1"),
whitespace(" "),
operator("/"),
numberLiteral("2"),
comment("// comment"));
});
it("correctly classifies a literal after a divide operator", function () {
testLexicalClassification("1 / 2, 3 / 4",
ts.EndOfLineState.None,
numberLiteral("1"),
whitespace(" "),
operator("/"),
numberLiteral("2"),
numberLiteral("3"),
numberLiteral("4"),
operator(","));
});
it("correctly classifies a multi-line string with one backslash", function () {
testLexicalClassification("'line1\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\"),
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
});
it("correctly classifies a multi-line string with three backslashes", function () {
testLexicalClassification("'line1\\\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
});
it("correctly classifies an unterminated single-line string with no backslashes", function () {
testLexicalClassification("'line1",
ts.EndOfLineState.None,
stringLiteral("'line1"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated single-line string with two backslashes", function () {
testLexicalClassification("'line1\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated single-line string with four backslashes", function () {
testLexicalClassification("'line1\\\\\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the continuing line of a multi-line string ending in one backslash", function () {
testLexicalClassification("\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\"),
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
});
it("correctly classifies the continuing line of a multi-line string ending in three backslashes", function () {
testLexicalClassification("\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\"),
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
});
it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", function () {
testLexicalClassification(" ",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral(" "),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", function () {
testLexicalClassification("\\\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", function () {
testLexicalClassification("\\\\\\\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of a multi-line string", function () {
testLexicalClassification("'",
ts.EndOfLineState.InSingleQuoteStringLiteral,
stringLiteral("'"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated multiline comment", function () {
testLexicalClassification("/*",
ts.EndOfLineState.None,
comment("/*"),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies the termination of a multiline comment", function () {
testLexicalClassification(" */ ",
ts.EndOfLineState.InMultiLineCommentTrivia,
comment(" */"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the continuation of a multiline comment", function () {
testLexicalClassification("LOREM IPSUM DOLOR ",
ts.EndOfLineState.InMultiLineCommentTrivia,
comment("LOREM IPSUM DOLOR "),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", function () {
testLexicalClassification(" /*/",
ts.EndOfLineState.None,
comment("/*/"),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies an unterminated multiline comment with trailing space", function () {
testLexicalClassification("/* ",
ts.EndOfLineState.None,
comment("/* "),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies a keyword after a dot", function () {
testLexicalClassification("a.var",
ts.EndOfLineState.None,
identifier("var"));
});
it("correctly classifies a string literal after a dot", function () {
testLexicalClassification("a.\"var\"",
ts.EndOfLineState.None,
stringLiteral("\"var\""));
});
it("correctly classifies a keyword after a dot separated by comment trivia", function () {
testLexicalClassification("a./*hello world*/ var",
ts.EndOfLineState.None,
identifier("a"),
punctuation("."),
comment("/*hello world*/"),
identifier("var"));
});
it("classifies a property access with whitespace around the dot", function () {
testLexicalClassification(" x .\tfoo ()",
ts.EndOfLineState.None,
identifier("x"),
identifier("foo"));
});
it("classifies a keyword after a dot on previous line", function () {
testLexicalClassification("var",
ts.EndOfLineState.None,
keyword("var"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies multiple keywords properly", function () {
testLexicalClassification("public static",
ts.EndOfLineState.None,
keyword("public"),
keyword("static"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification("public var",
ts.EndOfLineState.None,
keyword("public"),
identifier("var"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies a single line no substitution template string correctly", () => {
testLexicalClassification("`number number public string`",
ts.EndOfLineState.None,
stringLiteral("`number number public string`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies substitution parts of a template string correctly", () => {
testLexicalClassification("`number '${ 1 + 1 }' string '${ 'hello' }'`",
ts.EndOfLineState.None,
stringLiteral("`number '${"),
numberLiteral("1"),
operator("+"),
numberLiteral("1"),
stringLiteral("}' string '${"),
stringLiteral("'hello'"),
stringLiteral("}'`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies an unterminated no substitution template string correctly", () => {
testLexicalClassification("`hello world",
ts.EndOfLineState.None,
stringLiteral("`hello world"),
finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate));
});
it("classifies the entire line of an unterminated multiline no-substitution/head template", () => {
testLexicalClassification("...",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("..."),
finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate));
});
it("classifies the entire line of an unterminated multiline template middle/end", () => {
testLexicalClassification("...",
ts.EndOfLineState.InTemplateMiddleOrTail,
stringLiteral("..."),
finalEndOfLineState(ts.EndOfLineState.InTemplateMiddleOrTail));
});
it("classifies a termination of a multiline template head", () => {
testLexicalClassification("...${",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("...${"),
finalEndOfLineState(ts.EndOfLineState.InTemplateSubstitutionPosition));
});
it("classifies the termination of a multiline no substitution template", () => {
testLexicalClassification("...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("...`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies the substitution parts and middle/tail of a multiline template string", () => {
testLexicalClassification("${ 1 + 1 }...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("${"),
numberLiteral("1"),
operator("+"),
numberLiteral("1"),
stringLiteral("}...`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies a template middle and propagates the end of line state", () => {
testLexicalClassification("${ 1 + 1 }...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral("${"),
numberLiteral("1"),
operator("+"),
numberLiteral("1"),
stringLiteral("}...`"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies substitution expressions with curly braces appropriately", () => {
let pos = 0;
let lastLength = 0;
testLexicalClassification("...${ () => { } } ${ { x: `1` } }...`",
ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate,
stringLiteral(track("...${"), pos),
punctuation(track(" ", "("), pos),
punctuation(track(")"), pos),
punctuation(track(" ", "=>"), pos),
punctuation(track(" ", "{"), pos),
punctuation(track(" ", "}"), pos),
stringLiteral(track(" ", "} ${"), pos),
punctuation(track(" ", "{"), pos),
identifier(track(" ", "x"), pos),
punctuation(track(":"), pos),
stringLiteral(track(" ", "`1`"), pos),
punctuation(track(" ", "}"), pos),
stringLiteral(track(" ", "}...`"), pos),
finalEndOfLineState(ts.EndOfLineState.None));
// 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 (let i = 0, n = vals.length; i < n; i++) {
pos += lastLength;
lastLength = vals[i].length;
}
return ts.lastOrUndefined(vals);
}
});
it("classifies partially written generics correctly.", function () {
testLexicalClassification("Foo<number",
ts.EndOfLineState.None,
identifier("Foo"),
operator("<"),
identifier("number"),
finalEndOfLineState(ts.EndOfLineState.None));
// Looks like a cast, should get classified as a keyword.
testLexicalClassification("<number",
ts.EndOfLineState.None,
operator("<"),
keyword("number"),
finalEndOfLineState(ts.EndOfLineState.None));
// handle nesting properly.
testLexicalClassification("Foo<Foo,Foo<number",
ts.EndOfLineState.None,
identifier("Foo"),
operator("<"),
identifier("Foo"),
operator(","),
identifier("Foo"),
operator("<"),
identifier("number"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("LexicallyClassifiesConflictTokens", () => {
// Test conflict markers.
testLexicalClassification(
"class C {\r\n\
<<<<<<< HEAD\r\n\
v = 1;\r\n\
=======\r\n\
v = 2;\r\n\
>>>>>>> Branch - a\r\n\
}",
ts.EndOfLineState.None,
keyword("class"),
identifier("C"),
punctuation("{"),
comment("<<<<<<< HEAD"),
identifier("v"),
operator("="),
numberLiteral("1"),
punctuation(";"),
comment("=======\r\n v = 2;\r\n"),
comment(">>>>>>> Branch - a"),
punctuation("}"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification(
"<<<<<<< HEAD\r\n\
class C { }\r\n\
=======\r\n\
class D { }\r\n\
>>>>>>> Branch - a\r\n",
ts.EndOfLineState.None,
comment("<<<<<<< HEAD"),
keyword("class"),
identifier("C"),
punctuation("{"),
punctuation("}"),
comment("=======\r\nclass D { }\r\n"),
comment(">>>>>>> Branch - a"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("'of' keyword", function () {
testLexicalClassification("for (var of of of) { }",
ts.EndOfLineState.None,
keyword("for"),
punctuation("("),
keyword("var"),
keyword("of"),
keyword("of"),
keyword("of"),
punctuation(")"),
punctuation("{"),
punctuation("}"),
finalEndOfLineState(ts.EndOfLineState.None));
});
});
});

View File

@@ -0,0 +1,79 @@
/// <reference path="..\..\harness.ts" />
describe("DocumentRegistry", () => {
it("documents are shared between projects", () => {
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
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", () => {
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;
const f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
compilerOptions.declaration = false;
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;
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;
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;
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", () => {
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
// Simulate one LS getting the document.
documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), /* version */ "1");
// Simulate another LS getting the document at another version.
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", () => {
const documentRegistry = ts.createDocumentRegistry();
const defaultCompilerOptions = ts.getDefaultCompilerOptions();
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.
documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
// Simulate another LS getting that document.
documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
// Now LS1 updates their document.
documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "2");
// Now LS2 tries to update their document.
documentRegistry.updateDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "3");
});
});

View File

@@ -0,0 +1,80 @@
{ input: "function foo () {}", rules: [ ], span: { start: 0, length: 20 }, expected: "function foo() { }" },
{ input: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 349 }, expected: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}" },
{ input: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 379 }, expected: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}" },
{ input: "this . alert( \"Hello, World!\" );", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 32 }, expected: "this.alert( \"Hello, World!\" );" },
{ input: "a\r\n;b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a\r\n; b;" },
{ input: "a\r\n; b;", rules: [ ], span: { start: 0, length: 8 }, expected: "a\r\n; b;" },
{ input: "var a , b;\r\nf(a , b);", rules: [ ], span: { start: 0, length: 40 }, expected: "var a, b;\r\nf(a, b);" },
{ input: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}", rules: [ "SpaceAfterKeywordInControl" ], span: { start: 0, length: 171 }, expected: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}" },
{ input: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}", rules: [ "NoSpaceAfterKeywordInControl" ], span: { start: 0, length: 177 }, expected: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}" },
{ input: "{\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 10 }, expected: "{\r\n (a);\r\n}" },
{ input: "var a=[1,2];\r\nvar b=8>>2 ;\r\nvar c=1+2;", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 14, length: 12 }, expected: "var a=[1,2];\r\nvar b = 8 >> 2;\r\nvar c=1+2;" },
{ input: "if (true) {\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 20 }, expected: "if (true) {\r\n (a);\r\n}" },
{ input: " // var a=[1,2];\r\n /*var a=[3,4];*/\r\n /*\r\n var a=[5,6];\r\n */", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 62 }, expected: "// var a=[1,2];\r\n/*var a=[3,4];*/\r\n/*\r\n var a=[5,6];\r\n */" },
{ input: "f ();", rules: [ ], span: { start: 0, length: 14 }, expected: "f();" },
{ input: "var a = { b: 1 , c: 2 };\r\nvar d = [1 , 2];", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 44 }, expected: "var a = { b: 1, c: 2 };\r\nvar d = [1, 2];" },
{ input: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();", rules: [ ], span: { start: 0, length: 124 }, expected: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();" },
{ input: "function a() { };", rules: [ ], span: { start: 0, length: 20 }, expected: "function a() { };" },
{ input: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 123 }, expected: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];" },
{ input: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 136 }, expected: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];" },
{ input: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 215 }, expected: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}" },
{ input: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 228 }, expected: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}" },
{ input: "function Sum(a, b, c) {\r\nvar d = 1;\r\n}", rules: [ ], span: { start: 0, length: 38 }, expected: "function Sum(a, b, c) {\r\n var d = 1;\r\n}" },
{ input: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };", rules: [ "SpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 76 }, expected: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };" },
{ input: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };", rules: [ "NoSpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 79 }, expected: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };" },
{ input: "function a() {\r\n}b;", rules: [ ], span: { start: 0, length: 19 }, expected: "function a() {\r\n} b;" },
{ input: "function a() {\r\n} b;", rules: [ ], span: { start: 0, length: 21 }, expected: "function a() {\r\n} b;" },
{ input: "function a(){return 0;}\r\nfunction b(){toString();return 0;}", rules: [ ], span: { start: 0, length: 59 }, expected: "function a() { return 0; }\r\nfunction b() { toString(); return 0; }" },
{ input: "for (var i = 0;i < 10;++i) { }", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (var i = 0; i < 10; ++i) { }" },
{ input: "for (var i = 0; i < 10; ++i) { }", rules: [ "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var i = 0;i < 10;++i) { }" },
{ input: "function f() {\r\nif (1)\r\n{\r\nvar a=0;\r\n}\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 41 }, expected: "function f()\n{\r\n if (1) {\r\n var a=0;\r\n }\r\n}" },
{ input: "function a(b) {\r\n a({\r\n});\r\n}", rules: [ ], span: { start: 0, length: 32 }, expected: "function a(b) {\r\n a({\r\n });\r\n}" },
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 3, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 21, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 6, length: 15 }, expected: "eval(\"var a=b[1,2+3];\");" },
{ input: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 404 }, expected: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);" },
{ input: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 356 }, expected: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);" },
{ input: "for (var a = 0; a < 2; ++a) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a)\n{\r\n}" },
{ input: "for (var a = 0; a < 2; ++a)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a) {\r\n}" },
{ input: "function foo(a, b, c) { a = b + c;\n}", rules: [ "NewLineBeforeOpenCurlyInFunction", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 36 }, expected: "function foo(a, b, c)\n{\n a = b + c;\n}" },
{ input: "function a() {\r\n // comment\r\n}", rules: [ ], span: { start: 0, length: 33 }, expected: "function a() {\r\n // comment\r\n}" },
{ input: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}" },
{ input: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}" },
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = ( 0 );\r\nvar b = ( 1 );\r\nvar c = ( 1 + 2 );\r\nvar d = ( ( 1 + 2 ) - ( 3 + 4 ) );\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );" },
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 24 }, expected: "eval(\"var a=b[1,2+3];\");" },
{ input: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b)\r\n\r\n{\r\ni++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 53 }, expected: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b) {\r\n i++;\n}" },
{ input: "for (a in b) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b)\n{\r\n}" },
{ input: "for (a in b)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b) {\r\n}" },
{ input: " var a = { } ; \r\nvar b = { c : d, e : { } };\r\n ", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 59 }, expected: "var a = {};\r\nvar b = { c: d, e: {} };\r\n" },
{ input: "while (true) { }", rules: [ ], span: { start: 0, length: 19 }, expected: "while (true) { }" },
{ input: "for (a in b){ i++; }\r\n\r\nfor (a in b){ i++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 44 }, expected: "for (a in b) { i++; }\r\n\r\nfor (a in b) { i++; }" },
{ input: "function a() {\r\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a()\n{\r\n}" },
{ input: "function a()\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a() {\r\n}" },
{ input: "a;\r\nb;c;\r\nd;", rules: [ ], span: { start: 0, length: 12 }, expected: "a;\r\nb; c;\r\nd;" },
{ input: "a;\r\nb; c;\r\nd;", rules: [ ], span: { start: 0, length: 14 }, expected: "a;\r\nb; c;\r\nd;" },
{ input: " var a = 0;\r\n function b() {\r\n var c = 0;\r\n }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 61 }, expected: "var a = 0;\r\nfunction b() {\r\n var c = 0;\r\n}" },
{ input: "a;b;", rules: [ ], span: { start: 0, length: 4 }, expected: "a; b;" },
{ input: "a; b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a; b;" },
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2) - (3 + 4));\r\n\r\nvar e = (0);\r\nvar f = (1);\r\nvar g = (1 + 2);\r\nvar h = ((1 + 2) - (3 + 4));" },
{ input: "function a() {\r\n(b);\r\n}", rules: [ ], span: { start: 0, length: 23 }, expected: "function a() {\r\n (b);\r\n}" },
{ input: "function test(a) {\n var i;\n for (i = 0;i < 1; i++){ //select\n a++;//select\n }\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "NewLineBeforeOpenCurlyInFunction", "SpaceAfterSemicolonInFor" ], span: { start: 30, length: 50 }, expected: "function test(a) {\n var i;\n for (i = 0; i < 1; i++)\n { //select\n a++;//select\n }\n}" },
{ input: "function a(){ return 1; }", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function a() { return 1; }" },
{ input: "do {\r\n} while (true);", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do\n{\r\n} while (true);" },
{ input: "do\n{\r\n} while (true);", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do {\r\n} while (true);" },
{ input: "for (;;) { a = b + c; b = 2;\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator", "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (;;)\n{\n a = b + c; b = 2;\n}" },
{ input: "var a =0;\r\n\r\n+ 1;\r\n+ a;\r\n+ (1);\r\n+ (+ 1);\r\n+ [1];\r\n+ [+ 1];\r\n+ this.a;\r\n+ new Number(+ 1);\r\n\r\n- 1;\r\n- a;\r\n- (1);\r\n- (- 1);\r\n- [1];\r\n- [- 1];\r\n- this.a;\r\n- new Number(- 1);\r\n\r\n~ 1;\r\n~ a;\r\n~ (1);\r\n~ (~ 1);\r\n~ [1];\r\n~ [~ 1];\r\n~ this.a;\r\n~ new Number(~ 1);\r\n\r\n! 1;\r\n! a;\r\n! (1);\r\n! (! 1);\r\n! [1];\r\n! [! 1];\r\n! this.a;\r\n! new Number(! 1);\r\n\r\n++ a;\r\n++ (a);\r\n++ this.a;\r\n++ new f().a;\r\n\r\n-- a;\r\n-- (a);\r\n-- this.a;\r\n-- new f().a;\r\n\r\na ++;\r\n(a) ++;\r\nthis.a ++;\r\nnew f().a ++;\r\n\r\na --;\r\n(a) --;\r\nthis.a --;\r\nnew f().a --;", rules: [ ], span: { start: 0, length: 513 }, expected: "var a =0;\r\n\r\n+1;\r\n+a;\r\n+(1);\r\n+(+1);\r\n+[1];\r\n+[+1];\r\n+this.a;\r\n+new Number(+1);\r\n\r\n-1;\r\n-a;\r\n-(1);\r\n-(-1);\r\n-[1];\r\n-[-1];\r\n-this.a;\r\n-new Number(-1);\r\n\r\n~1;\r\n~a;\r\n~(1);\r\n~(~1);\r\n~[1];\r\n~[~1];\r\n~this.a;\r\n~new Number(~1);\r\n\r\n!1;\r\n!a;\r\n!(1);\r\n!(!1);\r\n![1];\r\n![!1];\r\n!this.a;\r\n!new Number(!1);\r\n\r\n++a;\r\n++(a);\r\n++this.a;\r\n++new f().a;\r\n\r\n--a;\r\n--(a);\r\n--this.a;\r\n--new f().a;\r\n\r\na++;\r\n(a)++;\r\nthis.a++;\r\nnew f().a++;\r\n\r\na--;\r\n(a)--;\r\nthis.a--;\r\nnew f().a--;" },
{ input: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
{ input: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
{ input: "function a()\r\n\r\n\r\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 22 }, expected: "function a() {\r\n}" },
{ input: "try {\r\n} catch (e) {\r\n} finally {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}" },
{ input: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try {\r\n} catch (e) {\r\n} finally {\r\n}" },
{ input: "with (a) {\r\n b = 0;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a)\n{\r\n b = 0;\r\n}" },
{ input: "with (a)\n{\r\n b = 0;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a) {\r\n b = 0;\r\n}" },
{ input: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 366 }, expected: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }" },
{ input: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 480 }, expected: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }" },
{ input: "function foo()\n\n{ a = 1\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function foo()\n{\n a = 1\n}" },
{ input: "while (true) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true)\n{\r\n}" },
{ input: "while (true)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true) {\r\n}" },
{ input: "var z = 1;\r\n for (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\nfor (k = 0; k < 10; ++k)\r\n{\r\nz++;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 117 }, expected: "var z = 1;\r\nfor (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\n for (k = 0; k < 10; ++k) {\r\n z++;\r\n }" },
{ input: "a++;b++;\nfor (; ; ) {\nx++;m++;\n}", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "a++; b++;\nfor (; ; ) {\n x++; m++;\n}" },
{ input: "var a;\r\n $(document).ready(function() {\r\n alert('hello');\r\n});\r\n", rules: [ ], span: { start: 0, length: 117 }, expected: "var a;\r\n$(document).ready(function () {\r\n alert('hello');\r\n});\r\n" }

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.code
{
font-family: Lucida Console;
font-size: 80%;
}
table
{
border: solid black 1px;
margin-bottom: 2em;
background: #F5F5F5;
padding: 0.5em;
}
th
{
text-align: left;
padding-left: 1em;
}
td
{
vertical-align: top;
padding: 0.75em;
margin: 0.25em;
}
td.test-input
{
background: #DDE;
}
td.test-output
{
background: #FEE;
}
td.test-expected
{
background: #EFE;
}
td.test-operation
{
font-family: inherit;
padding: 0.1em;
}
</style>
<script type="text/javascript">
function copy(code) {
if (window.clipboardData) {
window.clipboardData.setData('Text', decodeURIComponent(code));
} else {
alert(code);
}
}
</script>
</head>
<body>

View File

@@ -0,0 +1,88 @@
///<reference path='_project.ts'/>
describe('getFormattingEditsForRange', function() {
//
// Verify that formatting the typescript file "sourceFileName" results in the
// baseline file "baselineFileName".
//
function getFormattingEditsForRange(sourceFileName: string) {
var baselineFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + "BaseLine.ts";
sourceFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + ".ts";
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addDefaultLibrary();
typescriptLS.addFile(sourceFileName);
var ls = typescriptLS.getLanguageService();
var script = ls.languageService.getScriptAST(sourceFileName);
assert.notNull(script);
var edits = ls.languageService.getFormattingEditsForRange(sourceFileName, 0, script.limChar, new Services.FormatCodeOptions());
typescriptLS.checkEdits(sourceFileName, baselineFileName, edits);
}
describe('test cases for formatting engine', function() {
it("formats typescript constructs properly", function() {
getFormattingEditsForRange('typescriptConstructs');
});
it("formats document ready function properly", function() {
getFormattingEditsForRange('documentReadyFunction');
});
it("formats on closing bracket properly", function() {
getFormattingEditsForRange('onClosingBracket');
});
it("formats various javascript constructs", function() {
getFormattingEditsForRange('various');
});
it("formats main javascript program", function() {
getFormattingEditsForRange('main');
});
it("formats on semicolon properly", function() {
getFormattingEditsForRange('onSemiColon');
});
it("formats enum with trailling tab characters properly", function() {
getFormattingEditsForRange('tabAfterCloseCurly');
});
it("formats object literal", function() {
getFormattingEditsForRange('objectLiteral');
});
it("formats with statements", function() {
getFormattingEditsForRange('withStatement');
});
it("formats ':' and '?' in parameters", function() {
getFormattingEditsForRange('colonAndQMark');
});
it("formats 'import' declaration", function() {
getFormattingEditsForRange('importDeclaration');
});
it("formats exported class with implicit module", function() {
//TODO: this is to force generation of implicit module in AST
var svGenTarget = TypeScript.moduleGenTarget;
try {
TypeScript.moduleGenTarget = TypeScript.ModuleGenTarget.Asynchronous;
getFormattingEditsForRange('implicitModule');
}
finally {
TypeScript.moduleGenTarget = svGenTarget;
}
});
it("formats constructor statements correctelly", function() {
getFormattingEditsForRange('spaceAfterConstructor');
});
it("formats classes and interfaces correctelly", function() {
getFormattingEditsForRange('classes');
});
it("formats modules correctly", function() {
getFormattingEditsForRange('modules');
});
it("formats fat arrow expressions correctelly", function() {
getFormattingEditsForRange('fatArrowFunctions');
});
it("formats empty object/interface literals correctelly", function() {
getFormattingEditsForRange('emptyInterfaceLiteral');
});
it("formats variable declaration lists", function() {
getFormattingEditsForRange('formatVariableDeclarationList');
});
});
});

View File

@@ -0,0 +1,410 @@
///<reference path='_project.ts'/>
describe('getSmartIndentAtLineNumber', function() {
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addDefaultLibrary();
var fileName = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber.ts';
var fileName2 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber2.ts';
var fileName3 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber3.ts';
typescriptLS.addFile(fileName);
typescriptLS.addFile(fileName2);
typescriptLS.addFile(fileName3);
var ls = typescriptLS.getLanguageService();
//
// line is 1-based
//
function getSmartIndent(fileName: string, line: number): number {
assert.is(line >= 1);
var options = new Services.EditorOptions();
var position = typescriptLS.lineColToPosition(fileName, line, 1);
return ls.languageService.getSmartIndentAtLineNumber(fileName, position, options);
}
describe("test cases for smart indent", function() {
it("smart indent inside module", function() {
var result = getSmartIndent(fileName, 2);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside class", function() {
var result = getSmartIndent(fileName, 4);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after property in class", function() {
var result = getSmartIndent(fileName, 6);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent inside method in class ", function() {
var result = getSmartIndent(fileName, 9);
assert.notNull(result);
assert.equal(12, result);
});
it("smart indent after after method in class", function() {
var result = getSmartIndent(fileName, 12);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after class", function() {
var result = getSmartIndent(fileName, 17);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in interface", function() {
var result = getSmartIndent(fileName, 19);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after property in interface", function() {
var result = getSmartIndent(fileName, 21);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after method in interface", function() {
var result = getSmartIndent(fileName, 23);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after interface", function() {
var result = getSmartIndent(fileName, 25);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in nested module", function() {
var result = getSmartIndent(fileName, 27);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after function in nested module", function() {
var result = getSmartIndent(fileName, 30);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after variable in nested module", function() {
var result = getSmartIndent(fileName, 32);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after nested module", function() {
var result = getSmartIndent(fileName, 34);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in enum", function() {
var result = getSmartIndent(fileName, 36);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after variable in enum", function() {
var result = getSmartIndent(fileName, 38);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 2nd variable in enum", function() {
var result = getSmartIndent(fileName, 40);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after enum", function() {
var result = getSmartIndent(fileName, 42);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent after module", function() {
var result = getSmartIndent(fileName, 44);
assert.notNull(result);
assert.equal(0, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent after an aligned function argument", function() {
var result = getSmartIndent(fileName, 47);
assert.notNull(result);
assert.equal(13, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent inside a 'for' statement", function() {
var result = getSmartIndent(fileName, 53);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'for' statement", function() {
var result = getSmartIndent(fileName, 55);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'for in' statement", function() {
var result = getSmartIndent(fileName, 57);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'for in' statement", function() {
var result = getSmartIndent(fileName, 59);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'with' statement", function() {
var result = getSmartIndent(fileName, 61);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'with' statement", function() {
var result = getSmartIndent(fileName, 63);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'switch' statement", function() {
var result = getSmartIndent(fileName, 65);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'switch' statement", function() {
var result = getSmartIndent(fileName, 67);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'break' statement", function() {
var result = getSmartIndent(fileName, 69);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'break' statement", function() {
var result = getSmartIndent(fileName, 71);
assert.notNull(result);
assert.equal(12, result);
});
it("smart indent after a 'break' statement", function() {
var result = getSmartIndent(fileName, 73);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after last 'switch' statement", function() {
var result = getSmartIndent(fileName, 75);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 79);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 81);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 83);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 85);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 87);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 92);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 94);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 96);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 98);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 100);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 104);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 106);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'catch' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 108);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'catch' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 110);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 112);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 114);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 116);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent inside a block inside case", function() {
var result = getSmartIndent(fileName, 127);
assert.notNull(result);
assert.equal(20, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent works for a non terminated argument list at the end of a file", function() {
var result = getSmartIndent(fileName2, 8);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent works for a non terminated if statement at the end of a file", function() {
var result = getSmartIndent(fileName3, 7);
assert.notNull(result);
assert.equal(4, result);
});
});
});

View File

@@ -0,0 +1,212 @@
/// <reference path='..\..\..\..\src\harness\harness.ts'/>
/// <reference path="..\..\..\..\src\services\formatting\formatting.ts"/>
interface DocumentTestJson {
input: string;
rules: string[];
span: { start: number; length: number; };
expected: string;
}
interface FormatOperationTestJson {
input: string;
operations: {
operation: string;
point: { position: number; };
span: { start: number; length: number; };
}[];
expected: string;
}
function markupCodeForHtml(code: string) {
var formatted = code.replace(/</g, '&lt;').replace(/ /g, '&#183;').replace(/\t/g, '&nbsp;&rarr;&nbsp;').replace(/\n/g,'&#8629;<br>');
var escaped = encodeURIComponent(code).replace(/'/g, '%27');
return formatted + '<br><a href="javascript:;" onclick="copy(\'' + escaped + '\');">Copy</a>';
}
describe('importedJavaScriptFormatting - formatting rules', function() {
var documentTests: DocumentTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/documentFormattingTests.json').contents() + ']');
var outputFile = 'diff-1.html';
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
var checkTest = function(test: DocumentTestJson) {
var filename = 'temp.ts';
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addScript(filename, test.input);
var ls = typescriptLS.getLanguageService().languageService;
var unsupportedRules = [];
var ruleMap = {
'SpaceAfterSemicolonInFor': 'InsertSpaceAfterSemicolonInForStatements',
'SpaceAfterComma': 'InsertSpaceAfterCommaDelimiter',
'NewLineBeforeOpenCurlyInControl': 'PlaceOpenBraceOnNewLineForControlBlocks',
'NewLineBeforeOpenCurlyInFunction': 'PlaceOpenBraceOnNewLineForFunctions'
};
var options = new Services.FormatCodeOptions();
if (test.rules.indexOf('SpaceBeforeBinaryOperator') >= 0 && test.rules.indexOf('SpaceAfterBinaryOperator') >= 0) {
test.rules.splice(test.rules.indexOf('SpaceBeforeBinaryOperator'), 1);
test.rules.splice(test.rules.indexOf('SpaceAfterBinaryOperator'), 1);
options.InsertSpaceBeforeAndAfterBinaryOperators = true;
}
test.rules.forEach(ruleName => {
if (options[ruleName] !== undefined) {
// The options struct has a matching property, just set it directly
options[ruleName] = true;
} else {
if (ruleMap[ruleName] !== undefined) {
// We have a remapping of this name, use that instead
options[ruleMap[ruleName]] = true;
} else {
if (ruleName.indexOf('No') === 0) {
// This is a 'NoFoo', set 'Foo' to false
options[ruleMap[ruleName.substr(2)]] = false;
} else {
// ??
IO.printLine('Unsupported rule name ' + ruleName);
return;
}
}
}
});
var edits = ls.getFormattingEditsForRange(filename, test.span.start, test.span.start + test.span.length, options);
var output = typescriptLS.applyEdits(test.input, edits);
// Normalize line endings
output = output.replace(/\r\n/g, '\n');
test.expected = test.expected.replace(/\r\n/g, '\n');
if (output != test.expected) {
var outputHtml = '';
outputHtml += '<table class="test-table">';
outputHtml += '<tr class="test-header-row">';
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-results-row">';
outputHtml += '<td class="test-input code">' + markupCodeForHtml(test.input) + '</td>';
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-operations-row">';
outputHtml += '<td colspan="3">Format from character ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules: ' + test.rules.join(', ') + '</td>';
outputHtml += '</tr>';
outputHtml += '</table>'; // test-table
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
// TODO: Uncomment when things are working
// throw new Error("Formatting failed - refer to diff-1.html");
}
}
var i = 0;
for (var i = 0; i < documentTests.length; i++) {
var test = documentTests[i];
var msg = 'formats the code (index ' + i + ') from ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules = [' + test.rules.join(', ') + '] correctly';
it(msg, function(t) {
return function() {
checkTest(t);
}
}(test));
}
});
describe('importedJavaScriptFormatting - formatting operations', function() {
var outputFile = 'diff-2.html';
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
var checkTest = function(test: FormatOperationTestJson) {
var filename = 'temp.ts';
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addScript(filename, test.input);
var ls = typescriptLS.getLanguageService();
var operationsText = '';
var markedUpInput = test.input;
var output = test.input;
for (var i = 0; i < test.operations.length; i++) {
var options = new Services.FormatCodeOptions();
var op = test.operations[i];
var edits: Services.TextEdit[];
if (op.operation === 'CloseBrace') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '}', options);
operationsText += 'Format for } at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Enter') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '\n', options);
operationsText += 'Format for [enter] at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Semicolon') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, ';', options);
operationsText += 'Format for ; at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Document') {
edits = ls.languageService.getFormattingEditsForRange(filename, 0, output.length, options);
operationsText += 'Format Document';
} else if (op.operation === 'Selection') {
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
operationsText += 'Format selection from ' + op.span.start + ', length = ' + op.span.length;
} else if (op.operation === 'Paste') {
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
operationsText += 'Format pasted content from ' + op.span.start + ', length = ' + op.span.length;
} else {
throw new Error('Unknown operation: ' + op.operation);
}
output = typescriptLS.applyEdits(test.input, edits);
typescriptLS.updateScript(filename, output);
}
// Normalize line endings
output = output.replace(/\r\n/g, '\n');
test.expected = test.expected.replace(/\r\n/g, '\n');
var outputHtml = '';
outputHtml += '<table class="test-table">';
outputHtml += '<tr class="test-header-row">';
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-results-row">';
outputHtml += '<td class="test-input code">' + markupCodeForHtml(markedUpInput) + '</td>';
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-operations-row">';
outputHtml += '<td colspan="3">' + operationsText + '</td>';
outputHtml += '</tr>';
outputHtml += '</table>'; // test-table
if (test.expected == output) {
// Pass
} else {
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
// TODO: Uncomment when things are working
// throw new Error('Format test failed - refer to ' + outputFile);
}
}
var operationsTests: FormatOperationTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/ruleFormattingTests.json').contents() + ']');
for (var i = 0; i < operationsTests.length; i++) {
var test = operationsTests[i];
var msg = 'formats the text correctly, line = ' + i;
it(msg, function(t) {
return function() {
checkTest(t);
}
}(test));
}
});

View File

@@ -0,0 +1,284 @@
{ input: "function a() {\r\nvar b = 0;//}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//}\r\n}" },
{ input: "function foo() {\n do {\n } while (y < 10)\n\n}", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "function foo() {\n do {\n } while (y < 10)\n\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n}\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 87 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n\r\n}" },
{ input: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 76 } } ], expected: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}" },
{ input: " if ( a[\";\"])\r\nb++;", operations: [ { operation: "Semicolon", point: { position: 10 } } ], expected: " if ( a[\";\"])\r\nb++;" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
{ input: "var obj={a:{b:2,c:{d:{e:{\r\n}}}}}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d: {\n e: {\r\n }\n }\n }\n }\n}" },
{ input: "if(1)if(1)if(1)if(1)x+=2;", operations: [ { operation: "Semicolon", point: { position: 25 } } ], expected: "if (1) if (1) if (1) if (1) x += 2;" },
{ input: "\r\nvar webclass = [\r\n { 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]", operations: [ { operation: "Document" } ], expected: "\r\nvar webclass = [\r\n {\n 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]" },
{ input: "function f(x){ return x }\nwhile (f(true))\n y++;\n", operations: [ { operation: "Enter", point: { position: 51 } } ], expected: "function f(x){ return x }\nwhile (f(true))\n y++;\n" },
{ input: "throw e;", operations: [ { operation: "Document" } ], expected: "throw e;" },
{ input: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}", operations: [ { operation: "Document" } ], expected: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}" },
{ input: "return 1;", operations: [ { operation: "Document" } ], expected: "return 1;" },
{ input: "var x = [\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n 1,\n 2,\n 3\n]" },
{ input: "switch \r\n( a ){\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "switch\r\n(a) {\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\n test;\r\n" },
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 16 } } ], expected: "do{\r\ndo{\r\n do {\r\n } while (a !== b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "label1:\r\nvar a;\r\nvar b;", operations: [ { operation: "Document" } ], expected: "label1:\r\n var a;\r\nvar b;" },
{ input: "\r\nfunction a() {\r\nfunction test() // test\r\n{\r\nif (test) // test\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() // test\r\n {\r\n if (test) // test\r\n {\r\n }\r\n }\r\n}" },
{ input: "var obj = {\r\na:{\r\nb:2,c:{\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() +f();\r\n}\r\n}\r\n}\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 94 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\r\n};" },
{ input: "function f() {\r\n do{\r\nx++ }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n do{\r\n x++\n }\r\n\r\n}" },
{ input: "function foo (a, b, c)", operations: [ { operation: "Document" } ], expected: "function foo(a, b, c)" },
{ input: "{ var b;\n}", operations: [ { operation: "Document" } ], expected: "{\n var b;\n}" },
{ input: "var z = {\na: 1};", operations: [ { operation: "Document" } ], expected: "var z = {\n a: 1\n};" },
{ input: "for (var i = 0; i < 10; i++)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) {\n var a\n}" },
{ input: "if (1)\n {\nvar a }", operations: [ { operation: "Document" } ], expected: "if (1) {\n var a\n}" },
{ input: "while (1)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "while (1) {\n var a\n}" },
{ input: "do\n { var a\n} while (1)", operations: [ { operation: "Document" } ], expected: "do {\n var a\n} while (1)" },
{ input: "for (var a in b)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var a in b) {\n var a\n}" },
{ input: "with (x)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "with (x) {\n var a\n}" },
{ input: "try\n { var a\n} \ncatch (e)\n { var a\n} \nfinally\n {\n}", operations: [ { operation: "Document" } ], expected: "try {\n var a\n}\ncatch (e) {\n var a\n}\nfinally {\n}" },
{ input: "switch (x)\n { case 1: { var a }\n}", operations: [ { operation: "Document" } ], expected: "switch (x) {\n case 1: { var a }\n}" },
{ input: "function f()\n { var x\n}", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
{ input: "if(1)if(1)if(1)if(1){x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 28 } } ], expected: "if (1) if (1) if (1) if (1) {\n x += 2\r\n}" },
{ input: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i=0;i<10;i++)\r\ni --;\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 84 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i = 0; i < 10; i++)\r\n i--;\r\n}\r\n" },
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 42 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1);" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++)\r\n{j-=i}}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++)\r\n { j -= i }\n}" },
{ input: "function f() {\r\nstring='string\\r\n line2' + 'other part'}", operations: [ { operation: "CloseBrace", point: { position: 63 } } ], expected: "function f() {\r\n string = 'string\\r\n line2' + 'other part'\n}" },
{ input: "x =\r\n function ()\r\n{\r\n var a\r\n}", operations: [ { operation: "Document" } ], expected: "x =\r\n function () {\r\n var a\r\n }" },
{ input: "if (a instanceof b) { }", operations: [ { operation: "Document" } ], expected: "if (a instanceof b) { }" },
{ input: "do a++; while (0)", operations: [ { operation: "Document" } ], expected: "do a++; while (0)" },
{ input: "foo\r\n(1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo\r\n(1, 2, 3)" },
{ input: "if(1) //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "if (1) //comment\r\n{\r\n}\r\n" },
{ input: "var x =\n [\n1\n]", operations: [ { operation: "Document" } ], expected: "var x =\n [\n1\n ]" },
{ input: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}" },
{ input: "\r\ndefine(null,\r\n function test() {\r\nvar a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\ndefine(null,\r\n function test() {\r\n var a;\r\n }\r\n" },
{ input: "x = [\r\n 1,\r\n\r\n]", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "x = [\r\n 1,\r\n\r\n]" },
{ input: "var x =\n {\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x =\n {\n a: 1\n }" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "function f()\n{\n for (a in b)\n a++;\n}", operations: [ { operation: "Semicolon", point: { position: 40 } } ], expected: "function f()\n{\n for (a in b)\n a++;\n}" },
{ input: "if(x!=1^y===2) \r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 25 } } ], expected: "if(x!=1^y===2) \r\n x += 2\r\n" },
{ input: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\nelse\r\n x+=2\r\n", operations: [ { operation: "Enter", point: { position: 81 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\n else\r\n x += 2\r\n" },
{ input: "switch (a){\r\ncase 1 : x+=2 ; break;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 44 } } ], expected: "switch (a){\r\n case 1: x += 2; break;\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "{ { {\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 19 } } ], expected: "{ { {\r\n {\r\n test\r\n }\r\n}\r\n}\r\n}" },
{ input: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n} while (a !== b)\r\n} while (a !== b)", operations: [ { operation: "Enter", point: { position: 55 } } ], expected: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n } while (a !== b)\r\n} while (a !== b)" },
{ input: "\r\nswitch (t) {\r\n case 1:\r\n{\r\ntest\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (t) {\r\n case 1:\r\n {\r\n test\r\n }\r\n}\r\n" },
{ input: "if (true) {\r\n \r\n}", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n\r\n}" },
{ input: "for(var j=0;j<10;j++)\r\nj-=i;", operations: [ { operation: "Semicolon", point: { position: 28 } } ], expected: "for (var j = 0; j < 10; j++)\r\n j -= i;" },
{ input: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}" },
{ input: "if(1)if(1)if(1)if(1)x+=2\r\n", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) x += 2\r\n" },
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b)\r\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b)\r\n" },
{ input: "foo(\r\n)", operations: [ { operation: "Document" } ], expected: "foo(\r\n)" },
{ input: "function f() {\r\n'use strict';\r\n}", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict';\r\n}" },
{ input: "var x = function() {\n//comment\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x = function () {\n //comment\n return 1;\n}" },
{ input: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }", operations: [ { operation: "Selection", span: { start: 62, length: 120 } } ], expected: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }" },
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 46 } } ], expected: "do {\r\n do {\r\n do {\r\n } while (a !== b)\r\n } while (a !== b)\r\n} while (a !== b)" },
{ input: "if (true)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "if (true)\n // test\n test;" },
{ input: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 56 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\n}" },
{ input: " var a = 0 ;", operations: [ { operation: "Semicolon", point: { position: 14 } } ], expected: "var a = 0;" },
{ input: "var obj={a:{b:2,c:{d:\r\n{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d:\r\n { e: {} }\n }\n }\n}" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 74 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n}" },
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n}\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 96 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\n}" },
{ input: "if (x!=1^y===2){ x+=2}", operations: [ { operation: "CloseBrace", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) { x += 2 }" },
{ input: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n", operations: [ { operation: "Enter", point: { position: 58 } } ], expected: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){\r\nj-=i}}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}" },
{ input: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n }\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 67 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
{ input: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}" },
{ input: "{ { {\r\n{\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 13 } } ], expected: "{ { {\r\n {\r\n }\r\n}\r\n}\r\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\nj -= i}}\r\n", operations: [ { operation: "Enter", point: { position: 78 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}\r\n" },
{ input: "var a = {\r\n}", operations: [ { operation: "Document" } ], expected: "var a = {\r\n}" },
{ input: "\r\n switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 2 } } ], expected: "\r\nswitch (a) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "function a() {\r\nvar b = 0;//;\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//;\r\n}" },
{ input: "for (a in b) { }", operations: [ { operation: "Document" } ], expected: "for (a in b) { }" },
{ input: "\r\n{\r\nfunction test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n// test\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n function test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n // test\r\n }\r\n}\r\n" },
{ input: " //\r\n", operations: [ { operation: "Enter", point: { position: 8 } } ], expected: "//\r\n" },
{ input: " if ( a[\"}\"])\r\nb++;", operations: [ { operation: "CloseBrace", point: { position: 10 } } ], expected: " if ( a[\"}\"])\r\nb++;" },
{ input: "$ ( document ) . ready ( function ( ) { \n alert ( \"i am ready\" ) ;\n } );", operations: [ { operation: "Semicolon", point: { position: 138 } } ], expected: "$(document).ready(function () {\n alert(\"i am ready\");\n});" },
{ input: "function f() {\r\nvar s=\"string\";\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function f() {\r\n var s = \"string\";\r\n}" },
{ input: "do{for(var i=0;i<10;i++)i-=2\r\n}while(1!==1)", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "do {\n for (var i = 0; i < 10; i++) i -= 2\r\n} while (1 !== 1)" },
{ input: "do{\r\ndo{\r\n\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 12 } } ], expected: "do{\r\ndo{\r\n\r\n do {\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 49 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i }}" },
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n } \r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 99 } } ], expected: "var obj = {\r\na: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n}\r\n}" },
{ input: "var a = 0 ;var b=0;var c = 0 ;", operations: [ { operation: "Paste", span: { start: 13, length: 7 } } ], expected: "var a = 0; var b = 0; var c = 0;" },
{ input: "function a()\r\n{\r\n}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "function a()\r\n{\r\n}" },
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 25 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n test\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
{ input: " \r\nfunction a() { \r\n return; \r\n} \r\n ", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n return;\r\n}\r\n" },
{ input: "foo(\r\n1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(\r\n1, 2, 3)" },
{ input: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}" },
{ input: "\r\n //function start\r\n function abc() { }\r\n //function end\r\n", operations: [ { operation: "Document" } ], expected: "\r\n//function start\r\nfunction abc() { }\r\n//function end\r\n" },
{ input: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n\r\n}\r\n}" },
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
{ input: "x = {\r\n a: function() {\r\n},\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n a: function() {\r\n },\r\n\r\n}" },
{ input: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\n x += 2\r\n" },
{ input: "for (a in b) {\nx++;}\n", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "for (a in b) {\n x++;\n}\n" },
{ input: "if(1)if(1)if(1)if(1){x+=2}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) { x += 2 }" },
{ input: "if (x!=1^y===2){ x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (x != 1 ^ y === 2) {\n x += 2\r\n}" },
{ input: "var d = new Date ()", operations: [ { operation: "Document" } ], expected: "var d = new Date()" },
{ input: "do {\r\n} while (1 == 10);", operations: [ { operation: "Document" } ], expected: "do {\r\n} while (1 == 10);" },
{ input: "string='string+=2';", operations: [ { operation: "Semicolon", point: { position: 19 } } ], expected: "string = 'string+=2';" },
{ input: "function foo() {\r\n try {\r\n }\r\ncatch(e){\r\n } finally {\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function foo() {\r\n try {\r\n }\r\n catch (e) {\r\n } finally {\r\n }\r\n}" },
{ input: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n" },
{ input: "function f() {\r\n /**/ var x;\r\n}", operations: [ { operation: "Semicolon", point: { position: 39 } } ], expected: "function f() {\r\n /**/ var x;\r\n}" },
{ input: "if (a)\r\ntest;\r\nelse if (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse if (b)\r\n test;" },
{ input: "foo(1, 2, 3\r\n)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3\r\n)" },
{ input: "\r\nswitch (a){\r\n case 1: x++;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (a) {\r\n case 1: x++;\r\n}\r\n" },
{ input: "x = {\r\n a: function () {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "x = {\r\n a: function () {\r\n\r\n }\r\n}" },
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
{ input: "string='string+=2;'", operations: [ { operation: "Semicolon", point: { position: 18 } } ], expected: "string='string+=2;'" },
{ input: "function test() {\r\n function foo() {\r\n var a;\r\n// some\r\ncomment\r\n", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "function test() {\r\n function foo() {\r\n var a;\r\n // some\r\n comment\r\n" },
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;}\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 89 } } ], expected: "switch (a) {\r\n case 1: x += 2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\n }\r\n }\r\n}" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2;\r\n}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 33 } } ], expected: "do{\r\n for (var i = 0; i < 10; i++)\r\n i -= 2;\r\n}while(1!==1)" },
{ input: "\r\nfunction foo() {\r\n try{ } catch (e) { } finally { }\r\n\r\n\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "\r\nfunction foo() {\r\n try { } catch (e) { } finally { }\r\n\r\n\r\n}\r\n" },
{ input: "do{for(var i=0;i<10;i++)\r\ni-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "do {\n for (var i = 0; i < 10; i++)\r\n i -= 2\n} while (1 !== 1)" },
{ input: "\r\n fun(\r\n {\r\n a: 1\r\n });\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfun(\r\n {\r\n a: 1\r\n });\r\n" },
{ input: "function f () //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "function f() //comment\r\n{\r\n}\r\n" },
{ input: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 94 } } ], expected: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}" },
{ input: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 34 } } ], expected: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}" },
{ input: " \r\n do{\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "\r\ndo {\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
{ input: "function test() {\r\n label1:\r\nvar a\r\n\r\n var b;\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "function test() {\r\n label1:\r\n var a\r\n\r\n var b;\r\n}" },
{ input: "var x = {\n//comment\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x = {\n //comment\n a: 1\n}" },
{ input: "for(var i=0;i<10;i++){\r\n\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "for(var i=0;i<10;i++){\r\n\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n}\r\n}" },
{ input: "if (true) {\r\n//\r\n} else if (false) {\r\n//\r\n} else\r\n if (true)\r\n//", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n //\r\n} else if (false) {\r\n //\r\n} else\r\n if (true)\r\n //" },
{ input: "x = [\n 1,\n 1\n +\n // test\n 2\n]", operations: [ { operation: "Document" } ], expected: "x = [\n 1,\n 1\n +\n // test\n 2\n]" },
{ input: "var x =\n function() {\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x =\n function () {\n return 1;\n }" },
{ input: "function f() {\n var x }", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
{ input: "switch (a) {\r\n case 1: b++;\r\n break ;\r\n\r\n default: a++;\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\r\n case 1: b++;\r\n break;\r\n\r\n default: a++;\r\n break;\r\n}" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}" },
{ input: "function f(a, b\n , c){\n}", operations: [ { operation: "CloseBrace", point: { position: 39 } } ], expected: "function f(a, b\n , c) {\n}" },
{ input: "function add(a, b) { return a + b}", operations: [ { operation: "Document" } ], expected: "function add(a, b) { return a + b }" },
{ input: "var a = 0 ;\r\n", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "var a = 0;\r\n" },
{ input: "var a = function (b) {\r\nb = 0;\r\n}", operations: [ { operation: "CloseBrace", point: { position: 33 } } ], expected: "var a = function (b) {\r\n b = 0;\r\n}" },
{ input: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n" },
{ input: " var a = 0 ;\r\n var b = { } ;\r\n var c = false ;", operations: [ { operation: "Selection", span: { start: 18, length: 34 } } ], expected: " var a = 0 ;\r\n var b = {};\r\n var c = false ;" },
{ input: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 93 } } ], expected: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}" },
{ input: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();", operations: [ { operation: "Document" } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();" },
{ input: "function a() {\r\n /**/ }", operations: [ { operation: "Document" } ], expected: "function a() {\r\n /**/\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\nj=i;\r\n }\r\n}", operations: [ { operation: "Semicolon", point: { position: 64 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\n j = i;\r\n }\r\n}" },
{ input: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}" },
{ input: "foo (1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3)" },
{ input: "if (typeof a == null);", operations: [ { operation: "Document" } ], expected: "if (typeof a == null);" },
{ input: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}" },
{ input: "void x;", operations: [ { operation: "Document" } ], expected: "void x;" },
{ input: "function f() {\r\n string='string'\r\n }\r\n", operations: [ { operation: "Enter", point: { position: 44 } } ], expected: "function f() {\r\n string='string'\r\n}\r\n" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 48 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n} while (1 !== 1);" },
{ input: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}" },
{ input: "for(var i=0;i<10;i++)\r\n{for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (var i = 0; i < 10; i++)\r\n{ for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) { j -= i }\n}" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1)\r\n", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n} while (1 !== 1)\r\n" },
{ input: "if(1===1\r\n&& 2===2)x+=2", operations: [ { operation: "Enter", point: { position: 10 } } ], expected: "if (1 === 1\r\n&& 2 === 2) x += 2" },
{ input: "\r\n{\r\n\r\n/* test\r\n test2\r\n test3 */\r\nvar a,\r\n // test\r\n // test\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n}\r\n\r\na(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n/* test\r\n test2\r\n test3 */\r\nfunction foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n /* test\r\n test2\r\n test3 */\r\n var a,\r\n // test\r\n // test\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n }\r\n\r\n a(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n /* test\r\n test2\r\n test3 */\r\n function foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n }\r\n\r\n}\r\n" },
{ input: "\r\n for (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n }\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfor (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n}\r\n" },
{ input: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;" },
{ input: "x = {\n get foo () {\n },\n set foo (val) {\n }\n};", operations: [ { operation: "Document" } ], expected: "x = {\n get foo() {\n },\n set foo(val) {\n }\n};" },
{ input: "function foo\r\n(a, b, c) {\r\n}", operations: [ { operation: "Document" } ], expected: "function foo\r\n(a, b, c) {\r\n}" },
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;\r\n }}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 80 } } ], expected: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\r\n }\n }\r\n}" },
{ input: "function f() {\r\n'use strict'}", operations: [ { operation: "CloseBrace", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict'\n}" },
{ input: "foo(1\r\n, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1\r\n, 2, 3)" },
{ input: "do{\r\ndo\r\n{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "do{\r\n do\r\n {\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "function Sum(a,b,c) {\r\n for(i=0,j=1,k=0,fib=1;i<5;i++,fib=j+k,k=j,j=fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 49, length: 3 } } ], expected: "function Sum(a,b,c) {\r\n for (i = 0, j = 1, k = 0, fib = 1; i < 5; i++, fib = j + k, k = j, j = fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}" },
{ input: "function a() {\r\n function b() {\r\n\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "function a() {\r\n function b() {\r\n\r\n }\r\n}" },
{ input: "", operations: [ { operation: "Document" } ], expected: "" },
{ input: "function a() {\r\nvar b=\"c\"\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function a() {\r\n var b = \"c\"\r\n\r\n}" },
{ input: " if ( a[\"\r\n\"])\r\nb++;", operations: [ { operation: "Enter", point: { position: 11 } } ], expected: "if ( a[\"\r\n\"])\r\nb++;" },
{ input: "/* \r\n \r\n*/ ", operations: [ { operation: "Document" } ], expected: "/* \r\n \r\n*/" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 75 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n};" },
{ input: "if (1) if (1) a++;", operations: [ { operation: "Document" } ], expected: "if (1) if (1) a++;" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 53 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\n catch (e) {\r\n x += 2\r\n }finally {\r\nx+=2\r\n}\r\n}" },
{ input: "function f() {\r\n'use strict'\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "function f() {\r\n 'use strict'\r\n\r\n}" },
{ input: " \r\n ", operations: [ { operation: "Document" } ], expected: " \r\n " },
{ input: "{ var b; }", operations: [ { operation: "Document" } ], expected: "{ var b; }" },
{ input: "var z = {a: 1};", operations: [ { operation: "Document" } ], expected: "var z = { a: 1 };" },
{ input: "var z =\n {a: 1};", operations: [ { operation: "Document" } ], expected: "var z =\n { a: 1 };" },
{ input: "for (var i = 0; i < 10; i++) { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) { var a }" },
{ input: "for (var i = 0; i < 10; i++)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++)\n{ var a }" },
{ input: "if (1) { var a }", operations: [ { operation: "Document" } ], expected: "if (1) { var a }" },
{ input: "if (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "if (1)\n{ var a }" },
{ input: "while (1) { var a }", operations: [ { operation: "Document" } ], expected: "while (1) { var a }" },
{ input: "while (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "while (1)\n{ var a }" },
{ input: "do { var a } while (1)", operations: [ { operation: "Document" } ], expected: "do { var a } while (1)" },
{ input: "do\n { var a }\n while (1)", operations: [ { operation: "Document" } ], expected: "do\n{ var a }\nwhile (1)" },
{ input: "for (var a in b) { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b) { var a }" },
{ input: "for (var a in b)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b)\n{ var a }" },
{ input: "with (x) { var a }", operations: [ { operation: "Document" } ], expected: "with (x) { var a }" },
{ input: "with (x)\n { var a }", operations: [ { operation: "Document" } ], expected: "with (x)\n{ var a }" },
{ input: "try { var a } \ncatch (e) { var a } \nfinally { }", operations: [ { operation: "Document" } ], expected: "try { var a }\ncatch (e) { var a }\nfinally { }" },
{ input: "try\n { var a } \ncatch (e)\n { var a } \nfinally\n { }", operations: [ { operation: "Document" } ], expected: "try\n{ var a }\ncatch (e)\n{ var a }\nfinally\n{ }" },
{ input: "switch (x) { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x) { case 1: { var a } }" },
{ input: "switch (x)\n { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x)\n{ case 1: { var a } }" },
{ input: "function f() { var x }", operations: [ { operation: "Document" } ], expected: "function f() { var x }" },
{ input: "function f()\n\n { var x }", operations: [ { operation: "Document" } ], expected: "function f()\n\n{ var x }" },
{ input: "function test() {\r\nlabel1:\r\nvar a;\r\nvar b;\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n label1:\r\n var a;\r\n var b;\r\n}" },
{ input: "{\n x =\nfunction () {\n };\n}", operations: [ { operation: "Document" } ], expected: "{\n x =\nfunction () {\n};\n}" },
{ input: "switch (a){\r\n case 1: x+=2;\r\ncase 2 : { \r\nx+=2}\r\n}", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: {\r\n x += 2\n }\r\n}" },
{ input: " // ;", operations: [ { operation: "Semicolon", point: { position: 7 } } ], expected: " // ;" },
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 115 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
{ input: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 46, length: 33 } } ], expected: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}" },
{ input: "if (a in b) { }", operations: [ { operation: "Document" } ], expected: "if (a in b) { }" },
{ input: "\r\nfunction f() {\r\nlabel0:\r\nfor (var i = 0; i < 10; i++) {\r\nlabel1: {\r\nfor (var i = 0; i < 10; i++)\r\nx = 2;\r\nlabel2:\r\nfor (var i = 0; i < 10; i++) {\r\nbreak label2\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction f() {\r\n label0:\r\n for (var i = 0; i < 10; i++) {\r\n label1: {\r\n for (var i = 0; i < 10; i++)\r\n x = 2;\r\n label2:\r\n for (var i = 0; i < 10; i++) {\r\n break label2\r\n }\r\n }\r\n }\r\n}" },
{ input: "function f() {\r\nstring='string'}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function f() {\r\n string = 'string'\n}" },
{ input: "\r\nfunction a() {\r\nfunction test() /* test */\r\n{\r\nif (test) /* test */\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() /* test */ {\r\n if (test) /* test */ {\r\n }\r\n }\r\n}" },
{ input: "that = {\r\n method: function () {\r\n return this.datum;\r\n } , \r\n\r\n datum: 0\r\n};", operations: [ { operation: "Enter", point: { position: 98 } } ], expected: "that = {\r\n method: function () {\r\n return this.datum;\r\n },\r\n\r\n datum: 0\r\n};" },
{ input: "for (; ;)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "for (; ;)\n // test\n test;" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
{ input: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}", operations: [ { operation: "Enter", point: { position: 70 } } ], expected: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}" },
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}};", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } };" },
{ input: "if (1)\r\n x++;\r\nelse x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse x--;" },
{ input: "do{\r\nfor(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++) i -= 2\n} while (1 !== 1)" },
{ input: "switch (a){\r\n case 1,2,3:\r\n break;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "switch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}\r\n" },
{ input: " foo(function (file) {\r\n return 0\r\n })\r\n .then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n})\r\n .then(function (doc) {\r\n return 1\r\n });" },
{ input: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n" },
{ input: "do{for(var i=0;i<10;i++)i-=2}\r\nwhile(1!==1)", operations: [ { operation: "Enter", point: { position: 31 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 }\r\nwhile (1 !== 1)" },
{ input: " function a( b,c ) \r\n {\r\n var d=0 ;\r\n }", operations: [ { operation: "Document" } ], expected: "function a(b, c) {\r\n var d = 0;\r\n}" },
{ input: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}" },
{ input: "if (x!=1^y===2) x+=2\r\n", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) x += 2\r\n" },
{ input: "function f() {\n }", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "function f() {\n}" },
{ input: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n }" },
{ input: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];", operations: [ { operation: "Document" } ], expected: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];" },
{ input: "if (x!=1^y===2) x+=2;", operations: [ { operation: "Semicolon", point: { position: 23 } } ], expected: "if (x != 1 ^ y === 2) x += 2;" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 71 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\n x += 2\r\n}\r\n}" },
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
{ input: "function test() { }\r\n", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function test() { }\r\n" },
{ input: "delete x;", operations: [ { operation: "Document" } ], expected: "delete x;" },
{ input: "\r\n{\r\n\r\nvar a,\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n 2\r\n}\r\n\r\na(1,\r\n 2).\r\n test();\r\n\r\nfunction foo(a, b,\r\n c) {\r\n}\r\n\r\nfor (i = 0;\r\n i < 1;\r\n i++) {\r\n}\r\n\r\nfor (a\r\n in b) {\r\n}\r\n\r\nwhile (i +\r\n 2) {\r\n}\r\n\r\nswitch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n}\r\n\r\ntry {\r\n}\r\ncatch (\r\n e) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n var a,\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n 2\r\n }\r\n\r\n a(1,\r\n 2).\r\n test();\r\n\r\n function foo(a, b,\r\n c) {\r\n }\r\n\r\n for (i = 0;\r\n i < 1;\r\n i++) {\r\n }\r\n\r\n for (a\r\n in b) {\r\n }\r\n\r\n while (i +\r\n 2) {\r\n }\r\n\r\n switch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n }\r\n\r\n try {\r\n }\r\n catch (\r\n e) {\r\n }\r\n\r\n}\r\n" },
{ input: "function f() {\r\n do{\r\nx++ }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 30 } } ], expected: "function f() {\r\n do {\r\n x++\n }\r\n}" },
{ input: "do\r\n{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 4 } } ], expected: "do\r\n{ for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1)" },
{ input: "switch (a){\r\n case 1 :\r\n x+=2\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 28 } } ], expected: "switch (a){\r\n case 1:\r\n x += 2\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "var x = [\n //comment\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n //comment\n 1,\n 2,\n 3\n]" },
{ input: "switch (a){\r\n case 1: x += 2;\r\n\r\ncase 1 : x+=2;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n\r\n case 1: x += 2;\r\n}\r\n" },
{ input: " foo(function (file) {\r\n return 0\r\n }).then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n}).then(function (doc) {\r\n return 1\r\n});" },
{ input: "function f() {\r\nvar s=1 /**/;\r\n}", operations: [ { operation: "Semicolon", point: { position: 30 } } ], expected: "function f() {\r\n var s = 1 /**/;\r\n}" },
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n \r\n}", operations: [ { operation: "Enter", point: { position: 61 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n\r\n}" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2\r\n\r\n\r\n\r\n;", operations: [ { operation: "Semicolon", point: { position: 57 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2\r\n\r\n\r\n\r\n;" },
{ input: "function a() {\r\nvar b = 0;//\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function a() {\r\n var b = 0;//\r\n\r\n}" },
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse\r\n if (b)\r\n test;" },
{ input: "for(var j=0;j<10;j++)j-=i;", operations: [ { operation: "Semicolon", point: { position: 26 } } ], expected: "for (var j = 0; j < 10; j++) j -= i;" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2;", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2;" },
{ input: "function test() {\r\n var a\r\n }", operations: [ { operation: "Document" } ], expected: "function test() {\r\n var a\r\n}" },
{ input: "if (1) {\r\n} else { }", operations: [ { operation: "Document" } ], expected: "if (1) {\r\n} else { }" },
{ input: "function f() {\r\n /*\r\n\r\n */\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n /*\r\n\r\n */\r\n}" },
{ input: "if (x!=1^y===2) \r\n x+=2", operations: [ { operation: "Enter", point: { position: 18 } } ], expected: "if (x != 1 ^ y === 2)\r\n x += 2" },
{ input: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) {}}}}\n", operations: [ { operation: "Enter", point: { position: 88 } } ], expected: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) { }\n }\n }\n}\n" },
{ input: "a=a+\nb+\n c+\n d +\ne +\nm+f;", operations: [ { operation: "Semicolon", point: { position: 100 } } ], expected: "a = a +\nb +\n c +\n d +\ne +\nm + f;" },
{ input: "x = {\r\n get a() {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n get a() {\r\n\r\n }\r\n}" },
{ input: "if(1)\r\n;", operations: [ { operation: "Enter", point: { position: 7 } } ], expected: "if (1)\r\n ;" },
{ input: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}" },
{ input: "string='string+=2\\r\n'", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2\\r\n'" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\n{if(1)\r\nx+=2\r\nelse\r\nx+=2}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "if(1)\r\n if (1)\r\n x++\r\n else {\n if (1)\r\n x += 2\r\n else\r\n x += 2\n }" },
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 19 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2 : { x+=2;}\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 53 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: { x += 2;}\r\n}\r\n" },
{ input: "// ", operations: [ { operation: "Document" } ], expected: "// " },
{ input: "for(var i=0;\r\ni<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "for (var i = 0;\r\ni < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "if (a) if (b) if (c) if (d)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a) if (b) if (c) if (d)\r\n test;" },
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 15 } } ], expected: "do { for (var i = 0;i<10;i++)i-=2}while(1!==1)" },
{ input: "$ ( '#TextBox1' ) . unbind ( ) ;", operations: [ { operation: "Document" } ], expected: "$('#TextBox1').unbind();" },
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b);", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b);" },
{ input: "do{for(var i=0;i<10;i++)i-=2;}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2;}while(1!==1)" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 55 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n}" },
{ input: "function a() {\r\nfunction b() {\r\nfunction c() {\r\n}}}", operations: [ { operation: "CloseBrace", point: { position: 51 } } ], expected: "function a() {\r\n function b() {\r\n function c() {\r\n }\n }\n}" },
{ input: " do do do do\r\n test;\r\n while (0)\r\n while (0)\r\n while (0)\r\n while (0)", operations: [ { operation: "Document" } ], expected: "do do do do\r\n test;\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)" },
{ input: "/**/ ", operations: [ { operation: "Document" } ], expected: "/**/" },
{ input: "function a()\n{ var a\n}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "function a()\n{\n var a\n}" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;\r\nj++){j-=i}}", operations: [ { operation: "Enter", point: { position: 41 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10;\r\n j++) { j -= i }\n}" },
{ input: "function a() {\r\n if (true) {\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 40 } } ], expected: "function a() {\r\n if (true) {\r\n }\r\n\r\n}" },
{ input: "string='string+=2'\r\n", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2'\r\n" },
{ input: "for (a in b) {\r\nx++;}\r\n", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (a in b) {\r\n x++;\n}\r\n" },
{ input: "var obj={a:{b:2,c:{\r\nd:{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\r\n d: { e: {} }\n }\n }\n}" },
{ input: "\r\n// test\r\n\r\n{\r\n// test\r\n}\r\n\r\nfunction foo() {\r\n// test\r\n\r\nswitch (a) {\r\n// test\r\ncase 1:\r\n// test\r\ndefault:\r\n// test\r\n}\r\n\r\nif (false)\r\n// test\r\nifblock;\r\n\r\nif (false) {\r\n//test\r\n}\r\n\r\nif (false) test;\r\nelse\r\n// test\r\ntest;\r\n\r\nif (false) test;\r\nelse {\r\n// test\r\ntest;\r\n}\r\n\r\nfor (; ;)\r\n// test\r\ntest;\r\n\r\nfor (; ;) {\r\n// test\r\nforblock;\r\n}\r\n\r\nfor (a in b)\r\n// test\r\ntest;\r\n\r\nfor (a in b) {\r\n// test\r\ntest\r\n}\r\n\r\nwhile (false)\r\n// test\r\ntest;\r\n\r\nwhile (false) {\r\n// test\r\ntest;\r\n}\r\n\r\nwith (a) {\r\n// test\r\n}\r\n\r\ndo\r\n// test\r\ntestl\r\nwhile (false)\r\n\r\ndo {\r\n// test\r\ntest;\r\n} while (false)\r\n\r\ntry {\r\n// test\r\n} catch (e) {\r\n// test\r\n} finally {\r\n// test\r\n}\r\n\r\n(function () {\r\nvar a = function () {\r\nreturn 1;\r\n},\r\n// This is a comment inline with a multiline statement\r\nb = 2,\r\nc = 3;\r\n})();\r\n\r\n\r\nvar a = {\r\n// test\r\nx: 1,\r\ny: 2 +\r\n// test\r\n3 +\r\n4,\r\n}\r\n\r\n\r\nvar a,\r\n// test\r\nb;\r\n\r\nvar a = [\r\n// test\r\n1,\r\n2,\r\n3\r\n];\r\n\r\na = 1 +\r\n// test\r\n2;\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n// test\r\n\r\n{\r\n // test\r\n}\r\n\r\nfunction foo() {\r\n // test\r\n\r\n switch (a) {\r\n // test\r\n case 1:\r\n // test\r\n default:\r\n // test\r\n }\r\n\r\n if (false)\r\n // test\r\n ifblock;\r\n\r\n if (false) {\r\n //test\r\n }\r\n\r\n if (false) test;\r\n else\r\n // test\r\n test;\r\n\r\n if (false) test;\r\n else {\r\n // test\r\n test;\r\n }\r\n\r\n for (; ;)\r\n // test\r\n test;\r\n\r\n for (; ;) {\r\n // test\r\n forblock;\r\n }\r\n\r\n for (a in b)\r\n // test\r\n test;\r\n\r\n for (a in b) {\r\n // test\r\n test\r\n }\r\n\r\n while (false)\r\n // test\r\n test;\r\n\r\n while (false) {\r\n // test\r\n test;\r\n }\r\n\r\n with (a) {\r\n // test\r\n }\r\n\r\n do\r\n // test\r\n testl\r\n while (false)\r\n\r\n do {\r\n // test\r\n test;\r\n } while (false)\r\n\r\n try {\r\n // test\r\n } catch (e) {\r\n // test\r\n } finally {\r\n // test\r\n }\r\n\r\n (function () {\r\n var a = function () {\r\n return 1;\r\n },\r\n // This is a comment inline with a multiline statement\r\n b = 2,\r\n c = 3;\r\n })();\r\n\r\n\r\n var a = {\r\n // test\r\n x: 1,\r\n y: 2 +\r\n // test\r\n 3 +\r\n 4,\r\n }\r\n\r\n\r\n var a,\r\n // test\r\n b;\r\n\r\n var a = [\r\n // test\r\n 1,\r\n 2,\r\n 3\r\n ];\r\n\r\n a = 1 +\r\n // test\r\n 2;\r\n\r\n}\r\n" },
{ input: " \r\n /* \r\n\r\n a \r\n a\r\n a \r\n a \r\na \r\n \r\n\r\n */ \r\n ", operations: [ { operation: "Document" } ], expected: "\r\n/* \r\n\r\n a \r\n a\r\n a \r\na \r\na \r\n\r\n\r\n*/\r\n" },
{ input: "string='{string +=2}'", operations: [ { operation: "CloseBrace", point: { position: 20 } } ], expected: "string='{string +=2}'" },
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}}\r\n", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } }\r\n" },
{ input: "string='string\\r\n line2'+'other part'\r\n", operations: [ { operation: "Enter", point: { position: 47 } } ], expected: "string='string\\r\n line2' + 'other part'\r\n" },
{ input: " switch( a)\r\n{case 1 :x+=2 ;break\r\n case 2:{\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 13 } } ], expected: "switch (a)\r\n{\n case 1: x += 2; break\r\n case 2:{\r\n }\r\n}" }

View File

@@ -0,0 +1,79 @@
class a {
constructor ( n : number ) ;
constructor ( s : string ) ;
constructor ( ns : any ) {
}
public pgF ( ) { } ;
public pv ;
public get d ( ) {
return 30 ;
}
public set d ( ) {
}
public static get p2 ( ) {
return { x : 30 , y : 40 } ;
}
private static d2 ( ) {
}
private static get p3 ( ) {
return "string" ;
}
private pv3 ;
private foo ( n : number ) : string ;
private foo ( s : string ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor ( n : number ) ;
constructor ( s : string ) ;
public pgF ( ) : void ;
public pv ;
public d : number ;
static p2 : { x : number ; y : number ; } ;
static d2 ( ) ;
static p3 ;
private pv3 ;
private foo ( s ) ;
}
class d {
private foo ( n : number ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
}
class e {
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
private foo ( n : number ) : string ;
}

View File

@@ -0,0 +1,79 @@
class a {
constructor(n: number);
constructor(s: string);
constructor(ns: any) {
}
public pgF() { };
public pv;
public get d() {
return 30;
}
public set d() {
}
public static get p2() {
return { x: 30, y: 40 };
}
private static d2() {
}
private static get p3() {
return "string";
}
private pv3;
private foo(n: number): string;
private foo(s: string): string;
private foo(ns: any) {
return ns.toString();
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor(n: number);
constructor(s: string);
public pgF(): void;
public pv;
public d: number;
static p2: { x: number; y: number; };
static d2();
static p3;
private pv3;
private foo(s);
}
class d {
private foo(n: number): string;
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
}
class e {
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
private foo(n: number): string;
}

View File

@@ -0,0 +1,4 @@
class foo {
constructor (n?: number, m? = 5, o?: string = "") { }
x:number = 1?2:3;
}

View File

@@ -0,0 +1,4 @@
class foo {
constructor(n?: number, m? = 5, o?: string = "") { }
x: number = 1 ? 2 : 3;
}

View File

@@ -0,0 +1,3 @@
$ ( document ) . ready ( function ( ) {
alert ( 'i am ready' ) ;
} );

View File

@@ -0,0 +1,3 @@
$(document).ready(function() {
alert('i am ready');
});

View File

@@ -0,0 +1,10 @@
function foo ( x : { } ) { }
foo ( { } ) ;
interface bar {
x : { } ;
y : ( ) => { } ;
}

View File

@@ -0,0 +1,10 @@
function foo(x: {}) { }
foo({});
interface bar {
x: {};
y: () => {};
}

View File

@@ -0,0 +1,112 @@
// valid
( ) => 1 ;
( arg ) => 2 ;
arg => 2 ;
( arg = 1 ) => 3 ;
( arg ? ) => 4 ;
( arg : number ) => 5 ;
( arg : number = 0 ) => 6 ;
( arg ? : number ) => 7 ;
( ... arg : number [ ] ) => 8 ;
( arg1 , arg2 ) => 12 ;
( arg1 = 1 , arg2 =3 ) => 13 ;
( arg1 ? , arg2 ? ) => 14 ;
( arg1 : number , arg2 : number ) => 15 ;
( arg1 : number = 0 , arg2 : number = 1 ) => 16 ;
( arg1 ? : number , arg2 ? : number ) => 17 ;
( arg1 , ... arg2 : number [ ] ) => 18 ;
( arg1 , arg2 ? : number ) => 19 ;
// in paren
( ( ) => 21 ) ;
( ( arg ) => 22 ) ;
( ( arg = 1 ) => 23 ) ;
( ( arg ? ) => 24 ) ;
( ( arg : number ) => 25 ) ;
( ( arg : number = 0 ) => 26 ) ;
( ( arg ? : number ) => 27 ) ;
( ( ... arg : number [ ] ) => 28 ) ;
// in multiple paren
( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ;
// in ternary exression
false ? ( ) => 41 : null ;
false ? ( arg ) => 42 : null ;
false ? ( arg = 1 ) => 43 : null ;
false ? ( arg ? ) => 44 : null ;
false ? ( arg : number ) => 45 : null ;
false ? ( arg ? : number ) => 46 : null ;
false ? ( arg ? : number = 0 ) => 47 : null ;
false ? ( ... arg : number [ ] ) => 48 : null ;
// in ternary exression within paren
false ? ( ( ) => 51 ) : null ;
false ? ( ( arg ) => 52 ) : null ;
false ? ( ( arg = 1 ) => 53 ) : null ;
false ? ( ( arg ? ) => 54 ) : null ;
false ? ( ( arg : number ) => 55 ) : null ;
false ? ( ( arg ? : number ) => 56 ) : null ;
false ? ( ( arg ? : number = 0 ) => 57 ) : null ;
false ? ( ( ... arg : number [ ] ) => 58 ) : null ;
// ternary exression's else clause
false ? null : ( ) => 61 ;
false ? null : ( arg ) => 62 ;
false ? null : ( arg = 1 ) => 63 ;
false ? null : ( arg ? ) => 64 ;
false ? null : ( arg : number ) => 65 ;
false ? null : ( arg ? : number ) => 66 ;
false ? null : ( arg ? : number = 0 ) => 67 ;
false ? null : ( ... arg : number [ ] ) => 68 ;
// nested ternary expressions
( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ;
//multiple levels
( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ;
// In Expressions
( ( arg ) => 90 ) instanceof Function ;
( ( arg = 1 ) => 91 ) instanceof Function ;
( ( arg ? ) => 92 ) instanceof Function ;
( ( arg : number ) => 93 ) instanceof Function ;
( ( arg : number = 1 ) => 94 ) instanceof Function ;
( ( arg ? : number ) => 95 ) instanceof Function ;
( ( ... arg : number [ ] ) => 96 ) instanceof Function ;
'' + ( arg ) => 100 ;
( ( arg ) => 0 ) + '' + ( arg ) => 101 ;
( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ;
( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ;
( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ;
( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ;
( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ;
( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ;
( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ;
( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ;
// Function Parameters
function foo ( ... arg : any [ ] ) { }
foo (
( a ) => 110 ,
( ( a ) => 111 ) ,
( a ) => {
return 112 ;
} ,
( a ? ) => 113 ,
( a , b ? ) => 114 ,
( a : number ) => 115 ,
( a : number = 0 ) => 116 ,
( a = 0 ) => 117 ,
( a ? : number = 0 ) => 118 ,
( a ? , b ? : number = 0 ) => 118 ,
( ... a : number [ ] ) => 119 ,
( a , b ? = 0 , ... c : number [ ] ) => 120 ,
( a ) => ( b ) => ( c ) => 121 ,
false ? ( a ) => 0 : ( b ) => 122
) ;

View File

@@ -0,0 +1,112 @@
// valid
() => 1;
(arg) => 2;
arg => 2;
(arg = 1) => 3;
(arg?) => 4;
(arg: number) => 5;
(arg: number = 0) => 6;
(arg?: number) => 7;
(...arg: number[]) => 8;
(arg1, arg2) => 12;
(arg1 = 1, arg2 = 3) => 13;
(arg1?, arg2?) => 14;
(arg1: number, arg2: number) => 15;
(arg1: number = 0, arg2: number = 1) => 16;
(arg1?: number, arg2?: number) => 17;
(arg1, ...arg2: number[]) => 18;
(arg1, arg2?: number) => 19;
// in paren
(() => 21);
((arg) => 22);
((arg = 1) => 23);
((arg?) => 24);
((arg: number) => 25);
((arg: number = 0) => 26);
((arg?: number) => 27);
((...arg: number[]) => 28);
// in multiple paren
(((((arg) => { return 32; }))));
// in ternary exression
false ? () => 41 : null;
false ? (arg) => 42 : null;
false ? (arg = 1) => 43 : null;
false ? (arg?) => 44 : null;
false ? (arg: number) => 45 : null;
false ? (arg?: number) => 46 : null;
false ? (arg?: number = 0) => 47 : null;
false ? (...arg: number[]) => 48 : null;
// in ternary exression within paren
false ? (() => 51) : null;
false ? ((arg) => 52) : null;
false ? ((arg = 1) => 53) : null;
false ? ((arg?) => 54) : null;
false ? ((arg: number) => 55) : null;
false ? ((arg?: number) => 56) : null;
false ? ((arg?: number = 0) => 57) : null;
false ? ((...arg: number[]) => 58) : null;
// ternary exression's else clause
false ? null : () => 61;
false ? null : (arg) => 62;
false ? null : (arg = 1) => 63;
false ? null : (arg?) => 64;
false ? null : (arg: number) => 65;
false ? null : (arg?: number) => 66;
false ? null : (arg?: number = 0) => 67;
false ? null : (...arg: number[]) => 68;
// nested ternary expressions
(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; };
//multiple levels
(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82;
// In Expressions
((arg) => 90) instanceof Function;
((arg = 1) => 91) instanceof Function;
((arg?) => 92) instanceof Function;
((arg: number) => 93) instanceof Function;
((arg: number = 1) => 94) instanceof Function;
((arg?: number) => 95) instanceof Function;
((...arg: number[]) => 96) instanceof Function;
'' + (arg) => 100;
((arg) => 0) + '' + (arg) => 101;
((arg = 1) => 0) + '' + (arg = 2) => 102;
((arg?) => 0) + '' + (arg?) => 103;
((arg: number) => 0) + '' + (arg: number) => 104;
((arg: number = 1) => 0) + '' + (arg: number = 2) => 105;
((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106;
((...arg: number[]) => 0) + '' + (...arg: number[]) => 107;
((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108;
((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108;
// Function Parameters
function foo(...arg: any[]) { }
foo(
(a) => 110,
((a) => 111),
(a) => {
return 112;
},
(a?) => 113,
(a, b?) => 114,
(a: number) => 115,
(a: number = 0) => 116,
(a = 0) => 117,
(a?: number = 0) => 118,
(a?, b?: number = 0) => 118,
(...a: number[]) => 119,
(a, b? = 0, ...c: number[]) => 120,
(a) => (b) => (c) => 121,
false ? (a) => 0 : (b) => 122
);

View File

@@ -0,0 +1,2 @@
if(false){debugger;}
if ( false ) { debugger ; }

View File

@@ -0,0 +1,2 @@
if (false) { debugger; }
if (false) { debugger; }

View File

@@ -0,0 +1,13 @@
var fun1 = function ( ) {
var x = 'foo' ,
z = 'bar' ;
return x ;
},
fun2 = ( function ( f ) {
var fun = function ( ) {
console . log ( f ( ) ) ;
},
x = 'Foo' ;
return fun ;
} ( fun1 ) ) ;

View File

@@ -0,0 +1,13 @@
var fun1 = function() {
var x = 'foo',
z = 'bar';
return x;
},
fun2 = (function(f) {
var fun = function() {
console.log(f());
},
x = 'Foo';
return fun;
} (fun1));

View File

@@ -0,0 +1,3 @@
export class A {
}

View File

@@ -0,0 +1,3 @@
export class A {
}

View File

@@ -0,0 +1,6 @@
module Foo {
}
import bar = Foo;
import bar2=Foo;

View File

@@ -0,0 +1,6 @@
module Foo {
}
import bar = Foo;
import bar2 = Foo;

View File

@@ -0,0 +1,95 @@
var a;var c , b;var $d
var $e
var f
a++;b++;
function f ( ) {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m (a[b[c][d]])];
break;
switch ( variable){
case 1: abc += 425;
break;
case 404 : a [x--/2]%=3 ;
break ;
case vari : v[--x ] *=++y*( m + n / k[z]);
for (a in b){
for (a = 0; a < 10; ++a) {
a++;--a;
if (a == b) {
a++;b--;
}
else
if (a == c){
++a;
(--c)+=d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--;++b;
a++
}
}
}
for (x in y) {
m-=m;
k=1+2+3+4;
}
}
break;
}
}
var a ={b:function(){}};
return {a:1,b:2}
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready ();
function pageLoad() {
$('#TextBox1' ) . unbind ( ) ;
$('#TextBox1' ) . datepicker ( ) ;
}
function pageLoad ( ) {
var webclass=[
{ 'student' :
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
} ,
{ 'student':
{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'}
} ,
{ 'student':
{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'}
}
];
$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList'));
}
$( document ).ready(function(){
alert('hello');
} ) ;

View File

@@ -0,0 +1,98 @@
var a; var c, b; var $d
var $e
var f
a++; b++;
function f() {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m(a[b[c][d]])];
break;
switch (variable) {
case 1: abc += 425;
break;
case 404: a[x-- / 2] %= 3;
break;
case vari: v[--x] *= ++y * (m + n / k[z]);
for (a in b) {
for (a = 0; a < 10; ++a) {
a++; --a;
if (a == b) {
a++; b--;
}
else
if (a == c) {
++a;
(--c) += d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--; ++b;
a++
}
}
}
for (x in y) {
m -= m;
k = 1 + 2 + 3 + 4;
}
}
break;
}
}
var a = { b: function() { } };
return { a: 1, b: 2 }
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready();
function pageLoad() {
$('#TextBox1').unbind();
$('#TextBox1').datepicker();
}
function pageLoad() {
var webclass = [
{
'student':
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
},
{
'student':
{ 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' }
},
{
'student':
{ 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' }
}
];
$create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList'));
}
$(document).ready(function() {
alert('hello');
});

View File

@@ -0,0 +1,3 @@
module Foo {
export module A . B . C { }
}

View File

@@ -0,0 +1,3 @@
module Foo {
export module A.B.C { }
}

View File

@@ -0,0 +1,76 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
} ;
var x : d ;
export function foo ( ) : d ;
}
import m4 = module ( "m4" ) ;
export var x4 = m4.x ;
export var d4 = m4.d ;
export var f4 = m4.foo ( ) ;
export module m1 {
declare export module "m2" {
export class d {
} ;
var x: d ;
export function foo ( ) : d ;
}
import m2 = module ( "m2" ) ;
import m3 = module ( "m4" ) ;
export var x2 = m2.x ;
export var d2 = m2.d ;
export var f2 = m2.foo ( ) ;
export var x3 = m3.x ;
export var d3 = m3.d ;
export var f3 = m3.foo ( ) ;
}
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
export module m5 {
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
}

View File

@@ -0,0 +1,76 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
};
var x: d;
export function foo(): d;
}
import m4 = module("m4");
export var x4 = m4.x;
export var d4 = m4.d;
export var f4 = m4.foo();
export module m1 {
declare export module "m2" {
export class d {
};
var x: d;
export function foo(): d;
}
import m2 = module("m2");
import m3 = module("m4");
export var x2 = m2.x;
export var d2 = m2.d;
export var f2 = m2.foo();
export var x3 = m3.x;
export var d3 = m3.d;
export var f3 = m3.foo();
}
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
export module m5 {
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
}

View File

@@ -0,0 +1,27 @@
var x = {foo: 1,
bar: "tt",
boo: 1 + 5};
var x2 = {foo: 1,
bar: "tt",boo:1+5};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b : 2}
};
var x={ };
var y = {};

View File

@@ -0,0 +1,31 @@
var x = {
foo: 1,
bar: "tt",
boo: 1 + 5
};
var x2 = {
foo: 1,
bar: "tt", boo: 1 + 5
};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b: 2 }
};
var x = {};
var y = {};

View File

@@ -0,0 +1,32 @@
function f( ) {
var x = 3;
var z = 2 ;
a = z ++ - 2 * x ;
for ( ; ; ) {
a+=(g +g)*a%t;
b -- ;
}
switch ( a )
{
case 1 : {
a ++ ;
b--;
if(a===a)
return;
else
{
for(a in b)
if(a!=a)
{
for(a in b)
{
a++;
}
}
}
}
default:
break;
}
}

View File

@@ -0,0 +1,28 @@
function f() {
var x = 3;
var z = 2;
a = z++ - 2 * x;
for (; ;) {
a += (g + g) * a % t;
b--;
}
switch (a) {
case 1: {
a++;
b--;
if (a === a)
return;
else {
for (a in b)
if (a != a) {
for (a in b) {
a++;
}
}
}
}
default:
break;
}
}

View File

@@ -0,0 +1 @@
var a=b+c^d-e*++f;

View File

@@ -0,0 +1 @@
var a = b + c ^ d - e * ++f;

View File

@@ -0,0 +1 @@
class test { constructor () { } }

View File

@@ -0,0 +1 @@
class test { constructor() { } }

View File

@@ -0,0 +1,10 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob
{
Blah=1, Bleah=2
}
}

View File

@@ -0,0 +1,9 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob {
Blah = 1, Bleah = 2
}
}

View File

@@ -0,0 +1,65 @@
module MyModule
{
module A.B.C {
module F {
}
}
interface Blah
{
boo: string;
}
class Foo
{
}
class Foo2 {
public foo():number {
return 5 * 6;
}
public foo2() {
if (1 === 2)
{
var y : number= 76;
return y;
}
while (2 == 3) {
if ( y == null ) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a:number, b:number):number
{
return 0;
}
function bar(a:number, b:number) :number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View File

@@ -0,0 +1,58 @@
module MyModule {
module A.B.C {
module F {
}
}
interface Blah {
boo: string;
}
class Foo {
}
class Foo2 {
public foo(): number {
return 5 * 6;
}
public foo2() {
if (1 === 2) {
var y: number = 76;
return y;
}
while (2 == 3) {
if (y == null) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a: number, b: number): number {
return 0;
}
function bar(a: number, b: number): number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View File

@@ -0,0 +1,17 @@
function f(a,b,c,d){
for(var i=0;i<10;i++){
var a=0;
var b=a+a+a*a%a/2-1;
b+=a;
++b;
f(a,b,c,d);
if(1===1){
var m=function(e,f){
return e^f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}

View File

@@ -0,0 +1,17 @@
function f(a, b, c, d) {
for (var i = 0; i < 10; i++) {
var a = 0;
var b = a + a + a * a % a / 2 - 1;
b += a;
++b;
f(a, b, c, d);
if (1 === 1) {
var m = function(e, f) {
return e ^ f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}

View File

@@ -0,0 +1,9 @@
with (foo.bar)
{
}
with (bar.blah)
{
}

View File

@@ -0,0 +1,6 @@
with (foo.bar) {
}
with (bar.blah) {
}

View File

@@ -0,0 +1,79 @@
class a {
constructor ( n : number ) ;
constructor ( s : string ) ;
constructor ( ns : any ) {
}
public pgF ( ) { } ;
public pv ;
public get d ( ) {
return 30 ;
}
public set d ( ) {
}
public static get p2 ( ) {
return { x : 30 , y : 40 } ;
}
private static d2 ( ) {
}
private static get p3 ( ) {
return "string" ;
}
private pv3 ;
private foo ( n : number ) : string ;
private foo ( s : string ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor ( n : number ) ;
constructor ( s : string ) ;
public pgF ( ) : void ;
public pv ;
public d : number ;
static p2 : { x : number ; y : number ; } ;
static d2 ( ) ;
static p3 ;
private pv3 ;
private foo ( s ) ;
}
class d {
private foo ( n : number ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
}
class e {
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
private foo ( n : number ) : string ;
}

View File

@@ -0,0 +1,79 @@
class a {
constructor(n: number);
constructor(s: string);
constructor(ns: any) {
}
public pgF() { };
public pv;
public get d() {
return 30;
}
public set d() {
}
public static get p2() {
return { x: 30, y: 40 };
}
private static d2() {
}
private static get p3() {
return "string";
}
private pv3;
private foo(n: number): string;
private foo(s: string): string;
private foo(ns: any) {
return ns.toString();
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor(n: number);
constructor(s: string);
public pgF(): void;
public pv;
public d: number;
static p2: { x: number; y: number; };
static d2();
static p3;
private pv3;
private foo(s);
}
class d {
private foo(n: number): string;
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
}
class e {
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
private foo(n: number): string;
}

View File

@@ -0,0 +1,4 @@
class foo {
constructor (n?: number, m? = 5, o?: string = "") { }
x:number = 1?2:3;
}

View File

@@ -0,0 +1,4 @@
class foo {
constructor(n?: number, m? = 5, o?: string = "") { }
x: number = 1 ? 2 : 3;
}

View File

@@ -0,0 +1,3 @@
$ ( document ) . ready ( function ( ) {
alert ( 'i am ready' ) ;
} );

View File

@@ -0,0 +1,3 @@
$(document).ready(function() {
alert('i am ready');
});

View File

@@ -0,0 +1,10 @@
function foo ( x : { } ) { }
foo ( { } ) ;
interface bar {
x : { } ;
y : ( ) => { } ;
}

View File

@@ -0,0 +1,10 @@
function foo(x: {}) { }
foo({});
interface bar {
x: {};
y: () => {};
}

View File

@@ -0,0 +1,112 @@
// valid
( ) => 1 ;
( arg ) => 2 ;
arg => 2 ;
( arg = 1 ) => 3 ;
( arg ? ) => 4 ;
( arg : number ) => 5 ;
( arg : number = 0 ) => 6 ;
( arg ? : number ) => 7 ;
( ... arg : number [ ] ) => 8 ;
( arg1 , arg2 ) => 12 ;
( arg1 = 1 , arg2 =3 ) => 13 ;
( arg1 ? , arg2 ? ) => 14 ;
( arg1 : number , arg2 : number ) => 15 ;
( arg1 : number = 0 , arg2 : number = 1 ) => 16 ;
( arg1 ? : number , arg2 ? : number ) => 17 ;
( arg1 , ... arg2 : number [ ] ) => 18 ;
( arg1 , arg2 ? : number ) => 19 ;
// in paren
( ( ) => 21 ) ;
( ( arg ) => 22 ) ;
( ( arg = 1 ) => 23 ) ;
( ( arg ? ) => 24 ) ;
( ( arg : number ) => 25 ) ;
( ( arg : number = 0 ) => 26 ) ;
( ( arg ? : number ) => 27 ) ;
( ( ... arg : number [ ] ) => 28 ) ;
// in multiple paren
( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ;
// in ternary exression
false ? ( ) => 41 : null ;
false ? ( arg ) => 42 : null ;
false ? ( arg = 1 ) => 43 : null ;
false ? ( arg ? ) => 44 : null ;
false ? ( arg : number ) => 45 : null ;
false ? ( arg ? : number ) => 46 : null ;
false ? ( arg ? : number = 0 ) => 47 : null ;
false ? ( ... arg : number [ ] ) => 48 : null ;
// in ternary exression within paren
false ? ( ( ) => 51 ) : null ;
false ? ( ( arg ) => 52 ) : null ;
false ? ( ( arg = 1 ) => 53 ) : null ;
false ? ( ( arg ? ) => 54 ) : null ;
false ? ( ( arg : number ) => 55 ) : null ;
false ? ( ( arg ? : number ) => 56 ) : null ;
false ? ( ( arg ? : number = 0 ) => 57 ) : null ;
false ? ( ( ... arg : number [ ] ) => 58 ) : null ;
// ternary exression's else clause
false ? null : ( ) => 61 ;
false ? null : ( arg ) => 62 ;
false ? null : ( arg = 1 ) => 63 ;
false ? null : ( arg ? ) => 64 ;
false ? null : ( arg : number ) => 65 ;
false ? null : ( arg ? : number ) => 66 ;
false ? null : ( arg ? : number = 0 ) => 67 ;
false ? null : ( ... arg : number [ ] ) => 68 ;
// nested ternary expressions
( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ;
//multiple levels
( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ;
// In Expressions
( ( arg ) => 90 ) instanceof Function ;
( ( arg = 1 ) => 91 ) instanceof Function ;
( ( arg ? ) => 92 ) instanceof Function ;
( ( arg : number ) => 93 ) instanceof Function ;
( ( arg : number = 1 ) => 94 ) instanceof Function ;
( ( arg ? : number ) => 95 ) instanceof Function ;
( ( ... arg : number [ ] ) => 96 ) instanceof Function ;
'' + ( arg ) => 100 ;
( ( arg ) => 0 ) + '' + ( arg ) => 101 ;
( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ;
( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ;
( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ;
( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ;
( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ;
( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ;
( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ;
( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ;
// Function Parameters
function foo ( ... arg : any [ ] ) { }
foo (
( a ) => 110 ,
( ( a ) => 111 ) ,
( a ) => {
return 112 ;
} ,
( a ? ) => 113 ,
( a , b ? ) => 114 ,
( a : number ) => 115 ,
( a : number = 0 ) => 116 ,
( a = 0 ) => 117 ,
( a ? : number = 0 ) => 118 ,
( a ? , b ? : number = 0 ) => 118 ,
( ... a : number [ ] ) => 119 ,
( a , b ? = 0 , ... c : number [ ] ) => 120 ,
( a ) => ( b ) => ( c ) => 121 ,
false ? ( a ) => 0 : ( b ) => 122
) ;

View File

@@ -0,0 +1,112 @@
// valid
() => 1;
(arg) => 2;
arg => 2;
(arg = 1) => 3;
(arg?) => 4;
(arg: number) => 5;
(arg: number = 0) => 6;
(arg?: number) => 7;
(...arg: number[]) => 8;
(arg1, arg2) => 12;
(arg1 = 1, arg2 = 3) => 13;
(arg1?, arg2?) => 14;
(arg1: number, arg2: number) => 15;
(arg1: number = 0, arg2: number = 1) => 16;
(arg1?: number, arg2?: number) => 17;
(arg1, ...arg2: number[]) => 18;
(arg1, arg2?: number) => 19;
// in paren
(() => 21);
((arg) => 22);
((arg = 1) => 23);
((arg?) => 24);
((arg: number) => 25);
((arg: number = 0) => 26);
((arg?: number) => 27);
((...arg: number[]) => 28);
// in multiple paren
(((((arg) => { return 32; }))));
// in ternary exression
false ? () => 41 : null;
false ? (arg) => 42 : null;
false ? (arg = 1) => 43 : null;
false ? (arg?) => 44 : null;
false ? (arg: number) => 45 : null;
false ? (arg?: number) => 46 : null;
false ? (arg?: number = 0) => 47 : null;
false ? (...arg: number[]) => 48 : null;
// in ternary exression within paren
false ? (() => 51) : null;
false ? ((arg) => 52) : null;
false ? ((arg = 1) => 53) : null;
false ? ((arg?) => 54) : null;
false ? ((arg: number) => 55) : null;
false ? ((arg?: number) => 56) : null;
false ? ((arg?: number = 0) => 57) : null;
false ? ((...arg: number[]) => 58) : null;
// ternary exression's else clause
false ? null : () => 61;
false ? null : (arg) => 62;
false ? null : (arg = 1) => 63;
false ? null : (arg?) => 64;
false ? null : (arg: number) => 65;
false ? null : (arg?: number) => 66;
false ? null : (arg?: number = 0) => 67;
false ? null : (...arg: number[]) => 68;
// nested ternary expressions
(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; };
//multiple levels
(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82;
// In Expressions
((arg) => 90) instanceof Function;
((arg = 1) => 91) instanceof Function;
((arg?) => 92) instanceof Function;
((arg: number) => 93) instanceof Function;
((arg: number = 1) => 94) instanceof Function;
((arg?: number) => 95) instanceof Function;
((...arg: number[]) => 96) instanceof Function;
'' + (arg) => 100;
((arg) => 0) + '' + (arg) => 101;
((arg = 1) => 0) + '' + (arg = 2) => 102;
((arg?) => 0) + '' + (arg?) => 103;
((arg: number) => 0) + '' + (arg: number) => 104;
((arg: number = 1) => 0) + '' + (arg: number = 2) => 105;
((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106;
((...arg: number[]) => 0) + '' + (...arg: number[]) => 107;
((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108;
((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108;
// Function Parameters
function foo(...arg: any[]) { }
foo(
(a) => 110,
((a) => 111),
(a) => {
return 112;
},
(a?) => 113,
(a, b?) => 114,
(a: number) => 115,
(a: number = 0) => 116,
(a = 0) => 117,
(a?: number = 0) => 118,
(a?, b?: number = 0) => 118,
(...a: number[]) => 119,
(a, b? = 0, ...c: number[]) => 120,
(a) => (b) => (c) => 121,
false ? (a) => 0 : (b) => 122
);

View File

@@ -0,0 +1,2 @@
if(false){debugger;}
if ( false ) { debugger ; }

View File

@@ -0,0 +1,2 @@
if (false) { debugger; }
if (false) { debugger; }

View File

@@ -0,0 +1,13 @@
var fun1 = function ( ) {
var x = 'foo' ,
z = 'bar' ;
return x ;
},
fun2 = ( function ( f ) {
var fun = function ( ) {
console . log ( f ( ) ) ;
},
x = 'Foo' ;
return fun ;
} ( fun1 ) ) ;

View File

@@ -0,0 +1,13 @@
var fun1 = function() {
var x = 'foo',
z = 'bar';
return x;
},
fun2 = (function(f) {
var fun = function() {
console.log(f());
},
x = 'Foo';
return fun;
} (fun1));

View File

@@ -0,0 +1,3 @@
export class A {
}

View File

@@ -0,0 +1,6 @@
module Foo {
}
import bar = Foo;
import bar2=Foo;

View File

@@ -0,0 +1,6 @@
module Foo {
}
import bar = Foo;
import bar2 = Foo;

View File

@@ -0,0 +1,95 @@
var a;var c , b;var $d
var $e
var f
a++;b++;
function f ( ) {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m (a[b[c][d]])];
break;
switch ( variable){
case 1: abc += 425;
break;
case 404 : a [x--/2]%=3 ;
break ;
case vari : v[--x ] *=++y*( m + n / k[z]);
for (a in b){
for (a = 0; a < 10; ++a) {
a++;--a;
if (a == b) {
a++;b--;
}
else
if (a == c){
++a;
(--c)+=d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--;++b;
a++
}
}
}
for (x in y) {
m-=m;
k=1+2+3+4;
}
}
break;
}
}
var a ={b:function(){}};
return {a:1,b:2}
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready ();
function pageLoad() {
$('#TextBox1' ) . unbind ( ) ;
$('#TextBox1' ) . datepicker ( ) ;
}
function pageLoad ( ) {
var webclass=[
{ 'student' :
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
} ,
{ 'student':
{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'}
} ,
{ 'student':
{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'}
}
];
$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList'));
}
$( document ).ready(function(){
alert('hello');
} ) ;

View File

@@ -0,0 +1,98 @@
var a; var c, b; var $d
var $e
var f
a++; b++;
function f() {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m(a[b[c][d]])];
break;
switch (variable) {
case 1: abc += 425;
break;
case 404: a[x-- / 2] %= 3;
break;
case vari: v[--x] *= ++y * (m + n / k[z]);
for (a in b) {
for (a = 0; a < 10; ++a) {
a++; --a;
if (a == b) {
a++; b--;
}
else
if (a == c) {
++a;
(--c) += d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--; ++b;
a++
}
}
}
for (x in y) {
m -= m;
k = 1 + 2 + 3 + 4;
}
}
break;
}
}
var a = { b: function() { } };
return { a: 1, b: 2 }
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready();
function pageLoad() {
$('#TextBox1').unbind();
$('#TextBox1').datepicker();
}
function pageLoad() {
var webclass = [
{
'student':
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
},
{
'student':
{ 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' }
},
{
'student':
{ 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' }
}
];
$create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList'));
}
$(document).ready(function() {
alert('hello');
});

View File

@@ -0,0 +1,3 @@
module Foo {
export module A . B . C { }
}

View File

@@ -0,0 +1,3 @@
module Foo {
export module A.B.C { }
}

View File

@@ -0,0 +1,76 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
} ;
var x : d ;
export function foo ( ) : d ;
}
import m4 = module ( "m4" ) ;
export var x4 = m4.x ;
export var d4 = m4.d ;
export var f4 = m4.foo ( ) ;
export module m1 {
declare export module "m2" {
export class d {
} ;
var x: d ;
export function foo ( ) : d ;
}
import m2 = module ( "m2" ) ;
import m3 = module ( "m4" ) ;
export var x2 = m2.x ;
export var d2 = m2.d ;
export var f2 = m2.foo ( ) ;
export var x3 = m3.x ;
export var d3 = m3.d ;
export var f3 = m3.foo ( ) ;
}
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
export module m5 {
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
}

View File

@@ -0,0 +1,76 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
};
var x: d;
export function foo(): d;
}
import m4 = module("m4");
export var x4 = m4.x;
export var d4 = m4.d;
export var f4 = m4.foo();
export module m1 {
declare export module "m2" {
export class d {
};
var x: d;
export function foo(): d;
}
import m2 = module("m2");
import m3 = module("m4");
export var x2 = m2.x;
export var d2 = m2.d;
export var f2 = m2.foo();
export var x3 = m3.x;
export var d3 = m3.d;
export var f3 = m3.foo();
}
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
export module m5 {
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
}

View File

@@ -0,0 +1,27 @@
var x = {foo: 1,
bar: "tt",
boo: 1 + 5};
var x2 = {foo: 1,
bar: "tt",boo:1+5};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b : 2}
};
var x={ };
var y = {};

View File

@@ -0,0 +1,31 @@
var x = {
foo: 1,
bar: "tt",
boo: 1 + 5
};
var x2 = {
foo: 1,
bar: "tt", boo: 1 + 5
};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b: 2 }
};
var x = {};
var y = {};

View File

@@ -0,0 +1,32 @@
function f( ) {
var x = 3;
var z = 2 ;
a = z ++ - 2 * x ;
for ( ; ; ) {
a+=(g +g)*a%t;
b -- ;
}
switch ( a )
{
case 1 : {
a ++ ;
b--;
if(a===a)
return;
else
{
for(a in b)
if(a!=a)
{
for(a in b)
{
a++;
}
}
}
}
default:
break;
}
}

View File

@@ -0,0 +1,28 @@
function f() {
var x = 3;
var z = 2;
a = z++ - 2 * x;
for (; ;) {
a += (g + g) * a % t;
b--;
}
switch (a) {
case 1: {
a++;
b--;
if (a === a)
return;
else {
for (a in b)
if (a != a) {
for (a in b) {
a++;
}
}
}
}
default:
break;
}
}

View File

@@ -0,0 +1 @@
var a=b+c^d-e*++f;

View File

@@ -0,0 +1 @@
var a = b + c ^ d - e * ++f;

View File

@@ -0,0 +1 @@
class test { constructor () { } }

View File

@@ -0,0 +1 @@
class test { constructor() { } }

View File

@@ -0,0 +1,10 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob
{
Blah=1, Bleah=2
}
}

View File

@@ -0,0 +1,9 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob {
Blah = 1, Bleah = 2
}
}

View File

@@ -0,0 +1,65 @@
module MyModule
{
module A.B.C {
module F {
}
}
interface Blah
{
boo: string;
}
class Foo
{
}
class Foo2 {
public foo():number {
return 5 * 6;
}
public foo2() {
if (1 === 2)
{
var y : number= 76;
return y;
}
while (2 == 3) {
if ( y == null ) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a:number, b:number):number
{
return 0;
}
function bar(a:number, b:number) :number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View File

@@ -0,0 +1,58 @@
module MyModule {
module A.B.C {
module F {
}
}
interface Blah {
boo: string;
}
class Foo {
}
class Foo2 {
public foo(): number {
return 5 * 6;
}
public foo2() {
if (1 === 2) {
var y: number = 76;
return y;
}
while (2 == 3) {
if (y == null) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a: number, b: number): number {
return 0;
}
function bar(a: number, b: number): number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View File

@@ -0,0 +1,17 @@
function f(a,b,c,d){
for(var i=0;i<10;i++){
var a=0;
var b=a+a+a*a%a/2-1;
b+=a;
++b;
f(a,b,c,d);
if(1===1){
var m=function(e,f){
return e^f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}

Some files were not shown because too many files have changed in this diff Show More