spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / mods / diff / tests / views.test.ts
183 lines · 6.1 KBRaw
1import { describe, expect, test, tier } from 'claude-code/testing'
2
3import Fixtures from './fixtures'
4
5tier('builtin')
6
7describe('views', () => {
8 test('docked, every file has its hunks under the list', async ($, on) => {
9 const world = Fixtures.inRepository(on, Fixtures.TWO_FILES)
10
11 await $.session.start(Fixtures.SESSION)
12 await $.command.run(Fixtures.DIFF)
13 await world.clock.advance(Fixtures.SETTLE_MS)
14
15 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
16
17 expect(drawn).toContain('2 files changed +3 -1')
18
19 expect(drawn, "a closing empty row, as the built-in's").toContain(
20 '+const a = 2\n ',
21 )
22
23 expect(drawn, 'none after the last file').toMatch(/\+export const c = 2$/)
24 expect(drawn).not.toContain('❯')
25 })
26
27 test('inline, a row opens that file alone', async ($, on) => {
28 const world = Fixtures.inRepository(on, Fixtures.TWO_FILES)
29
30 await $.session.start(Fixtures.SESSION)
31 await $.command.run(Fixtures.DIALOG_DIFF)
32 await world.clock.advance(Fixtures.SETTLE_MS)
33 await $.ui.render(Fixtures.INLINE_PANE)
34
35 expect(await $.ui.press({ plugin: 'diff', key: 'file:lib.ts' })).toEqual({
36 element: 'file:lib.ts',
37 })
38
39 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.INLINE_PANE))
40
41 expect(drawn).toContain('+export const c = 2')
42 expect(drawn).not.toContain('+const a = 2')
43 expect(drawn).not.toContain('app.ts')
44 expect(drawn).toContain('\u2191/\u2193 to scroll \u00b7 Esc to back')
45 })
46
47 test('docked, a wheel tick moves the body, not the list', async ($, on) => {
48 const world = Fixtures.inRepository(on, Fixtures.MANY_FILES)
49
50 await $.session.start(Fixtures.SESSION)
51 await $.command.run(Fixtures.DIFF)
52 await world.clock.advance(Fixtures.SETTLE_MS)
53
54 const before = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
55
56 expect(before, 'listed, and named over its body').toContain('file0.ts')
57 expect(before.split('file0.ts')).toHaveLength(3)
58
59 expect(await $.ui.scroll(Fixtures.WHEEL_TICK)).toEqual({})
60
61 const after = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
62
63 expect(after.split('file0.ts'), 'its name row scrolled away').toHaveLength(
64 2,
65 )
66
67 expect(after).toContain('-const v = 0')
68 expect(after).toContain('10 files changed +10 -10')
69 })
70
71 test('past eight files the docked list scrolls by key', async ($, on) => {
72 const world = Fixtures.inRepository(on, Fixtures.MANY_FILES)
73
74 await $.session.start(Fixtures.SESSION)
75 await $.command.run(Fixtures.DIFF)
76 await world.clock.advance(Fixtures.SETTLE_MS)
77
78 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
79
80 expect(drawn).toContain('10 files changed +10 -10')
81 expect(drawn).toContain('file7.ts')
82 expect(drawn).toContain('\u2193 2 more below (opt+\u2193 to scroll)')
83 expect(drawn).not.toContain('file8.ts')
84
85 expect(await $.ui.press({ plugin: 'diff', key: 'list-down' })).toEqual({
86 element: 'list-down',
87 })
88
89 const scrolled = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
90
91 expect(scrolled).toContain('\u2191 1 more above')
92 expect(scrolled).toContain('file8.ts')
93 expect(scrolled).toContain('\u2193 1 more below')
94 })
95
96 test('a rename lists as git prints it, and reads no body', async ($, on) => {
97 const world = Fixtures.inRepository(on, Fixtures.RENAMED)
98
99 await $.session.start(Fixtures.SESSION)
100 await $.command.run(Fixtures.DIFF)
101 await world.clock.advance(Fixtures.SETTLE_MS)
102
103 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
104
105 expect(drawn).toContain('1 file changed')
106 expect(drawn).toContain('docs/{notes.txt => renamed-notes.txt}')
107 expect(drawn).toContain('No diff content')
108
109 expect(
110 world.runs.filter(run => run.argv.includes('docs/renamed-notes.txt')),
111 ).toEqual([])
112 })
113
114 test('inline, the dialog lists every file and its keys', async ($, on) => {
115 const world = Fixtures.inRepository(on, Fixtures.TWO_FILES)
116
117 await $.session.start(Fixtures.SESSION)
118 await $.command.run(Fixtures.DIALOG_DIFF)
119 await world.clock.advance(Fixtures.SETTLE_MS)
120
121 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.INLINE_PANE))
122
123 expect(drawn).toContain('Uncommitted changes (git diff HEAD)')
124 expect(drawn).toContain('2 files changed +3 -1')
125 expect(drawn).toContain(' app.ts')
126 expect(drawn).toContain(' lib.ts')
127 expect(drawn).not.toContain('+const a = 2')
128
129 expect(drawn).toContain(
130 '\u2191/\u2193 to select \u00b7 Enter to view \u00b7 Esc to close',
131 )
132 })
133
134 test('narrow under the fullscreen layout, the resize line', async ($, on) => {
135 const world = Fixtures.inRepository(on, Fixtures.TWO_FILES)
136
137 await $.session.start(Fixtures.SESSION)
138 await $.command.run(Fixtures.DIFF)
139 await world.clock.advance(Fixtures.SETTLE_MS)
140
141 expect(
142 Fixtures.textOf(await $.ui.render(Fixtures.NARROW_INLINE_PANE)),
143 ).toBe(
144 'Resize your terminal to at least 110 columns to show the diff panel',
145 )
146 })
147
148 test('off fullscreen, forty files list five at a time', async ($, on) => {
149 const world = Fixtures.inRepository(on, Fixtures.MANY_FILES)
150
151 await $.session.start(Fixtures.SESSION)
152 await $.command.run(Fixtures.DIALOG_DIFF)
153 await world.clock.advance(Fixtures.SETTLE_MS)
154
155 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.INLINE_PANE))
156
157 expect(drawn).toContain(' file4.ts')
158 expect(drawn).not.toContain('file5.ts')
159 expect(drawn).toContain(' \u2193 5 more files')
160
161 expect(await $.ui.press({ plugin: 'diff', key: 'files-down' })).toEqual({
162 element: 'files-down',
163 })
164
165 const paged = Fixtures.textOf(await $.ui.render(Fixtures.INLINE_PANE))
166
167 expect(paged).toContain(' \u2191 5 more files')
168 expect(paged).toContain(' file9.ts')
169 expect(paged).not.toContain('file4.ts')
170 })
171
172 test('off fullscreen, the dialog draws at any width', async ($, on) => {
173 const world = Fixtures.inRepository(on, Fixtures.TWO_FILES)
174
175 await $.session.start(Fixtures.SESSION)
176 await $.command.run(Fixtures.DIALOG_DIFF)
177 await world.clock.advance(Fixtures.SETTLE_MS)
178
179 expect(
180 Fixtures.textOf(await $.ui.render(Fixtures.NARROW_INLINE_PANE)),
181 ).toContain('Uncommitted changes (git diff HEAD)')
182 })
183})