test(cli): address unresolved feedback from PR #23252 (#23303)

This commit is contained in:
Tommaso Sciortino
2026-03-20 21:42:01 +00:00
committed by GitHub
parent 8eb419a47a
commit 11ec4ac2f8
3 changed files with 51 additions and 35 deletions
+10 -16
View File
@@ -376,6 +376,14 @@ export type RenderInstance = {
capturedOverflowActions: OverflowActions | undefined; capturedOverflowActions: OverflowActions | undefined;
}; };
export type RenderWithProvidersInstance = RenderInstance & {
simulateClick: (
col: number,
row: number,
button?: 0 | 1 | 2,
) => Promise<void>;
};
const instances: InkInstance[] = []; const instances: InkInstance[] = [];
export const render = async ( export const render = async (
@@ -618,15 +626,7 @@ export const renderWithProviders = async (
}; };
appState?: AppState; appState?: AppState;
} = {}, } = {},
): Promise< ): Promise<RenderWithProvidersInstance> => {
RenderInstance & {
simulateClick: (
col: number,
row: number,
button?: 0 | 1 | 2,
) => Promise<void>;
}
> => {
const baseState: UIState = new Proxy( const baseState: UIState = new Proxy(
{ ...baseMockUiState, ...providedUiState }, { ...baseMockUiState, ...providedUiState },
{ {
@@ -861,13 +861,7 @@ export async function renderHookWithProviders<Result, Props>(
const Wrapper = options.wrapper || (({ children }) => <>{children}</>); const Wrapper = options.wrapper || (({ children }) => <>{children}</>);
let renderResult: RenderInstance & { let renderResult: RenderWithProvidersInstance;
simulateClick: (
col: number,
row: number,
button?: 0 | 1 | 2,
) => Promise<void>;
};
await act(async () => { await act(async () => {
renderResult = await renderWithProviders( renderResult = await renderWithProviders(
@@ -3249,8 +3249,9 @@ describe('useGeminiStream', () => {
), ),
); );
// Reset start time after hook render, because renderHook (async) // Reset fake timers to startTime because the asynchronous render lifecycle
// advances fake timers by 50ms during its internal waitUntilReady() check. // (via waitUntilReady) advances the mock clock while waiting for initial
// components to settle.
vi.setSystemTime(startTime); vi.setSystemTime(startTime);
// Submit query // Submit query
@@ -43,10 +43,11 @@ const CWD = '/test/project';
const GIT_LOGS_HEAD_PATH = path.join(CWD, '.git', 'logs', 'HEAD'); const GIT_LOGS_HEAD_PATH = path.join(CWD, '.git', 'logs', 'HEAD');
describe('useGitBranchName', () => { describe('useGitBranchName', () => {
let deferredSpawn: { let deferredSpawn: Array<{
resolve: (val: { stdout: string; stderr: string }) => void; resolve: (val: { stdout: string; stderr: string }) => void;
reject: (err: Error) => void; reject: (err: Error) => void;
} | null = null; args: string[];
}> = [];
beforeEach(() => { beforeEach(() => {
vol.reset(); // Reset in-memory filesystem vol.reset(); // Reset in-memory filesystem
@@ -54,11 +55,11 @@ describe('useGitBranchName', () => {
[GIT_LOGS_HEAD_PATH]: 'ref: refs/heads/main', [GIT_LOGS_HEAD_PATH]: 'ref: refs/heads/main',
}); });
deferredSpawn = null; deferredSpawn = [];
vi.mocked(mockSpawnAsync).mockImplementation( vi.mocked(mockSpawnAsync).mockImplementation(
() => (_command: string, args: string[]) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
deferredSpawn = { resolve, reject }; deferredSpawn.push({ resolve, reject, args });
}), }),
); );
}); });
@@ -91,7 +92,9 @@ describe('useGitBranchName', () => {
expect(result.current).toBeUndefined(); expect(result.current).toBeUndefined();
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'main\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'main\n', stderr: '' });
}); });
expect(result.current).toBe('main'); expect(result.current).toBe('main');
@@ -101,7 +104,9 @@ describe('useGitBranchName', () => {
const { result } = await renderGitBranchNameHook(CWD); const { result } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.reject(new Error('Git error')); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.reject(new Error('Git error'));
}); });
expect(result.current).toBeUndefined(); expect(result.current).toBeUndefined();
@@ -111,12 +116,16 @@ describe('useGitBranchName', () => {
const { result } = await renderGitBranchNameHook(CWD); const { result } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'HEAD\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'HEAD\n', stderr: '' });
}); });
// It should now call spawnAsync again for the short hash // It should now call spawnAsync again for the short hash
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'a1b2c3d\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--short');
spawn.resolve({ stdout: 'a1b2c3d\n', stderr: '' });
}); });
expect(result.current).toBe('a1b2c3d'); expect(result.current).toBe('a1b2c3d');
@@ -126,11 +135,15 @@ describe('useGitBranchName', () => {
const { result } = await renderGitBranchNameHook(CWD); const { result } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'HEAD\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'HEAD\n', stderr: '' });
}); });
await act(async () => { await act(async () => {
deferredSpawn?.reject(new Error('Git error')); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--short');
spawn.reject(new Error('Git error'));
}); });
expect(result.current).toBeUndefined(); expect(result.current).toBeUndefined();
@@ -143,7 +156,9 @@ describe('useGitBranchName', () => {
const { result } = await renderGitBranchNameHook(CWD); const { result } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'main\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'main\n', stderr: '' });
}); });
expect(result.current).toBe('main'); expect(result.current).toBe('main');
@@ -160,7 +175,9 @@ describe('useGitBranchName', () => {
// Resolving the new branch name fetch // Resolving the new branch name fetch
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'develop\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'develop\n', stderr: '' });
}); });
expect(result.current).toBe('develop'); expect(result.current).toBe('develop');
@@ -173,7 +190,9 @@ describe('useGitBranchName', () => {
const { result } = await renderGitBranchNameHook(CWD); const { result } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'main\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'main\n', stderr: '' });
}); });
expect(result.current).toBe('main'); expect(result.current).toBe('main');
@@ -188,8 +207,8 @@ describe('useGitBranchName', () => {
fs.writeFileSync(GIT_LOGS_HEAD_PATH, 'ref: refs/heads/develop'); fs.writeFileSync(GIT_LOGS_HEAD_PATH, 'ref: refs/heads/develop');
}); });
// spawnAsync should NOT have been called again // spawnAsync should NOT have been called again for updating
expect(vi.mocked(mockSpawnAsync)).toHaveBeenCalledTimes(1); expect(deferredSpawn.length).toBe(0);
expect(result.current).toBe('main'); expect(result.current).toBe('main');
}); });
@@ -203,7 +222,9 @@ describe('useGitBranchName', () => {
const { unmount } = await renderGitBranchNameHook(CWD); const { unmount } = await renderGitBranchNameHook(CWD);
await act(async () => { await act(async () => {
deferredSpawn?.resolve({ stdout: 'main\n', stderr: '' }); const spawn = deferredSpawn.shift()!;
expect(spawn.args).toContain('--abbrev-ref');
spawn.resolve({ stdout: 'main\n', stderr: '' });
}); });
// Wait for watcher to be set up BEFORE unmounting // Wait for watcher to be set up BEFORE unmounting