use std::string::{FromUtf8Error, String};
use rsaeb::error::{
AllocationError, ParseError, RunError, RuntimeInputError, TraceSnapshotRunError,
};
use rsaeb::limits::DEFAULT_PARSE_LIMITS;
use rsaeb::{Program, ProgramSource};
pub enum TestFailure {
Message(String),
Parse(ParseError),
Input(RuntimeInputError),
Run(RunError),
TraceSnapshot(String),
Utf8(FromUtf8Error),
Allocation(AllocationError),
}
impl TestFailure {
pub fn message(message: impl Into<String>) -> Self {
Self::Message(message.into())
}
}
impl core::fmt::Debug for TestFailure {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Message(message) => formatter.debug_tuple("Message").field(message).finish(),
Self::Parse(error) => formatter.debug_tuple("Parse").field(error).finish(),
Self::Input(error) => formatter.debug_tuple("Input").field(error).finish(),
Self::Run(error) => formatter.debug_tuple("Run").field(error).finish(),
Self::TraceSnapshot(error) => {
formatter.debug_tuple("TraceSnapshot").field(error).finish()
}
Self::Utf8(error) => formatter.debug_tuple("Utf8").field(error).finish(),
Self::Allocation(error) => formatter.debug_tuple("Allocation").field(error).finish(),
}
}
}
impl From<ParseError> for TestFailure {
fn from(value: ParseError) -> Self {
Self::Parse(value)
}
}
impl From<RuntimeInputError> for TestFailure {
fn from(value: RuntimeInputError) -> Self {
Self::Input(value)
}
}
impl From<RunError> for TestFailure {
fn from(value: RunError) -> Self {
Self::Run(value)
}
}
impl<E> From<TraceSnapshotRunError<E>> for TestFailure
where
E: core::fmt::Debug,
{
fn from(value: TraceSnapshotRunError<E>) -> Self {
Self::TraceSnapshot(std::format!("{value:?}"))
}
}
impl From<FromUtf8Error> for TestFailure {
fn from(value: FromUtf8Error) -> Self {
Self::Utf8(value)
}
}
impl From<AllocationError> for TestFailure {
fn from(value: AllocationError) -> Self {
Self::Allocation(value)
}
}
pub type TestResult = Result<(), TestFailure>;
pub fn parse_program(source: &str) -> Result<Program, ParseError> {
Program::parse(ProgramSource::from_text(source), DEFAULT_PARSE_LIMITS)
}
pub fn ensure_matches(condition: bool, message: &'static str) -> TestResult {
if condition {
Ok(())
} else {
Err(TestFailure::message(message))
}
}
macro_rules! ensure_eq {
($actual:expr, $expected:expr $(,)?) => {{
match (&$actual, &$expected) {
(actual, expected) => {
if *actual == *expected {
Ok(())
} else {
Err($crate::support::TestFailure::message(::std::format!(
"values differed\nactual: {actual:?}\nexpected: {expected:?}",
)))
}
}
}
}};
}
pub(crate) use ensure_eq;