use std::io::{Cursor, Write};
use std::iter;
use partial_io::{PartialOp, PartialWrite};
use crate::stream::decode_all;
use crate::stream::write::{Decoder, Encoder};
#[test]
fn test_cycle() {
let input = b"Abcdefghabcdefgh";
let buffer = Cursor::new(Vec::new());
let mut encoder = Encoder::new(buffer, 1).unwrap();
encoder.write_all(input).unwrap();
let encoded = encoder.finish().unwrap().into_inner();
let buffer = Cursor::new(Vec::new());
let mut decoder = Decoder::new(buffer).unwrap();
decoder.write_all(&encoded).unwrap();
decoder.flush().unwrap();
let decoded = decoder.into_inner().into_inner();
assert_eq!(input, &decoded[..]);
}
#[test]
fn test_partial_write_flush() {
let input = vec![b'b'; 128 * 1024];
let mut z = setup_partial_write(&input);
z.flush().unwrap();
let buf = z.finish().unwrap().into_inner();
assert_eq!(&decode_all(&buf[..]).unwrap(), &input);
}
#[test]
fn test_partial_write_finish() {
let input = vec![b'b'; 128 * 1024];
let z = setup_partial_write(&input);
let buf = z.finish().unwrap().into_inner();
assert_eq!(&decode_all(&buf[..]).unwrap(), &input);
}
fn setup_partial_write(
input_data: &[u8],
) -> Encoder<'_, PartialWrite<Vec<u8>>> {
let buf =
PartialWrite::new(Vec::new(), iter::repeat(PartialOp::Limited(1)));
let mut z = Encoder::new(buf, 1).unwrap();
z.write_all(input_data).unwrap();
{
let inner = &mut z.writer;
assert_ne!(inner.offset(), inner.buffer().len());
}
z
}
#[test]
fn test_auto_wrappers_panicking_writer() {
struct Panicking;
impl Write for Panicking {
fn write(&mut self, _: &[u8]) -> std::io::Result<usize> {
panic!("this writer panics");
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
let input = vec![b'b'; 128 * 1024];
let encoded = crate::encode_all(&input[..], 1).unwrap();
std::panic::catch_unwind(|| {
let mut decoder = Decoder::new(Panicking).unwrap().auto_flush();
decoder.write_all(&encoded)
})
.unwrap_err();
std::panic::catch_unwind(|| {
let mut encoder = Encoder::new(Panicking, 1).unwrap().auto_finish();
encoder.write_all(&input).and_then(|()| encoder.flush())
})
.unwrap_err();
}
#[test]
fn test_decoder_finish_incomplete_frame() {
use std::io::ErrorKind::UnexpectedEof;
let input = b"Abcdefghabcdefgh";
let frame = crate::encode_all(&input[..], 1).unwrap();
let encoded = [&frame[..], &frame[..]].concat();
for cut in 0..=encoded.len() {
let complete = cut != 0 && cut % frame.len() == 0;
let mut decoder = Decoder::new(Vec::new()).unwrap();
decoder.write_all(&encoded[..cut]).unwrap();
match decoder.finish() {
Ok(decoded) => {
assert!(complete, "cut at {} accepted", cut);
assert_eq!(decoded, input.repeat(cut / frame.len()));
}
Err(e) => {
assert!(!complete, "cut at {} rejected: {}", cut, e);
assert_eq!(e.kind(), UnexpectedEof);
}
}
}
}
#[test]
fn test_decoder_do_finish_resume() {
let input = vec![b'b'; 128 * 1024];
let encoded = crate::encode_all(&input[..], 1).unwrap();
let (head, tail) = encoded.split_at(encoded.len() - 1);
let mut flushed = Decoder::new(Vec::new()).unwrap();
flushed.write_all(head).unwrap();
flushed.flush().unwrap();
let mut decoder = Decoder::new(Vec::new()).unwrap();
decoder.write_all(head).unwrap();
decoder.do_finish().unwrap_err();
assert_eq!(decoder.get_ref(), flushed.get_ref());
decoder.write_all(tail).unwrap();
assert_eq!(decoder.write(&[]).unwrap(), 0);
decoder.do_finish().unwrap();
decoder.write_all(&encoded).unwrap_err();
assert_eq!(decoder.finish().unwrap(), input);
}