92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
|
|
// Тест VaultIndex (Фаза 7): теги, [[ссылки]], md-ссылки, граф, списки файлов по тегу.
|
||
|
|
#include <QCoreApplication>
|
||
|
|
#include <QTemporaryDir>
|
||
|
|
#include <QDir>
|
||
|
|
#include <QFile>
|
||
|
|
#include <cstdio>
|
||
|
|
|
||
|
|
#include "core/VaultIndex.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");
|
||
|
|
|
||
|
|
QDir(dir.path()).mkpath("sub");
|
||
|
|
auto put = [&](const QString &rel, const QString &body) {
|
||
|
|
QFile f(dir.path() + "/" + rel);
|
||
|
|
f.open(QIODevice::WriteOnly);
|
||
|
|
f.write(body.toUtf8());
|
||
|
|
f.close();
|
||
|
|
};
|
||
|
|
|
||
|
|
put("a.md", "# Заголовок #тег1\n\nСсылка на [[b]] и [[b]].\nТег ещё #тег2 и #тег1.\n");
|
||
|
|
put("sub/b.md", "# B\n\nпростой текст #тег2\n");
|
||
|
|
put("c.md", "[Перейти на b](sub/b.md)\n\n```\n# не тег\nint x;\n```\n");
|
||
|
|
|
||
|
|
VaultIndex idx;
|
||
|
|
idx.rebuild(dir.path());
|
||
|
|
if (idx.fileCount() != 3)
|
||
|
|
return fail("fileCount", QString::number(idx.fileCount()));
|
||
|
|
|
||
|
|
const QString a = dir.path() + "/a.md";
|
||
|
|
const QString b = dir.path() + "/sub/b.md";
|
||
|
|
const QString c = dir.path() + "/c.md";
|
||
|
|
|
||
|
|
// Теги файла a: тег1, тег2 (заголовок "# Заголовок" не тег)
|
||
|
|
QStringList tagsA = idx.tagsOfFile(a);
|
||
|
|
if (!tagsA.contains("тег1") || !tagsA.contains("тег2") || tagsA.size() != 2)
|
||
|
|
return fail("tagsOfFile(a)", tagsA.join(","));
|
||
|
|
|
||
|
|
// Ссылки a → b (вики)
|
||
|
|
auto linksA = idx.linksOfFile(a);
|
||
|
|
if (linksA.isEmpty())
|
||
|
|
return fail("linksOfFile(a) пусто");
|
||
|
|
bool foundB = false;
|
||
|
|
for (const auto &l : linksA) {
|
||
|
|
if (l.toMap().value("path").toString() == b)
|
||
|
|
foundB = true;
|
||
|
|
}
|
||
|
|
if (!foundB)
|
||
|
|
return fail("вики-ссылка на b не разрешена");
|
||
|
|
|
||
|
|
// c → b по md-ссылке
|
||
|
|
auto linksC = idx.linksOfFile(c);
|
||
|
|
foundB = false;
|
||
|
|
for (const auto &l : linksC)
|
||
|
|
if (l.toMap().value("path").toString() == b)
|
||
|
|
foundB = true;
|
||
|
|
if (!foundB)
|
||
|
|
return fail("md-ссылка на b не разрешена", QString());
|
||
|
|
|
||
|
|
// Граф: узлы-файлы и рёбра; тег как узел
|
||
|
|
bool haveTagNode = false;
|
||
|
|
for (const auto &n : idx.nodes()) {
|
||
|
|
if (n.toMap().value("type").toString() == "tag")
|
||
|
|
haveTagNode = true;
|
||
|
|
}
|
||
|
|
if (!haveTagNode)
|
||
|
|
return fail("нет узла-тега в графе");
|
||
|
|
if (idx.edges().isEmpty())
|
||
|
|
return fail("нет рёбер в графе");
|
||
|
|
|
||
|
|
// filesWithTag
|
||
|
|
QStringList files1 = idx.filesWithTag("тег1");
|
||
|
|
if (files1.size() != 1 || files1.first() != a)
|
||
|
|
return fail("filesWithTag(тег1)", files1.join(","));
|
||
|
|
QStringList files2 = idx.filesWithTag("тег2");
|
||
|
|
if (files2.size() != 2)
|
||
|
|
return fail("filesWithTag(тег2)", QString::number(files2.size()));
|
||
|
|
|
||
|
|
std::printf("VAULTINDEX TEST OK\n");
|
||
|
|
return 0;
|
||
|
|
}
|