sotashimozono_obsidian-remo.../plugin/vitest.config.ts
sotashimozono 34ea26255b
fix(tests): repair 6 CI failures + bump 1.0.36 (#278)
* fix(tests): repair 6 CI failures introduced by recent PR merges

ObsidianRegistry.test.ts + ShadowVaultBootstrap.test.ts:
  Wrap `import * as fs from "fs"` in `vi.mock("fs", () => ({ ...actual }))`
  so vitest creates a configurable namespace. The raw ESM `fs` namespace
  is non-configurable in Node + Vitest 4, which made the existing
  `vi.spyOn(fs, "writeFileSync"|"renameSync"|"symlinkSync")` calls throw
  `Cannot redefine property` at test setup time. The mock re-exports
  `actual` so all non-spied fs calls keep their real behaviour.

ShadowVaultBootstrap.test.ts (collectPendingPluginSuggestions):
  Two tests asserted `data.pendingPluginSuggestions` equal `[]` when
  source `community-plugins.json` is invalid/non-array. The implementation
  (ShadowVaultBootstrap.ts:121-126) deliberately omits the key entirely
  when `pending.length === 0` -- the absent key is the "no suggestions"
  signal that ShadowStartupCoordinator relies on for its no-op fast path.
  Aligned the test with the implementation contract.

ConflictResolver.test.ts:58:
  `swapClient` test asserted `writeBinary` was called with a third
  `undefined` arg. Other tests in the file (e.g. line 91) and the
  source (ConflictResolver.ts:88,92,129) confirm the call passes only
  two args. Removed the spurious trailing `undefined`.

* chore: bump version to 1.0.36

* ci: bump Node heap to 6 GiB to stop intermittent test-job OOMs

Vitest 4's default `forks` pool plus jsdom on every test file pushed
peak RSS just past Node's default ~4 GiB old-space ceiling once the
suite grew to ~70 files / ~1000 tests. The CI logs showed `FATAL ERROR:
Reached heap limit Allocation failed - JavaScript heap out of memory`
during ubuntu-latest, ubuntu-node22, macos-latest, and windows-latest
test jobs on the last several main-branch runs (it predates this PR;
the earlier 6 unit-test failures were just the first symptom).

Apply the same env to release.yml's test gate so a release tag push
does not flake on the same wall.

GitHub-hosted runners advertise 7+ GiB, so 6 GiB is safe headroom
without crowding the kernel/page-cache budget.

* fix(tests): SftpClient unit tests caused worker OOM via infinite BFS

Root cause of the CI test-job crashes:

  tests/SftpClient.unit.test.ts > rmdir() > recursive: removes all
  files and subdirs before root

mocked sftp.readdir with a path-agnostic `mockImplementation` that
returned `[file.md, sub (dir)]` for every call. SftpClient.rmdir's
recursive branch calls listRecursive, whose BFS then re-discovered
`sub` inside `/vault/sub`, then `/vault/sub/sub`, then
`/vault/sub/sub/sub`, ... -- growing the visited Set, the queue, and
the result array without bound until the worker hit
`FATAL ERROR: Reached heap limit`. Replaced with a path-aware mock so
only `/vault` has children; the BFS terminates after one level.

Also fixed `listRecursive() returns files from nested subdirectories
via BFS`: the assertion expected `['deep.md', ...]` but
`SftpClient.listRecursive` deliberately returns the full path under
root as relativePath (`sub/deep.md`), not the basename -- every
downstream consumer needs the unambiguous form.

Plus pass `--max-old-space-size=6144` to vitest workers via
`test.execArgv` so future legitimately-large suites have headroom
without needing per-job NODE_OPTIONS overrides. (In Vitest 4 the
top-level `poolOptions` was removed; both `pool` and `execArgv` are
now top-level keys inside `test:`.)
2026-05-09 23:26:01 +09:00

75 lines
3.3 KiB
TypeScript

import { defineConfig } from 'vitest/config';
import * as path from 'path';
// Default config runs unit tests only. Integration tests live under
// `tests/integration/` and need a running docker sshd container —
// they're routed through `vitest.integration.config.ts` and
// invoked via `npm run test:integration`.
export default defineConfig({
resolve: {
alias: {
// Obsidian's npm package is types-only. UI/settings tests need
// a runtime, so route `import 'obsidian'` to our hand-rolled mock.
// Production builds use the real Obsidian provided by the host
// process — this alias only applies inside vitest.
obsidian: path.resolve(__dirname, 'tests/__mocks__/obsidian.ts'),
},
},
test: {
// jsdom gives us HTMLElement / document so the obsidian-mock can
// patch DOM helpers and Modal.contentEl works for free. The
// existing non-DOM tests stay happy under jsdom too — Buffer +
// fs work the same as in node mode (jsdom runs on top of node).
environment: 'jsdom',
setupFiles: ['./vitest.setup.ts'],
include: ['tests/**/*.test.ts'],
exclude: ['tests/integration/**', 'node_modules/**', 'tests/__mocks__/**'],
// Vitest 4's default `forks` pool spawns child Node processes that
// do NOT inherit the parent's `NODE_OPTIONS=--max-old-space-size`,
// so each worker is capped at the V8 default (~4 GiB). Once the
// suite grew to ~70 jsdom test files, individual workers started
// hitting `FATAL ERROR: Reached heap limit` mid-file (notably
// SftpClient.unit.test.ts, which exercises ~50 mock-heavy tests).
// Pass `--max-old-space-size=6144` to the spawned workers via
// `execArgv` so each gets the same 6 GiB headroom we set for the
// CI workflow's parent process. (In Vitest 4 `execArgv` is a
// top-level key inside `test`, not under `poolOptions`.)
execArgv: ['--max-old-space-size=6144'],
coverage: {
provider: 'v8',
reporter: ['text', 'lcov'],
include: ['src/**/*.ts'],
// src/ui/** + src/settings/** are testable on the
// tests/__mocks__/obsidian.ts runtime mock. Files below are
// excluded only until they have a dedicated test suite — drop
// entries from this list as the suites land, then bump the
// global thresholds back up.
exclude: [
'src/main.ts',
'src/ui/ConnectModal.ts',
'src/ui/HostKeyMismatchModal.ts',
'src/ui/KbdInteractiveModal.ts',
'src/ui/LargeTransferBar.ts',
'src/ui/PendingEditsBar.ts',
'src/ui/PendingEditsModal.ts',
'src/ui/PendingPluginsModal.ts',
'src/ui/RemotePathBrowserModal.ts',
// #149 — heavy xterm.js DOM rendering + ResizeObserver makes
// jsdom unit tests impractical. Manual smoke against a real
// Obsidian window covers this; RemoteShell has its own unit tests.
'src/ui/RemoteTerminalView.ts',
'src/ui/StatusBar.ts',
'src/ui/ThreeWayMergeModal.ts',
'src/ui/WriteConflictModal.ts',
'src/settings/ProfileForm.ts',
],
// Calibrated for the current measured scope. Bring back up as
// more UI/settings suites land and per-file coverage rises.
thresholds: {
lines: 76,
branches: 70,
functions: 72,
},
},
},
});