diff --git a/CHANGELOG.md b/CHANGELOG.md index 582e49d1..51928c03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [ Unreleased ] - ReleaseDate + +## Fixed + +- Fixed using Mockall when a function named `Ok` is in scope. The `anyhow` + crate, for example, creates a function by this name. + ([#389](https://github.com/asomers/mockall/pull/389)) + ## [ 0.11.1 ] - 2022-05-15 ### Fixed diff --git a/mockall/tests/anyhow.rs b/mockall/tests/anyhow.rs new file mode 100644 index 00000000..7d400931 --- /dev/null +++ b/mockall/tests/anyhow.rs @@ -0,0 +1,86 @@ +// vim: tw=80 +//! Mockall should be compatible with crates like Anyhow that redefine `Ok`. +#![deny(warnings)] + +use mockall::*; + +// Define Error, Result, and Ok similarly to how anyhow defines them +pub struct Error(); +impl Error { + pub fn new(_e: E) -> Self { + Self() + } +} +#[allow(non_snake_case)] +pub fn Ok(t: T) -> Result { + Result::Ok(t) +} +pub type Result = std::result::Result; + +#[automock] +trait Foo { + fn foo(&self) -> Result<(), Error>; + fn reffoo(&self) -> &Result<(), Error>; + fn refmutfoo(&mut self) -> &mut Result<(), Error>; + fn staticfoo() -> Result<(), Error>; +} + +mod static_method { + use super::*; + + #[test] + fn ok() { + let mut foo = MockFoo::new(); + foo.expect_foo() + .returning(|| Ok(())); + assert!(foo.foo().is_ok()); + } + + #[test] + fn err() { + let mut foo = MockFoo::new(); + foo.expect_foo() + .returning(|| Err(Error::new(std::io::Error::last_os_error()))); + assert!(foo.foo().is_err()); + } +} + +mod ref_method { + use super::*; + + #[test] + fn ok() { + let mut foo = MockFoo::new(); + foo.expect_reffoo() + .return_const(Ok(())); + assert!(foo.reffoo().is_ok()); + } + + #[test] + fn err() { + let mut foo = MockFoo::new(); + foo.expect_reffoo() + .return_const(Err(Error::new(std::io::Error::last_os_error()))); + assert!(foo.reffoo().is_err()); + } +} + +mod refmut_method { + use super::*; + + #[test] + fn ok() { + let mut foo = MockFoo::new(); + foo.expect_refmutfoo() + .return_var(Ok(())); + assert!(foo.refmutfoo().is_ok()); + } + + #[test] + fn err() { + let mut foo = MockFoo::new(); + foo.expect_refmutfoo() + .return_var(Err(Error::new(std::io::Error::last_os_error()))); + assert!(foo.refmutfoo().is_err()); + } +} diff --git a/mockall_derive/src/mock_function.rs b/mockall_derive/src/mock_function.rs index 78df187c..8de62080 100644 --- a/mockall_derive/src/mock_function.rs +++ b/mockall_derive/src/mock_function.rs @@ -1647,13 +1647,13 @@ impl<'a> ToTokens for RefRfunc<'a> { { match self { Rfunc::Default(Some(ref __mockall_o)) => { - Ok(__mockall_o) + ::std::result::Result::Ok(__mockall_o) }, Rfunc::Default(None) => { Err(#default_err_msg) }, Rfunc::Const(ref __mockall_o) => { - Ok(__mockall_o) + ::std::result::Result::Ok(__mockall_o) }, Rfunc::_Phantom(_) => unreachable!() } @@ -1717,7 +1717,7 @@ impl<'a> ToTokens for RefMutRfunc<'a> { { match self { Rfunc::Default(Some(ref mut __mockall_o)) => { - Ok(__mockall_o) + ::std::result::Result::Ok(__mockall_o) }, Rfunc::Default(None) => { Err(#default_err_msg) @@ -1726,7 +1726,7 @@ impl<'a> ToTokens for RefMutRfunc<'a> { { *__mockall_o = Some(__mockall_f(#(#argnames, )*)); if let Some(ref mut __mockall_o2) = __mockall_o { - Ok(__mockall_o2) + ::std::result::Result::Ok(__mockall_o2) } else { unreachable!() } @@ -1737,13 +1737,13 @@ impl<'a> ToTokens for RefMutRfunc<'a> { #(#argnames, )*) ); if let Some(ref mut __mockall_o2) = __mockall_o { - Ok(__mockall_o2) + ::std::result::Result::Ok(__mockall_o2) } else { unreachable!() } }, Rfunc::Var(ref mut __mockall_o) => { - Ok(__mockall_o) + ::std::result::Result::Ok(__mockall_o) }, Rfunc::_Phantom(_) => unreachable!() } @@ -1812,15 +1812,15 @@ impl<'a> ToTokens for StaticRfunc<'a> { Err("called twice, but it returns by move") }, Rfunc::Mut(__mockall_f) => { - Ok(__mockall_f( #(#argnames, )* )) + ::std::result::Result::Ok(__mockall_f( #(#argnames, )* )) }, Rfunc::MutSt(__mockall_f) => { - Ok((__mockall_f.get_mut())(#(#argnames,)*)) + ::std::result::Result::Ok((__mockall_f.get_mut())(#(#argnames,)*)) }, Rfunc::Once(_) => { if let Rfunc::Once(mut __mockall_f) = mem::replace(self, Rfunc::Expired) { - Ok(__mockall_f( #(#argnames, )* )) + ::std::result::Result::Ok(__mockall_f( #(#argnames, )* )) } else { unreachable!() } @@ -1828,7 +1828,7 @@ impl<'a> ToTokens for StaticRfunc<'a> { Rfunc::OnceSt(_) => { if let Rfunc::OnceSt(mut __mockall_f) = mem::replace(self, Rfunc::Expired) { - Ok((__mockall_f.into_inner())(#(#argnames,)*)) + ::std::result::Result::Ok((__mockall_f.into_inner())(#(#argnames,)*)) } else { unreachable!() }