// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::{ArtifactMetadata, MaybeUnknown, Outcome, SuiteResult, TestCaseResult, TestRunResult};
use std::{
    collections::{HashMap, HashSet},
    ops::Deref,
    path::{Path, PathBuf},
};
use test_list::TestTag;

enum MatchOption<T> {
    AnyOrNone,
    None,
    Any,
    Specified(T),
}

macro_rules! assert_match_option {
    ($expected:expr, $actual:expr, $field:expr) => {
        match $expected {
            MatchOption::AnyOrNone => (),
            MatchOption::None => {
                assert_eq!(None, $actual, "Expected {} to be None but was {:?}", $field, $actual)
            }
            MatchOption::Any => {
                assert!($actual.is_some(), "Expected {} to contain a value but was None", $field)
            }
            MatchOption::Specified(val) => assert_eq!(
                Some(val),
                $actual,
                "Expected {} to be {:?} but was {:?}",
                $field,
                Some(val),
                $actual
            ),
        }
    };
}

/// Container that identifies the entity that is being verified in an assertion.
#[derive(Clone, Copy)]
enum EntityContext<'a> {
    Run,
    Suite(&'a ExpectedSuite),
    Case(&'a ExpectedSuite, &'a ExpectedTestCase),
}

/// Container that identifies the artifact that is being verified in an assertion.
#[derive(Clone, Copy)]
struct ArtifactContext<'a, 'b> {
    entity: &'a EntityContext<'b>,
    metadata: &'a ArtifactMetadata,
}

impl std::fmt::Display for EntityContext<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Run => write!(f, "TEST RUN"),
            Self::Suite(suite) => write!(f, "SUITE {}", suite.name),
            Self::Case(suite, case) => write!(f, "SUITE {}: CASE {}", suite.name, case.name),
        }
    }
}

impl std::fmt::Display for ArtifactContext<'_, '_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Entity: {}, Metadata: {:?}", self.entity, self.metadata)
    }
}

/// A mapping from artifact metadata to assertions made on the artifact.
type ArtifactMetadataToAssertionMap = HashMap<ArtifactMetadata, ExpectedArtifact>;

/// Assert that the run results contained in `actual_run` and the directory specified by `root`
/// contain the results and artifacts in `expected_run`.
pub fn assert_run_result(root: &Path, expected_run: &ExpectedTestRun) {
    let context = EntityContext::Run;
    let actual_run = TestRunResult::from_dir(root).expect("Parse output directory");
    let TestRunResult { common, suites } = actual_run;
    assert_match_option!(
        expected_run.duration_milliseconds,
        common.deref().duration_milliseconds,
        format!("Run duration for {}", context)
    );
    assert_match_option!(
        expected_run.start_time,
        common.deref().start_time,
        format!("Start time for {}", context)
    );
    assert_eq!(common.deref().outcome, expected_run.outcome, "Outcome for {}", context);
    assert_artifacts(
        root,
        &common.deref().artifact_dir.root,
        &common.deref().artifact_dir.artifacts,
        &expected_run.artifacts,
        EntityContext::Run,
    );
    assert_suite_results(root, &suites, &expected_run.suites);
}

/// Assert that the suite results contained in `actual_suites` and the directory specified by `root`
/// contain the suites, results, artifacts, and test cases in `expected_suite`.
/// Note that this currently does not support duplicate suite names.
fn assert_suite_results(
    root: &Path,
    actual_suites: &Vec<SuiteResult<'_>>,
    expected_suites: &Vec<ExpectedSuite>,
) {
    assert_eq!(actual_suites.len(), expected_suites.len());
    let mut expected_suites_map = HashMap::new();
    for suite in expected_suites.iter() {
        expected_suites_map.insert(suite.name.clone(), suite);
    }
    assert_eq!(
        actual_suites.len(),
        expected_suites_map.len(),
        "Run contains multiple suites with the same name. \
        This is currently unsupported by assert_suite_results"
    );
    for suite in actual_suites.iter() {
        assert_suite_result(
            root,
            suite,
            expected_suites_map
                .get(&suite.common.deref().name)
                .expect("No matching expected suite"),
        );
    }
}

/// Assert that the suite results contained in `actual_suite` and the directory specified by `root`
/// contain the results, artifacts, and test cases in `expected_suite`.
pub fn assert_suite_result(
    root: &Path,
    actual_suite: &SuiteResult<'_>,
    expected_suite: &ExpectedSuite,
) {
    let context = EntityContext::Suite(expected_suite);
    let &SuiteResult { common, cases, tags, summary_file_hint: _ } = &actual_suite;
    assert_eq!(common.deref().outcome, expected_suite.outcome, "Outcome for {}", context);
    assert_eq!(common.deref().name, expected_suite.name, "Name for {}", context);
    assert_match_option!(
        expected_suite.duration_milliseconds,
        common.deref().duration_milliseconds,
        format!("Duration for {}", context)
    );
    assert_match_option!(
        expected_suite.start_time,
        common.deref().start_time,
        format!("Start time for {}", context)
    );

    let mut tags: Vec<TestTag> = tags.clone().into_owned();
    tags.sort();

    let mut expected_tags = expected_suite.tags.clone();
    expected_tags.sort();

    assert_eq!(tags, expected_tags);

    assert_artifacts(
        root,
        &common.deref().artifact_dir.root,
        &common.deref().artifact_dir.artifacts,
        &expected_suite.artifacts,
        context,
    );

    assert_eq!(cases.len(), expected_suite.cases.len());
    for case in cases.iter() {
        let expected_case = expected_suite.cases.get(&case.common.deref().name);
        assert!(
            expected_case.is_some(),
            "Found unexpected case {} in {}",
            case.common.deref().name,
            context
        );
        assert_case_result(root, case, expected_case.unwrap(), expected_suite);
    }
}

fn assert_case_result(
    root: &Path,
    actual_case: &TestCaseResult<'_>,
    expected_case: &ExpectedTestCase,
    parent_suite: &ExpectedSuite,
) {
    let context = EntityContext::Case(parent_suite, expected_case);
    assert_eq!(actual_case.common.deref().name, expected_case.name, "Name for {}", context);
    assert_eq!(
        actual_case.common.deref().outcome,
        expected_case.outcome,
        "Outcome for {}",
        context
    );
    assert_match_option!(
        expected_case.duration_milliseconds,
        actual_case.common.deref().duration_milliseconds,
        format!("Duration for {}", context)
    );
    assert_match_option!(
        expected_case.start_time,
        actual_case.common.deref().start_time,
        format!("Start time for {}", context)
    );
    assert_artifacts(
        root,
        &actual_case.common.deref().artifact_dir.root,
        &actual_case.common.deref().artifact_dir.artifacts,
        &expected_case.artifacts,
        context,
    );
}

fn assert_artifacts(
    root: &Path,
    artifact_dir: &Path,
    actual_artifacts: &HashMap<PathBuf, ArtifactMetadata>,
    expected_artifacts: &ArtifactMetadataToAssertionMap,
    entity_context: EntityContext<'_>,
) {
    // TODO(fxbug.dev/100463): add options so that the test author can explicitly declare whether
    // artifacts should be an exact match, should contain (and may contain more) artifacts,
    // or any number of artifacts is accesptable.
    // This skips artifact assertion for the typical case where verifying artifacts isn't
    // necessary and allows the author to avoid listing out every artifact that is generated
    // by the test.
    if expected_artifacts.is_empty() {
        return;
    }

    let actual_artifacts_by_metadata: HashMap<ArtifactMetadata, PathBuf> =
        actual_artifacts.iter().map(|(key, value)| (value.clone(), key.clone())).collect();
    // For now, artifact metadata should be unique for each artifact.
    assert_eq!(
        actual_artifacts_by_metadata.len(),
        actual_artifacts.len(),
        "Artifacts for {} do not have unique metadata. Actual artifacts: {:?}",
        entity_context,
        actual_artifacts
    );

    let expected_metadata: HashSet<_> = expected_artifacts.keys().collect();
    let actual_metadata: HashSet<_> = actual_artifacts_by_metadata.keys().collect();

    assert_eq!(
        expected_metadata, actual_metadata,
        "Artifacts for {} do not have matching metadata.",
        entity_context,
    );

    for (expected_metadata, expected_artifact) in expected_artifacts.iter() {
        let actual_filepath =
            artifact_dir.join(actual_artifacts_by_metadata.get(expected_metadata).unwrap());
        match expected_artifact {
            ExpectedArtifact::File { name, assertion_fn } => {
                assert_file(
                    &root.join(&actual_filepath),
                    name,
                    assertion_fn,
                    ArtifactContext { entity: &entity_context, metadata: expected_metadata },
                );
            }
            ExpectedArtifact::Directory { files, name } => {
                match name {
                    None => (),
                    Some(name) => assert_eq!(
                        name.as_str(),
                        actual_filepath.file_name().unwrap().to_str().unwrap(),
                        "Expected filename {} for artifact matching {:?} but got {}",
                        name,
                        expected_metadata,
                        actual_filepath.file_name().unwrap().to_str().unwrap()
                    ),
                }
                let actual_entries: HashSet<_> = std::fs::read_dir(root.join(&actual_filepath))
                    .expect("Failed to read directory artifact path")
                    .map(|entry| match entry {
                        Ok(dir_entry) if dir_entry.file_type().unwrap().is_file() => {
                            dir_entry.file_name().to_str().unwrap().to_string()
                        }
                        // TODO(fxbugdev/85528) - support directory artifacts with subdirectories
                        Ok(_) => panic!("Directory artifact with subdirectories unsupported"),
                        Err(e) => panic!("Error reading directory artifact: {:?}", e),
                    })
                    .collect();
                let expected_entries: HashSet<_> =
                    files.iter().map(|(name, _)| name.to_string()).collect();
                assert_eq!(
                    actual_entries, expected_entries,
                    "Expected files {:?} in directory artifact, got {:?}",
                    &expected_entries, &actual_entries
                );
                for (name, assertion) in files {
                    assert_file(
                        &root.join(&actual_filepath).join(name),
                        &None,
                        assertion,
                        ArtifactContext { entity: &entity_context, metadata: expected_metadata },
                    );
                }
            }
        }
    }
}

fn assert_file(
    file_path: &Path,
    name: &Option<String>,
    assertion_fn: &Box<dyn Fn(&str)>,
    artifact_context: ArtifactContext<'_, '_>,
) {
    match name {
        None => (),
        Some(name) => assert_eq!(
            name.as_str(),
            file_path.file_name().unwrap().to_str().unwrap(),
            "Got incorrect filename while checking file for artifact {}",
            artifact_context
        ),
    }
    let actual_contents = std::fs::read_to_string(&file_path);
    (assertion_fn)(&actual_contents.unwrap());
}

/// The expected contents of an artifact.
enum ExpectedArtifact {
    /// An artifact contained in a single file, such as stdout.
    File {
        /// If given, the expected name of the file.
        name: Option<String>,
        /// Assertion run against the contents of the file.
        assertion_fn: Box<dyn Fn(&str)>,
    },
    /// An artifact consisting of files in a directory.
    Directory {
        /// List of expected files, as (name, assertion) pairs. The name
        /// is the expected name of the file, and the assertion fn is run
        /// against the contents of the file.
        files: Vec<(String, Box<dyn Fn(&str)>)>,
        /// If given, the expected name of the directory.
        name: Option<String>,
    },
}

/// Contents of an expected directory artifact.
pub struct ExpectedDirectory {
    files: Vec<(String, Box<dyn Fn(&str)>)>,
}

impl ExpectedDirectory {
    /// Create a new empty expected directory.
    pub fn new() -> Self {
        Self { files: vec![] }
    }

    /// Add a file with expected |contents|.
    pub fn with_file(self, name: impl AsRef<str>, contents: impl AsRef<str>) -> Self {
        let owned_expected = contents.as_ref().to_string();
        let owned_name = name.as_ref().to_string();
        self.with_matching_file(name, move |actual| {
            assert_eq!(
                &owned_expected, actual,
                "Mismatch in contents of file {}. Expected: '{}', actual:'{}'",
                owned_name, &owned_expected, actual
            )
        })
    }

    pub fn with_matching_file(
        mut self,
        name: impl AsRef<str>,
        matcher: impl 'static + Fn(&str),
    ) -> Self {
        self.files.push((name.as_ref().to_string(), Box::new(matcher)));
        self
    }
}

/// A version of a test run result that contains all output in memory. This should only be used
/// for making assertions in a test.
pub struct ExpectedTestRun {
    artifacts: ArtifactMetadataToAssertionMap,
    outcome: MaybeUnknown<Outcome>,
    start_time: MatchOption<u64>,
    duration_milliseconds: MatchOption<u64>,
    suites: Vec<ExpectedSuite>,
}

/// A version of a suite run result that contains all output in memory. This should only be used
/// for making assertions in a test.
pub struct ExpectedSuite {
    artifacts: ArtifactMetadataToAssertionMap,
    name: String,
    outcome: MaybeUnknown<Outcome>,
    cases: HashMap<String, ExpectedTestCase>,
    start_time: MatchOption<u64>,
    duration_milliseconds: MatchOption<u64>,
    tags: Vec<TestTag>,
}

/// A version of a test case result that contains all output in memory. This should only be used
/// for making assertions in a test.
pub struct ExpectedTestCase {
    artifacts: ArtifactMetadataToAssertionMap,
    name: String,
    outcome: MaybeUnknown<Outcome>,
    start_time: MatchOption<u64>,
    duration_milliseconds: MatchOption<u64>,
}

macro_rules! common_impl {
    {} => {
        /// Add an artifact matching the exact contents. Artifacts are checked by finding
        /// an entry matching the given metadata, then checking the contents of the corresponding
        /// file. If |name| is provided, the name of the file is verified. Artifacts are keyed by
        /// metadata rather than by name as the names of files are not guaranteed to be stable.
        pub fn with_artifact<S, T, U>(
            self, metadata: U, name: Option<S>, contents: T
        ) -> Self
        where
            S: AsRef<str>,
            T: AsRef<str>,
            U: Into<ArtifactMetadata>
        {
            let owned_expected = contents.as_ref().to_string();
            let metadata = metadata.into();
            let metadata_clone = metadata.clone();
            self.with_matching_artifact(metadata, name, move |actual| {
                assert_eq!(
                    &owned_expected, actual,
                    "Mismatch in artifact with metadata {:?}. Expected: '{}', actual:'{}'",
                    metadata_clone, &owned_expected, actual
                )
            })
        }

        /// Add an artifact matching the exact contents. Artifacts are checked by finding
        /// an entry matching the given metadata, then running |matcher| against the contents of
        /// the file. If |name| is provided, the name of the file is verified. Artifacts are keyed
        /// by metadata rather than by name as the names of files are not guaranteed to be stable.
        pub fn with_matching_artifact<S, F, U>(
            mut self,
            metadata: U,
            name: Option<S>,
            matcher: F,
        ) -> Self
        where
            S: AsRef<str>,
            F: 'static + Fn(&str),
            U: Into<ArtifactMetadata>
        {
            self.artifacts.insert(
                metadata.into(),
                ExpectedArtifact::File {
                    name: name.map(|s| s.as_ref().to_string()),
                    assertion_fn: Box::new(matcher),
                }
            );
            self
        }

        /// Add a directory based artifact containing the entries described in |directory|.
        pub fn with_directory_artifact<S, U>(
            mut self,
            metadata: U,
            name: Option<S>,
            directory: ExpectedDirectory,
        ) -> Self
        where
            S: AsRef<str>,
            U: Into<ArtifactMetadata>
        {
            self.artifacts.insert(
                metadata.into(),
                ExpectedArtifact::Directory {
                    name: name.map(|s| s.as_ref().to_string()),
                    files: directory.files,
                }
            );
            self
        }

        /// Verify an exact start time.
        pub fn with_start_time(mut self, millis: u64) -> Self {
            self.start_time = MatchOption::Specified(millis);
            self
        }

        /// Verify an exact run duration.
        pub fn with_run_duration(mut self, millis: u64) -> Self {
            self.duration_milliseconds = MatchOption::Specified(millis);
            self
        }

        /// Verify that a start time is present.
        pub fn with_any_start_time(mut self) -> Self {
            self.start_time = MatchOption::Any;
            self
        }

        /// Verify that a run duration is present.
        pub fn with_any_run_duration(mut self) -> Self {
            self.duration_milliseconds = MatchOption::Any;
            self
        }

        /// Verify that no start time is present.
        pub fn with_no_start_time(mut self) -> Self {
            self.start_time = MatchOption::None;
            self
        }

        /// Verify that no run duration is present.
        pub fn with_no_run_duration(mut self) -> Self {
            self.duration_milliseconds = MatchOption::None;
            self
        }
    };
}

impl ExpectedTestRun {
    /// Create a new `ExpectedTestRun` with the given `outcome`.
    pub fn new(outcome: Outcome) -> Self {
        Self {
            artifacts: ArtifactMetadataToAssertionMap::new(),
            outcome: outcome.into(),
            start_time: MatchOption::AnyOrNone,
            duration_milliseconds: MatchOption::AnyOrNone,
            suites: vec![],
        }
    }

    pub fn with_suite(mut self, suite: ExpectedSuite) -> Self {
        self.suites.push(suite);
        self
    }

    common_impl! {}
}

impl ExpectedSuite {
    /// Create a new `ExpectedTestRun` with the given `name` and `outcome`.
    pub fn new<S: AsRef<str>>(name: S, outcome: Outcome) -> Self {
        Self {
            artifacts: ArtifactMetadataToAssertionMap::new(),
            name: name.as_ref().to_string(),
            outcome: outcome.into(),
            cases: HashMap::new(),
            start_time: MatchOption::AnyOrNone,
            duration_milliseconds: MatchOption::AnyOrNone,
            tags: vec![],
        }
    }

    /// Add a test case to the suite.
    pub fn with_case(mut self, case: ExpectedTestCase) -> Self {
        self.cases.insert(case.name.clone(), case);
        self
    }

    /// Add a tag to the suite.
    pub fn with_tag(mut self, tag: TestTag) -> Self {
        self.tags.push(tag);
        self
    }

    common_impl! {}
}

impl ExpectedTestCase {
    /// Create a new `ExpectedTestCase` with the given `name` and `outcome`.
    pub fn new<S: AsRef<str>>(name: S, outcome: Outcome) -> Self {
        Self {
            artifacts: ArtifactMetadataToAssertionMap::new(),
            name: name.as_ref().to_string(),
            outcome: outcome.into(),
            start_time: MatchOption::AnyOrNone,
            duration_milliseconds: MatchOption::AnyOrNone,
        }
    }

    common_impl! {}
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::{ArtifactType, CommonResult, OutputDirectoryBuilder, SchemaVersion, RUN_NAME};
    use std::borrow::Cow;
    use std::io::Write;

    fn test_with_directory<F: Fn(OutputDirectoryBuilder)>(_test_name: &str, test_fn: F) {
        for version in SchemaVersion::all_variants() {
            let dir = tempfile::TempDir::new().unwrap();
            let directory_builder =
                OutputDirectoryBuilder::new(dir.path(), version).expect("Create directory builder");
            test_fn(directory_builder);
        }
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_check_outcome_only(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Passed.into(),
                start_time: Some(64),
                duration_milliseconds: Some(128),
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_any_start_time().with_any_run_duration(),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_check_exact_timing(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Passed.into(),
                start_time: Some(64),
                duration_milliseconds: Some(128),
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_start_time(64).with_run_duration(128),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_check_timing_unspecified(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_no_start_time().with_no_run_duration(),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_single_artifact_unspecified_name(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Syslog, "b.txt").expect("create artifact");
        write!(artifact, "hello").expect("write to artifact");
        drop(artifact);

        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Syslog,
                Option::<&str>::None,
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_single_artifact_specified_name(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Syslog, "b.txt").expect("create artifact");
        write!(artifact, "hello").expect("write to artifact");
        drop(artifact);

        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Syslog,
                "b.txt".into(),
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Outcome for TEST RUN")]
    fn assert_run_outcome_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Failed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(output_dir.path(), &ExpectedTestRun::new(Outcome::Passed));
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Start time for TEST RUN")]
    fn assert_run_start_time_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Failed.into(),
                start_time: Some(64),
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_start_time(23),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Run duration for TEST RUN")]
    fn assert_run_duration_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Failed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_run_duration(23),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic]
    fn assert_run_artifact_mismatch(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Syslog, "missing").expect("create artifact");
        write!(artifact, "hello").expect("write to artifact");
        drop(artifact);

        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Failed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Failed).with_artifact(
                ArtifactType::Stderr,
                "stderr.txt".into(),
                "",
            ),
        );
    }

    fn passing_run_with_single_suite<'a>(
        output_dir: &OutputDirectoryBuilder,
        suite: SuiteResult<'a>,
    ) -> TestRunResult<'a> {
        TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Passed.into(),
                start_time: Some(64),
                duration_milliseconds: Some(128),
            }),
            suites: vec![suite],
        }
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_with_suite(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: Some(64),
                    duration_milliseconds: Some(128),
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(
                    ExpectedSuite::new("suite", Outcome::Passed)
                        .with_any_start_time()
                        .with_any_run_duration(),
                ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_with_suite_exact_times(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: Some(64),
                    duration_milliseconds: Some(128),
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(
                    ExpectedSuite::new("suite", Outcome::Passed)
                        .with_start_time(64)
                        .with_run_duration(128),
                ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_with_suite_no_times(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(
                    ExpectedSuite::new("suite", Outcome::Passed)
                        .with_no_start_time()
                        .with_no_run_duration(),
                ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_suite_with_artifact(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir =
            output_dir.new_artifact_dir("artifacts-suite").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Syslog, "b.txt").expect("create artifact");
        write!(artifact, "hello").expect("write to artifact");
        drop(artifact);

        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir,
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(ExpectedSuite::new("suite", Outcome::Passed).with_artifact(
                    ArtifactType::Syslog,
                    "b.txt".into(),
                    "hello",
                )),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_suite_with_case(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![TestCaseResult {
                    common: Cow::Owned(CommonResult {
                        name: "case".to_string(),
                        artifact_dir: output_dir
                            .new_artifact_dir("artifacts-case")
                            .expect("new artifact dir"),
                        outcome: Outcome::Passed.into(),
                        start_time: None,
                        duration_milliseconds: None,
                    }),
                }],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(
                    ExpectedSuite::new("suite", Outcome::Passed).with_case(
                        ExpectedTestCase::new("case", Outcome::Passed)
                            .with_no_run_duration()
                            .with_no_start_time(),
                    ),
                ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_run_result_suite_with_tags(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![
                    TestTag { key: "os".to_string(), value: "fuchsia".to_string() },
                    TestTag { key: "cpu".to_string(), value: "arm64".to_string() },
                ]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(
                    ExpectedSuite::new("suite", Outcome::Passed)
                        .with_tag(TestTag { key: "cpu".to_string(), value: "arm64".to_string() })
                        .with_tag(TestTag { key: "os".to_string(), value: "fuchsia".to_string() }),
                ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Outcome for SUITE suite")]
    fn assert_suite_outcome_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Failed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(ExpectedSuite::new("suite", Outcome::Passed)),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Start time for SUITE suite")]
    fn assert_suite_start_time_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: Some(128),
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(ExpectedSuite::new("suite", Outcome::Passed).with_any_start_time()),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Duration for SUITE suite")]
    fn assert_suite_duration_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: Some(128),
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(ExpectedSuite::new("suite", Outcome::Passed).with_run_duration(32)),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic]
    fn assert_suite_artifact_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Passed.into(),
                    start_time: None,
                    duration_milliseconds: Some(128),
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed)
                .with_any_start_time()
                .with_any_run_duration()
                .with_suite(ExpectedSuite::new("suite", Outcome::Passed).with_artifact(
                    ArtifactType::Stderr,
                    Option::<&str>::None,
                    "missing contents",
                )),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Found unexpected case")]
    fn assert_suite_case_mismatch(output_dir: OutputDirectoryBuilder) {
        let actual = passing_run_with_single_suite(
            &output_dir,
            SuiteResult {
                common: Cow::Owned(CommonResult {
                    name: "suite".to_string(),
                    artifact_dir: output_dir
                        .new_artifact_dir("artifacts-suite")
                        .expect("new artifact dir"),
                    outcome: Outcome::Failed.into(),
                    start_time: None,
                    duration_milliseconds: None,
                }),
                summary_file_hint: Cow::Owned("summary.json".into()),
                cases: vec![TestCaseResult {
                    common: Cow::Owned(CommonResult {
                        name: "case".to_string(),
                        artifact_dir: output_dir
                            .new_artifact_dir("artifacts-case")
                            .expect("new artifact dir"),
                        outcome: Outcome::Passed.into(),
                        start_time: None,
                        duration_milliseconds: None,
                    }),
                }],
                tags: Cow::Owned(vec![]),
            },
        );

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_any_start_time().with_suite(
                ExpectedSuite::new("suite", Outcome::Failed)
                    .with_case(ExpectedTestCase::new("wrong name", Outcome::Passed)),
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_empty(output_dir: OutputDirectoryBuilder) {
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir: output_dir.new_artifact_dir("artifacts").expect("new artifact dir"),
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(output_dir.path(), &ExpectedTestRun::new(Outcome::Passed));
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_exact_content(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("new artifact");
        write!(artifact, "hello").expect("write to artifact");
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Stderr,
                Option::<&str>::None,
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_exact_content_exact_name(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("new artifact");
        write!(artifact, "hello").expect("write to artifact");
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Stderr,
                Some("b.txt"),
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_matching_content(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("new artifact");
        write!(artifact, "hello").expect("write to artifact");
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_matching_artifact(
                ArtifactType::Stderr,
                Some("b.txt"),
                |content| assert_eq!(content, "hello"),
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_moniker_specified(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut artifact = artifact_dir
            .new_artifact(
                ArtifactMetadata {
                    artifact_type: ArtifactType::Syslog.into(),
                    component_moniker: Some("moniker".into()),
                },
                "b.txt",
            )
            .expect("new artifact");
        write!(artifact, "hello").expect("write to artifact");
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactMetadata {
                    artifact_type: ArtifactType::Syslog.into(),
                    component_moniker: Some("moniker".into()),
                },
                Some("b.txt"),
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_directory_artifact(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let dir_artifact =
            artifact_dir.new_directory_artifact(ArtifactType::Custom, "b").expect("new artifact");
        std::fs::write(dir_artifact.join("c.txt"), "hello c").unwrap();
        std::fs::write(dir_artifact.join("d.txt"), "hello d").unwrap();
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_directory_artifact(
                ArtifactType::Custom,
                Some("b"),
                ExpectedDirectory::new()
                    .with_file("c.txt", "hello c")
                    .with_matching_file("d.txt", |contents| assert_eq!(contents, "hello d")),
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Artifacts for TEST RUN")]
    fn assert_artifacts_missing(output_dir: OutputDirectoryBuilder) {
        let artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Syslog,
                Some("missing"),
                "missing contents",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic(expected = "Artifacts for TEST RUN")]
    fn assert_artifacts_extra_artifact(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut file_b =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("create artifact");
        write!(file_b, "hello").unwrap();
        let mut file_c =
            artifact_dir.new_artifact(ArtifactType::Stdout, "c.txt").expect("create artifact");
        write!(file_c, "hello").unwrap();
        drop(file_b);
        drop(file_c);
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Stderr,
                "c.txt".into(),
                "hello",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic]
    fn assert_artifacts_content_not_equal(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut file_b =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("create artifact");
        write!(file_b, "wrong content").unwrap();
        drop(file_b);
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_artifact(
                ArtifactType::Syslog,
                Option::<&str>::None,
                "expected content",
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic]
    fn assert_artifacts_content_does_not_match(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut file_b =
            artifact_dir.new_artifact(ArtifactType::Stderr, "b.txt").expect("create artifact");
        write!(file_b, "wrong content").unwrap();
        drop(file_b);
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_matching_artifact(
                ArtifactType::Syslog,
                Option::<&str>::None,
                |content| assert_eq!(content, "expected content"),
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    #[should_panic]
    fn assert_artifacts_directory_mismatch(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let dir_artifact =
            artifact_dir.new_directory_artifact(ArtifactType::Custom, "b").expect("new artifact");
        std::fs::write(dir_artifact.join("c.txt"), "unexpected file").unwrap();
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(
            output_dir.path(),
            &ExpectedTestRun::new(Outcome::Passed).with_directory_artifact(
                ArtifactType::Custom,
                Option::<&str>::None,
                ExpectedDirectory::new(),
            ),
        );
    }

    #[fixture::fixture(test_with_directory)]
    #[test]
    fn assert_artifacts_not_checked_if_unspecified(output_dir: OutputDirectoryBuilder) {
        let mut artifact_dir = output_dir.new_artifact_dir("artifacts").expect("new artifact dir");
        let mut file_c =
            artifact_dir.new_artifact(ArtifactType::Stderr, "c.txt").expect("create artifact");
        write!(file_c, "unexpected file").unwrap();
        drop(file_c);
        let actual = TestRunResult {
            common: Cow::Owned(CommonResult {
                name: RUN_NAME.to_string(),
                artifact_dir,
                outcome: Outcome::Passed.into(),
                start_time: None,
                duration_milliseconds: None,
            }),
            suites: vec![],
        };

        output_dir.save_summary(&actual).expect("save summary");
        assert_run_result(output_dir.path(), &ExpectedTestRun::new(Outcome::Passed));
    }
}
