fix: Remove isUserSource from tests

This commit is contained in:
Petr Mironychev
2026-06-28 17:37:11 +02:00
parent ccc2ec2e80
commit dc3100f054
12 changed files with 224 additions and 88 deletions

View File

@@ -357,6 +357,15 @@ SessionManager *ChatRootView::sessionManager() const
return m_sessionManager; return m_sessionManager;
} }
QodeAssist::Session *ChatRootView::ownerSession()
{
if (!m_clientInterface)
return nullptr;
m_clientInterface->setSessionManager(sessionManager());
m_clientInterface->ensureSession();
return m_clientInterface->session();
}
void ChatRootView::loadAvailableChatAgents() void ChatRootView::loadAvailableChatAgents()
{ {
m_agentController->setAgentFactory(agentFactory()); m_agentController->setAgentFactory(agentFactory());
@@ -535,13 +544,12 @@ void ChatRootView::clearMessages()
void ChatRootView::saveHistory(const QString &filePath) void ChatRootView::saveHistory(const QString &filePath)
{ {
if (filePath != m_recentFilePath) { if (auto registry = sessionFileRegistry();
if (auto registry = sessionFileRegistry(); registry && registry->isLocked(filePath)) { registry && registry->isLockedByOther(filePath, ownerSession())) {
m_lastErrorMessage m_lastErrorMessage = tr(
= tr("This chat file is already in use by another QodeAssist chat session."); "This chat file is already in use by another QodeAssist chat session.");
emit lastErrorMessageChanged(); emit lastErrorMessageChanged();
return; return;
}
} }
auto result = m_historyStore->save(filePath); auto result = m_historyStore->save(filePath);
@@ -554,13 +562,11 @@ void ChatRootView::saveHistory(const QString &filePath)
void ChatRootView::loadHistory(const QString &filePath) void ChatRootView::loadHistory(const QString &filePath)
{ {
if (filePath != m_recentFilePath) { if (auto registry = sessionFileRegistry();
if (auto registry = sessionFileRegistry(); registry && registry->isLocked(filePath)) { registry && registry->isLockedByOther(filePath, ownerSession())) {
m_lastErrorMessage m_lastErrorMessage = tr("This chat is already open in another QodeAssist chat session.");
= tr("This chat is already open in another QodeAssist chat session."); emit lastErrorMessageChanged();
emit lastErrorMessageChanged(); return;
return;
}
} }
auto result = m_historyStore->load(filePath); auto result = m_historyStore->load(filePath);
@@ -1032,7 +1038,7 @@ void ChatRootView::setRecentFilePath(const QString &filePath)
registry->release(m_recentFilePath); registry->release(m_recentFilePath);
} }
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
registry->lock(filePath); registry->lock(filePath, ownerSession());
} }
} }

View File

@@ -21,6 +21,7 @@ namespace QodeAssist {
class AgentFactory; class AgentFactory;
class SessionManager; class SessionManager;
class ConversationHistory; class ConversationHistory;
class Session;
} }
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
@@ -233,6 +234,7 @@ private:
Skills::SkillsManager *skillsManager() const; Skills::SkillsManager *skillsManager() const;
AgentFactory *agentFactory() const; AgentFactory *agentFactory() const;
SessionManager *sessionManager() const; SessionManager *sessionManager() const;
QodeAssist::Session *ownerSession();
QodeAssist::ConversationHistory *m_history; QodeAssist::ConversationHistory *m_history;
ChatModel *m_chatModel; ChatModel *m_chatModel;

View File

@@ -97,6 +97,55 @@ void ClientInterface::setActiveAgent(const QString &agentName)
m_activeAgent = agentName; m_activeAgent = agentName;
} }
Session *ClientInterface::session() const
{
return m_session;
}
void ClientInterface::ensureSession()
{
if (m_session || !m_sessionManager || !m_history)
return;
m_session = m_sessionManager->createDetachedSession(m_history, this);
connect(m_session, &Session::event, this, [this](const QodeAssist::ResponseEvent &ev) {
onSessionEvent(m_session, ev);
});
connect(m_session, &Session::finished, this, [this](const LLMQore::RequestID &id, const QString &) {
onSessionFinished(id);
});
connect(
m_session,
&Session::failed,
this,
[this](const LLMQore::RequestID &id, const QodeAssist::ErrorInfo &error) {
onSessionFailed(id, error);
});
}
bool ClientInterface::ensureAgentBound()
{
if (m_session->hasAgent() && m_boundAgent == m_activeAgent)
return true;
QString agentError;
if (!m_sessionManager->rebindAgentByName(m_session, m_activeAgent, &agentError)) {
m_boundAgent.clear();
const QString error = agentError.isEmpty() ? QStringLiteral("No chat agent selected")
: agentError;
LOG_MESSAGE(error);
emit errorOccurred(error);
return false;
}
m_boundAgent = m_activeAgent;
if (auto *client = m_session->client())
m_sessionManager->toolContributors().contribute(client->tools());
return true;
}
void ClientInterface::sendMessage( void ClientInterface::sendMessage(
const QString &message, const QString &message,
const QList<QString> &attachments, const QList<QString> &attachments,
@@ -173,22 +222,21 @@ void ClientInterface::sendMessage(
return; return;
} }
QString sessionError; ensureSession();
Session *session = m_sessionManager->createSession(m_activeAgent, m_history, &sessionError); if (!m_session) {
if (!session) { const QString error = QStringLiteral("Failed to create chat session");
const QString error = sessionError.isEmpty()
? QStringLiteral("No chat agent selected")
: sessionError;
LOG_MESSAGE(error); LOG_MESSAGE(error);
emit errorOccurred(error); emit errorOccurred(error);
return; return;
} }
auto *client = session->client(); if (!ensureAgentBound())
return;
auto *client = m_session->client();
if (!client) { if (!client) {
const QString error = QStringLiteral("Chat agent has no live client"); const QString error = QStringLiteral("Chat agent has no live client");
LOG_MESSAGE(error); LOG_MESSAGE(error);
m_sessionManager->removeSession(session);
emit errorOccurred(error); emit errorOccurred(error);
return; return;
} }
@@ -197,26 +245,27 @@ void ClientInterface::sendMessage(
Templates::ContextRenderer::Bindings bindings; Templates::ContextRenderer::Bindings bindings;
bindings.projectDir = project ? project->projectDirectory().toFSPathString() : QString(); bindings.projectDir = project ? project->projectDirectory().toFSPathString() : QString();
bindings.configDir = AgentFactory::userConfigDir(); bindings.configDir = AgentFactory::userConfigDir();
session->setContextBindings(bindings); m_session->setContextBindings(bindings);
const QString chatFilePath = m_chatFilePath; const QString chatFilePath = m_chatFilePath;
session->setContentLoader([chatFilePath, cache = m_contentCache](const QString &storedPath) { m_session->setContentLoader([chatFilePath, cache = m_contentCache](const QString &storedPath) {
return ChatSerializer::loadContentFromStorage(chatFilePath, storedPath, cache.get()); return ChatSerializer::loadContentFromStorage(chatFilePath, storedPath, cache.get());
}); });
m_sessionManager->toolContributors().contribute(client->tools());
client->toolLoop()->setMaxRounds(Settings::toolsSettings().maxToolContinuations()); client->toolLoop()->setMaxRounds(Settings::toolsSettings().maxToolContinuations());
client->setTransferTimeout( client->setTransferTimeout(
static_cast<int>(Settings::generalSettings().requestTimeout() * 1000)); static_cast<int>(Settings::generalSettings().requestTimeout() * 1000));
const QString chatContext = buildChatContextLayer(); const QString chatContext = buildChatContextLayer();
if (!chatContext.isEmpty()) if (chatContext.isEmpty())
session->systemPrompt()->setLayer(QStringLiteral("chat.context"), chatContext); m_session->systemPrompt()->clearLayer(QStringLiteral("chat.context"));
else
m_session->systemPrompt()->setLayer(QStringLiteral("chat.context"), chatContext);
if (linkedFiles.isEmpty()) { if (linkedFiles.isEmpty()) {
session->unpinContext(QStringLiteral("chat.files")); m_session->unpinContext(QStringLiteral("chat.files"));
} else { } else {
session->pinContext( m_session->pinContext(
QStringLiteral("chat.files"), QStringLiteral("chat.files"),
[contextManager = QPointer<Context::ContextManager>(m_contextManager), [contextManager = QPointer<Context::ContextManager>(m_contextManager),
linkedFiles]() -> QString { linkedFiles]() -> QString {
@@ -265,29 +314,16 @@ void ClientInterface::sendMessage(
} }
} }
connect(session, &Session::event, this, [this, session](const QodeAssist::ResponseEvent &ev) { const LLMQore::RequestID requestId = m_session->send(std::move(blocks));
onSessionEvent(session, ev);
});
connect(
session, &Session::finished, this,
[this](const LLMQore::RequestID &id, const QString &) { onSessionFinished(id); });
connect(
session, &Session::failed, this,
[this](const LLMQore::RequestID &id, const QodeAssist::ErrorInfo &error) {
onSessionFailed(id, error);
});
const LLMQore::RequestID requestId = session->send(std::move(blocks));
if (requestId.isEmpty()) { if (requestId.isEmpty()) {
const QString error = QStringLiteral("Failed to start chat request for agent '%1': %2") const QString error = QStringLiteral("Failed to start chat request for agent '%1': %2")
.arg(m_activeAgent, session->lastError().message); .arg(m_activeAgent, m_session->lastError().message);
LOG_MESSAGE(error); LOG_MESSAGE(error);
m_sessionManager->removeSession(session);
emit errorOccurred(error); emit errorOccurred(error);
return; return;
} }
m_activeRequests[requestId] = {QJsonObject{{"id", requestId}}, session}; m_activeRequests[requestId] = {QJsonObject{{"id", requestId}}, m_session};
emit requestStarted(requestId); emit requestStarted(requestId);
} }
@@ -337,8 +373,6 @@ void ClientInterface::onSessionFinished(const QString &requestId)
if (it == m_activeRequests.end()) if (it == m_activeRequests.end())
return; return;
Session *session = it.value().session;
QString applyError; QString applyError;
if (!Context::ChangesManager::instance().applyPendingEditsForRequest(requestId, &applyError)) { if (!Context::ChangesManager::instance().applyPendingEditsForRequest(requestId, &applyError)) {
LOG_MESSAGE(QString("Some edits for request %1 were not auto-applied: %2") LOG_MESSAGE(QString("Some edits for request %1 were not auto-applied: %2")
@@ -348,9 +382,6 @@ void ClientInterface::onSessionFinished(const QString &requestId)
emit messageReceivedCompletely(); emit messageReceivedCompletely();
m_activeRequests.erase(it); m_activeRequests.erase(it);
if (session && m_sessionManager)
m_sessionManager->removeSession(session);
} }
void ClientInterface::onSessionFailed(const QString &requestId, const QodeAssist::ErrorInfo &error) void ClientInterface::onSessionFailed(const QString &requestId, const QodeAssist::ErrorInfo &error)
@@ -359,15 +390,10 @@ void ClientInterface::onSessionFailed(const QString &requestId, const QodeAssist
if (it == m_activeRequests.end()) if (it == m_activeRequests.end())
return; return;
Session *session = it.value().session;
LOG_MESSAGE(QString("Chat request %1 failed: %2").arg(requestId, error.message)); LOG_MESSAGE(QString("Chat request %1 failed: %2").arg(requestId, error.message));
emit errorOccurred(error.message); emit errorOccurred(error.message);
m_activeRequests.erase(it); m_activeRequests.erase(it);
if (session && m_sessionManager)
m_sessionManager->removeSession(session);
} }
QStringList ClientInterface::invokedSkillNames(const QString &message) const QStringList ClientInterface::invokedSkillNames(const QString &message) const
@@ -419,20 +445,18 @@ QString ClientInterface::buildChatContextLayer() const
void ClientInterface::clearMessages() void ClientInterface::clearMessages()
{ {
if (m_session)
m_session->cancel();
m_activeRequests.clear();
if (m_history) if (m_history)
m_history->clear(); m_history->clear();
} }
void ClientInterface::cancelRequest() void ClientInterface::cancelRequest()
{ {
const auto requests = m_activeRequests;
m_activeRequests.clear(); m_activeRequests.clear();
if (m_session)
for (auto it = requests.begin(); it != requests.end(); ++it) { m_session->cancel();
Session *session = it.value().session;
if (session && m_sessionManager)
m_sessionManager->removeSession(session);
}
LOG_MESSAGE("All chat requests cancelled and state cleared"); LOG_MESSAGE("All chat requests cancelled and state cleared");
} }

View File

@@ -55,6 +55,9 @@ public:
void setChatFilePath(const QString &filePath); void setChatFilePath(const QString &filePath);
QString chatFilePath() const; QString chatFilePath() const;
void ensureSession();
Session *session() const;
signals: signals:
void errorOccurred(const QString &error); void errorOccurred(const QString &error);
void messageReceivedCompletely(); void messageReceivedCompletely();
@@ -63,6 +66,8 @@ signals:
int promptTokens, int completionTokens, int cachedPromptTokens, int reasoningTokens); int promptTokens, int completionTokens, int cachedPromptTokens, int reasoningTokens);
private: private:
bool ensureAgentBound();
void onSessionEvent(Session *session, const QodeAssist::ResponseEvent &ev); void onSessionEvent(Session *session, const QodeAssist::ResponseEvent &ev);
void onSessionFinished(const QString &requestId); void onSessionFinished(const QString &requestId);
void onSessionFailed(const QString &requestId, const QodeAssist::ErrorInfo &error); void onSessionFailed(const QString &requestId, const QodeAssist::ErrorInfo &error);
@@ -85,7 +90,9 @@ private:
QPointer<ConversationHistory> m_history; QPointer<ConversationHistory> m_history;
Skills::SkillsManager *m_skillsManager = nullptr; Skills::SkillsManager *m_skillsManager = nullptr;
QPointer<SessionManager> m_sessionManager; QPointer<SessionManager> m_sessionManager;
QPointer<Session> m_session;
QString m_activeAgent; QString m_activeAgent;
QString m_boundAgent;
QString m_chatFilePath; QString m_chatFilePath;
std::shared_ptr<StoredContentCache> m_contentCache; std::shared_ptr<StoredContentCache> m_contentCache;

View File

@@ -8,29 +8,43 @@
#include <QFileInfo> #include <QFileInfo>
#include <Session.hpp>
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
SessionFileRegistry::SessionFileRegistry(QObject *parent) SessionFileRegistry::SessionFileRegistry(QObject *parent)
: QObject(parent) : QObject(parent)
{} {}
SessionFileRegistry::~SessionFileRegistry() = default;
bool SessionFileRegistry::isLocked(const QString &path) const bool SessionFileRegistry::isLocked(const QString &path) const
{ {
return !path.isEmpty() && m_lockedPaths.contains(path); return !path.isEmpty() && !m_locks.value(path).isNull();
} }
bool SessionFileRegistry::lock(const QString &path) bool SessionFileRegistry::isLockedByOther(const QString &path, QodeAssist::Session *self) const
{ {
if (path.isEmpty() || m_lockedPaths.contains(path)) { if (path.isEmpty())
return false; return false;
} const auto owner = m_locks.value(path);
m_lockedPaths.insert(path); return !owner.isNull() && owner != self;
}
bool SessionFileRegistry::lock(const QString &path, QodeAssist::Session *owner)
{
if (path.isEmpty())
return false;
const auto existing = m_locks.value(path);
if (!existing.isNull() && existing != owner)
return false;
m_locks.insert(path, owner);
return true; return true;
} }
void SessionFileRegistry::release(const QString &path) void SessionFileRegistry::release(const QString &path)
{ {
m_lockedPaths.remove(path); m_locks.remove(path);
} }
void SessionFileRegistry::setPendingChatFile(const QString &path) void SessionFileRegistry::setPendingChatFile(const QString &path)
@@ -45,7 +59,7 @@ QString SessionFileRegistry::takePendingChatFile()
QString SessionFileRegistry::uniqueFreePath(const QString &desiredPath) const QString SessionFileRegistry::uniqueFreePath(const QString &desiredPath) const
{ {
if (desiredPath.isEmpty() || !m_lockedPaths.contains(desiredPath)) { if (desiredPath.isEmpty() || !isLocked(desiredPath)) {
return desiredPath; return desiredPath;
} }
@@ -59,7 +73,7 @@ QString SessionFileRegistry::uniqueFreePath(const QString &desiredPath) const
if (!suffix.isEmpty()) { if (!suffix.isEmpty()) {
candidate += '.' + suffix; candidate += '.' + suffix;
} }
if (!m_lockedPaths.contains(candidate)) { if (!isLocked(candidate)) {
return candidate; return candidate;
} }
} }

View File

@@ -4,24 +4,31 @@
#pragma once #pragma once
#include <QHash>
#include <QObject> #include <QObject>
#include <QSet> #include <QPointer>
#include <QString> #include <QString>
namespace QodeAssist {
class Session;
}
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
// Shared registry of chat session (autosave) file paths that are currently held by a live // Shared registry mapping each chat (autosave) file to the live Session that owns it, so a
// chat instance. Lets every chat view — bottom pane, navigation panel, editor split — claim // file is busy only while its owning Session is alive (a destroyed Session frees it — the
// a unique history file so two sessions never autosave into the same path. // QPointer goes null). Keeps two chat views from autosaving into the same path.
class SessionFileRegistry : public QObject class SessionFileRegistry : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SessionFileRegistry(QObject *parent = nullptr); explicit SessionFileRegistry(QObject *parent = nullptr);
~SessionFileRegistry() override;
bool isLocked(const QString &path) const; bool isLocked(const QString &path) const;
bool lock(const QString &path); bool isLockedByOther(const QString &path, QodeAssist::Session *self) const;
bool lock(const QString &path, QodeAssist::Session *owner);
void release(const QString &path); void release(const QString &path);
QString uniqueFreePath(const QString &desiredPath) const; QString uniqueFreePath(const QString &desiredPath) const;
@@ -32,7 +39,7 @@ public:
QString takePendingChatFile(); QString takePendingChatFile();
private: private:
QSet<QString> m_lockedPaths; QHash<QString, QPointer<QodeAssist::Session>> m_locks;
QString m_pendingChatFile; QString m_pendingChatFile;
}; };

View File

@@ -33,14 +33,33 @@ Session::Session(Agent *agent, QObject *parent)
Session::Session(Agent *agent, ConversationHistory *externalHistory, QObject *parent) Session::Session(Agent *agent, ConversationHistory *externalHistory, QObject *parent)
: QObject(parent) : QObject(parent)
, m_agent(agent)
, m_history(externalHistory ? externalHistory : new ConversationHistory(this)) , m_history(externalHistory ? externalHistory : new ConversationHistory(this))
, m_systemPrompt(new SystemPromptBuilder(this)) , m_systemPrompt(new SystemPromptBuilder(this))
{ {
if (!m_agent) { if (agent)
m_invalidReason = QStringLiteral("Session: agent is null"); setAgent(agent);
}
void Session::setAgent(Agent *agent)
{
if (agent == m_agent)
return; return;
if (isInFlight())
teardownInFlight();
if (m_router) {
delete m_router;
m_router = nullptr;
} }
delete m_agent;
m_agent = agent;
m_invalidReason.clear();
if (!m_agent)
return;
m_agent->setParent(this); m_agent->setParent(this);
if (!m_agent->isValid()) { if (!m_agent->isValid()) {
@@ -55,8 +74,7 @@ Session::Session(Agent *agent, ConversationHistory *externalHistory, QObject *pa
return; return;
} }
if (!m_agent->promptTemplate()) { if (!m_agent->promptTemplate()) {
m_invalidReason m_invalidReason = QStringLiteral("Session: agent has no inline prompt template");
= QStringLiteral("Session: agent has no inline prompt template");
return; return;
} }
@@ -85,6 +103,16 @@ bool Session::isInFlight() const noexcept
return !m_inFlight.isEmpty(); return !m_inFlight.isEmpty();
} }
bool Session::hasAgent() const noexcept
{
return m_agent != nullptr;
}
bool Session::canSend() const noexcept
{
return isValid() && m_agent != nullptr && client() != nullptr;
}
const ErrorInfo &Session::lastError() const noexcept const ErrorInfo &Session::lastError() const noexcept
{ {
return m_lastError; return m_lastError;
@@ -128,8 +156,12 @@ void Session::unpinContext(const QString &id)
LLMQore::RequestID Session::send(std::vector<std::unique_ptr<LLMQore::ContentBlock>> userBlocks) LLMQore::RequestID Session::send(std::vector<std::unique_ptr<LLMQore::ContentBlock>> userBlocks)
{ {
if (!isValid()) { if (!canSend()) {
m_lastError = makeError(ErrorCategory::Config, invalidReason()); const QString reason = m_agent ? (invalidReason().isEmpty()
? QStringLiteral("Session: agent has no live client")
: invalidReason())
: QStringLiteral("Session: no agent bound");
m_lastError = makeError(ErrorCategory::Config, reason);
return {}; return {};
} }
if (userBlocks.empty() || !m_history) { if (userBlocks.empty() || !m_history) {

View File

@@ -46,6 +46,8 @@ public:
bool isValid() const noexcept; bool isValid() const noexcept;
QString invalidReason() const; QString invalidReason() const;
bool isInFlight() const noexcept; bool isInFlight() const noexcept;
bool hasAgent() const noexcept;
bool canSend() const noexcept;
const ErrorInfo &lastError() const noexcept; const ErrorInfo &lastError() const noexcept;
using ContentLoader = ContextAssembler::ContentLoader; using ContentLoader = ContextAssembler::ContentLoader;
@@ -56,6 +58,7 @@ public:
void unpinContext(const QString &id); void unpinContext(const QString &id);
Agent *agent() noexcept { return m_agent; } Agent *agent() noexcept { return m_agent; }
void setAgent(Agent *agent);
ConversationHistory *history() const noexcept { return m_history; } ConversationHistory *history() const noexcept { return m_history; }
SystemPromptBuilder *systemPrompt() const noexcept { return m_systemPrompt; } SystemPromptBuilder *systemPrompt() const noexcept { return m_systemPrompt; }

View File

@@ -59,6 +59,43 @@ Session *SessionManager::createSession(
return session; return session;
} }
Session *SessionManager::createDetachedSession(ConversationHistory *externalHistory, QObject *parent)
{
return new Session(/*agent=*/nullptr, externalHistory, parent);
}
bool SessionManager::rebindAgentByName(Session *session, const QString &agentName, QString *errorOut)
{
if (!session) {
if (errorOut)
*errorOut = QStringLiteral("SessionManager: null session");
return false;
}
if (!m_agentFactory) {
if (errorOut)
*errorOut = QStringLiteral("SessionManager: no AgentFactory bound");
return false;
}
QString agentErr;
Agent *agent = m_agentFactory->create(agentName, /*parent=*/nullptr, &agentErr);
if (!agent) {
if (errorOut)
*errorOut = agentErr.isEmpty()
? QStringLiteral("SessionManager: agent '%1' not found").arg(agentName)
: agentErr;
return false;
}
session->setAgent(agent);
if (!session->isValid()) {
if (errorOut)
*errorOut = session->invalidReason();
return false;
}
return true;
}
Session *SessionManager::acquire(const QString &agentName, QString *errorOut) Session *SessionManager::acquire(const QString &agentName, QString *errorOut)
{ {
auto &bucket = m_pool[agentName]; auto &bucket = m_pool[agentName];

View File

@@ -34,6 +34,10 @@ public:
ConversationHistory *externalHistory, ConversationHistory *externalHistory,
QString *errorOut = nullptr); QString *errorOut = nullptr);
Session *createDetachedSession(ConversationHistory *externalHistory, QObject *parent);
bool rebindAgentByName(Session *session, const QString &agentName, QString *errorOut = nullptr);
Session *acquire(const QString &agentName, QString *errorOut = nullptr); Session *acquire(const QString &agentName, QString *errorOut = nullptr);
void release(Session *session); void release(Session *session);

View File

@@ -98,7 +98,7 @@ TEST(AgentLoaderTest, UserAgentCollidingWithBundledNameIsRejected)
const AgentConfig *cfg = findConfig(result, QStringLiteral("A")); const AgentConfig *cfg = findConfig(result, QStringLiteral("A"));
ASSERT_NE(cfg, nullptr); ASSERT_NE(cfg, nullptr);
EXPECT_EQ(cfg->description, QStringLiteral("base")); EXPECT_EQ(cfg->description, QStringLiteral("base"));
EXPECT_FALSE(cfg->isUserSource()); EXPECT_TRUE(cfg->sourcePath.startsWith(bundled.path()));
} }
TEST(AgentLoaderTest, HiddenIsNotInherited) TEST(AgentLoaderTest, HiddenIsNotInherited)

View File

@@ -370,7 +370,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext)
(QodeAssist::Templates::ContextData{ (QodeAssist::Templates::ContextData{
.prefix = "Line 0\nLine 1\nLin", .prefix = "Line 0\nLine 1\nLin",
.suffix = "e 2\nLine 3\nLine 4", .suffix = "e 2\nLine 3\nLine 4",
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" .fileContext = "\nFile information:\nMIME type: text/python\nFile path: /path/to/file\n\n"
"Recent Project Changes Context:\n "})); "Recent Project Changes Context:\n "}));
EXPECT_EQ( EXPECT_EQ(
@@ -378,7 +378,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext)
(QodeAssist::Templates::ContextData{ (QodeAssist::Templates::ContextData{
.prefix = "Line 1\nLin", .prefix = "Line 1\nLin",
.suffix = "e 2\nLine 3", .suffix = "e 2\nLine 3",
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" .fileContext = "\nFile information:\nMIME type: text/python\nFile path: /path/to/file\n\n"
"Recent Project Changes Context:\n "})); "Recent Project Changes Context:\n "}));
EXPECT_EQ( EXPECT_EQ(
@@ -386,7 +386,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext)
(QodeAssist::Templates::ContextData{ (QodeAssist::Templates::ContextData{
.prefix = "Line 0\nLine 1\nLin", .prefix = "Line 0\nLine 1\nLin",
.suffix = "e 2\nLine 3\nLine 4", .suffix = "e 2\nLine 3\nLine 4",
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" .fileContext = "\nFile information:\nMIME type: text/python\nFile path: /path/to/file\n\n"
"Recent Project Changes Context:\n "})); "Recent Project Changes Context:\n "}));
} }