Componentize AccountReconcilor.
[chromium-blink-merge.git] / chrome / utility / media_galleries / itunes_library_parser_unittest.cc
blobcb772f4b99084c23a6ac07d8b0d7c7557fa0b186
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "chrome/common/media_galleries/itunes_library.h"
7 #include "chrome/utility/media_galleries/itunes_library_parser.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 #define SIMPLE_HEADER() \
11 "<plist>" \
12 " <dict>" \
13 " <key>Tracks</key>" \
14 " <dict>"
16 #define SIMPLE_TRACK(key, id, path, artist, album) \
17 "<key>" #key "</key>" \
18 "<dict>" \
19 " <key>Track ID</key><integer>" #id "</integer>" \
20 " <key>Location</key><string>file://localhost/" path "</string>" \
21 " <key>Artist</key><string>" artist "</string>" \
22 " <key>Album</key><string>" album "</string>" \
23 "</dict>"
25 #define SIMPLE_FOOTER() \
26 " </dict>" \
27 " </dict>" \
28 "</plist>"
30 namespace itunes {
32 namespace {
34 void CompareTrack(const parser::Track& a, const parser::Track& b) {
35 EXPECT_EQ(a.id, b.id);
36 EXPECT_EQ(a.location.value(), b.location.value());
39 void CompareAlbum(const parser::Album& a, const parser::Album& b) {
40 EXPECT_EQ(a.size(), b.size());
42 parser::Album::const_iterator a_it;
43 parser::Album::const_iterator b_it;
44 for (a_it = a.begin(), b_it = b.begin();
45 a_it != a.end() && b_it != b.end();
46 ++a_it, ++b_it) {
47 CompareTrack(*a_it, *b_it);
51 void CompareAlbums(const parser::Albums& a, const parser::Albums& b) {
52 EXPECT_EQ(a.size(), b.size());
54 parser::Albums::const_iterator a_it;
55 parser::Albums::const_iterator b_it;
56 for (a_it = a.begin(), b_it = b.begin();
57 a_it != a.end() && b_it != b.end();
58 ++a_it, ++b_it) {
59 EXPECT_EQ(a_it->first, b_it->first);
60 CompareAlbum(a_it->second, b_it->second);
64 void CompareLibrary(const parser::Library& a, const parser::Library& b) {
65 EXPECT_EQ(a.size(), b.size());
67 parser::Library::const_iterator a_it;
68 parser::Library::const_iterator b_it;
69 for (a_it = a.begin(), b_it = b.begin();
70 a_it != a.end() && b_it != b.end();
71 ++a_it, ++b_it) {
72 EXPECT_EQ(a_it->first, b_it->first);
73 CompareAlbums(a_it->second, b_it->second);
77 class ITunesLibraryParserTest : public testing::Test {
78 public:
79 ITunesLibraryParserTest() {}
81 void TestParser(bool expected_result, const std::string& xml) {
82 ITunesLibraryParser parser;
84 EXPECT_EQ(expected_result, parser.Parse(xml));
85 if (!expected_result)
86 return;
88 CompareLibrary(expected_library_, parser.library());
91 void AddExpectedTrack(uint32 id, const std::string& location,
92 const std::string& artist, const std::string& album) {
93 // On Mac this pretends that C: is a directory.
94 #if defined(OS_MACOSX)
95 std::string os_location = "/" + location;
96 #else
97 const std::string& os_location = location;
98 #endif
99 parser::Track track(id, base::FilePath::FromUTF8Unsafe(os_location));
100 expected_library_[artist][album].insert(track);
103 private:
104 parser::Library expected_library_;
106 DISALLOW_COPY_AND_ASSIGN(ITunesLibraryParserTest);
109 TEST_F(ITunesLibraryParserTest, EmptyLibrary) {
110 TestParser(false, "");
113 TEST_F(ITunesLibraryParserTest, MinimalXML) {
114 AddExpectedTrack(1, "C:/dir/Song With Space.mp3", "Artist A", "Album A");
115 TestParser(
116 true,
117 SIMPLE_HEADER()
118 SIMPLE_TRACK(1, 1, "C:/dir/Song%20With%20Space.mp3", "Artist A",
119 "Album A")
120 SIMPLE_FOOTER());
123 TEST_F(ITunesLibraryParserTest, MultipleSongs) {
124 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Album A");
125 AddExpectedTrack(2, "C:/dir/SongA2.mp3", "Artist A", "Album A");
126 AddExpectedTrack(3, "C:/dir/SongA3.mp3", "Artist A", "Album A");
127 AddExpectedTrack(4, "C:/dir/SongB1.mp3", "Artist A", "Album B");
128 AddExpectedTrack(5, "C:/dir/SongB2.mp3", "Artist A", "Album B");
129 AddExpectedTrack(6, "C:/dir2/SongB1.mp3", "Artist B", "Album B");
130 AddExpectedTrack(7, "C:/dir2/SongB2.mp3", "Artist B", "Album B");
131 TestParser(
132 true,
133 SIMPLE_HEADER()
134 SIMPLE_TRACK(1, 1, "C:/dir/SongA1.mp3", "Artist A", "Album A")
135 SIMPLE_TRACK(2, 2, "C:/dir/SongA2.mp3", "Artist A", "Album A")
136 SIMPLE_TRACK(3, 3, "C:/dir/SongA3.mp3", "Artist A", "Album A")
137 SIMPLE_TRACK(4, 4, "C:/dir/SongB1.mp3", "Artist A", "Album B")
138 SIMPLE_TRACK(5, 5, "C:/dir/SongB2.mp3", "Artist A", "Album B")
139 SIMPLE_TRACK(6, 6, "C:/dir2/SongB1.mp3", "Artist B", "Album B")
140 SIMPLE_TRACK(7, 7, "C:/dir2/SongB2.mp3", "Artist B", "Album B")
141 SIMPLE_FOOTER());
144 TEST_F(ITunesLibraryParserTest, MismatchedId) {
145 TestParser(
146 false,
147 SIMPLE_HEADER()
148 SIMPLE_TRACK(1, 2, "C:/dir/SongA1.mp3", "Artist A", "Album A")
149 SIMPLE_FOOTER());
151 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Album A");
152 TestParser(
153 true,
154 SIMPLE_HEADER()
155 SIMPLE_TRACK(1, 1, "C:/dir/SongA1.mp3", "Artist A", "Album A")
156 SIMPLE_TRACK(2, 3, "C:/dir/SongA2.mp3", "Artist A", "Album A")
157 SIMPLE_FOOTER());
160 TEST_F(ITunesLibraryParserTest, OtherDictionaryEntries) {
161 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Album A");
162 TestParser(
163 true,
164 "<plist>"
165 " <dict>"
166 " <key>Other section</key>"
167 " <dict>"
168 // In Other section, not Tracks.
169 SIMPLE_TRACK(10, 10, "C:/dir/SongB2.mp3", "Artist B", "Album B")
170 " </dict>"
171 " <key>Tracks</key>"
172 " <dict>"
173 " <key>1</key>"
174 " <dict>"
175 // In the body of a track dictionary before the interesting entries.
176 SIMPLE_TRACK(20, 20, "C:/dir/SongB2.mp3", "Artist B", "Album B")
177 // Entries in a different order.
178 " <key>Artist</key><string>Artist A</string>"
179 " <key>Location</key>"
180 " <string>file://localhost/C:/dir/SongA1.mp3</string>"
181 " <key>Album</key><string>Album A</string>"
182 " <key>Track ID</key><integer>1</integer>"
183 // In the body of a track dictionary after the interesting entries.
184 SIMPLE_TRACK(30, 30, "C:/dir/SongB3.mp3", "Artist B", "Album B")
185 " </dict>"
186 " <key>40</key>"
187 " <dict>"
188 // Missing album name.
189 " <key>Artist</key><string>Artist B</string>"
190 " <key>Location</key>"
191 " <string>file://localhost/C:/dir/SongB4.mp3</string>"
192 " <key>Track ID</key><integer>1</integer>"
193 " </dict>"
194 SIMPLE_FOOTER());
197 TEST_F(ITunesLibraryParserTest, MissingEntry) {
198 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Album A");
199 AddExpectedTrack(3, "C:/dir/SongA3.mp3", "Artist A", "Album A");
200 TestParser(
201 true,
202 SIMPLE_HEADER()
203 SIMPLE_TRACK(1, 1, "C:/dir/SongA1.mp3", "Artist A", "Album A")
204 "<key>2</key><dict>"
205 " <key>Track ID</key><integer>2</integer>"
206 " <key>Album</key><string>Album A</string>"
207 " <key>Foo</key><string>Bar</string>"
208 " " // A whitespace node is important for the test.
209 "</dict>"
210 SIMPLE_TRACK(3, 3, "C:/dir/SongA3.mp3", "Artist A", "Album A")
211 SIMPLE_FOOTER());
214 TEST_F(ITunesLibraryParserTest, UnknownAlbumOrArtist) {
215 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Unknown Album");
216 AddExpectedTrack(2, "C:/dir/SongA2.mp3", "Unknown Artist", "Album A");
217 AddExpectedTrack(3, "C:/dir/SongA3.mp3", "Unknown Artist", "Unknown Album");
218 TestParser(
219 true,
220 SIMPLE_HEADER()
221 "<key>1</key><dict>"
222 " <key>Track ID</key><integer>1</integer>"
223 " <key>Location</key><string>file://localhost/C:/dir/SongA1.mp3</string>"
224 " <key>Artist</key><string>Artist A</string>"
225 "</dict>"
226 "<key>2</key><dict>"
227 " <key>Track ID</key><integer>2</integer>"
228 " <key>Location</key><string>file://localhost/C:/dir/SongA2.mp3</string>"
229 " <key>Album</key><string>Album A</string>"
230 "</dict>"
231 "<key>3</key><dict>"
232 " <key>Track ID</key><integer>3</integer>"
233 " <key>Location</key><string>file://localhost/C:/dir/SongA3.mp3</string>"
234 "</dict>"
235 SIMPLE_FOOTER());
238 TEST_F(ITunesLibraryParserTest, AlbumArtist) {
239 AddExpectedTrack(1, "C:/dir/SongA1.mp3", "Artist A", "Unknown Album");
240 AddExpectedTrack(2, "C:/dir/SongA2.mp3", "Artist A", "Unknown Album");
241 AddExpectedTrack(3, "C:/dir/SongA3.mp3", "Artist A", "Unknown Album");
242 AddExpectedTrack(4, "C:/dir/SongA4.mp3", "Artist A", "Album");
243 TestParser(
244 true,
245 SIMPLE_HEADER()
246 "<key>1</key><dict>"
247 " <key>Track ID</key><integer>1</integer>"
248 " <key>Location</key><string>file://localhost/C:/dir/SongA1.mp3</string>"
249 " <key>Album Artist</key><string>Artist A</string>"
250 "</dict>"
251 "<key>2</key><dict>"
252 " <key>Track ID</key><integer>2</integer>"
253 " <key>Location</key><string>file://localhost/C:/dir/SongA2.mp3</string>"
254 " <key>Artist</key><string>Artist B</string>"
255 " <key>Album Artist</key><string>Artist A</string>"
256 "</dict>"
257 "<key>3</key><dict>"
258 " <key>Track ID</key><integer>3</integer>"
259 " <key>Location</key><string>file://localhost/C:/dir/SongA3.mp3</string>"
260 " <key>Album Artist</key><string>Artist A</string>"
261 " <key>Artist</key><string>Artist B</string>"
262 "</dict>"
263 "<key>4</key><dict>"
264 " <key>Track ID</key><integer>4</integer>"
265 " <key>Location</key><string>file://localhost/C:/dir/SongA4.mp3</string>"
266 " <key>Album</key><string>Album</string>"
267 " <key>Artist</key><string>Artist B</string>"
268 " <key>Album Artist</key><string>Artist A</string>"
269 "</dict>"
270 SIMPLE_FOOTER());
273 TEST_F(ITunesLibraryParserTest, MacPath) {
274 AddExpectedTrack(1, "dir/Song With Space.mp3", "Artist A", "Album A");
275 TestParser(
276 true,
277 SIMPLE_HEADER()
278 // This path is concatenated with "http://localhost/", so no leading
279 // slash should be used.
280 SIMPLE_TRACK(1, 1, "dir/Song%20With%20Space.mp3", "Artist A", "Album A")
281 SIMPLE_FOOTER());
284 } // namespace
286 } // namespace itunes