1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
use std::any::TypeId;

use effectful::blocking::BlockingSpin;
use common::{
    protocol::{hint::MockHintWalker, request_hint::MockRequestHintVisitor},
    walker::MockWalker,
};
use mockall::predicate::eq;
use treaty::{
    any::OwnedStatic,
    protocol::{
        visitor::{RequestHint, ValueKnown, VisitResult},
        DynWalker,
    },
    Flow,
};

use crate::common::{protocol::hint::KnownFactory};
use effectful::bound::Dynamic;

mod common;

#[test]
fn hints_can_be_requested() {
    let mut mock = MockRequestHintVisitor::<BlockingSpin>::new();

    // We will request a hint from the visitor.
    mock.expect_request_hint().once().returning(|mut walker| {
        // Lookup the value protocol on the walker.
        let obj = walker
            .upcast_mut::<HintProto<ValueProto<OwnedStatic<i32>, BlockingSpin>>>()
            .unwrap();

        // Get the known for the value protocol.
        assert_eq!(
            obj.known(&()).into_value(),
            Ok(ValueKnown {
                preview: Some(Dynamic(&OwnedStatic(42)))
            })
        );

        // We are done.
        VisitResult::Control(Flow::Done)
    });

    // This mock becomes the visitor.
    let visitor: &mut dyn RequestHint<BlockingSpin> = &mut mock;

    let mut mock = MockWalker::<(), (), BlockingSpin>::new();

    // The visitor will lookup the value protocol on the walker.
    mock.expect_traits_mut()
        .once()
        .with(eq(TypeNameId::of::<
            HintProto<ValueProto<OwnedStatic<i32>, BlockingSpin>>,
            BlockingSpin,
        >()))
        .returning(|_id| {
            let mut mock = MockHintWalker::<ValueProto<OwnedStatic<i32>, BlockingSpin>>::new();

            // Expect to give a known for the value protocol to the visitor.
            mock.expect_known().once().return_const(
                (|_, ()| {
                    Ok(ValueKnown {
                        preview: Some(Dynamic(&OwnedStatic(42))),
                    })
                }) as KnownFactory<ValueProto<OwnedStatic<i32>, BlockingSpin>>,
            );

            Some(Box::new(mock))
        });

    // Request a hint from the visitor.
    assert!(matches!(
        visitor.request_hint(DynWalker(&mut mock)).into_value(),
        VisitResult::Control(Flow::Done)
    ));
}

#[test]
fn request_hint_proto() {
    // The type id of the higher ranked type.
    let id = TypeId::of::<RequestHintProto<BlockingSpin>>();

    // The type id for the lifetime containing value protocol trait object.
    let name_id = TypeNameId::of_lower::<dyn RequestHint<BlockingSpin>, BlockingSpin>();

    // They should be the same.
    assert_eq!(id, name_id.into_type_id());
}
*/