1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <QDebug>
31#include "qmediaservice.h"
32#include "qmediaplaylist.h"
33#include <private/qmediaplaylistcontrol_p.h>
34#include <private/qmediaplaylistsourcecontrol_p.h>
35#include <private/qmediaplaylistnavigator_p.h>
36#include <private/qmediapluginloader_p.h>
37
38#include "qm3uhandler.h"
39
40//TESTED_COMPONENT=src/multimedia
41
42#include "mockplaylistservice.h"
43#include "mockmediaplaylistcontrol.h"
44#include "mockmediaplaylistsourcecontrol.h"
45#include "mockreadonlyplaylistprovider.h"
46
47QT_USE_NAMESPACE
48
49class MockPlaylistObject : public QMediaObject
50{
51 Q_OBJECT
52public:
53 MockPlaylistObject(QObject *parent = 0)
54 : QMediaObject(parent, mockService = new MockPlaylistService)
55 {
56 }
57
58 MockPlaylistService *mockService;
59};
60
61class tst_QMediaPlaylist : public QObject
62{
63 Q_OBJECT
64public slots:
65 void init();
66 void cleanup();
67 void initTestCase();
68
69private slots:
70 void construction();
71 void append();
72 void insert();
73 void clear();
74 void removeMedia();
75 void currentItem();
76 void saveAndLoad();
77 void loadM3uFile();
78 void loadPLSFile();
79 void playbackMode();
80 void playbackMode_data();
81 void shuffle();
82 void readOnlyPlaylist();
83 void setMediaObject();
84
85 void testCurrentIndexChanged_signal();
86 void testCurrentMediaChanged_signal();
87 void testLoaded_signal();
88 void testMediaChanged_signal();
89 void testPlaybackModeChanged_signal();
90 void testEnums();
91
92 void mediaPlayListProvider();
93 // TC for Abstract control classes
94 void mediaPlayListControl();
95 void mediaPlayListSourceControl();
96
97
98private:
99 QMediaContent content1;
100 QMediaContent content2;
101 QMediaContent content3;
102};
103
104void tst_QMediaPlaylist::init()
105{
106}
107
108void tst_QMediaPlaylist::initTestCase()
109{
110 qRegisterMetaType<QMediaContent>();
111 content1 = QMediaContent(QUrl(QLatin1String("file:///1")));
112 content2 = QMediaContent(QUrl(QLatin1String("file:///2")));
113 content3 = QMediaContent(QUrl(QLatin1String("file:///3")));
114
115}
116
117void tst_QMediaPlaylist::cleanup()
118{
119}
120
121void tst_QMediaPlaylist::construction()
122{
123 QMediaPlaylist playlist;
124 QCOMPARE(playlist.mediaCount(), 0);
125 QVERIFY(playlist.isEmpty());
126}
127
128void tst_QMediaPlaylist::append()
129{
130 QMediaPlaylist playlist;
131 QVERIFY(!playlist.isReadOnly());
132
133 playlist.addMedia(content: content1);
134 QCOMPARE(playlist.mediaCount(), 1);
135 QCOMPARE(playlist.media(0), content1);
136
137 QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int)));
138 QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int)));
139 playlist.addMedia(content: content2);
140 QCOMPARE(playlist.mediaCount(), 2);
141 QCOMPARE(playlist.media(1), content2);
142
143 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
144 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1);
145 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1);
146
147 QCOMPARE(insertedSignalSpy.count(), 1);
148 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1);
149 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1);
150
151 aboutToBeInsertedSignalSpy.clear();
152 insertedSignalSpy.clear();
153
154 QMediaContent content4(QUrl(QLatin1String("file:///4")));
155 QMediaContent content5(QUrl(QLatin1String("file:///5")));
156 playlist.addMedia(items: QList<QMediaContent>() << content3 << content4 << content5);
157 QCOMPARE(playlist.mediaCount(), 5);
158 QCOMPARE(playlist.media(2), content3);
159 QCOMPARE(playlist.media(3), content4);
160 QCOMPARE(playlist.media(4), content5);
161
162 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
163 QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 2);
164 QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 4);
165
166 QCOMPARE(insertedSignalSpy.count(), 1);
167 QCOMPARE(insertedSignalSpy[0][0].toInt(), 2);
168 QCOMPARE(insertedSignalSpy[0][1].toInt(), 4);
169
170 aboutToBeInsertedSignalSpy.clear();
171 insertedSignalSpy.clear();
172
173 playlist.addMedia(items: QList<QMediaContent>());
174 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0);
175 QCOMPARE(insertedSignalSpy.count(), 0);
176}
177
178void tst_QMediaPlaylist::insert()
179{
180 QMediaPlaylist playlist;
181 QVERIFY(!playlist.isReadOnly());
182
183 playlist.addMedia(content: content1);
184 QCOMPARE(playlist.mediaCount(), 1);
185 QCOMPARE(playlist.media(0), content1);
186
187 playlist.addMedia(content: content2);
188 QCOMPARE(playlist.mediaCount(), 2);
189 QCOMPARE(playlist.media(1), content2);
190
191 QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int)));
192 QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int)));
193
194 playlist.insertMedia(index: 1, content: content3);
195 QCOMPARE(playlist.mediaCount(), 3);
196 QCOMPARE(playlist.media(0), content1);
197 QCOMPARE(playlist.media(1), content3);
198 QCOMPARE(playlist.media(2), content2);
199
200 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
201 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1);
202 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1);
203
204 QCOMPARE(insertedSignalSpy.count(), 1);
205 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1);
206 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1);
207
208 aboutToBeInsertedSignalSpy.clear();
209 insertedSignalSpy.clear();
210
211 QMediaContent content4(QUrl(QLatin1String("file:///4")));
212 QMediaContent content5(QUrl(QLatin1String("file:///5")));
213 playlist.insertMedia(index: 1, items: QList<QMediaContent>() << content4 << content5);
214
215 QCOMPARE(playlist.media(0), content1);
216 QCOMPARE(playlist.media(1), content4);
217 QCOMPARE(playlist.media(2), content5);
218 QCOMPARE(playlist.media(3), content3);
219 QCOMPARE(playlist.media(4), content2);
220 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
221 QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 1);
222 QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 2);
223
224 QCOMPARE(insertedSignalSpy.count(), 1);
225 QCOMPARE(insertedSignalSpy[0][0].toInt(), 1);
226 QCOMPARE(insertedSignalSpy[0][1].toInt(), 2);
227
228 aboutToBeInsertedSignalSpy.clear();
229 insertedSignalSpy.clear();
230
231 playlist.insertMedia(index: 1, items: QList<QMediaContent>());
232 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0);
233 QCOMPARE(insertedSignalSpy.count(), 0);
234
235 playlist.clear();
236 playlist.addMedia(content: content1);
237 aboutToBeInsertedSignalSpy.clear();
238 insertedSignalSpy.clear();
239
240 playlist.insertMedia(index: -10, content: content2);
241 QCOMPARE(playlist.media(0), content2);
242 QCOMPARE(playlist.media(1), content1);
243 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
244 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 0);
245 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 0);
246 QCOMPARE(insertedSignalSpy.count(), 1);
247 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 0);
248 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 0);
249
250 aboutToBeInsertedSignalSpy.clear();
251 insertedSignalSpy.clear();
252
253 playlist.insertMedia(index: 10, content: content3);
254 QCOMPARE(playlist.media(0), content2);
255 QCOMPARE(playlist.media(1), content1);
256 QCOMPARE(playlist.media(2), content3);
257 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
258 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 2);
259 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 2);
260 QCOMPARE(insertedSignalSpy.count(), 1);
261 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 2);
262 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 2);
263
264 aboutToBeInsertedSignalSpy.clear();
265 insertedSignalSpy.clear();
266
267 playlist.insertMedia(index: -10, items: QList<QMediaContent>() << content4 << content5);
268 QCOMPARE(playlist.media(0), content4);
269 QCOMPARE(playlist.media(1), content5);
270 QCOMPARE(playlist.media(2), content2);
271 QCOMPARE(playlist.media(3), content1);
272 QCOMPARE(playlist.media(4), content3);
273 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
274 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 0);
275 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1);
276 QCOMPARE(insertedSignalSpy.count(), 1);
277 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 0);
278 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1);
279
280 aboutToBeInsertedSignalSpy.clear();
281 insertedSignalSpy.clear();
282
283 QMediaContent content6(QUrl(QLatin1String("file:///6")));
284 QMediaContent content7(QUrl(QLatin1String("file:///7")));
285 playlist.insertMedia(index: 10, items: QList<QMediaContent>() << content6 << content7);
286 QCOMPARE(playlist.media(0), content4);
287 QCOMPARE(playlist.media(1), content5);
288 QCOMPARE(playlist.media(2), content2);
289 QCOMPARE(playlist.media(3), content1);
290 QCOMPARE(playlist.media(4), content3);
291 QCOMPARE(playlist.media(5), content6);
292 QCOMPARE(playlist.media(6), content7);
293 QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1);
294 QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 5);
295 QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 6);
296 QCOMPARE(insertedSignalSpy.count(), 1);
297 QCOMPARE(insertedSignalSpy.first()[0].toInt(), 5);
298 QCOMPARE(insertedSignalSpy.first()[1].toInt(), 6);
299}
300
301
302void tst_QMediaPlaylist::currentItem()
303{
304 QMediaPlaylist playlist;
305 playlist.addMedia(content: content1);
306 playlist.addMedia(content: content2);
307
308 QCOMPARE(playlist.currentIndex(), -1);
309 QCOMPARE(playlist.currentMedia(), QMediaContent());
310
311 QCOMPARE(playlist.nextIndex(), 0);
312 QCOMPARE(playlist.nextIndex(2), 1);
313 QCOMPARE(playlist.previousIndex(), 1);
314 QCOMPARE(playlist.previousIndex(2), 0);
315
316 playlist.setCurrentIndex(0);
317 QCOMPARE(playlist.currentIndex(), 0);
318 QCOMPARE(playlist.currentMedia(), content1);
319
320 QCOMPARE(playlist.nextIndex(), 1);
321 QCOMPARE(playlist.nextIndex(2), -1);
322 QCOMPARE(playlist.previousIndex(), -1);
323 QCOMPARE(playlist.previousIndex(2), -1);
324
325 playlist.setCurrentIndex(1);
326 QCOMPARE(playlist.currentIndex(), 1);
327 QCOMPARE(playlist.currentMedia(), content2);
328
329 QCOMPARE(playlist.nextIndex(), -1);
330 QCOMPARE(playlist.nextIndex(2), -1);
331 QCOMPARE(playlist.previousIndex(), 0);
332 QCOMPARE(playlist.previousIndex(2), -1);
333
334 playlist.setCurrentIndex(2);
335
336 QCOMPARE(playlist.currentIndex(), -1);
337 QCOMPARE(playlist.currentMedia(), QMediaContent());
338}
339
340void tst_QMediaPlaylist::clear()
341{
342 QMediaPlaylist playlist;
343 playlist.addMedia(content: content1);
344 playlist.addMedia(content: content2);
345
346 playlist.clear();
347 QVERIFY(playlist.isEmpty());
348 QCOMPARE(playlist.mediaCount(), 0);
349}
350
351void tst_QMediaPlaylist::removeMedia()
352{
353 QMediaPlaylist playlist;
354 playlist.addMedia(content: content1);
355 playlist.addMedia(content: content2);
356 playlist.addMedia(content: content3);
357
358 QSignalSpy aboutToBeRemovedSignalSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int,int)));
359 QSignalSpy removedSignalSpy(&playlist, SIGNAL(mediaRemoved(int,int)));
360 playlist.removeMedia(pos: 1);
361 QCOMPARE(playlist.mediaCount(), 2);
362 QCOMPARE(playlist.media(1), content3);
363
364 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1);
365 QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 1);
366 QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1);
367
368 QCOMPARE(removedSignalSpy.count(), 1);
369 QCOMPARE(removedSignalSpy.first()[0].toInt(), 1);
370 QCOMPARE(removedSignalSpy.first()[1].toInt(), 1);
371
372 aboutToBeRemovedSignalSpy.clear();
373 removedSignalSpy.clear();
374
375 playlist.removeMedia(start: 0,end: 1);
376 QVERIFY(playlist.isEmpty());
377
378 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1);
379 QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0);
380 QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1);
381
382 QCOMPARE(removedSignalSpy.count(), 1);
383 QCOMPARE(removedSignalSpy.first()[0].toInt(), 0);
384 QCOMPARE(removedSignalSpy.first()[1].toInt(), 1);
385
386
387 playlist.addMedia(content: content1);
388 playlist.addMedia(content: content2);
389 playlist.addMedia(content: content3);
390
391 playlist.removeMedia(start: 0,end: 1);
392 QCOMPARE(playlist.mediaCount(), 1);
393 QCOMPARE(playlist.media(0), content3);
394
395 QCOMPARE(playlist.removeMedia(-1), false);
396 QCOMPARE(playlist.removeMedia(1), false);
397
398 playlist.addMedia(content: content1);
399 aboutToBeRemovedSignalSpy.clear();
400 removedSignalSpy.clear();
401
402 playlist.removeMedia(start: -10, end: 10);
403 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1);
404 QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0);
405 QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1);
406 QCOMPARE(removedSignalSpy.count(), 1);
407 QCOMPARE(removedSignalSpy.first()[0].toInt(), 0);
408 QCOMPARE(removedSignalSpy.first()[1].toInt(), 1);
409
410 playlist.addMedia(content: content1);
411 playlist.addMedia(content: content2);
412 playlist.addMedia(content: content3);
413 aboutToBeRemovedSignalSpy.clear();
414 removedSignalSpy.clear();
415
416 QCOMPARE(playlist.removeMedia(10, -10), false);
417 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0);
418 QCOMPARE(removedSignalSpy.count(), 0);
419 QCOMPARE(playlist.removeMedia(-10, -5), false);
420 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0);
421 QCOMPARE(removedSignalSpy.count(), 0);
422 QCOMPARE(playlist.removeMedia(5, 10), false);
423 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0);
424 QCOMPARE(removedSignalSpy.count(), 0);
425
426 playlist.removeMedia(start: 1, end: 10);
427 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1);
428 QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 1);
429 QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 2);
430 QCOMPARE(removedSignalSpy.count(), 1);
431 QCOMPARE(removedSignalSpy.first()[0].toInt(), 1);
432 QCOMPARE(removedSignalSpy.first()[1].toInt(), 2);
433
434 playlist.addMedia(content: content2);
435 playlist.addMedia(content: content3);
436 aboutToBeRemovedSignalSpy.clear();
437 removedSignalSpy.clear();
438
439 playlist.removeMedia(start: -10, end: 1);
440 QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1);
441 QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0);
442 QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1);
443 QCOMPARE(removedSignalSpy.count(), 1);
444 QCOMPARE(removedSignalSpy.first()[0].toInt(), 0);
445 QCOMPARE(removedSignalSpy.first()[1].toInt(), 1);
446}
447
448void tst_QMediaPlaylist::saveAndLoad()
449{
450 QMediaPlaylist playlist;
451 playlist.addMedia(content: content1);
452 playlist.addMedia(content: content2);
453 playlist.addMedia(content: content3);
454
455 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
456 QVERIFY(playlist.errorString().isEmpty());
457
458 QBuffer buffer;
459 buffer.open(openMode: QBuffer::ReadWrite);
460
461 bool res = playlist.save(device: &buffer, format: "unsupported_format");
462 QVERIFY(!res);
463 QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
464 QVERIFY(!playlist.errorString().isEmpty());
465
466 QSignalSpy loadedSignal(&playlist, SIGNAL(loaded()));
467 QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed()));
468 playlist.load(device: &buffer, format: "unsupported_format");
469 QTRY_VERIFY(loadedSignal.isEmpty());
470 QCOMPARE(errorSignal.size(), 1);
471 QVERIFY(playlist.error() != QMediaPlaylist::NoError);
472 QVERIFY(!playlist.errorString().isEmpty());
473
474 res = playlist.save(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.unsupported_format")), format: "unsupported_format");
475 QVERIFY(!res);
476 QVERIFY(playlist.error() != QMediaPlaylist::NoError);
477 QVERIFY(!playlist.errorString().isEmpty());
478
479 loadedSignal.clear();
480 errorSignal.clear();
481 playlist.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.unsupported_format")), format: "unsupported_format");
482 QTRY_VERIFY(loadedSignal.isEmpty());
483 QCOMPARE(errorSignal.size(), 1);
484 QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
485 QVERIFY(!playlist.errorString().isEmpty());
486
487 res = playlist.save(device: &buffer, format: "m3u");
488
489 QVERIFY(res);
490 QVERIFY(buffer.pos() > 0);
491 buffer.seek(off: 0);
492
493 QMediaPlaylist playlist2;
494 QSignalSpy loadedSignal2(&playlist2, SIGNAL(loaded()));
495 QSignalSpy errorSignal2(&playlist2, SIGNAL(loadFailed()));
496 playlist2.load(device: &buffer, format: "m3u");
497 QCOMPARE(loadedSignal2.size(), 1);
498 QTRY_VERIFY(errorSignal2.isEmpty());
499 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
500
501 QCOMPARE(playlist.mediaCount(), playlist2.mediaCount());
502 QCOMPARE(playlist.media(0), playlist2.media(0));
503 QCOMPARE(playlist.media(1), playlist2.media(1));
504 QCOMPARE(playlist.media(3), playlist2.media(3));
505 res = playlist.save(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u")), format: "m3u");
506 QVERIFY(res);
507
508 loadedSignal2.clear();
509 errorSignal2.clear();
510 playlist2.clear();
511 QVERIFY(playlist2.isEmpty());
512 playlist2.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u")), format: "m3u");
513 QCOMPARE(loadedSignal2.size(), 1);
514 QTRY_VERIFY(errorSignal2.isEmpty());
515 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
516
517 QCOMPARE(playlist.mediaCount(), playlist2.mediaCount());
518 QCOMPARE(playlist.media(0), playlist2.media(0));
519 QCOMPARE(playlist.media(1), playlist2.media(1));
520 QCOMPARE(playlist.media(3), playlist2.media(3));
521}
522
523void tst_QMediaPlaylist::loadM3uFile()
524{
525 QMediaPlaylist playlist;
526
527 // Try to load playlist that does not exist in the testdata folder
528 QSignalSpy loadSpy(&playlist, SIGNAL(loaded()));
529 QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed()));
530 QString testFileName = QFINDTESTDATA("testdata");
531 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName + "/missing_file.m3u"));
532 QTRY_VERIFY(loadSpy.isEmpty());
533 QVERIFY(!loadFailedSpy.isEmpty());
534 QVERIFY(playlist.error() != QMediaPlaylist::NoError);
535
536 loadSpy.clear();
537 loadFailedSpy.clear();
538 testFileName = QFINDTESTDATA("testdata/test.m3u");
539 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName));
540 QTRY_VERIFY(!loadSpy.isEmpty());
541 QVERIFY(loadFailedSpy.isEmpty());
542 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
543 QCOMPARE(playlist.mediaCount(), 7);
544
545 QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path")));
546 QCOMPARE(playlist.media(1).request().url(), QUrl(QLatin1String("http://test.host/path")));
547 testFileName = QFINDTESTDATA("testdata/testfile");
548 QCOMPARE(playlist.media(2).request().url(),
549 QUrl::fromLocalFile(testFileName));
550 testFileName = QFINDTESTDATA("testdata");
551 QCOMPARE(playlist.media(3).request().url(),
552 QUrl::fromLocalFile(testFileName + "/testdir/testfile"));
553 QCOMPARE(playlist.media(4).request().url(), QUrl(QLatin1String("file:///testdir/testfile")));
554 QCOMPARE(playlist.media(5).request().url(), QUrl(QLatin1String("file://path/name#suffix")));
555 //ensure #2 suffix is not stripped from path
556 testFileName = QFINDTESTDATA("testdata/testfile2#suffix");
557 QCOMPARE(playlist.media(6).request().url(), QUrl::fromLocalFile(testFileName));
558
559 // check ability to load from QNetworkRequest
560 loadSpy.clear();
561 loadFailedSpy.clear();
562 playlist.load(request: QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.m3u"))));
563 QTRY_VERIFY(!loadSpy.isEmpty());
564 QVERIFY(loadFailedSpy.isEmpty());
565}
566
567void tst_QMediaPlaylist::loadPLSFile()
568{
569 QMediaPlaylist playlist;
570
571 // Try to load playlist that does not exist in the testdata folder
572 QSignalSpy loadSpy(&playlist, SIGNAL(loaded()));
573 QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed()));
574 QString testFileName = QFINDTESTDATA("testdata");
575 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName + "/missing_file.pls"));
576 QTRY_VERIFY(loadSpy.isEmpty());
577 QVERIFY(!loadFailedSpy.isEmpty());
578 QVERIFY(playlist.error() != QMediaPlaylist::NoError);
579
580 // Try to load empty playlist
581 loadSpy.clear();
582 loadFailedSpy.clear();
583 testFileName = QFINDTESTDATA("testdata/empty.pls");
584 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName));
585 QTRY_VERIFY(!loadSpy.isEmpty());
586 QVERIFY(loadFailedSpy.isEmpty());
587 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
588 QCOMPARE(playlist.mediaCount(), 0);
589
590 // Try to load regular playlist
591 loadSpy.clear();
592 loadFailedSpy.clear();
593 testFileName = QFINDTESTDATA("testdata/test.pls");
594 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName));
595 QTRY_VERIFY(!loadSpy.isEmpty());
596 QVERIFY(loadFailedSpy.isEmpty());
597 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
598 QCOMPARE(playlist.mediaCount(), 7);
599
600 QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path")));
601 QCOMPARE(playlist.media(1).request().url(), QUrl(QLatin1String("http://test.host/path")));
602 testFileName = QFINDTESTDATA("testdata/testfile");
603 QCOMPARE(playlist.media(2).request().url(),
604 QUrl::fromLocalFile(testFileName));
605 testFileName = QFINDTESTDATA("testdata");
606 QCOMPARE(playlist.media(3).request().url(),
607 QUrl::fromLocalFile(testFileName + "/testdir/testfile"));
608 QCOMPARE(playlist.media(4).request().url(), QUrl(QLatin1String("file:///testdir/testfile")));
609 QCOMPARE(playlist.media(5).request().url(), QUrl(QLatin1String("file://path/name#suffix")));
610 //ensure #2 suffix is not stripped from path
611 testFileName = QFINDTESTDATA("testdata/testfile2#suffix");
612 QCOMPARE(playlist.media(6).request().url(), QUrl::fromLocalFile(testFileName));
613
614 // Try to load a totem-pl generated playlist
615 // (Format doesn't respect the spec)
616 loadSpy.clear();
617 loadFailedSpy.clear();
618 playlist.clear();
619 testFileName = QFINDTESTDATA("testdata/totem-pl-example.pls");
620 playlist.load(location: QUrl::fromLocalFile(localfile: testFileName));
621 QTRY_VERIFY(!loadSpy.isEmpty());
622 QVERIFY(loadFailedSpy.isEmpty());
623 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
624 QCOMPARE(playlist.mediaCount(), 1);
625 QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path")));
626
627
628 // check ability to load from QNetworkRequest
629 loadSpy.clear();
630 loadFailedSpy.clear();
631 playlist.load(request: QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.pls"))));
632 QTRY_VERIFY(!loadSpy.isEmpty());
633 QVERIFY(loadFailedSpy.isEmpty());
634}
635
636void tst_QMediaPlaylist::playbackMode_data()
637{
638 QTest::addColumn<QMediaPlaylist::PlaybackMode>(name: "playbackMode");
639 QTest::addColumn<int>(name: "expectedPrevious");
640 QTest::addColumn<int>(name: "pos");
641 QTest::addColumn<int>(name: "expectedNext");
642
643 QTest::newRow(dataTag: "Sequential, 0") << QMediaPlaylist::Sequential << -1 << 0 << 1;
644 QTest::newRow(dataTag: "Sequential, 1") << QMediaPlaylist::Sequential << 0 << 1 << 2;
645 QTest::newRow(dataTag: "Sequential, 2") << QMediaPlaylist::Sequential << 1 << 2 << -1;
646
647 QTest::newRow(dataTag: "Loop, 0") << QMediaPlaylist::Loop << 2 << 0 << 1;
648 QTest::newRow(dataTag: "Loop, 1") << QMediaPlaylist::Loop << 0 << 1 << 2;
649 QTest::newRow(dataTag: "Lopp, 2") << QMediaPlaylist::Loop << 1 << 2 << 0;
650
651 QTest::newRow(dataTag: "ItemOnce, 1") << QMediaPlaylist::CurrentItemOnce << -1 << 1 << -1;
652 QTest::newRow(dataTag: "ItemInLoop, 1") << QMediaPlaylist::CurrentItemInLoop << 1 << 1 << 1;
653
654 // Bit difficult to test random this way
655}
656
657void tst_QMediaPlaylist::playbackMode()
658{
659 QFETCH(QMediaPlaylist::PlaybackMode, playbackMode);
660 QFETCH(int, expectedPrevious);
661 QFETCH(int, pos);
662 QFETCH(int, expectedNext);
663
664 QMediaPlaylist playlist;
665 playlist.addMedia(content: content1);
666 playlist.addMedia(content: content2);
667 playlist.addMedia(content: content3);
668
669 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Sequential);
670 QCOMPARE(playlist.currentIndex(), -1);
671
672 playlist.setPlaybackMode(playbackMode);
673 QCOMPARE(playlist.playbackMode(), playbackMode);
674
675 playlist.setCurrentIndex(pos);
676 QCOMPARE(playlist.currentIndex(), pos);
677 QCOMPARE(playlist.nextIndex(), expectedNext);
678 QCOMPARE(playlist.previousIndex(), expectedPrevious);
679
680 playlist.next();
681 QCOMPARE(playlist.currentIndex(), expectedNext);
682
683 playlist.setCurrentIndex(pos);
684 playlist.previous();
685 QCOMPARE(playlist.currentIndex(), expectedPrevious);
686}
687
688void tst_QMediaPlaylist::shuffle()
689{
690 QMediaPlaylist playlist;
691 QList<QMediaContent> contentList;
692
693 for (int i=0; i<100; i++) {
694 QMediaContent content(QUrl::fromLocalFile(localfile: QString::number(i)));
695 contentList.append(t: content);
696 playlist.addMedia(content);
697 }
698
699 playlist.shuffle();
700
701 QList<QMediaContent> shuffledContentList;
702 for (int i=0; i<playlist.mediaCount(); i++)
703 shuffledContentList.append(t: playlist.media(index: i));
704
705 QVERIFY(contentList != shuffledContentList);
706
707}
708
709void tst_QMediaPlaylist::readOnlyPlaylist()
710{
711 MockPlaylistObject mediaObject;
712 mediaObject.mockService->mockControl->setReadOnly(true);
713
714 QMediaPlaylist playlist;
715 mediaObject.bind(&playlist);
716
717 QVERIFY(playlist.isReadOnly());
718 QVERIFY(!playlist.isEmpty());
719 QCOMPARE(playlist.mediaCount(), 3);
720
721 QCOMPARE(playlist.media(0), content1);
722 QCOMPARE(playlist.media(1), content2);
723 QCOMPARE(playlist.media(2), content3);
724 QCOMPARE(playlist.media(3), QMediaContent());
725
726 //it's a read only playlist, so all the modification should fail
727 QVERIFY(!playlist.addMedia(content1));
728 QCOMPARE(playlist.mediaCount(), 3);
729 QVERIFY(!playlist.addMedia(QList<QMediaContent>() << content1 << content2));
730 QCOMPARE(playlist.mediaCount(), 3);
731 QVERIFY(!playlist.insertMedia(1, content1));
732 QCOMPARE(playlist.mediaCount(), 3);
733 QVERIFY(!playlist.insertMedia(1, QList<QMediaContent>() << content1 << content2));
734 QCOMPARE(playlist.mediaCount(), 3);
735 QVERIFY(!playlist.removeMedia(1));
736 QCOMPARE(playlist.mediaCount(), 3);
737 QVERIFY(!playlist.removeMedia(0,2));
738 QCOMPARE(playlist.mediaCount(), 3);
739 QVERIFY(!playlist.clear());
740 QCOMPARE(playlist.mediaCount(), 3);
741
742 //but it is still allowed to append/insert an empty list
743 QVERIFY(playlist.addMedia(QList<QMediaContent>()));
744 QVERIFY(playlist.insertMedia(1, QList<QMediaContent>()));
745
746 playlist.shuffle();
747 //it's still the same
748 QCOMPARE(playlist.media(0), content1);
749 QCOMPARE(playlist.media(1), content2);
750 QCOMPARE(playlist.media(2), content3);
751 QCOMPARE(playlist.media(3), QMediaContent());
752
753
754 //load to read only playlist should fail,
755 //unless underlaying provider supports it
756 QBuffer buffer;
757 buffer.open(openMode: QBuffer::ReadWrite);
758 buffer.write(data: QByteArray("file:///1\nfile:///2"));
759 buffer.seek(off: 0);
760
761 QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed()));
762 playlist.load(device: &buffer, format: "m3u");
763 QCOMPARE(errorSignal.size(), 1);
764 QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError);
765 QVERIFY(!playlist.errorString().isEmpty());
766 QCOMPARE(playlist.mediaCount(), 3);
767
768 errorSignal.clear();
769 playlist.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u")), format: "m3u");
770
771 QCOMPARE(errorSignal.size(), 1);
772 QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError);
773 QVERIFY(!playlist.errorString().isEmpty());
774 QCOMPARE(playlist.mediaCount(), 3);
775}
776
777void tst_QMediaPlaylist::setMediaObject()
778{
779 QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3")));
780 QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3")));
781 QMediaContent content2(QUrl(QLatin1String("test://video/movie1.mp4")));
782 QMediaContent content3(QUrl(QLatin1String("test://video/movie2.mp4")));
783
784 {
785 MockPlaylistObject mediaObject;
786
787 QMediaPlaylist playlist;
788 QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int)));
789 QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
790 QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int)));
791 QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int)));
792 QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int)));
793 QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int)));
794 QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int)));
795
796 QVERIFY(playlist.isEmpty());
797
798 mediaObject.bind(&playlist);
799
800 // Playlist is now using the service's control, nothing should have changed
801 QVERIFY(playlist.isEmpty());
802 QCOMPARE(playlist.currentIndex(), -1);
803 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Sequential);
804 QCOMPARE(currentIndexSpy.count(), 0);
805 QCOMPARE(playbackModeSpy.count(), 0);
806 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
807 QCOMPARE(mediaInsertedSpy.count(), 0);
808 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
809 QCOMPARE(mediaRemovedSpy.count(), 0);
810 QCOMPARE(mediaChangedSpy.count(), 0);
811
812 // add items to service's playlist control
813 playlist.addMedia(content: content0);
814 playlist.addMedia(content: content1);
815 playlist.setCurrentIndex(1);
816 playlist.setPlaybackMode(QMediaPlaylist::Random);
817 QCOMPARE(playlist.mediaCount(), 2);
818 QCOMPARE(playlist.currentIndex(), 1);
819 QCOMPARE(playlist.currentMedia(), content1);
820 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random);
821
822 currentIndexSpy.clear();
823 playbackModeSpy.clear();
824 mediaAboutToBeInsertedSpy.clear();
825 mediaInsertedSpy.clear();
826 mediaAboutToBeRemovedSpy.clear();
827 mediaRemovedSpy.clear();
828 mediaChangedSpy.clear();
829
830 // unbind the playlist, reverting back to the internal control.
831 // playlist content should't have changed.
832 mediaObject.unbind(&playlist);
833 QCOMPARE(playlist.mediaCount(), 2);
834 QCOMPARE(playlist.currentIndex(), 1);
835 QCOMPARE(playlist.currentMedia(), content1);
836 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random);
837 QCOMPARE(playbackModeSpy.count(), 0);
838 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
839 QCOMPARE(mediaInsertedSpy.count(), 0);
840 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
841 QCOMPARE(mediaRemovedSpy.count(), 0);
842 QCOMPARE(mediaChangedSpy.count(), 0);
843 }
844 {
845 MockPlaylistObject mediaObject;
846
847 QMediaPlaylist playlist;
848 QVERIFY(playlist.isEmpty());
849 // Add items to playlist before binding to the service (internal control)
850 playlist.addMedia(content: content0);
851 playlist.addMedia(content: content1);
852 playlist.addMedia(content: content2);
853 playlist.setCurrentIndex(2);
854 playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
855
856 QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int)));
857 QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
858 QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int)));
859 QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int)));
860 QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int)));
861 QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int)));
862 QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int)));
863
864 // Bind playlist, content should be unchanged
865 mediaObject.bind(&playlist);
866 QCOMPARE(playlist.mediaCount(), 3);
867 QCOMPARE(playlist.currentIndex(), 2);
868 QCOMPARE(playlist.currentMedia(), content2);
869 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
870 QCOMPARE(currentIndexSpy.count(), 0);
871 QCOMPARE(playbackModeSpy.count(), 0);
872 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
873 QCOMPARE(mediaInsertedSpy.count(), 0);
874 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
875 QCOMPARE(mediaRemovedSpy.count(), 0);
876 QCOMPARE(mediaChangedSpy.count(), 0);
877
878 // Clear playlist content (service's playlist control)
879 playlist.clear();
880 playlist.setCurrentIndex(-1);
881 playlist.setPlaybackMode(QMediaPlaylist::Random);
882
883 currentIndexSpy.clear();
884 playbackModeSpy.clear();
885 mediaAboutToBeInsertedSpy.clear();
886 mediaInsertedSpy.clear();
887 mediaAboutToBeRemovedSpy.clear();
888 mediaRemovedSpy.clear();
889 mediaChangedSpy.clear();
890
891 // unbind playlist from service, reverting back to the internal control.
892 // playlist should still be empty
893 mediaObject.unbind(&playlist);
894 QCOMPARE(playlist.mediaCount(), 0);
895 QCOMPARE(playlist.currentIndex(), -1);
896 QCOMPARE(playlist.currentMedia(), QMediaContent());
897 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random);
898 QCOMPARE(playbackModeSpy.count(), 0);
899 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
900 QCOMPARE(mediaInsertedSpy.count(), 0);
901 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
902 QCOMPARE(mediaRemovedSpy.count(), 0);
903 QCOMPARE(mediaChangedSpy.count(), 0);
904 }
905 {
906 MockPlaylistObject mediaObject;
907
908 QMediaPlaylist playlist;
909 QVERIFY(playlist.isEmpty());
910 // Add items to playlist before attaching to media player (internal control)
911 playlist.addMedia(content: content0);
912 playlist.addMedia(content: content1);
913 playlist.setCurrentIndex(-1);
914 playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
915
916 // Add items to service's playlist before binding
917 QMediaPlaylistProvider *pp = mediaObject.mockService->mockControl->playlistProvider();
918 pp->addMedia(content: content2);
919 pp->addMedia(content: content3);
920 mediaObject.mockService->mockControl->setCurrentIndex(1);
921 mediaObject.mockService->mockControl->setPlaybackMode(QMediaPlaylist::Random);
922
923 QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int)));
924 QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
925 QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int)));
926 QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int)));
927 QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int)));
928 QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int)));
929 QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int)));
930
931 // Bind playlist, it should contain only what was explicitly added to the playlist.
932 // Anything that was present in the service's control should have been cleared
933 mediaObject.bind(&playlist);
934 QCOMPARE(playlist.mediaCount(), 2);
935 QCOMPARE(playlist.currentIndex(), -1);
936 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
937 QCOMPARE(currentIndexSpy.count(), 0);
938 QCOMPARE(playbackModeSpy.count(), 0);
939 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
940 QCOMPARE(mediaInsertedSpy.count(), 0);
941 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
942 QCOMPARE(mediaRemovedSpy.count(), 0);
943 QCOMPARE(mediaChangedSpy.count(), 0);
944
945 // do some changes
946 playlist.removeMedia(pos: 0); // content0
947 playlist.addMedia(content: content3);
948 playlist.setCurrentIndex(0);
949
950 currentIndexSpy.clear();
951 playbackModeSpy.clear();
952 mediaAboutToBeInsertedSpy.clear();
953 mediaInsertedSpy.clear();
954 mediaAboutToBeRemovedSpy.clear();
955 mediaRemovedSpy.clear();
956 mediaChangedSpy.clear();
957
958 // unbind playlist from service
959 mediaObject.unbind(&playlist);
960 QCOMPARE(playlist.mediaCount(), 2);
961 QCOMPARE(playlist.currentIndex(), 0);
962 QCOMPARE(playlist.currentMedia(), content1);
963 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
964 QCOMPARE(currentIndexSpy.count(), 0);
965 QCOMPARE(playbackModeSpy.count(), 0);
966 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
967 QCOMPARE(mediaInsertedSpy.count(), 0);
968 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
969 QCOMPARE(mediaRemovedSpy.count(), 0);
970 QCOMPARE(mediaChangedSpy.count(), 0);
971
972 // bind again, nothing should have changed
973 mediaObject.bind(&playlist);
974 QCOMPARE(playlist.mediaCount(), 2);
975 QCOMPARE(playlist.currentIndex(), 0);
976 QCOMPARE(playlist.currentMedia(), content1);
977 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
978 QCOMPARE(currentIndexSpy.count(), 0);
979 QCOMPARE(playbackModeSpy.count(), 0);
980 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
981 QCOMPARE(mediaInsertedSpy.count(), 0);
982 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
983 QCOMPARE(mediaRemovedSpy.count(), 0);
984 QCOMPARE(mediaChangedSpy.count(), 0);
985 }
986 {
987 MockPlaylistObject mediaObject;
988 mediaObject.mockService->mockControl->setReadOnly(true);
989
990 QMediaPlaylist playlist;
991 QVERIFY(playlist.isEmpty());
992 // Add items to playlist before binding to the service internal control)
993 playlist.addMedia(content: content0);
994 playlist.addMedia(content: content1);
995 playlist.setCurrentIndex(-1);
996 playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
997
998 QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int)));
999 QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
1000 QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int)));
1001 QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int)));
1002 QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int)));
1003 QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int)));
1004 QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int)));
1005
1006 // Bind playlist. Since the service's control is read-only, no synchronization
1007 // should be done with the internal control. The mediaRemoved() and mediaInserted()
1008 // should be emitted to notify about the change.
1009 mediaObject.bind(&playlist);
1010 QCOMPARE(playlist.mediaCount(), 3);
1011 QCOMPARE(playlist.currentIndex(), -1);
1012 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
1013 QCOMPARE(currentIndexSpy.count(), 0);
1014 QCOMPARE(playbackModeSpy.count(), 0);
1015
1016 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 1);
1017 QCOMPARE(mediaAboutToBeRemovedSpy.last().at(0).toInt(), 0);
1018 QCOMPARE(mediaAboutToBeRemovedSpy.last().at(1).toInt(), 1);
1019 QCOMPARE(mediaRemovedSpy.count(), 1);
1020 QCOMPARE(mediaRemovedSpy.last().at(0).toInt(), 0);
1021 QCOMPARE(mediaRemovedSpy.last().at(1).toInt(), 1);
1022
1023 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 1);
1024 QCOMPARE(mediaAboutToBeInsertedSpy.last().at(0).toInt(), 0);
1025 QCOMPARE(mediaAboutToBeInsertedSpy.last().at(1).toInt(), 2);
1026 QCOMPARE(mediaInsertedSpy.count(), 1);
1027 QCOMPARE(mediaInsertedSpy.last().at(0).toInt(), 0);
1028 QCOMPARE(mediaInsertedSpy.last().at(1).toInt(), 2);
1029
1030 QCOMPARE(mediaChangedSpy.count(), 0);
1031
1032 currentIndexSpy.clear();
1033 playbackModeSpy.clear();
1034 mediaAboutToBeInsertedSpy.clear();
1035 mediaInsertedSpy.clear();
1036 mediaAboutToBeRemovedSpy.clear();
1037 mediaRemovedSpy.clear();
1038 mediaChangedSpy.clear();
1039
1040 // detach playlist from player
1041 mediaObject.unbind(&playlist);
1042 QCOMPARE(playlist.mediaCount(), 3);
1043 QCOMPARE(playlist.currentIndex(), -1);
1044 QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce);
1045 QCOMPARE(currentIndexSpy.count(), 0);
1046 QCOMPARE(playbackModeSpy.count(), 0);
1047 QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0);
1048 QCOMPARE(mediaInsertedSpy.count(), 0);
1049 QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0);
1050 QCOMPARE(mediaRemovedSpy.count(), 0);
1051 QCOMPARE(mediaChangedSpy.count(), 0);
1052 }
1053}
1054
1055void tst_QMediaPlaylist::testCurrentIndexChanged_signal()
1056{
1057 //create an instance of QMediaPlaylist class.
1058 QMediaPlaylist playlist;
1059 playlist.addMedia(content: content1); //set the media to playlist
1060 playlist.addMedia(content: content2); //set the media to playlist
1061
1062 QSignalSpy spy(&playlist, SIGNAL(currentIndexChanged(int)));
1063 QVERIFY(spy.size()== 0);
1064 QCOMPARE(playlist.currentIndex(), -1);
1065
1066 //set the current index for playlist.
1067 playlist.setCurrentIndex(0);
1068 QVERIFY(spy.size()== 1); //verify the signal emission.
1069 QCOMPARE(playlist.currentIndex(), 0); //verify the current index of playlist
1070
1071 //set the current index for playlist.
1072 playlist.setCurrentIndex(1);
1073 QVERIFY(spy.size()== 2); //verify the signal emission.
1074 QCOMPARE(playlist.currentIndex(), 1); //verify the current index of playlist
1075}
1076
1077void tst_QMediaPlaylist::testCurrentMediaChanged_signal()
1078{
1079 //create an instance of QMediaPlaylist class.
1080 QMediaPlaylist playlist;
1081 playlist.addMedia(content: content1); //set the media to playlist
1082 playlist.addMedia(content: content2); //set the media to playlist
1083
1084 QSignalSpy spy(&playlist, SIGNAL(currentMediaChanged(QMediaContent)));
1085 QVERIFY(spy.size()== 0);
1086 QCOMPARE(playlist.currentIndex(), -1);
1087 QCOMPARE(playlist.currentMedia(), QMediaContent());
1088
1089 //set the current index for playlist.
1090 playlist.setCurrentIndex(0);
1091 QVERIFY(spy.size()== 1); //verify the signal emission.
1092 QCOMPARE(playlist.currentIndex(), 0); //verify the current index of playlist
1093 QCOMPARE(playlist.currentMedia(), content1); //verify the current media of playlist
1094
1095 //set the current index for playlist.
1096 playlist.setCurrentIndex(1);
1097 QVERIFY(spy.size()== 2); //verify the signal emission.
1098 QCOMPARE(playlist.currentIndex(), 1); //verify the current index of playlist
1099 QCOMPARE(playlist.currentMedia(), content2); //verify the current media of playlist
1100}
1101
1102void tst_QMediaPlaylist::testLoaded_signal()
1103{
1104 //create an instance of QMediaPlaylist class.
1105 QMediaPlaylist playlist;
1106 playlist.addMedia(content: content1); //set the media to playlist
1107 playlist.addMedia(content: content2); //set the media to playlist
1108 playlist.addMedia(content: content3); //set the media to playlist
1109
1110 QSignalSpy spy(&playlist, SIGNAL(loaded()));
1111 QVERIFY(spy.size()== 0);
1112
1113 QBuffer buffer;
1114 buffer.open(openMode: QBuffer::ReadWrite);
1115
1116 //load the playlist
1117 playlist.load(device: &buffer,format: "m3u");
1118 QVERIFY(spy.size()== 1); //verify the signal emission.
1119}
1120
1121void tst_QMediaPlaylist::testMediaChanged_signal()
1122{
1123 //create an instance of QMediaPlaylist class.
1124 QMediaPlaylist playlist;
1125
1126 QSignalSpy spy(&playlist, SIGNAL(mediaChanged(int,int)));
1127
1128 // Add media to playlist
1129 playlist.addMedia(content: content1); //set the media to playlist
1130 playlist.addMedia(content: content2); //set the media to playlist
1131 playlist.addMedia(content: content3); //set the media to playlist
1132
1133 // Adds/inserts do not cause change signals
1134 QVERIFY(spy.size() == 0);
1135
1136 // Now change the list
1137 playlist.shuffle();
1138
1139 QVERIFY(spy.size() == 1);
1140 spy.clear();
1141
1142 //create media.
1143 QMediaContent content4(QUrl(QLatin1String("file:///4")));
1144 QMediaContent content5(QUrl(QLatin1String("file:///5")));
1145
1146 //insert media to playlist
1147 playlist.insertMedia(index: 1, content: content4);
1148 playlist.insertMedia(index: 2, content: content5);
1149 // Adds/inserts do not cause change signals
1150 QVERIFY(spy.size() == 0);
1151
1152 // And again
1153 playlist.shuffle();
1154
1155 QVERIFY(spy.size() == 1);
1156}
1157
1158void tst_QMediaPlaylist::testPlaybackModeChanged_signal()
1159{
1160 //create an instance of QMediaPlaylist class.
1161 QMediaPlaylist playlist;
1162 playlist.addMedia(content: content1); //set the media to playlist
1163 playlist.addMedia(content: content2); //set the media to playlist
1164 playlist.addMedia(content: content3); //set the media to playlist
1165
1166 QSignalSpy spy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
1167 QVERIFY(playlist.playbackMode()== QMediaPlaylist::Sequential);
1168 QVERIFY(spy.size() == 0);
1169
1170 // Set playback mode to the playlist
1171 playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
1172 QVERIFY(playlist.playbackMode()== QMediaPlaylist::CurrentItemOnce);
1173 QVERIFY(spy.size() == 1);
1174
1175 // Set playback mode to the playlist
1176 playlist.setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
1177 QVERIFY(playlist.playbackMode()== QMediaPlaylist::CurrentItemInLoop);
1178 QVERIFY(spy.size() == 2);
1179
1180 // Set playback mode to the playlist
1181 playlist.setPlaybackMode(QMediaPlaylist::Sequential);
1182 QVERIFY(playlist.playbackMode()== QMediaPlaylist::Sequential);
1183 QVERIFY(spy.size() == 3);
1184
1185 // Set playback mode to the playlist
1186 playlist.setPlaybackMode(QMediaPlaylist::Loop);
1187 QVERIFY(playlist.playbackMode()== QMediaPlaylist::Loop);
1188 QVERIFY(spy.size() == 4);
1189
1190 // Set playback mode to the playlist
1191 playlist.setPlaybackMode(QMediaPlaylist::Random);
1192 QVERIFY(playlist.playbackMode()== QMediaPlaylist::Random);
1193 QVERIFY(spy.size() == 5);
1194}
1195
1196void tst_QMediaPlaylist::testEnums()
1197{
1198 //create an instance of QMediaPlaylist class.
1199 QMediaPlaylist playlist;
1200 playlist.addMedia(content: content1); //set the media to playlist
1201 playlist.addMedia(content: content2); //set the media to playlist
1202 playlist.addMedia(content: content3); //set the media to playlist
1203 QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
1204
1205 QBuffer buffer;
1206 buffer.open(openMode: QBuffer::ReadWrite);
1207
1208 // checking for QMediaPlaylist::FormatNotSupportedError enum
1209 QVERIFY(!playlist.save(&buffer, "unsupported_format"));
1210 QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
1211
1212 playlist.load(device: &buffer,format: "unsupported_format");
1213 QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
1214}
1215
1216// MaemoAPI-1849:test QMediaPlayListControl constructor
1217void tst_QMediaPlaylist::mediaPlayListControl()
1218{
1219 // To check changes in abstract classe's pure virtual functions
1220 QObject parent;
1221 MockMediaPlaylistControl plylistctrl(false, &parent);
1222}
1223
1224// MaemoAPI-1850:test QMediaPlayListSourceControl constructor
1225void tst_QMediaPlaylist::mediaPlayListSourceControl()
1226{
1227 // To check changes in abstract classe's pure virtual functions
1228 QObject parent;
1229 MockPlaylistSourceControl plylistsrcctrl(&parent);
1230}
1231
1232// MaemoAPI-1852:test constructor
1233void tst_QMediaPlaylist::mediaPlayListProvider()
1234{
1235 // srcs of QMediaPlaylistProvider is incomplete
1236 QObject parent;
1237 MockReadOnlyPlaylistProvider provider(&parent);
1238}
1239
1240QTEST_MAIN(tst_QMediaPlaylist)
1241#include "tst_qmediaplaylist.moc"
1242
1243

source code of qtmultimedia/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp