From ef65828110801ddac065c7bf436005e31d6736c6 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 28 Aug 2020 21:21:32 -0600 Subject: [PATCH] Allow mocking methods that return slices When setting expectations, use the owned form: a Vec. Fixes #130 --- CHANGELOG.md | 3 +++ mockall/src/lib.rs | 1 + mockall/tests/automock_deref.rs | 9 +++++++++ mockall_derive/src/mock_function.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac8f9742..178d3d40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate ### Added +- Methods returning slices can now be mocked. Their expectations take `Vec`s. + ([#185](https://github.com/asomers/mockall/pull/185)) + - Compatibility with the `#[async_trait]` macro. ([#183](https://github.com/asomers/mockall/pull/183)) diff --git a/mockall/src/lib.rs b/mockall/src/lib.rs index 58fc8c99..ac3c19d6 100644 --- a/mockall/src/lib.rs +++ b/mockall/src/lib.rs @@ -490,6 +490,7 @@ //! [`CStr`](std::ffi::CStr), //! [`OsStr`](std::ffi::OsStr), //! [`Path`](std::path::Path), +//! [`Slice`][std::slice], //! and //! [`str`](std::str) //! types are supported. Using this feature is automatic: diff --git a/mockall/tests/automock_deref.rs b/mockall/tests/automock_deref.rs index 2ff03c7f..61c55b33 100644 --- a/mockall/tests/automock_deref.rs +++ b/mockall/tests/automock_deref.rs @@ -15,6 +15,7 @@ trait Foo { fn desc(&self) -> &OsStr; fn path(&self) -> &Path; fn text(&self) -> &'static str; + fn slice(&self) -> &[i32]; } mod return_const { @@ -62,4 +63,12 @@ mod return_const { mock.expect_text().return_const(TEXT); assert_eq!("abcd", mock.text()); } + + #[test] + fn slice() { + let r = vec![1, 2, 3]; + let mut mock = MockFoo::new(); + mock.expect_slice().return_const(r); + assert_eq!(&[1, 2, 3], mock.slice()); + } } diff --git a/mockall_derive/src/mock_function.rs b/mockall_derive/src/mock_function.rs index 1cb3297f..04b2144a 100644 --- a/mockall_derive/src/mock_function.rs +++ b/mockall_derive/src/mock_function.rs @@ -37,6 +37,32 @@ fn destrify(ty: &mut Type) { *tr.elem = pathbuf_ty, Type::Path(ref path) if *path == str_ty => *tr.elem = string_ty, + Type::Slice(ts) => { + let inner = (*ts.elem).clone(); + let mut segments = Punctuated::new(); + segments.push(format_ident!("std").into()); + segments.push(format_ident!("vec").into()); + let mut v: PathSegment = format_ident!("Vec").into(); + let mut abga_args = Punctuated::new(); + abga_args.push(GenericArgument::Type(inner)); + v.arguments = PathArguments::AngleBracketed( + AngleBracketedGenericArguments { + colon2_token: None, + lt_token: Token![<](Span::call_site()), + args: abga_args, + gt_token: Token![>](Span::call_site()), + } + ); + segments.push(v); + + *tr.elem = Type::Path(TypePath { + qself: None, + path: Path { + leading_colon: Some(Token![::](Span::call_site())), + segments + } + }); + }, _ => (), // Nothing to do }; }