chore: Add unit tests for DocumentContextReader (#90)

chore: Add unit tests for DocumentContextReader

The tests are based on GTest like some tests in Qt Creator itself, which
makes it easy to run as full Qt Creator does not need to be started.
This commit is contained in:
Povilas Kanapickas 2025-03-05 16:01:52 +02:00 committed by GitHub
parent bcf7b6c226
commit 247256d4a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 239 additions and 2 deletions

View File

@ -70,7 +70,7 @@ jobs:
cmakeVersion: ${{ env.CMAKE_VERSION }}
ninjaVersion: ${{ env.NINJA_VERSION }}
- name: Install system libs
- name: Install dependencies
shell: cmake -P {0}
run: |
if ("${{ runner.os }}" STREQUAL "Linux")
@ -78,7 +78,13 @@ jobs:
COMMAND sudo apt update
)
execute_process(
COMMAND sudo apt install libgl1-mesa-dev
COMMAND sudo apt install
# build dependencies
libgl1-mesa-dev libgtest-dev
# runtime dependencies for tests (Qt is downloaded outside package manager,
# thus minimal dependencies must be installed explicitly)
libsecret-1-0 libxcb-cursor0 libxcb-icccm4 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-render0
libxcb-shape0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxcb-xkb1 libxkbcommon-x11-0 xvfb
RESULT_VARIABLE result
)
if (NOT result EQUAL 0)
@ -258,6 +264,11 @@ jobs:
name: ${{ env.PLUGIN_NAME }}-origin-json
path: ./build/build/${{ env.PLUGIN_NAME }}.json
- name: Run unit tests
if: matrix.config.os == 'ubuntu-latest'
run: |
xvfb-run ./build/build/test/QodeAssistTest
update_json:
if: contains(github.ref, 'tags/v')
runs-on: ubuntu-latest

View File

@ -12,6 +12,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(QtCreator REQUIRED COMPONENTS Core)
find_package(Qt6 COMPONENTS Core Gui Quick Widgets Network REQUIRED)
find_package(GTest)
add_definitions(
-DQODEASSIST_QT_CREATOR_VERSION_MAJOR=${QODEASSIST_QT_CREATOR_VERSION_MAJOR}
@ -24,6 +25,9 @@ add_subdirectory(settings)
add_subdirectory(logger)
add_subdirectory(ChatView)
add_subdirectory(context)
if(GTest_FOUND)
add_subdirectory(test)
endif()
add_qtc_plugin(QodeAssist
PLUGIN_DEPENDS

14
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
add_executable(QodeAssistTest
DocumentContextReaderTest.cpp
unittest_main.cpp
)
target_link_libraries(QodeAssistTest PRIVATE
Qt::Core
GTest::GTest
GTest::Main
QtCreator::LanguageClient
Context
)
add_test(NAME QodeAssistTest COMMAND QodeAssistTest)

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2025 Povilas Kanapickas
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context/DocumentContextReader.hpp"
#include <gtest/gtest.h>
#include <QTextDocument>
using namespace QodeAssist::Context;
std::ostream &operator<<(std::ostream &out, const QString &value)
{
out << value.toStdString();
return out;
}
class DocumentContextReaderTest : public QObject, public testing::Test
{
Q_OBJECT
protected:
QTextDocument *createTestDocument(const QString &text)
{
auto *doc = new QTextDocument(this);
doc->setPlainText(text);
return doc;
}
DocumentContextReader createTestReader(const QString &text)
{
return DocumentContextReader(createTestDocument(text), "text/python", "/path/to/file");
}
};
TEST_F(DocumentContextReaderTest, testGetLineText)
{
auto reader = createTestReader("Line 1\nLine 2\nLine 3");
EXPECT_EQ(reader.getLineText(0), "Line 1");
EXPECT_EQ(reader.getLineText(1), "Line 2");
EXPECT_EQ(reader.getLineText(2), "Line 3");
EXPECT_EQ(reader.getLineText(0, 4), "Line");
}
TEST_F(DocumentContextReaderTest, testGetContextBefore)
{
auto reader = createTestReader("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
EXPECT_EQ(reader.getContextBefore(2, -1, 2), "Line 1\nLine 2\nLine 3");
EXPECT_EQ(reader.getContextBefore(4, -1, 3), "Line 2\nLine 3\nLine 4\nLine 5");
}
TEST_F(DocumentContextReaderTest, testGetContextAfter)
{
auto reader = createTestReader("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
EXPECT_EQ(reader.getContextAfter(0, -1, 2), "Line 2\nLine 3");
EXPECT_EQ(reader.getContextAfter(2, -1, 2), "Line 4\nLine 5");
}
TEST_F(DocumentContextReaderTest, testGetContextBeforeWithCopyright)
{
auto reader = createTestReader("/* Copyright (C) 2024 */\nLine 1\nLine 2\nLine 3\nLine 4");
// Test getting context before with copyright header
EXPECT_EQ(reader.getContextBefore(2, -1, 2), "Line 1\nLine 2");
// Test getting context before skipping copyright
EXPECT_EQ(reader.getContextBefore(3, 0, 2), "Line 1\nLine 2\n");
}
TEST_F(DocumentContextReaderTest, testGetContextAfterWithCopyright)
{
auto reader = createTestReader("/* Copyright (C) 2024 */\nLine 1\nLine 2\nLine 3\nLine 4");
// Test getting context after copyright header
EXPECT_EQ(reader.getContextAfter(0, -1, 2), "Line 1\nLine 2");
// Test getting context after with copyright skipped
EXPECT_EQ(reader.getContextAfter(1, 0, 2), "Line 2\n");
}
TEST_F(DocumentContextReaderTest, testReadWholeFile)
{
auto reader = createTestReader("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
EXPECT_EQ(reader.readWholeFileBefore(2, -1), "Line 1\nLine 2\nLine 3");
EXPECT_EQ(reader.readWholeFileAfter(2, -1), "Line 3\nLine 4\nLine 5");
}
TEST_F(DocumentContextReaderTest, testReadWholeFileWithCopyright)
{
auto reader = createTestReader("/* Copyright (C) 2024 */\nLine 1\nLine 2\nLine 3\nLine 4");
EXPECT_EQ(reader.readWholeFileBefore(2, -1), "Line 1\nLine 2");
EXPECT_EQ(reader.readWholeFileAfter(2, -1), "Line 2\nLine 3\nLine 4");
EXPECT_EQ(reader.readWholeFileBefore(2, 0), "Line 1\n");
EXPECT_EQ(reader.readWholeFileAfter(2, 0), "Line 2\nLine 3\n");
}
TEST_F(DocumentContextReaderTest, testReadWholeFileWithMultilineCopyright)
{
auto reader = createTestReader(
"/*\n * Copyright (C) 2024\n * \n * This file is part of QodeAssist.\n */\n"
"Line 1\nLine 2");
EXPECT_EQ(reader.readWholeFileBefore(6, -1), "Line 1\nLine 2");
EXPECT_EQ(reader.readWholeFileAfter(5, -1), "Line 1\nLine 2");
EXPECT_EQ(reader.readWholeFileBefore(6, 4), "Line 1\nLine");
EXPECT_EQ(reader.readWholeFileAfter(5, 4), "Line 1\nLine");
}
TEST_F(DocumentContextReaderTest, testFindCopyrightSingleLine)
{
auto reader = createTestReader("/* Copyright (C) 2024 */\nCode line 1\nCode line 2");
auto info = reader.findCopyright();
ASSERT_TRUE(info.found);
EXPECT_EQ(info.startLine, 0);
EXPECT_EQ(info.endLine, 0);
}
TEST_F(DocumentContextReaderTest, testFindCopyrightMultiLine)
{
auto reader = createTestReader(
"/*\n * Copyright (C) 2024\n * \n * This file is part of QodeAssist.\n */\nCode line 1");
auto info = reader.findCopyright();
ASSERT_TRUE(info.found);
EXPECT_EQ(info.startLine, 0);
EXPECT_EQ(info.endLine, 4);
}
TEST_F(DocumentContextReaderTest, testFindCopyrightMultipleBlocks)
{
auto reader = createTestReader("/* Copyright 2023 */\n\n/* Copyright 2024 */\nCode");
auto info = reader.findCopyright();
ASSERT_TRUE(info.found);
EXPECT_EQ(info.startLine, 0);
EXPECT_EQ(info.endLine, 0);
}
TEST_F(DocumentContextReaderTest, testFindCopyrightNoCopyright)
{
auto reader = createTestReader("/* Just a comment */\nCode line 1");
auto info = reader.findCopyright();
ASSERT_TRUE(!info.found);
EXPECT_EQ(info.startLine, -1);
EXPECT_EQ(info.endLine, -1);
}
TEST_F(DocumentContextReaderTest, testGetContextBetween)
{
auto reader = createTestReader("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
EXPECT_EQ(reader.getContextBetween(1, 3, -1), "Line 2\nLine 3\nLine 4");
EXPECT_EQ(reader.getContextBetween(0, 2, 4), "Line 1\nLine 2\nLine");
}
#include "DocumentContextReaderTest.moc"

28
test/unittest_main.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 Povilas Kanapickas
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include <QGuiApplication>
int main(int argc, char *argv[])
{
QGuiApplication application(argc, argv);
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}