use std::sync::atomic::AtomicI32;
use futures_lite::{future::block_on, io::Cursor, AsyncWriteExt};
use crate::write::AsyncMapWriter;
#[test]
fn basic_transformation() {
let output = Cursor::new(vec![]);
let transformer = |buf: &mut Vec<u8>| {
for byte in buf.iter_mut() {
if *byte >= b'a' && *byte <= b'z' {
*byte = *byte - b'a' + b'A';
}
}
};
let mut writer = AsyncMapWriter::new(output, transformer);
block_on(async {
writer.write_all(b"hello world").await.unwrap();
writer.flush().await.unwrap();
let result = writer.into_inner().into_inner();
assert_eq!(result, b"HELLO WORLD");
});
}
#[test]
fn small_writes_accumulation() {
let output = Cursor::new(vec![]);
let counter = AtomicI32::new(0);
let transformer = |_: &mut Vec<u8>| {
counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
};
let mut writer = AsyncMapWriter::with_capacity(output, transformer, 10);
block_on(async {
writer.write_all(b"abc").await.unwrap(); writer.write_all(b"def").await.unwrap(); writer.flush().await.unwrap();
assert_eq!(writer.into_inner().into_inner(), b"abcdef");
let counter = counter.load(std::sync::atomic::Ordering::SeqCst);
assert!(counter == 1, "Transformer should have only been called once");
});
}
#[test]
fn large_write_exceeding_buffer() {
let output = Cursor::new(vec![]);
let transformer = |buf: &mut Vec<u8>| {
let original = buf.clone();
buf.clear();
for byte in original {
buf.push(byte);
buf.push(byte);
}
};
let mut writer = AsyncMapWriter::with_capacity(output, transformer, 5);
block_on(async {
writer.write_all(b"abcdefghij").await.unwrap();
writer.flush().await.unwrap();
let result = writer.into_inner().into_inner();
assert_eq!(result, b"aabbccddeeffgghhiijj");
});
}
#[test]
fn empty_write() {
let output = Cursor::new(vec![]);
let transformer = |_: &mut Vec<u8>| {};
let mut writer = AsyncMapWriter::new(output, transformer);
block_on(async {
let n = writer.write(b"").await.unwrap();
assert_eq!(n, 0, "Empty write should return 0 bytes written");
writer.flush().await.unwrap();
let result = writer.into_inner().into_inner();
assert!(result.is_empty(), "No data should have been written");
});
}
#[test]
fn close_behavior() {
let output = Cursor::new(vec![]);
let transformer = |buf: &mut Vec<u8>| {
let mut prefix = b"prefix:".to_vec();
prefix.append(buf);
*buf = prefix;
};
let mut writer = AsyncMapWriter::new(output, transformer);
block_on(async {
writer.write_all(b"data").await.unwrap();
writer.close().await.unwrap();
let result = writer.into_inner().into_inner();
assert_eq!(result, b"prefix:data");
});
}
#[test]
fn identity_function() {
let output = Cursor::new(vec![]);
let transformer = |_: &mut Vec<u8>| {
};
let mut writer = AsyncMapWriter::new(output, transformer);
block_on(async {
writer.write_all(b"identity test").await.unwrap();
writer.flush().await.unwrap();
let result = writer.into_inner().into_inner();
assert_eq!(result, b"identity test");
});
}
#[test]
fn chunk_processing_after_large_write() {
let transformer = |buf: &mut Vec<u8>| {
println!("Processing chunk");
buf.reverse();
};
let output = Cursor::new(vec![]);
let mut writer = AsyncMapWriter::with_capacity(output, transformer, 10);
block_on(async {
let large_chunk = b"abcdefghijklmno"; writer.write_all(large_chunk).await.unwrap();
for &byte in b"0123456789" {
writer.write_all(&[byte]).await.unwrap();
}
writer.flush().await.unwrap();
let result = writer.into_inner().into_inner();
let expected = b"jihgfedcba43210onmlk98765";
assert_eq!(result, expected, "Output should match transformed chunks");
});
}