1 use std::fs;
2
3 use walkdir::WalkDir;
4
5 use mp4ameta::{AdvisoryRating, Data, MediaType, STANDARD_GENRES, Tag};
6
7 const EXTENSIONS: [&str; 4] = [".m4a", ".m4b", ".m4p", ".m4v"];
8
9 #[test]
sample_files()10 fn sample_files() {
11 for d in WalkDir::new("./files")
12 .follow_links(true)
13 .into_iter()
14 .filter_map(|e| e.ok())
15 .filter(|e| e.metadata().map(|m| m.is_file()).unwrap_or(false))
16 {
17 let filename = d.file_name().to_str().unwrap();
18 let mut mp4file = false;
19 for e in EXTENSIONS.iter() {
20 if filename.ends_with(e) {
21 mp4file = true;
22 }
23 }
24
25 if !mp4file {
26 continue;
27 }
28
29 let filepath = d.into_path();
30
31 println!("{}:", filepath.display());
32 let tag_sample = Tag::read_from_path(&filepath).unwrap();
33 println!("{:#?}", tag_sample);
34 }
35 }
36
37 #[test]
verify_sample_data()38 fn verify_sample_data() {
39 let tag = Tag::read_from_path("./files/sample.m4a").unwrap();
40
41 assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Explicit(4)));
42 assert_eq!(tag.album(), Some("TEST ALBUM"));
43 assert_eq!(tag.album_artist(), Some("TEST ALBUM ARTIST"));
44 assert_eq!(tag.artist(), Some("TEST ARTIST"));
45 assert_eq!(tag.bpm(), Some(132));
46 assert_eq!(tag.category(), Some("TEST CATEGORY"));
47 assert_eq!(tag.comment(), Some("TEST COMMENT"));
48 assert_eq!(tag.compilation(), true);
49 assert_eq!(tag.composer(), Some("TEST COMPOSER"));
50 assert_eq!(tag.copyright(), Some("TEST COPYRIGHT"));
51 assert_eq!(tag.description(), Some("TEST DESCRIPTION"));
52 assert_eq!(tag.disc(), (Some(1), Some(2)));
53 assert_eq!(tag.disc_number(), Some(1));
54 assert_eq!(tag.total_discs(), Some(2));
55 assert_eq!(tag.encoder(), Some("Lavf58.29.100"));
56 assert_eq!(tag.gapless_playback(), true);
57 assert_eq!(tag.genre(), Some("Hard Rock"));
58 assert_eq!(tag.grouping(), Some("TEST GROUPING"));
59 assert_eq!(tag.keyword(), Some("TEST KEYWORD"));
60 assert_eq!(tag.lyrics(), Some("TEST LYRICS"));
61 assert_eq!(tag.media_type(), Some(MediaType::Normal));
62 assert_eq!(tag.title(), Some("TEST TITLE"));
63 assert_eq!(tag.track(), (Some(7), Some(13)));
64 assert_eq!(tag.track_number(), Some(7));
65 assert_eq!(tag.total_tracks(), Some(13));
66 assert_eq!(tag.year(), Some("2013"));
67 assert_eq!(tag.artwork(), Some(&Data::Png(fs::read("./files/artwork.png").unwrap())));
68 assert_eq!(tag.duration(), Some(0.48523809523809525));
69 assert_eq!(tag.filetype(), Some("M4A \u{0}\u{0}\u{2}\u{0}isomiso2"));
70 }
71
72 #[test]
write_read()73 fn write_read() {
74 let mut tag = Tag::default();
75 tag.set_advisory_rating(AdvisoryRating::Inoffensive);
76 tag.set_album("NEW ALBUM");
77 tag.set_album_artist("NEW ALBUM ARTIST");
78 tag.set_artist("NEW ARTIST");
79 tag.set_bpm(98);
80 tag.set_category("NEW CATEGORY");
81 tag.set_comment("NEW COMMENT");
82 tag.set_compilation();
83 tag.set_composer("NEW COMPOSER");
84 tag.set_copyright("NEW COPYRIGHT");
85 tag.set_description("NEW DESCRIPTION");
86 tag.set_disc(2, 0);
87 tag.set_encoder("Lavf58.12.100");
88 tag.set_gapless_playback();
89 tag.set_genre("Hard Rock");
90 tag.set_grouping("NEW GROUPING");
91 tag.set_keyword("NEW KEYWORD");
92 tag.set_lyrics("NEW LYRICS");
93 tag.set_media_type(MediaType::AudioBook);
94 tag.set_title("NEW TITLE");
95 tag.set_track(3, 7);
96 tag.set_year("1998");
97 tag.set_artwork(Data::Jpeg(b"NEW ARTWORK".to_vec()));
98
99 std::fs::copy("./files/sample.m4a", "./files/temp.m4a").unwrap();
100 tag.write_to_path("./files/temp.m4a").unwrap();
101
102 let tag = Tag::read_from_path("./files/temp.m4a").unwrap();
103 assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Inoffensive));
104 assert_eq!(tag.album(), Some("NEW ALBUM"));
105 assert_eq!(tag.album_artist(), Some("NEW ALBUM ARTIST"));
106 assert_eq!(tag.artist(), Some("NEW ARTIST"));
107 assert_eq!(tag.bpm(), Some(98));
108 assert_eq!(tag.category(), Some("NEW CATEGORY"));
109 assert_eq!(tag.comment(), Some("NEW COMMENT"));
110 assert_eq!(tag.compilation(), true);
111 assert_eq!(tag.composer(), Some("NEW COMPOSER"));
112 assert_eq!(tag.copyright(), Some("NEW COPYRIGHT"));
113 assert_eq!(tag.description(), Some("NEW DESCRIPTION"));
114 assert_eq!(tag.disc(), (Some(2), None));
115 assert_eq!(tag.disc_number(), Some(2));
116 assert_eq!(tag.total_discs(), None);
117 assert_eq!(tag.encoder(), Some("Lavf58.12.100"));
118 assert_eq!(tag.gapless_playback(), true);
119 assert_eq!(tag.genre(), Some("Hard Rock"));
120 assert_eq!(tag.grouping(), Some("NEW GROUPING"));
121 assert_eq!(tag.keyword(), Some("NEW KEYWORD"));
122 assert_eq!(tag.lyrics(), Some("NEW LYRICS"));
123 assert_eq!(tag.media_type(), Some(MediaType::AudioBook));
124 assert_eq!(tag.title(), Some("NEW TITLE"));
125 assert_eq!(tag.track(), (Some(3), Some(7)));
126 assert_eq!(tag.track_number(), Some(3));
127 assert_eq!(tag.total_tracks(), Some(7));
128 assert_eq!(tag.year(), Some("1998"));
129 assert_eq!(tag.artwork(), Some(&Data::Jpeg(b"NEW ARTWORK".to_vec())));
130 assert_eq!(tag.duration(), Some(0.48523809523809525));
131 assert_eq!(tag.filetype(), Some("M4A \u{0}\u{0}\u{2}\u{0}isomiso2"));
132
133 std::fs::remove_file("./files/temp.m4a").unwrap();
134 }
135
136 #[test]
dump_read()137 fn dump_read() {
138 let mut tag = Tag::default();
139 tag.set_advisory_rating(AdvisoryRating::Explicit(4));
140 tag.set_album("TEST ALBUM");
141 tag.set_album_artist("TEST ALBUM ARTIST");
142 tag.set_artist("TEST ARTIST");
143 tag.set_bpm(132);
144 tag.set_category("TEST CATEGORY");
145 tag.set_comment("TEST COMMENT");
146 tag.set_compilation();
147 tag.set_composer("TEST COMPOSER");
148 tag.set_copyright("TEST COPYRIGHT");
149 tag.set_description("TEST DESCRIPTION");
150 tag.set_disc(1, 2);
151 tag.set_encoder("Lavf58.29.100");
152 tag.set_gapless_playback();
153 tag.set_genre("Hard Rock");
154 tag.set_grouping("TEST GROUPING");
155 tag.set_keyword("TEST KEYWORD");
156 tag.set_lyrics("TEST LYRICS");
157 tag.set_media_type(MediaType::Normal);
158 tag.set_title("TEST TITLE");
159 tag.set_track(7, 13);
160 tag.set_year("2013");
161 tag.set_artwork(Data::Png(b"TEST ARTWORK".to_vec()));
162
163 tag.dump_to_path("./files/temp.m4a").unwrap();
164
165 let tag = Tag::read_from_path("./files/temp.m4a").unwrap();
166 assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Explicit(4)));
167 assert_eq!(tag.album(), Some("TEST ALBUM"));
168 assert_eq!(tag.album_artist(), Some("TEST ALBUM ARTIST"));
169 assert_eq!(tag.artist(), Some("TEST ARTIST"));
170 assert_eq!(tag.bpm(), Some(132));
171 assert_eq!(tag.category(), Some("TEST CATEGORY"));
172 assert_eq!(tag.comment(), Some("TEST COMMENT"));
173 assert_eq!(tag.compilation(), true);
174 assert_eq!(tag.composer(), Some("TEST COMPOSER"));
175 assert_eq!(tag.copyright(), Some("TEST COPYRIGHT"));
176 assert_eq!(tag.description(), Some("TEST DESCRIPTION"));
177 assert_eq!(tag.disc(), (Some(1), Some(2)));
178 assert_eq!(tag.disc_number(), Some(1));
179 assert_eq!(tag.total_discs(), Some(2));
180 assert_eq!(tag.encoder(), Some("Lavf58.29.100"));
181 assert_eq!(tag.gapless_playback(), true);
182 assert_eq!(tag.genre(), Some("Hard Rock"));
183 assert_eq!(tag.grouping(), Some("TEST GROUPING"));
184 assert_eq!(tag.keyword(), Some("TEST KEYWORD"));
185 assert_eq!(tag.lyrics(), Some("TEST LYRICS"));
186 assert_eq!(tag.media_type(), Some(MediaType::Normal));
187 assert_eq!(tag.title(), Some("TEST TITLE"));
188 assert_eq!(tag.track(), (Some(7), Some(13)));
189 assert_eq!(tag.track_number(), Some(7));
190 assert_eq!(tag.total_tracks(), Some(13));
191 assert_eq!(tag.year(), Some("2013"));
192 assert_eq!(tag.artwork(), Some(&Data::Png(b"TEST ARTWORK".to_vec())));
193
194 std::fs::remove_file("./files/temp.m4a").unwrap();
195 }
196
197 #[test]
multiple_values()198 fn multiple_values() {
199 let mut tag = Tag::default();
200
201 tag.add_artist("1");
202 tag.add_artist("2");
203 tag.add_artist("3");
204 tag.add_artist("4");
205
206 assert_eq!(tag.artist(), Some("1"));
207 {
208 let mut artists = tag.artists();
209 assert_eq!(artists.next(), Some("1"));
210 assert_eq!(artists.next(), Some("2"));
211 assert_eq!(artists.next(), Some("3"));
212 assert_eq!(artists.next(), Some("4"));
213 assert_eq!(artists.next(), None);
214 }
215
216 tag.set_artist("5");
217
218 assert_eq!(tag.artist(), Some("5"));
219 {
220 let mut artists = tag.artists();
221 assert_eq!(artists.next(), Some("5"));
222 assert_eq!(artists.next(), None);
223 }
224
225 tag.add_artist("6");
226 tag.add_artist("7");
227
228 assert_eq!(tag.artist(), Some("5"));
229 {
230 let mut artists = tag.artists();
231 assert_eq!(artists.next(), Some("5"));
232 assert_eq!(artists.next(), Some("6"));
233 assert_eq!(artists.next(), Some("7"));
234 assert_eq!(artists.next(), None);
235 }
236
237 tag.remove_artists();
238
239 assert_eq!(tag.artists().next(), None);
240 assert_eq!(tag.artist(), None);
241 }
242
243 #[test]
genre_handling()244 fn genre_handling() {
245 let (code, name) = STANDARD_GENRES[4];
246
247 let mut tag = Tag::default();
248 assert_eq!(tag.genre(), None);
249 assert_eq!(tag.standard_genre(), None);
250 assert_eq!(tag.custom_genre(), None);
251
252 tag.set_genre(name);
253 assert_eq!(tag.genre(), Some(name));
254 assert_eq!(tag.standard_genre(), Some(code));
255 assert_eq!(tag.custom_genre(), None);
256
257 tag.set_genre("CUSTOM GENRE");
258 assert_eq!(tag.genre(), Some("CUSTOM GENRE"));
259 assert_eq!(tag.standard_genre(), None);
260 assert_eq!(tag.custom_genre(), Some("CUSTOM GENRE"));
261
262 tag.remove_genres();
263 assert_eq!(tag.genre(), None);
264 assert_eq!(tag.genres().next(), None);
265
266 let (code1, name1) = STANDARD_GENRES[6];
267 let (code2, name2) = STANDARD_GENRES[23];
268 tag.add_custom_genre("GENRE 1");
269 tag.add_standard_genre(code1);
270 tag.add_custom_genre("GENRE 2");
271 tag.add_standard_genre(code2);
272
273 {
274 let mut genres = tag.genres();
275 assert_eq!(genres.next(), Some(name1));
276 assert_eq!(genres.next(), Some(name2));
277 assert_eq!(genres.next(), Some("GENRE 1"));
278 assert_eq!(genres.next(), Some("GENRE 2"));
279 assert_eq!(genres.next(), None);
280
281 let mut standard_genres = tag.standard_genres();
282 assert_eq!(standard_genres.next(), Some(code1));
283 assert_eq!(standard_genres.next(), Some(code2));
284 assert_eq!(genres.next(), None);
285
286 let mut custom_genres = tag.custom_genres();
287 assert_eq!(custom_genres.next(), Some("GENRE 1"));
288 assert_eq!(custom_genres.next(), Some("GENRE 2"));
289 assert_eq!(genres.next(), None);
290 }
291
292 tag.remove_standard_genres();
293 assert_eq!(tag.standard_genres().next(), None);
294 assert_eq!(tag.genres().next(), Some("GENRE 1"));
295
296 tag.remove_custom_genres();
297 assert_eq!(tag.custom_genres().next(), None);
298 assert_eq!(tag.genres().next(), None);
299 }
300
301 #[test]
track_disc_handling()302 fn track_disc_handling() {
303 let track_number = 4u16;
304 let total_tracks = 16u16;
305 let disc_number = 2u16;
306 let total_discs = 3u16;
307
308 let mut tag = Tag::default();
309 assert_eq!(tag.track(), (None, None));
310 assert_eq!(tag.track_number(), None);
311 assert_eq!(tag.total_tracks(), None);
312 assert_eq!(tag.disc(), (None, None));
313 assert_eq!(tag.disc_number(), None);
314 assert_eq!(tag.total_discs(), None);
315
316 tag.set_track_number(track_number);
317 tag.set_total_tracks(total_tracks);
318 tag.set_disc_number(disc_number);
319 tag.set_total_discs(total_discs);
320
321 assert_eq!(tag.track(), (Some(track_number), Some(total_tracks)));
322 assert_eq!(tag.track_number(), Some(track_number));
323 assert_eq!(tag.total_tracks(), Some(total_tracks));
324 assert_eq!(tag.disc(), (Some(disc_number), Some(total_discs)));
325 assert_eq!(tag.disc_number(), Some(disc_number));
326 assert_eq!(tag.total_discs(), Some(total_discs));
327
328 tag.remove_track_number();
329 tag.remove_disc_number();
330
331 assert_eq!(tag.track(), (None, Some(total_tracks)));
332 assert_eq!(tag.track_number(), None);
333 assert_eq!(tag.total_tracks(), Some(total_tracks));
334 assert_eq!(tag.disc(), (None, Some(total_discs)));
335 assert_eq!(tag.disc_number(), None);
336 assert_eq!(tag.total_discs(), Some(total_discs));
337
338 tag.remove_total_tracks();
339 tag.remove_total_discs();
340
341 assert_eq!(tag.track(), (None, None));
342 assert_eq!(tag.track_number(), None);
343 assert_eq!(tag.total_tracks(), None);
344 assert_eq!(tag.disc(), (None, None));
345 assert_eq!(tag.disc_number(), None);
346 assert_eq!(tag.total_discs(), None);
347 }
348
349 #[test]
work_movement_handling()350 fn work_movement_handling() {
351 let movement = "TEST MOVEMENT";
352 let index = 1u16;
353 let count = 8u16;
354 let work = "TEST WORK";
355
356 let mut tag = Tag::default();
357 assert_eq!(tag.movement(), None);
358 assert_eq!(tag.movement_count(), None);
359 assert_eq!(tag.movement_index(), None);
360 assert_eq!(tag.show_movement(), false);
361 assert_eq!(tag.work(), None);
362
363 tag.set_movement(movement);
364 tag.set_movement_count(count);
365 tag.set_movement_index(index);
366 tag.set_show_movement();
367 tag.set_work(work);
368
369 assert_eq!(tag.movement(), Some(movement));
370 assert_eq!(tag.movement_count(), Some(count));
371 assert_eq!(tag.movement_index(), Some(index));
372 assert_eq!(tag.show_movement(), true);
373 assert_eq!(tag.work(), Some(work));
374 }
375