test_dsl/
test_case.rs

1//! Individual testcases
2
3use miette::Diagnostic;
4use thiserror::Error;
5
6use crate::TestCaseInput;
7use crate::VerbInstance;
8use crate::error::TestError;
9
10/// A singular test case
11pub 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")]
24/// An error occured while running a test
25pub 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    /// Get the path of the source of this test case.
42    ///
43    /// Returns `None` if the test case source came from in-memory.
44    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    /// Run the given test and report on its success
52    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}