Skip to content

Commit bd95f85

Browse files
author
equalsraf
committed
Add test for output rendering
For now this is mostly an example - but it seems useful to have the ability to test rendering output.
1 parent 1f73d63 commit bd95f85

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

.circleci/config.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,19 @@ jobs:
2323
pyenv global system
2424
mkdir build
2525
cd build
26-
cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_GCOV=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 ..
26+
cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_GCOV=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DENABLE_TESTS=ON ..
2727
cmake --build . --target bindings -- VERBOSE=1
2828
cmake --build . -- VERBOSE=1
2929
- run:
3030
name: test
3131
command: |
3232
cd build
33-
ctest -VV
33+
xvfb-run -a -e /dev/stdout ctest -VV
3434
- run:
3535
name: Generate coverage report with lcov
3636
command: lcov --directory . --capture --output-file coverage.info
3737
- run:
3838
name: Upload coverage report to codecov
3939
command: bash <(curl -s https://codecov.io/bash) -f coverage.info
40+
- store_test_results:
41+
path: build/test_shellwidget_output/

src/gui/shellwidget/test/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ if (WIN32 AND USE_STATIC_QT)
44
add_definitions(-DUSE_STATIC_QT)
55
endif ()
66

7+
add_definitions(-DCMAKE_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\")
8+
79
# Define shell2.txt location for bench_paint
810
file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR} TEST_SOURCE_DIR)
911
add_definitions(-DTEST_SOURCE_DIR="${TEST_SOURCE_DIR}")
@@ -14,6 +16,9 @@ function(add_xtest SOURCE_NAME)
1416
add_test(NAME ${SOURCE_NAME} COMMAND ${SOURCE_NAME} ${CTEST_EXE_ARGS})
1517
endfunction()
1618

19+
file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR} TEST_SOURCE_DIR)
20+
add_definitions(-DTEST_SOURCE_DIR="${TEST_SOURCE_DIR}")
21+
1722
add_xtest(test_cell)
1823
add_xtest(test_shellcontents)
1924
add_xtest(test_shellwidget)
2.36 KB
Loading

src/gui/shellwidget/test/test_shellwidget.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
#include <QFontDatabase>
12
#include <QtTest/QtTest>
3+
#include <QPainter>
24
#include "shellwidget.h"
35

46
#if defined(Q_OS_WIN) && defined(USE_STATIC_QT)
@@ -14,9 +16,52 @@ private slots:
1416
void clearRegion();
1517
void fontDescriptionFromQFont();
1618
void fontDescriptionToQFont();
19+
void render();
20+
private:
21+
QString outputFolderPath();
22+
QString outputFilePath(const QString& name);
23+
QString originalFilePath(const QString& name);
24+
void saveWidgetOutput(ShellWidget& w, QString name);
25+
void diffWidgetOutput(QString name);
26+
27+
private slots:
28+
void initTestCase() noexcept;
1729
};
1830

1931

32+
void Test::initTestCase() noexcept
33+
{
34+
const QStringList fonts{
35+
QStringLiteral("third-party/DejaVuSansMono.ttf"),
36+
QStringLiteral("third-party/DejaVuSansMono-Bold.ttf"),
37+
QStringLiteral("third-party/DejaVuSansMono-BoldOblique.ttf") };
38+
39+
for (const auto& path : fonts) {
40+
QString abs_path_to_font(CMAKE_SOURCE_DIR);
41+
abs_path_to_font.append("/").append(path);
42+
QFontDatabase::addApplicationFont(abs_path_to_font);
43+
}
44+
}
45+
46+
QString Test::outputFolderPath()
47+
{
48+
auto folderName = "test_shellwidget_output";
49+
QDir().mkpath(folderName);
50+
return folderName;
51+
}
52+
53+
/// Render Output file path to save a file
54+
QString Test::outputFilePath(const QString& name)
55+
{
56+
return QDir(outputFolderPath()).filePath(name);
57+
}
58+
59+
/// Previous output from rendering, from the source test folder
60+
QString Test::originalFilePath(const QString& name)
61+
{
62+
return QDir(QDir(TEST_SOURCE_DIR).filePath("renderoutput")).filePath(name);
63+
}
64+
2065
void Test::clearRegion()
2166
{
2267
ShellWidget *w = new ShellWidget();
@@ -126,5 +171,86 @@ void Test::fontDescriptionToQFont()
126171
QCOMPARE(varInvalidHeight, QVariant{ QString{ "Invalid font height" } });
127172
}
128173

174+
void Test::saveWidgetOutput(ShellWidget& w, QString name)
175+
{
176+
QImage img(w.size(), QImage::Format_ARGB32);
177+
QPainter painter(&img);
178+
w.render(&painter);
179+
QCOMPARE(img.save(outputFilePath(name)), true);
180+
}
181+
182+
void Test::diffWidgetOutput(QString name)
183+
{
184+
auto p1 = outputFilePath(name);
185+
auto output = QImage(p1);
186+
qDebug() << "Loading" << p1 << output;
187+
auto p2 = originalFilePath(name);
188+
auto expected = QImage(p2);
189+
qDebug() << "Loading" << p2 << expected;
190+
191+
QCOMPARE(output.isNull(), false);
192+
QCOMPARE(expected.isNull(), false);
193+
194+
QImage diff(output.size(), QImage::Format_RGB32);
195+
diff.fill(Qt::white);
196+
197+
bool failed = false;
198+
199+
for (int y=0; y < output.height(); y++) {
200+
for (int x=0; x < output.width(); x++) {
201+
auto outputColor = output.pixel(x, y);
202+
auto expectedColor = expected.pixel(x, y);
203+
204+
if (outputColor != expectedColor) {
205+
//qWarning() << "Pixel color mismatch at position " << x << y;
206+
//qWarning() << " output:" << outputColor << "expected:" << expectedColor;
207+
diff.setPixel(x, y, Qt::red);
208+
failed = true;
209+
}
210+
}
211+
}
212+
213+
auto outpath = outputFilePath("diff_" + name);
214+
qDebug() << "Saving diff" << outpath;
215+
216+
217+
if (QGuiApplication::platformName() != "xcb") {
218+
auto msg = QString("Skipping render test in non X11: %1")
219+
.arg(QGuiApplication::platformName());
220+
QSKIP(qPrintable(msg));
221+
}
222+
223+
QCOMPARE(diff.save(outpath), true);
224+
225+
QCOMPARE(output.width(), expected.width());
226+
QCOMPARE(output.height(), expected.height());
227+
228+
if (failed) {
229+
qWarning() << "Failing diff, check the output diff image" << outpath;
230+
QCOMPARE(failed, false);
231+
}
232+
}
233+
234+
/// This is mostly an example it renders a shell widget and saves it as an image.
235+
/// For more complicated tests we may want to parametrize these.
236+
void Test::render()
237+
{
238+
ShellWidget w;
239+
w.setShellFont(QFont("DejaVu Sans Mono", 11, QFont::Weight::Normal, false));
240+
w.resizeShell(20, 20);
241+
w.show();
242+
243+
w.put("hello", 2, 2, HighlightAttribute());
244+
w.put("fffffff", 3, 3, HighlightAttribute(Qt::red, Qt::black, Qt::white, false, false, false, false, false, false));
245+
w.put("italic text", 4, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, true, false, false, false, false));
246+
w.put("bold text", 5, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, false, true, false, false, false));
247+
w.put("underline text", 6, 3, HighlightAttribute(Qt::white, Qt::black, Qt::white, false, false, false, true, false, false));
248+
w.put("undercurl text", 7, 3, HighlightAttribute(Qt::white, Qt::black, Qt::red, false, false, false, false, true, false));
249+
250+
auto name = "shellwidget_render_works.png";
251+
saveWidgetOutput(w, name);
252+
diffWidgetOutput(name);
253+
}
254+
129255
QTEST_MAIN(Test)
130256
#include "test_shellwidget.moc"

0 commit comments

Comments
 (0)