use crate::prelude::*;
use crate::testing::runner::*;
use crate::testing::utils::*;
#[derive(Debug, Clone, PartialEq, Eq, Component)]
#[component(storage = "SparseSet")]
pub enum TestOutcome {
Pass,
Skip(TestSkip),
Fail(TestFail),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TestSkip {
NoRun,
CompileFail,
Ignore(Option<&'static str>),
FailedFilter,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TestFail {
Err { message: String },
ExpectedPanic { message: Option<String> },
Panic {
payload: Option<String>,
location: Option<FileSpan>,
},
Timeout { elapsed: Duration },
}
impl TestFail {
pub fn start(&self, test: &Test) -> LineCol {
match self {
TestFail::Panic { location, .. }
if let Some(location) = location =>
{
location.start()
}
_ => test.start(),
}
}
pub fn end(&self, test: &Test) -> LineCol {
match self {
TestFail::Panic { location, .. }
if let Some(location) = location =>
{
location.end()
}
_ => test.end(),
}
}
pub fn is_timeout(&self) -> bool {
matches!(self, TestFail::Timeout { .. })
}
pub fn is_panic(&self) -> bool { matches!(self, TestFail::Panic { .. }) }
pub fn is_error(&self) -> bool { matches!(self, TestFail::Err { .. }) }
pub fn is_expected_panic(&self) -> bool {
matches!(self, TestFail::ExpectedPanic { .. })
}
}
impl Into<TestOutcome> for TestFail {
fn into(self) -> TestOutcome { TestOutcome::Fail(self) }
}
impl Into<TestOutcome> for TestSkip {
fn into(self) -> TestOutcome { TestOutcome::Skip(self) }
}
impl TestOutcome {
pub fn is_pass(&self) -> bool { self == &TestOutcome::Pass }
pub fn is_fail(&self) -> bool { matches!(self, TestOutcome::Fail(_)) }
pub fn is_skip(&self) -> bool { matches!(self, TestOutcome::Skip(_)) }
pub fn as_fail(&self) -> Option<&TestFail> {
if let TestOutcome::Fail(fail) = self {
Some(fail)
} else {
None
}
}
pub fn from_panic_result(
result: PanicResult,
should_panic: test::ShouldPanic,
) -> Self {
match (result, should_panic) {
(PanicResult::Ok, test::ShouldPanic::No) => {
TestOutcome::Pass
}
(PanicResult::Ok, test::ShouldPanic::Yes) => {
TestOutcome::Fail(TestFail::ExpectedPanic { message: None })
}
(PanicResult::Ok, test::ShouldPanic::YesWithMessage(message)) => {
TestOutcome::Fail(TestFail::ExpectedPanic {
message: Some(message.to_string()),
})
}
(PanicResult::Err(message), _) => {
TestOutcome::Fail(TestFail::Err { message })
}
(
PanicResult::Panic { .. },
test::ShouldPanic::Yes | test::ShouldPanic::YesWithMessage(_),
) => {
TestOutcome::Pass
}
(
PanicResult::Panic { location, payload },
test::ShouldPanic::No,
) => {
TestOutcome::Fail(TestFail::Panic { location, payload })
}
}
}
}