mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-05-28 03:10:28 -04:00
refactor: Make DocumentContextReader::prepareContext() testable (#96)
This commit is contained in:
parent
e218699e64
commit
69a8aa80d9
@ -267,7 +267,7 @@ LLMCore::ContextData LLMClientInterface::prepareContext(
|
|||||||
|
|
||||||
Context::DocumentContextReader reader(
|
Context::DocumentContextReader reader(
|
||||||
textDocument->document(), textDocument->mimeType(), textDocument->filePath().toString());
|
textDocument->document(), textDocument->mimeType(), textDocument->filePath().toString());
|
||||||
return reader.prepareContext(lineNumber, cursorPosition);
|
return reader.prepareContext(lineNumber, cursorPosition, Settings::codeCompletionSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLMClientInterface::sendCompletionToClient(
|
void LLMClientInterface::sendCompletionToClient(
|
||||||
|
@ -244,39 +244,29 @@ CopyrightInfo DocumentContextReader::copyrightInfo() const
|
|||||||
return m_copyrightInfo;
|
return m_copyrightInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLMCore::ContextData DocumentContextReader::prepareContext(int lineNumber, int cursorPosition) const
|
LLMCore::ContextData DocumentContextReader::prepareContext(
|
||||||
|
int lineNumber, int cursorPosition, const Settings::CodeCompletionSettings &settings) const
|
||||||
{
|
{
|
||||||
QString contextBefore = getContextBefore(lineNumber, cursorPosition);
|
QString contextBefore;
|
||||||
QString contextAfter = getContextAfter(lineNumber, cursorPosition);
|
QString contextAfter;
|
||||||
|
if (settings.readFullFile()) {
|
||||||
|
contextBefore = readWholeFileBefore(lineNumber, cursorPosition);
|
||||||
|
contextAfter = readWholeFileAfter(lineNumber, cursorPosition);
|
||||||
|
} else {
|
||||||
|
contextBefore
|
||||||
|
= getContextBefore(lineNumber, cursorPosition, settings.readStringsBeforeCursor());
|
||||||
|
contextAfter
|
||||||
|
= getContextAfter(lineNumber, cursorPosition, settings.readStringsAfterCursor());
|
||||||
|
}
|
||||||
|
|
||||||
QString fileContext;
|
QString fileContext;
|
||||||
fileContext.append("\n ").append(getLanguageAndFileInfo());
|
fileContext.append("\n ").append(getLanguageAndFileInfo());
|
||||||
|
|
||||||
if (Settings::codeCompletionSettings().useProjectChangesCache())
|
if (settings.useProjectChangesCache())
|
||||||
fileContext.append("\n ").append(
|
fileContext.append("\n ").append(
|
||||||
ChangesManager::instance().getRecentChangesContext(m_textDocument));
|
ChangesManager::instance().getRecentChangesContext(m_textDocument));
|
||||||
|
|
||||||
return {.prefix = contextBefore, .suffix = contextAfter, .fileContext = fileContext};
|
return {.prefix = contextBefore, .suffix = contextAfter, .fileContext = fileContext};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DocumentContextReader::getContextBefore(int lineNumber, int cursorPosition) const
|
|
||||||
{
|
|
||||||
if (Settings::codeCompletionSettings().readFullFile()) {
|
|
||||||
return readWholeFileBefore(lineNumber, cursorPosition);
|
|
||||||
} else {
|
|
||||||
int linesCount = Settings::codeCompletionSettings().readStringsBeforeCursor();
|
|
||||||
return getContextBefore(lineNumber, cursorPosition, linesCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DocumentContextReader::getContextAfter(int lineNumber, int cursorPosition) const
|
|
||||||
{
|
|
||||||
if (Settings::codeCompletionSettings().readFullFile()) {
|
|
||||||
return readWholeFileAfter(lineNumber, cursorPosition);
|
|
||||||
} else {
|
|
||||||
int linesCount = Settings::codeCompletionSettings().readStringsAfterCursor();
|
|
||||||
return getContextAfter(lineNumber, cursorPosition, linesCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace QodeAssist::Context
|
} // namespace QodeAssist::Context
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
#include <llmcore/ContextData.hpp>
|
#include <llmcore/ContextData.hpp>
|
||||||
|
#include <settings/CodeCompletionSettings.hpp>
|
||||||
|
|
||||||
namespace QodeAssist::Context {
|
namespace QodeAssist::Context {
|
||||||
|
|
||||||
@ -72,11 +73,8 @@ public:
|
|||||||
|
|
||||||
CopyrightInfo copyrightInfo() const;
|
CopyrightInfo copyrightInfo() const;
|
||||||
|
|
||||||
LLMCore::ContextData prepareContext(int lineNumber, int cursorPosition) const;
|
LLMCore::ContextData prepareContext(
|
||||||
|
int lineNumber, int cursorPosition, const Settings::CodeCompletionSettings &settings) const;
|
||||||
private:
|
|
||||||
QString getContextBefore(int lineNumber, int cursorPosition) const;
|
|
||||||
QString getContextAfter(int lineNumber, int cursorPosition) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextEditor::TextDocument *m_textDocument;
|
TextEditor::TextDocument *m_textDocument;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2024 Petr Mironychev
|
* Copyright (C) 2024 Petr Mironychev
|
||||||
*
|
*
|
||||||
* This file is part of QodeAssist.
|
* This file is part of QodeAssist.
|
||||||
@ -28,6 +28,10 @@ struct Message
|
|||||||
{
|
{
|
||||||
QString role;
|
QString role;
|
||||||
QString content;
|
QString content;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
auto operator<=>(const Message&) const = default;
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContextData
|
struct ContextData
|
||||||
@ -37,6 +41,8 @@ struct ContextData
|
|||||||
std::optional<QString> suffix;
|
std::optional<QString> suffix;
|
||||||
std::optional<QString> fileContext;
|
std::optional<QString> fileContext;
|
||||||
std::optional<QVector<Message>> history;
|
std::optional<QVector<Message>> history;
|
||||||
|
|
||||||
|
bool operator==(const ContextData &) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::LLMCore
|
} // namespace QodeAssist::LLMCore
|
||||||
|
@ -20,16 +20,59 @@
|
|||||||
#include "context/DocumentContextReader.hpp"
|
#include "context/DocumentContextReader.hpp"
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
using namespace QodeAssist::Context;
|
using namespace QodeAssist::Context;
|
||||||
|
using namespace QodeAssist::LLMCore;
|
||||||
|
using namespace QodeAssist::Settings;
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const QString &value)
|
std::ostream &operator<<(std::ostream &out, const QString &value)
|
||||||
{
|
{
|
||||||
out << value.toStdString();
|
out << '"' << value.toStdString() << '"';
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::ostream &operator<<(std::ostream &out, const QVector<T> &value)
|
||||||
|
{
|
||||||
|
out << "[";
|
||||||
|
for (const auto &el : value) {
|
||||||
|
out << value << ", ";
|
||||||
|
}
|
||||||
|
out << "]";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::ostream &operator<<(std::ostream &out, const std::optional<T> &value)
|
||||||
|
{
|
||||||
|
if (value.has_value()) {
|
||||||
|
out << value.value();
|
||||||
|
} else {
|
||||||
|
out << "(no value)";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QodeAssist::LLMCore {
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Message &value)
|
||||||
|
{
|
||||||
|
out << "Message{"
|
||||||
|
<< "role=" << value.role << "content=" << value.content << "}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ContextData &value)
|
||||||
|
{
|
||||||
|
out << "ContextData{"
|
||||||
|
<< "\n systemPrompt=" << value.systemPrompt << "\n prefix=" << value.prefix
|
||||||
|
<< "\n suffix=" << value.suffix << "\n fileContext=" << value.fileContext
|
||||||
|
<< "\n history=" << value.history << "\n}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
} // namespace QodeAssist::LLMCore
|
||||||
|
|
||||||
class DocumentContextReaderTest : public QObject, public testing::Test
|
class DocumentContextReaderTest : public QObject, public testing::Test
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -46,6 +89,24 @@ protected:
|
|||||||
{
|
{
|
||||||
return DocumentContextReader(createTestDocument(text), "text/python", "/path/to/file");
|
return DocumentContextReader(createTestDocument(text), "text/python", "/path/to/file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSharedPointer<CodeCompletionSettings> createSettingsForWholeFile()
|
||||||
|
{
|
||||||
|
// CodeCompletionSettings is noncopyable
|
||||||
|
auto settings = QSharedPointer<CodeCompletionSettings>::create();
|
||||||
|
settings->readFullFile.setValue(true);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<CodeCompletionSettings> createSettingsForLines(int linesBefore, int linesAfter)
|
||||||
|
{
|
||||||
|
// CodeCompletionSettings is noncopyable
|
||||||
|
auto settings = QSharedPointer<CodeCompletionSettings>::create();
|
||||||
|
settings->readFullFile.setValue(false);
|
||||||
|
settings->readStringsBeforeCursor.setValue(linesBefore);
|
||||||
|
settings->readStringsAfterCursor.setValue(linesAfter);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(DocumentContextReaderTest, testGetLineText)
|
TEST_F(DocumentContextReaderTest, testGetLineText)
|
||||||
@ -208,4 +269,30 @@ TEST_F(DocumentContextReaderTest, testGetContextBetween)
|
|||||||
EXPECT_EQ(reader.getContextBetween(1, 2, 3, 2), "ne 2\nLine 3\nLi");
|
EXPECT_EQ(reader.getContextBetween(1, 2, 3, 2), "ne 2\nLine 3\nLi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DocumentContextReaderTest, testPrepareContext)
|
||||||
|
{
|
||||||
|
auto reader = createTestReader("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
reader.prepareContext(2, 3, *createSettingsForWholeFile()),
|
||||||
|
(ContextData{
|
||||||
|
.prefix = "Line 1\nLine 2\nLin",
|
||||||
|
.suffix = "e 3\nLine 4\nLine 5",
|
||||||
|
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n\n "}));
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
reader.prepareContext(2, 3, *createSettingsForLines(1, 1)),
|
||||||
|
(ContextData{
|
||||||
|
.prefix = "Lin",
|
||||||
|
.suffix = "e 3",
|
||||||
|
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n\n "}));
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
reader.prepareContext(2, 3, *createSettingsForLines(2, 2)),
|
||||||
|
(ContextData{
|
||||||
|
.prefix = "Line 2\nLin",
|
||||||
|
.suffix = "e 3\nLine 4",
|
||||||
|
.fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n\n "}));
|
||||||
|
}
|
||||||
|
|
||||||
#include "DocumentContextReaderTest.moc"
|
#include "DocumentContextReaderTest.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user