1use miette::Diagnostic;
4use thiserror::Error;
5
6use crate::TestCaseInput;
7use crate::VerbInstance;
8use crate::error::TestError;
9
10pub struct TestCase<H> {
12 pub(crate) cases: Vec<VerbInstance<H>>,
13 pub(crate) source_code: TestCaseInput,
14}
15
16impl<H> std::fmt::Debug for TestCase<H> {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 f.debug_struct("TestCase").finish_non_exhaustive()
19 }
20}
21
22#[derive(Error, Diagnostic, Debug)]
23#[error("Testcase did not run successfully")]
24pub struct TestCaseError {
26 #[diagnostic_source]
27 pub(crate) error: TestError,
28
29 #[source_code]
30 pub(crate) source_code: TestCaseInput,
31}
32
33impl<H: 'static> TestCase<H> {
34 pub(crate) fn new(source_code: TestCaseInput) -> Self {
35 TestCase {
36 cases: vec![],
37 source_code,
38 }
39 }
40
41 pub fn path(&self) -> Option<&str> {
45 match self.source_code {
46 TestCaseInput::InMemory(_) => None,
47 TestCaseInput::FromFile { ref filepath, .. } => Some(&**filepath),
48 }
49 }
50
51 pub fn run(&self, harness: &mut H) -> Result<(), TestCaseError> {
53 self.cases
54 .iter()
55 .try_for_each(|verb| verb.run(harness))
56 .map_err(|error| TestCaseError {
57 error,
58 source_code: self.source_code.clone(),
59 })
60 }
61}