Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for output rendering #690

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
pyenv global system
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_GCOV=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 ..
cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_GCOV=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DENABLE_TESTS=ON ..
cmake --build . --target bindings -- VERBOSE=1
cmake --build . -- VERBOSE=1
- run:
Expand All @@ -37,3 +37,5 @@ jobs:
- run:
name: Upload coverage report to codecov
command: bash <(curl -s https://codecov.io/bash) -f coverage.info
- store_test_results:
path: build/test_shellwidget_output/
8 changes: 8 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ jobs:
macdeployqt ./build/bin/nvim-qt.app -dmg
mv ./build/bin/nvim-qt.dmg neovim-qt.dmg

- name: Upload Test Artifacts
uses: actions/upload-artifact@v2
if: always()
with:
name: ${{ matrix.name }}_testoutput
path: |
build/test_shellwidget_output/
- name: Upload Artifacts
if: ${{ matrix.publish }}
uses: actions/upload-artifact@v2
Expand All @@ -129,3 +136,4 @@ jobs:
neovim-qt.dmg
neovim-qt-installer.msi
neovim-qt.zip

5 changes: 5 additions & 0 deletions src/gui/shellwidget/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ if (WIN32 AND USE_STATIC_QT)
add_definitions(-DUSE_STATIC_QT)
endif ()

add_definitions(-DCMAKE_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\")

# Define shell2.txt location for bench_paint
file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR} TEST_SOURCE_DIR)
add_definitions(-DTEST_SOURCE_DIR="${TEST_SOURCE_DIR}")
Expand All @@ -14,6 +16,9 @@ function(add_xtest SOURCE_NAME)
add_test(NAME ${SOURCE_NAME} COMMAND ${SOURCE_NAME} ${CTEST_EXE_ARGS})
endfunction()

file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR} TEST_SOURCE_DIR)
add_definitions(-DTEST_SOURCE_DIR="${TEST_SOURCE_DIR}")

add_xtest(test_cell)
add_xtest(test_shellcontents)
add_xtest(test_shellwidget)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions src/gui/shellwidget/test/test_shellwidget.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <QFontDatabase>
#include <QtTest/QtTest>
#include <QPainter>
#include "shellwidget.h"

#if defined(Q_OS_WIN) && defined(USE_STATIC_QT)
Expand All @@ -14,9 +16,52 @@ private slots:
void clearRegion();
void fontDescriptionFromQFont();
void fontDescriptionToQFont();
void render();
private:
QString outputFolderPath();
QString outputFilePath(const QString& name);
QString originalFilePath(const QString& name);
void saveWidgetOutput(ShellWidget& w, QString name);
void diffWidgetOutput(QString name);

private slots:
void initTestCase() noexcept;
};


void Test::initTestCase() noexcept
{
const QStringList fonts{
QStringLiteral("third-party/DejaVuSansMono.ttf"),
QStringLiteral("third-party/DejaVuSansMono-Bold.ttf"),
QStringLiteral("third-party/DejaVuSansMono-BoldOblique.ttf") };

for (const auto& path : fonts) {
QString abs_path_to_font(CMAKE_SOURCE_DIR);
abs_path_to_font.append("/").append(path);
QFontDatabase::addApplicationFont(abs_path_to_font);
}
}

QString Test::outputFolderPath()
{
auto folderName = "test_shellwidget_output";
QDir().mkpath(folderName);
return folderName;
}

/// Render Output file path to save a file
QString Test::outputFilePath(const QString& name)
{
return QDir(outputFolderPath()).filePath(name);
}

/// Previous output from rendering, from the source test folder
QString Test::originalFilePath(const QString& name)
{
return QDir(QDir(TEST_SOURCE_DIR).filePath("renderoutput")).filePath(name);
}

void Test::clearRegion()
{
ShellWidget *w = new ShellWidget();
Expand Down Expand Up @@ -126,5 +171,90 @@ void Test::fontDescriptionToQFont()
QCOMPARE(varInvalidHeight, QVariant{ QString{ "Invalid font height" } });
}

void Test::saveWidgetOutput(ShellWidget& w, QString name)
{
QImage img(w.size(), QImage::Format_ARGB32);
QPainter painter(&img);
w.render(&painter);
QCOMPARE(img.save(outputFilePath(name)), true);
}

void Test::diffWidgetOutput(QString name)
{
auto p1 = outputFilePath(name);
auto output = QImage(p1);
qDebug() << "Loading" << p1 << output;
auto p2 = originalFilePath(name);
auto expected = QImage(p2);
qDebug() << "Loading" << p2 << expected;

QCOMPARE(output.isNull(), false);
QCOMPARE(expected.isNull(), false);

QImage diff(output.size(), QImage::Format_RGB32);
diff.fill(Qt::white);

bool failed = (output.width() != expected.width()) || (output.height() != expected.height());
if (failed) {
qWarning() << "Output dimensions do not match";
}

for (int y=0; y < output.height(); y++) {
for (int x=0; x < output.width(); x++) {
auto outputColor = output.pixel(x, y);
auto expectedColor = expected.pixel(x, y);

if (outputColor != expectedColor) {
//qWarning() << "Pixel color mismatch at position " << x << y;
//qWarning() << " output:" << outputColor << "expected:" << expectedColor;
diff.setPixel(x, y, Qt::red);
failed = true;
}
}
}

auto outpath = outputFilePath("diff_" + name);
qDebug() << "Saving diff" << outpath;


auto platform = QGuiApplication::platformName();
if (platform != "xcb") {
auto msg = QString("Skipping render test in non X11: %1")
.arg(platform);
QSKIP(qPrintable(msg));
}

QCOMPARE(diff.save(outpath), true);

QCOMPARE(output.width(), expected.width());
QCOMPARE(output.height(), expected.height());

if (failed) {
qWarning() << platform << " - Failing diff, check the output diff image" << outpath;
QCOMPARE(failed, false);
}
}

/// This is mostly an example it renders a shell widget and saves it as an image.
/// For more complicated tests we may want to parametrize these.
void Test::render()
{
ShellWidget w;
w.setShellFont(QFont("DejaVu Sans Mono", 11, QFont::Weight::Normal, false));
w.resizeShell(20, 20);
w.show();

w.put("hello", 2, 2, HighlightAttribute());
w.put("fffffff", 3, 3, HighlightAttribute(Qt::red, Qt::black, Qt::white, false, false, false, false, false, false));
w.put("italic text", 4, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, true, false, false, false, false));
w.put("bold text", 5, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, false, true, false, false, false));
w.put("underline text", 6, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, false, false, true, false, false));
w.put("undercurl text", 7, 3, HighlightAttribute(Qt::white, Qt::black, Qt::red, false, false, false, false, true, false));

auto name = "shellwidget_render_works.png";
saveWidgetOutput(w, name);
diffWidgetOutput(name);
}

QTEST_MAIN(Test)
#include "test_shellwidget.moc"
Loading