1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
//! # Overview //! This crate provides the macro `utest!(..)` Implementing the 3 phases setup/test/teardown. //! [![Crates.io](https://img.shields.io/crates/v/test-generator.svg)](https://crates.io/crates/test-generator-utest) //! [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/frehberg/test-generator/blob/master/LICENSE-MIT) //! [![Apache License](http://img.shields.io/badge/license-Apache-blue.svg)](https://github.com/frehberg/test-generator/blob/master/LICENSE-APACHE) //! [![Example](http://img.shields.io/badge/crate-Example-red.svg)](https://github.com/frehberg/test-generator/tree/master/example) //! //! [Documentation](https://docs.rs/test-generator-utest/) //! //! [Repository](https://github.com/frehberg/test-generator/) //! //! # Getting Started //! //! First of all you have to add this dependency to your `Cargo.toml`: //! //! ```toml //! [dev-dependencies] //! test-generator-utest = "^0.2" //! ``` //! The test-functionality is supports stable Rust. //! ```ignore //! #![cfg(test)] //! extern crate test_generator-utest; //! //! // Don't forget that procedural macros are imported with `use` statement, //! // for example importing the macro 'test_resources' //! #![cfg(test)] //! use test_generator-utest::utest; //! ``` //! /// Macro implementing the 3 phases setup/test/teardown /// /// # Usage /// /// The `utest` functionality supports the stable release of Rust-compiler since version 1.30. /// /// ```ignore /// #[cfg(test)] /// extern crate test_generator_utest; /// /// // demonstrating usage of utest-harness /// mod testsuite { /// use std::fs::File; /// use std::io::prelude::*; /// /// use test_generator_utest::utest; /// /// utest!(hello_world, /// || setup("/tmp/hello_world.txt"), /// |ctx_ref| test_write_hello_world(ctx_ref), /// |ctx|teardown(ctx)); /// /// utest!(hello_europe, /// || setup("/tmp/hello_europe.txt"), /// test_write_hello_europe, /// teardown); /// /// // Defining a context structure, storing the resources /// struct Context<'t> { file: File, name: &'t str } /// /// // Setup - Initializing the resources /// fn setup<'t>(filename: &str) -> Context { /// // unwrap may panic /// Context { file: File::create(filename).unwrap(), name: filename } /// } /// /// // Teardown - Releasing the resources /// fn teardown(context: Context) { /// let Context { file, name } = context; /// // drop file resources explicitly /// std::mem::drop(file); /// // unwrap may panic /// std::fs::remove_file(name).unwrap(); /// } /// /// // Test - verify feature /// fn test_write_hello_world(ctx: &Context) { /// // may panic /// let mut file = ctx.file.try_clone().unwrap(); /// // may panic /// file.write_all(b"Hello, world!\n").unwrap(); /// // !!!! although this assertion will fail, the teardown function will be invoked /// assert_eq!(1, 0); /// } /// /// // Test - verify feature /// fn test_write_hello_europe(ctx: &Context) { /// // may panic /// let mut file = ctx.file.try_clone().unwrap(); /// // may panic /// file.write_all(b"Hello, Europe!\n").unwrap(); /// } /// } /// ``` #[macro_export] macro_rules! utest { ( $id: ident, $setup:expr, $test:expr, $teardown:expr ) => { #[test] fn $id() { let context = std::panic::catch_unwind(|| { $setup() }); assert!(context.is_ok()); // unwrap the internal context item let ctx = match context { Ok(ctx) => ctx, Err(_) => unreachable!(), }; let result = std::panic::catch_unwind(|| { $test(&ctx) }); let finalizer = std::panic::catch_unwind(|| { $teardown(ctx) }); assert!(result.is_ok()); assert!(finalizer.is_ok()); } }; }