This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew/tests/
layout_tests.rs

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Snapshot testing of Yew components
//!
//! This tests must be run in browser and thus require the `csr` feature to be enabled
use gloo::console::log;

use crate::dom_bundle::{BSubtree, Bundle, DomSlot};
use crate::html::AnyScope;
use crate::virtual_dom::VNode;
use crate::{scheduler, Component, Context, Html};

struct Comp;
impl Component for Comp {
    type Message = ();
    type Properties = ();

    fn create(_: &Context<Self>) -> Self {
        unimplemented!()
    }

    fn update(&mut self, _ctx: &Context<Self>, _: Self::Message) -> bool {
        unimplemented!();
    }

    fn changed(&mut self, _ctx: &Context<Self>, _: &Self::Properties) -> bool {
        unimplemented!()
    }

    fn view(&self, _ctx: &Context<Self>) -> Html {
        unimplemented!()
    }
}

#[derive(Debug)]
#[allow(missing_docs)]
pub struct TestLayout<'a> {
    pub name: &'a str,
    pub node: VNode,
    pub expected: &'a str,
}

#[allow(missing_docs)]
pub fn diff_layouts(layouts: Vec<TestLayout<'_>>) {
    let document = gloo::utils::document();
    let scope: AnyScope = AnyScope::test();
    let parent_element = document.create_element("div").unwrap();
    let root = BSubtree::create_root(&parent_element);

    let end_node = document.create_text_node("END");
    parent_element.append_child(&end_node).unwrap();

    // Tests each layout independently
    let slot = DomSlot::at(end_node.into());
    for layout in layouts.iter() {
        // Apply the layout
        let vnode = layout.node.clone();
        log!("Independently apply layout '{}'", layout.name);

        let mut bundle = Bundle::new();
        bundle.reconcile(&root, &scope, &parent_element, slot.clone(), vnode);
        scheduler::start_now();
        assert_eq!(
            parent_element.inner_html(),
            format!("{}END", layout.expected),
            "Independent apply failed for layout '{}'",
            layout.name,
        );

        // Diff with no changes
        let vnode = layout.node.clone();

        log!("Independently reapply layout '{}'", layout.name);

        bundle.reconcile(&root, &scope, &parent_element, slot.clone(), vnode);
        scheduler::start_now();
        assert_eq!(
            parent_element.inner_html(),
            format!("{}END", layout.expected),
            "Independent reapply failed for layout '{}'",
            layout.name,
        );

        // Detach
        bundle.detach(&root, &parent_element, false);
        scheduler::start_now();
        assert_eq!(
            parent_element.inner_html(),
            "END",
            "Independent detach failed for layout '{}'",
            layout.name,
        );
    }

    // Sequentially apply each layout
    let mut bundle = Bundle::new();
    for layout in layouts.iter() {
        let next_vnode = layout.node.clone();

        log!("Sequentially apply layout '{}'", layout.name);
        bundle.reconcile(&root, &scope, &parent_element, slot.clone(), next_vnode);

        scheduler::start_now();
        assert_eq!(
            parent_element.inner_html(),
            format!("{}END", layout.expected),
            "Sequential apply failed for layout '{}'",
            layout.name,
        );
    }

    // Sequentially detach each layout
    for layout in layouts.into_iter().rev() {
        let next_vnode = layout.node.clone();

        log!("Sequentially detach layout '{}'", layout.name);
        bundle.reconcile(&root, &scope, &parent_element, slot.clone(), next_vnode);

        scheduler::start_now();
        assert_eq!(
            parent_element.inner_html(),
            format!("{}END", layout.expected),
            "Sequential detach failed for layout '{}'",
            layout.name,
        );
    }

    // Detach last layout
    bundle.detach(&root, &parent_element, false);
    scheduler::start_now();
    assert_eq!(
        parent_element.inner_html(),
        "END",
        "Failed to detach last layout"
    );
}