From 297ed8a04b4e5423213f0eb8680a57f5ca58a469 Mon Sep 17 00:00:00 2001 From: plur9 Date: Sat, 26 Sep 2026 19:09:27 +0200 Subject: [PATCH] sync test: run against a fixture, not the publisher's ~/Data statusAll ran git status over every live space and timed out at 5s often enough to block the 2.5.1 publish. sync.ts froze DATA_DIR at import, so the test could not be pointed anywhere else; it is now resolved per call. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GSzwHUALnUZdoW7v21dDtr --- src/lib/sync.ts | 10 +++++---- tests/sync.test.ts | 56 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/lib/sync.ts b/src/lib/sync.ts index 0735d15..6b80424 100644 --- a/src/lib/sync.ts +++ b/src/lib/sync.ts @@ -12,7 +12,9 @@ import { listSpaces } from './space' import { dataDir, datacoreLib } from './paths' import { findPython } from './python' -const DATA_DIR = dataDir() +// Resolved per call, like upgrade.ts: freezing it at import made the tests +// read whichever installation the first importer happened to see. +const DATA_DIR = () => dataDir() /** * Locate the ledger transport, or null on an installation that predates it. @@ -22,7 +24,7 @@ const DATA_DIR = dataDir() function findLedgerTransport(): { python: string; script: string } | null { const script = join(datacoreLib(), 'ledger_transport.py') if (!existsSync(script)) return null - const python = findPython(DATA_DIR) + const python = findPython(DATA_DIR()) if (!python) return null return { python, script } } @@ -283,8 +285,8 @@ function getGitRepos(): Array<{ path: string; name: string }> { const repos: Array<{ path: string; name: string }> = [] // Data root - if (isGitRepo(DATA_DIR)) { - repos.push({ path: DATA_DIR, name: 'Data' }) + if (isGitRepo(DATA_DIR())) { + repos.push({ path: DATA_DIR(), name: 'Data' }) } // All spaces with git diff --git a/tests/sync.test.ts b/tests/sync.test.ts index 12f88ed..f9652b5 100644 --- a/tests/sync.test.ts +++ b/tests/sync.test.ts @@ -1,22 +1,51 @@ /** * Tests for git sync utilities. + * + * Runs against a fixture installation, not the developer's ~/Data: against the + * live one, statusAll ran `git status` over every real space and timed out at + * 5s often enough to block a publish on the publisher's disk state. */ -import { describe, it, expect } from 'bun:test' -import { statusAll, getRepoStatus } from '../src/lib/sync' +import { describe, it, expect, beforeAll, afterAll } from 'bun:test' +import { mkdtempSync, mkdirSync, rmSync } from 'fs' +import { execFileSync } from 'child_process' +import { tmpdir } from 'os' import { join } from 'path' +import { statusAll, getRepoStatus } from '../src/lib/sync' + +let root: string +const savedRoot = process.env.DATACORE_ROOT -const DATA_DIR = join(process.env.HOME || '~', 'Data') +function gitInit(dir: string) { + mkdirSync(dir, { recursive: true }) + execFileSync('git', ['init', '-q', '-b', 'main', dir]) + execFileSync('git', ['-C', dir, '-c', 'core.hooksPath=/dev/null', '-c', 'user.email=t@example.com', '-c', 'user.name=T', + 'commit', '-q', '--allow-empty', '-m', 'init']) +} + +beforeAll(() => { + root = mkdtempSync(join(tmpdir(), 'dc-cli-sync-')) + gitInit(root) + gitInit(join(root, '0-personal')) + process.env.DATACORE_ROOT = root +}) + +afterAll(() => { + if (savedRoot === undefined) delete process.env.DATACORE_ROOT + else process.env.DATACORE_ROOT = savedRoot + rmSync(root, { recursive: true, force: true }) +}) describe('Sync Utilities', () => { describe('statusAll', () => { - it('returns an array', () => { - const statuses = statusAll() - expect(Array.isArray(statuses)).toBe(true) + it('finds the root repo and each space repo', () => { + const paths = statusAll().map((s) => s.path).sort() + expect(paths).toEqual([root, join(root, '0-personal')].sort()) }) it('statuses have required properties', () => { const statuses = statusAll() + expect(statuses.length).toBeGreaterThan(0) for (const status of statuses) { expect(typeof status.path).toBe('string') expect(typeof status.name).toBe('string') @@ -31,17 +60,16 @@ describe('Sync Utilities', () => { describe('getRepoStatus', () => { it('returns null for non-git directory', () => { - const status = getRepoStatus('/tmp') - expect(status).toBeNull() + const dir = mkdtempSync(join(tmpdir(), 'dc-cli-nogit-')) + expect(getRepoStatus(dir)).toBeNull() + rmSync(dir, { recursive: true, force: true }) }) it('returns status for git directory', () => { - const status = getRepoStatus(DATA_DIR) - // Data directory may or may not be a git repo - if (status) { - expect(typeof status.branch).toBe('string') - expect(typeof status.dirty).toBe('boolean') - } + const status = getRepoStatus(root) + expect(status).not.toBeNull() + expect(status!.branch).toBe('main') + expect(status!.dirty).toBe(false) }) }) })