// Тест DocumentManager (Фаза 4): открытие вкладок, редактирование, // сохранение, автосохранение по таймеру, закрытие, заголовки, dirty-флаги. #include #include #include #include #include #include #include "core/DocumentManager.h" static int fail(const char *msg, const QString &detail = QString()) { std::fprintf(stderr, "FAIL: %s %s\n", msg, qPrintable(detail)); return 1; } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTemporaryDir dir; if (!dir.isValid()) return fail("temp dir"); const QString vault = dir.path(); QDir(vault).mkpath("sub"); // --- открытие --- { QFile f(vault + "/a.md"); f.open(QIODevice::WriteOnly); f.write("# A\n"); f.close(); } DocumentManager dm; dm.setAutosaveIntervalMs(300); // быстрый автосейв для теста int idx = dm.openDocument(vault + "/a.md"); if (idx != 0) return fail("openDocument вернул неверный индекс", QString::number(idx)); if (dm.openTabs().size() != 1) return fail("вкладка не создана"); if (dm.contentAt(0) != "# A\n") return fail("содержимое не прочитано"); if (dm.titleAt(0) != "a.md") return fail("заголовок", dm.titleAt(0)); if (dm.isDirty(0)) return fail("свежий файл помечен изменённым"); // --- повторное открытие той же вкладки --- if (dm.openDocument(vault + "/a.md") != 0) return fail("повторное открытие создало новую вкладку"); // --- редактирование --- dm.updateContent(0, "# A edited\n\nНовый текст\n"); if (!dm.isDirty(0)) return fail("правка не помечена"); if (dm.contentAt(0).isEmpty() || !dm.contentAt(0).contains("Новый текст")) return fail("контент не обновился"); // --- сохранение --- dm.saveDocument(0); if (dm.isDirty(0)) return fail("после сохранения dirty остался"); { QFile f(vault + "/a.md"); f.open(QIODevice::ReadOnly); const QString s = QString::fromUtf8(f.readAll()); if (!s.contains("Новый текст")) return fail("файл не записан"); } // --- автосохранение по таймеру --- dm.updateContent(0, "# A edited\n\nАвтосейв\n"); { // используем отдельный event-loop, чтобы не триггерить aboutToQuit QEventLoop loop; QTimer t; QObject::connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit); t.setSingleShot(true); t.start(700); loop.exec(); } if (dm.isDirty(0)) return fail("автосохранение не сработало"); { QFile f(vault + "/a.md"); f.open(QIODevice::ReadOnly); if (!QString::fromUtf8(f.readAll()).contains("Автосейв")) return fail("автосохранение не записало файл"); } // --- второй документ и закрытие --- { QFile f(vault + "/sub/b.md"); f.open(QIODevice::WriteOnly); f.write("b\n"); f.close(); } const int idxB = dm.openDocument(vault + "/sub/b.md"); if (idxB != 1) return fail("второй документ", QString::number(idxB)); if (dm.openTabs().size() != 2) return fail("вкладок должно быть 2"); dm.updateContent(idxB, "b изменён"); if (!dm.closeTab(1)) return fail("closeTab"); if (dm.openTabs().size() != 1) return fail("вкладка не закрыта"); if (dm.isDirty(0)) return fail("активная вкладка испорчена после закрытия"); { QFile f(vault + "/sub/b.md"); f.open(QIODevice::ReadOnly); if (!QString::fromUtf8(f.readAll()).contains("изменён")) return fail("закрытие не сохранило изменённый документ"); } // --- несуществующий файл --- if (dm.openDocument(vault + "/нет.md") != -1) return fail("открытие несуществующего файла"); // --- isTextForEditor --- if (!dm.isTextForEditor("/x/a.md") || !dm.isTextForEditor("/x/a.txt") || !dm.isTextForEditor("/x/a.py") || dm.isTextForEditor("/x/a.png") || dm.isTextForEditor("/x/a.pdf")) return fail("isTextForEditor"); // --- autosaveEnabled (ручной режим настроек) --- if (!dm.autosaveEnabled()) return fail("autosave enabled by default"); { QTimer *t = dm.findChild(); if (!t || !t->isActive()) return fail("autosave timer active"); } dm.setAutosaveEnabled(false); if (dm.autosaveEnabled()) return fail("autosave disabled"); { QTimer *t = dm.findChild(); if (!t || t->isActive()) return fail("autosave timer stopped"); } dm.setAutosaveEnabled(true); if (!dm.autosaveEnabled()) return fail("autosave re-enabled"); std::printf("DOCUMENT MANAGER TEST OK\n"); return 0; }