1 /*
2 * Strawberry Music Player
3 * This file was part of Clementine.
4 * Copyright 2010, David Sansome <me@davidsansome.com>
5 * Copyright 2019, Jonas Kvinge <jonas@jkvinge.net>
6 *
7 * Strawberry is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Strawberry is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include <memory>
23
24 #include <gtest/gtest.h>
25
26 #include "test_utils.h"
27
28 #include "collection/collectionplaylistitem.h"
29 #include "playlist/playlist.h"
30 #include "mock_settingsprovider.h"
31 #include "mock_playlistitem.h"
32
33 #include <QtDebug>
34 #include <QUndoStack>
35
36 using ::testing::Return;
37
38 // clazy:excludeall=non-pod-global-static,returning-void-expression
39
40 namespace {
41
42 class PlaylistTest : public ::testing::Test {
43 protected:
PlaylistTest()44 PlaylistTest()
45 : playlist_(nullptr, nullptr, nullptr, 1),
46 sequence_(nullptr, new DummySettingsProvider)
47 {
48 }
49
SetUp()50 void SetUp() override {
51 playlist_.set_sequence(&sequence_);
52 }
53
MakeMockItem(const QString & title,const QString & artist=QString (),const QString & album=QString (),int length=123) const54 MockPlaylistItem* MakeMockItem(const QString &title, const QString &artist = QString(), const QString &album = QString(), int length = 123) const {
55 Song metadata;
56 metadata.Init(title, artist, album, length);
57
58 MockPlaylistItem *ret = new MockPlaylistItem;
59 EXPECT_CALL(*ret, Metadata()).WillRepeatedly(Return(metadata));
60
61 return ret;
62 }
63
MakeMockItemP(const QString & title,const QString & artist=QString (),const QString & album=QString (),int length=123) const64 PlaylistItemPtr MakeMockItemP(const QString &title, const QString &artist = QString(), const QString &album = QString(), int length = 123) const {
65 return PlaylistItemPtr(MakeMockItem(title, artist, album, length));
66 }
67
68 Playlist playlist_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
69 PlaylistSequence sequence_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
70
71 };
72
TEST_F(PlaylistTest,Basic)73 TEST_F(PlaylistTest, Basic) {
74 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
75 }
76
TEST_F(PlaylistTest,InsertItems)77 TEST_F(PlaylistTest, InsertItems) {
78
79 MockPlaylistItem* item = MakeMockItem("Title", "Artist", "Album", 123);
80 PlaylistItemPtr item_ptr(item);
81
82 // Insert the item
83 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
84 playlist_.InsertItems(PlaylistItemList() << item_ptr, -1);
85 ASSERT_EQ(1, playlist_.rowCount(QModelIndex()));
86
87 // Get the metadata
88 EXPECT_EQ("Title", playlist_.data(playlist_.index(0, Playlist::Column_Title)));
89 EXPECT_EQ("Artist", playlist_.data(playlist_.index(0, Playlist::Column_Artist)));
90 EXPECT_EQ("Album", playlist_.data(playlist_.index(0, Playlist::Column_Album)));
91 EXPECT_EQ(123, playlist_.data(playlist_.index(0, Playlist::Column_Length)));
92
93 }
94
TEST_F(PlaylistTest,Indexes)95 TEST_F(PlaylistTest, Indexes) {
96
97 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
98 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
99
100 // Start "playing" track 1
101 playlist_.set_current_row(0);
102 EXPECT_EQ(0, playlist_.current_row());
103 EXPECT_EQ("One", playlist_.current_item()->Metadata().title());
104 EXPECT_EQ(-1, playlist_.previous_row());
105 EXPECT_EQ(1, playlist_.next_row());
106
107 // Stop playing
108 EXPECT_EQ(0, playlist_.last_played_row());
109 playlist_.set_current_row(-1);
110 EXPECT_EQ(0, playlist_.last_played_row());
111 EXPECT_EQ(-1, playlist_.current_row());
112
113 // Play track 2
114 playlist_.set_current_row(1);
115 EXPECT_EQ(1, playlist_.current_row());
116 EXPECT_EQ("Two", playlist_.current_item()->Metadata().title());
117 EXPECT_EQ(0, playlist_.previous_row());
118 EXPECT_EQ(2, playlist_.next_row());
119
120 // Play track 3
121 playlist_.set_current_row(2);
122 EXPECT_EQ(2, playlist_.current_row());
123 EXPECT_EQ("Three", playlist_.current_item()->Metadata().title());
124 EXPECT_EQ(1, playlist_.previous_row());
125 EXPECT_EQ(-1, playlist_.next_row());
126
127 }
128
TEST_F(PlaylistTest,RepeatPlaylist)129 TEST_F(PlaylistTest, RepeatPlaylist) {
130
131 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
132 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
133
134 playlist_.sequence()->SetRepeatMode(PlaylistSequence::Repeat_Playlist);
135
136 playlist_.set_current_row(0);
137 EXPECT_EQ(1, playlist_.next_row());
138
139 playlist_.set_current_row(1);
140 EXPECT_EQ(2, playlist_.next_row());
141
142 playlist_.set_current_row(2);
143 EXPECT_EQ(0, playlist_.next_row());
144
145 }
146
TEST_F(PlaylistTest,RepeatTrack)147 TEST_F(PlaylistTest, RepeatTrack) {
148
149 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
150 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
151
152 playlist_.sequence()->SetRepeatMode(PlaylistSequence::Repeat_Track);
153
154 playlist_.set_current_row(0);
155 EXPECT_EQ(0, playlist_.next_row());
156
157 }
158
TEST_F(PlaylistTest,RepeatAlbum)159 TEST_F(PlaylistTest, RepeatAlbum) {
160
161 playlist_.InsertItems(PlaylistItemList()
162 << MakeMockItemP("One", "Album one")
163 << MakeMockItemP("Two", "Album two")
164 << MakeMockItemP("Three", "Album one"));
165 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
166
167 playlist_.sequence()->SetRepeatMode(PlaylistSequence::Repeat_Album);
168
169 playlist_.set_current_row(0);
170 EXPECT_EQ(2, playlist_.next_row());
171
172 playlist_.set_current_row(2);
173 EXPECT_EQ(0, playlist_.next_row());
174
175 }
176
TEST_F(PlaylistTest,RemoveBeforeCurrent)177 TEST_F(PlaylistTest, RemoveBeforeCurrent) {
178
179 playlist_.InsertItems(PlaylistItemList()
180 << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
181 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
182
183 // Remove a row before the currently playing track
184 playlist_.set_current_row(2);
185 EXPECT_EQ(2, playlist_.current_row());
186 playlist_.removeRow(1, QModelIndex());
187 EXPECT_EQ(1, playlist_.current_row());
188 EXPECT_EQ(1, playlist_.last_played_row());
189 EXPECT_EQ(0, playlist_.previous_row());
190 EXPECT_EQ(-1, playlist_.next_row());
191
192 }
193
TEST_F(PlaylistTest,RemoveAfterCurrent)194 TEST_F(PlaylistTest, RemoveAfterCurrent) {
195
196 playlist_.InsertItems(PlaylistItemList()
197 << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
198 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
199
200 // Remove a row after the currently playing track
201 playlist_.set_current_row(0);
202 EXPECT_EQ(0, playlist_.current_row());
203 playlist_.removeRow(1, QModelIndex());
204 EXPECT_EQ(0, playlist_.current_row());
205 EXPECT_EQ(0, playlist_.last_played_row());
206 EXPECT_EQ(-1, playlist_.previous_row());
207 EXPECT_EQ(1, playlist_.next_row());
208
209 playlist_.set_current_row(1);
210 EXPECT_EQ(-1, playlist_.next_row());
211
212 }
213
TEST_F(PlaylistTest,RemoveCurrent)214 TEST_F(PlaylistTest, RemoveCurrent) {
215
216 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
217 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
218
219 // Remove the currently playing track's row
220 playlist_.set_current_row(1);
221 EXPECT_EQ(1, playlist_.current_row());
222 playlist_.removeRow(1, QModelIndex());
223 EXPECT_EQ(-1, playlist_.current_row());
224 EXPECT_EQ(-1, playlist_.last_played_row());
225 EXPECT_EQ(-1, playlist_.previous_row());
226 EXPECT_EQ(0, playlist_.next_row());
227
228 }
229
TEST_F(PlaylistTest,InsertBeforeCurrent)230 TEST_F(PlaylistTest, InsertBeforeCurrent) {
231
232 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
233 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
234
235 playlist_.set_current_row(1);
236 EXPECT_EQ(1, playlist_.current_row());
237 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Four"), 0);
238 ASSERT_EQ(4, playlist_.rowCount(QModelIndex()));
239
240 EXPECT_EQ(2, playlist_.current_row());
241 EXPECT_EQ(2, playlist_.last_played_row());
242 EXPECT_EQ(1, playlist_.previous_row());
243 EXPECT_EQ(3, playlist_.next_row());
244
245 EXPECT_EQ("Four", playlist_.data(playlist_.index(0, Playlist::Column_Title)));
246 EXPECT_EQ("One", playlist_.data(playlist_.index(1, Playlist::Column_Title)));
247
248 }
249
TEST_F(PlaylistTest,InsertAfterCurrent)250 TEST_F(PlaylistTest, InsertAfterCurrent) {
251
252 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
253 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
254
255 playlist_.set_current_row(1);
256 EXPECT_EQ(1, playlist_.current_row());
257 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Four"), 2);
258 ASSERT_EQ(4, playlist_.rowCount(QModelIndex()));
259
260 EXPECT_EQ(1, playlist_.current_row());
261 EXPECT_EQ(1, playlist_.last_played_row());
262 EXPECT_EQ(0, playlist_.previous_row());
263 EXPECT_EQ(2, playlist_.next_row());
264
265 EXPECT_EQ("Two", playlist_.data(playlist_.index(1, Playlist::Column_Title)));
266 EXPECT_EQ("Four", playlist_.data(playlist_.index(2, Playlist::Column_Title)));
267 EXPECT_EQ("Three", playlist_.data(playlist_.index(3, Playlist::Column_Title)));
268
269 }
270
TEST_F(PlaylistTest,Clear)271 TEST_F(PlaylistTest, Clear) {
272
273 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
274 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
275
276 playlist_.set_current_row(1);
277 EXPECT_EQ(1, playlist_.current_row());
278 playlist_.Clear();
279
280 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
281 EXPECT_EQ(-1, playlist_.current_row());
282 EXPECT_EQ(-1, playlist_.last_played_row());
283 EXPECT_EQ(-1, playlist_.previous_row());
284 EXPECT_EQ(-1, playlist_.next_row());
285
286 }
287
TEST_F(PlaylistTest,UndoAdd)288 TEST_F(PlaylistTest, UndoAdd) {
289
290 EXPECT_FALSE(playlist_.undo_stack()->canUndo());
291 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
292
293 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Title"));
294 EXPECT_EQ(1, playlist_.rowCount(QModelIndex()));
295 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
296 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
297
298 playlist_.undo_stack()->undo();
299 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
300 EXPECT_FALSE(playlist_.undo_stack()->canUndo());
301 ASSERT_TRUE(playlist_.undo_stack()->canRedo());
302
303 playlist_.undo_stack()->redo();
304 EXPECT_EQ(1, playlist_.rowCount(QModelIndex()));
305 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
306 EXPECT_TRUE(playlist_.undo_stack()->canUndo());
307
308 EXPECT_EQ("Title", playlist_.data(playlist_.index(0, Playlist::Column_Title)));
309
310 }
311
TEST_F(PlaylistTest,UndoMultiAdd)312 TEST_F(PlaylistTest, UndoMultiAdd) {
313
314 // Add 1 item
315 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One"));
316
317 // Add 2 items
318 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Two") << MakeMockItemP("Three"));
319
320 // Undo adding 2 items
321 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
322 EXPECT_EQ("add 2 songs", playlist_.undo_stack()->undoText());
323 playlist_.undo_stack()->undo();
324
325 // Undo adding 1 item
326 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
327 EXPECT_EQ("add 1 songs", playlist_.undo_stack()->undoText());
328 playlist_.undo_stack()->undo();
329
330 EXPECT_FALSE(playlist_.undo_stack()->canUndo());
331
332 }
333
TEST_F(PlaylistTest,UndoRemove)334 TEST_F(PlaylistTest, UndoRemove) {
335
336 EXPECT_FALSE(playlist_.undo_stack()->canUndo());
337 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
338
339 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Title"));
340
341 EXPECT_TRUE(playlist_.undo_stack()->canUndo());
342 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
343
344 playlist_.removeRow(0);
345
346 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
347 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
348 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
349
350 playlist_.undo_stack()->undo();
351 EXPECT_EQ(1, playlist_.rowCount(QModelIndex()));
352 ASSERT_TRUE(playlist_.undo_stack()->canRedo());
353
354 EXPECT_EQ("Title", playlist_.data(playlist_.index(0, Playlist::Column_Title)));
355
356 playlist_.undo_stack()->redo();
357 EXPECT_EQ(0, playlist_.rowCount(QModelIndex()));
358 EXPECT_FALSE(playlist_.undo_stack()->canRedo());
359 EXPECT_TRUE(playlist_.undo_stack()->canUndo());
360
361 }
362
TEST_F(PlaylistTest,UndoMultiRemove)363 TEST_F(PlaylistTest, UndoMultiRemove) {
364
365 // Add 3 items
366 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
367 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
368
369 // Remove 1 item
370 playlist_.removeRow(1); // Item "Two"
371
372 // Remove 2 items
373 playlist_.removeRows(0, 2); // "One" and "Three"
374
375 ASSERT_EQ(0, playlist_.rowCount(QModelIndex()));
376
377 // Undo removing all 3 items
378 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
379 EXPECT_EQ("remove 3 songs", playlist_.undo_stack()->undoText());
380
381 playlist_.undo_stack()->undo();
382 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
383
384 }
385
TEST_F(PlaylistTest,UndoClear)386 TEST_F(PlaylistTest, UndoClear) {
387
388 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("One") << MakeMockItemP("Two") << MakeMockItemP("Three"));
389 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
390
391 playlist_.Clear();
392 ASSERT_EQ(0, playlist_.rowCount(QModelIndex()));
393 ASSERT_TRUE(playlist_.undo_stack()->canUndo());
394 EXPECT_EQ("remove 3 songs", playlist_.undo_stack()->undoText());
395 playlist_.undo_stack()->undo();
396
397 ASSERT_EQ(3, playlist_.rowCount(QModelIndex()));
398
399 }
400
TEST_F(PlaylistTest,UndoRemoveCurrent)401 TEST_F(PlaylistTest, UndoRemoveCurrent) {
402
403 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Title"));
404 playlist_.set_current_row(0);
405 EXPECT_EQ(0, playlist_.current_row());
406 EXPECT_EQ(0, playlist_.last_played_row());
407
408 playlist_.removeRow(0);
409 EXPECT_EQ(-1, playlist_.current_row());
410 EXPECT_EQ(-1, playlist_.last_played_row());
411
412 playlist_.undo_stack()->undo();
413 EXPECT_EQ(-1, playlist_.current_row());
414 EXPECT_EQ(-1, playlist_.last_played_row());
415
416 }
417
TEST_F(PlaylistTest,UndoRemoveOldCurrent)418 TEST_F(PlaylistTest, UndoRemoveOldCurrent) {
419
420 playlist_.InsertItems(PlaylistItemList() << MakeMockItemP("Title"));
421 playlist_.set_current_row(0);
422 EXPECT_EQ(0, playlist_.current_row());
423 EXPECT_EQ(0, playlist_.last_played_row());
424
425 playlist_.removeRow(0);
426 EXPECT_EQ(-1, playlist_.current_row());
427 EXPECT_EQ(-1, playlist_.last_played_row());
428
429 playlist_.set_current_row(-1);
430
431 playlist_.undo_stack()->undo();
432 EXPECT_EQ(-1, playlist_.current_row());
433 EXPECT_EQ(-1, playlist_.last_played_row());
434
435 }
436
TEST_F(PlaylistTest,ShuffleThenNext)437 TEST_F(PlaylistTest, ShuffleThenNext) {
438
439 // Add 100 items
440 PlaylistItemList items;
441 items.reserve(100);
442 for (int i=0 ; i<100 ; ++i)
443 items << MakeMockItemP("Item " + QString::number(i));
444 playlist_.InsertItems(items);
445
446 playlist_.set_current_row(0);
447
448 // Shuffle until the current index is not at the end
449 forever {
450 playlist_.Shuffle();
451 if (playlist_.current_row() != items.count()-1)
452 break;
453 }
454
455 int index = playlist_.current_row();
456 EXPECT_EQ("Item 0", playlist_.current_item()->Metadata().title());
457 EXPECT_EQ("Item 0", playlist_.data(playlist_.index(index, Playlist::Column_Title)));
458 EXPECT_EQ(index, playlist_.last_played_row());
459 //EXPECT_EQ(index + 1, playlist_.next_row());
460
461 // Shuffle until the current index *is* at the end
462 //forever {
463 //playlist_.Shuffle();
464 //if (playlist_.current_row() == items.count()-1)
465 //break;
466 //}
467
468 index = playlist_.current_row();
469 EXPECT_EQ("Item 0", playlist_.current_item()->Metadata().title());
470 EXPECT_EQ("Item 0", playlist_.data(playlist_.index(index, Playlist::Column_Title)));
471 EXPECT_EQ(index, playlist_.last_played_row());
472 //EXPECT_EQ(-1, playlist_.next_row());
473 //EXPECT_EQ(index-1, playlist_.previous_row());
474
475 }
476
TEST_F(PlaylistTest,CollectionIdMapSingle)477 TEST_F(PlaylistTest, CollectionIdMapSingle) {
478
479 Song song;
480 song.Init("title", "artist", "album", 123);
481 song.set_id(1);
482
483 PlaylistItemPtr item(std::make_shared<CollectionPlaylistItem>(song));
484 playlist_.InsertItems(PlaylistItemList() << item);
485
486 EXPECT_EQ(0, playlist_.collection_items_by_id(-1).count());
487 EXPECT_EQ(0, playlist_.collection_items_by_id(0).count());
488 EXPECT_EQ(0, playlist_.collection_items_by_id(2).count());
489 ASSERT_EQ(1, playlist_.collection_items_by_id(1).count());
490 EXPECT_EQ(song.title(), playlist_.collection_items_by_id(1)[0]->Metadata().title()); // clazy:exclude=detaching-temporary
491
492 playlist_.Clear();
493
494 EXPECT_EQ(0, playlist_.collection_items_by_id(1).count());
495
496 }
497
TEST_F(PlaylistTest,CollectionIdMapInvalid)498 TEST_F(PlaylistTest, CollectionIdMapInvalid) {
499
500 Song invalid;
501 invalid.Init("title", "artist", "album", 123);
502 ASSERT_EQ(-1, invalid.id());
503
504 PlaylistItemPtr item(std::make_shared<CollectionPlaylistItem>(invalid));
505 playlist_.InsertItems(PlaylistItemList() << item);
506
507 EXPECT_EQ(0, playlist_.collection_items_by_id(-1).count());
508 EXPECT_EQ(0, playlist_.collection_items_by_id(0).count());
509 EXPECT_EQ(0, playlist_.collection_items_by_id(1).count());
510 EXPECT_EQ(0, playlist_.collection_items_by_id(2).count());
511
512 }
513
TEST_F(PlaylistTest,CollectionIdMapMulti)514 TEST_F(PlaylistTest, CollectionIdMapMulti) {
515
516 Song one;
517 one.Init("title", "artist", "album", 123);
518 one.set_id(1);
519
520 Song two;
521 two.Init("title 2", "artist 2", "album 2", 123);
522 two.set_id(2);
523
524 PlaylistItemPtr item_one(std::make_shared<CollectionPlaylistItem>(one));
525 PlaylistItemPtr item_two(std::make_shared<CollectionPlaylistItem>(two));
526 PlaylistItemPtr item_three(std::make_shared<CollectionPlaylistItem>(one));
527 playlist_.InsertItems(PlaylistItemList() << item_one << item_two << item_three);
528
529 EXPECT_EQ(2, playlist_.collection_items_by_id(1).count());
530 EXPECT_EQ(1, playlist_.collection_items_by_id(2).count());
531
532 playlist_.removeRow(1); // item_two
533 EXPECT_EQ(2, playlist_.collection_items_by_id(1).count());
534 EXPECT_EQ(0, playlist_.collection_items_by_id(2).count());
535
536 playlist_.removeRow(1); // item_three
537 EXPECT_EQ(1, playlist_.collection_items_by_id(1).count());
538 EXPECT_EQ(0, playlist_.collection_items_by_id(2).count());
539
540 playlist_.removeRow(0); // item_one
541 EXPECT_EQ(0, playlist_.collection_items_by_id(1).count());
542 EXPECT_EQ(0, playlist_.collection_items_by_id(2).count());
543
544 }
545
546
547 } // namespace
548