Skip to content

Commit 2382183

Browse files
sagudevSerial-ATA
authored andcommitted
Tests: Add AIFF tests from TagLib
1 parent 1dda6d1 commit 2382183

File tree

7 files changed

+234
-0
lines changed

7 files changed

+234
-0
lines changed

tests/taglib/data/alaw.aifc

1.85 KB
Binary file not shown.

tests/taglib/data/empty.aiff

5.8 KB
Binary file not shown.

tests/taglib/data/excessive_alloc.aif

2.12 KB
Binary file not shown.

tests/taglib/data/segfault.aif

31 Bytes
Binary file not shown.

tests/taglib/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub(crate) mod util;
2+
3+
mod test_aiff;

tests/taglib/test_aiff.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
use lofty::{Accessor, AudioFile, FileType, TaggedFileExt};
2+
3+
use std::io::Seek;
4+
5+
use crate::util::get_filetype;
6+
use crate::{assert_delta, temp_file};
7+
8+
#[test]
9+
#[ignore]
10+
fn test_aiff_properties() {
11+
let file = lofty::read_from_path("tests/taglib/data/empty.aiff").unwrap();
12+
13+
assert_eq!(file.file_type(), FileType::AIFF);
14+
15+
let properties = file.properties();
16+
assert_eq!(properties.duration().as_secs(), 0);
17+
assert_delta!(properties.duration().as_millis(), 67, 1);
18+
assert_delta!(properties.audio_bitrate().unwrap(), 706, 1);
19+
assert_eq!(properties.sample_rate(), Some(44100));
20+
assert_eq!(properties.channels(), Some(1));
21+
assert_eq!(properties.bit_depth(), Some(16));
22+
// TODO: get those options in lofty
23+
// CPPUNIT_ASSERT_EQUAL(2941U, f.audioProperties()->sampleFrames());
24+
// CPPUNIT_ASSERT_EQUAL(false, f.audioProperties()->isAiffC());
25+
}
26+
27+
#[test]
28+
#[ignore]
29+
fn test_aifc_properties() {
30+
let file = lofty::read_from_path("tests/taglib/data/alaw.aifc").unwrap();
31+
32+
assert_eq!(file.file_type(), FileType::AIFF);
33+
34+
let properties = file.properties();
35+
assert_eq!(properties.duration().as_secs(), 0);
36+
assert_delta!(properties.duration().as_millis(), 37, 1);
37+
assert_eq!(properties.audio_bitrate(), Some(355));
38+
assert_eq!(properties.sample_rate(), Some(44100));
39+
assert_eq!(properties.channels(), Some(1));
40+
assert_eq!(properties.bit_depth(), Some(16));
41+
// TODO: get those options in lofty
42+
// CPPUNIT_ASSERT_EQUAL(1622U, f.audioProperties()->sampleFrames());
43+
// CPPUNIT_ASSERT_EQUAL(true, f.audioProperties()->isAiffC());
44+
// CPPUNIT_ASSERT_EQUAL(ByteVector("ALAW"), f.audioProperties()->compressionType());
45+
// CPPUNIT_ASSERT_EQUAL(String("SGI CCITT G.711 A-law"), f.audioProperties()->compressionName());
46+
}
47+
48+
#[test]
49+
#[ignore]
50+
fn test_save_id3v2() {
51+
let mut file = temp_file!("tests/taglib/data/empty.aiff");
52+
53+
{
54+
let mut tfile = lofty::read_from(&mut file).unwrap();
55+
56+
assert_eq!(tfile.file_type(), FileType::AIFF);
57+
58+
assert!(tfile.tag(lofty::TagType::ID3v2).is_none());
59+
60+
let mut tag = lofty::Tag::new(lofty::TagType::ID3v2);
61+
tag.set_title("TitleXXX".to_string());
62+
tfile.insert_tag(tag);
63+
file.rewind().unwrap();
64+
tfile.save_to(&mut file).unwrap();
65+
assert!(tfile.contains_tag_type(lofty::TagType::ID3v2));
66+
}
67+
68+
file.rewind().unwrap();
69+
70+
{
71+
let mut tfile = lofty::read_from(&mut file).unwrap();
72+
73+
assert_eq!(tfile.file_type(), FileType::AIFF);
74+
75+
let mut tag = tfile.tag(lofty::TagType::ID3v2).unwrap().to_owned();
76+
assert_eq!(tag.title().as_deref(), Some("TitleXXX"));
77+
tag.set_title("".to_string());
78+
tfile.insert_tag(tag);
79+
file.rewind().unwrap();
80+
tfile.save_to(&mut file).unwrap();
81+
assert!(!tfile.contains_tag_type(lofty::TagType::ID3v2));
82+
}
83+
84+
file.rewind().unwrap();
85+
86+
{
87+
let tfile = lofty::read_from(&mut file).unwrap();
88+
89+
assert_eq!(tfile.file_type(), FileType::AIFF);
90+
91+
assert!(!tfile.contains_tag_type(lofty::TagType::ID3v2));
92+
}
93+
}
94+
95+
// TODO: testSaveID3v23
96+
// TODO: testDuplicateID3v2
97+
98+
#[test]
99+
#[ignore]
100+
fn test_fuzzed_file1() {
101+
assert_eq!(
102+
get_filetype("tests/taglib/data/segfault.aif"),
103+
FileType::AIFF
104+
);
105+
}
106+
107+
// the file doesn't even have a valid signature
108+
// #[test]
109+
// #[ignore]
110+
// fn test_fuzzed_file2() {
111+
// let mut file = File::open("tests/taglib/data/excessive_alloc.aif").unwrap();
112+
//
113+
// let mut buf = [0; 12];
114+
// file.read_exact(&mut buf).unwrap();
115+
//
116+
// assert_eq!(FileType::from_buffer(&buf).unwrap(), FileType::AIFF);
117+
// }

tests/taglib/util/mod.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/// This function tries to simulate TagLibs isValid function
2+
// https://github.com/Serial-ATA/lofty-rs/pull/51#discussion_r873171570
3+
pub fn get_filetype<P: AsRef<std::path::Path>>(path: P) -> lofty::FileType {
4+
let mut file = std::fs::File::open(path).unwrap();
5+
let mut buf = [0; 12];
6+
std::io::Read::read_exact(&mut file, &mut buf).unwrap();
7+
lofty::FileType::from_buffer(&buf).unwrap()
8+
}
9+
10+
#[macro_export]
11+
macro_rules! assert_delta {
12+
($x:expr, $y:expr, $d:expr) => {
13+
if $x > $y {
14+
assert!($x - $y <= $d)
15+
} else if $y > $x {
16+
assert!($y - $x <= $d)
17+
}
18+
};
19+
}
20+
21+
#[macro_export]
22+
macro_rules! temp_file {
23+
($path:tt) => {{
24+
use std::io::{Seek, Write};
25+
let mut file = tempfile::tempfile().unwrap();
26+
file.write_all(&std::fs::read($path).unwrap()).unwrap();
27+
28+
file.seek(std::io::SeekFrom::Start(0)).unwrap();
29+
30+
file
31+
}};
32+
}
33+
34+
#[macro_export]
35+
macro_rules! verify_artist {
36+
($file:ident, $method:ident, $expected_value:literal, $item_count:expr) => {{
37+
println!("VERIFY: Expecting `{}` to have {} items, with an artist of \"{}\"", stringify!($method), $item_count, $expected_value);
38+
39+
verify_artist!($file, $method(), $expected_value, $item_count)
40+
}};
41+
($file:ident, $method:ident, $arg:path, $expected_value:literal, $item_count:expr) => {{
42+
println!("VERIFY: Expecting `{}` to have {} items, with an artist of \"{}\"", stringify!($arg), $item_count, $expected_value);
43+
44+
verify_artist!($file, $method($arg), $expected_value, $item_count)
45+
}};
46+
($file:ident, $method:ident($($arg:path)?), $expected_value:literal, $item_count:expr) => {{
47+
assert!($file.$method($(&$arg)?).is_some());
48+
49+
let tag = $file.$method($(&$arg)?).unwrap();
50+
51+
assert_eq!(tag.item_count(), $item_count);
52+
53+
assert_eq!(
54+
tag.get_item_ref(&ItemKey::TrackArtist),
55+
Some(&TagItem::new(
56+
ItemKey::TrackArtist,
57+
ItemValue::Text(String::from($expected_value))
58+
))
59+
);
60+
61+
tag
62+
}};
63+
}
64+
65+
#[macro_export]
66+
macro_rules! set_artist {
67+
($tagged_file:ident, $method:ident, $expected_value:literal, $item_count:expr => $file_write:ident, $new_value:literal) => {
68+
let tag = verify_artist!($tagged_file, $method, $expected_value, $item_count);
69+
println!(
70+
"WRITE: Writing artist \"{}\" to {}\n",
71+
$new_value,
72+
stringify!($method)
73+
);
74+
set_artist!($file_write, $new_value, tag)
75+
};
76+
($tagged_file:ident, $method:ident, $arg:path, $expected_value:literal, $item_count:expr => $file_write:ident, $new_value:literal) => {
77+
let tag = verify_artist!($tagged_file, $method, $arg, $expected_value, $item_count);
78+
println!(
79+
"WRITE: Writing artist \"{}\" to {}\n",
80+
$new_value,
81+
stringify!($arg)
82+
);
83+
set_artist!($file_write, $new_value, tag)
84+
};
85+
($file_write:ident, $new_value:literal, $tag:ident) => {
86+
$tag.insert_item_unchecked(TagItem::new(
87+
ItemKey::TrackArtist,
88+
ItemValue::Text(String::from($new_value)),
89+
));
90+
91+
$file_write.seek(std::io::SeekFrom::Start(0)).unwrap();
92+
93+
$tag.save_to(&mut $file_write).unwrap();
94+
};
95+
}
96+
97+
#[macro_export]
98+
macro_rules! remove_tag {
99+
($path:tt, $tag_type:path) => {
100+
let mut file = temp_file!($path);
101+
102+
let tagged_file = lofty::read_from(&mut file, false).unwrap();
103+
assert!(tagged_file.tag(&$tag_type).is_some());
104+
105+
file.seek(std::io::SeekFrom::Start(0)).unwrap();
106+
107+
$tag_type.remove_from(&mut file).unwrap();
108+
109+
file.seek(std::io::SeekFrom::Start(0)).unwrap();
110+
111+
let tagged_file = lofty::read_from(&mut file, false).unwrap();
112+
assert!(tagged_file.tag(&$tag_type).is_none());
113+
};
114+
}

0 commit comments

Comments
 (0)