1use std::sync::Arc;
2
3use miette::Diagnostic;
4use miette::NamedSource;
5use thiserror::Error;
6
7use super::TestVerbCreator;
8use crate::error::TestErrorCase;
9
10pub struct TestCase<H> {
11 pub(crate) creators: Vec<Box<dyn TestVerbCreator<H>>>,
12 pub(crate) source_code: NamedSource<Arc<str>>,
13}
14
15impl<H> std::fmt::Debug for TestCase<H> {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 f.debug_struct("TestCase").finish_non_exhaustive()
18 }
19}
20
21#[derive(Error, Diagnostic, Debug)]
22#[error("Testcase did not run successfully")]
23pub struct TestCaseError {
24 #[diagnostic_source]
25 pub(crate) error: TestErrorCase,
26
27 #[source_code]
28 pub(crate) source_code: miette::NamedSource<Arc<str>>,
29}
30
31impl<H: 'static> TestCase<H> {
32 pub fn new(source_code: miette::NamedSource<Arc<str>>) -> Self {
33 TestCase {
34 creators: vec![],
35 source_code,
36 }
37 }
38
39 pub fn run(&self, harness: &mut H) -> Result<(), TestCaseError> {
40 self.creators
41 .iter()
42 .flat_map(|c| {
43 c.get_test_verbs()
44 .map(|verb| verb.run(harness))
45 .collect::<Vec<_>>()
46 })
47 .collect::<Result<(), _>>()
48 .map_err(|error| TestCaseError {
49 error,
50 source_code: self.source_code.clone(),
51 })
52 }
53}