1
/* This file is part of Clementine.
2
Copyright 2010, David Sansome <me@davidsansome.com>
4
Clementine is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
Clementine is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
19
#include "gmock/gmock-matchers.h"
20
#include "gtest/gtest.h"
21
#include "test_utils.h"
22
#include "mock_taglib.h"
24
#include "playlistparsers/cueparser.h"
26
class CueParserTest : public ::testing::Test {
28
static void SetUpTestCase() {
29
testing::DefaultValue<TagLib::String>::Set("foobarbaz");
36
// We believe CUE - all songs with proper CUE entries should be valid.
37
bool validate_songs(SongList songs) {
38
foreach(const Song& song, songs) {
39
if(!song.is_valid()) {
47
qlonglong to_nanosec(int minutes, int seconds, int frames) {
48
return (minutes * 60 * 75 + seconds * 75 + frames) * kNsecPerSec / 75;
52
MockFileRefFactory taglib_;
55
TEST_F(CueParserTest, ParsesASong) {
56
QFile file(":testdata/onesong.cue");
57
file.open(QIODevice::ReadOnly);
59
SongList song_list = parser_.Load(&file, "CUEPATH", QDir(""));
62
ASSERT_EQ(1, song_list.size());
64
// with the specified metadata
65
Song first_song = song_list.at(0);
66
ASSERT_EQ("Un soffio caldo", first_song.title());
67
ASSERT_EQ("Zucchero", first_song.artist());
68
ASSERT_EQ("Zucchero himself", first_song.albumartist());
69
ASSERT_EQ("", first_song.album());
70
ASSERT_EQ(to_nanosec(0, 1, 15), first_song.beginning_nanosec());
71
ASSERT_EQ(1, first_song.track());
72
ASSERT_EQ("CUEPATH", first_song.cue_path());
74
validate_songs(song_list);
77
TEST_F(CueParserTest, ParsesTwoSongs) {
78
QFile file(":testdata/twosongs.cue");
79
file.open(QIODevice::ReadOnly);
81
SongList song_list = parser_.Load(&file, "", QDir(""));
84
ASSERT_EQ(2, song_list.size());
86
// with the specified metadata
87
Song first_song = song_list.at(0);
88
Song second_song = song_list.at(1);
90
ASSERT_EQ("Un soffio caldo", first_song.title());
91
ASSERT_EQ("Chocabeck", first_song.album());
92
ASSERT_EQ("Zucchero himself", first_song.artist());
93
ASSERT_EQ("Zucchero himself", first_song.albumartist());
94
ASSERT_EQ(to_nanosec(0, 1, 0), first_song.beginning_nanosec());
95
ASSERT_EQ(second_song.beginning_nanosec() - first_song.beginning_nanosec(), first_song.length_nanosec());
96
ASSERT_EQ(1, first_song.track());
98
ASSERT_EQ("Somewon Else's Tears", second_song.title());
99
ASSERT_EQ("Chocabeck", second_song.album());
100
ASSERT_EQ("Zucchero himself", second_song.artist());
101
ASSERT_EQ("Zucchero himself", second_song.albumartist());
102
ASSERT_EQ(to_nanosec(5, 3, 68), second_song.beginning_nanosec());
103
ASSERT_EQ(2, second_song.track());
105
validate_songs(song_list);
108
TEST_F(CueParserTest, SkipsBrokenSongs) {
109
QFile file(":testdata/brokensong.cue");
110
file.open(QIODevice::ReadOnly);
112
SongList song_list = parser_.Load(&file, "", QDir(""));
114
// two songs (the broken one is not in the list)
115
ASSERT_EQ(2, song_list.size());
117
// with the specified metadata
118
Song first_song = song_list.at(0);
119
Song second_song = song_list.at(1);
121
ASSERT_EQ("Un soffio caldo", first_song.title());
122
ASSERT_EQ("Chocabeck", first_song.album());
123
ASSERT_EQ("Zucchero himself", first_song.artist());
124
ASSERT_EQ("Zucchero himself", first_song.albumartist());
125
ASSERT_EQ(to_nanosec(0, 1, 0), first_song.beginning_nanosec());
126
// includes the broken song too; this entry will span from it's
127
// INDEX (beginning) to the end of the next correct song
128
ASSERT_EQ(second_song.beginning_nanosec() - first_song.beginning_nanosec(), first_song.length_nanosec());
129
ASSERT_EQ(1, first_song.track());
131
ASSERT_EQ("Somewon Else's Tears", second_song.title());
132
ASSERT_EQ("Chocabeck", second_song.album());
133
ASSERT_EQ("Zucchero himself", second_song.artist());
134
ASSERT_EQ("Zucchero himself", second_song.albumartist());
135
ASSERT_EQ(to_nanosec(5, 0, 0), second_song.beginning_nanosec());
136
ASSERT_EQ(2, second_song.track());
138
validate_songs(song_list);
141
TEST_F(CueParserTest, UsesAllMetadataInformation) {
142
QFile file(":testdata/fullmetadata.cue");
143
file.open(QIODevice::ReadOnly);
145
SongList song_list = parser_.Load(&file, "", QDir(""));
148
ASSERT_EQ(2, song_list.size());
150
// with the specified metadata
151
Song first_song = song_list.at(0);
152
Song second_song = song_list.at(1);
154
ASSERT_TRUE(first_song.filename().endsWith("a_file.mp3"));
155
ASSERT_EQ("Un soffio caldo", first_song.title());
156
ASSERT_EQ("Album", first_song.album());
157
ASSERT_EQ("Zucchero", first_song.artist());
158
ASSERT_EQ("Zucchero himself", first_song.albumartist());
159
ASSERT_EQ("Some guy", first_song.composer());
160
ASSERT_EQ(to_nanosec(0, 1, 0), first_song.beginning_nanosec());
161
ASSERT_EQ(second_song.beginning_nanosec() - first_song.beginning_nanosec(), first_song.length_nanosec());
162
ASSERT_EQ(1, first_song.track());
164
ASSERT_TRUE(second_song.filename().endsWith("a_file.mp3"));
165
ASSERT_EQ("Hey you!", second_song.title());
166
ASSERT_EQ("Album", second_song.album());
167
ASSERT_EQ("Zucchero himself", second_song.artist());
168
ASSERT_EQ("Zucchero himself", second_song.albumartist());
169
ASSERT_EQ("Some other guy", second_song.composer());
170
ASSERT_EQ(to_nanosec(0, 2, 0), second_song.beginning_nanosec());
171
ASSERT_EQ(2, second_song.track());
173
validate_songs(song_list);
176
TEST_F(CueParserTest, AcceptsMultipleFileBasedCues) {
177
QFile file(":testdata/manyfiles.cue");
178
file.open(QIODevice::ReadOnly);
180
SongList song_list = parser_.Load(&file, "CUEPATH", QDir(""));
183
ASSERT_EQ(5, song_list.size());
185
// with the specified metadata
186
Song first_song = song_list.at(0);
187
Song second_song = song_list.at(1);
188
Song third_song = song_list.at(2);
189
Song fourth_song = song_list.at(3);
190
Song fifth_song = song_list.at(4);
192
ASSERT_TRUE(first_song.filename().endsWith("files/longer_one.mp3"));
193
ASSERT_EQ("A1Song1", first_song.title());
194
ASSERT_EQ("Artist One Album", first_song.album());
195
ASSERT_EQ("Artist One", first_song.artist());
196
ASSERT_EQ("Artist One", first_song.albumartist());
197
ASSERT_EQ(to_nanosec(0, 1, 0), first_song.beginning_nanosec());
198
ASSERT_EQ(second_song.beginning_nanosec() - first_song.beginning_nanosec(), first_song.length_nanosec());
199
ASSERT_EQ(-1, first_song.track());
200
ASSERT_EQ("CUEPATH", first_song.cue_path());
202
ASSERT_TRUE(second_song.filename().endsWith("files/longer_one.mp3"));
203
ASSERT_EQ("A1Song2", second_song.title());
204
ASSERT_EQ("Artist One Album", second_song.album());
205
ASSERT_EQ("Artist One", second_song.artist());
206
ASSERT_EQ("Artist One", second_song.albumartist());
207
ASSERT_EQ(to_nanosec(5, 3, 68), second_song.beginning_nanosec());
208
ASSERT_EQ(-1, second_song.track());
210
ASSERT_TRUE(third_song.filename().endsWith("files/longer_two_p1.mp3"));
211
ASSERT_EQ("A2P1Song1", third_song.title());
212
ASSERT_EQ("Artist Two Album", third_song.album());
213
ASSERT_EQ("Artist X", third_song.artist());
214
ASSERT_EQ("Artist Two", third_song.albumartist());
215
ASSERT_EQ(to_nanosec(0, 0, 12), third_song.beginning_nanosec());
216
ASSERT_EQ(fourth_song.beginning_nanosec() - third_song.beginning_nanosec(), third_song.length_nanosec());
217
ASSERT_EQ(-1, third_song.track());
218
ASSERT_EQ("CUEPATH", third_song.cue_path());
220
ASSERT_TRUE(fourth_song.filename().endsWith("files/longer_two_p1.mp3"));
221
ASSERT_EQ("A2P1Song2", fourth_song.title());
222
ASSERT_EQ("Artist Two Album", fourth_song.album());
223
ASSERT_EQ("Artist Two", fourth_song.artist());
224
ASSERT_EQ("Artist Two", fourth_song.albumartist());
225
ASSERT_EQ(to_nanosec(4, 0, 13), fourth_song.beginning_nanosec());
226
ASSERT_EQ(-1, fourth_song.track());
228
ASSERT_TRUE(fifth_song.filename().endsWith("files/longer_two_p2.mp3"));
229
ASSERT_EQ("A2P2Song1", fifth_song.title());
230
ASSERT_EQ("Artist Two Album", fifth_song.album());
231
ASSERT_EQ("Artist Two", fifth_song.artist());
232
ASSERT_EQ("Artist Two", fifth_song.albumartist());
233
ASSERT_EQ(to_nanosec(0, 1, 0), fifth_song.beginning_nanosec());
234
ASSERT_EQ(-1, fifth_song.track());
235
ASSERT_EQ("CUEPATH", fifth_song.cue_path());
237
validate_songs(song_list);
240
TEST_F(CueParserTest, SkipsBrokenSongsInMultipleFileBasedCues) {
241
QFile file(":testdata/manyfilesbroken.cue");
242
file.open(QIODevice::ReadOnly);
244
SongList song_list = parser_.Load(&file, "", QDir(""));
247
ASSERT_EQ(4, song_list.size());
249
// with the specified metadata
250
Song first_song = song_list.at(0);
251
Song second_song = song_list.at(1);
252
Song third_song = song_list.at(2);
253
Song fourth_song = song_list.at(3);
255
// A* - broken song in the middle
256
ASSERT_TRUE(first_song.filename().endsWith("file1.mp3"));
257
ASSERT_EQ("Artist One", first_song.artist());
258
ASSERT_EQ("Artist One Album", first_song.album());
259
ASSERT_EQ("A1", first_song.title());
260
ASSERT_EQ(to_nanosec(0, 1, 15), first_song.beginning_nanosec());
261
ASSERT_EQ(second_song.beginning_nanosec() - first_song.beginning_nanosec(), first_song.length_nanosec());
262
ASSERT_EQ(-1, first_song.track());
264
ASSERT_TRUE(second_song.filename().endsWith("file1.mp3"));
265
ASSERT_EQ("Artist One", second_song.artist());
266
ASSERT_EQ("Artist One Album", second_song.album());
267
ASSERT_EQ("A3", second_song.title());
268
ASSERT_EQ(to_nanosec(1, 0, 16), second_song.beginning_nanosec());
269
ASSERT_EQ(-1, second_song.track());
271
// all B* songs are broken
273
// C* - broken song at the end
274
ASSERT_TRUE(third_song.filename().endsWith("file3.mp3"));
275
ASSERT_EQ("Artist Three", third_song.artist());
276
ASSERT_EQ("Artist Three Album", third_song.album());
277
ASSERT_EQ("C1", third_song.title());
278
ASSERT_EQ(to_nanosec(0, 1, 0), third_song.beginning_nanosec());
279
ASSERT_EQ(-1, third_song.track());
281
// D* - broken song at the beginning
282
ASSERT_TRUE(fourth_song.filename().endsWith("file4.mp3"));
283
ASSERT_EQ("Artist Four", fourth_song.artist());
284
ASSERT_EQ("Artist Four Album", fourth_song.album());
285
ASSERT_EQ("D2", fourth_song.title());
286
ASSERT_EQ(to_nanosec(15, 55, 66), fourth_song.beginning_nanosec());
287
ASSERT_EQ(-1, fourth_song.track());
289
validate_songs(song_list);
292
TEST_F(CueParserTest, SkipsDataFiles) {
293
QFile file(":testdata/withdatafiles.cue");
294
file.open(QIODevice::ReadOnly);
296
SongList song_list = parser_.Load(&file, "", QDir(""));
299
ASSERT_EQ(2, song_list.size());
301
// with the specified metadata
302
Song first_song = song_list.at(0);
303
Song second_song = song_list.at(1);
305
ASSERT_TRUE(first_song.filename().endsWith("file1.mp3"));
306
ASSERT_EQ("Artist One", first_song.artist());
307
ASSERT_EQ("Artist One Album", first_song.album());
308
ASSERT_EQ("A1", first_song.title());
309
ASSERT_EQ(to_nanosec(0, 1, 0), first_song.beginning_nanosec());
310
ASSERT_EQ(-1, first_song.track());
312
ASSERT_TRUE(second_song.filename().endsWith("file4.mp3"));
313
ASSERT_EQ("Artist Four", second_song.artist());
314
ASSERT_EQ("Artist Four Album", second_song.album());
315
ASSERT_EQ("D1", second_song.title());
316
ASSERT_EQ(to_nanosec(1, 1, 0), second_song.beginning_nanosec());
317
ASSERT_EQ(-1, second_song.track());
319
validate_songs(song_list);