Session 5 of voyage-rebrand (V6). Operator-authorized cross-plugin scope. - git mv plugins/ultraplan-local plugins/voyage (rename detected, history preserved) - .claude-plugin/marketplace.json: voyage entry replaces ultraplan-local - CLAUDE.md: voyage row in plugin list, voyage in design-system consumer list - README.md: bulk rename ultra*-local commands -> trek* commands; ultraplan-local refs -> voyage; type discriminators (type: trekbrief/trekreview); session-title pattern (voyage:<command>:<slug>); v4.0.0 release-note paragraph - plugins/voyage/.claude-plugin/plugin.json: homepage/repository URLs point to monorepo voyage path - plugins/voyage/verify.sh: drop URL whitelist exception (no longer needed) Closes voyage-rebrand. bash plugins/voyage/verify.sh PASS 7/7. npm test 361/361.
61 lines
2.1 KiB
JavaScript
61 lines
2.1 KiB
JavaScript
// tests/lib/atomic-write.test.mjs
|
|
// Unit tests for lib/util/atomic-write.mjs
|
|
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtempSync, rmSync, readFileSync, existsSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { atomicWriteJson } from '../../lib/util/atomic-write.mjs';
|
|
|
|
test('atomicWriteJson — writes valid JSON and round-trips', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'aw-test-'));
|
|
try {
|
|
const path = join(dir, 'state.json');
|
|
const obj = { schema_version: 1, status: 'in_progress', items: [1, 2, 3] };
|
|
atomicWriteJson(path, obj);
|
|
const read = JSON.parse(readFileSync(path, 'utf-8'));
|
|
assert.deepEqual(read, obj);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test('atomicWriteJson — leaves no .tmp orphan after success', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'aw-test-'));
|
|
try {
|
|
const path = join(dir, 'state.json');
|
|
atomicWriteJson(path, { ok: true });
|
|
assert.equal(existsSync(path), true);
|
|
assert.equal(existsSync(path + '.tmp'), false);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test('atomicWriteJson — overwrites existing file atomically', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'aw-test-'));
|
|
try {
|
|
const path = join(dir, 'state.json');
|
|
writeFileSync(path, '{"old":true}');
|
|
atomicWriteJson(path, { new: true });
|
|
const read = JSON.parse(readFileSync(path, 'utf-8'));
|
|
assert.deepEqual(read, { new: true });
|
|
assert.equal(existsSync(path + '.tmp'), false);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test('atomicWriteJson — pretty-prints with 2-space indent', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'aw-test-'));
|
|
try {
|
|
const path = join(dir, 'state.json');
|
|
atomicWriteJson(path, { a: 1, b: { c: 2 } });
|
|
const text = readFileSync(path, 'utf-8');
|
|
assert.match(text, /\n {2}"a": 1/);
|
|
assert.match(text, /\n {4}"c": 2/);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|