mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 16:03:45 +00:00
test(shared): ban vi.mock factory keys that name no export of the mocked module
A `vi.mock` key that matches no export of the module it names is not a stub, it is a comment. The registry serves it to nobody, production keeps calling the real function, and the suite goes green for a reason its author did not intend. Nothing caught this before: a factory is a plain object literal so it typechecks, nothing warns at runtime, and the only tell is to make the key throw and notice that nothing happens. The guard reads each factory's keys with the same oxc parser the bundler uses and compares them against the mocked module's real exports, following `export *`. A module whose exports cannot be fully enumerated is skipped rather than half-checked, so the guard never accuses a key it did not actually see. It convicted 86 sites across 73 suites on this commit, in eight clusters: 56 scheduleTerminalWebglAtlasRecovery on terminal-webgl-atlas-recovery 8 isSshPtyNotFoundError on ssh-pty-provider 7 isSshPtyIdentityMismatchError on ssh-pty-provider 3 answerStartupTerminalColorQueriesForPty on ipc/pty 4 BASE_REF_SEARCH_ARGS, filterBaseRefSearchOutput on git/repo 4 classifyProjectError, rateLimitedError, noteRateLimitSpend, rateLimitGuard 1 runWithFreshOrcaCloudSessionMock on profile-cloud-session-refresh 3 relative paths with no module behind them at all Each was confirmed dead by making the key throw on any access: 908 tests across the affected suites stayed green. The renamed symbols are repointed at the real export; the ones that exist nowhere are deleted; the three wrong paths are corrected. Deleting a key is behaviour-preserving by construction -- the real implementation was already the one running. The webgl cluster is the sharpest case: terminal-webgl-atlas-recovery's own test already asserted the module must NOT export `scheduleTerminalWebglAtlasRecovery`, and 56 suites went on mocking that name anyway. Nothing connected the two.
This commit is contained in:
committed by
Merge Sim
parent
d0a81db4cd
commit
9db3efad33
@@ -28,14 +28,12 @@ vi.mock('./internals', () => ({
|
||||
stdout: ''
|
||||
}),
|
||||
ghExecFileAsync: ghExecFileAsyncMock,
|
||||
rateLimitGuard: () => ({ blocked: false }),
|
||||
noteRateLimitSpend: vi.fn(),
|
||||
|
||||
repositoryRateLimitGuard: repositoryRateLimitGuardMock,
|
||||
noteRepositoryRateLimitSpend: noteRepositoryRateLimitSpendMock,
|
||||
projectHostAuthenticationError: projectHostAuthenticationErrorMock,
|
||||
projectGhExecOptions: (host?: string) => ({ host: host ?? 'github.com' }),
|
||||
classifyProjectError: (stderr: string) => ({ type: 'unknown', message: stderr }),
|
||||
rateLimitedError: () => ({ type: 'rate_limited', message: 'rate limited' }),
|
||||
|
||||
runGraphql: runGraphqlMock,
|
||||
runRest: runRestMock,
|
||||
validateSlugArgs: (owner: string, repo: string) =>
|
||||
|
||||
@@ -140,7 +140,7 @@ vi.mock('electron', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('../../shared/runtime-environment-store', () => ({
|
||||
vi.mock('../../../shared/runtime-environment-store', () => ({
|
||||
listEnvironments: listEnvironmentsMock
|
||||
}))
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ vi.mock('../git/repo', () => ({
|
||||
searchBaseRefs: vi.fn().mockResolvedValue([])
|
||||
}))
|
||||
|
||||
vi.mock('../repo-detection', () => ({
|
||||
vi.mock('../repo-icon-autodetect', () => ({
|
||||
detectRepoIconAndUpstream: detectRepoIconAndUpstreamMock
|
||||
}))
|
||||
|
||||
|
||||
@@ -30,9 +30,7 @@ vi.mock('../git/repo', () => ({
|
||||
isGitRepo: vi.fn().mockReturnValue(true),
|
||||
getRepoName: vi.fn().mockImplementation((path: string) => path.split('/').pop()),
|
||||
getBaseRefDefault: vi.fn().mockResolvedValue('origin/main'),
|
||||
searchBaseRefs: vi.fn().mockResolvedValue([]),
|
||||
BASE_REF_SEARCH_ARGS: ['for-each-ref'],
|
||||
filterBaseRefSearchOutput: vi.fn().mockReturnValue([])
|
||||
searchBaseRefs: vi.fn().mockResolvedValue([])
|
||||
}))
|
||||
|
||||
vi.mock('./registered-worktree-roots-cache', () => ({ invalidateAuthorizedRootsCache: vi.fn() }))
|
||||
|
||||
@@ -37,9 +37,7 @@ vi.mock('../git/repo', () => ({
|
||||
isGitRepo: vi.fn().mockReturnValue(true),
|
||||
getRepoName: vi.fn().mockImplementation((path: string) => path.split('/').pop()),
|
||||
getBaseRefDefault: vi.fn().mockResolvedValue('origin/main'),
|
||||
searchBaseRefs: vi.fn().mockResolvedValue([]),
|
||||
BASE_REF_SEARCH_ARGS: ['for-each-ref'],
|
||||
filterBaseRefSearchOutput: vi.fn().mockReturnValue([])
|
||||
searchBaseRefs: vi.fn().mockResolvedValue([])
|
||||
}))
|
||||
|
||||
vi.mock('./registered-worktree-roots-cache', () => ({
|
||||
|
||||
@@ -28,7 +28,6 @@ vi.mock('electron', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('./profile-cloud-session-refresh', () => ({
|
||||
runWithFreshOrcaCloudSessionMock,
|
||||
runWithFreshOrcaCloudSession: runWithFreshOrcaCloudSessionMock
|
||||
}))
|
||||
|
||||
|
||||
@@ -78,8 +78,7 @@ vi.mock('../ipc/pty', () => ({
|
||||
deletePtyOwnership: vi.fn(),
|
||||
setPtyOwnership: vi.fn(),
|
||||
restorePtyIncarnation: vi.fn(),
|
||||
isCurrentPtyExit: vi.fn(() => true),
|
||||
answerStartupTerminalColorQueriesForPty: vi.fn((_id: string, data: string) => data)
|
||||
isCurrentPtyExit: vi.fn(() => true)
|
||||
}))
|
||||
vi.mock('../providers/ssh-filesystem-dispatch', () => ({
|
||||
registerSshFilesystemProvider: vi.fn(),
|
||||
|
||||
@@ -65,8 +65,6 @@ vi.mock('../agent-hooks/remote-managed-hook-installers', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: vi.fn().mockReturnValue(false),
|
||||
isSshPtyIdentityMismatchError: vi.fn().mockReturnValue(false),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockImplementation((handler) => {
|
||||
ptyDataHandlerRef.current = handler
|
||||
|
||||
@@ -76,8 +76,7 @@ vi.mock('../ipc/pty', () => ({
|
||||
deletePtyOwnership: vi.fn(),
|
||||
setPtyOwnership: vi.fn(),
|
||||
restorePtyIncarnation: vi.fn(),
|
||||
isCurrentPtyExit: vi.fn(() => true),
|
||||
answerStartupTerminalColorQueriesForPty: vi.fn((_id: string, data: string) => data)
|
||||
isCurrentPtyExit: vi.fn(() => true)
|
||||
}))
|
||||
vi.mock('../providers/ssh-filesystem-dispatch', () => ({
|
||||
registerSshFilesystemProvider: vi.fn(),
|
||||
|
||||
@@ -31,8 +31,6 @@ vi.mock('./ssh-channel-multiplexer', () => ({
|
||||
}
|
||||
}))
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: vi.fn(() => false),
|
||||
isSshPtyIdentityMismatchError: vi.fn(() => false),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
|
||||
@@ -81,8 +81,6 @@ vi.mock('../agent-hooks/remote-managed-hook-installers', () => ({
|
||||
installRemoteManagedAgentHooks: vi.fn()
|
||||
}))
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: (error: unknown) => String(error).includes('not found'),
|
||||
isSshPtyIdentityMismatchError: (error: unknown) => String(error).includes('identity mismatch'),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
@@ -110,8 +108,7 @@ vi.mock('../ipc/pty', () => ({
|
||||
deletePtyOwnership: vi.fn(),
|
||||
setPtyOwnership: vi.fn(),
|
||||
restorePtyIncarnation: vi.fn(),
|
||||
isCurrentPtyExit: vi.fn(() => true),
|
||||
answerStartupTerminalColorQueriesForPty: vi.fn((_id: string, data: string) => data)
|
||||
isCurrentPtyExit: vi.fn(() => true)
|
||||
}))
|
||||
vi.mock('../providers/ssh-filesystem-dispatch', () => ({
|
||||
registerSshFilesystemProvider: vi.fn(),
|
||||
|
||||
@@ -53,8 +53,6 @@ vi.mock('../agent-hooks/remote-managed-hook-installers', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: vi.fn().mockReturnValue(false),
|
||||
isSshPtyIdentityMismatchError: vi.fn().mockReturnValue(false),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
|
||||
@@ -63,8 +63,6 @@ vi.mock('./ssh-channel-multiplexer', () => ({
|
||||
}
|
||||
}))
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: vi.fn().mockReturnValue(false),
|
||||
isSshPtyIdentityMismatchError: vi.fn().mockReturnValue(false),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockImplementation((handler) => {
|
||||
ptyDataHandlerRef.current = handler
|
||||
|
||||
@@ -86,8 +86,6 @@ vi.mock('./ssh-channel-multiplexer', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: () => false,
|
||||
isSshPtyIdentityMismatchError: () => false,
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
|
||||
@@ -40,8 +40,6 @@ vi.mock('./ssh-channel-multiplexer', () => {
|
||||
})
|
||||
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: (err: unknown) =>
|
||||
(err instanceof Error ? err.message : String(err)).includes('not found'),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
|
||||
@@ -61,10 +61,6 @@ vi.mock('./ssh-channel-multiplexer', () => {
|
||||
})
|
||||
|
||||
vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
isSshPtyNotFoundError: (err: unknown) =>
|
||||
(err instanceof Error ? err.message : String(err)).includes('not found'),
|
||||
isSshPtyIdentityMismatchError: (err: unknown) =>
|
||||
(err instanceof Error ? err.message : String(err)).includes('identity mismatch'),
|
||||
SshPtyProvider: class MockSshPtyProvider {
|
||||
onData = vi.fn().mockReturnValue(() => {})
|
||||
onReplay = vi.fn().mockReturnValue(() => {})
|
||||
|
||||
@@ -16,7 +16,7 @@ vi.mock('@/components/ui/dropdown-menu', () => dropdownMenuStubs())
|
||||
vi.mock('../ui/dropdown-menu', () => dropdownMenuStubs())
|
||||
vi.mock('@/components/ui/popover', () => popoverStubs())
|
||||
vi.mock('@/store', () => ({ useAppStore: appStoreStub() }))
|
||||
vi.mock('../../store', () => ({ useAppStore: appStoreStub() }))
|
||||
vi.mock('../store', () => ({ useAppStore: appStoreStub() }))
|
||||
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }))
|
||||
|
||||
import { BrowserCookieImportDisclosure } from './BrowserCookieImportDisclosure'
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ let transportFactoryQueue: unknown[] = []
|
||||
|
||||
vi.mock('@/runtime/sync-runtime-graph', () => ({ scheduleRuntimeGraphSync: vi.fn() }))
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn()
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn()
|
||||
}))
|
||||
vi.mock('@/lib/codex-stale-pane-sweep', () => ({ notifyCodexPaneBoundForStaleSweep: vi.fn() }))
|
||||
vi.mock('sonner', () => ({ toast: { info: vi.fn() } }))
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -21,14 +21,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -50,7 +50,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -29,14 +29,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -58,7 +58,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -30,14 +30,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -59,7 +59,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -28,14 +28,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -57,7 +57,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -29,14 +29,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -58,7 +58,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -30,14 +30,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -59,7 +59,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -28,14 +28,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -57,7 +57,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+4
-4
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
@@ -130,7 +130,7 @@ function createDeps(overrides: Record<string, unknown> = {}) {
|
||||
|
||||
function expectNoGlobalAtlasRecovery(): void {
|
||||
// Why: the removed output path requested recovery 200ms before its global reset ran.
|
||||
expect(scheduleTerminalWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(scheduleImagePasteWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(resetAndRefreshAllTerminalWebglAtlases).not.toHaveBeenCalled()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -29,7 +29,7 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
@@ -37,7 +37,7 @@ const {
|
||||
presentPaneViewportPreservingSynchronizedOutput
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -65,7 +65,7 @@ vi.mock('@/lib/pane-manager/pane-webgl-renderer', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -26,14 +26,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -55,7 +55,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -26,14 +26,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -55,7 +55,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -31,14 +31,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -60,7 +60,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -24,14 +24,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -53,7 +53,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -47,7 +47,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -21,14 +21,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -50,7 +50,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -27,14 +27,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -56,7 +56,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -17,14 +17,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -43,7 +43,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({ scheduleTerminalWebglAtlasRecovery }))
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({ scheduleImagePasteWebglAtlasRecovery }))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
useAppStore: {
|
||||
|
||||
@@ -21,14 +21,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -50,7 +50,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -38,14 +38,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -67,7 +67,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -25,14 +25,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -54,7 +54,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+4
-4
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
@@ -130,7 +130,7 @@ function createDeps(overrides: Record<string, unknown> = {}) {
|
||||
|
||||
function expectNoGlobalAtlasRecovery(): void {
|
||||
// Why: the removed output path requested recovery 200ms before its global reset ran.
|
||||
expect(scheduleTerminalWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(scheduleImagePasteWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(resetAndRefreshAllTerminalWebglAtlases).not.toHaveBeenCalled()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -36,14 +36,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -65,7 +65,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -18,14 +18,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -45,7 +45,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -21,14 +21,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -50,7 +50,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -23,14 +23,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -52,7 +52,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -23,14 +23,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -52,7 +52,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -20,14 +20,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -49,7 +49,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -27,14 +27,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -56,7 +56,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -25,14 +25,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -54,7 +54,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -24,14 +24,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -53,7 +53,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+3
-3
@@ -19,14 +19,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -48,7 +48,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
+4
-4
@@ -22,14 +22,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -51,7 +51,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
@@ -133,7 +133,7 @@ function createDeps(overrides: Record<string, unknown> = {}) {
|
||||
|
||||
function expectNoGlobalAtlasRecovery(): void {
|
||||
// Why: the removed output path requested recovery 200ms before its global reset ran.
|
||||
expect(scheduleTerminalWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(scheduleImagePasteWebglAtlasRecovery).not.toHaveBeenCalled()
|
||||
expect(resetAndRefreshAllTerminalWebglAtlases).not.toHaveBeenCalled()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -26,14 +26,14 @@ import {
|
||||
|
||||
const {
|
||||
resetAndRefreshAllTerminalWebglAtlases,
|
||||
scheduleTerminalWebglAtlasRecovery,
|
||||
scheduleImagePasteWebglAtlasRecovery,
|
||||
scheduleRuntimeGraphSync,
|
||||
shouldSeedCacheTimerOnInitialTitle,
|
||||
toastInfo,
|
||||
notifyCodexPaneBoundForStaleSweep
|
||||
} = vi.hoisted(() => ({
|
||||
resetAndRefreshAllTerminalWebglAtlases: vi.fn(),
|
||||
scheduleTerminalWebglAtlasRecovery: vi.fn(),
|
||||
scheduleImagePasteWebglAtlasRecovery: vi.fn(),
|
||||
scheduleRuntimeGraphSync: vi.fn(),
|
||||
shouldSeedCacheTimerOnInitialTitle: vi.fn(() => false),
|
||||
toastInfo: vi.fn(),
|
||||
@@ -55,7 +55,7 @@ vi.mock('@/lib/pane-manager/pane-manager-registry', async (importOriginal) => ({
|
||||
}))
|
||||
|
||||
vi.mock('./terminal-webgl-atlas-recovery', () => ({
|
||||
scheduleTerminalWebglAtlasRecovery
|
||||
scheduleImagePasteWebglAtlasRecovery
|
||||
}))
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
import { resolve } from 'node:path'
|
||||
import { beforeAll, describe, expect, it } from 'vitest'
|
||||
import type { parseAst as ParseAstFn } from 'vite' with { 'resolution-mode': 'import' }
|
||||
import type { AstNode, ParseProgram } from './source-scan/module-export-names'
|
||||
import { readExportedNames, resolveRelativeModule } from './source-scan/module-export-names'
|
||||
import { scanSourceTree } from './source-scan/source-tree-scan'
|
||||
|
||||
// Dynamic import: vite is ESM-only and this file typechecks under tsconfig.tc.cli.json's node16/CJS.
|
||||
let parseAst: typeof ParseAstFn
|
||||
|
||||
beforeAll(async () => {
|
||||
;({ parseAst } = await import('vite'))
|
||||
})
|
||||
|
||||
/**
|
||||
* Ban `vi.mock` factory keys that name nothing the mocked module exports.
|
||||
*
|
||||
* A key that matches no export is not a stub -- it is a comment. The module
|
||||
* registry serves it to nobody, production keeps calling the real function, and
|
||||
* the suite goes green for a reason its author did not intend. Nothing else
|
||||
* catches this: it typechecks (a factory is a plain object literal), it does not
|
||||
* warn at runtime, and the tell only shows if you make the key throw and notice
|
||||
* that nothing happens.
|
||||
*
|
||||
* It found 83 such keys across 73 suites on the commit that introduced it,
|
||||
* in seven clusters. The two largest were symbols that had been renamed or moved
|
||||
* out of the mocked module, leaving eight SSH-relay suites and 56 terminal-pane
|
||||
* suites each carrying a stub that had never once been reached.
|
||||
*/
|
||||
|
||||
type MockCall = { specifier: string; keys: string[] }
|
||||
|
||||
/** Unwraps a factory to the object literal it yields, or null if not statically known. */
|
||||
function factoryObject(node: AstNode | undefined): AstNode | null {
|
||||
let current: AstNode | undefined = node
|
||||
if (current?.type === 'ArrowFunctionExpression' || current?.type === 'FunctionExpression') {
|
||||
// A concise arrow body is one node; a block body is a statement list.
|
||||
current = Array.isArray(current.body) ? undefined : current.body
|
||||
if (current?.type === 'BlockStatement') {
|
||||
const statements = Array.isArray(current.body) ? current.body : []
|
||||
current = statements.findLast((statement) => statement.type === 'ReturnStatement')?.argument
|
||||
}
|
||||
}
|
||||
const TRANSPARENT = [
|
||||
'TSAsExpression',
|
||||
'ParenthesizedExpression',
|
||||
'AwaitExpression',
|
||||
'TSSatisfiesExpression'
|
||||
]
|
||||
while (current && TRANSPARENT.includes(current.type)) {
|
||||
current = current.expression ?? current.argument
|
||||
}
|
||||
return current?.type === 'ObjectExpression' ? current : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Every statically readable `vi.mock`/`vi.doMock` in a file.
|
||||
*
|
||||
* A factory whose keys cannot all be read -- a computed key, or a returned
|
||||
* identifier -- is dropped whole rather than half-checked, so the guard never
|
||||
* accuses a key it did not actually see.
|
||||
*/
|
||||
function readMockCalls(program: { body: AstNode[] }): MockCall[] {
|
||||
const calls: MockCall[] = []
|
||||
const stack: unknown[] = [program]
|
||||
while (stack.length > 0) {
|
||||
const node = stack.pop()
|
||||
if (!node || typeof node !== 'object') {
|
||||
continue
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
stack.push(...node)
|
||||
continue
|
||||
}
|
||||
const candidate = node as AstNode
|
||||
const callee = candidate.callee
|
||||
if (
|
||||
candidate.type === 'CallExpression' &&
|
||||
callee?.type === 'MemberExpression' &&
|
||||
callee.object?.name === 'vi' &&
|
||||
(callee.property?.name === 'mock' || callee.property?.name === 'doMock')
|
||||
) {
|
||||
calls.push(...readMockCall(candidate))
|
||||
}
|
||||
stack.push(...Object.values(candidate as Record<string, unknown>))
|
||||
}
|
||||
return calls
|
||||
}
|
||||
|
||||
function readMockCall(call: AstNode): MockCall[] {
|
||||
const args = call.arguments ?? []
|
||||
const target = args[0]
|
||||
// `vi.mock(import('./x'), ...)` names its module through an import expression.
|
||||
const specifier = target?.type === 'Literal' ? target.value : target?.source?.value
|
||||
const object = factoryObject(args[1])
|
||||
if (typeof specifier !== 'string' || !object) {
|
||||
return []
|
||||
}
|
||||
const keys: string[] = []
|
||||
for (const property of object.properties ?? []) {
|
||||
// A spread carries the real module's exports through; its own keys are not ours to judge.
|
||||
if (property.type === 'SpreadElement') {
|
||||
continue
|
||||
}
|
||||
const key = property.computed ? undefined : (property.key?.name ?? property.key?.value)
|
||||
if (typeof key !== 'string') {
|
||||
return []
|
||||
}
|
||||
keys.push(key)
|
||||
}
|
||||
return [{ specifier, keys }]
|
||||
}
|
||||
|
||||
describe('dead vi.mock factory keys', () => {
|
||||
const repoRoot = resolve(__dirname, '..', '..')
|
||||
const offenders: string[] = []
|
||||
const phantomPaths: string[] = []
|
||||
const unparseable: string[] = []
|
||||
let filesScanned = 0
|
||||
let mockCallsSeen = 0
|
||||
let mockCallsChecked = 0
|
||||
|
||||
beforeAll(() => {
|
||||
const scanned = scanSourceTree(resolve(repoRoot, 'src'), { includeTests: true })
|
||||
filesScanned = scanned.length
|
||||
// One pass to hold every file's text, so a mocked module is readable whether or
|
||||
// not the walk has reached it yet.
|
||||
const sources = new Map(scanned.map((file) => [file.path, file.source]))
|
||||
const parse: ParseProgram = (file) =>
|
||||
parseAst(sources.get(file) ?? '', {
|
||||
lang: file.endsWith('.tsx') ? 'tsx' : 'ts'
|
||||
}) as unknown as { body: AstNode[] }
|
||||
const exportCache = new Map<string, ReturnType<typeof readExportedNames>>()
|
||||
const exportsOf = (file: string): ReturnType<typeof readExportedNames> => {
|
||||
const cached = exportCache.get(file)
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
const read = readExportedNames(file, parse)
|
||||
exportCache.set(file, read)
|
||||
return read
|
||||
}
|
||||
|
||||
for (const file of scanned) {
|
||||
if (!/vi\.(?:mock|doMock)\s*\(/.test(file.source)) {
|
||||
continue
|
||||
}
|
||||
let program: { body: AstNode[] }
|
||||
try {
|
||||
program = parse(file.path)
|
||||
} catch {
|
||||
// Fail closed: a file the guard cannot read is not a file the guard cleared.
|
||||
unparseable.push(file.relativePath)
|
||||
continue
|
||||
}
|
||||
for (const call of readMockCalls(program)) {
|
||||
mockCallsSeen += 1
|
||||
const target = resolveRelativeModule(file.path, call.specifier)
|
||||
if (!target) {
|
||||
// A relative path that resolves to nothing is the same bug one level up:
|
||||
// the whole factory is dead, not just a key. `?asset`-style specifiers are
|
||||
// resolved by a bundler plugin, not by the filesystem, so they are exempt.
|
||||
if (call.specifier.startsWith('.') && !call.specifier.includes('?')) {
|
||||
phantomPaths.push(`${file.relativePath}: vi.mock('${call.specifier}')`)
|
||||
}
|
||||
continue
|
||||
}
|
||||
const { names, complete } = exportsOf(target)
|
||||
if (!complete) {
|
||||
continue
|
||||
}
|
||||
mockCallsChecked += 1
|
||||
for (const key of call.keys.filter((name) => !names.has(name))) {
|
||||
offenders.push(`${file.relativePath}: vi.mock('${call.specifier}') key '${key}'`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('scans a plausible amount of the tree', () => {
|
||||
// Counting what the filter saw, not just what it reported: a broken walk or a
|
||||
// regressed AST shape would make every assertion below vacuously green.
|
||||
expect(filesScanned).toBeGreaterThan(5000)
|
||||
expect(mockCallsSeen).toBeGreaterThan(2000)
|
||||
expect(mockCallsChecked).toBeGreaterThan(1000)
|
||||
})
|
||||
|
||||
it('parses every file that mocks a module', () => {
|
||||
expect(unparseable).toEqual([])
|
||||
})
|
||||
|
||||
it('mocks no relative path that resolves to no module', () => {
|
||||
expect(
|
||||
phantomPaths,
|
||||
'This vi.mock names a relative path with no module behind it, so the whole factory is ' +
|
||||
'inert and the real module loads. Correct the path.'
|
||||
).toEqual([])
|
||||
})
|
||||
|
||||
it('has no factory key that the mocked module does not export', () => {
|
||||
expect(
|
||||
offenders,
|
||||
'This vi.mock key matches no export of that module, so the mock never applies and the ' +
|
||||
'real implementation runs. Point it at the module that actually exports the symbol, ' +
|
||||
'fix the name, or delete the key.'
|
||||
).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,145 @@
|
||||
import { existsSync, statSync } from 'node:fs'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
|
||||
/**
|
||||
* The set of names a module actually exports, read from its source.
|
||||
*
|
||||
* Why source and not a dynamic import: the modules a test mocks are the ones
|
||||
* with side effects at import time -- Electron handles, native bindings, a
|
||||
* relay socket -- so importing them to enumerate their exports is exactly what
|
||||
* the mock existed to avoid.
|
||||
*/
|
||||
|
||||
export type AstNode = {
|
||||
type: string
|
||||
name?: string
|
||||
value?: unknown
|
||||
computed?: boolean
|
||||
declaration?: AstNode
|
||||
declarations?: { id?: { name?: string } }[]
|
||||
specifiers?: { exported?: { name?: string; value?: string } }[]
|
||||
exported?: { name?: string } | null
|
||||
source?: { value?: string }
|
||||
id?: { name?: string }
|
||||
key?: { name?: string; value?: unknown }
|
||||
properties?: AstNode[]
|
||||
arguments?: AstNode[]
|
||||
callee?: AstNode
|
||||
object?: AstNode
|
||||
property?: AstNode
|
||||
expression?: AstNode
|
||||
argument?: AstNode
|
||||
/** An array on a Program or BlockStatement, a single node on a concise arrow body. */
|
||||
body?: AstNode | AstNode[]
|
||||
}
|
||||
|
||||
export type ParseProgram = (filePath: string) => { body: AstNode[] }
|
||||
|
||||
/** Extensions tried for a relative specifier, in resolution order. */
|
||||
const CANDIDATE_SUFFIXES = ['.ts', '.tsx', '/index.ts', '/index.tsx']
|
||||
|
||||
/**
|
||||
* A relative specifier resolved to a file in the tree, or null.
|
||||
*
|
||||
* Bare specifiers return null on purpose: a package's exports are not ours to
|
||||
* read, and guessing at them would be the wrong kind of confident.
|
||||
*/
|
||||
export function resolveRelativeModule(fromFile: string, specifier: string): string | null {
|
||||
if (!specifier.startsWith('.')) {
|
||||
return null
|
||||
}
|
||||
// A `.js` specifier is the TS `node16` spelling of a `.ts` file on disk.
|
||||
const base = resolve(dirname(fromFile), specifier.replace(/\.js$/, ''))
|
||||
if (existsSync(base) && statSync(base).isFile()) {
|
||||
return base
|
||||
}
|
||||
return CANDIDATE_SUFFIXES.map((suffix) => base + suffix).find((path) => existsSync(path)) ?? null
|
||||
}
|
||||
|
||||
export type ModuleExports = {
|
||||
names: Set<string>
|
||||
/**
|
||||
* False when some export could not be enumerated -- an unparseable file, a
|
||||
* destructured `export const`, or an `export *` through a package. Callers
|
||||
* must skip an incomplete module rather than report its keys as unknown,
|
||||
* because a partial set turns every real export it missed into a false
|
||||
* accusation.
|
||||
*/
|
||||
complete: boolean
|
||||
}
|
||||
|
||||
function collectDeclarationNames(declaration: AstNode, into: ModuleExports): void {
|
||||
if (declaration.type === 'VariableDeclaration') {
|
||||
for (const declarator of declaration.declarations ?? []) {
|
||||
if (declarator.id?.name) {
|
||||
into.names.add(declarator.id.name)
|
||||
} else {
|
||||
into.complete = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (declaration.id?.name) {
|
||||
into.names.add(declaration.id.name)
|
||||
return
|
||||
}
|
||||
into.complete = false
|
||||
}
|
||||
|
||||
/** Follows `export * from './x'` so a barrel reports what it really re-exports. */
|
||||
export function readExportedNames(
|
||||
file: string,
|
||||
parse: ParseProgram,
|
||||
seen = new Set<string>()
|
||||
): ModuleExports {
|
||||
if (seen.has(file)) {
|
||||
return { names: new Set(), complete: true }
|
||||
}
|
||||
seen.add(file)
|
||||
let program: { body: AstNode[] }
|
||||
try {
|
||||
program = parse(file)
|
||||
} catch {
|
||||
return { names: new Set(), complete: false }
|
||||
}
|
||||
const result: ModuleExports = { names: new Set(), complete: true }
|
||||
for (const statement of program.body) {
|
||||
if (statement.type === 'ExportDefaultDeclaration') {
|
||||
result.names.add('default')
|
||||
continue
|
||||
}
|
||||
if (statement.type === 'ExportNamedDeclaration') {
|
||||
if (statement.declaration) {
|
||||
collectDeclarationNames(statement.declaration, result)
|
||||
}
|
||||
for (const specifier of statement.specifiers ?? []) {
|
||||
const name = specifier.exported?.name ?? specifier.exported?.value
|
||||
if (name) {
|
||||
result.names.add(name)
|
||||
} else {
|
||||
result.complete = false
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if (statement.type !== 'ExportAllDeclaration') {
|
||||
continue
|
||||
}
|
||||
// `export * as ns from '...'` contributes one name, not the target's set.
|
||||
if (statement.exported?.name) {
|
||||
result.names.add(statement.exported.name)
|
||||
continue
|
||||
}
|
||||
const target = resolveRelativeModule(file, statement.source?.value ?? '')
|
||||
if (!target) {
|
||||
result.complete = false
|
||||
continue
|
||||
}
|
||||
const reExported = readExportedNames(target, parse, seen)
|
||||
for (const name of reExported.names) {
|
||||
result.names.add(name)
|
||||
}
|
||||
result.complete &&= reExported.complete
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user