1namespace ts { 2 describe("unittests:: services:: hostNewLineSupport", () => { 3 function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) { 4 function snapFor(path: string): IScriptSnapshot | undefined { 5 if (path === "lib.d.ts") { 6 return ScriptSnapshot.fromString(""); 7 } 8 const result = find(files, f => f.unitName === path); 9 return result && ScriptSnapshot.fromString(result.content); 10 } 11 const lshost: LanguageServiceHost = { 12 getCompilationSettings: () => settings, 13 getScriptFileNames: () => map(files, f => f.unitName), 14 getScriptVersion: () => "1", 15 getScriptSnapshot: name => snapFor(name), 16 getDefaultLibFileName: () => "lib.d.ts", 17 getCurrentDirectory: () => "", 18 }; 19 return createLanguageService(lshost); 20 } 21 22 function verifyNewLines(content: string, options: CompilerOptions) { 23 const ls = testLSWithFiles(options, [{ 24 content, 25 fileOptions: {}, 26 unitName: "input.ts" 27 }]); 28 const result = ls.getEmitOutput("input.ts"); 29 assert(!result.emitSkipped, "emit was skipped"); 30 assert(result.outputFiles.length === 1, "a number of files other than 1 was output"); 31 assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`); 32 assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); 33 assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); 34 } 35 36 function verifyBothNewLines(content: string) { 37 verifyNewLines(content, { newLine: NewLineKind.CarriageReturnLineFeed }); 38 verifyNewLines(content, { newLine: NewLineKind.LineFeed }); 39 } 40 41 function verifyOutliningSpanNewLines(content: string, options: CompilerOptions) { 42 const ls = testLSWithFiles(options, [{ 43 content, 44 fileOptions: {}, 45 unitName: "input.ts" 46 }]); 47 const span = ls.getOutliningSpans("input.ts")[0]; 48 const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); 49 assert(textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); 50 assert(!textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); 51 } 52 53 it("should exist and respect provided compiler options", () => { 54 verifyBothNewLines(` 55 function foo() { 56 return 2 + 2; 57 } 58 `); 59 }); 60 61 it("should respect CRLF line endings around outlining spans", () => { 62 verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", 63 { newLine: NewLineKind.CarriageReturnLineFeed }); 64 }); 65 66 it("should respect LF line endings around outlining spans", () => { 67 verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", 68 { newLine: NewLineKind.LineFeed }); 69 }); 70 }); 71} 72