QQuickCanvas renames
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickimage / tst_qquickimage.cpp
index eda56fa..d81fc40 100644 (file)
@@ -55,6 +55,7 @@
 #include <QtTest/QSignalSpy>
 #include <QtGui/QPainter>
 #include <QtGui/QImageReader>
+#include <QQuickWindow>
 
 #include "../../shared/util.h"
 #include "../../shared/testhttpserver.h"
@@ -75,6 +76,7 @@ public:
     tst_qquickimage();
 
 private slots:
+    void cleanup();
     void noSource();
     void imageSource();
     void imageSource_data();
@@ -84,6 +86,7 @@ private slots:
     void smooth();
     void mirror();
     void svg();
+    void svg_data();
     void geometry();
     void geometry_data();
     void big();
@@ -97,6 +100,8 @@ private slots:
     void imageCrash_QTBUG_22125();
     void sourceSize_data();
     void sourceSize();
+    void progressAndStatusChanges();
+    void sourceSizeChanges();
 
 private:
     QQmlEngine engine;
@@ -106,6 +111,13 @@ tst_qquickimage::tst_qquickimage()
 {
 }
 
+void tst_qquickimage::cleanup()
+{
+    QQuickWindow window;
+    window.releaseResources();
+    engine.clearComponentCache();
+}
+
 void tst_qquickimage::noSource()
 {
     QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }";
@@ -144,7 +156,8 @@ void tst_qquickimage::imageSource_data()
     QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << "";
     if (QImageReader::supportedImageFormats().contains("svg"))
         QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << "";
-
+    if (QImageReader::supportedImageFormats().contains("svgz"))
+        QTest::newRow("remote svgz") << SERVER_ADDR "/heart.svgz" << 550.0 << 500.0 << true << false << false << "";
     QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true
         << false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found";
 
@@ -246,23 +259,23 @@ void tst_qquickimage::resized()
 
 void tst_qquickimage::preserveAspectRatio()
 {
-    QQuickView *canvas = new QQuickView(0);
-    canvas->show();
+    QQuickView *window = new QQuickView(0);
+    window->show();
 
-    canvas->setSource(testFileUrl("aspectratio.qml"));
-    QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    window->setSource(testFileUrl("aspectratio.qml"));
+    QQuickImage *image = qobject_cast<QQuickImage*>(window->rootObject());
     QVERIFY(image != 0);
     image->setWidth(80.0);
     QCOMPARE(image->width(), 80.);
     QCOMPARE(image->height(), 80.);
 
-    canvas->setSource(testFileUrl("aspectratio.qml"));
-    image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    window->setSource(testFileUrl("aspectratio.qml"));
+    image = qobject_cast<QQuickImage*>(window->rootObject());
     image->setHeight(60.0);
     QVERIFY(image != 0);
     QCOMPARE(image->height(), 60.);
     QCOMPARE(image->width(), 60.);
-    delete canvas;
+    delete window;
 }
 
 void tst_qquickimage::smooth()
@@ -282,30 +295,30 @@ void tst_qquickimage::smooth()
 
 void tst_qquickimage::mirror()
 {
-    QSKIP("Test is broken on multiple levels, will need incremental fixes");
-
     QMap<QQuickImage::FillMode, QImage> screenshots;
     QList<QQuickImage::FillMode> fillModes;
     fillModes << QQuickImage::Stretch << QQuickImage::PreserveAspectFit << QQuickImage::PreserveAspectCrop
-              << QQuickImage::Tile << QQuickImage::TileVertically << QQuickImage::TileHorizontally;
+              << QQuickImage::Tile << QQuickImage::TileVertically << QQuickImage::TileHorizontally << QQuickImage::Pad;
 
     qreal width = 300;
     qreal height = 250;
 
     foreach (QQuickImage::FillMode fillMode, fillModes) {
-        QQuickView *canvas = new QQuickView;
-        canvas->setSource(testFileUrl("mirror.qml"));
+        QQuickView *window = new QQuickView;
+        window->setSource(testFileUrl("mirror.qml"));
 
-        QQuickImage *obj = canvas->rootObject()->findChild<QQuickImage*>("image");
+        QQuickImage *obj = window->rootObject()->findChild<QQuickImage*>("image");
         QVERIFY(obj != 0);
 
         obj->setFillMode(fillMode);
         obj->setProperty("mirror", true);
-        canvas->show();
+        window->show();
+        window->requestActivateWindow();
+        QTest::qWaitForWindowShown(window);
 
-        QImage screenshot = canvas->grabFrameBuffer();
+        QImage screenshot = window->grabWindow();
         screenshots[fillMode] = screenshot;
-        delete canvas;
+        delete window;
     }
 
     foreach (QQuickImage::FillMode fillMode, fillModes) {
@@ -319,6 +332,8 @@ void tst_qquickimage::mirror()
         transform.translate(width, 0).scale(-1, 1.0);
         p_e.setTransform(transform);
 
+        QPoint offset(width / 2 - srcPixmap.width() / 2, height / 2 - srcPixmap.height() / 2);
+
         switch (fillMode) {
         case QQuickImage::Stretch:
             p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
@@ -335,45 +350,55 @@ void tst_qquickimage::mirror()
             break;
         }
         case QQuickImage::Tile:
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap, -offset);
             break;
         case QQuickImage::TileVertically:
             transform.scale(width / srcPixmap.width(), 1.0);
             p_e.setTransform(transform);
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap, QPoint(0, -offset.y()));
             break;
         case QQuickImage::TileHorizontally:
             transform.scale(1.0, height / srcPixmap.height());
             p_e.setTransform(transform);
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap, QPoint(-offset.x(), 0));
             break;
         case QQuickImage::Pad:
+            p_e.drawPixmap(offset, srcPixmap);
             break;
         }
 
         QImage img = expected.toImage();
-        QEXPECT_FAIL("", "QTBUG-21005 fails", Continue);
         QCOMPARE(screenshots[fillMode], img);
     }
 }
 
+void tst_qquickimage::svg_data()
+{
+    QTest::addColumn<QString>("src");
+    QTest::addColumn<QByteArray>("format");
+
+    QTest::newRow("svg") << testFileUrl("heart.svg").toString() << QByteArray("svg");
+    QTest::newRow("svgz") << testFileUrl("heart.svgz").toString() << QByteArray("svgz");
+}
+
 void tst_qquickimage::svg()
 {
-    if (!QImageReader::supportedImageFormats().contains("svg"))
+    QFETCH(QString, src);
+    QFETCH(QByteArray, format);
+    if (!QImageReader::supportedImageFormats().contains(format))
         QSKIP("svg support not available");
 
-    QString src = testFileUrl("heart.svg").toString();
     QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; sourceSize.width: 300; sourceSize.height: 300 }";
     QQmlComponent component(&engine);
     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
     QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
     QVERIFY(obj != 0);
     QCOMPARE(obj->width(), 300.0);
-    QCOMPARE(obj->height(), 300.0);
+    QCOMPARE(obj->height(), 273.0);
     obj->setSourceSize(QSize(200,200));
 
     QCOMPARE(obj->width(), 200.0);
-    QCOMPARE(obj->height(), 200.0);
+    QCOMPARE(obj->height(), 182.0);
     delete obj;
 }
 
@@ -467,41 +492,24 @@ void tst_qquickimage::big()
     delete obj;
 }
 
-// As tiling_QTBUG_6716 doesn't complete, it doesn't delete the
-// canvas which causes leak warnings.  Use this delete on stack
-// destruction pattern to work around this.
-template<typename T>
-struct AutoDelete {
-    AutoDelete(T *t) : t(t) {}
-    ~AutoDelete() { delete t; }
-private:
-    T *t;
-};
-
 void tst_qquickimage::tiling_QTBUG_6716()
 {
-    QSKIP("Test is broken on multiple levels, will need incremental fixes");
-
     QFETCH(QString, source);
 
-    QQuickView *canvas = new QQuickView(0);
-    AutoDelete<QQuickView> del(canvas);
-
-    canvas->setSource(testFileUrl(source));
-    canvas->show();
-    qApp->processEvents();
+    QQuickView view(testFileUrl(source));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
 
-    QQuickImage *tiling = findItem<QQuickImage>(canvas->rootObject(), "tiling");
+    QQuickImage *tiling = findItem<QQuickImage>(view.rootObject(), "tiling");
 
     QVERIFY(tiling != 0);
-    QImage img = canvas->grabFrameBuffer();
+    QImage img = view.grabWindow();
     for (int x = 0; x < tiling->width(); ++x) {
         for (int y = 0; y < tiling->height(); ++y) {
             QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0));
         }
     }
-
-    delete canvas;
 }
 
 void tst_qquickimage::tiling_QTBUG_6716_data()
@@ -539,7 +547,7 @@ void tst_qquickimage::noLoading()
     QTRY_VERIFY(obj->progress() == 1.0);
     QTRY_COMPARE(sourceSpy.count(), 1);
     QTRY_COMPARE(progressSpy.count(), 0);
-    QTRY_COMPARE(statusSpy.count(), 0);
+    QTRY_COMPARE(statusSpy.count(), 1);
 
     // Loading remote file
     ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
@@ -549,7 +557,7 @@ void tst_qquickimage::noLoading()
     QTRY_VERIFY(obj->progress() == 1.0);
     QTRY_COMPARE(sourceSpy.count(), 2);
     QTRY_COMPARE(progressSpy.count(), 2);
-    QTRY_COMPARE(statusSpy.count(), 2);
+    QTRY_COMPARE(statusSpy.count(), 3);
 
     // Loading remote file again - should not go through 'Loading' state.
     ctxt->setContextProperty("srcImage", testFileUrl("green.png"));
@@ -558,7 +566,7 @@ void tst_qquickimage::noLoading()
     QTRY_VERIFY(obj->progress() == 1.0);
     QTRY_COMPARE(sourceSpy.count(), 4);
     QTRY_COMPARE(progressSpy.count(), 2);
-    QTRY_COMPARE(statusSpy.count(), 2);
+    QTRY_COMPARE(statusSpy.count(), 5);
 
     delete obj;
 }
@@ -630,13 +638,13 @@ void tst_qquickimage::sourceSize_QTBUG_14303()
 
 void tst_qquickimage::sourceSize_QTBUG_16389()
 {
-    QQuickView *canvas = new QQuickView(0);
-    canvas->setSource(testFileUrl("qtbug_16389.qml"));
-    canvas->show();
+    QQuickView *window = new QQuickView(0);
+    window->setSource(testFileUrl("qtbug_16389.qml"));
+    window->show();
     qApp->processEvents();
 
-    QQuickImage *image = findItem<QQuickImage>(canvas->rootObject(), "iconImage");
-    QQuickItem *handle = findItem<QQuickItem>(canvas->rootObject(), "blueHandle");
+    QQuickImage *image = findItem<QQuickImage>(window->rootObject(), "iconImage");
+    QQuickItem *handle = findItem<QQuickItem>(window->rootObject(), "blueHandle");
 
     QCOMPARE(image->sourceSize().width(), 200);
     QCOMPARE(image->sourceSize().height(), 200);
@@ -650,7 +658,7 @@ void tst_qquickimage::sourceSize_QTBUG_16389()
     QCOMPARE(image->paintedWidth(), 20.0);
     QCOMPARE(image->paintedHeight(), 20.0);
 
-    delete canvas;
+    delete window;
 }
 
 static int numberOfWarnings = 0;
@@ -663,23 +671,23 @@ static void checkWarnings(QtMsgType, const char *msg)
 // QTBUG-15690
 void tst_qquickimage::nullPixmapPaint()
 {
-    QQuickView *canvas = new QQuickView(0);
-    canvas->setSource(testFileUrl("nullpixmap.qml"));
-    canvas->show();
+    QQuickView *window = new QQuickView(0);
+    window->setSource(testFileUrl("nullpixmap.qml"));
+    window->show();
 
-    QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    QQuickImage *image = qobject_cast<QQuickImage*>(window->rootObject());
     QTRY_VERIFY(image != 0);
     image->setSource(SERVER_ADDR + QString("/no-such-file.png"));
 
     QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings);
 
     // used to print "QTransform::translate with NaN called"
-    QPixmap pm = QPixmap::fromImage(canvas->grabFrameBuffer());
+    QPixmap pm = QPixmap::fromImage(window->grabWindow());
     qInstallMsgHandler(previousMsgHandler);
     QVERIFY(numberOfWarnings == 0);
     delete image;
 
-    delete canvas;
+    delete window;
 }
 
 void tst_qquickimage::imageCrash_QTBUG_22125()
@@ -724,16 +732,16 @@ void tst_qquickimage::sourceSize()
     QFETCH(qreal, implicitWidth);
     QFETCH(qreal, implicitHeight);
 
-    QQuickView *canvas = new QQuickView(0);
-    QQmlContext *ctxt = canvas->rootContext();
+    QQuickView *window = new QQuickView(0);
+    QQmlContext *ctxt = window->rootContext();
     ctxt->setContextProperty("srcWidth", sourceWidth);
     ctxt->setContextProperty("srcHeight", sourceHeight);
 
-    canvas->setSource(testFileUrl("sourceSize.qml"));
-    canvas->show();
+    window->setSource(testFileUrl("sourceSize.qml"));
+    window->show();
     qApp->processEvents();
 
-    QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    QQuickImage *image = qobject_cast<QQuickImage*>(window->rootObject());
     QVERIFY(image);
 
     QCOMPARE(image->sourceSize().width(), sourceWidth);
@@ -741,7 +749,131 @@ void tst_qquickimage::sourceSize()
     QCOMPARE(image->implicitWidth(), implicitWidth);
     QCOMPARE(image->implicitHeight(), implicitHeight);
 
-    delete canvas;
+    delete window;
+}
+
+void tst_qquickimage::sourceSizeChanges()
+{
+    TestHTTPServer server(14449);
+    QVERIFY(server.isValid());
+    server.serveDirectory(dataDirectory());
+
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData("import QtQuick 2.0\nImage { source: srcImage }", QUrl::fromLocalFile(""));
+    QTRY_VERIFY(component.isReady());
+    QQmlContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", "");
+    QQuickImage *img = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(img != 0);
+
+    QSignalSpy sourceSizeSpy(img, SIGNAL(sourceSizeChanged()));
+
+    // Local
+    ctxt->setContextProperty("srcImage", QUrl(""));
+    QTRY_COMPARE(img->status(), QQuickImage::Null);
+    QTRY_COMPARE(sourceSizeSpy.count(), 0);
+
+    ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+    ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+    ctxt->setContextProperty("srcImage", testFileUrl("heart_copy.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+    ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 2);
+
+    ctxt->setContextProperty("srcImage", QUrl(""));
+    QTRY_COMPARE(img->status(), QQuickImage::Null);
+    QTRY_COMPARE(sourceSizeSpy.count(), 3);
+
+    // Remote
+    ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+    ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+    ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart_copy.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+    ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.png"));
+    QTRY_COMPARE(img->status(), QQuickImage::Ready);
+    QTRY_COMPARE(sourceSizeSpy.count(), 5);
+
+    ctxt->setContextProperty("srcImage", QUrl(""));
+    QTRY_COMPARE(img->status(), QQuickImage::Null);
+    QTRY_COMPARE(sourceSizeSpy.count(), 6);
+
+    delete img;
+}
+
+void tst_qquickimage::progressAndStatusChanges()
+{
+    TestHTTPServer server(14449);
+    QVERIFY(server.isValid());
+    server.serveDirectory(dataDirectory());
+
+    QQmlEngine engine;
+    QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
+    QQmlContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+    QQmlComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+
+    qRegisterMetaType<QQuickImageBase::Status>();
+    QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
+    QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
+    QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+
+    // Same image
+    ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 0);
+    QTRY_COMPARE(progressSpy.count(), 0);
+    QTRY_COMPARE(statusSpy.count(), 0);
+
+    // Loading local file
+    ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 1);
+    QTRY_COMPARE(progressSpy.count(), 0);
+    QTRY_COMPARE(statusSpy.count(), 1);
+
+    // Loading remote file
+    ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/heart.png");
+    QTRY_VERIFY(obj->status() == QQuickImage::Loading);
+    QTRY_VERIFY(obj->progress() == 0.0);
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 2);
+    QTRY_VERIFY(progressSpy.count() > 1);
+    QTRY_COMPARE(statusSpy.count(), 3);
+
+    ctxt->setContextProperty("srcImage", "");
+    QTRY_VERIFY(obj->status() == QQuickImage::Null);
+    QTRY_VERIFY(obj->progress() == 0.0);
+    QTRY_COMPARE(sourceSpy.count(), 3);
+    QTRY_VERIFY(progressSpy.count() > 2);
+    QTRY_COMPARE(statusSpy.count(), 4);
+
+    delete obj;
 }
 
 QTEST_MAIN(tst_qquickimage)