rtest 0.2.2

integration test building framework
Documentation
/*
    Ever wondered if your filesystem, ext4, ntfs, apfs can create, modify and delete files?
    Ofc testing a filesystem doesn't make sense, this however is a great test to show the dependency model of integration-test
*/
//use integration_test::main;
use rtest::{Context, TestError};
use rtest_derive::{rtest, run, Resource};
use std::{fs, result::Result};
use thiserror::Error;

#[derive(Clone, Resource)]
struct FileInfo {
    name: String,
}

#[derive(Clone, Resource)]
struct File {
    name: String,
}

#[derive(Debug, Error)]
pub enum FileError {
    #[error("setup problem, no test failure: {0}")]
    Setup(std::io::Error),
    #[error("test failure: {0}")]
    Assertion(std::io::Error),
}

impl TestError for FileError {
    fn fails(&self) -> bool {
        match self {
            FileError::Setup(_) => false,
            FileError::Assertion(_) => true,
        }
    }

    fn exitcode(&self) -> (u8, u64) {
        match self {
            FileError::Setup(_) => (0, 0),
            FileError::Assertion(_) => (100, 0),
        }
    }
}

mod init {
    use super::*;

    #[rtest(module = "filesystem::init", group = "create")]
    pub async fn setup_fileinfo() -> Result<FileInfo, FileError> {
        Ok(FileInfo {
            name: "foobar.txt.example".to_string(),
        })
    }
}

#[rtest(
    module = "filesystem",
    group = "create",
    responsible = "maintainer@example.com",
    cost = 100
)]
fn create_file(file: FileInfo) -> Result<File, FileError> {
    use std::fs;
    let mut _file = fs::File::create(&file.name).map_err(FileError::Setup)?;
    fs::metadata(&file.name).map_err(FileError::Assertion)?;
    Ok(File {
        name: file.name.clone(),
    })
}

#[rtest(group = "read")]
async fn read_metadata(file: &File) -> Result<(), FileError> {
    fs::metadata(&file.name).map_err(FileError::Assertion)?;
    Ok(())
}

#[rtest(group = "read")]
async fn test_that_should_fail(file: &File) -> Result<(), FileError> {
    tracing::info!("Wubba Lubba dub-dub");
    fs::metadata(format!("{}-invalid", file.name)).map_err(FileError::Assertion)?;

    Ok(())
}

#[rtest(group = "read")]
fn test_that_should_panic(_: &File) -> Result<(), FileError> {
    tracing::info!("Kaboom?");
    panic!("Yes Rico, Kaboom");
}

#[rtest(group = "read", optional)]
fn optional_test(_: File) -> Result<(), FileError> { Ok(()) }

#[rtest]
fn delete_file(file: File) -> Result<(), FileError> {
    fs::remove_file(&file.name).map_err(FileError::Setup)?;
    if fs::metadata(&file.name).is_ok() {
        return Err(FileError::Assertion(std::io::Error::new(
            std::io::ErrorKind::Other,
            "I removed the file, but it still seems to exist",
        )));
    }
    Ok(())
}

pub fn main() -> std::process::ExitCode {
    let file = FileInfo {
        name: "foobar.txt.example".to_string(),
    };
    let runconfig = rtest::RunConfig {
        context: Context::default().with_resource(file),
        ..Default::default()
    };
    run!(runconfig)
}