mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 00:04:01 +00:00
79 lines
2.6 KiB
TypeScript
79 lines
2.6 KiB
TypeScript
import { createElement } from 'react'
|
|
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import type { WorktreeShowResolution } from '../worktree/worktree-show-resolution'
|
|
import { isSyntheticWorkspaceRoute } from './synthetic-workspace-route'
|
|
import {
|
|
shouldBounceMissingWorktree,
|
|
useMissingWorktreeBounce
|
|
} from './use-missing-worktree-bounce'
|
|
|
|
describe('shouldBounceMissingWorktree', () => {
|
|
it('bounces only a host-proven missing worktree', () => {
|
|
expect(shouldBounceMissingWorktree('repo::wt', 'missing')).toBe(true)
|
|
expect(shouldBounceMissingWorktree('repo::wt', 'unknown')).toBe(false)
|
|
expect(shouldBounceMissingWorktree('repo::wt', 'present')).toBe(false)
|
|
})
|
|
|
|
it('never bounces synthetic routes the host cannot resolve', () => {
|
|
expect(isSyntheticWorkspaceRoute('folder:/Users/x/dir')).toBe(true)
|
|
expect(shouldBounceMissingWorktree('folder:/Users/x/dir', 'missing')).toBe(false)
|
|
expect(shouldBounceMissingWorktree('global-floating-terminal', 'missing')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('useMissingWorktreeBounce', () => {
|
|
let renderer: ReactTestRenderer | null = null
|
|
const bounce = vi.fn()
|
|
|
|
beforeEach(() => {
|
|
bounce.mockReset()
|
|
renderer = null
|
|
})
|
|
|
|
function Harness(props: { worktreeId: string; resolution: WorktreeShowResolution }): null {
|
|
useMissingWorktreeBounce({
|
|
hostId: 'host-1',
|
|
worktreeId: props.worktreeId,
|
|
resolution: props.resolution,
|
|
bounce
|
|
})
|
|
return null
|
|
}
|
|
|
|
function render(worktreeId: string, resolution: WorktreeShowResolution): void {
|
|
act(() => {
|
|
const element = createElement(Harness, { worktreeId, resolution })
|
|
if (renderer) {
|
|
renderer.update(element)
|
|
} else {
|
|
renderer = create(element)
|
|
}
|
|
})
|
|
}
|
|
|
|
it('bounces exactly once per worktree even across re-renders', () => {
|
|
render('repo::wt', 'unknown')
|
|
expect(bounce).not.toHaveBeenCalled()
|
|
|
|
render('repo::wt', 'missing')
|
|
expect(bounce).toHaveBeenCalledExactlyOnceWith('host-1')
|
|
|
|
// Why: navigation lands after the render, so the pre-unmount renders must not re-fire.
|
|
render('repo::wt', 'missing')
|
|
expect(bounce).toHaveBeenCalledTimes(1)
|
|
act(() => renderer?.unmount())
|
|
})
|
|
|
|
it('re-arms for a different worktree on the reused screen', () => {
|
|
render('repo::wt-1', 'missing')
|
|
expect(bounce).toHaveBeenCalledTimes(1)
|
|
|
|
render('repo::wt-2', 'unknown')
|
|
expect(bounce).toHaveBeenCalledTimes(1)
|
|
render('repo::wt-2', 'missing')
|
|
expect(bounce).toHaveBeenCalledTimes(2)
|
|
act(() => renderer?.unmount())
|
|
})
|
|
})
|