Редактор: превью с поворотом, проекты, безопасное сохранение zip, dev-меню
RotatedImage: размер контейнера через clientWidth/Height (не getBoundingClientRect), чтобы cover при 90°/270° работал под zoom React Flow; убраны отладочные логи. Главное меню в dev: пункт «Вид» с DevTools (Ctrl+Shift+I без пустого application menu). Список проектов: project.list без лицензии; список подгружается при неактивной лицензии; ProjectPicker с подсказками; listProjects пропускает битые zip. Сохранение проектов: atomicReplace — замена zip без rm до commit; восстановление *.dnd.zip.tmp при старте; тесты. EditorApp: блокировка UI при открытых окнах презентации и пульта; стили оверлея. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
|
||||
import { replaceFileAtomic } from './atomicReplace';
|
||||
|
||||
void test('replaceFileAtomic: replaces existing file without deleting before rename succeeds', async () => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'dnd-replace-'));
|
||||
const finalPath = path.join(dir, 'out.bin');
|
||||
const tmpPath = path.join(dir, 'out.bin.tmp');
|
||||
await fs.writeFile(finalPath, 'previous', 'utf8');
|
||||
await fs.writeFile(tmpPath, 'updated-content', 'utf8');
|
||||
await replaceFileAtomic(tmpPath, finalPath);
|
||||
assert.equal(await fs.readFile(finalPath, 'utf8'), 'updated-content');
|
||||
await assert.rejects(() => fs.stat(tmpPath));
|
||||
});
|
||||
|
||||
void test('replaceFileAtomic: rejects empty source', async () => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'dnd-replace-'));
|
||||
const finalPath = path.join(dir, 'out.bin');
|
||||
const tmpPath = path.join(dir, 'out.bin.tmp');
|
||||
await fs.writeFile(finalPath, 'x', 'utf8');
|
||||
await fs.writeFile(tmpPath, '', 'utf8');
|
||||
await assert.rejects(() => replaceFileAtomic(tmpPath, finalPath));
|
||||
assert.equal(await fs.readFile(finalPath, 'utf8'), 'x');
|
||||
});
|
||||
Reference in New Issue
Block a user