1
/****************************************************************************
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** GNU Lesser General Public License Usage
10
** This file may be used under the terms of the GNU Lesser General Public
11
** License version 2.1 as published by the Free Software Foundation and
12
** appearing in the file LICENSE.LGPL included in the packaging of this
13
** file. Please review the following information to ensure the GNU Lesser
14
** General Public License version 2.1 requirements will be met:
15
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
** In addition, as a special exception, Nokia gives you certain additional
18
** rights. These rights are described in the Nokia Qt LGPL Exception
19
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
** GNU General Public License Usage
22
** Alternatively, this file may be used under the terms of the GNU General
23
** Public License version 3.0 as published by the Free Software Foundation
24
** and appearing in the file LICENSE.GPL included in the packaging of this
25
** file. Please review the following information to ensure the GNU General
26
** Public License version 3.0 requirements will be met:
27
** http://www.gnu.org/copyleft/gpl.html.
30
** Alternatively, this file may be used in accordance with the terms and
31
** conditions contained in a signed written agreement between you and Nokia.
40
****************************************************************************/
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>
49
#include <QtQml/qqmlcontext.h>
51
#include "../../shared/testhttpserver.h"
52
#include "../../shared/util.h"
54
Q_DECLARE_METATYPE(QQuickImageBase::Status)
56
class tst_qquickanimatedimage : public QQmlDataTest
60
tst_qquickanimatedimage() {}
68
void mirror_running();
69
void mirror_notRunning();
70
void mirror_notRunning_data();
74
void sourceSizeReadOnly();
77
void progressAndStatusChanges();
81
void tst_qquickanimatedimage::play()
84
QQmlComponent component(&engine, testFileUrl("stickman.qml"));
85
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
87
QVERIFY(anim->isPlaying());
92
void tst_qquickanimatedimage::pause()
95
QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
96
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
98
QVERIFY(anim->isPlaying());
99
QVERIFY(anim->isPaused());
104
void tst_qquickanimatedimage::stopped()
107
QQmlComponent component(&engine, testFileUrl("stickmanstopped.qml"));
108
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
110
QVERIFY(!anim->isPlaying());
111
QCOMPARE(anim->currentFrame(), 0);
116
void tst_qquickanimatedimage::setFrame()
119
QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
120
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
122
QVERIFY(anim->isPlaying());
123
QCOMPARE(anim->currentFrame(), 2);
128
void tst_qquickanimatedimage::frameCount()
131
QQmlComponent component(&engine, testFileUrl("colors.qml"));
132
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
134
QVERIFY(anim->isPlaying());
135
QCOMPARE(anim->frameCount(), 3);
140
void tst_qquickanimatedimage::mirror_running()
142
// test where mirror is set to true after animation has started
147
canvas.setSource(testFileUrl("hearts.qml"));
148
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas.rootObject());
151
int width = anim->property("width").toInt();
153
QCOMPARE(anim->currentFrame(), 0);
154
QPixmap frame0 = QPixmap::fromImage(canvas.grabFrameBuffer());
156
anim->setCurrentFrame(1);
157
QPixmap frame1 = QPixmap::fromImage(canvas.grabFrameBuffer());
159
anim->setCurrentFrame(0);
161
QSignalSpy spy(anim, SIGNAL(frameChanged()));
162
anim->setPlaying(true);
164
QTRY_VERIFY(spy.count() == 1); spy.clear();
165
anim->setProperty("mirror", true);
167
QCOMPARE(anim->currentFrame(), 1);
168
QPixmap frame1_flipped = QPixmap::fromImage(canvas.grabFrameBuffer());
170
QTRY_VERIFY(spy.count() == 1); spy.clear();
171
QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first
172
QPixmap frame0_flipped = QPixmap::fromImage(canvas.grabFrameBuffer());
174
QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
176
QTransform transform;
177
transform.translate(width, 0).scale(-1, 1.0);
178
QPixmap frame0_expected = frame0.transformed(transform);
179
QPixmap frame1_expected = frame1.transformed(transform);
181
QCOMPARE(frame0_flipped, frame0_expected);
182
QCOMPARE(frame1_flipped, frame1_expected);
185
void tst_qquickanimatedimage::mirror_notRunning()
187
QFETCH(QUrl, fileUrl);
192
canvas.setSource(fileUrl);
193
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas.rootObject());
196
int width = anim->property("width").toInt();
197
QPixmap screenshot = QPixmap::fromImage(canvas.grabFrameBuffer());
199
QTransform transform;
200
transform.translate(width, 0).scale(-1, 1.0);
201
QPixmap expected = screenshot.transformed(transform);
203
int frame = anim->currentFrame();
204
bool playing = anim->isPlaying();
205
bool paused = anim->isPlaying();
207
anim->setProperty("mirror", true);
208
screenshot = QPixmap::fromImage(canvas.grabFrameBuffer());
210
QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
211
QCOMPARE(screenshot, expected);
213
// mirroring should not change the current frame or playing status
214
QCOMPARE(anim->currentFrame(), frame);
215
QCOMPARE(anim->isPlaying(), playing);
216
QCOMPARE(anim->isPaused(), paused);
219
void tst_qquickanimatedimage::mirror_notRunning_data()
221
QTest::addColumn<QUrl>("fileUrl");
223
QTest::newRow("paused") << testFileUrl("stickmanpause.qml");
224
QTest::newRow("stopped") << testFileUrl("stickmanstopped.qml");
227
void tst_qquickanimatedimage::remote()
229
QFETCH(QString, fileName);
230
QFETCH(bool, paused);
232
TestHTTPServer server(14449);
233
QVERIFY(server.isValid());
234
server.serveDirectory(dataDirectory());
237
QQmlComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
238
QTRY_VERIFY(component.isReady());
240
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
243
QTRY_VERIFY(anim->isPlaying());
245
QTRY_VERIFY(anim->isPaused());
246
QCOMPARE(anim->currentFrame(), 2);
248
QVERIFY(anim->status() != QQuickAnimatedImage::Error);
253
void tst_qquickanimatedimage::sourceSize()
256
QQmlComponent component(&engine, testFileUrl("stickmanscaled.qml"));
257
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
259
QCOMPARE(anim->width(),240.0);
260
QCOMPARE(anim->height(),180.0);
261
QCOMPARE(anim->sourceSize(),QSize(160,120));
266
void tst_qquickanimatedimage::sourceSizeReadOnly()
269
QQmlComponent component(&engine, testFileUrl("stickmanerror1.qml"));
270
QVERIFY(component.isError());
271
QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
274
void tst_qquickanimatedimage::remote_data()
276
QTest::addColumn<QString>("fileName");
277
QTest::addColumn<bool>("paused");
279
QTest::newRow("playing") << "stickman.qml" << false;
280
QTest::newRow("paused") << "stickmanpause.qml" << true;
283
void tst_qquickanimatedimage::invalidSource()
286
QQmlComponent component(&engine);
287
component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
288
QVERIFY(component.isReady());
290
QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
292
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
295
QVERIFY(!anim->isPlaying());
296
QVERIFY(!anim->isPaused());
297
QCOMPARE(anim->currentFrame(), 0);
298
QCOMPARE(anim->frameCount(), 0);
299
QTRY_VERIFY(anim->status() == 3);
302
void tst_qquickanimatedimage::qtbug_16520()
304
TestHTTPServer server(14449);
305
QVERIFY(server.isValid());
306
server.serveDirectory(dataDirectory());
309
QQmlComponent component(&engine, testFileUrl("qtbug-16520.qml"));
310
QTRY_VERIFY(component.isReady());
312
QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
314
QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
316
anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
318
QTRY_VERIFY(anim->opacity() == 0);
319
QTRY_VERIFY(anim->opacity() == 1);
324
void tst_qquickanimatedimage::progressAndStatusChanges()
326
TestHTTPServer server(14449);
327
QVERIFY(server.isValid());
328
server.serveDirectory(dataDirectory());
331
QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
332
QQmlContext *ctxt = engine.rootContext();
333
ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
334
QQmlComponent component(&engine);
335
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
336
QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
338
QVERIFY(obj->status() == QQuickImage::Ready);
339
QTRY_VERIFY(obj->progress() == 1.0);
341
qRegisterMetaType<QQuickImageBase::Status>();
342
QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
343
QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
344
QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
346
// Loading local file
347
ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
348
QTRY_VERIFY(obj->status() == QQuickImage::Ready);
349
QTRY_VERIFY(obj->progress() == 1.0);
350
QTRY_COMPARE(sourceSpy.count(), 1);
351
QTRY_COMPARE(progressSpy.count(), 0);
352
QTRY_COMPARE(statusSpy.count(), 0);
354
// Loading remote file
355
ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
356
QTRY_VERIFY(obj->status() == QQuickImage::Loading);
357
QTRY_VERIFY(obj->progress() == 0.0);
358
QTRY_VERIFY(obj->status() == QQuickImage::Ready);
359
QTRY_VERIFY(obj->progress() == 1.0);
360
QTRY_COMPARE(sourceSpy.count(), 2);
361
QTRY_VERIFY(progressSpy.count() > 1);
362
QTRY_COMPARE(statusSpy.count(), 2);
364
ctxt->setContextProperty("srcImage", "");
365
QTRY_VERIFY(obj->status() == QQuickImage::Null);
366
QTRY_VERIFY(obj->progress() == 0.0);
367
QTRY_COMPARE(sourceSpy.count(), 3);
368
QTRY_VERIFY(progressSpy.count() > 2);
369
QTRY_COMPARE(statusSpy.count(), 3);
372
QTEST_MAIN(tst_qquickanimatedimage)
374
#include "tst_qquickanimatedimage.moc"