mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
test: remove low-value image, runtime and cleanup tests (#42086)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
@@ -239,7 +239,6 @@
|
||||
"config/scripts/desktop-distribution/runtime-verification/verify-packaged-serve-payload.test.mjs": 83,
|
||||
"config/scripts/desktop-distribution/runtime-verification/verify-packaged-windows-agent-hook.test.mjs": 43,
|
||||
"config/scripts/runtime-verification/skills-cli/verify-skills-cli-runtime.test.mjs": 213,
|
||||
"config/scripts/test-runtime/module-cache/vitest-module-cache-resolution-key.test.ts": 50,
|
||||
"config/scripts/test-runtime/node-worker/vitest-node-runtime-pool.test.ts": 560,
|
||||
"config/scripts/test-runtime/environment/vitest-real-agent-home-write-guard.test.ts": 71,
|
||||
"config/scripts/test-runtime/execution-policy/vitest-run-temp-directory.test.mjs": 51,
|
||||
@@ -258,7 +257,6 @@
|
||||
"config/scripts/ci/workflow-contracts/workflow-ref-mirror-case-safety.test.mjs": 447,
|
||||
"config/scripts/ci/workflow-contracts/workflow-ref-reachability.test.mjs": 1650,
|
||||
"config/scripts/workspace/source-exports/workspace-source-exports.test.mjs": 117,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-admission.test.mjs": 1430,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-coordinate-boundaries.test.mjs": 191,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-file-transport.test.mjs": 404,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-glyph-visibility.test.mjs": 250,
|
||||
@@ -266,7 +264,6 @@
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-placeholder-lifecycle.test.mjs": 252,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-kitty-retransmit.test.mjs": 835,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-lifecycle-contract.test.mjs": 174,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-memory-contract.test.mjs": 368,
|
||||
"config/scripts/terminal-dependencies/xterm-patches/xterm-image-wasm-budget-contract.test.mjs": 469,
|
||||
"config/scripts/ci/workflow-contracts/zcode-credential-workflow.test.mjs": 668,
|
||||
"config/scripts/archives/platform-command/zip-extractor-command.test.mjs": 74,
|
||||
|
||||
-19
@@ -3,35 +3,16 @@ import { countRecurringTimers } from './check-recurring-timer-ratchet.mjs'
|
||||
|
||||
describe('recurring-timer ratchet', () => {
|
||||
it.each([
|
||||
['setInterval(poll, 1000)', 1],
|
||||
['window.setInterval(poll, 1)\nglobalThis.setInterval(poll, 1)\nobj.setInterval(1)', 2],
|
||||
[
|
||||
"import { setInterval } from 'node:timers'\nsetInterval(poll, 1)\nwindow.setInterval(poll, 1)",
|
||||
2
|
||||
],
|
||||
["const { setInterval } = require('node:timers')\nsetInterval(poll, 1)", 1],
|
||||
["import { setInterval as every } from 'node:timers/promises'\nevery(5000)", 1],
|
||||
// Alias and destructure forms of an imported timer count once, like the direct call.
|
||||
[
|
||||
"import * as timers from 'node:timers'\nconst setInterval = timers.setInterval\nsetInterval(poll, 1)",
|
||||
1
|
||||
],
|
||||
[
|
||||
"const timers = require('node:timers')\nconst { setInterval } = timers\nsetInterval(poll, 1)",
|
||||
1
|
||||
],
|
||||
["const { setInterval } = await import('node:timers')\nsetInterval(poll, 1)", 1],
|
||||
// An unrelated local binding must not hide a global poll elsewhere in the file.
|
||||
['function configure(setInterval) {\n return setInterval\n}\nsetInterval(poll, 1000)', 1],
|
||||
['type Configure = (setInterval: number) => void\nsetInterval(poll, 1000)', 1],
|
||||
['function a(setInterval) { setInterval(f) }\nfunction b() { setInterval(g, 1) }', 1],
|
||||
['function setInterval(f) {}\nsetInterval(poll)', 0],
|
||||
// Aliases and bracket access of the global timer are charged at the reference.
|
||||
['const schedule = setInterval\nschedule(poll, 1000)', 1],
|
||||
["window['setInterval'](poll, 1000)", 1],
|
||||
['const every = window.setInterval\nevery(poll, 1)', 1],
|
||||
["if (typeof setInterval === 'function') {}\ntype T = typeof setInterval", 0],
|
||||
['const deps = { setInterval, clearInterval }\ndeps.setInterval(poll, 1)', 1],
|
||||
["setInterval = replacement\nwindow['setInterval'] = replacement\ntypeof (setInterval)", 0],
|
||||
['(window.setInterval ||= fallback)(poll, 1000)', 1]
|
||||
])('counts %s', (source, count) => {
|
||||
|
||||
-7
@@ -67,15 +67,8 @@ describe('listChangedFiles', () => {
|
||||
})
|
||||
|
||||
it.each([
|
||||
['a new finding', `${movedImports}Date.now()\n`],
|
||||
['a changed suppression comment', movedImports.replace('declaration only', 'new reason')],
|
||||
['an import binding change', movedImports.replace('{ watch }', '{ watch as renamed }')],
|
||||
[
|
||||
'an import type flag change',
|
||||
movedImports.replace('import type { Snapshot }', 'import { Snapshot }')
|
||||
],
|
||||
['a body change', movedImports.replace('Date.now()', 'performance.now()')],
|
||||
['a whitespace change', `${movedImports}\n`],
|
||||
['a parse failure', `${movedImports})\n`]
|
||||
])('keeps %s in enforcement scope alongside import path changes', (_label, current) => {
|
||||
createExistingTest()
|
||||
|
||||
@@ -23,13 +23,10 @@ function runWithBase(base) {
|
||||
|
||||
describe('check-react-doctor-changed diff base', () => {
|
||||
// Invalid bases must fail before installing or running a tool.
|
||||
it.each(['main & calc', 'main | whoami', 'main"x', '%PATH%', 'main $(id)', '--help'])(
|
||||
'refuses %j',
|
||||
(base) => {
|
||||
const result = runWithBase(base)
|
||||
it.each(['main $(id)', '--help'])('refuses %j', (base) => {
|
||||
const result = runWithBase(base)
|
||||
|
||||
expect(result.status).not.toBe(0)
|
||||
expect(result.stderr).toContain('Refusing to pass an unsafe diff base')
|
||||
}
|
||||
)
|
||||
expect(result.status).not.toBe(0)
|
||||
expect(result.stderr).toContain('Refusing to pass an unsafe diff base')
|
||||
})
|
||||
})
|
||||
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
createPlaceholderTerminal,
|
||||
PNG,
|
||||
TrackedBitmap,
|
||||
writeKitty
|
||||
} from './xterm-kitty-placeholder-test-terminal.mjs'
|
||||
|
||||
afterEach(() => vi.unstubAllGlobals())
|
||||
|
||||
describe('virtual prototype admission before replacement retirement', () => {
|
||||
it('bounds markerless prototypes across distinct sources while allowing replacement at the bound', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
vi.stubGlobal('createImageBitmap', async () => {
|
||||
const bitmap = new TrackedBitmap(1, 1)
|
||||
h.bitmaps.push(bitmap)
|
||||
return bitmap
|
||||
})
|
||||
try {
|
||||
for (let id = 1; id <= 256; id++) {
|
||||
await writeKitty(h.terminal, `a=T,f=100,i=${id},U=1,p=10,c=1,r=1`, PNG)
|
||||
}
|
||||
expect(h.kitty._virtualStorageIds.size).toBe(256)
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=257,U=1,p=10,c=1,r=1', PNG)
|
||||
expect(h.kitty._virtualStorageIds.size).toBe(256)
|
||||
expect(h.storage._images.size).toBe(256)
|
||||
expect(h.bitmaps[256].close).toHaveBeenCalledOnce()
|
||||
const replaced = h.bitmaps[0]
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=1,U=1,p=10,c=1,r=1', PNG)
|
||||
expect(h.kitty._virtualStorageIds.size).toBe(256)
|
||||
expect(h.storage._images.size).toBe(256)
|
||||
expect(replaced.close).toHaveBeenCalledOnce()
|
||||
expect(h.bitmaps[257].close).not.toHaveBeenCalled()
|
||||
h.addon.reset()
|
||||
expect(h.kitty._virtualStorageIds.size).toBe(0)
|
||||
expect(h.storage._images.size).toBe(0)
|
||||
for (const bitmap of h.bitmaps) {
|
||||
expect(bitmap.close).toHaveBeenCalledOnce()
|
||||
}
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('reads a reduced live budget and safely retires a failed current replacement', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
const previous = h.bitmaps[0]
|
||||
const oversized = new TrackedBitmap(400, 400)
|
||||
let finish
|
||||
vi.stubGlobal(
|
||||
'createImageBitmap',
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
finish = resolve
|
||||
})
|
||||
)
|
||||
const writing = writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
await vi.waitFor(() => expect(finish).toBeTypeOf('function'))
|
||||
h.addon.storageLimit = 0.5
|
||||
finish(oversized)
|
||||
await writing
|
||||
expect(h.kitty._virtualStorageIds.size).toBe(0)
|
||||
expect(h.storage._images.size).toBe(0)
|
||||
expect(previous.close).toHaveBeenCalledOnce()
|
||||
expect(oversized.close).toHaveBeenCalledOnce()
|
||||
expect(h.addon.storageUsage).toBeLessThanOrEqual(0.5)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
+30
-40
@@ -18,8 +18,7 @@ const marks = {
|
||||
128: '\u{82d}',
|
||||
255: '\u{a8e5}',
|
||||
256: '\u{a8e6}',
|
||||
283: '\u{10a0f}',
|
||||
296: '\u{1d244}'
|
||||
283: '\u{10a0f}'
|
||||
}
|
||||
|
||||
function colors(id, placement = 0) {
|
||||
@@ -35,45 +34,40 @@ function placeholderAt(id, placement, row, col) {
|
||||
}
|
||||
|
||||
describe('placeholder coordinate and ID boundaries through real parsing', () => {
|
||||
it.each([0xff000007, 0xffffffff])(
|
||||
'resolves maximum high-byte image ID %i as unsigned',
|
||||
async (id) => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, `a=T,f=100,i=${id},U=1,c=2,r=2`, PNG)
|
||||
await write(h.terminal, placeholderAt(id, 0, 0, 0))
|
||||
expect(render(h)).toHaveLength(1)
|
||||
expect(h.kitty._virtualPlacements.has(id)).toBe(true)
|
||||
expect(h.kitty._virtualPlacements.has(id | 0)).toBe(false)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
it('resolves maximum high-byte image ID as unsigned', async () => {
|
||||
const id = 0xff000007
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, `a=T,f=100,i=${id},U=1,c=2,r=2`, PNG)
|
||||
await write(h.terminal, placeholderAt(id, 0, 0, 0))
|
||||
expect(render(h)).toHaveLength(1)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it.each([283, 296])(
|
||||
'decodes non-BMP row/column index %i without UTF-16 splitting',
|
||||
async (index) => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
h.addon._handlers.get('kitty')._createBitmap = async () => {
|
||||
const bitmap = new TrackedBitmap(297, 297)
|
||||
h.bitmaps.push(bitmap)
|
||||
return bitmap
|
||||
}
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=297,r=297', PNG)
|
||||
await write(h.terminal, placeholderAt(7, 0, index, index))
|
||||
const calls = render(h)
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].slice(1)).toEqual([index, index, 1, 1, 0, 0, 10, 10])
|
||||
expect(h.terminal.buffer.active.cursorX).toBe(1)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
it('decodes a non-BMP row/column index without UTF-16 splitting', async () => {
|
||||
const index = 283
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
h.addon._handlers.get('kitty')._createBitmap = async () => {
|
||||
const bitmap = new TrackedBitmap(297, 297)
|
||||
h.bitmaps.push(bitmap)
|
||||
return bitmap
|
||||
}
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=297,r=297', PNG)
|
||||
await write(h.terminal, placeholderAt(7, 0, index, index))
|
||||
const calls = render(h)
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].slice(1)).toEqual([index, index, 1, 1, 0, 0, 10, 10])
|
||||
expect(h.terminal.buffer.active.cursorX).toBe(1)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it.each([256, 296])('rejects table index %i only in the high-byte position', async (index) => {
|
||||
it('rejects table index 256 in the high-byte position', async () => {
|
||||
const index = 256
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
@@ -142,8 +136,6 @@ async function prepared() {
|
||||
|
||||
async function overwriteUnnamed(h) {
|
||||
await write(h.terminal, `\x1b[0m\x1b[H\x1b[38;2;0;0;7m${PLACEHOLDER}\u0305\u0305`)
|
||||
const line = h.terminal._core.buffer.lines.get(0)
|
||||
expect(line.getBg(0) & 0x10000000).toBe(0)
|
||||
return render(h)
|
||||
}
|
||||
|
||||
@@ -152,8 +144,6 @@ describe('placeholder placement IDs after overwriting old extended attributes',
|
||||
const h = await prepared()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=d,d=I,i=7,p=10,q=2')
|
||||
expect(h.kitty._virtualPlacements.get(7).has(0)).toBe(true)
|
||||
expect(h.kitty._virtualPlacements.get(7).has(10)).toBe(false)
|
||||
const calls = await overwriteUnnamed(h)
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0][0]).toBe(h.bitmaps[0])
|
||||
|
||||
-67
@@ -2,7 +2,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
createPlaceholderTerminal,
|
||||
placeholderCells,
|
||||
TrackedBitmap,
|
||||
write
|
||||
} from './xterm-kitty-placeholder-test-terminal.mjs'
|
||||
|
||||
@@ -12,17 +11,6 @@ afterEach(() => vi.unstubAllGlobals())
|
||||
|
||||
const cell = (h, row = 0, col = 0) => h.terminal.buffer.active.getLine(row)?.getCell(col)
|
||||
|
||||
function metadata(line, col) {
|
||||
return {
|
||||
words: [...line._data.subarray(col * 3, col * 3 + 3)],
|
||||
chars: line.getString(col),
|
||||
width: line.getWidth(col),
|
||||
code: line.getCodePoint(col),
|
||||
combined: line.isCombined(col),
|
||||
extended: line._extendedAttrs[col]
|
||||
}
|
||||
}
|
||||
|
||||
function reservedRow(h, last = false) {
|
||||
const buffer = h.terminal._core.buffer
|
||||
for (
|
||||
@@ -54,45 +42,6 @@ describe('reserved placeholder glyph visibility', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('masks a reserved cell without replacing its physical tile payload or linked attributes', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await write(
|
||||
h.terminal,
|
||||
`\x1b[4;48;2;30;40;50m\x1b]8;;https://example.invalid/\x1b\\${placeholderCells(7, 10, 1, 1)}\x1b]8;;\x1b\\\x1b[H`
|
||||
)
|
||||
const bitmap = new TrackedBitmap(10, 10)
|
||||
h.storage.addImage(bitmap, { scrolling: true, layer: 'top', zIndex: 0, cursorPos: 'iip' })
|
||||
const line = h.terminal._core.buffer.lines.get(0)
|
||||
const realCell = cell(h)
|
||||
realCell.fg &= ~INVISIBLE
|
||||
line.setCell(0, realCell)
|
||||
const before = metadata(line, 0)
|
||||
const extended = line.getExtended(0)
|
||||
const payload = extended.payload
|
||||
const attrs = [extended.ext, extended.urlId, extended.underlineColor]
|
||||
expect(extended.urlId).toBeGreaterThan(0)
|
||||
expect(extended.underlineColor & 0xffffff).toBe(10)
|
||||
expect(h.storage._images.get(payload.imageId).orig).toBe(bitmap)
|
||||
h.kitty.hidePlaceholderGlyphs(h.terminal)
|
||||
const after = metadata(line, 0)
|
||||
expect(after).toEqual({
|
||||
...before,
|
||||
words: [before.words[0], before.words[1] | INVISIBLE, before.words[2]]
|
||||
})
|
||||
expect(line.getExtended(0)).toBe(extended)
|
||||
expect(line.getExtended(0).payload).toBe(payload)
|
||||
expect([extended.ext, extended.urlId, extended.underlineColor]).toEqual(attrs)
|
||||
const drawImage = vi.fn()
|
||||
const canvas = { getContext: () => ({ drawImage }) }
|
||||
window.document = { createElement: () => canvas }
|
||||
expect(h.storage.getImageAtBufferCell(0, 0)).toBe(canvas)
|
||||
expect(drawImage).toHaveBeenCalledWith(bitmap, 0, 0, 10, 10)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('ordinary text overwrites clear invisibility and remain visible', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
@@ -131,22 +80,6 @@ describe('reserved placeholder glyph visibility', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('cancels a queued scroll scan when the addon is disposed', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await write(h.terminal, `${PLACEHOLDER}\r\n${'ROW\r\n'.repeat(24)}`)
|
||||
const scans = vi.spyOn(h.kitty, 'hidePlaceholderGlyphs')
|
||||
h.terminal.scrollToTop()
|
||||
h.addon.dispose()
|
||||
await Promise.resolve()
|
||||
expect(scans).not.toHaveBeenCalled()
|
||||
expect(cell(h).getChars()).toBe(PLACEHOLDER)
|
||||
expect(cell(h).isInvisible()).toBeFalsy()
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('addon disposal releases visibility subscriptions while keeping the terminal usable', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
|
||||
+3
-33
@@ -30,29 +30,13 @@ describe('Kitty virtual placement ownership and rendering', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it.each(['i', 'I'])('releases the virtual bitmap on d=%s', async (selector) => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
await write(h.terminal, placeholderCells(7))
|
||||
expect(render(h)).toHaveLength(2)
|
||||
await writeKitty(h.terminal, `a=d,d=${selector},i=7,q=2`)
|
||||
expect(render(h)).toHaveLength(0)
|
||||
expect(h.storage._images.size).toBe(0)
|
||||
expect(h.bitmaps[0].close).toHaveBeenCalledOnce()
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('replaces a prototype without losing its encoded payload or leaking its old bitmap', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
const oldBitmap = h.bitmaps[0]
|
||||
await writeKitty(h.terminal, 'a=p,U=1,i=7,p=10,c=1,r=1')
|
||||
expect(h.kitty.getImage(7)).toBeDefined()
|
||||
expect(h.storage._images.size).toBe(1)
|
||||
|
||||
expect(oldBitmap.close).toHaveBeenCalledOnce()
|
||||
await write(h.terminal, placeholderCells(7, 10, 1, 1))
|
||||
expect(render(h)).toHaveLength(1)
|
||||
@@ -97,7 +81,7 @@ describe('Kitty virtual placement ownership and rendering', () => {
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
await writeKitty(h.terminal, 'a=d,d=i,i=7,q=2')
|
||||
expect(h.kitty.getImage(7)).toBeDefined()
|
||||
|
||||
await writeKitty(h.terminal, 'a=p,U=1,i=7,c=2,r=2')
|
||||
await write(h.terminal, placeholderCells(7))
|
||||
expect(render(h)).toHaveLength(2)
|
||||
@@ -122,30 +106,16 @@ describe('Kitty virtual placement ownership and rendering', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('ignores invalid row diacritics rather than treating them as omitted', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
await write(h.terminal, `\x1b[38;5;7m${PLACEHOLDER}\u0301${DIACRITICS[0]}`)
|
||||
expect(render(h)).toHaveLength(0)
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('preserves the source aspect ratio when cell proportions change', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
await write(h.terminal, placeholderCells(7))
|
||||
const createCanvas = vi.fn(() => ({ getContext: () => ({ drawImage: vi.fn() }) }))
|
||||
vi.stubGlobal('document', { createElement: createCanvas })
|
||||
|
||||
vi.spyOn(h.renderer, 'cellSize', 'get').mockReturnValue({ width: 5, height: 10 })
|
||||
const calls = render(h)
|
||||
expect(calls[0].slice(1)).toEqual([0, 0, 20, 5, 0, 7.5, 10, 2.5])
|
||||
expect(calls[1].slice(1)).toEqual([0, 5, 20, 5, 0, 10, 10, 2.5])
|
||||
expect(h.storage.getUsage()).toBe(0.0008)
|
||||
expect(createCanvas).not.toHaveBeenCalled()
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
|
||||
+2
-2
@@ -62,7 +62,7 @@ describe('Kitty virtual placement lifecycle', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it.each(['reset', 'dispose'])('discards a virtual decode completing after %s', async (action) => {
|
||||
it('discards a virtual decode completing after disposal', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
let finishDecode
|
||||
@@ -72,7 +72,7 @@ describe('Kitty virtual placement lifecycle', () => {
|
||||
})
|
||||
const decoding = writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,c=2,r=2', PNG)
|
||||
await vi.waitFor(() => expect(finishDecode).toBeTypeOf('function'))
|
||||
h.addon[action]()
|
||||
h.addon.dispose()
|
||||
const bitmap = new TrackedBitmap()
|
||||
finishDecode(bitmap)
|
||||
await decoding
|
||||
|
||||
-48
@@ -58,22 +58,6 @@ describe('placeholder replacement publication boundaries', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('does not delete another picture when the replacement fails decoding', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=9,U=1,p=11,c=2,r=2', PNG)
|
||||
const unrelated = [...h.kitty._virtualPlacements.get(9).values()][0]
|
||||
vi.stubGlobal('createImageBitmap', () => Promise.reject(new Error('decode failure')))
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
expect(h.kitty._virtualPlacements.has(7)).toBe(false)
|
||||
expect(h.kitty._virtualPlacements.get(9).get(11)).toBe(unrelated)
|
||||
expect(h.bitmaps[1].close).not.toHaveBeenCalled()
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('drops stale pictures and closes the replacement when storage rejects publication', async () => {
|
||||
const { h, first, pending } = await prepared()
|
||||
const writing = writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
@@ -92,36 +76,4 @@ describe('placeholder replacement publication boundaries', () => {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('retains every old placement until success, then leaves only the replacement placement ID', async () => {
|
||||
const h = createPlaceholderTerminal()
|
||||
try {
|
||||
await writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=10,c=2,r=2', PNG)
|
||||
await writeKitty(h.terminal, 'a=p,U=1,i=7,p=11,c=1,r=1')
|
||||
const old = [...h.bitmaps]
|
||||
let resolve
|
||||
vi.stubGlobal(
|
||||
'createImageBitmap',
|
||||
() =>
|
||||
new Promise((finish) => {
|
||||
resolve = finish
|
||||
})
|
||||
)
|
||||
const writing = writeKitty(h.terminal, 'a=T,f=100,i=7,U=1,p=12,c=2,r=2', PNG)
|
||||
await vi.waitFor(() => expect(resolve).toBeTypeOf('function'))
|
||||
const during = [...(h.kitty._virtualPlacements.get(7)?.keys() ?? [])]
|
||||
const replacement = new TrackedBitmap()
|
||||
resolve(replacement)
|
||||
await writing
|
||||
expect(during).toEqual([10, 11])
|
||||
expect([...h.kitty._virtualPlacements.get(7).keys()]).toEqual([12])
|
||||
expect(h.storage._images.size).toBe(1)
|
||||
for (const bitmap of old) {
|
||||
expect(bitmap.close).toHaveBeenCalledOnce()
|
||||
}
|
||||
expect(replacement.close).not.toHaveBeenCalled()
|
||||
} finally {
|
||||
h.terminal.dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ describe('xterm image allocation lifecycle', () => {
|
||||
const { terminal, kitty } = createTerminal()
|
||||
try {
|
||||
const compressed = deflateSync(Buffer.alloc(64 * 1024 * 1024))
|
||||
expect(compressed.byteLength).toBeLessThan(100_000)
|
||||
|
||||
const result = await kitty._decompressZlib(compressed).then(
|
||||
(bytes) => ({ decodedBytes: bytes.byteLength }),
|
||||
() => ({ rejected: true })
|
||||
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const require = createRequire(
|
||||
new URL('../../xterm-image-memory-contract.test.mjs', import.meta.url)
|
||||
)
|
||||
const { Terminal } = require('@xterm/xterm')
|
||||
const { ImageAddon } = require('@xterm/addon-image')
|
||||
|
||||
function createTerminal(options = {}) {
|
||||
const terminal = new Terminal({ allowProposedApi: true })
|
||||
const addon = new ImageAddon({
|
||||
enableSizeReports: false,
|
||||
storageLimit: 32,
|
||||
kittySizeLimit: 8 * 1024 * 1024,
|
||||
...options
|
||||
})
|
||||
terminal.loadAddon(addon)
|
||||
const handler = addon._handlers.get('kitty')
|
||||
if (options.kittyStorageLimit !== undefined) {
|
||||
handler._kittyStorage._storage.setLimit(options.kittyStorageLimit)
|
||||
}
|
||||
return { terminal, addon, handler }
|
||||
}
|
||||
|
||||
function writeKitty(terminal, command, payload) {
|
||||
return new Promise((resolve) => terminal.write(`\x1b_G${command};${payload}\x1b\\`, resolve))
|
||||
}
|
||||
|
||||
describe('xterm image memory contract', () => {
|
||||
it('bounds abandoned uploads by retained decoder capacity and accepts a continuation', async () => {
|
||||
const { terminal, handler } = createTerminal()
|
||||
try {
|
||||
for (let id = 1; id <= 40; id++) {
|
||||
await writeKitty(terminal, `a=t,f=32,s=1,v=1,i=${id},m=1,q=2`, 'AAAA')
|
||||
const pending = [...handler._pendingTransmissions.values()]
|
||||
const retainedBytes = pending.reduce(
|
||||
(total, upload) => total + upload.decoder._mem.buffer.byteLength,
|
||||
0
|
||||
)
|
||||
expect(retainedBytes).toBeLessThanOrEqual(32_000_000)
|
||||
expect(pending.length).toBeLessThanOrEqual(2)
|
||||
}
|
||||
await writeKitty(terminal, 'm=0,q=2', 'AA==')
|
||||
expect(handler._kittyStorage.getImage(40).data.size).toBe(4)
|
||||
terminal.dispose()
|
||||
expect(handler._pendingTransmissions.size).toBe(0)
|
||||
} finally {
|
||||
terminal.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('evicts transmitted images by byte size before placement', async () => {
|
||||
const { terminal, handler } = createTerminal({ storageLimit: 12, kittyStorageLimit: 0.5 })
|
||||
const payload = Buffer.alloc(200_000, 1).toString('base64')
|
||||
try {
|
||||
for (let id = 1; id <= 4; id++) {
|
||||
await writeKitty(terminal, `a=t,f=32,s=250,v=200,i=${id},q=2`, payload)
|
||||
const retainedBytes = [...handler._kittyStorage.images.values()].reduce(
|
||||
(total, image) => total + image.data.size,
|
||||
0
|
||||
)
|
||||
expect(retainedBytes).toBeLessThanOrEqual(500_000)
|
||||
}
|
||||
expect(handler._kittyStorage.getImage(1)).toBeUndefined()
|
||||
expect(handler._kittyStorage.getImage(3).data.size).toBe(200_000)
|
||||
expect(handler._kittyStorage.getImage(4).data.size).toBe(200_000)
|
||||
await writeKitty(terminal, 'a=d,d=A,q=2', '')
|
||||
expect(handler._kittyStorage.images.size).toBe(0)
|
||||
} finally {
|
||||
terminal.dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
+4
-16
@@ -7,8 +7,6 @@ const require = createRequire(
|
||||
const { Terminal } = require('@xterm/xterm')
|
||||
const { ImageAddon } = require('@xterm/addon-image')
|
||||
|
||||
// Renderer V8 limits live wasm memories (~124); idle terminals need zero and exhaustion must drop image without wedging write queue.
|
||||
|
||||
const SIXEL_RED_REGISTER_1 = '\x1bPq#1;2;100;0;0#1~\x1b\\'
|
||||
const SIXEL_USE_REGISTER_1 = '\x1bPq#1~\x1b\\'
|
||||
const PNG_1X1 =
|
||||
@@ -65,14 +63,6 @@ function write(terminal, data) {
|
||||
return new Promise((resolve) => terminal.write(data, resolve))
|
||||
}
|
||||
|
||||
// A throw out of a handler leaves xterm's write queue waiting forever.
|
||||
function writeOrWedge(terminal, data) {
|
||||
return Promise.race([
|
||||
write(terminal, data).then(() => 'parsed'),
|
||||
new Promise((resolve) => setTimeout(() => resolve('wedged'), 2000))
|
||||
])
|
||||
}
|
||||
|
||||
function firstPixel(image) {
|
||||
return Array.from(image.data.subarray(0, 4))
|
||||
}
|
||||
@@ -107,12 +97,10 @@ describe('xterm image wasm budget', () => {
|
||||
}
|
||||
vi.stubGlobal('WebAssembly', { ...WebAssembly, Memory: exhausted, Instance: exhausted })
|
||||
try {
|
||||
expect(await writeOrWedge(terminal, '\x1b_Ga=T,f=32,s=1,v=1,i=7;AAAA/w==\x1b\\')).toBe(
|
||||
'parsed'
|
||||
)
|
||||
expect(await writeOrWedge(terminal, IIP_PNG)).toBe('parsed')
|
||||
expect(await writeOrWedge(terminal, SIXEL_USE_REGISTER_1)).toBe('parsed')
|
||||
expect(await writeOrWedge(terminal, 'after')).toBe('parsed')
|
||||
await write(terminal, '\x1b_Ga=T,f=32,s=1,v=1,i=7;AAAA/w==\x1b\\')
|
||||
await write(terminal, IIP_PNG)
|
||||
await write(terminal, SIXEL_USE_REGISTER_1)
|
||||
await write(terminal, 'after')
|
||||
|
||||
expect(addon._storage._images.size).toBe(0)
|
||||
expect(replies.join('')).toContain('ENOMEM')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join, resolve } from 'node:path'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import { gitSigningOffEnv } from './vitest-git-signing-env.mjs'
|
||||
|
||||
@@ -26,9 +26,7 @@ it('commits and tags unsigned under a signing global config, keeping its other s
|
||||
const inherited = { ...process.env, GIT_CONFIG_GLOBAL: globalConfig, GIT_CONFIG_NOSYSTEM: '1' }
|
||||
const env = { ...inherited, ...gitSigningOffEnv(inherited) }
|
||||
cleanup.push(env.GIT_CONFIG_GLOBAL)
|
||||
expect(dirname(env.GIT_CONFIG_GLOBAL)).toBe(
|
||||
resolve(import.meta.dirname, '../../../../node_modules/.cache')
|
||||
)
|
||||
|
||||
const git = (...args) =>
|
||||
execFileSync('git', args, { cwd: root, env, encoding: 'utf8', stdio: 'pipe' }).trim()
|
||||
|
||||
@@ -39,5 +37,4 @@ it('commits and tags unsigned under a signing global config, keeping its other s
|
||||
|
||||
expect(git('cat-file', '-t', 'v1.0.0')).toBe('commit')
|
||||
expect(git('log', '-1', '--format=%an %G?')).toBe('Test N')
|
||||
expect(gitSigningOffEnv({ ...inherited, GIT_CONFIG_GLOBAL: join(root, 'missing') })).toEqual({})
|
||||
})
|
||||
|
||||
@@ -13,9 +13,4 @@ describe.skipIf(!globalThis.orcaRealAgentCliGuard)('vitest real-agent-cli guard'
|
||||
expect(result.stderr).toMatch(/real-agent-cli guard/)
|
||||
expect(takeRealAgentCliCalls()).toEqual(['claude -p hello'])
|
||||
})
|
||||
|
||||
it('records calls from a shell that keeps the inherited PATH', () => {
|
||||
spawnSync('/bin/sh', ['-c', 'copilot --help; codex exec x'], { env: process.env })
|
||||
expect(takeRealAgentCliCalls()).toEqual(['copilot --help', 'codex exec x'])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import { createResolutionFingerprint } from './vitest-module-cache-resolution-key'
|
||||
|
||||
const roots: string[] = []
|
||||
afterEach(() => {
|
||||
for (const root of roots.splice(0)) {
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
function fixture(): string {
|
||||
const root = mkdtempSync(join(tmpdir(), 'orca-resolution-key-'))
|
||||
roots.push(root)
|
||||
mkdirSync(join(root, 'src/lib/foo'), { recursive: true })
|
||||
writeFileSync(join(root, 'src/lib/foo/index.ts'), '')
|
||||
return root
|
||||
}
|
||||
|
||||
const source = "import a from './lib/foo'\nimport b from '@/lib/foo?raw'"
|
||||
const aliases = (root: string) => [{ find: '@', replacement: join(root, 'src') }]
|
||||
|
||||
it.each([
|
||||
['a same-stem sibling shadows a directory index', 'src/lib/foo.ts'],
|
||||
['a higher-precedence extension appears', 'src/lib/foo.mts'],
|
||||
['another index candidate appears', 'src/lib/foo/index.mts'],
|
||||
['the directory gains a package.json', 'src/lib/foo/package.json']
|
||||
])('changes the key when %s', (_, added) => {
|
||||
const root = fixture()
|
||||
const before = createResolutionFingerprint(root, aliases(root))(join(root, 'src/a.ts'), source)
|
||||
writeFileSync(join(root, added), '{}')
|
||||
const after = createResolutionFingerprint(root, aliases(root))(join(root, 'src/a.ts'), source)
|
||||
expect(after).not.toBe(before)
|
||||
})
|
||||
@@ -7,7 +7,7 @@ import { createVitestZodBundle } from './vitest-zod-bundle.mjs'
|
||||
let root
|
||||
afterEach(() => rmSync(root, { recursive: true, force: true }))
|
||||
|
||||
it('reuses one bundle across runs and removes directories leaked by killed runs', () => {
|
||||
it('removes stale directories leaked by killed runs and preserves recent ones', () => {
|
||||
root = mkdtempSync(join(tmpdir(), 'orca-zod-bundle-'))
|
||||
const leaked = join(root, '.tmp', 'vitest-zod-leaked')
|
||||
const active = join(root, '.tmp', 'vitest-zod-active')
|
||||
@@ -16,11 +16,9 @@ it('reuses one bundle across runs and removes directories leaked by killed runs'
|
||||
const hoursAgo = new Date(Date.now() - 7 * 60 * 60 * 1000)
|
||||
utimesSync(leaked, hoursAgo, hoursAgo)
|
||||
|
||||
const first = createVitestZodBundle(root)
|
||||
const second = createVitestZodBundle(root)
|
||||
const bundle = createVitestZodBundle(root)
|
||||
|
||||
expect(second.path).toBe(first.path)
|
||||
expect(existsSync(first.path)).toBe(true)
|
||||
expect(existsSync(bundle.path)).toBe(true)
|
||||
expect(existsSync(leaked)).toBe(false)
|
||||
expect(existsSync(active)).toBe(true)
|
||||
})
|
||||
|
||||
@@ -4,20 +4,11 @@ import { runTypecheckProjects, TYPECHECK_PROJECTS } from './run-typecheck-projec
|
||||
|
||||
const spawn = vi.fn()
|
||||
let children
|
||||
let active
|
||||
let peak
|
||||
beforeEach(() => {
|
||||
children = []
|
||||
active = 0
|
||||
peak = 0
|
||||
spawn.mockReset().mockImplementation((spec) => {
|
||||
const child = new EventEmitter()
|
||||
children.push({ child, spec })
|
||||
active++
|
||||
peak = Math.max(peak, active)
|
||||
child.once('close', () => {
|
||||
active--
|
||||
})
|
||||
return child
|
||||
})
|
||||
})
|
||||
@@ -49,5 +40,4 @@ it('keeps checking after compiler failures and reports errors in project order',
|
||||
'bun config/tsconfig.node.json exited with signal SIGKILL',
|
||||
'bun config/tsconfig.tc.web.json exited with code 1'
|
||||
])
|
||||
expect(peak).toBe(2)
|
||||
})
|
||||
|
||||
@@ -78,26 +78,19 @@ function request(method = 'GET', url = '/wasm/fixture.wasm') {
|
||||
return { response, next, source: observed.streams.at(-1), foreign }
|
||||
}
|
||||
|
||||
it('releases file handles after repeated abandoned responses with backpressure', async () => {
|
||||
const responses: ReturnType<typeof request>[] = []
|
||||
for (let index = 0; index < 25; index += 1) {
|
||||
const current = request()
|
||||
const { response, source } = current
|
||||
responses.push(current)
|
||||
if (!source) {
|
||||
throw new Error('Missing source')
|
||||
}
|
||||
await once(source, 'pause')
|
||||
const closed = once(response, 'close')
|
||||
response.destroy()
|
||||
await closed
|
||||
}
|
||||
await expect.poll(() => observed.streams.filter((stream) => !stream.closed).length).toBe(0)
|
||||
expect(observed.streams.every((stream) => stream.fd === null)).toBe(true)
|
||||
for (const { response, foreign } of responses) {
|
||||
expect(response.listeners('close')).toEqual([foreign.close])
|
||||
expect(response.listeners('error')).toEqual([foreign.error])
|
||||
it('releases the file handle after an abandoned response with backpressure', async () => {
|
||||
const { response, source, foreign } = request()
|
||||
if (!source) {
|
||||
throw new Error('Missing source')
|
||||
}
|
||||
await once(source, 'pause')
|
||||
const closed = once(response, 'close')
|
||||
response.destroy()
|
||||
await closed
|
||||
await expect.poll(() => source.closed).toBe(true)
|
||||
expect(source.fd).toBeNull()
|
||||
expect(response.listeners('close')).toEqual([foreign.close])
|
||||
expect(response.listeners('error')).toEqual([foreign.error])
|
||||
})
|
||||
|
||||
it('preserves successful GET bytes and removes response cleanup listeners', async () => {
|
||||
@@ -108,10 +101,6 @@ it('preserves successful GET bytes and removes response cleanup listeners', asyn
|
||||
await expect.poll(() => source?.closed).toBe(true)
|
||||
expect(Buffer.concat(chunks).toString()).toBe('map bytes')
|
||||
expect(response.statusCode).toBe(200)
|
||||
expect(response.setHeader.mock.calls).toEqual([
|
||||
['Content-Length', 9],
|
||||
['Content-Type', 'application/octet-stream']
|
||||
])
|
||||
expect(response.listeners('close')).toEqual([foreign.close])
|
||||
expect(response.listeners('error')).toEqual([foreign.error])
|
||||
expect(next).not.toHaveBeenCalled()
|
||||
|
||||
@@ -1,32 +1,10 @@
|
||||
import { spawn } from 'node:child_process'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { parse } from 'yaml'
|
||||
import { UNIT_EXCLUDE } from '../../ci/unit-selection/dependency-graph/ci-unit-files.mjs'
|
||||
import { classifyPrJobs } from './pr-code-change-scope.mjs'
|
||||
|
||||
const projectDir = resolve(import.meta.dirname, '../../../..')
|
||||
|
||||
const SHELL_CONTRACTS_STEP = 'Test real shell contracts'
|
||||
|
||||
/** Every test file the shell contracts step's whole `run` script names, across all of its commands.
|
||||
* The YAML parser owns the block's extent, so a blank line or a later command cannot truncate the
|
||||
* list (C3-3). Null when the step is gone. */
|
||||
function shellContractsStepTests(workflowYaml) {
|
||||
const steps = parse(workflowYaml)?.jobs?.shell_contracts?.steps ?? []
|
||||
const step = steps.find((candidate) => candidate?.name === SHELL_CONTRACTS_STEP)
|
||||
if (typeof step?.run !== 'string') {
|
||||
return null
|
||||
}
|
||||
return step.run.split(/\s+/).filter((token) => token.endsWith('.test.ts'))
|
||||
}
|
||||
|
||||
describe('per-job path classification', () => {
|
||||
// Mobile-only edits must run audits that lint mobile; skipped audits let #20702 duplicate imports break later merge refs.
|
||||
|
||||
// The ratchet: adding a tree to an audit command has to widen this trigger on its own.
|
||||
|
||||
// Stale-base diffs exceed pipe buffer; one fd-0 read can exit 0 with no pairs, silently skipping every lane.
|
||||
it('classifies a path that arrives after the first pipe buffer', async () => {
|
||||
const filler = Array.from(
|
||||
@@ -76,22 +54,4 @@ describe('per-job path classification', () => {
|
||||
expect(stdout).toContain('should_run=true\n')
|
||||
expect(stdout).toContain('xterm_patch_sync=true\n')
|
||||
})
|
||||
|
||||
// Unit shards exclude live-shell tests, so a test the shell contracts job runs must also route a focused
|
||||
// edit to that job; otherwise a change to it, or to what it guards, runs no real shell at all (STA-2380 C2 F1).
|
||||
it('routes every test the shell contracts job runs to shell_contracts', () => {
|
||||
const tests = shellContractsStepTests(
|
||||
readFileSync(resolve(projectDir, '.github/workflows/pr.yml'), 'utf8')
|
||||
)
|
||||
expect(tests, `pr.yml must keep the "${SHELL_CONTRACTS_STEP}" step`).not.toBeNull()
|
||||
// Partial-omission guard with an independent source: every real-shell test the unit shards exclude
|
||||
// is run by this job or by nothing, so each must appear in the parsed step.
|
||||
const realShellTests = UNIT_EXCLUDE.filter((file) =>
|
||||
/\.(?:live-shell|node-pty)\.test\.ts$/.test(file)
|
||||
)
|
||||
expect(realShellTests.length).toBeGreaterThan(0)
|
||||
expect(tests).toEqual(expect.arrayContaining(realShellTests))
|
||||
const unrouted = tests.filter((file) => classifyPrJobs([file]).shell_contracts !== true)
|
||||
expect(unrouted).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,11 +63,6 @@ it('maps only explicit public source exports with exact aliases independent of c
|
||||
false,
|
||||
false
|
||||
])
|
||||
expect(resolver.aliases.every((alias) => !alias.replacement.includes('/dist/'))).toBe(true)
|
||||
expect(resolver.esbuildAliases).toEqual({
|
||||
'@orca/process-host': resolver.resolve('@orca/process-host').path,
|
||||
'@orca/process-host/process-spec': resolver.resolve('@orca/process-host/process-spec').path
|
||||
})
|
||||
expect(resolver.resolve('node:child_process')).toBeNull()
|
||||
expect(resolver.resolve('zod')).toBeNull()
|
||||
})
|
||||
|
||||
@@ -29,8 +29,7 @@ function makeWorktree(bundles: { name: string; marker: boolean }[]): string {
|
||||
describe('sweeping across worktrees', () => {
|
||||
it.each([
|
||||
['--apply', '--exclude-worktree'],
|
||||
['--exclude-worktree', '--apply'],
|
||||
['--exclude-worktree', '-invalid', '--apply']
|
||||
['--exclude-worktree', '--apply']
|
||||
])('rejects invalid exclusion operands before cleanup: %j', async (...flags) => {
|
||||
const worktree = makeWorktree([{ name: 'idle', marker: true }])
|
||||
const initialized = await runProcess({ program: 'git', args: ['-C', worktree, 'init', '-q'] })
|
||||
|
||||
@@ -33,7 +33,7 @@ it('removes only idle profiles whose worktree of this repository is gone', async
|
||||
const running = profile('dddddddddd', path.join(root, 'removed-running'), commonDirectory)
|
||||
writeFileSync(path.join(running, 'orca-runtime.json'), JSON.stringify({ pid: 4242 }))
|
||||
|
||||
const result = await reclaimDevWorktreeProfiles({
|
||||
await reclaimDevWorktreeProfiles({
|
||||
apply: true,
|
||||
profilesRoot,
|
||||
repository: { commonDirectory, worktrees: [liveWorktree] },
|
||||
@@ -41,7 +41,6 @@ it('removes only idle profiles whose worktree of this repository is gone', async
|
||||
report: () => {}
|
||||
})
|
||||
|
||||
expect(result).toEqual({ entries: 1, protected: 1 })
|
||||
expect(existsSync(removed)).toBe(false)
|
||||
expect(existsSync(live)).toBe(true)
|
||||
expect(existsSync(otherRepo)).toBe(true)
|
||||
|
||||
@@ -70,22 +70,6 @@ it.skipIf(process.platform === 'win32')(
|
||||
}
|
||||
)
|
||||
|
||||
it('shares a writable install and preserves its executable bytes', async () => {
|
||||
const { pkg, executable, run } = await fixture()
|
||||
const preview = await run()
|
||||
expect(preview.code, preview.stderr).toBe(0)
|
||||
expect(preview.stdout).toContain('Would share 1 worktree(s)')
|
||||
const applied = await run(true)
|
||||
expect(applied.code, applied.stderr).toBe(0)
|
||||
expect(applied.stdout).toContain('Shared 1 worktree(s)')
|
||||
expect(await readFile(executable, 'utf8')).toBe('fake electron executable\n')
|
||||
expect(await readFile(join(pkg, '.orca-shared-dist'), 'utf8')).toBe(
|
||||
`99.1.0-${process.platform}-${process.arch}`
|
||||
)
|
||||
const repeated = await run()
|
||||
expect(repeated.stdout).toContain('Would share 0 worktree(s)')
|
||||
})
|
||||
|
||||
it('protects the launching worktree, including when selected through a filesystem alias', async () => {
|
||||
const { root, pkg, executable, run } = await fixture()
|
||||
const alias = join(root, 'alias')
|
||||
@@ -103,13 +87,11 @@ it('protects the launching worktree, including when selected through a filesyste
|
||||
}
|
||||
})
|
||||
|
||||
it.each([['--exclude-worktree'], ['--exclude-worktree', '--apply']])(
|
||||
'rejects invalid exclusions before changing an install: %j',
|
||||
async (...flags) => {
|
||||
const { pkg, run } = await fixture()
|
||||
const result = await run(true, flags)
|
||||
expect(result.code).not.toBe(0)
|
||||
expect(result.stderr).toContain('--exclude-worktree requires a directory')
|
||||
await expect(readFile(join(pkg, '.orca-shared-dist'))).rejects.toMatchObject({ code: 'ENOENT' })
|
||||
}
|
||||
)
|
||||
it('rejects a missing exclusion before changing an install', async () => {
|
||||
const flags = ['--exclude-worktree']
|
||||
const { pkg, run } = await fixture()
|
||||
const result = await run(true, flags)
|
||||
expect(result.code).not.toBe(0)
|
||||
expect(result.stderr).toContain('--exclude-worktree requires a directory')
|
||||
await expect(readFile(join(pkg, '.orca-shared-dist'))).rejects.toMatchObject({ code: 'ENOENT' })
|
||||
})
|
||||
|
||||
@@ -252,7 +252,6 @@ it('retains a replacement directory introduced while the final Git check is runn
|
||||
apply: true,
|
||||
report: () => {}
|
||||
})
|
||||
expect(checks).toBe(2)
|
||||
expect(result.protected).toBe(1)
|
||||
expect(await readFile(file, 'utf8')).toBe('generated bytes')
|
||||
expect(await readFile(join(saved, 'generated.txt'), 'utf8')).toBe('generated bytes')
|
||||
@@ -280,42 +279,39 @@ it.skipIf(process.platform === 'win32' || process.getuid?.() === 0)(
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['manual', 'automatic'])(
|
||||
'includes generated cleanup in %s CLI preview and apply',
|
||||
async (mode) => {
|
||||
const f = await fixture()
|
||||
const protectedFile = await generated(f.repoRoot)
|
||||
const file = await generated(f.sibling, 'mobile/node_modules')
|
||||
const store = join(f.root, 'global-pnpm-store')
|
||||
await mkdir(store)
|
||||
const shared = join(store, 'package.js')
|
||||
await writeFile(shared, 'shared package')
|
||||
await link(shared, join(dirname(file), 'package.js'))
|
||||
await symlink(store, join(dirname(file), 'shared-package'), 'junction')
|
||||
await utimes(dirname(file), new Date(0), new Date(0))
|
||||
const run = (args) =>
|
||||
runProcess({
|
||||
program: process.env.ORCA_TEST_NODE_EXECUTABLE ?? process.execPath,
|
||||
args: [
|
||||
resolve(import.meta.dirname, 'reclaim-worktree-space.mjs'),
|
||||
'--repo',
|
||||
f.repoRoot,
|
||||
...(mode === 'automatic' ? ['--automatic'] : []),
|
||||
...args
|
||||
],
|
||||
cwd: tmpdir(),
|
||||
env: { ...process.env, ORCA_BACKGROUND_LAUNCH: '1' },
|
||||
timeoutMs: 30_000,
|
||||
terminationBarrier: true
|
||||
})
|
||||
const preview = await run([])
|
||||
expect(preview.code, preview.stderr).toBe(0)
|
||||
expect(preview.stdout).toContain('would remove generated directory')
|
||||
expect(await readFile(file, 'utf8')).toBe('generated bytes')
|
||||
const applied = await run(['--apply'])
|
||||
expect(applied.code, applied.stderr).toBe(0)
|
||||
await expect(lstat(file)).rejects.toMatchObject({ code: 'ENOENT' })
|
||||
expect(await readFile(protectedFile, 'utf8')).toBe('generated bytes')
|
||||
expect(await readFile(shared, 'utf8')).toBe('shared package')
|
||||
}
|
||||
)
|
||||
it('includes generated cleanup in automatic CLI preview and apply', async () => {
|
||||
const f = await fixture()
|
||||
const protectedFile = await generated(f.repoRoot)
|
||||
const file = await generated(f.sibling, 'mobile/node_modules')
|
||||
const store = join(f.root, 'global-pnpm-store')
|
||||
await mkdir(store)
|
||||
const shared = join(store, 'package.js')
|
||||
await writeFile(shared, 'shared package')
|
||||
await link(shared, join(dirname(file), 'package.js'))
|
||||
await symlink(store, join(dirname(file), 'shared-package'), 'junction')
|
||||
await utimes(dirname(file), new Date(0), new Date(0))
|
||||
const run = (args) =>
|
||||
runProcess({
|
||||
program: process.env.ORCA_TEST_NODE_EXECUTABLE ?? process.execPath,
|
||||
args: [
|
||||
resolve(import.meta.dirname, 'reclaim-worktree-space.mjs'),
|
||||
'--repo',
|
||||
f.repoRoot,
|
||||
'--automatic',
|
||||
...args
|
||||
],
|
||||
cwd: tmpdir(),
|
||||
env: { ...process.env, ORCA_BACKGROUND_LAUNCH: '1' },
|
||||
timeoutMs: 30_000,
|
||||
terminationBarrier: true
|
||||
})
|
||||
const preview = await run([])
|
||||
expect(preview.code, preview.stderr).toBe(0)
|
||||
expect(preview.stdout).toContain('would remove generated directory')
|
||||
expect(await readFile(file, 'utf8')).toBe('generated bytes')
|
||||
const applied = await run(['--apply'])
|
||||
expect(applied.code, applied.stderr).toBe(0)
|
||||
await expect(lstat(file)).rejects.toMatchObject({ code: 'ENOENT' })
|
||||
expect(await readFile(protectedFile, 'utf8')).toBe('generated bytes')
|
||||
expect(await readFile(shared, 'utf8')).toBe('shared package')
|
||||
})
|
||||
|
||||
@@ -103,5 +103,4 @@ it('rejects competing sweeps and releases the lock after a failed operation', as
|
||||
await rejected
|
||||
options.execute.mockResolvedValue({ code: 0, timedOut: false })
|
||||
await reclaimWorktreeSpace(options)
|
||||
expect(options.execute).toHaveBeenCalledTimes(8)
|
||||
})
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// Run with `orca plugin test .`: plain Node, no Orca window, the same runtime and checks Orca uses.
|
||||
import { afterEach, assert, mount, test, type TestPanel } from 'orca/testing'
|
||||
import * as gallery from './panel'
|
||||
|
||||
let panel: TestPanel | undefined
|
||||
afterEach(() => panel?.unmount())
|
||||
|
||||
test('fills in the form and saves once the checks pass', async () => {
|
||||
panel = await mount(gallery)
|
||||
assert.ok(panel.find({ role: 'alert' }) === null)
|
||||
assert.equal(panel.find({ role: 'button', text: 'Save' })?.disabled, true)
|
||||
|
||||
await panel.type({ label: 'Title' }, 'Write docs')
|
||||
await panel.select({ label: 'Priority' }, 'high')
|
||||
await panel.slide({ label: 'Effort' }, 5)
|
||||
await panel.toggle({ label: 'I have read the guidelines' })
|
||||
await panel.press({ role: 'button', text: 'Save' })
|
||||
|
||||
assert.ok(panel.find({ text: 'Saved Write docs' }))
|
||||
assert.equal(panel.valueOf({ label: 'Priority' }), 'high')
|
||||
assert.deepEqual(panel.persisted.plugin['gallery.title'], 'Write docs')
|
||||
assert.deepEqual(panel.errors, [])
|
||||
})
|
||||
|
||||
test('pages, sorts and selects the Table, and loads Tree children lazily', async () => {
|
||||
panel = await mount(gallery)
|
||||
await panel.select({ type: 'Tabs' }, 'data')
|
||||
const table = { role: 'grid', label: 'Files' }
|
||||
assert.equal(panel.rowsOf(table).length, 50)
|
||||
|
||||
await panel.loadMore(table)
|
||||
assert.equal(panel.rowsOf(table).length, 100)
|
||||
await panel.sort(table, 'size')
|
||||
assert.equal(panel.rowsOf(table).length, 50)
|
||||
await panel.selectRows(table, panel.rowsOf(table).slice(0, 2))
|
||||
assert.ok(panel.find({ text: /2 selected/ }))
|
||||
|
||||
const tree = { role: 'tree' }
|
||||
assert.ok(!panel.find(tree)?.text.includes('main.ts'))
|
||||
await panel.expand(tree, 'src')
|
||||
assert.ok(panel.find(tree)?.text.includes('main.ts'))
|
||||
await panel.selectItem(tree, 'src/main.ts')
|
||||
assert.equal(panel.valueOf(tree), 'src/main.ts')
|
||||
assert.deepEqual(panel.errors, [])
|
||||
})
|
||||
Reference in New Issue
Block a user