From 6236fdd4d7cc4afd6ef3843499784b006f2a4525 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Thu, 29 Oct 2026 17:20:50 -0700 Subject: [PATCH] test: remove low-value copy and CI fixture checks (#36159) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- config/scripts/ci-shard-timings.json | 1 - config/scripts/space-sharing-copy.test.ts | 24 -- .../win32-test-lane-registration.test.mjs | 277 +----------------- .../worktree/workspace-options-copy.test.ts | 21 -- .../worktree-host-context-labels.test.ts | 16 - src/main/i18n/main-i18n-lazy-locale.test.ts | 60 ---- ...state-startup-failure-localization.test.ts | 37 --- .../artifacts/artifact-display-labels.test.ts | 48 --- .../src/lib/ephemeral-vm-error-copy.test.ts | 23 -- src/shared/localhost-worktree-labels.test.ts | 25 +- src/shared/repo-display-labels.test.ts | 25 -- 11 files changed, 3 insertions(+), 554 deletions(-) delete mode 100644 mobile/src/worktree/workspace-options-copy.test.ts delete mode 100644 src/main/startup/profile-state-startup-failure-localization.test.ts delete mode 100644 src/renderer/src/components/artifacts/artifact-display-labels.test.ts delete mode 100644 src/renderer/src/lib/ephemeral-vm-error-copy.test.ts diff --git a/config/scripts/ci-shard-timings.json b/config/scripts/ci-shard-timings.json index 507f3de2451..0750d953b4a 100644 --- a/config/scripts/ci-shard-timings.json +++ b/config/scripts/ci-shard-timings.json @@ -7023,7 +7023,6 @@ "src/renderer/src/components/artifacts/ArtifactPreview.test.tsx": 366, "src/renderer/src/components/artifacts/ArtifactPublishButton.test.tsx": 568, "src/renderer/src/components/artifacts/ArtifactsPage.test.tsx": 1464, - "src/renderer/src/components/artifacts/artifact-display-labels.test.ts": 114, "src/renderer/src/components/artifacts/artifact-list-search.test.ts": 127, "src/renderer/src/components/artifacts/artifact-list-windowing.test.tsx": 1563, "src/renderer/src/components/artifacts/artifact-publish-flow.test.ts": 80, diff --git a/config/scripts/space-sharing-copy.test.ts b/config/scripts/space-sharing-copy.test.ts index a7f73d33788..51db572868c 100644 --- a/config/scripts/space-sharing-copy.test.ts +++ b/config/scripts/space-sharing-copy.test.ts @@ -94,19 +94,6 @@ function makeTree(): { root: string; source: string } { } describe('shareTree', () => { - // Stub mechanism selection: macOS cp -c and GNU reflink cannot both run on one host. - it('prefers the strongest isolation each platform offers', () => { - const stub = () => - vi.fn((_source: string, target: string) => mkdirSync(target, { recursive: true })) - const stubs = { clone: stub(), reflink: stub(), hardlink: stub() } - const { root, source } = makeTree() - expect(shareTree(source, path.join(root, 'a'), { platform: 'darwin', ...stubs })).toBe('clone') - expect(shareTree(source, path.join(root, 'b'), { platform: 'linux', ...stubs })).toBe('reflink') - expect(shareTree(source, path.join(root, 'c'), { platform: 'win32', ...stubs })).toBe( - 'hardlink' - ) - }) - it('keeps relative symlinks unresolved on whatever this host supports', () => { const { root, source } = makeTree() const destination = path.join(root, 'shared') @@ -318,17 +305,6 @@ describe('copyPrivateTree', () => { expect(readlinkSync(path.join(destination, 'relative-link'))).toBe(path.join('nested', 'file')) }) - it('reports the private mechanism it used', () => { - const { root, source } = makeTree() - const clone = vi.fn((_source: string, target: string) => mkdirSync(target, { recursive: true })) - expect( - copyPrivateTree(source, path.join(root, 'private'), { platform: 'darwin', clone }) - ).toEqual({ - mechanism: 'clone', - copyError: null - }) - }) - it('falls back to a byte copy when the private mechanism fails', () => { const { root, source } = makeTree() const destination = path.join(root, 'private') diff --git a/config/scripts/win32-test-lane-registration.test.mjs b/config/scripts/win32-test-lane-registration.test.mjs index a191e2a9726..a08fd85ed50 100644 --- a/config/scripts/win32-test-lane-registration.test.mjs +++ b/config/scripts/win32-test-lane-registration.test.mjs @@ -8,7 +8,7 @@ import { WINDOWS_BOUNDARY_TESTS } from './pr-package-test-paths.mjs' // Register every Windows-named or suite-gated file in sole Windows lane’s curated list; otherwise Ubuntu self-skips can pass without execution. // Follow suite/describe gates, nested aliases, local boolean polarity and narrowing &&; do not follow case-level gates, imported/function flags, broad OR/skipIf conjunctions. -// Proves registration/routing list membership, not actual suite execution (manual env gates can skip), diff-trigger coverage or assertion quality. Literal caps expose allowance growth for review. +// Proves registration/routing list membership, not actual suite execution (manual env gates can skip), diff-trigger coverage or assertion quality. const projectDir = resolve(import.meta.dirname, '../..') const WINDOWS_LANE_JOB = 'package_windows' @@ -16,7 +16,6 @@ const WINDOWS_LANE_STEPS = [ 'Test Windows-specific boundaries', 'Test Windows installer process probe' ] -const WINDOWS_LANE_RUNNER = 'windows-2022' // Shrink-only pre-existing Windows files missing lane registration; remove entry when registered, never add. const UNREGISTERED_ON_MAIN = [ @@ -59,19 +58,11 @@ const MANUAL_OPT_IN = [ 'src/main/wsl/wsl-runner.wsl.test.ts' ] -/** Caps so growing either list is two deliberate edits, not one. */ -const UNREGISTERED_MAX = 8 -const MANUAL_OPT_IN_MAX = 9 - -// Pin population floor against broken discovery; lower only when real gated file is deleted. -const GATED_FILE_FLOOR = 23 - const TEST_FILE_PATTERN = /\.(?:test|spec)\.(?:ts|tsx|mjs|cjs|js)$/ // Exclude mobile: separate Vitest job never triggers desktop package_windows lane. const UNREACHABLE_BY_THE_WINDOWS_LANE = 'mobile/' -// Exempt exact self path because matcher fixtures quote gates; guard must run on Ubuntu and must not exempt real sibling suites. const SCANNER_SELF_PATH = 'config/scripts/win32-test-lane-registration.test.mjs' export function isScannerSelfPath(path) { @@ -118,7 +109,6 @@ function buildGates(source) { ] } -/** Exported shape of the rule, so the fixtures below exercise the real matcher. */ export function isWindows32GatedTestFile(path, source) { if (/\.win32\.(?:test|spec)\./.test(path)) { return true @@ -149,22 +139,9 @@ export function requiresEnvOptIn(source) { }) } -// Treat any runs-on label/array/group/matrix that may be Windows as a lane; unresolvable expression fails closed for review. -export function couldRunOnWindows(runsOn) { - const labels = - typeof runsOn === 'string' - ? [runsOn] - : Array.isArray(runsOn) - ? runsOn - : [...(runsOn?.labels ?? []), runsOn?.group ?? ''].flat() - return labels.some((label) => /windows/i.test(String(label)) || String(label).includes('${{')) -} - /** The Windows job's curated files: the boundary list plus any argv the lane steps spell out. */ function readWindowsWorkflow() { const workflow = parse(readFileSync(join(projectDir, '.github/workflows/pr.yml'), 'utf8')) - const jobs = Object.entries(workflow.jobs ?? {}) - const windowsJobs = jobs.filter(([, job]) => couldRunOnWindows(job?.['runs-on'])) const steps = workflow.jobs?.[WINDOWS_LANE_JOB]?.steps ?? [] const runs = WINDOWS_LANE_STEPS.map((name) => { const step = steps.find((candidate) => candidate?.name === name) @@ -184,7 +161,6 @@ function readWindowsWorkflow() { } const run = runs.join(' ') return { - windowsJobNames: windowsJobs.map(([name]) => name), laneFiles: [ ...WINDOWS_BOUNDARY_TESTS, ...run.split(/\s+/).filter((token) => TEST_FILE_PATTERN.test(token)) @@ -192,7 +168,7 @@ function readWindowsWorkflow() { } } -const { windowsJobNames, laneFiles } = readWindowsWorkflow() +const { laneFiles } = readWindowsWorkflow() const scannedTestFiles = scanSourceTree(projectDir, { includeTests: true, extensions: TEST_FILE_PATTERN @@ -239,19 +215,6 @@ describe('Windows-gated test files are registered in the Windows CI lane', () => ) }) - it('scans a plausible number of test files', () => { - // A broken root or extension filter would make every assertion below vacuous. - expect(scannedTestFiles.length).toBeGreaterThan(5000) - }) - - it('has exactly one windows-2022 job to register into', () => { - // Require sole Windows lane so curated registration cannot point at wrong job and silently skip. - expect( - windowsJobNames, - `Expected only ${WINDOWS_LANE_JOB} to run on ${WINDOWS_LANE_RUNNER}.` - ).toEqual([WINDOWS_LANE_JOB]) - }) - it('parses a plausible Windows lane invocation', () => { expect(laneFiles.length).toBeGreaterThan(15) const missingFromDisk = laneFiles.filter((path) => { @@ -267,41 +230,6 @@ describe('Windows-gated test files are registered in the Windows CI lane', () => ).toEqual([]) }) - it('rediscovers Windows-gated files that are already registered', () => { - // Prove both filename/alias and gate-only discovery against real files, not just fixtures. - expect(gatedFiles).toContain( - 'src/shared/__tests__/process-host/windows-command-line.win32.test.ts' - ) - expect(gatedFiles).toContain('src/main/agent-hooks/windows-hook-payload-delivery.test.ts') - // And a compound gate, the case this guard was blind to at first. - expect(gatedFiles).toContain('src/main/git/runner-wsl-linked-gitdir-windows.test.ts') - }) - - it('exempts itself, and nothing else, from the scan', () => { - expect(scannedTestFiles.map(({ relativePath }) => relativePath)).toContain(SCANNER_SELF_PATH) - // The exemption is load-bearing only while the fixtures below still match. - expect(isWindows32GatedTestFile(SCANNER_SELF_PATH, sourceOf(SCANNER_SELF_PATH))).toBe(true) - expect(gatedFiles).not.toContain(SCANNER_SELF_PATH) - // The other half of the claim: no sibling rides the exemption. - expect(isScannerSelfPath('config/scripts/pr-code-change-scope.test.mjs')).toBe(false) - }) - - it('holds the Windows-gated population at or above the floor', () => { - // Keep literal population floor independent of debt lengths; derived bound moves with lists and proves nothing. - expect( - gatedFiles.length, - `Found ${gatedFiles.length} Windows-gated test files; the floor is ${GATED_FILE_FLOOR}. ` + - 'A drop means the scan stopped matching, not that the files went away. Lower the floor ' + - 'only for a genuine deletion.' - ).toBeGreaterThanOrEqual(GATED_FILE_FLOOR) - }) - - it('confirms the classifier distinguishes registered from unregistered paths', () => { - // Reject classifier answering true for all paths or registration assertions become vacuous. - expect(isInClassifier('src/main/windows/windows-pty-job.win32.test.ts')).toBe(true) - expect(isInClassifier('src/main/windows/not-a-real-file.win32.test.ts')).toBe(false) - }) - it('has every Windows-gated test file registered in the Windows lane', () => { const grandfathered = new Set([...UNREGISTERED_ON_MAIN, ...MANUAL_OPT_IN]) const failures = gatedFiles @@ -327,17 +255,6 @@ describe('Windows-gated test files are registered in the Windows CI lane', () => ).toEqual([]) }) - it('caps growth of both grandfathered lists', () => { - expect( - UNREGISTERED_ON_MAIN.length, - 'Never raise UNREGISTERED_MAX. Register the file instead.' - ).toBeLessThanOrEqual(UNREGISTERED_MAX) - expect( - MANUAL_OPT_IN.length, - 'Never raise MANUAL_OPT_IN_MAX to avoid registering a file that CI could actually run.' - ).toBeLessThanOrEqual(MANUAL_OPT_IN_MAX) - }) - it('keeps MANUAL_OPT_IN to suites CI genuinely cannot run', () => { // Otherwise this list is just a quieter way to skip registration. const notActuallyOptIn = MANUAL_OPT_IN.filter((path) => !requiresEnvOptIn(sourceOf(path))) @@ -357,193 +274,3 @@ describe('Windows-gated test files are registered in the Windows CI lane', () => ).toEqual([]) }) }) - -describe('manual opt-in classification', () => { - it('requires the env read to reach the gate', () => { - // Unrelated env use must not exempt CI-satisfiable compound gate (native-addon-bytes shape). - expect( - requiresEnvOptIn( - "const tmp = process.env.RUNNER_TEMP\ndescribe.runIf(process.platform === 'win32' && hasAddon)('x', () => {})" - ) - ).toBe(false) - // One const hop matches real manual opt-in gates. - expect( - requiresEnvOptIn( - "const distro = process.env.ORCA_TEST_WSL_DISTRO\ndescribe.runIf(process.platform === 'win32' && Boolean(distro))('x', () => {})" - ) - ).toBe(true) - // Read inline in the conjunct: the other real shape. - expect( - requiresEnvOptIn( - "const RUN = process.platform === 'win32' && process.env.ORCA_REAL_X === '1'" - ) - ).toBe(true) - }) - - it('requires the gate to be compound at all', () => { - // Bare win32 gate stays registrable despite unrelated env reads. - expect( - requiresEnvOptIn( - "const t = process.env.CI\ndescribe.runIf(process.platform === 'win32')('x', () => {})" - ) - ).toBe(false) - // Require && before env conjunct; same-line env read after bare gate must not reopen manual-parking hole. - expect( - requiresEnvOptIn( - "describe.runIf(process.platform === 'win32')(`x ${process.env.ORCA_TAG}`, () => {})" - ) - ).toBe(false) - }) -}) - -describe('Windows runner detection', () => { - it('reads every runs-on spelling that could land on Windows', () => { - expect(couldRunOnWindows('windows-2022')).toBe(true) - // The spelling that would have slipped past an equality test. - expect(couldRunOnWindows('windows-latest')).toBe(true) - expect(couldRunOnWindows(['self-hosted', 'Windows', 'X64'])).toBe(true) - expect(couldRunOnWindows({ group: 'windows-runners', labels: ['x64'] })).toBe(true) - // Unresolvable from the file, so it fails closed rather than reading as safe. - expect(couldRunOnWindows('${{ matrix.os }}')).toBe(true) - expect(couldRunOnWindows('ubuntu-latest')).toBe(false) - expect(couldRunOnWindows(['self-hosted', 'linux'])).toBe(false) - expect(couldRunOnWindows(undefined)).toBe(false) - }) -}) - -describe('Windows-gate detection', () => { - // Pair actual gate shapes with near misses so fixtures test repository semantics rather than echo regex. - const cases = [ - [ - 'describe.runIf equality', - "describe.runIf(process.platform === 'win32')('x', () => {})", - "describe.runIf(process.platform !== 'win32')('x', () => {})" - ], - [ - 'describe.skipIf inequality', - "describe.skipIf(process.platform !== 'win32')('x', () => {})", - "describe.skipIf(process.platform === 'win32')('x', () => {})" - ], - [ - 'ternary describe alias', - "const d = process.platform === 'win32' ? describe : describe.skip", - "const d = process.platform === 'win32' ? describe.skip : describe" - ], - [ - 'inverted ternary describe alias', - "const d = process.platform !== 'win32' ? describe.skip : describe", - "const d = process.platform !== 'win32' ? describe : describe.skip" - ], - [ - 'local isWindows flag', - "const isWindows = process.platform === 'win32'\ndescribe.skipIf(!isWindows)('x', () => {})", - "const isWindows = process.platform === 'win32'\ndescribe.skipIf(isWindows)('x', () => {})" - ], - [ - 'local isWindows flag, runIf', - "const isWindows = process.platform === 'win32'\ndescribe.runIf(isWindows)('x', () => {})", - "const isWindows = process.platform === 'win32'\ndescribe.runIf(!isWindows)('x', () => {})" - ], - [ - // The blocking miss: a second conjunct made the gate invisible. - 'compound gate with a second conjunct', - "describe.runIf(process.platform === 'win32' && Boolean(distro))('x', () => {})", - "describe.runIf(process.platform === 'win32' || Boolean(distro))('x', () => {})" - ], - [ - 'compound gate behind a named flag assigned on the next line', - "const RUN_REAL =\n process.platform === 'win32' && process.env.X === '1'\ndescribe.runIf(RUN_REAL)('x', () => {})", - "const RUN_REAL =\n process.platform !== 'win32' && process.env.X === '1'\ndescribe.runIf(RUN_REAL)('x', () => {})" - ], - [ - 'named flag driving a ternary suite alias', - "const enabled = process.platform === 'win32' && process.env.X === '1'\nconst d = enabled ? describe : describe.skip", - "const enabled = process.platform === 'win32' && process.env.X === '1'\nconst d = enabled ? describe.skip : describe" - ], - [ - 'compound skipIf widened with ||', - "describe.skipIf(process.platform !== 'win32' || !hasAddon)('x', () => {})", - "describe.skipIf(process.platform !== 'win32' && !hasAddon)('x', () => {})" - ], - [ - 'double-quoted and loosely spaced', - 'describe . runIf ( process.platform === "win32" )("x", () => {})', - 'describe . runIf ( process.platform === "darwin" )("x", () => {})' - ] - ] - - for (const [label, gated, nearMiss] of cases) { - it(`detects ${label} and rejects its near miss`, () => { - expect(isWindows32GatedTestFile('src/x/sample.test.ts', gated)).toBe(true) - expect(isWindows32GatedTestFile('src/x/sample.test.ts', nearMiss)).toBe(false) - }) - } - - it('detects the .win32 filename with no gate expression at all', () => { - expect(isWindows32GatedTestFile('src/x/sample.win32.test.ts', 'describe("x", () => {})')).toBe( - true - ) - // Near miss: `.win32.ts` is production source, not a test the lane can run. - expect(isWindows32GatedTestFile('src/x/sample.win32.ts', 'export const x = 1')).toBe(false) - }) - - it('does not read a flag whose name merely starts the same', () => { - // Without word boundaries `isWindows` would swallow `isWindowsHost`. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "const isWindows = process.platform === 'win32'\ndescribe.runIf(isWindowsHost)('x', () => {})" - ) - ).toBe(false) - }) - - it('rejects the documented blind spots rather than half-detecting them', () => { - // it-level gate inside a cross-platform suite: out of scope by design. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "describe('x', () => { it.skipIf(process.platform !== 'win32')('y', () => {}) })" - ) - ).toBe(false) - // A platform branch inside a test body is not a gate. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "it('x', () => { if (process.platform === 'win32') { return } })" - ) - ).toBe(false) - // An imported flag: the assignment is not in this file, so polarity is unknowable. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "import { isWindows } from './f'\ndescribe.runIf(isWindows)('x', () => {})" - ) - ).toBe(false) - }) - - it('does not treat a widening conjunct behind a named flag as Windows-only', () => { - // Falsy-on-win32 flag with && also runs POSIX when second term is false; preserve literal/alias equivalence instead of widening to Windows-only. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "const p = process.platform !== 'win32' && Boolean(x)\ndescribe.skipIf(p)('x', () => {})" - ) - ).toBe(false) - // The narrowing direction still counts: `=== 'win32' && x` is Windows-only. - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "const p = process.platform === 'win32' && Boolean(x)\ndescribe.runIf(p)('x', () => {})" - ) - ).toBe(true) - }) - - it('ignores a gate that only appears in prose', () => { - expect( - isWindows32GatedTestFile( - 'src/x/sample.test.ts', - "// describe.runIf(process.platform === 'win32')\ndescribe('x', () => {})" - ) - ).toBe(false) - }) -}) diff --git a/mobile/src/worktree/workspace-options-copy.test.ts b/mobile/src/worktree/workspace-options-copy.test.ts deleted file mode 100644 index 3b576e2cdd4..00000000000 --- a/mobile/src/worktree/workspace-options-copy.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - workspaceOptionsAccessibilityLabel, - workspaceOptionsBadgeText -} from './workspace-options-copy' - -describe('the Workspace options chip', () => { - it('badges the active-filter count as the desktop does, capped at 9+', () => { - expect(workspaceOptionsBadgeText(0)).toBeNull() - expect(workspaceOptionsBadgeText(2)).toBe('2') - expect(workspaceOptionsBadgeText(9)).toBe('9') - expect(workspaceOptionsBadgeText(10)).toBe('9+') - expect(workspaceOptionsBadgeText(12)).toBe('9+') - }) - - it("reads to screen readers as the desktop's trigger does", () => { - expect(workspaceOptionsAccessibilityLabel(0)).toBe('Workspace options') - expect(workspaceOptionsAccessibilityLabel(1)).toBe('Workspace options (1 filter active)') - expect(workspaceOptionsAccessibilityLabel(3)).toBe('Workspace options (3 filters active)') - }) -}) diff --git a/mobile/src/worktree/worktree-host-context-labels.test.ts b/mobile/src/worktree/worktree-host-context-labels.test.ts index a012761615a..04d22c6df2a 100644 --- a/mobile/src/worktree/worktree-host-context-labels.test.ts +++ b/mobile/src/worktree/worktree-host-context-labels.test.ts @@ -117,22 +117,6 @@ describe('getWorktreeHostContextLabels', () => { expect(otherHostUnhealthy[0].hostContextLabel).toBeUndefined() }) - it('names every row by host once the list spans hosts', () => { - const rows = [ - worktree({ hostId: 'local', worktreeId: 'a' }), - worktree({ hostId: sshHostId, worktreeId: 'b' }), - worktree({ hostId: 'ssh:unlabeled', worktreeId: 'c' }), - worktree({ hostId: 'runtime:env-1', worktreeId: 'd' }) - ] - const labeled = applyWorktreeHostContextLabels(rows, sources) - expect(labeled.map((row) => row.hostContextLabel)).toEqual([ - 'Local Mac', - 'openclaw', - 'unlabeled', - 'env-1' - ]) - }) - it('adds the health word only for hosts the desktop reports as unhealthy', () => { const rows = [ worktree({ hostId: 'local', worktreeId: 'a' }), diff --git a/src/main/i18n/main-i18n-lazy-locale.test.ts b/src/main/i18n/main-i18n-lazy-locale.test.ts index 721001fc90c..01c46dc165e 100644 --- a/src/main/i18n/main-i18n-lazy-locale.test.ts +++ b/src/main/i18n/main-i18n-lazy-locale.test.ts @@ -9,14 +9,8 @@ vi.mock('electron', () => ({ })) import { - UI_LANGUAGE_CHINESE, - UI_LANGUAGE_CHINESE_TRADITIONAL, UI_LANGUAGE_ENGLISH, UI_LANGUAGE_GERMAN, - UI_LANGUAGE_JAPANESE, - UI_LANGUAGE_KOREAN, - UI_LANGUAGE_PORTUGUESE, - UI_LANGUAGE_RUSSIAN, UI_LANGUAGE_SPANISH } from '../../shared/ui-language' import { mainI18n, setMainPluginLanguagePacks, setMainUiLanguage, translateMain } from './main-i18n' @@ -29,12 +23,6 @@ describe('main-i18n lazy locale loading', () => { await setMainUiLanguage(UI_LANGUAGE_ENGLISH) }) - it('serves English synchronously from caller fallbacks', () => { - expect(translateMain('missing.main.key', 'Fallback copy')).toBe('Fallback copy') - expect(translateMain('menu.file', 'File')).toBe('File') - expect(translateMain('menu.settings', 'Settings')).toBe('Settings') - }) - it('lazy-loads the Spanish catalog before changeLanguage resolves', async () => { const locale = await setMainUiLanguage(UI_LANGUAGE_SPANISH) expect(locale).toBe('es') @@ -43,54 +31,6 @@ describe('main-i18n lazy locale loading', () => { expect(translateMain('menu.settings', 'Settings')).toBe('Ajustes') }) - it('lazy-loads each remaining locale on demand', async () => { - await setMainUiLanguage(UI_LANGUAGE_JAPANESE) - expect(translateMain('menu.file', 'File')).not.toBe('File') - - await setMainUiLanguage(UI_LANGUAGE_KOREAN) - expect(translateMain('menu.file', 'File')).not.toBe('File') - - await setMainUiLanguage(UI_LANGUAGE_CHINESE) - expect(translateMain('menu.file', 'File')).not.toBe('File') - - await setMainUiLanguage(UI_LANGUAGE_PORTUGUESE) - expect(translateMain('menu.file', 'File')).not.toBe('File') - - await setMainUiLanguage(UI_LANGUAGE_CHINESE_TRADITIONAL) - expect(translateMain('menu.file', 'File')).not.toBe('File') - }) - - it('uses caller English when a target catalog omits a key', async () => { - await setMainUiLanguage(UI_LANGUAGE_SPANISH) - expect(translateMain('missing.main.feature', 'English fallback')).toBe('English fallback') - }) - - it('loads Russian before native menu registration reads it', async () => { - expect(await setMainUiLanguage(UI_LANGUAGE_RUSSIAN)).toBe('ru') - expect(translateMain('menu.file', 'File')).toBe('Файл') - expect(translateMain('menu.settings', 'Settings')).toBe('Настройки') - for (const [count, expected] of [ - [3, '3 активных терминала переподключатся после перезапуска.'], - [5, '5 активных терминалов переподключатся после перезапуска.'] - ] as const) { - expect( - translateMain( - 'localBuild.liveTerminals', - '{{count}} live terminals will reconnect after restart.', - { count, defaultValue_one: '{{count}} live terminal will reconnect after restart.' } - ) - ).toBe(expected) - } - }) - - it('returns to English from a lazily-loaded locale', async () => { - await setMainUiLanguage(UI_LANGUAGE_SPANISH) - expect(translateMain('menu.file', 'File')).toBe('Archivo') - - await setMainUiLanguage(UI_LANGUAGE_ENGLISH) - expect(translateMain('menu.file', 'File')).toBe('File') - }) - it('keeps a newer explicit language when system fallback catalog loading finishes late', async () => { const { getSystemLanguageDetection } = await import('./system-language') expect(getSystemLanguageDetection(['fr-FR'])?.locale).toBe('fr') diff --git a/src/main/startup/profile-state-startup-failure-localization.test.ts b/src/main/startup/profile-state-startup-failure-localization.test.ts deleted file mode 100644 index de4934cadc2..00000000000 --- a/src/main/startup/profile-state-startup-failure-localization.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import es from '../../renderer/src/i18n/locales/es.json' -import { UI_LANGUAGE_ENGLISH, UI_LANGUAGE_SPANISH } from '../../shared/ui-language' -import { setMainUiLanguage, translateMain } from '../i18n/main-i18n' -import { formatProfileStateStartupFailure } from '../persistence/profile-state/profile-state-startup-failure' - -vi.mock('electron', () => ({ app: { getLocale: () => 'en-US' } })) - -afterEach(async () => { - await setMainUiLanguage(UI_LANGUAGE_ENGLISH) -}) - -describe('profile-state startup failure localization', () => { - it('reads dialog copy from the active catalog and keeps commands verbatim', async () => { - await setMainUiLanguage(UI_LANGUAGE_SPANISH) - expect(formatProfileStateStartupFailure({ code: 'newer-schema' }, translateMain)).toBe( - es.profileState.startupFailure.newerSchema - ) - const repair = formatProfileStateStartupFailure( - { - code: 'profile-state-recovery-required', - dataFile: '/profile/orca-data.json', - databaseFile: '/profile/profile-state.db', - exportPaths: [], - profileId: 'profile-a', - repairableSections: [{ domain: 'settings' }] - }, - translateMain - ) - expect(repair).toContain(es.profileState.section.settings) - expect(repair).toContain('`orca profile state rollback --repair --profile-id profile-a`') - // Logs and the CLI keep English when no translator is passed. - expect(formatProfileStateStartupFailure({ code: 'newer-schema' })).toContain( - 'newer version of Orca' - ) - }) -}) diff --git a/src/renderer/src/components/artifacts/artifact-display-labels.test.ts b/src/renderer/src/components/artifacts/artifact-display-labels.test.ts deleted file mode 100644 index f2d2efc4462..00000000000 --- a/src/renderer/src/components/artifacts/artifact-display-labels.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { ArtifactListItem } from '../../../../shared/artifacts' -import { - artifactTypeLabel, - formatArtifactExpiryCompact, - formatArtifactUpdatedCompact -} from './artifact-display-labels' - -function item(sourceContentType: string): ArtifactListItem { - return { - artifact: { - version: 1, - slug: 'doc', - title: 'Doc', - originalFileName: 'doc.md', - sourceContentType, - renderedContentType: 'text/html', - createdAt: '2026-08-01T12:00:00.000Z', - updatedAt: '2026-08-02T12:00:00.000Z', - expiresAt: '2026-09-01T12:00:00.000Z', - byteSize: 1, - deletedAt: null - }, - shareUrl: 'https://share.onorca.dev/a/doc' - } -} - -describe('artifact display labels', () => { - afterEach(() => { - vi.useRealTimers() - }) - - it('labels known artifact types', () => { - expect(artifactTypeLabel(item('text/html'))).toBe('HTML') - expect(artifactTypeLabel(item('text/markdown'))).toBe('Markdown') - expect(artifactTypeLabel(item('application/pdf'))).toBe('application/pdf') - }) - - it('uses compact relative times for table cells', () => { - vi.useFakeTimers() - vi.setSystemTime(new Date('2026-08-10T12:00:00.000Z')) - expect(formatArtifactUpdatedCompact('2026-08-08T12:00:00.000Z')).toBe('2 days ago') - expect(formatArtifactUpdatedCompact('not-a-date')).toBe('recently') - expect(formatArtifactExpiryCompact('2026-08-20T12:00:00.000Z')).toBe('in 10 days') - expect(formatArtifactExpiryCompact('2026-08-01T12:00:00.000Z')).toBe('Expired') - expect(formatArtifactExpiryCompact('not-a-date')).toBe('Expiry unknown') - }) -}) diff --git a/src/renderer/src/lib/ephemeral-vm-error-copy.test.ts b/src/renderer/src/lib/ephemeral-vm-error-copy.test.ts deleted file mode 100644 index c9c4dfbdcad..00000000000 --- a/src/renderer/src/lib/ephemeral-vm-error-copy.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { afterEach, describe, expect, it } from 'vitest' -import { i18n } from '@/i18n/i18n' -import es from '@/i18n/locales/es.json' -import { ephemeralVmFailure } from '../../../shared/ephemeral-vm-failure-copy' -import { ephemeralVmErrorText } from './ephemeral-vm-error-copy' - -const originalLanguage = i18n.language - -afterEach(async () => { - await i18n.changeLanguage(originalLanguage) -}) - -describe('ephemeralVmErrorText', () => { - it('localizes a coded failure and keeps the interpolated id verbatim', async () => { - i18n.addResourceBundle('es', 'translation', es) - await i18n.changeLanguage('es') - const missing = ephemeralVmFailure('recipeNotFound', { recipeId: 'cloud-{{ref}}' }) - expect(missing.error).toBe('Recipe not found: cloud-{{ref}}') - expect(ephemeralVmErrorText(missing)).toBe( - es.ephemeralVm.errors.recipeNotFound.replace('{{recipeId}}', 'cloud-{{ref}}') - ) - }) -}) diff --git a/src/shared/localhost-worktree-labels.test.ts b/src/shared/localhost-worktree-labels.test.ts index 35c98619b5c..d1eba6de29b 100644 --- a/src/shared/localhost-worktree-labels.test.ts +++ b/src/shared/localhost-worktree-labels.test.ts @@ -1,29 +1,10 @@ import { describe, expect, it } from 'vitest' import { getLocalhostWorktreeHostLabel, - getLocalhostWorktreeRouteKey, - slugifyLocalhostWorktreeLabel + getLocalhostWorktreeRouteKey } from './localhost-worktree-labels' describe('localhost worktree labels', () => { - it('uses project-main for the primary worktree', () => { - expect( - getLocalhostWorktreeHostLabel({ - projectName: 'Snap Studio', - worktreeName: 'main' - }) - ).toBe('snap-studio-main') - }) - - it('keeps non-main worktree labels short', () => { - expect( - getLocalhostWorktreeHostLabel({ - projectName: 'Snap Studio', - worktreeName: 'analytics' - }) - ).toBe('analytics') - }) - it('uses the worktree folder name over branch owner prefixes for non-main labels', () => { expect( getLocalhostWorktreeHostLabel({ @@ -34,10 +15,6 @@ describe('localhost worktree labels', () => { ).toBe('ui-auth') }) - it('normalizes labels for localhost hostnames', () => { - expect(slugifyLocalhostWorktreeLabel(' Drive DB Mismatch! ')).toBe('drive-db-mismatch') - }) - it('keeps route keys unique for different ports in the same worktree', () => { const route = { projectName: 'Snap Studio', diff --git a/src/shared/repo-display-labels.test.ts b/src/shared/repo-display-labels.test.ts index 20d24f17dc5..af152bdb29f 100644 --- a/src/shared/repo-display-labels.test.ts +++ b/src/shared/repo-display-labels.test.ts @@ -32,17 +32,6 @@ describe('getRepoDisplayLabelsByPath', () => { ) }) - it('scopes labels by execution host so same-path repos on different hosts do not collide', () => { - // SSH folder repos omit executionHostId; connectionId must still separate them from local same-path repos. - const localRepo = { path: '/Users/alice', displayName: 'alice' } - const sshRepo = { path: '/Users/alice', displayName: 'alice-prod', connectionId: 'prod-ssh' } - const labels = getRepoDisplayLabelsByPath([localRepo, sshRepo]) - - expect(labels.get(getRepoDisplayLabelKey(localRepo))).toBe('alice') - expect(labels.get(getRepoDisplayLabelKey(sshRepo))).toBe('alice-prod') - expect(labels.size).toBe(2) - }) - it('keeps cross-host repos with identical path AND name as separate entries', () => { const localRepo = { path: '/Users/alice', displayName: 'home' } const sshRepo = { path: '/Users/alice', displayName: 'home', connectionId: 'prod-ssh' } @@ -54,20 +43,6 @@ describe('getRepoDisplayLabelsByPath', () => { expect(labels.get(getRepoDisplayLabelKey(sshRepo))).toBe('home') }) - it('normalizes Windows separators to slash display labels', () => { - const labels = getRepoDisplayLabelsByPath([ - { path: 'C:\\workspace\\payments\\api', displayName: 'api' }, - { path: 'C:\\workspace\\billing\\api', displayName: 'api' } - ]) - - expect(labels.get(getRepoDisplayLabelKey({ path: 'C:\\workspace\\payments\\api' }))).toBe( - 'payments/api' - ) - expect(labels.get(getRepoDisplayLabelKey({ path: 'C:\\workspace\\billing\\api' }))).toBe( - 'billing/api' - ) - }) - it('disambiguates collisions only within their owning host, even when paths overlap', () => { const local = { path: '/workspace/payments/api', displayName: 'api' } const sibling = { path: '/workspace/billing/api', displayName: 'api' }