Skip to content

Commit 32a14f9

Browse files
committed
Add support for trait-variant
1 parent 6a8ac02 commit 32a14f9

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
@@ -771,6 +771,7 @@ fn find_lifetimes(ty: &Type) -> HashSet<Lifetime> {
771771
struct AttrFormatter<'a>{
772772
attrs: &'a [Attribute],
773773
async_trait: bool,
774+
trait_variant: bool,
774775
doc: bool,
775776
must_use: bool,
776777
}
@@ -780,6 +781,7 @@ impl<'a> AttrFormatter<'a> {
780781
Self {
781782
attrs,
782783
async_trait: true,
784+
trait_variant: false,
783785
doc: true,
784786
must_use: false,
785787
}
@@ -790,6 +792,11 @@ impl<'a> AttrFormatter<'a> {
790792
self
791793
}
792794

795+
fn trait_variant(&mut self, allowed: bool) -> &mut Self {
796+
self.trait_variant = allowed;
797+
self
798+
}
799+
793800
fn doc(&mut self, allowed: bool) -> &mut Self {
794801
self.doc = allowed;
795802
self
@@ -820,6 +827,8 @@ impl<'a> AttrFormatter<'a> {
820827
self.doc
821828
} else if *i.as_ref().unwrap() == "async_trait" {
822829
self.async_trait
830+
} else if *i.as_ref().unwrap() == "make" {
831+
self.trait_variant
823832
} else if *i.as_ref().unwrap() == "expect" {
824833
// This probably means that there's a lint that needs to be
825834
// 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)