#![allow(dead_code)]
use double_trait::{Dummy, dummies};
#[test]
fn invoke_method_on_partial_implementation_of_trait() {
#[dummies]
trait MyTrait {
fn answer(&self) -> i32;
fn some_other_method(&self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn answer(&self) -> i32 {
42
}
}
assert_eq!(42, MyTrait::answer(&MyStruct));
}
#[tokio::test]
async fn partially_implement_async_trait() {
#[dummies]
trait MyTrait {
async fn answer(&self) -> i32;
async fn foobar(&self);
}
struct MyStruct;
impl MyTrait for MyStruct {
async fn answer(&self) -> i32 {
42
}
}
assert_eq!(42, MyTrait::answer(&MyStruct).await);
}
#[tokio::test]
async fn associated_async_method_invocation() {
#[dummies]
trait MyTrait {
async fn answer() -> i32;
}
struct MyStruct;
impl MyTrait for MyStruct {
async fn answer() -> i32 {
42
}
}
assert_eq!(42, <MyStruct as MyTrait>::answer().await);
}
#[tokio::test]
async fn impl_future_method_invocation() {
use std::future::Future;
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Future<Output = i32>;
}
struct MyStruct;
impl MyTrait for MyStruct {
fn answer(&self) -> impl Future<Output = i32> {
async { 42 }
}
}
assert_eq!(42, MyTrait::answer(&MyStruct).await);
}
#[tokio::test]
async fn annotate_traits_with_impl_iterator() {
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Iterator<Item = String>;
fn question(&self) -> impl Iterator<Item = String>;
}
struct MyStruct;
impl MyTrait for MyStruct {
fn answer(&self) -> impl Iterator<Item = String> {
(0..1).map(|i| format!("Item {}", i))
}
}
assert_eq!("Item 0", MyTrait::answer(&MyStruct).next().unwrap());
}
#[test]
fn dummy_implements_my_trait() {
#[dummies]
trait MyTrait {}
fn use_trait(_: impl MyTrait) {}
use_trait(Dummy);
}
#[test]
fn trait_with_existing_default_method_impl() {
#[dummies]
trait MyTrait {
fn answer(&self) -> i32 {
42
}
}
}
#[test]
fn trait_with_associated_types() {
#[dummies]
trait OrgTrait {
type AssociatedType;
}
}
#[test]
#[should_panic(expected = "not implemented: MyTrait::answer")]
fn calling_unimplemented_double_method_mentions_method_name() {
#[dummies]
trait MyTrait {
fn answer(&self) -> i32;
}
MyTrait::answer(&Dummy);
}
#[test]
fn don_t_panic_on_invoking_method_with_no_return_type() {
#[dummies]
trait MyTrait {
fn answer(&self);
}
Dummy.answer();
}
#[tokio::test]
async fn don_t_panic_on_invoking_method_returning_future_with_unit() {
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Future<Output = ()>;
}
Dummy.answer().await;
}
#[tokio::test]
async fn future_of_iterator() {
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Future<Output = impl Iterator<Item = i32>>;
}
let values: Vec<_> = Dummy.answer().await.collect();
assert!(values.is_empty())
}
#[tokio::test]
async fn iterator_of_future() {
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Iterator<Item = impl Future<Output = i32>>;
}
let values: Vec<_> = Dummy.answer().collect();
assert!(values.is_empty())
}
#[cfg(feature = "stream")]
#[tokio::test]
async fn impl_stream_return() {
use futures_util::{Stream, StreamExt};
#[dummies]
trait MyTrait {
fn answer(&self) -> impl Stream<Item = i32>;
}
struct MyStruct;
impl MyTrait for MyStruct {}
let values: Vec<_> = MyStruct.answer().collect().await;
assert!(values.is_empty())
}