Skip to content

Commit 4e1e0e7

Browse files
committed
Add support for trait-variant
1 parent aeb460c commit 4e1e0e7

File tree

6 files changed

+76
-9
lines changed

6 files changed

+76
-9
lines changed

mockall/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ predicates-tree = "1.0"
4646
mockall_derive = { version = "=0.13.1", path = "../mockall_derive" }
4747

4848
[dev-dependencies]
49+
trait-variant = "0.1.2"
4950
async-trait = "0.1.38"
5051
auto_enums = "0.8.5"
5152
futures = "0.3.7"

mockall/src/lib.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -1067,15 +1067,14 @@
10671067
//!
10681068
//! ## Async Traits
10691069
//!
1070-
//! Async traits aren't yet (as of 1.47.0) a part of the Rust language. But
1071-
//! they're available from the
1072-
//! [`async_trait`](https://docs.rs/async-trait/0.1.38/async_trait/) crate.
1073-
//! Mockall is compatible with this crate, with two important limitations:
1074-
//!
1075-
//! * The `#[automock]` attribute must appear _before_ the `#[async_trait]`
1076-
//! attribute.
1077-
//!
1078-
//! * The `#[async_trait]` macro must be imported with its canonical name.
1070+
//! Partial support for async traits was introduced in the Rust language since
1071+
//! 1.75.0.
1072+
//! Mockall is compatible with them, as well as both
1073+
//! [`async_trait`](https://docs.rs/async-trait/latest/async_trait/) and
1074+
//! [`trait_variant`](https://docs.rs/trait-variant/latest/trait_variant/)
1075+
//! crates, with an important limitation:
1076+
//!
1077+
//! * The `#[automock]` attribute must appear _before_ the crate's attribute.
10791078
//!
10801079
//! ```
10811080
//! # use async_trait::async_trait;
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// vim: tw=80
2+
//! An async trait, for use with Futures
3+
#![deny(warnings)]
4+
5+
use futures::executor::block_on;
6+
use mockall::*;
7+
8+
#[automock]
9+
#[trait_variant::make(Send)]
10+
pub trait Foo {
11+
async fn foo(&self) -> u32;
12+
async fn bar() -> u32;
13+
}
14+
15+
16+
#[test]
17+
fn return_const() {
18+
let mut mock = MockFoo::new();
19+
mock.expect_foo()
20+
.return_const(42u32);
21+
assert_eq!(block_on(mock.foo()), 42);
22+
}
23+
24+
#[test]
25+
fn static_method() {
26+
let ctx = MockFoo::bar_context();
27+
ctx.expect()
28+
.return_const(42u32);
29+
assert_eq!(block_on(MockFoo::bar()), 42);
30+
}

mockall/tests/mock_trait_variant.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// vim: tw=80
2+
//! An async trait, for use with Futures
3+
#![deny(warnings)]
4+
5+
use futures::executor::block_on;
6+
use mockall::*;
7+
8+
#[trait_variant::make(Send)]
9+
pub trait Foo {
10+
async fn foo(&self) -> u32;
11+
}
12+
13+
mock! {
14+
pub Bar { }
15+
#[trait_variant::make(Send)]
16+
impl Foo for Bar {
17+
async fn foo(&self) -> u32;
18+
}
19+
}
20+
21+
#[test]
22+
fn return_const() {
23+
let mut mock = MockBar::new();
24+
mock.expect_foo()
25+
.return_const(42u32);
26+
assert_eq!(block_on(mock.foo()), 42);
27+
}

mockall_derive/src/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ fn find_lifetimes(ty: &Type) -> HashSet<Lifetime> {
774774
struct AttrFormatter<'a>{
775775
attrs: &'a [Attribute],
776776
async_trait: bool,
777+
trait_variant: bool,
777778
doc: bool,
778779
must_use: bool,
779780
}
@@ -783,6 +784,7 @@ impl<'a> AttrFormatter<'a> {
783784
Self {
784785
attrs,
785786
async_trait: true,
787+
trait_variant: false,
786788
doc: true,
787789
must_use: false,
788790
}
@@ -793,6 +795,11 @@ impl<'a> AttrFormatter<'a> {
793795
self
794796
}
795797

798+
fn trait_variant(&mut self, allowed: bool) -> &mut Self {
799+
self.trait_variant = allowed;
800+
self
801+
}
802+
796803
fn doc(&mut self, allowed: bool) -> &mut Self {
797804
self.doc = allowed;
798805
self
@@ -823,6 +830,8 @@ impl<'a> AttrFormatter<'a> {
823830
self.doc
824831
} else if *i.as_ref().unwrap() == "async_trait" {
825832
self.async_trait
833+
} else if *i.as_ref().unwrap() == "make" {
834+
self.trait_variant
826835
} else if *i.as_ref().unwrap() == "expect" {
827836
// This probably means that there's a lint that needs to be
828837
// surpressed for the real code, but not for the mock code.

mockall_derive/src/mockable_struct.rs

+1
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ impl From<(Attrs, ItemTrait)> for MockableStruct {
371371
let mut attrs = AttrFormatter::new(&trait_.attrs)
372372
.doc(true)
373373
.async_trait(true)
374+
.trait_variant(true)
374375
.must_use(false)
375376
.format();
376377
attrs.push(derive_debug());

0 commit comments

Comments
 (0)