mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
test: consolidate duplicate checks and strengthen runtime assertions (#33171)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,6 @@ const {
|
||||
readElfMachine,
|
||||
declaredArchFromPath,
|
||||
findArchViolation,
|
||||
ELF_MACHINE_BY_ARCH,
|
||||
parseGlibcVersion,
|
||||
compareGlibcVersions,
|
||||
parseVersionNeeds,
|
||||
@@ -409,8 +408,8 @@ describe('bundled native binary architecture', () => {
|
||||
it('reads e_machine from a little-endian ELF', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'orca-elf-arch-'))
|
||||
const file = join(dir, 'pty.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.arm64))
|
||||
expect(readElfMachine(file)).toBe(ELF_MACHINE_BY_ARCH.arm64)
|
||||
await writeFile(file, elfHeader(0xb7))
|
||||
expect(readElfMachine(file)).toBe(0xb7)
|
||||
await rm(dir, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
@@ -423,7 +422,7 @@ describe('bundled native binary architecture', () => {
|
||||
const pkg = join(dir, '@parcel', 'watcher-linux-arm64-glibc')
|
||||
await mkdir(pkg, { recursive: true })
|
||||
const file = join(pkg, 'watcher.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.arm64))
|
||||
await writeFile(file, elfHeader(0xb7))
|
||||
expect(declaredArchFromPath(file)).toBe('arm64')
|
||||
expect(findArchViolation(file, 'x64')).toBeNull()
|
||||
await rm(dir, { recursive: true, force: true })
|
||||
@@ -435,7 +434,7 @@ describe('bundled native binary architecture', () => {
|
||||
const nested = join(dir, 'bin', 'linux-arm64-148')
|
||||
await mkdir(nested, { recursive: true })
|
||||
const file = join(nested, 'node-pty.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.x64))
|
||||
await writeFile(file, elfHeader(0x3e))
|
||||
expect(findArchViolation(file, 'arm64')).toMatchObject({ actual: 'x64', expectedArch: 'arm64' })
|
||||
// Still caught even when the slice being built is x64.
|
||||
expect(findArchViolation(file, 'x64')).toMatchObject({ actual: 'x64', expectedArch: 'arm64' })
|
||||
@@ -448,7 +447,7 @@ describe('bundled native binary architecture', () => {
|
||||
const dir = join(root, 'resources', 'ripgrep', 'linux-x64')
|
||||
await mkdir(dir, { recursive: true })
|
||||
const file = join(dir, 'rg')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.x64))
|
||||
await writeFile(file, elfHeader(0x3e))
|
||||
expect(findArchViolation(file, 'arm64', root)).toBeNull()
|
||||
await rm(dirname(root), { recursive: true, force: true })
|
||||
})
|
||||
@@ -456,7 +455,7 @@ describe('bundled native binary architecture', () => {
|
||||
it('flags an x86-64 binary in an arm64 slice', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'orca-elf-arch-'))
|
||||
const file = join(dir, 'pty.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.x64))
|
||||
await writeFile(file, elfHeader(0x3e))
|
||||
expect(findArchViolation(file, 'arm64')).toMatchObject({ actual: 'x64' })
|
||||
await rm(dir, { recursive: true, force: true })
|
||||
})
|
||||
@@ -464,7 +463,7 @@ describe('bundled native binary architecture', () => {
|
||||
it('accepts a matching architecture', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'orca-elf-arch-'))
|
||||
const file = join(dir, 'pty.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.x64))
|
||||
await writeFile(file, elfHeader(0x3e))
|
||||
expect(findArchViolation(file, 'x64')).toBeNull()
|
||||
await rm(dir, { recursive: true, force: true })
|
||||
})
|
||||
@@ -472,7 +471,7 @@ describe('bundled native binary architecture', () => {
|
||||
it('stays silent when no target architecture is supplied', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'orca-elf-arch-'))
|
||||
const file = join(dir, 'pty.node')
|
||||
await writeFile(file, elfHeader(ELF_MACHINE_BY_ARCH.x64))
|
||||
await writeFile(file, elfHeader(0x3e))
|
||||
expect(findArchViolation(file, undefined)).toBeNull()
|
||||
await rm(dir, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join } from 'node:path'
|
||||
@@ -15,10 +15,6 @@ const {
|
||||
const { CYGWIN_BREAKAWAY_MARKER } = require('./node-pty-job-ownership.cjs')
|
||||
|
||||
const fixtureDir = mkdtempSync(join(tmpdir(), 'packaged-node-pty-job-'))
|
||||
const ELECTRON_BUILDER_CONFIG = readFileSync(
|
||||
new URL('../electron-builder.config.cjs', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
|
||||
/** A real enough addon: a machine field the arch check reads, and the marker. */
|
||||
function conptyImage({ arch = 'x64', cygwinBreakawayDenied = true } = {}) {
|
||||
@@ -139,33 +135,16 @@ describe('verifyPackagedConptyBreakawayMarker', () => {
|
||||
// The cross-host package. No host but Windows can build conpty.node, so there
|
||||
// is no build/Release for prune to have replaced the prebuild with -- and the
|
||||
// published prebuild is exactly the binary that leaks every MSYS pane child.
|
||||
it('fails a cross-host package left holding the published prebuild', () => {
|
||||
it('rejects an unpatched published prebuild and explains both host remedies', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'prebuilds/win32-x64/conpty.node': { cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')).toThrow(
|
||||
/predates the Cygwin\/MSYS job-breakaway denial/
|
||||
)
|
||||
})
|
||||
|
||||
it('tells that package how to fix it, which is not a rebuild it can run', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'prebuilds/win32-x64/conpty.node': { cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')).toThrow(
|
||||
const verify = () => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')
|
||||
expect(verify).toThrow(/predates the Cygwin\/MSYS job-breakaway denial/)
|
||||
expect(verify).toThrow(
|
||||
/this package holds no node-pty source build at all[\s\S]*Otherwise package this Windows slice on a host that can/
|
||||
)
|
||||
})
|
||||
|
||||
// The same state reaches this from a capable host too, when the rebuild left
|
||||
// nothing: telling that packager to change hosts would send them nowhere.
|
||||
it('does not assume the packaging host is the wrong one', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'prebuilds/win32-x64/conpty.node': { cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')).toThrow(
|
||||
/If this IS a Windows x64 host, the rebuild did not leave one/
|
||||
)
|
||||
expect(verify).toThrow(/If this IS a Windows x64 host, the rebuild did not leave one/)
|
||||
})
|
||||
|
||||
// The cross-arch package that worked: beforeBuild rebuilds node-pty for the
|
||||
@@ -183,30 +162,25 @@ describe('verifyPackagedConptyBreakawayMarker', () => {
|
||||
// The cross-arch package that silently did not: build/Release is the
|
||||
// packaging host's own arch, the target cannot load it, and the loader falls
|
||||
// through to the unpatched prebuild underneath.
|
||||
it('fails a cross-arch package whose build/Release is the packaging host arch', () => {
|
||||
it('rejects a wrong-arch source build with the target rebuild command', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'build/Release/conpty.node': { arch: 'x64' },
|
||||
'prebuilds/win32-arm64/conpty.node': { arch: 'arm64', cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/prebuilds[\\/]win32-arm64/
|
||||
const verify = () => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')
|
||||
expect(verify).toThrow(/prebuilds[\\/]win32-arm64/)
|
||||
expect(verify).toThrow(
|
||||
/the source build beside it is the wrong architecture[\s\S]*machine 0x8664/
|
||||
)
|
||||
expect(verify).toThrow(/rebuild-native-deps\.mjs --platform=win32 --arch=arm64/)
|
||||
expect(verify).toThrow(/^(?![\s\S]*Package this Windows slice on such a host)[\s\S]*$/)
|
||||
})
|
||||
|
||||
it('refuses a package whose every conpty.node is the wrong architecture', () => {
|
||||
it('rejects unloadable architectures and reports their machine values', () => {
|
||||
const resourcesDir = packagedResources({ 'build/Release/conpty.node': { arch: 'x64' } })
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/the app can load none of them/
|
||||
)
|
||||
})
|
||||
|
||||
// Naming the machine it found is what separates a cross-arch build from a
|
||||
// truncated download, which are the same "cannot load this" to the loader.
|
||||
it('names what it found rather than guessing why', () => {
|
||||
const resourcesDir = packagedResources({ 'build/Release/conpty.node': { arch: 'x64' } })
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/machine 0x8664[\s\S]*0xaa64/
|
||||
)
|
||||
const verify = () => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')
|
||||
expect(verify).toThrow(/the app can load none of them/)
|
||||
expect(verify).toThrow(/machine 0x8664[\s\S]*0xaa64/)
|
||||
})
|
||||
|
||||
it('calls a candidate that is not a PE image what it is', () => {
|
||||
@@ -245,38 +219,6 @@ describe('verifyPackagedConptyBreakawayMarker', () => {
|
||||
)
|
||||
})
|
||||
|
||||
// The remedy for this one is a rebuild, not a different host, and the
|
||||
// difference is a build somebody has to run twice to find out.
|
||||
it('blames the wrong-arch source build rather than the host, when there is one', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'build/Release/conpty.node': { arch: 'x64' },
|
||||
'prebuilds/win32-arm64/conpty.node': { arch: 'arm64', cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/the source build beside it is the wrong architecture[\s\S]*machine 0x8664/
|
||||
)
|
||||
})
|
||||
|
||||
it('tells that build the command that would fix it', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'build/Release/conpty.node': { arch: 'x64' },
|
||||
'prebuilds/win32-arm64/conpty.node': { arch: 'arm64', cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/rebuild-native-deps\.mjs --platform=win32 --arch=arm64/
|
||||
)
|
||||
})
|
||||
|
||||
it('does not tell it to change hosts, which would not help', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'build/Release/conpty.node': { arch: 'x64' },
|
||||
'prebuilds/win32-arm64/conpty.node': { arch: 'arm64', cygwinBreakawayDenied: false }
|
||||
})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'arm64')).toThrow(
|
||||
/^(?![\s\S]*Package this Windows slice on such a host)[\s\S]*$/
|
||||
)
|
||||
})
|
||||
|
||||
it('ignores a prebuild for an arch this slice will never load', () => {
|
||||
const resourcesDir = packagedResources({
|
||||
'build/Release/conpty.node': {},
|
||||
@@ -310,18 +252,11 @@ describe('verifyPackagedConptyBreakawayMarker', () => {
|
||||
|
||||
// Nothing to load is not "a layout we do not recognise", it is a package with
|
||||
// no ConPTY backend, and a gate that cannot see its subject is not a gate.
|
||||
it('refuses rather than skip a package with no conpty.node at all', () => {
|
||||
it('rejects a package with no ConPTY backend and lists the searched paths', () => {
|
||||
const resourcesDir = packagedResources({})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')).toThrow(
|
||||
/no conpty\.node on any path its loader tries/
|
||||
)
|
||||
})
|
||||
|
||||
it('names every path it looked at when it finds none', () => {
|
||||
const resourcesDir = packagedResources({})
|
||||
expect(() => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')).toThrow(
|
||||
/build[\\/]Release[\s\S]*build[\\/]Debug[\s\S]*prebuilds[\\/]win32-x64/
|
||||
)
|
||||
const verify = () => verifyPackagedConptyBreakawayMarker(resourcesDir, 'x64')
|
||||
expect(verify).toThrow(/no conpty\.node on any path its loader tries/)
|
||||
expect(verify).toThrow(/build[\\/]Release[\s\S]*build[\\/]Debug[\s\S]*prebuilds[\\/]win32-x64/)
|
||||
})
|
||||
|
||||
// Present but unreadable is the state that used to pass, so it must not warn.
|
||||
@@ -421,10 +356,4 @@ describe('verifyPackagedWindowsNodePty', () => {
|
||||
})
|
||||
).toThrow(/predates the Cygwin\/MSYS job-breakaway denial/)
|
||||
})
|
||||
|
||||
it('is what the afterPack hook calls for a Windows slice', () => {
|
||||
expect(ELECTRON_BUILDER_CONFIG).toContain(
|
||||
'verifyPackagedWindowsNodePty(resourcesDir, context.arch, { canExecuteTargetArch })'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises'
|
||||
import { mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises'
|
||||
import { realpathSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import { tmpdir } from 'node:os'
|
||||
@@ -21,23 +21,6 @@ async function writeSkillsCliFixture(outDir, handlerSource) {
|
||||
}
|
||||
|
||||
describe('skills CLI runtime closure', () => {
|
||||
it('runs after Electron composes the final output', async () => {
|
||||
const packageJson = JSON.parse(
|
||||
await readFile(new URL('../../package.json', import.meta.url), 'utf8')
|
||||
)
|
||||
for (const scriptName of ['build:desktop', 'build:desktop:ci', 'build:release']) {
|
||||
const script = packageJson.scripts[scriptName].replace(
|
||||
'pnpm run build:desktop:assets',
|
||||
packageJson.scripts['build:desktop:assets']
|
||||
)
|
||||
expect(script).toContain('build:electron-vite')
|
||||
expect(script).toContain('verify:built-skills-cli')
|
||||
expect(script.indexOf('build:electron-vite')).toBeLessThan(
|
||||
script.indexOf('verify:built-skills-cli')
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('reports the missing final-artifact import and its owner', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'orca-skills-cli-closure-'))
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { expect, it } from 'vitest'
|
||||
import { WSL_FAMILIES, wslOrcadQualification } from './wsl-orcad-qualification.mjs'
|
||||
import { wslOrcadQualification } from './wsl-orcad-qualification.mjs'
|
||||
|
||||
const fullFamilies = ['ubuntu-24.04', 'debian-12', 'fedora-41']
|
||||
const runtime = 'src/main/runtime/rpc/methods/session-title.ts'
|
||||
const events = Array.from({ length: 100 }, (_, index) => ({
|
||||
name: 'pull_request',
|
||||
@@ -45,7 +46,7 @@ it.each([
|
||||
'src/main/runtime/../outside.ts'
|
||||
])('retains every distro for a mixed change containing %s', (file) => {
|
||||
expect(wslOrcadQualification([runtime, file], [runtime, file], event).families).toEqual(
|
||||
WSL_FAMILIES
|
||||
fullFamilies
|
||||
)
|
||||
})
|
||||
|
||||
@@ -76,6 +77,6 @@ it.each([
|
||||
])(
|
||||
'fails closed for incomplete, non-modification or reference evidence: %j',
|
||||
({ changed, modified, context }) => {
|
||||
expect(wslOrcadQualification(changed, modified, context).families).toEqual(WSL_FAMILIES)
|
||||
expect(wslOrcadQualification(changed, modified, context).families).toEqual(fullFamilies)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { HostProfile } from './types'
|
||||
import {
|
||||
HOME_AUTO_CONNECT_LIMIT,
|
||||
resolveHomeHostConnectionState,
|
||||
selectHomeAutoConnectHostIds
|
||||
} from './home-host-auto-connect'
|
||||
@@ -25,11 +24,12 @@ describe('home host auto-connect', () => {
|
||||
host('second', 4),
|
||||
host('third', 3),
|
||||
host('fourth', 2),
|
||||
host('missing-credentials', 6, false)
|
||||
host('missing-credentials', 6, false),
|
||||
{ ...host('missing-token', 7), deviceToken: '' },
|
||||
{ ...host('missing-key', 8), publicKeyB64: '' }
|
||||
]
|
||||
|
||||
expect(selectHomeAutoConnectHostIds(hosts)).toEqual(['newest', 'second', 'third'])
|
||||
expect(selectHomeAutoConnectHostIds(hosts)).toHaveLength(HOME_AUTO_CONNECT_LIMIT)
|
||||
})
|
||||
|
||||
it('does not mutate the host card order', () => {
|
||||
|
||||
@@ -17,16 +17,19 @@ describe('HostOpenRetryScheduler', () => {
|
||||
open
|
||||
})
|
||||
|
||||
scheduler.recordFailure('host-1', generation)
|
||||
await vi.advanceTimersByTimeAsync(1_000)
|
||||
expect(open).toHaveBeenCalledOnce()
|
||||
|
||||
generation = 2
|
||||
scheduler.recordFailure('host-1', generation)
|
||||
await vi.advanceTimersByTimeAsync(1_999)
|
||||
expect(open).toHaveBeenCalledOnce()
|
||||
await vi.advanceTimersByTimeAsync(1)
|
||||
expect(open).toHaveBeenCalledTimes(2)
|
||||
const delays = [1_000, 2_000, 5_000, 15_000, 30_000, 60_000, 60_000]
|
||||
for (const [index, delay] of delays.entries()) {
|
||||
generation = index + 1
|
||||
expect(scheduler.recordFailure('host-1', generation)).toEqual({
|
||||
failureCount: index + 1,
|
||||
nextDelayMs: delay
|
||||
})
|
||||
await vi.advanceTimersByTimeAsync(delay - 1)
|
||||
expect(open).toHaveBeenCalledTimes(index)
|
||||
await vi.advanceTimersByTimeAsync(1)
|
||||
expect(open).toHaveBeenCalledTimes(index + 1)
|
||||
expect(open).toHaveBeenLastCalledWith('host-1')
|
||||
}
|
||||
})
|
||||
|
||||
it('expedites without forgiving the failure streak', async () => {
|
||||
@@ -47,6 +50,13 @@ describe('HostOpenRetryScheduler', () => {
|
||||
expect(open).toHaveBeenCalledOnce()
|
||||
await vi.advanceTimersByTimeAsync(1)
|
||||
expect(open).toHaveBeenCalledTimes(2)
|
||||
|
||||
scheduler.recordFailure('host-1', generation)
|
||||
generation = 3
|
||||
scheduler.expedite('host-1')
|
||||
expect(open).toHaveBeenCalledTimes(2)
|
||||
await vi.advanceTimersByTimeAsync(5_000)
|
||||
expect(open).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('schedules and clears with no injected timers when the global rejects a non-global receiver', async () => {
|
||||
|
||||
@@ -161,7 +161,9 @@ describe('mobileWeb.bundle.v1 on a released client', () => {
|
||||
expect(advertised.probedCapabilities).toContain(MOBILE_WEB_BUNDLE_CAPABILITY)
|
||||
expect(advertised.quickCommandsSupported).toBe(true)
|
||||
expect(advertised.worktreeCreateSupport?.tasksSupported).toBe(true)
|
||||
expect(advertised.worktreeCreateSupport?.worktreeCreateIdempotency).not.toBe(false)
|
||||
expect(advertised.worktreeCreateSupport?.worktreeCreateIdempotency).toEqual({
|
||||
dedupeTtlMs: 60_000
|
||||
})
|
||||
expect(oldDesktop.gates.hostCapabilities).not.toContain(MOBILE_WEB_BUNDLE_CAPABILITY)
|
||||
|
||||
expect(asIfNeverAdvertised(advertised)).toEqual(oldDesktop)
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('the host status decodes from every version the gate admits', () => {
|
||||
protocolVersion: 5,
|
||||
minCompatibleMobileVersion: 1,
|
||||
appVersion: '1.4.200',
|
||||
capabilities: ['mobile.tasks.v1', 'push.v1'],
|
||||
capabilities: ['mobile.tasks.v1', 'push.v1', 'a', 'b'],
|
||||
floatingWorkspaceEnabled: true,
|
||||
hostPlatform: 'darwin',
|
||||
machineName: 'Studio'
|
||||
@@ -40,10 +40,6 @@ describe('the host status decodes from every version the gate admits', () => {
|
||||
})
|
||||
|
||||
describe('capabilities salvage whole, not per element', () => {
|
||||
it('keeps a list of strings', () => {
|
||||
expect(reads(hostStatusSchema, { capabilities: ['a', 'b'] }).capabilities).toEqual(['a', 'b'])
|
||||
})
|
||||
|
||||
it('drops the whole list for one non-string, which is what the probe published', () => {
|
||||
// transport-capability-probe-non-string-capabilities-drop records main publishing `[]` for
|
||||
// `['push.v1', 7]`; dropping only the 7 would publish a set main never published.
|
||||
|
||||
@@ -21,6 +21,9 @@ describe('browser history view rows', () => {
|
||||
expect(listBrowserHistoryRows(history, [], 'orca github').map((r) => r.title)).toEqual([
|
||||
'Orca repo'
|
||||
])
|
||||
expect(listBrowserHistoryRows(history, [], ' GITHUB ORCA ').map((r) => r.title)).toEqual([
|
||||
'Orca repo'
|
||||
])
|
||||
expect(listBrowserHistoryRows(history, [], '').map((r) => r.title)).toEqual([
|
||||
'Orca - Wikipedia',
|
||||
'Orca repo'
|
||||
|
||||
@@ -7,10 +7,16 @@ describe('requestViewerZoom', () => {
|
||||
expect(requestViewerZoom('in')).toBe(false)
|
||||
|
||||
const onZoom = vi.fn()
|
||||
const stop = listenForViewerZoomRequests(onZoom, { current: document.body })
|
||||
const rootRef: { current: HTMLElement | null } = { current: document.body }
|
||||
const stop = listenForViewerZoomRequests(onZoom, rootRef)
|
||||
expect(requestViewerZoom('out')).toBe(true)
|
||||
expect(onZoom).toHaveBeenCalledWith('out')
|
||||
|
||||
rootRef.current = null
|
||||
expect(requestViewerZoom('in')).toBe(false)
|
||||
expect(onZoom).toHaveBeenCalledTimes(1)
|
||||
|
||||
rootRef.current = document.body
|
||||
stop()
|
||||
expect(requestViewerZoom('reset')).toBe(false)
|
||||
expect(onZoom).toHaveBeenCalledTimes(1)
|
||||
|
||||
@@ -109,6 +109,14 @@ describe('useAiVaultPanelScope', () => {
|
||||
expect(hook.result.current.collapsedGroups.size).toBe(512)
|
||||
expect(hook.result.current.collapsedGroups.has('group-0')).toBe(false)
|
||||
expect(hook.result.current.collapsedGroups.has('group-512')).toBe(true)
|
||||
|
||||
act(() => hook.result.current.toggleGroup('group-512'))
|
||||
expect(hook.result.current.collapsedGroups.size).toBe(511)
|
||||
expect(hook.result.current.collapsedGroups.has('group-512')).toBe(false)
|
||||
act(() => hook.result.current.toggleGroup('group-512'))
|
||||
expect(hook.result.current.collapsedGroups.size).toBe(512)
|
||||
expect(hook.result.current.collapsedGroups.has('group-1')).toBe(true)
|
||||
expect(hook.result.current.collapsedGroups.has('group-512')).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps a dialog local without inheriting or changing sidebar choices', () => {
|
||||
|
||||
+2
@@ -115,5 +115,7 @@ describe('loginSetsEqual', () => {
|
||||
loginSetOfUsers([{ login: 'alice', name: null, avatarUrl: '' }])
|
||||
)
|
||||
).toBe(true)
|
||||
expect(loginSetsEqual(new Set(['alice']), new Set(['bob']))).toBe(false)
|
||||
expect(loginSetsEqual(new Set(['alice']), new Set(['alice', 'bob']))).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -67,6 +67,10 @@ describe('groupLinearIssues', () => {
|
||||
'identifier'
|
||||
)
|
||||
expect(sections.map((section) => section.key)).toEqual(['status:Todo', 'status:Done'])
|
||||
expect(sections.map((section) => section.issues.map((entry) => entry.identifier))).toEqual([
|
||||
['COR-1'],
|
||||
['COR-2']
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -48,15 +48,6 @@ describe('findStructuredAgentSessionTab', () => {
|
||||
createdAt: 0
|
||||
} satisfies Tab
|
||||
|
||||
it('matches the native session identity in its workspace inventory', () => {
|
||||
expect(
|
||||
findStructuredAgentSessionTab(
|
||||
{ 'wt-1': [tab] },
|
||||
{ workspaceId: 'wt-1', sessionId: 'session-1' }
|
||||
)
|
||||
).toBe(tab)
|
||||
})
|
||||
|
||||
it('does not match a session or tab from another workspace', () => {
|
||||
expect(
|
||||
findStructuredAgentSessionTab(
|
||||
|
||||
@@ -132,5 +132,23 @@ describe('reference evidence native chat identity', () => {
|
||||
agent: 'claude',
|
||||
sessionId: 'chat-session'
|
||||
})
|
||||
|
||||
const renamed = {
|
||||
...chat,
|
||||
unifiedTabsByWorktree: {
|
||||
[workspaceId]: chat.unifiedTabsByWorktree[workspaceId].map((tab) => ({
|
||||
...tab,
|
||||
customLabel: 'Pinned chat'
|
||||
}))
|
||||
}
|
||||
}
|
||||
expect(
|
||||
getWorkspaceAttachmentObservedOrigin(
|
||||
renamed,
|
||||
workspaceId,
|
||||
{ kind: 'agent-session', tabId: 'chat-tab' },
|
||||
'local'
|
||||
)
|
||||
).toMatchObject({ label: 'Pinned chat' })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user