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)
}