-
-
Notifications
You must be signed in to change notification settings - Fork 45
Add tests from taglib #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6e6dd5e
fa88fef
36e5007
68ff183
db48aac
944cd3e
8bd07bd
95d4456
513e1d2
e6b1413
1786e77
f758179
514bf22
7ba156b
d251a58
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub(crate) mod util; | ||
|
||
mod test_aiff; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use std::io::Seek; | ||
|
||
use crate::util::get_filetype; | ||
use crate::{assert_delta, temp_file}; | ||
use lofty::{Accessor, AudioFile, FileType}; | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_aiff_properties() { | ||
let file = lofty::read_from_path("tests/taglib/data/empty.aiff", true).unwrap(); | ||
|
||
assert_eq!(file.file_type(), FileType::AIFF); | ||
|
||
let properties = file.properties(); | ||
assert_eq!(properties.duration().as_secs(), 0); | ||
assert_delta!(properties.duration().as_millis(), 67, 1); | ||
assert_delta!(properties.audio_bitrate().unwrap(), 706, 1); | ||
assert_eq!(properties.sample_rate(), Some(44100)); | ||
assert_eq!(properties.channels(), Some(1)); | ||
assert_eq!(properties.bit_depth(), Some(16)); | ||
// TODO: get those options in lofty | ||
// CPPUNIT_ASSERT_EQUAL(2941U, f.audioProperties()->sampleFrames()); | ||
// CPPUNIT_ASSERT_EQUAL(false, f.audioProperties()->isAiffC()); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_aifc_properties() { | ||
let file = lofty::read_from_path("tests/taglib/data/alaw.aifc", true).unwrap(); | ||
|
||
assert_eq!(file.file_type(), FileType::AIFF); | ||
|
||
let properties = file.properties(); | ||
assert_eq!(properties.duration().as_secs(), 0); | ||
assert_delta!(properties.duration().as_millis(), 37, 1); | ||
assert_eq!(properties.audio_bitrate(), Some(355)); | ||
assert_eq!(properties.sample_rate(), Some(44100)); | ||
assert_eq!(properties.channels(), Some(1)); | ||
assert_eq!(properties.bit_depth(), Some(16)); | ||
// TODO: get those options in lofty | ||
// CPPUNIT_ASSERT_EQUAL(1622U, f.audioProperties()->sampleFrames()); | ||
// CPPUNIT_ASSERT_EQUAL(true, f.audioProperties()->isAiffC()); | ||
// CPPUNIT_ASSERT_EQUAL(ByteVector("ALAW"), f.audioProperties()->compressionType()); | ||
// CPPUNIT_ASSERT_EQUAL(String("SGI CCITT G.711 A-law"), f.audioProperties()->compressionName()); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_save_id3v2() { | ||
let mut file = temp_file!("tests/taglib/data/empty.aiff"); | ||
|
||
{ | ||
let mut tfile = lofty::read_from(&mut file, true).unwrap(); | ||
|
||
assert_eq!(tfile.file_type(), FileType::AIFF); | ||
|
||
assert!(tfile.tag(lofty::TagType::ID3v2).is_none()); | ||
|
||
let mut tag = lofty::Tag::new(lofty::TagType::ID3v2); | ||
tag.set_title("TitleXXX".to_string()); | ||
tfile.insert_tag(tag); | ||
file.rewind().unwrap(); | ||
tfile.save_to(&mut file).unwrap(); | ||
assert!(tfile.contains_tag_type(lofty::TagType::ID3v2)); | ||
} | ||
|
||
file.rewind().unwrap(); | ||
|
||
{ | ||
let mut tfile = lofty::read_from(&mut file, true).unwrap(); | ||
|
||
assert_eq!(tfile.file_type(), FileType::AIFF); | ||
|
||
let mut tag = tfile.tag(lofty::TagType::ID3v2).unwrap().to_owned(); | ||
assert_eq!(tag.title(), Some("TitleXXX")); | ||
tag.set_title("".to_string()); | ||
sagudev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
tfile.insert_tag(tag); | ||
file.rewind().unwrap(); | ||
tfile.save_to(&mut file).unwrap(); | ||
assert!(!tfile.contains_tag_type(lofty::TagType::ID3v2)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if I comment out this line similar test in line 90 runs successfully. Lofty apparently keeps empty ID3v2 in it struct but does not write it, while TagLib probably removes it on save to keep internal struct in-sync with file. Is this made on porpuse or is it a bug @Serial-ATA? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like TagLib removes them in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And something analogus to how TagLib handles files would be very useful too. The File instance would then needed to be stored somewhere inside. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean tying a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, something like that. I was also thinking about wrapper that would allowed that and provide backwards compatibility. |
||
} | ||
|
||
file.rewind().unwrap(); | ||
|
||
{ | ||
let tfile = lofty::read_from(&mut file, true).unwrap(); | ||
|
||
assert_eq!(tfile.file_type(), FileType::AIFF); | ||
|
||
assert!(!tfile.contains_tag_type(lofty::TagType::ID3v2)); | ||
} | ||
} | ||
|
||
// TODO: testSaveID3v23 | ||
// TODO: testDuplicateID3v2 | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_fuzzed_file1() { | ||
assert_eq!( | ||
get_filetype("tests/taglib/data/segfault.aif"), | ||
FileType::AIFF | ||
); | ||
} | ||
|
||
// the file doesn't even have a valid signature | ||
// #[test] | ||
// #[ignore] | ||
// fn test_fuzzed_file2() { | ||
// let mut file = File::open("tests/taglib/data/excessive_alloc.aif").unwrap(); | ||
// | ||
// let mut buf = [0; 12]; | ||
// file.read_exact(&mut buf).unwrap(); | ||
// | ||
// assert_eq!(FileType::from_buffer(&buf).unwrap(), FileType::AIFF); | ||
// } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/// This function tries to simulate TagLibs isValid function | ||
// https://github.com/Serial-ATA/lofty-rs/pull/51#discussion_r873171570 | ||
pub fn get_filetype<P: AsRef<std::path::Path>>(path: P) -> lofty::FileType { | ||
let mut file = std::fs::File::open(path).unwrap(); | ||
let mut buf = [0; 12]; | ||
std::io::Read::read_exact(&mut file, &mut buf).unwrap(); | ||
lofty::FileType::from_buffer(&buf).unwrap() | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! assert_delta { | ||
($x:expr, $y:expr, $d:expr) => { | ||
if $x > $y { | ||
assert!($x - $y <= $d) | ||
} else if $y > $x { | ||
assert!($y - $x <= $d) | ||
} | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! temp_file { | ||
($path:tt) => {{ | ||
use std::io::{Seek, Write}; | ||
let mut file = tempfile::tempfile().unwrap(); | ||
file.write_all(&std::fs::read($path).unwrap()).unwrap(); | ||
|
||
file.seek(std::io::SeekFrom::Start(0)).unwrap(); | ||
|
||
file | ||
}}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! verify_artist { | ||
($file:ident, $method:ident, $expected_value:literal, $item_count:expr) => {{ | ||
println!("VERIFY: Expecting `{}` to have {} items, with an artist of \"{}\"", stringify!($method), $item_count, $expected_value); | ||
|
||
verify_artist!($file, $method(), $expected_value, $item_count) | ||
}}; | ||
($file:ident, $method:ident, $arg:path, $expected_value:literal, $item_count:expr) => {{ | ||
println!("VERIFY: Expecting `{}` to have {} items, with an artist of \"{}\"", stringify!($arg), $item_count, $expected_value); | ||
|
||
verify_artist!($file, $method($arg), $expected_value, $item_count) | ||
}}; | ||
($file:ident, $method:ident($($arg:path)?), $expected_value:literal, $item_count:expr) => {{ | ||
assert!($file.$method($(&$arg)?).is_some()); | ||
|
||
let tag = $file.$method($(&$arg)?).unwrap(); | ||
|
||
assert_eq!(tag.item_count(), $item_count); | ||
|
||
assert_eq!( | ||
tag.get_item_ref(&ItemKey::TrackArtist), | ||
Some(&TagItem::new( | ||
ItemKey::TrackArtist, | ||
ItemValue::Text(String::from($expected_value)) | ||
)) | ||
); | ||
|
||
tag | ||
}}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! set_artist { | ||
($tagged_file:ident, $method:ident, $expected_value:literal, $item_count:expr => $file_write:ident, $new_value:literal) => { | ||
let tag = verify_artist!($tagged_file, $method, $expected_value, $item_count); | ||
println!( | ||
"WRITE: Writing artist \"{}\" to {}\n", | ||
$new_value, | ||
stringify!($method) | ||
); | ||
set_artist!($file_write, $new_value, tag) | ||
}; | ||
($tagged_file:ident, $method:ident, $arg:path, $expected_value:literal, $item_count:expr => $file_write:ident, $new_value:literal) => { | ||
let tag = verify_artist!($tagged_file, $method, $arg, $expected_value, $item_count); | ||
println!( | ||
"WRITE: Writing artist \"{}\" to {}\n", | ||
$new_value, | ||
stringify!($arg) | ||
); | ||
set_artist!($file_write, $new_value, tag) | ||
}; | ||
($file_write:ident, $new_value:literal, $tag:ident) => { | ||
$tag.insert_item_unchecked(TagItem::new( | ||
ItemKey::TrackArtist, | ||
ItemValue::Text(String::from($new_value)), | ||
)); | ||
|
||
$file_write.seek(std::io::SeekFrom::Start(0)).unwrap(); | ||
|
||
$tag.save_to(&mut $file_write).unwrap(); | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! remove_tag { | ||
($path:tt, $tag_type:path) => { | ||
let mut file = temp_file!($path); | ||
|
||
let tagged_file = lofty::read_from(&mut file, false).unwrap(); | ||
assert!(tagged_file.tag(&$tag_type).is_some()); | ||
|
||
file.seek(std::io::SeekFrom::Start(0)).unwrap(); | ||
|
||
$tag_type.remove_from(&mut file).unwrap(); | ||
|
||
file.seek(std::io::SeekFrom::Start(0)).unwrap(); | ||
|
||
let tagged_file = lofty::read_from(&mut file, false).unwrap(); | ||
assert!(tagged_file.tag(&$tag_type).is_none()); | ||
}; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.