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 / register.test.ts
210 lines · 5.3 KBRaw
1import { describe, expect, mock, test, tier } from 'claude-code/testing'
2
3import Limits from '../hooks/limits'
4import Fixtures from './fixtures'
5
6tier('builtin')
7
8describe('register', () => {
9 test('/diff at boot joins the boot probe, then asks again', async ($, on) => {
10 const probes: (readonly string[])[] = []
11 const clock = Fixtures.startsSession(on)
12
13 on('process.run', async ($, e) => {
14 probes.push(e.argv)
15
16 if (probes.length === 1) {
17 await clock.sleep(Limits.GIT_TIMEOUT_MS)
18
19 return { deny: Fixtures.GIT_HUNG }
20 }
21
22 return { value: Fixtures.NOT_A_REPOSITORY }
23 })
24
25 const booting = $.session.start(Fixtures.SESSION)
26
27 await clock.settle()
28
29 const ran = $.command.run(Fixtures.DIFF)
30
31 await clock.settle()
32
33 expect(probes, 'the boot probe, which /diff joined').toHaveLength(1)
34
35 await clock.advance(Limits.GIT_TIMEOUT_MS)
36 await booting
37
38 expect(await ran).toEqual({
39 text: expect.stringContaining("isn't in a git repository"),
40 })
41
42 expect(probes, 'then one more of its own').toHaveLength(2)
43 })
44
45 test('outside a repository /diff says so, opens nothing', async ($, on) => {
46 const opened: string[] = []
47
48 Fixtures.startsSession(on)
49 on('process.run', () => ({ value: Fixtures.NOT_A_REPOSITORY }))
50
51 on('ui.open', ($, e, next) => {
52 opened.push(e.id)
53
54 return next(e)
55 })
56
57 await $.session.start(Fixtures.SESSION)
58
59 const { text } = await $.command.run(Fixtures.DIFF)
60
61 expect(text).toContain("isn't in a git repository")
62 expect(opened).toEqual([])
63 })
64
65 test('a git that never answers is not "no repository"', async ($, on) => {
66 Fixtures.startsSession(on)
67 on('process.run', () => ({ deny: Fixtures.GIT_HUNG }))
68
69 await $.session.start(Fixtures.SESSION)
70
71 const { text } = await $.command.run(Fixtures.DIFF)
72
73 expect(text).toContain("git didn't answer")
74 })
75
76 test('when the built-in holds /diff, the mod stands down', async ($, on) => {
77 const logged: string[] = []
78
79 mock.clock(on)
80 on('session.start', ($, e) => ({ cwd: e.cwd }))
81 on('command.register', () => ({ deny: Fixtures.BUILTIN_HOLDS }))
82 on('command.run', () => ({ text: 'the built-in /diff ran' }))
83
84 on('ui.log', ($, e) => {
85 logged.push(e.text)
86
87 return { value: undefined }
88 })
89
90 await $.session.start(Fixtures.SESSION)
91
92 expect(await $.command.run(Fixtures.DIFF)).toEqual({
93 text: 'the built-in /diff ran',
94 })
95
96 expect(logged).toEqual([])
97 })
98
99 test('a refusal the built-in did not cause is said aloud', async ($, on) => {
100 const logged: string[] = []
101
102 mock.clock(on)
103 on('session.start', ($, e) => ({ cwd: e.cwd }))
104
105 on('command.register', () => ({
106 deny: '32 commands are registered already',
107 }))
108
109 on('ui.log', ($, e) => {
110 logged.push(e.text)
111
112 return { value: undefined }
113 })
114
115 await $.session.start(Fixtures.SESSION)
116
117 expect(logged).toEqual([
118 'could not register /diff: diff: $.command.register: 32 commands are ' +
119 'registered already; the diff panel is unavailable this session',
120 ])
121 })
122
123 test('/diff opens the pane, unfocused, and says so', async ($, on) => {
124 const world = Fixtures.inRepository(on)
125
126 await $.session.start(Fixtures.SESSION)
127
128 expect(await $.command.run(Fixtures.DIFF)).toEqual({
129 text: 'Diff panel shown',
130 })
131
132 expect(world.opened).toEqual([
133 { id: 'diff', title: 'Diff', holdToasts: true },
134 ])
135
136 await world.clock.advance(Fixtures.SETTLE_MS)
137
138 const drawn = Fixtures.textOf(await $.ui.render(Fixtures.PANE))
139
140 expect(drawn).toContain('1 file changed')
141 expect(drawn).toContain('app.ts')
142 })
143
144 test('off fullscreen, /diff opens the dialog, focused', async ($, on) => {
145 const world = Fixtures.inRepository(on)
146
147 await $.session.start(Fixtures.SESSION)
148
149 expect(await $.command.run(Fixtures.DIALOG_DIFF)).toEqual({})
150
151 expect(world.opened).toEqual([
152 {
153 id: 'diff',
154 title: 'Diff',
155 holdToasts: true,
156 focus: true,
157 closeOnEscape: true,
158 },
159 ])
160
161 expect(await $.command.run(Fixtures.DIALOG_DIFF)).toEqual({
162 text: 'Diff dialog dismissed',
163 })
164 })
165
166 test('/diff again closes the pane and says so', async ($, on) => {
167 const world = Fixtures.inRepository(on)
168
169 await $.session.start(Fixtures.SESSION)
170 await $.command.run(Fixtures.DIFF)
171
172 expect(await $.command.run(Fixtures.DIFF)).toEqual({
173 text: 'Diff panel hidden',
174 })
175
176 expect(world.closed.map(pane => pane.id)).toEqual(['diff'])
177 })
178
179 test('a wide terminal opens the pane at the first edit', async ($, on) => {
180 const world = Fixtures.inRepository(on)
181
182 on('tool.call', () => ({ result: 'edited' }))
183
184 await $.session.start(Fixtures.SESSION)
185 await $.ui.render(Fixtures.HINT)
186
187 await $.tool.call({
188 tool: 'Edit',
189 file_path: '/work/app.ts',
190 old_string: '1',
191 new_string: '2',
192 })
193
194 await world.clock.advance(Fixtures.SETTLE_MS)
195
196 expect(world.opened.map(pane => pane.id)).toEqual(['diff'])
197 })
198
199 test('/clear closes the pane it finds open', async ($, on) => {
200 const world = Fixtures.inRepository(on)
201
202 on('command.run', { command: 'clear' }, () => ({}))
203
204 await $.session.start(Fixtures.SESSION)
205 await $.command.run(Fixtures.DIFF)
206 await $.command.run(Fixtures.CLEAR)
207
208 expect(world.closed.map(pane => pane.id)).toEqual(['diff'])
209 })
210})