diff --git a/Jakefile.js b/Jakefile.js index 0b3659e205116..ba6943d30153d 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -154,6 +154,7 @@ var harnessSources = harnessCoreSources.concat([ "symbolWalker.ts", "languageService.ts", "publicApi.ts", + "hostNewLineSupport.ts", ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f907cce85b1f3..b08d8888d70eb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3199,7 +3199,7 @@ namespace ts { const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; - export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: System): string { + export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: { newLine: string }): string { switch (options.newLine) { case NewLineKind.CarriageReturnLineFeed: return carriageReturnLineFeed; diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index a0c141f4f1760..18baeb67c823f 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -139,6 +139,7 @@ "./unittests/telemetry.ts", "./unittests/languageService.ts", "./unittests/programMissingFiles.ts", - "./unittests/publicApi.ts" + "./unittests/publicApi.ts", + "./unittests/hostNewLineSupport.ts" ] } diff --git a/src/harness/unittests/hostNewLineSupport.ts b/src/harness/unittests/hostNewLineSupport.ts new file mode 100644 index 0000000000000..9f6b09dfb72d0 --- /dev/null +++ b/src/harness/unittests/hostNewLineSupport.ts @@ -0,0 +1,67 @@ +/// +namespace ts { + describe("hostNewLineSupport", () => { + function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) { + function snapFor(path: string): IScriptSnapshot { + if (path === "lib.d.ts") { + return { + dispose() {}, + getChangeRange() { return undefined; }, + getLength() { return 0; }, + getText(_start, _end) { + return ""; + } + }; + } + const result = forEach(files, f => f.unitName === path ? f : undefined); + if (result) { + return { + dispose() {}, + getChangeRange() { return undefined; }, + getLength() { return result.content.length; }, + getText(start, end) { + return result.content.substring(start, end); + } + }; + } + return undefined; + } + const lshost: LanguageServiceHost = { + getCompilationSettings: () => settings, + getScriptFileNames: () => map(files, f => f.unitName), + getScriptVersion: () => "1", + getScriptSnapshot: name => snapFor(name), + getDefaultLibFileName: () => "lib.d.ts", + getCurrentDirectory: () => "", + }; + return ts.createLanguageService(lshost); + } + + function verifyNewLines(content: string, options: CompilerOptions) { + const ls = testLSWithFiles(options, [{ + content, + fileOptions: {}, + unitName: "input.ts" + }]); + const result = ls.getEmitOutput("input.ts"); + assert(!result.emitSkipped, "emit was skipped"); + assert(result.outputFiles.length === 1, "a number of files other than 1 was output"); + assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`); + assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); + } + + function verifyBothNewLines(content: string) { + verifyNewLines(content, { newLine: NewLineKind.CarriageReturnLineFeed }); + verifyNewLines(content, { newLine: NewLineKind.LineFeed }); + } + + it("should exist and respect provided compiler options", () => { + verifyBothNewLines(` + function foo() { + return 2 + 2; + } + `); + }); + }); +} \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index a5c9c1d353a18..114692ebba2e5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1146,7 +1146,7 @@ namespace ts { getCancellationToken: () => cancellationToken, getCanonicalFileName, useCaseSensitiveFileNames: () => useCaseSensitivefileNames, - getNewLine: () => getNewLineOrDefaultFromHost(host), + getNewLine: () => getNewLineCharacter(newSettings, { newLine: getNewLineOrDefaultFromHost(host) }), getDefaultLibFileName: (options) => host.getDefaultLibFileName(options), writeFile: noop, getCurrentDirectory: () => currentDirectory,