use super::*;
pub(crate) fn streamed_wav(frames: u32, junk: Option<u32>) -> Vec<u8> {
let mut out = b"RIFF".to_vec();
out.extend(u32::MAX.to_le_bytes());
out.extend(b"WAVE");
if let Some(size) = junk {
out.extend(b"JUNK");
out.extend(size.to_le_bytes());
out.extend(vec![0u8; size as usize]);
}
out.extend(b"fmt ");
out.extend(16u32.to_le_bytes());
out.extend(1u16.to_le_bytes()); out.extend(2u16.to_le_bytes()); out.extend(48_000u32.to_le_bytes());
out.extend((48_000u32 * 4).to_le_bytes());
out.extend(4u16.to_le_bytes());
out.extend(16u16.to_le_bytes());
out.extend(b"data");
out.extend(u32::MAX.to_le_bytes());
for i in 0..frames {
out.extend((i as i16).to_le_bytes());
out.extend((-(i as i16)).to_le_bytes());
}
out
}
fn file_of(bytes: &[u8]) -> (tempfile::TempDir, File) {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("take.wav");
std::fs::write(&path, bytes).unwrap();
let file = std::fs::OpenOptions::new()
.read(true)
.write(true)
.open(&path)
.unwrap();
(dir, file)
}
#[test]
fn a_streamed_wav_gets_its_sizes() {
let bytes = streamed_wav(100, None);
let (_dir, mut file) = file_of(&bytes);
assert_eq!(fix_wav_sizes(&mut file).unwrap(), Fixed::Riff);
assert_eq!(read_u32(&mut file, 4).unwrap() as usize, bytes.len() - 8);
assert_eq!(
read_u32(&mut file, 40).unwrap(),
400,
"100 frames of 4 bytes"
);
let header =
crate::formats::audio::read_header(&std::fs::read(_dir.path().join("take.wav")).unwrap());
assert!(header.is_ok(), "{header:?}");
assert_eq!(fix_wav_sizes(&mut file).unwrap(), Fixed::Nothing, "once");
}
#[test]
fn other_files_are_left_alone() {
let (_dir, mut file) = file_of(b"a,b\n1,2\n");
assert_eq!(fix_wav_sizes(&mut file).unwrap(), Fixed::Nothing);
assert_eq!(
std::fs::read(_dir.path().join("take.wav")).unwrap(),
b"a,b\n1,2\n"
);
}
#[test]
fn over_four_gigabytes_the_header_becomes_rf64() {
let bytes = streamed_wav(0, Some(28));
let (dir, mut file) = file_of(&bytes);
let len = 5u64 << 30;
file.set_len(len).unwrap();
assert_eq!(fix_wav_sizes(&mut file).unwrap(), Fixed::Rf64);
let head = {
let mut head = vec![0u8; 80];
file.seek(SeekFrom::Start(0)).unwrap();
file.read_exact(&mut head).unwrap();
head
};
assert_eq!(&head[0..4], b"RF64");
assert_eq!(&head[12..16], b"ds64");
let u64_at = |at: usize| u64::from_le_bytes(head[at..at + 8].try_into().unwrap());
assert_eq!(u64_at(20), len - 8, "the RIFF size");
let data_at = 12 + 8 + 28 + 8 + 16;
assert_eq!(&head[data_at..data_at + 4], b"data");
assert_eq!(u64_at(28), len - (data_at as u64 + 8), "the data size");
drop(dir);
let (_dir, mut file) = file_of(&streamed_wav(0, None));
file.set_len(len).unwrap();
assert_eq!(fix_wav_sizes(&mut file).unwrap(), Fixed::TooLong);
}
#[test]
fn an_existing_file_is_refused_without_force() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("run1.csv");
std::fs::write(&path, "keep me").unwrap();
let refused = create(&path, false).unwrap_err();
assert!(refused.contains("--force"), "{refused}");
assert_eq!(std::fs::read(&path).unwrap(), b"keep me");
create(&path, true).unwrap();
assert_eq!(
std::fs::read(&path).unwrap(),
b"",
"overwritten with --force"
);
}