s_test_fixture 0.1.5

s_test_fixture or simple test fixture is a macro library to implement test fixture with no hassle
Documentation
//! # s_test_fixture
//!
//! `s_test_fixture` or simple test fixture is a macro library to implement test fixture with no hassle.
//!
//! Their is four macros: `before`, `after`, `before_each`, `after_each`. The function pass as argument must return nothing.
//! `before` and `after` are added before the target test function . `before_each` and `after_each` are added before the target module.

use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;
mod util;
use syn::{ExprCall, ItemFn, ItemMod};

/// execute a function after the test is executed even if the test failled
/// # Examples
/// ```
/// #[test]
/// #[after(function_to_run(66))]
/// fn test() -> Result<(), ()> {
///    println!("before");
///    let i = -55;
///    if i == 0 {
///        Ok(())
///    } else if i == 2 {
///        return Ok(());
///    } else {
///        panic!("oh no!")
///        Ok(())
///    }
/// }
///
/// fn function_to_run(i:i32){
///     println!("I did {} thing(s)",i);
/// }
/// ```
///
/// will return
/// ```text
/// before
/// {panic statement}
/// I did 66 thing(s)
/// ```
/// 
#[proc_macro_attribute]
pub fn after(_metadata: TokenStream, input: TokenStream) -> TokenStream {
    let mut function = parse_macro_input!(input as ItemFn);
    let args = parse_macro_input!(_metadata as ExprCall);

    util::add_fn_after(&mut function, &args)
}

/// execute a function before the test start
/// # Examples
/// ```
/// #[test]
/// #[before(function_to_run(2))]
/// fn test() {
///    let a = 2;
///    assert_eq!(a,2);
///    println!("ending");
/// }
///
/// fn function_to_run(i:i32){
///     println!("I did {} thing(s)",i);
/// }
/// ```
/// will return
/// ```text
/// before
/// I did 2 thing(s)
/// ending
/// ```
#[proc_macro_attribute]
pub fn before(_metadata: TokenStream, input: TokenStream) -> TokenStream {
    let mut function = parse_macro_input!(input as ItemFn);
    let args = parse_macro_input!(_metadata as ExprCall);

    util::add_fn_before(&mut function, &args)
}

/// for each tests of a module execute the function before the test start
/// # Examples
/// ```
/// #[before_each(function_to_run(2))]
/// mod tests{
///     #[test]
///     fn test() {
///         let a = 2;
///         assert_eq!(a,2);
///         println!("ending");
///     }
/// 
///     #[test]
///     fn another_test() {
///         let a = 2;
///         assert_eq!(a,2);
///         println!("ending");
///     }
///
///     fn function_to_run(i:i32){
///         println!("I did {} thing(s)",i);
///     }
/// }
/// ```
#[proc_macro_attribute]
pub fn before_each(_metadata: TokenStream, input: TokenStream) -> TokenStream {
    let mut test_mod = parse_macro_input!(input as ItemMod);
    let args = parse_macro_input!(_metadata as ExprCall);
    util::add_fn_before_each(&mut test_mod, &args);
    TokenStream::from(quote! {
        #test_mod
    })
}

/// for each tests of a module execute the function after the test end even if the test failled
/// # Examples
/// ```
/// #[after_each(function_to_run(66))]
/// mod tests{
///     #[test]
///     fn test() -> Result<(), ()> {
///         println!("before");
///         let i = -55;
///         if i == 0 {
///             Ok(())
///         } else if i == 2 {
///             return Ok(());
///         } else {
///             panic!("oh no!")
///             Ok(())
///          }
///     }
/// 
///     #[test]
///     fn another_test() -> Result<(), ()> {
///         println!("before");
///         let i = 0;
///         if i == 0 {
///             Ok(())
///         } else if i == 2 {
///             return Ok(());
///         } else {
///             panic!("oh no!")
///             Ok(())
///          }
///     }
///
///     fn function_to_run(i:i32){
///         println!("I did {} thing(s)",i);
///     }
/// }

/// ```
#[proc_macro_attribute]
pub fn after_each(_metadata: TokenStream, input: TokenStream) -> TokenStream {
    let mut test_mod = parse_macro_input!(input as ItemMod);
    let args = parse_macro_input!(_metadata as ExprCall);
    util::add_fn_after_each(&mut test_mod, &args);
    TokenStream::from(quote! {
        #test_mod
    })
}