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 readFile: name => { 19 const snap = snapFor(name); 20 if (!snap) return undefined; 21 return snap.getText(0, snap.getLength()); 22 }, 23 fileExists: name => !!snapFor(name), 24 }; 25 return createLanguageService(lshost); 26 } 27 28 function verifyNewLines(content: string, options: CompilerOptions) { 29 const ls = testLSWithFiles(options, [{ 30 content, 31 fileOptions: {}, 32 unitName: "input.ts" 33 }]); 34 const result = ls.getEmitOutput("input.ts"); 35 assert(!result.emitSkipped, "emit was skipped"); 36 assert(result.outputFiles.length === 1, "a number of files other than 1 was output"); 37 assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`); 38 assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); 39 assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); 40 } 41 42 function verifyBothNewLines(content: string) { 43 verifyNewLines(content, { newLine: NewLineKind.CarriageReturnLineFeed }); 44 verifyNewLines(content, { newLine: NewLineKind.LineFeed }); 45 } 46 47 function verifyOutliningSpanNewLines(content: string, options: CompilerOptions) { 48 const ls = testLSWithFiles(options, [{ 49 content, 50 fileOptions: {}, 51 unitName: "input.ts" 52 }]); 53 const span = ls.getOutliningSpans("input.ts")[0]; 54 const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); 55 assert(textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); 56 assert(!textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); 57 } 58 59 it("should exist and respect provided compiler options", () => { 60 verifyBothNewLines(` 61 function foo() { 62 return 2 + 2; 63 } 64 `); 65 }); 66 67 it("should respect CRLF line endings around outlining spans", () => { 68 verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", 69 { newLine: NewLineKind.CarriageReturnLineFeed }); 70 }); 71 72 it("should respect LF line endings around outlining spans", () => { 73 verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", 74 { newLine: NewLineKind.LineFeed }); 75 }); 76 }); 77} 78