mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
test: retire narrow runtime and navigation samples
This commit is contained in:
@@ -1,87 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { AgentLaunchResult } from '../../../../src/shared/agent-launch/contracts/agent-launch-intent'
|
||||
import { notificationPaneTab } from '../../session/tabs/notification-pane-tab'
|
||||
import type { MobileSessionTab } from '../../session/tabs/mobile-session-tabs'
|
||||
import { launchedAgentOpens } from './pr-ai-triage-launch'
|
||||
|
||||
function result(outcome: AgentLaunchResult['outcome']): AgentLaunchResult {
|
||||
return {
|
||||
outcome,
|
||||
worktreeId: 'wt-a',
|
||||
receipt: {
|
||||
mode: outcome.kind,
|
||||
preferred: outcome.kind,
|
||||
reason: 'requested',
|
||||
detail: 'Requested.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The id format createStructuredAgentSessionId produces: the agent, then a UUID with underscores.
|
||||
const SESSION_ID = 'claude_11111111_2222_4333_8444_555555555555'
|
||||
const LEAF_ID = '11111111-1111-4111-8111-111111111111'
|
||||
|
||||
const chatTab = (id: string, sessionId = SESSION_ID): MobileSessionTab => ({
|
||||
type: 'agent-session',
|
||||
id,
|
||||
title: 'Chat',
|
||||
sessionId,
|
||||
agent: 'claude',
|
||||
isActive: false
|
||||
})
|
||||
const otherChatTab = chatTab('tab-other', 'claude_99999999_2222_4333_8444_555555555555')
|
||||
|
||||
// The session screen finds the tab to select from the pane key with notificationPaneTab.
|
||||
describe('launchedAgentOpens', () => {
|
||||
it('names a chat by the tab the host reported, which the session screen finds', () => {
|
||||
const opens = launchedAgentOpens(
|
||||
result({ kind: 'structured', sessionId: SESSION_ID, handle: 'h', tabId: 'tab-9' })
|
||||
)
|
||||
expect(opens).toEqual({
|
||||
worktreeId: 'wt-a',
|
||||
paneKey: 'tab-9:7d731d20-5488-436f-ad53-d3e49333f320'
|
||||
})
|
||||
expect(notificationPaneTab([otherChatTab, chatTab('tab-9')], opens.paneKey ?? '')?.id).toBe(
|
||||
'tab-9'
|
||||
)
|
||||
})
|
||||
|
||||
it('derives a chat’s tab from its session on a host that reports none', () => {
|
||||
const opens = launchedAgentOpens(
|
||||
result({ kind: 'structured', sessionId: SESSION_ID, handle: 'h' })
|
||||
)
|
||||
expect(opens).toEqual({
|
||||
worktreeId: 'wt-a',
|
||||
paneKey:
|
||||
'structured-agent-session-claude_11111111_2222_4333_8444_555555555555:7d731d20-5488-436f-ad53-d3e49333f320'
|
||||
})
|
||||
// The host may publish the chat under another tab id; the session id still finds it.
|
||||
expect(
|
||||
notificationPaneTab([otherChatTab, chatTab('host-tab-3')], opens.paneKey ?? '')?.id
|
||||
).toBe('host-tab-3')
|
||||
})
|
||||
|
||||
it('names a terminal by its pane, or by none when the host reported none', () => {
|
||||
const paneKey = `tab-1:${LEAF_ID}`
|
||||
const opens = launchedAgentOpens(result({ kind: 'terminal', handle: 'h', paneKey }))
|
||||
expect(opens).toEqual({ worktreeId: 'wt-a', paneKey })
|
||||
const terminal = (id: string, leafId: string): MobileSessionTab => ({
|
||||
type: 'terminal',
|
||||
id,
|
||||
title: 'Terminal',
|
||||
isActive: false,
|
||||
terminal: null,
|
||||
leafId
|
||||
})
|
||||
expect(
|
||||
notificationPaneTab(
|
||||
[terminal('tab-2', LEAF_ID), terminal('tab-1', LEAF_ID)],
|
||||
opens.paneKey ?? ''
|
||||
)?.id
|
||||
).toBe('tab-1')
|
||||
expect(launchedAgentOpens(result({ kind: 'terminal', handle: 'h' }))).toEqual({
|
||||
worktreeId: 'wt-a',
|
||||
paneKey: null
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,94 +0,0 @@
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import { runWithGitCause } from './git-operation-cause'
|
||||
import { startGitSpan, withGitSpan } from './instrumentation'
|
||||
import { setActiveSink } from './tracer'
|
||||
|
||||
afterEach(() => setActiveSink(null))
|
||||
|
||||
it('keeps concurrent Git causes isolated and retires a settled cause before detached work', async () => {
|
||||
const records: unknown[] = []
|
||||
setActiveSink({ push: (record) => records.push(record), flush() {}, close() {} })
|
||||
const firstGate = Promise.withResolvers<void>()
|
||||
const secondGate = Promise.withResolvers<void>()
|
||||
const detachedGate = Promise.withResolvers<void>()
|
||||
let detached = Promise.resolve()
|
||||
const first = runWithGitCause(
|
||||
{ family: 'catalog', reason: 'desktop-catalog', cache: 'miss' },
|
||||
{ namespace: 'local', commonDir: '/fixture/common.git' },
|
||||
async () => {
|
||||
detached = detachedGate.promise.then(() =>
|
||||
withGitSpan({ args: ['worktree', 'remove', 'PRIVATE_PATH'] }, async () => {})
|
||||
)
|
||||
await withGitSpan({ args: ['worktree', 'list', '--porcelain', '-z'] }, async () => {
|
||||
await firstGate.promise
|
||||
})
|
||||
}
|
||||
)
|
||||
const second = runWithGitCause(
|
||||
{ family: 'fetch', reason: 'conflict-preview', cache: 'refresh' },
|
||||
{ namespace: 'wsl:fixture', commonDir: '/fixture/common.git' },
|
||||
() => withGitSpan({ args: ['fetch', 'PRIVATE_REMOTE'] }, () => secondGate.promise)
|
||||
)
|
||||
secondGate.resolve()
|
||||
await second
|
||||
firstGate.resolve()
|
||||
await first
|
||||
detachedGate.resolve()
|
||||
await detached
|
||||
|
||||
expect(records).toEqual([
|
||||
expect.objectContaining({
|
||||
attributes: expect.objectContaining({
|
||||
'git.reason': 'conflict-preview',
|
||||
'git.cache': 'refresh',
|
||||
'git.common_dir_hash': '48e43725147afff2'
|
||||
})
|
||||
}),
|
||||
expect.objectContaining({
|
||||
attributes: expect.objectContaining({
|
||||
'git.reason': 'desktop-catalog',
|
||||
'git.variant': 'worktree-list-z',
|
||||
'git.common_dir_hash': '39be98da86a94d54'
|
||||
})
|
||||
}),
|
||||
expect.objectContaining({
|
||||
attributes: expect.objectContaining({
|
||||
'git.subcommand': 'worktree',
|
||||
'git.arg_count': 3,
|
||||
'git.variant': 'worktree-remove'
|
||||
})
|
||||
})
|
||||
])
|
||||
expect(records[2]).toEqual(
|
||||
expect.objectContaining({
|
||||
attributes: expect.not.objectContaining({ 'git.reason': expect.any(String) })
|
||||
})
|
||||
)
|
||||
expect(JSON.stringify(records)).not.toContain('PRIVATE_')
|
||||
})
|
||||
|
||||
it('records fixed failure categories without changing the original Git rejection', async () => {
|
||||
const records: unknown[] = []
|
||||
setActiveSink({ push: (record) => records.push(record), flush() {}, close() {} })
|
||||
const error = new Error('PRIVATE_OUTPUT')
|
||||
await expect(
|
||||
withGitSpan({ args: ['for-each-ref', '--sort=-committerdate', 'PRIVATE_QUERY'] }, async () => {
|
||||
throw error
|
||||
})
|
||||
).rejects.toBe(error)
|
||||
const timeout = new Error('PRIVATE_TIMEOUT')
|
||||
timeout.name = 'GitCommandTimeoutError'
|
||||
startGitSpan({ args: ['fetch', 'PRIVATE_REMOTE'] }).fail(timeout)
|
||||
const cancelled = new Error('PRIVATE_CANCEL')
|
||||
cancelled.name = 'AbortError'
|
||||
startGitSpan({ args: ['status'] }).fail(cancelled)
|
||||
startGitSpan({ args: ['status'] }).interrupt('PRIVATE_INTERRUPT')
|
||||
|
||||
expect(records).toEqual([
|
||||
expect.objectContaining({ exit: { _tag: 'Failure', cause: 'Git command failed' } }),
|
||||
expect.objectContaining({ exit: { _tag: 'Failure', cause: 'Git command timed out' } }),
|
||||
expect.objectContaining({ exit: { _tag: 'Failure', cause: 'Git command cancelled' } }),
|
||||
expect.objectContaining({ exit: { _tag: 'Interrupted', cause: 'Git command cancelled' } })
|
||||
])
|
||||
expect(JSON.stringify(records)).not.toContain('PRIVATE_')
|
||||
})
|
||||
@@ -1,57 +0,0 @@
|
||||
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { runProcess } from '@orca/process-host'
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import { createSetupRunnerScript } from './worktree-runner-script'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
|
||||
let directory: string | undefined
|
||||
afterEach(async () => {
|
||||
if (directory) {
|
||||
await rm(directory, { recursive: true, force: true })
|
||||
directory = undefined
|
||||
}
|
||||
})
|
||||
|
||||
it('writes usable setup scripts for linked worktrees and rejects non-repositories', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'orca-setup-path-'))
|
||||
directory = root
|
||||
const git = async (args: string[]) => {
|
||||
const result = await runProcess({ program: 'git', args, cwd: root })
|
||||
if (result.code !== 0) {
|
||||
throw new Error(result.stderr)
|
||||
}
|
||||
return result.stdout.trim()
|
||||
}
|
||||
await git(['init', '-q'])
|
||||
await git(['config', 'user.name', 'Setup fixture'])
|
||||
await git(['config', 'user.email', 'setup@example.invalid'])
|
||||
await git(['config', 'commit.gpgsign', 'false'])
|
||||
await git(['config', 'core.hooksPath', ''])
|
||||
await git(['commit', '--allow-empty', '-qm', 'fixture'])
|
||||
const linked = join(root, 'linked')
|
||||
await git(['worktree', 'add', '--detach', linked, 'HEAD'])
|
||||
const repo: Repo = {
|
||||
id: 'setup-fixture',
|
||||
displayName: 'fixture',
|
||||
badgeColor: 'blue',
|
||||
addedAt: 0,
|
||||
path: root
|
||||
}
|
||||
const result = await createSetupRunnerScript(repo, linked, 'echo SETUP_PATH_OK')
|
||||
expect(await readFile(result.runnerScriptPath, 'utf8')).toContain('echo SETUP_PATH_OK')
|
||||
const execution = await runProcess({
|
||||
program: process.platform === 'win32' ? 'cmd.exe' : 'bash',
|
||||
args:
|
||||
process.platform === 'win32' ? ['/c', result.runnerScriptPath] : [result.runnerScriptPath],
|
||||
cwd: linked
|
||||
})
|
||||
expect(execution.code).toBe(0)
|
||||
expect(execution.stdout).toContain('SETUP_PATH_OK')
|
||||
const nonRepository = join(root, 'non-repository')
|
||||
await mkdir(nonRepository)
|
||||
// Stop Git discovery at an owned invalid marker, even when TMPDIR is inside a checkout.
|
||||
await writeFile(join(nonRepository, '.git'), 'gitdir: missing-fixture-directory\n')
|
||||
await expect(createSetupRunnerScript(repo, nonRepository, 'echo UNREACHABLE')).rejects.toThrow()
|
||||
})
|
||||
-87
@@ -52,44 +52,6 @@ afterEach(() => {
|
||||
})
|
||||
|
||||
describe('installDiffEditorHorizontalWheelScroll', () => {
|
||||
it('scrolls only the pane under the pointer on a sideways swipe without Shift', () => {
|
||||
const { original, modified } = installPanes(10)
|
||||
|
||||
const event = dispatchWheel(original.container, { deltaX: 30, deltaY: 4 })
|
||||
|
||||
expect(original.setScrollLeft).toHaveBeenCalledWith(40)
|
||||
expect(modified.setScrollLeft).not.toHaveBeenCalled()
|
||||
expect(event.defaultPrevented).toBe(true)
|
||||
})
|
||||
|
||||
it('leaves a mostly vertical swipe untouched for the outer list', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
const event = dispatchWheel(original.container, { deltaX: 5, deltaY: 40 })
|
||||
|
||||
expect(original.setScrollLeft).not.toHaveBeenCalled()
|
||||
expect(original.getScrollLeft()).toBe(10)
|
||||
expect(event.defaultPrevented).toBe(false)
|
||||
})
|
||||
|
||||
it('scrolls sideways from a vertical wheel while Shift is held', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
const event = dispatchWheel(original.container, { deltaX: 5, deltaY: 40, shiftKey: true })
|
||||
|
||||
expect(original.getScrollLeft()).toBe(50)
|
||||
expect(event.defaultPrevented).toBe(true)
|
||||
})
|
||||
|
||||
it('hands the gesture to the outer list when the pane is already at its edge', () => {
|
||||
const { original } = installPanes(800)
|
||||
|
||||
const event = dispatchWheel(original.container, { deltaY: 30, shiftKey: true })
|
||||
|
||||
expect(original.setScrollLeft).not.toHaveBeenCalled()
|
||||
expect(event.defaultPrevented).toBe(false)
|
||||
})
|
||||
|
||||
it('moves right by one pixel once quarter-pixel swipes add up to it', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
@@ -98,53 +60,4 @@ describe('installDiffEditorHorizontalWheelScroll', () => {
|
||||
expect(original.getScrollLeft()).toBe(11)
|
||||
expect(events.map((event) => event.defaultPrevented)).toEqual([true, true, true, true])
|
||||
})
|
||||
|
||||
it('moves left by one pixel once quarter-pixel swipes add up to it', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
swipe(original.container, -0.25, 4)
|
||||
|
||||
expect(original.getScrollLeft()).toBe(9)
|
||||
})
|
||||
|
||||
it('starts over when the swipe changes direction', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
swipe(original.container, 0.25, 3)
|
||||
swipe(original.container, -0.25, 3)
|
||||
expect(original.getScrollLeft()).toBe(10)
|
||||
|
||||
swipe(original.container, -0.25, 1)
|
||||
expect(original.getScrollLeft()).toBe(9)
|
||||
})
|
||||
|
||||
it('drops a partial pixel left over from an earlier gesture', () => {
|
||||
const { original } = installPanes(10)
|
||||
|
||||
dispatchWheel(original.container, { deltaX: 0.75, timeStamp: 1000 })
|
||||
dispatchWheel(original.container, { deltaX: 0.25, timeStamp: 1151 })
|
||||
expect(original.getScrollLeft()).toBe(10)
|
||||
|
||||
dispatchWheel(original.container, { deltaX: 0.75, timeStamp: 1301 })
|
||||
expect(original.getScrollLeft()).toBe(11)
|
||||
})
|
||||
|
||||
it('carries a partial pixel when the pointer crosses to the other pane', () => {
|
||||
const { original, modified } = installPanes(10)
|
||||
|
||||
swipe(original.container, 0.25, 2)
|
||||
swipe(modified.container, 0.25, 2)
|
||||
|
||||
expect(modified.getScrollLeft()).toBe(11)
|
||||
expect(original.getScrollLeft()).toBe(10)
|
||||
})
|
||||
|
||||
it('hands partial-pixel swipes at the edge to the outer list', () => {
|
||||
const { original } = installPanes(800)
|
||||
|
||||
const events = swipe(original.container, 0.25, 4)
|
||||
|
||||
expect(original.getScrollLeft()).toBe(800)
|
||||
expect(events.map((event) => event.defaultPrevented)).toEqual([false, false, false, false])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user