@@ -30,33 +30,51 @@ the test registers with `on` sit beneath the mod, where the rest of the world
3030would be, and nothing is beneath them: a call they leave unanswered throws,
3131naming its event.
3232
33+ A test file is named for what it covers under ` hooks/ ` (` register.test.ts `
34+ beside ` hooks/register.ts ` , ` git.test.ts ` beside ` hooks/git/ ` ), and holds its
35+ imports, the tier the mod loads in, and one ` describe ` titled with that name;
36+ what several tests share sits under ` tests/fixtures/ ` , one export a file.
37+
3338``` ts
34- import { expect , test , tier } from ' claude-code/testing'
39+ import { describe , expect , memoryClock , test , tier } from ' claude-code/testing'
3540
3641tier (' builtin' )
3742
38- test (' outside a git repository /diff says so and opens nothing' , async ($ , on ) => {
39- const opened: string [] = []
40- on (' session.start' , ($ , e ) => ({ cwd: e .cwd }))
41- on (' command.register' , ($ , e ) => ({ value: { command: e .name } }))
42- on (' process.run' , () => ({ value: { exitCode: 128 , stdout: ' ' , stderr: ' ' } }))
43- on (' ui.open' , ($ , e , next ) => {
44- opened .push (e .id )
45- return next (e )
46- })
43+ describe (' register' , () => {
44+ test (' outside a git repository /diff says so, opens nothing' , async ($ , on ) => {
45+ const opened: string [] = []
46+ memoryClock (on )
47+ on (' session.start' , ($ , e ) => ({ cwd: e .cwd }))
48+ on (' command.register' , ($ , e ) => ({ value: { command: e .name } }))
49+ on (' process.run' , () => ({
50+ value: { exitCode: 128 , stdout: ' ' , stderr: ' fatal: not a git repository' },
51+ }))
52+ on (' ui.open' , ($ , e , next ) => {
53+ opened .push (e .id )
54+ return next (e )
55+ })
4756
48- await $ .session .start ({ surface: ' terminal' , isInteractive: true , cwd: ' /work' })
49- const { text } = await $ .command .run ({
50- command: ' diff' ,
51- args: ' ' ,
52- origin: { kind: ' composer' },
53- })
57+ await $ .session .start ({ surface: ' terminal' , isInteractive: true , cwd: ' /work' })
58+ const { text } = await $ .command .run ({
59+ command: ' diff' ,
60+ args: ' ' ,
61+ origin: { kind: ' composer' },
62+ })
5463
55- expect (text ).toContain (" isn't in a git repository" )
56- expect (opened ).toEqual ([])
64+ expect (text ).toContain (" isn't in a git repository" )
65+ expect (opened ).toEqual ([])
66+ })
5767})
5868```
5969
70+ The kit's helpers are plain functions over ` on ` , each answering one noun
71+ beneath the mod where the test calls it: ` memoryEnv(on, variables) ` for
72+ ` $.env ` , ` memoryStore(on, entries) ` for ` $.store ` , and ` memoryClock(on) ` for
73+ ` $.clock ` , whose ` advance(ms) ` resolves every wait the mod asked for
74+ (` $.clock.sleep ` , ` after ` , ` every ` ) as the clock crosses it. ` textOf(tree) `
75+ reads a rendered tree's text, and ` $.ui.press({ plugin, key }) ` presses a
76+ ` Button ` the test rendered, as a click in the terminal does.
77+
6078` tsc -p mods/tsconfig.json ` typechecks every mod's hooks and tests against
6179` types/ ` .
6280
0 commit comments