use std::io::SeekFrom;
use async_spooled_tempfile::{SpooledData, SpooledTempFile};
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
#[tokio::test]
async fn test_implicit_rollover() {
let mut sf = SpooledTempFile::new(5);
let mut read_buffer = Vec::new();
assert!(!sf.is_rolled());
assert!(!sf.is_poisoned());
assert!(std::matches!(sf.stream_position().await, Ok(0)));
sf.read_to_end(&mut read_buffer).await.unwrap();
assert_eq!(read_buffer.len(), 0);
let first_data_written = b"1234";
sf.write_all(first_data_written).await.unwrap();
assert!(!sf.is_rolled());
assert!(!sf.is_poisoned());
let res_cur_pos = sf.stream_position().await;
assert!(std::matches!(res_cur_pos, Ok(4)));
let cur_pos = res_cur_pos.unwrap();
sf.seek(SeekFrom::Start(0)).await.unwrap();
sf.read_to_end(&mut read_buffer).await.unwrap();
assert_eq!(read_buffer.as_slice(), first_data_written);
read_buffer.clear();
sf.seek(SeekFrom::Start(cur_pos)).await.unwrap();
let second_data_written = b"5678";
sf.write_all(second_data_written).await.unwrap();
assert!(sf.is_rolled());
assert!(!sf.is_poisoned());
assert!(std::matches!(sf.stream_position().await, Ok(8)));
sf.seek(SeekFrom::Start(0)).await.unwrap();
sf.read_to_end(&mut read_buffer).await.unwrap();
assert_eq!(
read_buffer,
[
first_data_written.as_slice(),
second_data_written.as_slice()
]
.concat()
);
assert!(std::matches!(
sf.into_inner().await,
Ok(SpooledData::OnDisk(..))
));
}
#[tokio::test]
async fn test_explicit_rollover() {
let mut sf = SpooledTempFile::new(5);
let mut read_buffer = Vec::new();
let first_data_written = b"123";
sf.write_all(first_data_written).await.unwrap();
assert!(!sf.is_rolled());
assert!(!sf.is_poisoned());
assert!(std::matches!(sf.stream_position().await, Ok(3)));
sf.seek(SeekFrom::Start(0)).await.unwrap();
sf.roll().await.unwrap();
assert!(sf.is_rolled());
assert!(!sf.is_poisoned());
assert!(std::matches!(sf.stream_position().await, Ok(0)));
sf.read_to_end(&mut read_buffer).await.unwrap();
assert_eq!(read_buffer.as_slice(), first_data_written);
assert!(std::matches!(
sf.into_inner().await,
Ok(SpooledData::OnDisk(..))
));
}
#[tokio::test]
async fn test_into_inner() {
let mut sf1 = SpooledTempFile::new(10);
let first_data_written = b"1234567";
sf1.write_all(first_data_written).await.unwrap();
assert!(!sf1.is_rolled());
assert!(!sf1.is_poisoned());
assert!(std::matches!(sf1.stream_position().await, Ok(7)));
assert!(std::matches!(
sf1.into_inner().await,
Ok(SpooledData::InMemory(..))
));
let mut sf2 = SpooledTempFile::with_max_size_and_capacity(10, 10);
let second_data_written = b"123456789abcdef";
sf2.write_all(second_data_written).await.unwrap();
assert!(sf2.is_rolled());
assert!(!sf2.is_poisoned());
assert!(std::matches!(sf2.stream_position().await, Ok(15)));
assert!(std::matches!(
sf2.into_inner().await,
Ok(SpooledData::OnDisk(..))
));
}
#[tokio::test]
async fn test_set_len() {
let mut sf1 = SpooledTempFile::new(10);
sf1.set_len(4).await.unwrap();
let f1_buffer = match sf1.into_inner().await {
Ok(SpooledData::InMemory(cur)) => cur.into_inner(),
_ => panic!("the data of the first spooled file should be in memory"),
};
assert_eq!(f1_buffer.as_slice(), b"\x00\x00\x00\x00");
let mut sf2 = SpooledTempFile::new(5);
sf2.write_all(b"abc").await.unwrap();
assert!(!sf2.is_rolled());
assert!(!sf2.is_poisoned());
sf2.set_len(10).await.unwrap();
let mut sf2_file = match sf2.into_inner().await {
Ok(SpooledData::OnDisk(file)) => file,
_ => panic!("the data of the second spooled file should be located in a file"),
};
sf2_file.seek(SeekFrom::Start(0)).await.unwrap();
let mut sf2_content = Vec::new();
sf2_file.read_to_end(&mut sf2_content).await.unwrap();
assert_eq!(sf2_content.as_slice(), b"abc\x00\x00\x00\x00\x00\x00\x00");
}