import LineByLineRenderer from "../line-by-line-renderer"; import HoganJsUtils from "../hoganjs-utils"; import { LineType, CSSLineClass, DiffLine, DiffFile } from "../render-utils"; describe("LineByLineRenderer", () => { describe("_generateEmptyDiff", () => { it("should return an empty diff", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const fileHtml = lineByLineRenderer.generateEmptyDiff(); const expected = "\n" + ' \n' + '
\n' + " File without changes\n" + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); }); describe("makeLineHtml", () => { it("should work for insertions", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); let fileHtml = lineByLineRenderer.makeLineHtml(false, CSSLineClass.INSERTS, "test", undefined, 30, "+"); fileHtml = fileHtml.replace(/\n\n+/g, "\n"); const expected = "\n" + ' \n' + '
\n' + '
30
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test\n' + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); it("should work for deletions", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); let fileHtml = lineByLineRenderer.makeLineHtml(false, CSSLineClass.DELETES, "test", 30, undefined, "-"); fileHtml = fileHtml.replace(/\n\n+/g, "\n"); const expected = "\n" + ' \n' + '
30
\n' + '
\n' + " \n" + ' \n' + '
\n' + ' -\n' + ' test\n' + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); it("should convert indents into non breakin spaces (2 white spaces)", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); let fileHtml = lineByLineRenderer.makeLineHtml(false, CSSLineClass.INSERTS, " test", undefined, 30, "+"); fileHtml = fileHtml.replace(/\n\n+/g, "\n"); const expected = "\n" + ' \n' + '
\n' + '
30
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test\n' + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); it("should convert indents into non breakin spaces (4 white spaces)", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); let fileHtml = lineByLineRenderer.makeLineHtml(false, CSSLineClass.INSERTS, " test", undefined, 30, "+"); fileHtml = fileHtml.replace(/\n\n+/g, "\n"); const expected = "\n" + ' \n' + '
\n' + '
30
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test\n' + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); it("should preserve tabs", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); let fileHtml = lineByLineRenderer.makeLineHtml(false, CSSLineClass.INSERTS, "\ttest", undefined, 30, "+"); fileHtml = fileHtml.replace(/\n\n+/g, "\n"); const expected = "\n" + ' \n' + '
\n' + "" + '
30
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' \ttest\n' + "
\n" + " \n" + ""; expect(fileHtml).toEqual(expected); }); }); describe("makeFileDiffHtml", () => { it("should work for simple file", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const file = { addedLines: 12, deletedLines: 41, language: "js", oldName: "my/file/name.js", newName: "my/file/name.js", isCombined: false, isGitDiff: false, blocks: [] }; const diffs = "Random Html"; const fileHtml = lineByLineRenderer.makeFileDiffHtml(file, diffs); const expected = '
\n' + '
\n' + ' \n' + ' my/file/name.js\n' + ' CHANGED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " Random Html\n" + " \n" + "
\n" + "
\n" + "
\n" + "
"; expect(fileHtml).toEqual(expected); }); it("should work for simple added file", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const file = { addedLines: 12, deletedLines: 0, language: "js", oldName: "dev/null", newName: "my/file/name.js", isNew: true, isCombined: false, isGitDiff: false, blocks: [] }; const diffs = "Random Html"; const fileHtml = lineByLineRenderer.makeFileDiffHtml(file, diffs); const expected = '
\n' + '
\n' + ' \n' + ' my/file/name.js\n' + ' ADDED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " Random Html\n" + " \n" + "
\n" + "
\n" + "
\n" + "
"; expect(fileHtml).toEqual(expected); }); it("should work for simple deleted file", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const file = { addedLines: 0, deletedLines: 41, language: "js", oldName: "my/file/name.js", newName: "dev/null", isDeleted: true, isCombined: false, isGitDiff: false, blocks: [] }; const diffs = "Random Html"; const fileHtml = lineByLineRenderer.makeFileDiffHtml(file, diffs); const expected = '
\n' + '
\n' + ' \n' + ' my/file/name.js\n' + ' DELETED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " Random Html\n" + " \n" + "
\n" + "
\n" + "
\n" + "
"; expect(fileHtml).toEqual(expected); }); it("should work for simple renamed file", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const file = { addedLines: 12, deletedLines: 41, language: "js", oldName: "my/file/name1.js", newName: "my/file/name2.js", isRename: true, isCombined: false, isGitDiff: false, blocks: [] }; const diffs = "Random Html"; const fileHtml = lineByLineRenderer.makeFileDiffHtml(file, diffs); const expected = '
\n' + '
\n' + ' \n' + ' my/file/{name1.js → name2.js}\n' + ' RENAMED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " Random Html\n" + " \n" + "
\n" + "
\n" + "
\n" + "
"; expect(fileHtml).toEqual(expected); }); it("should return empty when option renderNothingWhenEmpty is true and file blocks not present", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, { renderNothingWhenEmpty: true }); const file = { addedLines: 0, deletedLines: 0, language: "js", oldName: "my/file/name1.js", newName: "my/file/name2.js", isRename: true, isCombined: false, isGitDiff: false, blocks: [] }; const diffs = "Random Html"; const fileHtml = lineByLineRenderer.makeFileDiffHtml(file, diffs); const expected = ""; expect(fileHtml).toEqual(expected); }); }); describe("makeLineByLineHtmlWrapper", () => { it("should work for simple content", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const fileHtml = lineByLineRenderer.makeLineByLineHtmlWrapper("Random Html"); const expected = '
\n' + " Random Html\n" + "
"; expect(fileHtml).toEqual(expected); }); }); describe("generateLineByLineJsonHtml", () => { it("should work for list of files", () => { const exampleJson: DiffFile[] = [ { blocks: [ { lines: [ { content: "-test", type: LineType.DELETE, oldNumber: 1, newNumber: undefined }, { content: "+test1r", type: LineType.INSERT, oldNumber: undefined, newNumber: 1 } ], oldStartLine: 1, oldStartLine2: undefined, newStartLine: 1, header: "@@ -1 +1 @@" } ], deletedLines: 1, addedLines: 1, checksumBefore: "0000001", checksumAfter: "0ddf2ba", oldName: "sample", newName: "sample", language: "txt", isCombined: false, isGitDiff: true } ]; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, { matching: "lines" }); const html = lineByLineRenderer.render(exampleJson); const expected = '
\n' + '
\n' + '
\n' + ' \n' + ' sample\n' + ' CHANGED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " \n" + ' \n' + ' \n" + "\n" + ' \n" + ' \n" + "\n" + ' \n" + ' \n" + "\n" + " \n" + "
\n' + '
@@ -1 +1 @@
\n' + "
\n' + '
1
\n' + '
\n' + "
\n' + '
\n' + ' -\n' + ' test\n' + "
\n" + "
\n' + '
\n' + '
1
\n' + "
\n' + '
\n' + ' +\n' + ' test1r\n' + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
"; expect(html).toEqual(expected); }); it("should work for empty blocks", () => { const exampleJson = [ { blocks: [], deletedLines: 0, addedLines: 0, oldName: "sample", language: "js", newName: "sample", isCombined: false, isGitDiff: false } ]; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, { renderNothingWhenEmpty: false }); const html = lineByLineRenderer.render(exampleJson); const expected = '
\n' + '
\n' + '
\n' + ' \n' + ' sample\n' + ' CHANGED\n' + "
\n" + '
\n' + '
\n' + ' \n' + ' \n' + " \n" + ' \n" + "\n" + " \n" + "
\n' + '
\n' + " File without changes\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
"; expect(html).toEqual(expected); }); }); describe("_processLines", () => { it("should work for simple block header", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const oldLines: DiffLine[] = [ { content: "-test", type: LineType.DELETE, oldNumber: 1, newNumber: undefined } ]; const newLines: DiffLine[] = [ { content: "+test1r", type: LineType.INSERT, oldNumber: undefined, newNumber: 1 } ]; const html = lineByLineRenderer.processLines(false, oldLines, newLines); const expected = "\n" + ' \n' + '
1
\n' + '
\n' + " \n" + ' \n' + '
\n' + ' -\n' + ' test\n' + "
\n" + " \n" + "\n" + ' \n' + '
\n' + '
1
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test1r\n' + "
\n" + " \n" + ""; expect(html).toEqual(expected); }); }); describe("_generateFileHtml", () => { it("should work for simple file", () => { const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); const file: DiffFile = { blocks: [ { lines: [ { content: " one context line", type: LineType.CONTEXT, oldNumber: 1, newNumber: 1 }, { content: "-test", type: LineType.DELETE, oldNumber: 2, newNumber: undefined }, { content: "+test1r", type: LineType.INSERT, oldNumber: undefined, newNumber: 2 }, { content: "+test2r", type: LineType.INSERT, oldNumber: undefined, newNumber: 3 } ], oldStartLine: 1, oldStartLine2: undefined, newStartLine: 1, header: "@@ -1 +1 @@" } ], deletedLines: 1, addedLines: 1, checksumBefore: "0000001", checksumAfter: "0ddf2ba", oldName: "sample", language: "txt", newName: "sample", isCombined: false, isGitDiff: true }; const html = lineByLineRenderer.generateFileHtml(file); const expected = "\n" + ' \n' + ' \n' + '
@@ -1 +1 @@
\n' + " \n" + "\n" + ' \n' + '
1
\n' + '
1
\n' + " \n" + ' \n' + '
\n' + '  \n' + ' one context line\n' + "
\n" + " \n" + "\n" + ' \n' + '
2
\n' + '
\n' + " \n" + ' \n' + '
\n' + ' -\n' + ' test\n' + "
\n" + " \n" + "\n" + ' \n' + '
\n' + '
2
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test1r\n' + "
\n" + " \n" + "\n" + ' \n' + '
\n' + '
3
\n' + " \n" + ' \n' + '
\n' + ' +\n' + ' test2r\n' + "
\n" + " \n" + ""; expect(html).toEqual(expected); }); }); });