Skip to content

Commit

Permalink
implement from_fn! and pattern!
Browse files Browse the repository at this point in the history
these macros allow for pattern matching either with a closure or
pattern respectively
  • Loading branch information
nrxus committed Apr 4, 2021
1 parent b5f1acb commit a209091
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
//! expectations.

mod any;
mod from_fn;
mod eq;
mod invocation_matcher;

pub use any::{any, Any};
pub use eq::{eq, eq_against, Eq, EqAgainst};
pub use from_fn::from_fn;
pub use invocation_matcher::InvocationMatcher;

use std::fmt::{self, Formatter};
Expand Down
47 changes: 47 additions & 0 deletions src/matcher/from_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use super::ArgMatcher;
use std::fmt;

pub struct Custom<F> {
message: String,
matcher: F,
}

impl<Arg, F: Fn(&Arg) -> bool> ArgMatcher<Arg> for Custom<F> {
fn matches(&self, argument: &Arg) -> bool {
let matcher = &self.matcher;
matcher(argument)
}
}

impl<F> fmt::Display for Custom<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.message)
}
}

pub fn from_fn<Arg>(
matcher: impl Fn(&Arg) -> bool,
message: impl fmt::Display,
) -> impl ArgMatcher<Arg> {
Custom {
matcher,
message: message.to_string(),
}
}

#[macro_export]
macro_rules! from_fn {
($matcher:expr) => {
faux::matcher::from_fn($matcher, stringify!($matcher))
};
}

#[macro_export]
macro_rules! pattern {
($ty:ty => $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => (
faux::matcher::from_fn(
move |arg: &$ty| matches!(arg, $($pattern)|+ $(if $guard)?),
stringify!($($pattern)|+ $(if $guard)?),
)
);
}
14 changes: 14 additions & 0 deletions tests/when_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ fn custom_matcher() {
assert_eq!(mock.one_ref_arg(&data), 123);
}

#[test]
fn pattern() {
let mut mock = Foo::faux();
faux::when!(mock.one_ref_arg(_ = faux::pattern!(&Data => Data { a: 2, .. }))).then_return(123);
assert_eq!(mock.one_ref_arg(&Data { a: 2, b: 789 }), 123);
}

#[test]
fn from_fn() {
let mut mock = Foo::faux();
faux::when!(mock.one_ref_arg(_ = faux::from_fn!(|data: &&Data| data.b == 3))).then_return(123);
assert_eq!(mock.one_ref_arg(&Data { a: 123, b: 3 }), 123);
}

#[test]
fn mixed_args() {
let mut mock = Foo::faux();
Expand Down

0 comments on commit a209091

Please sign in to comment.