All QWindow properties that have "window" in them have been renamed.
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickanimatedimage / tst_qquickanimatedimage.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtQml/qqmlengine.h>
43 #include <QtQml/qqmlcomponent.h>
44 #include <QtQuick/qquickview.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <private/qquickimage_p.h>
47 #include <private/qquickanimatedimage_p.h>
48 #include <QSignalSpy>
49 #include <QtQml/qqmlcontext.h>
50
51 #include "../../shared/testhttpserver.h"
52 #include "../../shared/util.h"
53
54 Q_DECLARE_METATYPE(QQuickImageBase::Status)
55
56 class tst_qquickanimatedimage : public QQmlDataTest
57 {
58     Q_OBJECT
59 public:
60     tst_qquickanimatedimage() {}
61
62 private slots:
63     void cleanup();
64     void play();
65     void pause();
66     void stopped();
67     void setFrame();
68     void frameCount();
69     void mirror_running();
70     void mirror_notRunning();
71     void mirror_notRunning_data();
72     void remote();
73     void remote_data();
74     void sourceSize();
75     void sourceSizeChanges();
76     void sourceSizeReadOnly();
77     void invalidSource();
78     void qtbug_16520();
79     void progressAndStatusChanges();
80     void playingAndPausedChanges();
81 };
82
83 void tst_qquickanimatedimage::cleanup()
84 {
85     QQuickWindow window;
86     window.releaseResources();
87 }
88
89 void tst_qquickanimatedimage::play()
90 {
91     QQmlEngine engine;
92     QQmlComponent component(&engine, testFileUrl("stickman.qml"));
93     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
94     QVERIFY(anim);
95     QVERIFY(anim->isPlaying());
96
97     delete anim;
98 }
99
100 void tst_qquickanimatedimage::pause()
101 {
102     QQmlEngine engine;
103     QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
104     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
105     QVERIFY(anim);
106
107     QTRY_VERIFY(anim->isPaused());
108     QTRY_VERIFY(anim->isPlaying());
109
110     delete anim;
111 }
112
113 void tst_qquickanimatedimage::stopped()
114 {
115     QQmlEngine engine;
116     QQmlComponent component(&engine, testFileUrl("stickmanstopped.qml"));
117     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
118     QVERIFY(anim);
119     QTRY_VERIFY(!anim->isPlaying());
120     QCOMPARE(anim->currentFrame(), 0);
121
122     delete anim;
123 }
124
125 void tst_qquickanimatedimage::setFrame()
126 {
127     QQmlEngine engine;
128     QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
129     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
130     QVERIFY(anim);
131     QVERIFY(anim->isPlaying());
132     QCOMPARE(anim->currentFrame(), 2);
133
134     delete anim;
135 }
136
137 void tst_qquickanimatedimage::frameCount()
138 {
139     QQmlEngine engine;
140     QQmlComponent component(&engine, testFileUrl("colors.qml"));
141     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
142     QVERIFY(anim);
143     QVERIFY(anim->isPlaying());
144     QCOMPARE(anim->frameCount(), 3);
145
146     delete anim;
147 }
148
149 void tst_qquickanimatedimage::mirror_running()
150 {
151     // test where mirror is set to true after animation has started
152
153     QQuickView window;
154     window.setSource(testFileUrl("hearts.qml"));
155     window.requestActivate();
156     window.show();
157     QTest::qWaitForWindowActive(&window);
158
159     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject());
160     QVERIFY(anim);
161
162     int width = anim->property("width").toInt();
163
164     QCOMPARE(anim->frameCount(), 2);
165
166     QCOMPARE(anim->currentFrame(), 0);
167     QImage frame0 = window.grabWindow();
168
169     anim->setCurrentFrame(1);
170     QCOMPARE(anim->currentFrame(), 1);
171     QImage frame1 = window.grabWindow();
172
173     anim->setCurrentFrame(0);
174
175     QSignalSpy spy(anim, SIGNAL(frameChanged()));
176     QVERIFY(spy.isValid());
177     anim->setPlaying(true);
178
179     QTRY_VERIFY(spy.count() == 1); spy.clear();
180     anim->setMirror(true);
181
182     QCOMPARE(anim->currentFrame(), 1);
183     QImage frame1_flipped = window.grabWindow();
184
185     QTRY_VERIFY(spy.count() == 1); spy.clear();
186     QCOMPARE(anim->currentFrame(), 0);  // animation only has 2 frames, should cycle back to first
187     QImage frame0_flipped = window.grabWindow();
188
189     QTransform transform;
190     transform.translate(width, 0).scale(-1, 1.0);
191     QImage frame0_expected = frame0.transformed(transform);
192     QImage frame1_expected = frame1.transformed(transform);
193
194     QCOMPARE(frame0_flipped, frame0_expected);
195     QCOMPARE(frame1_flipped, frame1_expected);
196
197     delete anim;
198 }
199
200 void tst_qquickanimatedimage::mirror_notRunning()
201 {
202     QFETCH(QUrl, fileUrl);
203
204     QQuickView window;
205     window.show();
206
207     window.setSource(fileUrl);
208     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject());
209     QVERIFY(anim);
210
211     int width = anim->property("width").toInt();
212     QPixmap screenshot = QPixmap::fromImage(window.grabWindow());
213
214     QTransform transform;
215     transform.translate(width, 0).scale(-1, 1.0);
216     QPixmap expected = screenshot.transformed(transform);
217
218     int frame = anim->currentFrame();
219     bool playing = anim->isPlaying();
220     bool paused = anim->isPlaying();
221
222     anim->setProperty("mirror", true);
223     screenshot = QPixmap::fromImage(window.grabWindow());
224
225     QCOMPARE(screenshot, expected);
226
227     // mirroring should not change the current frame or playing status
228     QCOMPARE(anim->currentFrame(), frame);
229     QCOMPARE(anim->isPlaying(), playing);
230     QCOMPARE(anim->isPaused(), paused);
231
232     delete anim;
233 }
234
235 void tst_qquickanimatedimage::mirror_notRunning_data()
236 {
237     QTest::addColumn<QUrl>("fileUrl");
238
239     QTest::newRow("paused") << testFileUrl("stickmanpause.qml");
240     QTest::newRow("stopped") << testFileUrl("stickmanstopped.qml");
241 }
242
243 void tst_qquickanimatedimage::remote_data()
244 {
245     QTest::addColumn<QString>("fileName");
246     QTest::addColumn<bool>("paused");
247
248     QTest::newRow("playing") << "stickman.qml" << false;
249     QTest::newRow("paused") << "stickmanpause.qml" << true;
250 }
251
252 void tst_qquickanimatedimage::remote()
253 {
254     QFETCH(QString, fileName);
255     QFETCH(bool, paused);
256
257     TestHTTPServer server(14449);
258     QVERIFY(server.isValid());
259     server.serveDirectory(dataDirectory());
260
261     QQmlEngine engine;
262     QQmlComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
263     QTRY_VERIFY(component.isReady());
264
265     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
266     QVERIFY(anim);
267
268     QTRY_VERIFY(anim->isPlaying());
269     if (paused) {
270         QTRY_VERIFY(anim->isPaused());
271         QCOMPARE(anim->currentFrame(), 2);
272     }
273     QVERIFY(anim->status() != QQuickAnimatedImage::Error);
274
275     delete anim;
276 }
277
278 void tst_qquickanimatedimage::sourceSize()
279 {
280     QQmlEngine engine;
281     QQmlComponent component(&engine, testFileUrl("stickmanscaled.qml"));
282     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
283     QVERIFY(anim);
284     QCOMPARE(anim->width(),240.0);
285     QCOMPARE(anim->height(),180.0);
286     QCOMPARE(anim->sourceSize(),QSize(160,120));
287
288     delete anim;
289 }
290
291 void tst_qquickanimatedimage::sourceSizeReadOnly()
292 {
293     QQmlEngine engine;
294     QQmlComponent component(&engine, testFileUrl("stickmanerror1.qml"));
295     QVERIFY(component.isError());
296     QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
297 }
298
299 void tst_qquickanimatedimage::invalidSource()
300 {
301     QQmlEngine engine;
302     QQmlComponent component(&engine);
303     component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
304     QVERIFY(component.isReady());
305
306     QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
307
308     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
309     QVERIFY(anim);
310
311     QVERIFY(anim->isPlaying());
312     QVERIFY(!anim->isPaused());
313     QCOMPARE(anim->currentFrame(), 0);
314     QCOMPARE(anim->frameCount(), 0);
315     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Error);
316
317     delete anim;
318 }
319
320 void tst_qquickanimatedimage::sourceSizeChanges()
321 {
322     TestHTTPServer server(14449);
323     QVERIFY(server.isValid());
324     server.serveDirectory(dataDirectory());
325
326     QQmlEngine engine;
327     QQmlComponent component(&engine);
328     component.setData("import QtQuick 2.0\nAnimatedImage { source: srcImage }", QUrl::fromLocalFile(""));
329     QTRY_VERIFY(component.isReady());
330     QQmlContext *ctxt = engine.rootContext();
331     ctxt->setContextProperty("srcImage", "");
332     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage*>(component.create());
333     QVERIFY(anim != 0);
334
335     QSignalSpy sourceSizeSpy(anim, SIGNAL(sourceSizeChanged()));
336
337     // Local
338     ctxt->setContextProperty("srcImage", QUrl(""));
339     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
340     QTRY_VERIFY(sourceSizeSpy.count() == 0);
341
342     ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
343     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
344     QTRY_VERIFY(sourceSizeSpy.count() == 1);
345
346     ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
347     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
348     QTRY_VERIFY(sourceSizeSpy.count() == 1);
349
350     ctxt->setContextProperty("srcImage", testFileUrl("hearts_copy.gif"));
351     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
352     QTRY_VERIFY(sourceSizeSpy.count() == 1);
353
354     ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
355     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
356     QTRY_VERIFY(sourceSizeSpy.count() == 2);
357
358     ctxt->setContextProperty("srcImage", QUrl(""));
359     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
360     QTRY_VERIFY(sourceSizeSpy.count() == 3);
361
362     // Remote
363     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
364     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
365     QTRY_VERIFY(sourceSizeSpy.count() == 4);
366
367     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
368     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
369     QTRY_VERIFY(sourceSizeSpy.count() == 4);
370
371     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts_copy.gif"));
372     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
373     QTRY_VERIFY(sourceSizeSpy.count() == 4);
374
375     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.gif"));
376     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
377     QTRY_VERIFY(sourceSizeSpy.count() == 5);
378
379     ctxt->setContextProperty("srcImage", QUrl(""));
380     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
381     QTRY_VERIFY(sourceSizeSpy.count() == 6);
382
383     delete anim;
384 }
385
386 void tst_qquickanimatedimage::qtbug_16520()
387 {
388     TestHTTPServer server(14449);
389     QVERIFY(server.isValid());
390     server.serveDirectory(dataDirectory());
391
392     QQmlEngine engine;
393     QQmlComponent component(&engine, testFileUrl("qtbug-16520.qml"));
394     QTRY_VERIFY(component.isReady());
395
396     QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
397     QVERIFY(root);
398     QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
399     QVERIFY(anim != 0);
400
401     anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
402     QTRY_VERIFY(anim->opacity() == 0);
403     QTRY_VERIFY(anim->opacity() == 1);
404
405     delete anim;
406     delete root;
407 }
408
409 void tst_qquickanimatedimage::progressAndStatusChanges()
410 {
411     TestHTTPServer server(14449);
412     QVERIFY(server.isValid());
413     server.serveDirectory(dataDirectory());
414
415     QQmlEngine engine;
416     QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
417     QQmlContext *ctxt = engine.rootContext();
418     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
419     QQmlComponent component(&engine);
420     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
421     QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
422     QVERIFY(obj != 0);
423     QVERIFY(obj->status() == QQuickImage::Ready);
424     QTRY_VERIFY(obj->progress() == 1.0);
425
426     qRegisterMetaType<QQuickImageBase::Status>();
427     QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
428     QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
429     QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
430
431     // Same image
432     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
433     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
434     QTRY_VERIFY(obj->progress() == 1.0);
435     QTRY_COMPARE(sourceSpy.count(), 0);
436     QTRY_COMPARE(progressSpy.count(), 0);
437     QTRY_COMPARE(statusSpy.count(), 0);
438
439     // Loading local file
440     ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
441     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
442     QTRY_VERIFY(obj->progress() == 1.0);
443     QTRY_COMPARE(sourceSpy.count(), 1);
444     QTRY_COMPARE(progressSpy.count(), 0);
445     QTRY_COMPARE(statusSpy.count(), 1);
446
447     // Loading remote file
448     ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
449     QTRY_VERIFY(obj->status() == QQuickImage::Loading);
450     QTRY_VERIFY(obj->progress() == 0.0);
451     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
452     QTRY_VERIFY(obj->progress() == 1.0);
453     QTRY_COMPARE(sourceSpy.count(), 2);
454     QTRY_VERIFY(progressSpy.count() > 1);
455     QTRY_COMPARE(statusSpy.count(), 3);
456
457     ctxt->setContextProperty("srcImage", "");
458     QTRY_VERIFY(obj->status() == QQuickImage::Null);
459     QTRY_VERIFY(obj->progress() == 0.0);
460     QTRY_COMPARE(sourceSpy.count(), 3);
461     QTRY_VERIFY(progressSpy.count() > 2);
462     QTRY_COMPARE(statusSpy.count(), 4);
463
464     delete obj;
465 }
466
467 void tst_qquickanimatedimage::playingAndPausedChanges()
468 {
469     QQmlEngine engine;
470     QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
471     QQmlContext *ctxt = engine.rootContext();
472     ctxt->setContextProperty("srcImage", QUrl(""));
473     QQmlComponent component(&engine);
474     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
475     QQuickAnimatedImage *obj = qobject_cast<QQuickAnimatedImage*>(component.create());
476     QVERIFY(obj != 0);
477     QVERIFY(obj->status() == QQuickAnimatedImage::Null);
478     QTRY_VERIFY(obj->isPlaying());
479     QTRY_VERIFY(!obj->isPaused());
480     QSignalSpy playingSpy(obj, SIGNAL(playingChanged()));
481     QSignalSpy pausedSpy(obj, SIGNAL(pausedChanged()));
482
483     // initial state
484     obj->setProperty("playing", true);
485     obj->setProperty("paused", false);
486     QTRY_VERIFY(obj->isPlaying());
487     QTRY_VERIFY(!obj->isPaused());
488     QTRY_COMPARE(playingSpy.count(), 0);
489     QTRY_COMPARE(pausedSpy.count(), 0);
490
491     obj->setProperty("playing", false);
492     obj->setProperty("paused", true);
493     QTRY_VERIFY(!obj->isPlaying());
494     QTRY_VERIFY(obj->isPaused());
495     QTRY_COMPARE(playingSpy.count(), 1);
496     QTRY_COMPARE(pausedSpy.count(), 1);
497
498     obj->setProperty("playing", true);
499     obj->setProperty("paused", false);
500     QTRY_VERIFY(obj->isPlaying());
501     QTRY_VERIFY(!obj->isPaused());
502     QTRY_COMPARE(playingSpy.count(), 2);
503     QTRY_COMPARE(pausedSpy.count(), 2);
504
505     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
506     QTRY_VERIFY(obj->isPlaying());
507     QTRY_VERIFY(!obj->isPaused());
508     QTRY_COMPARE(playingSpy.count(), 2);
509     QTRY_COMPARE(pausedSpy.count(), 2);
510
511     obj->setProperty("paused", true);
512     QTRY_VERIFY(obj->isPlaying());
513     QTRY_VERIFY(obj->isPaused());
514     QTRY_COMPARE(playingSpy.count(), 2);
515     QTRY_COMPARE(pausedSpy.count(), 3);
516
517     obj->setProperty("playing", false);
518     QTRY_VERIFY(!obj->isPlaying());
519     QTRY_VERIFY(!obj->isPaused());
520     QTRY_COMPARE(playingSpy.count(), 3);
521     QTRY_COMPARE(pausedSpy.count(), 4);
522
523     obj->setProperty("playing", true);
524
525     // Cannot animate this image, playing will be false
526     ctxt->setContextProperty("srcImage", testFileUrl("green.png"));
527     QTRY_VERIFY(!obj->isPlaying());
528     QTRY_VERIFY(!obj->isPaused());
529     QTRY_COMPARE(playingSpy.count(), 5);
530     QTRY_COMPARE(pausedSpy.count(), 4);
531
532     delete obj;
533 }
534 QTEST_MAIN(tst_qquickanimatedimage)
535
536 #include "tst_qquickanimatedimage.moc"