#![allow(dead_code)]
use async_trait::async_trait;
use double_trait::{Dummy, double};
#[test]
fn implement_double_instead_of_original_trait() {
#[double(MyEmptyTraitDummy)]
trait MyEmptyTrait {}
struct MyStruct;
impl MyEmptyTraitDummy for MyStruct {}
fn use_trait(_: impl MyEmptyTrait) {
}
use_trait(MyStruct);
}
#[test]
fn invoke_implemented_method_through_original_trait() {
#[double(DummyTrait)]
trait OrgTrait {
fn answer(&self) -> i32;
fn some_other_method(&self);
}
struct MyStruct;
impl DummyTrait for MyStruct {
fn answer(&self) -> i32 {
42
}
}
assert_eq!(42, OrgTrait::answer(&MyStruct));
}
#[tokio::test]
async fn async_method_invocation() {
#[double(DummyTrait)]
trait OrgTrait {
async fn answer(&self) -> i32;
async fn foobar(&self);
}
struct MyStruct;
impl DummyTrait for MyStruct {
async fn answer(&self) -> i32 {
42
}
}
assert_eq!(42, OrgTrait::answer(&MyStruct).await);
}
#[tokio::test]
async fn associated_method_invocation() {
#[double(DummyTrait)]
trait OrgTrait {
async fn answer() -> i32;
}
struct MyStruct;
impl DummyTrait for MyStruct {
async fn answer() -> i32 {
42
}
}
assert_eq!(42, <MyStruct as OrgTrait>::answer().await);
}
#[tokio::test]
async fn impl_future_method_invocation() {
use std::future::Future;
#[double(DummyTrait)]
trait OrgTrait {
fn answer(&self) -> impl Future<Output = i32>;
}
struct MyStruct;
impl DummyTrait for MyStruct {
fn answer(&self) -> impl Future<Output = i32> {
async { 42 }
}
}
assert_eq!(42, OrgTrait::answer(&MyStruct).await);
}
#[test]
fn dummy_implements_double_trait() {
#[double(DummyTrait)]
trait OrgTrait {}
fn use_trait(_: impl OrgTrait) {}
use_trait(Dummy);
}
#[tokio::test]
async fn combine_with_async_trait() {
#[async_trait]
#[double(DummyTrait)]
trait OrgTrait {
async fn answer(&self) -> i32;
}
struct MyStruct;
#[async_trait]
impl DummyTrait for MyStruct {
async fn answer(&self) -> i32 {
42
}
}
assert_eq!(42, OrgTrait::answer(&MyStruct).await);
}
#[test]
fn trait_with_existing_default_method_impl() {
#[double(DoubleTrait)]
trait OrgTrait {
fn answer(&self) -> i32 {
42
}
}
}
#[test]
fn trait_with_associated_types() {
#[double(DoubleTrait)]
trait OrgTrait {
type AssociatedType;
}
}
#[test]
#[should_panic(expected = "not implemented: DummyTrait::answer")]
fn calling_unimplemented_double_method_mentions_method_name() {
#[double(DummyTrait)]
trait OrgTrait {
fn answer(&self) -> i32;
}
OrgTrait::answer(&Dummy);
}