From b0bc7c3d996d25c9fefdfbcba3ca19fa46ad199f Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Thu, 19 Jun 2025 20:17:23 +0000 Subject: Fix flicker issues by ensuring all actively changing content fits in the viewport (#1217) --- .../ui/components/messages/DiffRenderer.test.tsx | 156 +++++++++++++++------ 1 file changed, 117 insertions(+), 39 deletions(-) (limited to 'packages/cli/src/ui/components/messages/DiffRenderer.test.tsx') diff --git a/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx b/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx index 8c2bba43..52152f55 100644 --- a/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx +++ b/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx @@ -16,6 +16,9 @@ describe('', () => { mockColorizeCode.mockClear(); }); + const sanitizeOutput = (output: string | undefined, terminalWidth: number) => + output?.replace(/GAP_INDICATOR/g, '═'.repeat(terminalWidth)); + it('should call colorizeCode with correct language for new file with known extension', () => { const newFileDiffContent = ` diff --git a/test.py b/test.py @@ -27,11 +30,17 @@ index 0000000..e69de29 +print("hello world") `; render( - , + , ); expect(mockColorizeCode).toHaveBeenCalledWith( 'print("hello world")', 'python', + undefined, + 80, ); }); @@ -46,9 +55,18 @@ index 0000000..e69de29 +some content `; render( - , + , + ); + expect(mockColorizeCode).toHaveBeenCalledWith( + 'some content', + null, + undefined, + 80, ); - expect(mockColorizeCode).toHaveBeenCalledWith('some content', null); }); it('should call colorizeCode with null language for new file if no filename is provided', () => { @@ -61,8 +79,15 @@ index 0000000..e69de29 @@ -0,0 +1 @@ +some text content `; - render(); - expect(mockColorizeCode).toHaveBeenCalledWith('some text content', null); + render( + , + ); + expect(mockColorizeCode).toHaveBeenCalledWith( + 'some text content', + null, + undefined, + 80, + ); }); it('should render diff content for existing file (not calling colorizeCode directly for the whole block)', () => { @@ -79,6 +104,7 @@ index 0000001..0000002 100644 , ); // colorizeCode is used internally by the line-by-line rendering, not for the whole block @@ -103,14 +129,20 @@ index 1234567..1234567 100644 +++ b/file.txt `; const { lastFrame } = render( - , + , ); expect(lastFrame()).toContain('No changes detected'); expect(mockColorizeCode).not.toHaveBeenCalled(); }); it('should handle empty diff content', () => { - const { lastFrame } = render(); + const { lastFrame } = render( + , + ); expect(lastFrame()).toContain('No diff content'); expect(mockColorizeCode).not.toHaveBeenCalled(); }); @@ -130,7 +162,11 @@ index 123..456 100644 context line 11 `; const { lastFrame } = render( - , + , ); const output = lastFrame(); expect(output).toContain('═'); // Check for the border character used in the gap @@ -161,7 +197,11 @@ index abc..def 100644 context line 15 `; const { lastFrame } = render( - , + , ); const output = lastFrame(); expect(output).not.toContain('═'); // Ensure no separator is rendered @@ -171,7 +211,7 @@ index abc..def 100644 expect(output).toContain('context line 11'); }); - it('should correctly render a diff with multiple hunks and a gap indicator', () => { + describe('should correctly render a diff with multiple hunks and a gap indicator', () => { const diffWithMultipleHunks = ` diff --git a/multi.js b/multi.js index 123..789 100644 @@ -188,25 +228,56 @@ index 123..789 100644 +const anotherNew = 'test'; console.log('end of second hunk'); `; - const { lastFrame } = render( - , - ); - const output = lastFrame(); - - // Check for content from the first hunk - expect(output).toContain("1 console.log('first hunk');"); - expect(output).toContain('2 - const oldVar = 1;'); - expect(output).toContain('2 + const newVar = 1;'); - expect(output).toContain("3 console.log('end of first hunk');"); - // Check for the gap indicator between hunks - expect(output).toContain('═'); - - // Check for content from the second hunk - expect(output).toContain("20 console.log('second hunk');"); - expect(output).toContain("21 - const anotherOld = 'test';"); - expect(output).toContain("21 + const anotherNew = 'test';"); - expect(output).toContain("22 console.log('end of second hunk');"); + it.each([ + { + terminalWidth: 80, + height: undefined, + expected: `1 console.log('first hunk'); +2 - const oldVar = 1; +2 + const newVar = 1; +3 console.log('end of first hunk'); +════════════════════════════════════════════════════════════════════════════════ +20 console.log('second hunk'); +21 - const anotherOld = 'test'; +21 + const anotherNew = 'test'; +22 console.log('end of second hunk');`, + }, + { + terminalWidth: 80, + height: 6, + expected: `... first 4 lines hidden ... +════════════════════════════════════════════════════════════════════════════════ +20 console.log('second hunk'); +21 - const anotherOld = 'test'; +21 + const anotherNew = 'test'; +22 console.log('end of second hunk');`, + }, + { + terminalWidth: 30, + height: 6, + expected: `... first 10 lines hidden ... + 'test'; +21 + const anotherNew = + 'test'; +22 console.log('end of + second hunk');`, + }, + ])( + 'with terminalWidth $terminalWidth and height $height', + ({ terminalWidth, height, expected }) => { + const { lastFrame } = render( + , + ); + const output = lastFrame(); + expect(sanitizeOutput(output, terminalWidth)).toEqual(expected); + }, + ); }); it('should correctly render a diff with a SVN diff format', () => { @@ -226,15 +297,19 @@ fileDiff Index: file.txt \\ No newline at end of file `; const { lastFrame } = render( - , + , ); const output = lastFrame(); - expect(output).toContain('1 - const oldVar = 1;'); - expect(output).toContain('1 + const newVar = 1;'); - expect(output).toContain('═'); - expect(output).toContain("20 - const anotherOld = 'test';"); - expect(output).toContain("20 + const anotherNew = 'test';"); + expect(output).toEqual(`1 - const oldVar = 1; +1 + const newVar = 1; +════════════════════════════════════════════════════════════════════════════════ +20 - const anotherOld = 'test'; +20 + const anotherNew = 'test';`); }); it('should correctly render a new file with no file extension correctly', () => { @@ -250,12 +325,15 @@ fileDiff Index: Dockerfile \\ No newline at end of file `; const { lastFrame } = render( - , + , ); const output = lastFrame(); - - expect(output).toContain('1 FROM node:14'); - expect(output).toContain('2 RUN npm install'); - expect(output).toContain('3 RUN npm run build'); + expect(output).toEqual(`1 FROM node:14 +2 RUN npm install +3 RUN npm run build`); }); }); -- cgit v1.2.3