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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

//! # Usage
//! Add ```must``` to your Cargo.toml file.
//!
//! ```ignore
//! [dev-dependencies]
//! must = "0.2.*"
//! ```
//!
//! And add
//!
//! ```ignore
//! #[cfg_attr(test, macro_use)]
//! #[cfg(test)]
//! extern crate must;
//! ```
//!
//! to your [root module][].
//!
//! Then add
//!
//! ```ignore
//! use must::prelude::*;
//! ```
//!
//! your test module.
//!
//!
//!
//! # Features
//!
//! - Lazy. You can use .with_msg() after assertion.
//! - Fluent.
//! - You can build your own composable test tool. See [lazy module][] for full example.
//!
//! ```rust,ignore
//! let parser: fn(&str) -> Result<Lit, ParseError> = parse_lit;
//! parser.must_parse("false").as_ok(Lit::Bool(false)); // .or(fail!()) is optional
//! parser.must_parse("true").as_ok(Lit::Bool(true)).or(fail!());
//! parser.must_parse("352").as_ok(Lit::Num(352)).or(fail!());
//! ```
//!
//!
//!
//! # How does it work?
//!
//! - If value is not explicitly taken by user, it panics on drop.
//! - As it defers panic, with_msg() can be used almost anywhere.
//!
//!
//! # Examples (Usage)
//!
//! ```rust
//! #[macro_use] extern crate must;
//! use must::prelude::*;
//! # fn main() {
//! // fail!() is optional, and if not called, it will panic on drop.
//! // but as it's value is not used, it will be dropped right after one assertion chain.
//!
//!
//! Some(5u8).must_be_some_and(|val| {
//!     val.must_be(5) // closure must return assertion
//! }).or(fail!("your msg {}", "and args"));
//!   // fail! macro captures location, so you can know source of panic without backtrace.
//!   // fail! macro supports optional formatting.
//!   // As value is printed by must, you don't have to put it in format args.
//!
//! fn double(x: usize) -> usize {
//!     x * 2
//! }
//!
//! 10.must_be_in_range(10..);
//! 10.must_not_be_in_range(..10);
//! double(10).must_be_in_range(..);
//! double(10).must_not_be_in_range(..20);
//! # }
//! ```
//!
//!
//!
//! # Examples (Extending must with builder style)
//!
//! See [lazy module][].
//!
//!
//!
//! [lazy module]:lazy/index.html
//! [root module]:https://doc.rust-lang.org/book/crates-and-modules.html

#[macro_use]
extern crate log;
extern crate mutator;
extern crate num_traits;

pub use mutator::Mutator;
pub use self::errors::{Error, ErrorKind};
pub use self::lazy::{LazyAssertion, LazyMatcher};
pub mod errors;
pub mod lazy;
pub mod marker;
pub mod prelude;
pub mod error_renderer;
pub mod matchers;


/// **fail!** macro is used to add source and custom message to result.
///
/// fail!() - Just capture source location.
///
/// fail!("") - Add message.
///
/// fail!("{:?}", var) - Add message.
///
#[macro_export]
macro_rules! fail {
    () => {{
        fn fail_with_src(err: &$crate::Error) {
            let src = $crate::error_renderer::Source {
                filename: file!(),
                line: line!(),
                column: column!(),
            };

            let renderer = &$crate::error_renderer::ErrRenderer {
			    err: err,
			    src: Some(src),
                msg: None,
		    };
            panic!("{}", renderer);
        }

        fail_with_src
    }};

     ($fmt:expr) => {{
        let f = |ref err: &$crate::Error| {
            let src = $crate::error_renderer::Source {
                filename: file!(),
                line: line!(),
                column: column!(),
            };

            let renderer = &$crate::error_renderer::ErrRenderer {
			    err: err,
			    src: Some(src),
                msg: Some(format!($fmt)),
		    };
            panic!("{}", renderer);
        };

        f
    }};

    ($fmt:expr, $($arg:tt)*) => {{
        let f = |ref err: &$crate::Error| {
            let src = $crate::error_renderer::Source {
                filename: file!(),
                line: line!(),
                column: column!(),
            };

            let renderer = &$crate::error_renderer::ErrRenderer {
			    err: err,
			    src: Some(src),
                msg: Some(format!($fmt, $($arg)* )),
		    };
            panic!("{}", renderer);
        };

        f
    }};
}