Фазы 2-3: мульти-окна (WindowController, per-window FileStore), файловое дерево (FileStore+FileTreePanel, иконки/раскрытие/ПКМ/+drag&drop/подтверждения), NameDialog/ConfirmDialog; тест filestore (13/13)

This commit is contained in:
Flora (opencode)
2026-08-17 01:02:05 +03:00
parent ed633ae036
commit c740c9a756
12 changed files with 1305 additions and 76 deletions
+134
View File
@@ -0,0 +1,134 @@
// Тест FileStore (Фаза 3): дерево хранилища, создание/переименование/
// удаление/перемещение, раскрытие папок, иконки, валидация имён.
#include <QCoreApplication>
#include <QTemporaryDir>
#include <QDir>
#include <QFile>
#include <cstdio>
#include "core/FileStore.h"
static int fail(const char *msg, const QString &detail = QString())
{
std::fprintf(stderr, "FAIL: %s %s\n", msg, qPrintable(detail));
return 1;
}
static int rowOf(FileStore &fs, const QString &path)
{
const int n = fs.rowCount();
for (int i = 0; i < n; ++i)
if (fs.itemPath(i) == path)
return i;
return -1;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QTemporaryDir dir;
if (!dir.isValid())
return fail("temp dir");
FileStore fs;
const QString vault = dir.path();
QString err = fs.openVault(vault);
if (!err.isEmpty())
return fail("openVault", err);
// --- создание ---
err = fs.createFile(vault, "note.md");
if (!err.isEmpty())
return fail("createFile", err);
err = fs.createFolder(vault, "sub");
if (!err.isEmpty())
return fail("createFolder", err);
err = fs.createFolder(dir.path() + "/sub", "deep");
if (!err.isEmpty())
return fail("createFolder deep", err);
err = fs.createFile(dir.path() + "/sub", "inner.txt");
if (!err.isEmpty())
return fail("createFile inner", err);
const QString note = dir.path() + "/note.md";
const QString sub = dir.path() + "/sub";
const QString deep = dir.path() + "/sub/deep";
const QString inner = dir.path() + "/sub/inner.txt";
// Папка sub содержит children; deep пустая
if (rowOf(fs, sub) < 0)
return fail("sub не в дереве");
// --- иконки (sub автоматически раскрыта после создания) ---
{
const QString subIcon = fs.data(fs.index(rowOf(fs, sub)), FileStore::IconRole).toString();
if (subIcon != "folder")
return fail("иконка sub", subIcon);
const int ri = rowOf(fs, deep);
if (ri < 0)
return fail("deep не видна (авто-раскрытие)", QString());
const QString deepIcon = fs.data(fs.index(ri), FileStore::IconRole).toString();
if (deepIcon != "folder-empty")
return fail("иконка deep", deepIcon);
}
// --- раскрытие/сворачивание ---
{
const int subRow = rowOf(fs, sub);
if (subRow < 0)
return fail("sub отсутствует");
if (rowOf(fs, inner) < 0 || rowOf(fs, deep) < 0)
return fail("вложенное не видно при раскрытой sub");
fs.toggleExpand(subRow); // сворачиваем
if (rowOf(fs, inner) >= 0 || rowOf(fs, deep) >= 0)
return fail("свёрнутая sub показывает вложенное");
fs.toggleExpand(rowOf(fs, sub)); // раскрываем снова
if (rowOf(fs, inner) < 0 || rowOf(fs, deep) < 0)
return fail("повторное раскрытие не работает");
}
// --- переименование ---
err = fs.renameItem(deep, "deep2");
if (!err.isEmpty())
return fail("renameItem", err);
if (!QDir(dir.path() + "/sub/deep2").exists())
return fail("rename: папка не переименована");
// --- перемещение ---
err = fs.moveItem(note, sub);
if (!err.isEmpty())
return fail("moveItem", err);
if (!QFile::exists(dir.path() + "/sub/note.md"))
return fail("move: файл не перемещён");
// --- удаление ---
err = fs.removeItem(dir.path() + "/sub/inner.txt");
if (!err.isEmpty())
return fail("removeItem file", err);
err = fs.removeItem(dir.path() + "/sub/deep2");
if (!err.isEmpty())
return fail("removeItem dir", err);
err = fs.removeItem(sub);
if (!err.isEmpty())
return fail("removeItem sub", err);
if (QDir(sub).exists())
return fail("папка осталась после удаления");
// --- валидация ---
if (fs.createFile(vault, "bad/name").isEmpty())
return fail("имя с '/' принято");
if (fs.createFile(vault, "").isEmpty())
return fail("пустое имя принято");
if (fs.renameItem(dir.path() + "/note.md", "../escape").isEmpty())
return fail("переименование с '..' принято");
// --- невалидное хранилище ---
if (fs.openVault("/нет/такого/пути_xyz").isEmpty())
return fail("openVault неверный путь");
std::printf("FILESTORE TEST OK\n");
return 0;
}