tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
--- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp	Fri Sep 17 08:34:18 2010 +0300
+++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp	Mon Oct 04 01:19:32 2010 +0300
@@ -44,6 +44,7 @@
 #include <QtDeclarative/qdeclarativeimageprovider.h>
 #include <private/qdeclarativeimage_p.h>
 #include <QImageReader>
+#include <QWaitCondition>
 
 #ifdef Q_OS_SYMBIAN
 // In Symbian OS test data is located in applications private dir
@@ -85,6 +86,8 @@
     void removeProvider_data();
     void removeProvider();
 
+    void threadTest();
+
 private:
     QString newImageFileName() const;
     void fillRequestTestsData(const QString &id);
@@ -95,11 +98,17 @@
 class TestQImageProvider : public QDeclarativeImageProvider
 {
 public:
-    TestQImageProvider()
-        : QDeclarativeImageProvider(Image)
+    TestQImageProvider(bool *deleteWatch = 0)
+        : QDeclarativeImageProvider(Image), deleteWatch(deleteWatch)
     {
     }
 
+    ~TestQImageProvider()
+    {
+        if (deleteWatch)
+            *deleteWatch = true;
+    }
+
     QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize)
     {
         if (id == QLatin1String("no-such-file.png"))
@@ -114,6 +123,8 @@
             image = image.scaled(requestedSize);
         return image;
     }
+
+    bool *deleteWatch;
 };
 Q_DECLARE_METATYPE(TestQImageProvider*);
 
@@ -121,11 +132,17 @@
 class TestQPixmapProvider : public QDeclarativeImageProvider
 {
 public:
-    TestQPixmapProvider()
-        : QDeclarativeImageProvider(Pixmap)
+    TestQPixmapProvider(bool *deleteWatch = 0)
+        : QDeclarativeImageProvider(Pixmap), deleteWatch(deleteWatch)
     {
     }
 
+    ~TestQPixmapProvider()
+    {
+        if (deleteWatch)
+            *deleteWatch = true;
+    }
+
     QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
     {
         if (id == QLatin1String("no-such-file.png"))
@@ -140,6 +157,8 @@
             image = image.scaled(requestedSize);
         return image;
     }
+
+    bool *deleteWatch;
 };
 Q_DECLARE_METATYPE(TestQPixmapProvider*);
 
@@ -202,8 +221,8 @@
             TRY_WAIT(obj->status() == QDeclarativeImage::Ready);
         else
             QVERIFY(obj->status() == QDeclarativeImage::Ready);
-        QCOMPARE(obj->width(), 100.0);
-        QCOMPARE(obj->height(), 100.0);
+        QCOMPARE(obj->width(), qreal(size.width()));
+        QCOMPARE(obj->height(), qreal(size.height()));
         QCOMPARE(obj->pixmap().width(), size.width());
         QCOMPARE(obj->pixmap().height(), size.height());
         QCOMPARE(obj->fillMode(), QDeclarativeImage::Stretch);
@@ -225,7 +244,9 @@
 
 void tst_qdeclarativeimageprovider::requestImage_sync()
 {
-    runTest(false, new TestQImageProvider);
+    bool deleteWatch = false;
+    runTest(false, new TestQImageProvider(&deleteWatch));
+    QVERIFY(deleteWatch);
 }
 
 void tst_qdeclarativeimageprovider::requestImage_async_data()
@@ -235,7 +256,9 @@
 
 void tst_qdeclarativeimageprovider::requestImage_async()
 {
-    runTest(true, new TestQImageProvider);
+    bool deleteWatch = false;
+    runTest(true, new TestQImageProvider(&deleteWatch));
+    QVERIFY(deleteWatch);
 }
 
 void tst_qdeclarativeimageprovider::requestPixmap_sync_data()
@@ -245,13 +268,15 @@
 
 void tst_qdeclarativeimageprovider::requestPixmap_sync()
 {
-    runTest(false, new TestQPixmapProvider);
+    bool deleteWatch = false;
+    runTest(false, new TestQPixmapProvider(&deleteWatch));
+    QVERIFY(deleteWatch);
 }
 
 void tst_qdeclarativeimageprovider::requestPixmap_async()
 {
     QDeclarativeEngine engine;
-    QDeclarativeImageProvider *provider = new TestQPixmapProvider;
+    QDeclarativeImageProvider *provider = new TestQPixmapProvider();
 
     engine.addImageProvider("test", provider);
     QVERIFY(engine.imageProvider("test") != 0);
@@ -305,6 +330,71 @@
     delete obj;
 }
 
+class TestThreadProvider : public QDeclarativeImageProvider
+{
+    public:
+        TestThreadProvider() : QDeclarativeImageProvider(Image), ok(false) {}
+
+        ~TestThreadProvider() {}
+
+        QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize)
+        {
+            mutex.lock();
+            if (!ok)
+                cond.wait(&mutex);
+            mutex.unlock();
+            QVector<int> v;
+            for (int i = 0; i < 10000; i++)
+                v.prepend(i); //do some computation
+            QImage image(50,50, QImage::Format_RGB32);
+            image.fill(QColor(id).rgb());
+            if (size)
+                *size = image.size();
+            if (requestedSize.isValid())
+                image = image.scaled(requestedSize);
+            return image;
+        }
+
+        QWaitCondition cond;
+        QMutex mutex;
+        bool ok;
+};
+
+
+void tst_qdeclarativeimageprovider::threadTest()
+{
+    QDeclarativeEngine engine;
+
+    TestThreadProvider *provider = new TestThreadProvider;
+
+    engine.addImageProvider("test_thread", provider);
+    QVERIFY(engine.imageProvider("test_thread") != 0);
+
+    QString componentStr = "import Qt 4.7\nItem { \n"
+            "Image { source: \"image://test_thread/blue\";  asynchronous: true; }\n"
+            "Image { source: \"image://test_thread/red\";  asynchronous: true; }\n"
+            "Image { source: \"image://test_thread/green\";  asynchronous: true; }\n"
+            "Image { source: \"image://test_thread/yellow\";  asynchronous: true; }\n"
+            " }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QObject *obj = component.create();
+    //MUST not deadlock
+    QVERIFY(obj != 0);
+    QList<QDeclarativeImage *> images = obj->findChildren<QDeclarativeImage *>();
+    QCOMPARE(images.count(), 4);
+    QTest::qWait(100);
+    foreach(QDeclarativeImage *img, images) {
+        QCOMPARE(img->status(), QDeclarativeImage::Loading);
+    }
+    provider->ok = true;
+    provider->cond.wakeAll();
+    QTest::qWait(250);
+    foreach(QDeclarativeImage *img, images) {
+        TRY_WAIT(img->status() == QDeclarativeImage::Ready);
+    }
+}
+
 
 QTEST_MAIN(tst_qdeclarativeimageprovider)