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
/* Copyright 2017 Christopher Bacher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //! The variant module contains matchers for asserting properties of enums and convienience functions for Option and Result. use super::super::*; /// Matches if the asserted value's variant matches the expected variant. /// /// # Examples /// If the enum's variants are already imported one can write: /// /// ``` /// # #[macro_use] extern crate galvanic_assert; /// # fn main() { /// let ok: Result<i32, ()> = Ok(4); /// assert_that!(&ok, is_variant!(Ok)); /// # } /// ``` /// If not then the full path of the variant has to be used: /// /// ``` /// # #[macro_use] extern crate galvanic_assert; /// # fn main() { /// enum MyEnum { Foo, Bar(i32), Baz{x: i32} } /// assert_that!(&MyEnum::Baz{x: 2}, is_variant!(MyEnum::Baz)); /// # } /// ``` #[macro_export] macro_rules! is_variant { ( $variant: path ) => { Box::new(|actual: &_| { use galvanic_assert::MatchResultBuilder; let builder = MatchResultBuilder::for_("is_variant"); match actual { &$variant {..} => builder.matched(), _ => builder.failed_because( &format!("passed variant does not match '{}'", stringify!($variant)) ) } }) } } /// Matches the contents of an `Option` againts a passed `Matcher`. /// /// #Examples /// ```rust /// # #[macro_use] extern crate galvanic_assert; /// use galvanic_assert::matchers::*; /// use galvanic_assert::matchers::variant::*; /// # fn main() { /// assert_that!(&Some(32), maybe_some(eq(32))); /// # } pub fn maybe_some<'a, T: 'a>(matcher: Box<Matcher<'a,T> + 'a>) -> Box<Matcher<'a,Option<T>> + 'a> { Box::new(move |maybe_actual: &'a Option<T>| { maybe_actual.as_ref() .map_or(MatchResultBuilder::for_("maybe_some") .failed_because("passed Option is None; cannot evaluate nested matcher"), |actual| matcher.check(actual) ) }) } /// Matches the contents of a `Result` if it is `Ok` againts a passed `Matcher`. /// /// #Examples /// ```rust /// # #[macro_use] extern crate galvanic_assert; /// use galvanic_assert::matchers::*; /// use galvanic_assert::matchers::variant::*; /// # fn main() { /// let ok: Result<i32,()> = Ok(32); /// assert_that!(&ok, maybe_ok(eq(32))); /// # } pub fn maybe_ok<'a, T: 'a, E: 'a>(matcher: Box<Matcher<'a,T> + 'a>) -> Box<Matcher<'a,Result<T,E>> + 'a> { Box::new(move |maybe_actual: &'a Result<T,E>| { match maybe_actual.as_ref() { Ok(actual) => matcher.check(actual), Err(_) => MatchResultBuilder::for_("maybe_ok") .failed_because("passed Result is Err; cannot evaluate nested matcher") } }) } /// Matches the contents of a `Result` if it is `Err` againts a passed `Matcher`. /// /// #Examples /// ```rust /// # #[macro_use] extern crate galvanic_assert; /// use galvanic_assert::matchers::*; /// use galvanic_assert::matchers::variant::*; /// # fn main() { /// let err: Result<i32,i32> = Err(32); /// assert_that!(&err, maybe_err(eq(32))); /// # } pub fn maybe_err<'a, T: 'a, E: 'a>(matcher: Box<Matcher<'a,E> + 'a>) -> Box<Matcher<'a,Result<T,E>> + 'a> { Box::new(move |maybe_actual: &'a Result<T,E>| { match maybe_actual.as_ref() { Err(actual) => matcher.check(actual), Ok(_) => MatchResultBuilder::for_("maybe_err") .failed_because("passed Result is Ok; cannot evaluate nested matcher") } }) }