Files
MyNote/tests/unit/atomic-write.test.ts

42 lines
1.5 KiB
TypeScript

import { describe, it, expect, afterEach } from 'vitest';
import nodePath from 'node:path';
import os from 'node:os';
import { promises as fs } from 'node:fs';
import { writeFileAtomic, withFileLock } from '../../apps/desktop/src/main/safe/atomic-write';
const dir = nodePath.join(os.tmpdir(), 'dsh-atomic-test');
afterEach(async () => { await fs.rm(dir, { recursive: true, force: true }); });
describe('writeFileAtomic (FR-S5)', () => {
it('写入内容并回读一致', async () => {
const p = nodePath.join(dir, 'a.md');
await writeFileAtomic(p, '# 标题\n内容');
expect(await fs.readFile(p, 'utf8')).toBe('# 标题\n内容');
});
it('不残留临时文件', async () => {
const p = nodePath.join(dir, 'b.md');
await writeFileAtomic(p, 'x');
const files = await fs.readdir(dir);
expect(files).toEqual(['b.md']);
});
it('覆盖已有文件', async () => {
const p = nodePath.join(dir, 'c.md');
await writeFileAtomic(p, 'old');
await writeFileAtomic(p, 'new');
expect(await fs.readFile(p, 'utf8')).toBe('new');
});
});
describe('withFileLock 并发安全', () => {
it('同文件请求串行执行', async () => {
const p = nodePath.join(dir, 'lock.md');
const order: number[] = [];
const t = (id: number, delay: number) => withFileLock(p, async () => {
order.push(id);
await new Promise(r => setTimeout(r, delay));
});
await Promise.all([t(1, 20), t(2, 1), t(3, 1)]);
expect(order).toEqual([1, 2, 3]);
});
});