#include #include #include #include #include "../src/middleware/orchestrator.h" class OrchestratorTest : public QObject { Q_OBJECT private slots: void journal_from_prompt_writes_outputs(); }; void OrchestratorTest::journal_from_prompt_writes_outputs() { // Create a temp state dir QDir tmp = QDir::temp(); const QString base = QStringLiteral("kompanion_test_%1").arg(QDateTime::currentMSecsSinceEpoch()); QVERIFY(tmp.mkpath(base)); QDir state(tmp.filePath(base)); // Prepare a task JSONL QFile tasks(state.filePath("tasks.jsonl")); QVERIFY(tasks.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)); const QByteArray line = QByteArray("{\"type\":\"journal.from_prompt\",\"aspect\":\"companion\",\"prompt\":\"hello world\"}\n"); QVERIFY(tasks.write(line) == line.size()); tasks.close(); // Stub provider returns deterministic text StubModelProvider stub(QStringLiteral("TEST_OUTPUT")); Orchestrator orch; orch.setStateDir(state); orch.setModelProvider(&stub); orch.processPendingTasks(); // Expect journal file for today exists and contains the output const QString journalPath = state.filePath("journal/" + QDate::currentDate().toString(Qt::ISODate) + ".md"); QFile journal(journalPath); QVERIFY(journal.exists()); QVERIFY(journal.open(QIODevice::ReadOnly | QIODevice::Text)); const QString content = QString::fromUtf8(journal.readAll()); QVERIFY2(content.contains("TEST_OUTPUT"), "Journal should contain model output"); // Expect ledger file exists QFile ledger(state.filePath("trust_ledger.jsonl")); QVERIFY(ledger.exists()); } QTEST_MAIN(OrchestratorTest) #include "test_orchestrator.moc"