// Тест FileStore (Фаза 3): дерево хранилища, создание/переименование/ // удаление/перемещение, раскрытие папок, иконки, валидация имён. #include #include #include #include #include #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; }