use crate::succinct::Errorlike;
use crate::transcoder::{transcode, TranscodeError};
use std::convert::Infallible;
use std::error::Error;
use std::io;
use std::io::{Cursor, ErrorKind};
#[test]
fn transcode_error_conversion() {
let error = TranscodeError::<()>::from(io::Error::new(ErrorKind::AddrInUse, "test"));
assert!(error.into_io_error().is_some());
let error = TranscodeError::<()>::Io(io::Error::new(ErrorKind::AddrInUse, "test"));
assert_eq!(None, error.into_conversion_error());
let error = TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
};
assert_eq!(
(10, Errorlike("test")),
error.into_conversion_error().unwrap()
);
let error = TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
};
assert!(error.into_io_error().is_none());
}
#[test]
fn transcode_error_into_dynamic_for_conversion_error() {
let error = TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
};
let boxed = error.into_dynamic();
assert!(boxed.into_conversion_error().is_some());
}
#[test]
fn transcode_error_into_dynamic_for_io_error() {
let error =
TranscodeError::<Errorlike<String>>::Io(io::Error::new(ErrorKind::AddrInUse, "test"));
let boxed = error.into_dynamic();
assert_eq!(ErrorKind::AddrInUse, boxed.into_io_error().unwrap().kind());
}
#[test]
fn transcode_error_implements_debug() {
let error = TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
};
let formatted = format!("{error:?}");
assert_eq!(
"Conversion { line_no: 10, error: Errorlike(\"test\") }",
formatted
);
let error = TranscodeError::<()>::Io(io::Error::new(ErrorKind::AddrInUse, "test"));
let formatted = format!("{error:?}");
assert!(formatted.contains("Io"));
}
#[test]
fn transcode_error_implements_display_for_conversion_error() {
let error = TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
};
let formatted = format!("{error}");
assert_eq!("conversion error on line 10: test", formatted);
}
#[test]
fn transcode_error_implements_display_for_io_error() {
let error =
TranscodeError::<String>::Io(io::Error::new(ErrorKind::AddrInUse, "address in use"));
let formatted = format!("{error}");
assert_eq!(
"I/O error: Custom { kind: AddrInUse, error: \"address in use\" }",
formatted
);
}
#[test]
fn transcode_error_implements_error() {
let _: Box<dyn Error> = Box::new(TranscodeError::Conversion {
line_no: 10,
error: Errorlike("test"),
});
}
#[test]
fn transcode_no_errors() {
let processor = |line_no: u32, line: &str| -> Result<String, Infallible> {
Ok(format!("{line_no}-{line}"))
};
let content = concat!("first\n", "second\n", "third\n");
let mut r = Cursor::new(content.as_bytes());
let mut w = Cursor::new(Vec::new());
let result = transcode(&mut r, &mut w, processor);
assert!(result.is_ok());
let output = String::from_utf8(w.into_inner()).unwrap();
let expected = concat!("1-first\n", "2-second\n", "3-third\n");
assert_eq!(expected, output);
}
#[test]
fn transcode_with_processor_error() {
let processor = |line_no: u32, line: &str| -> Result<String, &str> {
match line_no {
1 => Ok(format!("{line_no}-{line}")),
_ => Err("could not process"),
}
};
let content = concat!("first\n", "second\n", "third\n");
let mut r = Cursor::new(content.as_bytes());
let mut w = Cursor::new(Vec::new());
let result = transcode(&mut r, &mut w, processor);
assert!(result.is_err());
assert!(matches!(
result,
Err(TranscodeError::Conversion {
line_no: 2,
error: "could not process"
})
));
}
#[test]
fn transcode_with_io_error() {
let processor = |line_no: u32, line: &str| -> Result<String, Infallible> {
Ok(format!("{line_no}-{line}"))
};
let content = concat!("first\n", "second\n", "third\n");
let mut r = Cursor::new(content.as_bytes());
let mut w = Cursor::new([0; 0]); let result = transcode(&mut r, &mut w, processor);
assert!(result.is_err());
let io_error = result.err().unwrap().into_io_error().unwrap();
assert_eq!(ErrorKind::WriteZero, io_error.kind());
}