Add autotests for IconItem

Add some tests for IconItem.
Also found one issue in animation when quickly changing source, first frame
will be rendered with wrong icon.

REVIEW: 127103
This commit is contained in:
David Rosca 2016-02-27 21:24:45 +01:00
parent 361204cbee
commit 526915895b
6 changed files with 338 additions and 1 deletions

View File

@ -27,7 +27,8 @@ MACRO(PLASMA_UNIT_TESTS)
KF5::ConfigGui
KF5::I18n
KF5::KIOCore
KF5::Service)
KF5::Service
KF5::IconThemes)
if(QT_QTOPENGL_FOUND)
target_link_libraries(${_testname} Qt5::OpenGL)
endif()
@ -43,6 +44,7 @@ PLASMA_UNIT_TESTS(
packageurlinterceptortest
pluginloadertest
framesvgtest
iconitemtest
# plasmoidpackagetest
)

View File

@ -0,0 +1,72 @@
<?xml version="1.0"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="22" height="22" id="svg2" version="1.1" inkscape:version="0.91pre2 r" viewBox="0 0 22 22" sodipodi:docname="plasma.svg">
<defs id="defs4">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#4d4d4d;
}
.ColorScheme-Background {
color:#eff0f1;
}
.ColorScheme-Highlight {
color:#3daee9;
}
.ColorScheme-ViewText {
color:#31363b;
}
.ColorScheme-ViewBackground {
color:#fcfcfc;
}
.ColorScheme-ViewHover {
color:#93cee9;
}
.ColorScheme-ViewFocus{
color:#3daee9;
}
.ColorScheme-ButtonText {
color:#31363b;
}
.ColorScheme-ButtonBackground {
color:#eff0f1;
}
.ColorScheme-ButtonHover {
color:#93cee9;
}
.ColorScheme-ButtonFocus{
color:#3daee9;
}
</style>
</defs>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="22.627417" inkscape:cx="7.6662963" inkscape:cy="11.508125" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" units="px" inkscape:showpageshadow="false" inkscape:window-width="1366" inkscape:window-height="669" inkscape:window-x="-4" inkscape:window-y="25" inkscape:window-maximized="1" showguides="true">
<inkscape:grid type="xygrid" id="grid4101"/>
<sodipodi:guide position="2,20.000017" orientation="18,0" id="guide4107"/>
<sodipodi:guide position="2,2.0000174" orientation="0,18" id="guide4109"/>
<sodipodi:guide position="20,2.0000174" orientation="-18,0" id="guide4111"/>
<sodipodi:guide position="20,20.000017" orientation="0,-18" id="guide4113"/>
<sodipodi:guide position="3,19.000017" orientation="16,0" id="guide4115"/>
<sodipodi:guide position="3,3.0000174" orientation="0,16" id="guide4117"/>
<sodipodi:guide position="19,3.0000174" orientation="-16,0" id="guide4119"/>
<sodipodi:guide position="19,19.000017" orientation="0,-16" id="guide4121"/>
<sodipodi:guide position="10,6.0000174" orientation="-7,0" id="guide4162"/>
<sodipodi:guide position="11,12.000017" orientation="5,0" id="guide4280"/>
<sodipodi:guide position="11,7.0000174" orientation="0,5" id="guide4282"/>
<sodipodi:guide position="16,7.0000174" orientation="-5,0" id="guide4284"/>
<sodipodi:guide position="16,12.000017" orientation="0,-5" id="guide4286"/>
<sodipodi:guide position="5,13.000017" orientation="6,0" id="guide4294"/>
<sodipodi:guide position="5,7.0000174" orientation="0,6" id="guide4296"/>
<sodipodi:guide position="11,7.0000174" orientation="-6,0" id="guide4298"/>
</sodipodi:namedview>
<metadata id="metadata7">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:label="Capa 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-1030.3622)">
<path style="opacity:1;fill:currentColor;fill-opacity:1;stroke:none" d="M 7 3 C 6.446 3 6 3.446 6 4 C 6 4.554 6.446 5 7 5 C 7.554 5 8 4.554 8 4 C 8 3.446 7.554 3 7 3 z M 14 3 L 12 5 L 15 8 L 12 11 L 14 13 L 17 10 L 19 8 L 14 3 z M 4.5 9 C 3.669 9 3 9.669 3 10.5 C 3 11.331 3.669 12 4.5 12 C 5.331 12 6 11.331 6 10.5 C 6 9.669 5.331 9 4.5 9 z M 9 15 C 7.892 15 7 15.892 7 17 C 7 18.108 7.892 19 9 19 C 10.108 19 11 18.108 11 17 C 11 15.892 10.108 15 9 15 z " transform="translate(0,1030.3622)" id="rect4231" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

2
autotests/data/view.qml Normal file
View File

@ -0,0 +1,2 @@
import QtQuick 2.0
Item { }

214
autotests/iconitemtest.cpp Normal file
View File

@ -0,0 +1,214 @@
/******************************************************************************
* Copyright 2016 David Rosca <nowrep@gmail.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public License *
* along with this library; see the file COPYING.LIB. If not, write to *
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301, USA. *
*******************************************************************************/
#include "iconitemtest.h"
#include <QIcon>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include <QQuickItemGrabResult>
#include <QtTest/QSignalSpy>
#include <KIconLoader>
#include <KIconEngine>
#include "plasma/theme.h"
#include "plasma/svg.h"
static bool imageIsEmpty(const QImage &img)
{
const QColor empty = QColor::fromRgba(0);
for (int i = 0; i < img.width(); ++i) {
for (int j = 0; j < img.height(); ++j) {
if (img.pixelColor(i, j) != empty) {
return false;
}
}
}
return true;
}
void IconItemTest::initTestCase()
{
m_view = new QQuickView();
m_view->setSource(QUrl::fromLocalFile(QFINDTESTDATA("data/view.qml")));
m_view->show();
QTest::qWaitForWindowExposed(m_view);
}
void IconItemTest::cleanup()
{
qDeleteAll(m_view->rootObject()->childItems());
}
QQuickItem *IconItemTest::createIconItem()
{
QByteArray iconQml =
"import QtQuick 2.0;"
"import org.kde.plasma.core 2.0 as PlasmaCore;"
"PlasmaCore.IconItem {"
" id: root;"
"}";
QQmlComponent component(m_view->engine());
QSignalSpy spy(&component, SIGNAL(statusChanged(QQmlComponent::Status)));
component.setData(iconQml, QUrl("test://iconTest"));
if (component.status() != QQmlComponent::Ready) {
spy.wait();
}
QQuickItem *item = qobject_cast<QQuickItem*>(component.create(m_view->engine()->rootContext()));
Q_ASSERT(item && qstrcmp(item->metaObject()->className(), "IconItem") == 0);
item->setParentItem(m_view->rootObject());
return item;
}
QImage IconItemTest::grabImage(QQuickItem *item)
{
QSharedPointer<QQuickItemGrabResult> grab = item->grabToImage();
QSignalSpy spy(grab.data(), SIGNAL(ready()));
spy.wait();
return grab->image();
}
// ------ Tests
void IconItemTest::invalidIcon()
{
QString name("tst-plasma-framework-invalid-icon-name");
KIconLoader iconLoader("tst_plasma-framework");
if (iconLoader.hasIcon(name)) {
QSKIP("Current icon theme has 'tst-plasma-framework-invalid-icon-name' icon.");
}
QQuickItem *item = createIconItem();
item->setProperty("source", name);
QVERIFY(!item->property("valid").toBool());
QVERIFY(imageIsEmpty(grabImage(item)));
}
void IconItemTest::usesPlasmaTheme()
{
Plasma::Theme theme;
if (!theme.themeName().startsWith("breeze")) {
QSKIP("Current Plasma theme is not Breeze.");
}
// usesPlasmaTheme = true (default)
QQuickItem *item1 = createIconItem();
item1->setProperty("source", "konversation");
QVERIFY(item1->property("valid").toBool());
Plasma::Svg svg;
svg.setContainsMultipleImages(true);
svg.setImagePath("icons/konversation");
QImage img1 = grabImage(item1);
QImage img2 = svg.image(QSize(item1->width(), item1->height()), "konversation");
QVERIFY(!imageIsEmpty(img1));
QVERIFY(!imageIsEmpty(img2));
QCOMPARE(img1, img2);
// usesPlasmaTheme = false
QQuickItem *item2 = createIconItem();
item2->setProperty("usesPlasmaTheme", false);
item2->setProperty("source", "konversation");
img1 = grabImage(item2);
// This depends on konversation icon being different in Plasma Breeze theme
// and normal Breeze icon theme
QVERIFY(img1 != img2);
}
void IconItemTest::animation()
{
// animated = true (default)
QQuickItem *item1 = createIconItem();
item1->setProperty("source", "user-away");
// first icon is not animated
QImage userAwayImg = grabImage(item1);
item1->setProperty("source", "user-busy");
grabImage(item1);
item1->setProperty("source", "user-away");
// animation from user-busy -> user-away
QVERIFY(userAwayImg != grabImage(item1));
// animated = false
QQuickItem *item2 = createIconItem();
item2->setProperty("animated", false);
item2->setProperty("source", "user-busy");
QImage userBusyImg = grabImage(item2);
item2->setProperty("source", "user-away");
QCOMPARE(userAwayImg, grabImage(item2));
item2->setProperty("source", "user-busy");
QCOMPARE(userBusyImg, grabImage(item2));
}
void IconItemTest::animationAfterHide()
{
QEXPECT_FAIL("", "Needs 'no animation after hide' patch", Abort);
QQuickItem *item1 = createIconItem();
QQuickItem *item2 = createIconItem();
item1->setProperty("source", "user-away");
item2->setProperty("source", "user-busy");
// first icon is not animated
QImage userAwayImg = grabImage(item1);
QImage userBusyImg = grabImage(item2);
item1->setProperty("source", "user-busy");
grabImage(item1);
item1->setProperty("visible", "false");
item1->setProperty("visible", "true");
item1->setProperty("source", "user-away");
// icon was hidden, no animation
QCOMPARE(userAwayImg, grabImage(item1));
item1->setProperty("source", "user-busy");
QVERIFY(userBusyImg != grabImage(item1));
}
void IconItemTest::bug_359388()
{
QString name("bug359388");
KIconLoader iconLoader("tst_plasma-framework");
if (iconLoader.hasIcon(name)) {
QSKIP("Current icon theme has 'bug359388' icon.");
}
iconLoader.addAppDir("tst_plasma-framework", QFINDTESTDATA("data/icons"));
QIcon customThemeIcon(new KIconEngine(name, &iconLoader));
QQuickItem *item1 = createIconItem();
item1->setProperty("source", customThemeIcon);
QVERIFY(item1->property("valid").toBool());
QQuickItem *item2 = createIconItem();
item2->setProperty("source", QIcon(QFINDTESTDATA("data/icons/hicolor/22x22/apps/" + name + ".svg")));
QVERIFY(item2->property("valid").toBool());
QCOMPARE(grabImage(item1), grabImage(item2));
}
QTEST_MAIN(IconItemTest)

46
autotests/iconitemtest.h Normal file
View File

@ -0,0 +1,46 @@
/******************************************************************************
* Copyright 2016 David Rosca <nowrep@gmail.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public License *
* along with this library; see the file COPYING.LIB. If not, write to *
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301, USA. *
*******************************************************************************/
#pragma once
#include <QQuickItem>
#include <QQuickView>
#include <QtTest/QtTest>
class IconItemTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void cleanup();
void invalidIcon();
void usesPlasmaTheme();
void animation();
void animationAfterHide();
void bug_359388();
private:
QQuickItem *createIconItem();
QImage grabImage(QQuickItem *item);
QQuickView *m_view;
};

View File

@ -450,6 +450,7 @@ void IconItem::loadPixmap()
//don't animate initial setting
if (m_animated && !m_oldIconPixmap.isNull() && !m_sizeChanged) {
m_animValue = 0.0;
m_animation->setStartValue((qreal)0);
m_animation->setEndValue((qreal)1);
m_animation->start();