on master help sign in
port tests/web
commit5e28ad31272513aa4c8df9d733f8b33c162e0478 authorldesgoui <ldesgoui@ldesgoui.xyz> dateSat 30 Nov 2019, 18:41 (7 years ago) parent5b02cf8
8 files changed+297−193
Cargo.lock+121 Cargo.toml+1 tests/web/cached.rs+69−61 tests/web/events.rs+52−69 tests/web/js_api.rs+28−35 tests/web/keyed.rs+13−16 tests/web/main.rs+13−11 tests/web/render.rs−1
Cargo.lock+121
@@ -186,6 +186,7 @@ dependencies = [
186186 "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
187187 "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
188188 "dodrio-js-api 0.1.0",
189+ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
189190 "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
190191 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
191192 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -329,6 +330,88 @@ name = "futures"
329330version = "0.1.28"
330331source = "registry+https://github.com/rust-lang/crates.io-index"
331332
333+[[package]]
334+name = "futures"
335+version = "0.3.1"
336+source = "registry+https://github.com/rust-lang/crates.io-index"
337+dependencies = [
338+ "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
339+ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
340+ "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
341+ "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
342+ "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
343+ "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
344+ "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
345+]
346+
347+[[package]]
348+name = "futures-channel"
349+version = "0.3.1"
350+source = "registry+https://github.com/rust-lang/crates.io-index"
351+dependencies = [
352+ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
353+ "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
354+]
355+
356+[[package]]
357+name = "futures-core"
358+version = "0.3.1"
359+source = "registry+https://github.com/rust-lang/crates.io-index"
360+
361+[[package]]
362+name = "futures-executor"
363+version = "0.3.1"
364+source = "registry+https://github.com/rust-lang/crates.io-index"
365+dependencies = [
366+ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
367+ "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
368+ "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
369+]
370+
371+[[package]]
372+name = "futures-io"
373+version = "0.3.1"
374+source = "registry+https://github.com/rust-lang/crates.io-index"
375+
376+[[package]]
377+name = "futures-macro"
378+version = "0.3.1"
379+source = "registry+https://github.com/rust-lang/crates.io-index"
380+dependencies = [
381+ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
382+ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
383+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
384+ "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
385+]
386+
387+[[package]]
388+name = "futures-sink"
389+version = "0.3.1"
390+source = "registry+https://github.com/rust-lang/crates.io-index"
391+
392+[[package]]
393+name = "futures-task"
394+version = "0.3.1"
395+source = "registry+https://github.com/rust-lang/crates.io-index"
396+
397+[[package]]
398+name = "futures-util"
399+version = "0.3.1"
400+source = "registry+https://github.com/rust-lang/crates.io-index"
401+dependencies = [
402+ "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
403+ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
404+ "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
405+ "futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
406+ "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
407+ "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
408+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
409+ "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
410+ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
411+ "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
412+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
413+]
414+
332415[[package]]
333416name = "fxhash"
334417version = "0.2.1"
@@ -437,6 +520,26 @@ dependencies = [
437520 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
438521]
439522
523+[[package]]
524+name = "pin-utils"
525+version = "0.1.0-alpha.4"
526+source = "registry+https://github.com/rust-lang/crates.io-index"
527+
528+[[package]]
529+name = "proc-macro-hack"
530+version = "0.5.11"
531+source = "registry+https://github.com/rust-lang/crates.io-index"
532+dependencies = [
533+ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
534+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
535+ "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
536+]
537+
538+[[package]]
539+name = "proc-macro-nested"
540+version = "0.1.3"
541+source = "registry+https://github.com/rust-lang/crates.io-index"
542+
440543[[package]]
441544name = "proc-macro2"
442545version = "0.4.27"
@@ -609,6 +712,11 @@ dependencies = [
609712 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
610713]
611714
715+[[package]]
716+name = "slab"
717+version = "0.4.2"
718+source = "registry+https://github.com/rust-lang/crates.io-index"
719+
612720[[package]]
613721name = "sourcefile"
614722version = "0.1.4"
@@ -891,6 +999,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
891999"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
8921000"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
8931001"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
1002+"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987"
1003+"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86"
1004+"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866"
1005+"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231"
1006+"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff"
1007+"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764"
1008+"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16"
1009+"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9"
1010+"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
8941011"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
8951012"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
8961013"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
@@ -906,6 +1023,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
9061023"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
9071024"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
9081025"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
1026+"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
1027+"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
1028+"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
9091029"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
9101030"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
9111031"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
@@ -928,6 +1048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
9281048"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
9291049"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
9301050"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
1051+"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
9311052"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
9321053"checksum syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f89693ae015201f8de93fd96bde2d065f8bfc3f97ce006d5bc9f900b97c0c7c0"
9331054"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
Cargo.toml+1
@@ -66,6 +66,7 @@ features = [
6666[dev-dependencies]
6767console_log = "0.1.2"
6868dodrio-js-api = { version = "=0.1.0", path = "./crates/js-api" }
69+futures = "0.3.1"
6970log = "0.4.8"
7071wasm-bindgen-test = "0.3.5"
7172
tests/web/cached.rs+69−61
@@ -1,6 +1,5 @@
11use super::{assert_rendered, before_after, create_element, RenderFn};
22use dodrio::{builder::*, bumpalo, Cached, Node, Render, RenderContext, RootRender, Vdom};
3−use futures::prelude::*;
43use std::cell::Cell;
54use std::rc::Rc;
65use wasm_bindgen::prelude::*;
@@ -29,8 +28,8 @@ impl Render for CountRenders {
2928 }
3029}
3130
32−#[wasm_bindgen_test(async)]
33−fn uses_cached_render() -> impl Future<Item = (), Error = JsValue> {
31+#[wasm_bindgen_test]
32+async fn uses_cached_render() {
3433 use dodrio::builder::*;
3534
3635 let cached = Cached::new(CountRenders::new());
@@ -50,52 +49,61 @@ fn uses_cached_render() -> impl Future<Item = (), Error = JsValue> {
5049 let vdom6 = vdom0.clone();
5150 let vdom7 = vdom0.clone();
5251
52+ // We render, populate the cache, and get "1".
53+ vdom0.weak().render().await.unwrap();
5354 vdom0
5455 .weak()
55− // We render, populate the cache, and get "1".
56− .render()
57− .and_then(move |_| {
58− vdom0.weak().with_component(move |comp| {
59− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
60− assert_eq!(comp.render_count.get(), 1);
61− assert_rendered(&container1, &RenderFn(|_| text("1")));
62− })
56+ .with_component(move |comp| {
57+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
58+ assert_eq!(comp.render_count.get(), 1);
59+ assert_rendered(&container1, &RenderFn(|_| text("1")));
6360 })
64− // We re-render, re-use the cached node, and get "1" again.
65− .and_then(move |_| vdom1.weak().render())
66− .and_then(move |_| {
67− vdom2.weak().with_component(move |comp| {
68− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
69− assert_eq!(comp.render_count.get(), 1);
70− assert_rendered(&container2, &RenderFn(|_| text("1")));
71− })
61+ .await
62+ .unwrap();
63+
64+ // We re-render, re-use the cached node, and get "1" again.
65+ vdom1.weak().render().await.unwrap();
66+ vdom2
67+ .weak()
68+ .with_component(move |comp| {
69+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
70+ assert_eq!(comp.render_count.get(), 1);
71+ assert_rendered(&container2, &RenderFn(|_| text("1")));
7272 })
73− // We invalidate the cache, re-render, re-populate the cache, and should
74− // now have "2".
75− .and_then(move |_| {
76− vdom3.weak().with_component(move |comp| {
77− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
78− Cached::invalidate(comp);
79− })
73+ .await
74+ .unwrap();
75+
76+ // We invalidate the cache, re-render, re-populate the cache, and should now have "2".
77+ vdom3
78+ .weak()
79+ .with_component(move |comp| {
80+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
81+ Cached::invalidate(comp);
8082 })
81− .and_then(move |_| vdom4.weak().render())
82− .and_then(move |_| {
83− vdom5.weak().with_component(move |comp| {
84− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
85− assert_eq!(comp.render_count.get(), 2);
86− assert_rendered(&container3, &RenderFn(|_| text("2")));
87− })
83+ .await
84+ .unwrap();
85+ vdom4.weak().render().await.unwrap();
86+ vdom5
87+ .weak()
88+ .with_component(move |comp| {
89+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
90+ assert_eq!(comp.render_count.get(), 2);
91+ assert_rendered(&container3, &RenderFn(|_| text("2")));
8892 })
89− // We re-render, re-use the cached node, and get "2" again.
90− .and_then(move |_| vdom6.weak().render())
91− .and_then(move |_| {
92− vdom7.weak().with_component(move |comp| {
93− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
94− assert_eq!(comp.render_count.get(), 2);
95− assert_rendered(&container4, &RenderFn(|_| text("2")));
96− })
93+ .await
94+ .unwrap();
95+
96+ // We re-render, re-use the cached node, and get "2" again.
97+ vdom6.weak().render().await.unwrap();
98+ vdom7
99+ .weak()
100+ .with_component(move |comp| {
101+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
102+ assert_eq!(comp.render_count.get(), 2);
103+ assert_rendered(&container4, &RenderFn(|_| text("2")));
97104 })
98− .map_err(|e| JsValue::from(e.to_string()))
105+ .await
106+ .unwrap();
99107}
100108
101109#[wasm_bindgen(module = "/tests/web/cached.js")]
@@ -104,8 +112,8 @@ extern "C" {
104112 fn get_clone_node_count() -> u32;
105113}
106114
107−#[wasm_bindgen_test(async)]
108−fn creating_cached_nodes_uses_clone_node() -> impl Future<Item = (), Error = JsValue> {
115+#[wasm_bindgen_test]
116+async fn creating_cached_nodes_uses_clone_node() {
109117 use dodrio::builder::*;
110118
111119 let container = create_element("div");
@@ -113,28 +121,28 @@ fn creating_cached_nodes_uses_clone_node() -> impl Future<Item = (), Error = JsV
113121 // The initial vdom render should populate the cache and save a template.
114122 let vdom0 = Rc::new(Vdom::new(&container, Cached::new(CountRenders::new())));
115123 let vdom1 = vdom0.clone();
116− let vdom2 = vdom0.clone();
124+ let _vdom2 = vdom0.clone();
117125
118126 let clone_node_count_before = get_clone_node_count();
119127
128+ // Render something entirely different...
120129 vdom0
121130 .weak()
122− // Render something entirely different...
123− .set_component(Box::new(RenderFn(|_| text("hi"))) as Box<RootRender>)
124− .and_then(move |_| {
125− // Re-render our cached node. Since we are creating it from scratch,
126− // and already have a template from the earlier render, we should
127− // call `cloneNode` here.
128− vdom1
129− .weak()
130− .set_component(Box::new(Cached::new(CountRenders::new())) as Box<RootRender>)
131− })
132− .map(move |_| {
133− let clone_node_count_after = get_clone_node_count();
134− assert_eq!(clone_node_count_after, clone_node_count_before + 1);
135− drop(vdom2);
136− })
137− .map_err(|e| JsValue::from(e.to_string()))
131+ .set_component(Box::new(RenderFn(|_| text("hi"))) as Box<dyn RootRender>)
132+ .await
133+ .unwrap();
134+
135+ // Re-render our cached node. Since we are creating it from scratch,
136+ // and already have a template from the earlier render, we should
137+ // call `cloneNode` here.
138+ vdom1
139+ .weak()
140+ .set_component(Box::new(Cached::new(CountRenders::new())) as Box<dyn RootRender>)
141+ .await
142+ .unwrap();
143+
144+ let clone_node_count_after = get_clone_node_count();
145+ assert_eq!(clone_node_count_after, clone_node_count_before + 1);
138146}
139147
140148struct Id(&'static str);
tests/web/events.rs+52−69
@@ -1,6 +1,6 @@
11use super::create_element;
22use dodrio::{Node, Render, RenderContext, Vdom};
3−use futures::Future;
3+use futures::future::{select, Either};
44use std::cell::{Cell, RefCell};
55use std::rc::Rc;
66use wasm_bindgen::prelude::*;
@@ -9,7 +9,7 @@ use wasm_bindgen_test::*;
99
1010struct EventContainer {
1111 event: &'static str,
12− on_event: Box<FnMut()>,
12+ on_event: Box<dyn FnMut()>,
1313}
1414
1515impl EventContainer {
@@ -44,14 +44,14 @@ fn target(container: &web_sys::Element) -> web_sys::HtmlElement {
4444 .unchecked_into()
4545}
4646
47−#[wasm_bindgen_test(async)]
48−fn click() -> impl Future<Item = (), Error = JsValue> {
47+#[wasm_bindgen_test]
48+async fn click() {
4949 let container = create_element("div");
5050
51− let (sender, receiver) = futures::sync::oneshot::channel();
51+ let (sender, receiver) = futures::channel::oneshot::channel();
5252 let mut sender = Some(sender);
5353
54− let vdom = Vdom::new(
54+ let _vdom = Vdom::new(
5555 &container,
5656 EventContainer::new("click", move || {
5757 sender
@@ -64,18 +64,14 @@ fn click() -> impl Future<Item = (), Error = JsValue> {
6464
6565 target(&container).click();
6666
67− receiver
68− .map(|_| {
69− drop(vdom);
70− })
71− .map_err(|e| JsValue::from(e.to_string()))
67+ receiver.await.unwrap();
7268}
7369
74−#[wasm_bindgen_test(async)]
75−fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
70+#[wasm_bindgen_test]
71+async fn updated_listener_is_called() {
7672 let container = create_element("div");
7773
78− let (first_sender, first_receiver) = futures::sync::oneshot::channel();
74+ let (first_sender, first_receiver) = futures::channel::oneshot::channel();
7975 let mut first_sender = Some(first_sender);
8076
8177 let vdom = Vdom::new(
@@ -89,7 +85,7 @@ fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
8985 }),
9086 );
9187
92− let (second_sender, second_receiver) = futures::sync::oneshot::channel();
88+ let (second_sender, second_receiver) = futures::channel::oneshot::channel();
9389 let mut second_sender = Some(second_sender);
9490
9591 vdom.weak()
@@ -100,25 +96,22 @@ fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
10096 .send("second")
10197 .expect_throw("should not have dropped the receiver");
10298 })))
103− .map_err(|e| JsValue::from(e.to_string()))
104− .and_then(move |_| {
105− target(&container).click();
106−
107− first_receiver
108− .select(second_receiver)
109− .map(|(which, _other)| which)
110− .or_else(|(_error, other)| other)
111− .map(|which| {
112− assert_eq!(which, "second");
113− drop(vdom);
114− })
115− .map_err(|e| JsValue::from(e.to_string()))
116− })
99+ .await
100+ .unwrap();
101+
102+ target(&container).click();
103+
104+ match select(first_receiver, second_receiver).await {
105+ Either::Left((Ok(_), _)) => panic!(),
106+ Either::Left((Err(_), second)) => assert_eq!(second.await, Ok("second")),
107+ Either::Right((Ok(msg), _)) => assert_eq!(msg, "second"),
108+ Either::Right((Err(_), _)) => panic!(),
109+ }
117110}
118111
119112struct ListensOnlyOnFirstRender {
120113 count: Cell<usize>,
121− callback: Box<FnMut()>,
114+ callback: Box<dyn FnMut()>,
122115}
123116
124117impl ListensOnlyOnFirstRender {
@@ -150,11 +143,11 @@ impl Render for ListensOnlyOnFirstRender {
150143 }
151144}
152145
153−#[wasm_bindgen_test(async)]
154−fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
146+#[wasm_bindgen_test]
147+async fn removed_listener_is_not_called() {
155148 let container = create_element("div");
156149
157− let (outer_sender, outer_receiver) = futures::sync::oneshot::channel();
150+ let (outer_sender, outer_receiver) = futures::channel::oneshot::channel();
158151 let outer_sender = Rc::new(RefCell::new(Some(outer_sender)));
159152 let outer_listener = Closure::wrap(Box::new(move |_| {
160153 outer_sender
@@ -163,13 +156,13 @@ fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
163156 .expect_throw("should only invoke outer_listener once")
164157 .send("outer")
165158 .expect_throw("should not have dropped receiver");
166− }) as Box<FnMut(web_sys::Event)>);
159+ }) as Box<dyn FnMut(web_sys::Event)>);
167160
168161 container
169162 .add_event_listener_with_callback("click", outer_listener.as_ref().unchecked_ref())
170163 .unwrap();
171164
172− let (vdom_sender, vdom_receiver) = futures::sync::oneshot::channel();
165+ let (vdom_sender, vdom_receiver) = futures::channel::oneshot::channel();
173166 let mut vdom_sender = Some(vdom_sender);
174167
175168 // Render a vdom with a listener into container.
@@ -184,33 +177,26 @@ fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
184177 }),
185178 );
186179
187− vdom.weak()
188− // Re-render, so we aren't listening anymore.
189− .render()
190− .map_err(|e| JsValue::from(e.to_string()))
191− .and_then(move |_| {
192− target(&container).click();
193−
194− // We should get our container's event handler fired, and not the unmounted
195− // vdom's event handler.
196− outer_receiver
197− .select(vdom_receiver)
198− .map(|(which, _other)| which)
199− .or_else(|(_error, other)| other)
200− .map(|which| {
201− assert_eq!(which, "outer");
202− drop(outer_listener);
203− drop(vdom)
204− })
205− .map_err(|e| JsValue::from(e.to_string()))
206− })
180+ // Re-render, so we aren't listening anymore.
181+ vdom.weak().render().await.unwrap();
182+
183+ target(&container).click();
184+
185+ // We should get our container's event handler fired, and not the unmounted
186+ // vdom's event handler.
187+ match select(outer_receiver, vdom_receiver).await {
188+ Either::Left((Ok(msg), _)) => assert_eq!(msg, ("outer")),
189+ Either::Left((Err(_), _)) => panic!(),
190+ Either::Right((Ok(_), _)) => panic!(),
191+ Either::Right((Err(_), outer)) => assert_eq!(outer.await, Ok("outer")),
192+ }
207193}
208194
209−#[wasm_bindgen_test(async)]
210−fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsValue> {
195+#[wasm_bindgen_test]
196+async fn event_does_not_fire_after_unmounting() {
211197 let container = create_element("div");
212198
213− let (outer_sender, outer_receiver) = futures::sync::oneshot::channel();
199+ let (outer_sender, outer_receiver) = futures::channel::oneshot::channel();
214200 let outer_sender = Rc::new(RefCell::new(Some(outer_sender)));
215201 let outer_listener = Closure::wrap(Box::new(move |_| {
216202 outer_sender
@@ -219,13 +205,13 @@ fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsVa
219205 .expect_throw("should only invoke outer_listener once")
220206 .send("outer")
221207 .expect_throw("should not have dropped receiver");
222− }) as Box<FnMut(web_sys::Event)>);
208+ }) as Box<dyn FnMut(web_sys::Event)>);
223209
224210 container
225211 .add_event_listener_with_callback("click", outer_listener.as_ref().unchecked_ref())
226212 .unwrap();
227213
228− let (vdom_sender, vdom_receiver) = futures::sync::oneshot::channel();
214+ let (vdom_sender, vdom_receiver) = futures::channel::oneshot::channel();
229215 let mut vdom_sender = Some(vdom_sender);
230216
231217 // Render a vdom with a listener into container.
@@ -255,13 +241,10 @@ fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsVa
255241
256242 // We should get our container's event handler fired, and not the unmounted
257243 // vdom's event handler.
258− outer_receiver
259− .select(vdom_receiver)
260− .map(|(which, _other)| which)
261− .or_else(|(_error, other)| other)
262− .map(|which| {
263− assert_eq!(which, "outer");
264− drop(outer_listener);
265− })
266− .map_err(|e| JsValue::from(e.to_string()))
244+ match select(outer_receiver, vdom_receiver).await {
245+ Either::Left((Ok(msg), _)) => assert_eq!(msg, ("outer")),
246+ Either::Left((Err(_), _)) => panic!(),
247+ Either::Right((Ok(_), _)) => panic!(),
248+ Either::Right((Err(_), outer)) => assert_eq!(outer.await, Ok("outer")),
249+ }
267250}
tests/web/js_api.rs+28−35
@@ -1,8 +1,7 @@
11use super::{assert_rendered, create_element, RenderFn};
22use dodrio::{builder::*, Node, Render, RenderContext, Vdom};
33use dodrio_js_api::JsRender;
4−use futures::prelude::*;
5−use futures::sync::oneshot;
4+use futures::channel::oneshot;
65use js_sys::Object;
76use std::rc::Rc;
87use wasm_bindgen::prelude::*;
@@ -14,7 +13,7 @@ pub struct WrapJs {
1413}
1514
1615impl WrapJs {
17− pub fn new() -> (WrapJs, oneshot::Receiver<()>, Closure<FnMut()>) {
16+ pub fn new() -> (WrapJs, oneshot::Receiver<()>, Closure<dyn FnMut()>) {
1817 let (sender, receiver) = oneshot::channel();
1918
2019 let on_after_render = Closure::wrap(Box::new({
@@ -26,7 +25,7 @@ impl WrapJs {
2625 .send(())
2726 .expect_throw("receiver should not have been dropped");
2827 }
29− }) as Box<FnMut()>);
28+ }) as Box<dyn FnMut()>);
3029
3130 let component = WrapJs {
3231 inner: JsRender::new(JsComponent::new(&on_after_render)),
@@ -52,7 +51,7 @@ extern "C" {
5251 type JsComponent;
5352
5453 #[wasm_bindgen(constructor)]
55− fn new(on_after_render: &Closure<FnMut()>) -> JsComponent;
54+ fn new(on_after_render: &Closure<dyn FnMut()>) -> JsComponent;
5655}
5756
5857fn eval_js_rendering_component() {
@@ -96,14 +95,14 @@ fn eval_js_rendering_component() {
9695 });
9796}
9897
99−#[wasm_bindgen_test(async)]
100−fn can_use_js_rendering_components() -> impl Future<Item = (), Error = JsValue> {
98+#[wasm_bindgen_test]
99+async fn can_use_js_rendering_components() {
101100 eval_js_rendering_component();
102101
103102 let container = create_element("div");
104− let (component, receiver, closure) = WrapJs::new();
103+ let (component, receiver, _closure) = WrapJs::new();
104+ let _vdom = Rc::new(Vdom::new(&container, component));
105105
106− let vdom = Rc::new(Vdom::new(&container, component));
107106 assert_rendered(
108107 &container,
109108 &RenderFn(|cx| {
@@ -131,30 +130,24 @@ fn can_use_js_rendering_components() -> impl Future<Item = (), Error = JsValue>
131130 .expect_throw("should be an `HTMLElement` object")
132131 .click();
133132
134− receiver
135− .map(move |_| {
136− assert_rendered(
137− &container,
138− &RenderFn(|cx| {
139− div(&cx)
140− .attr("class", "wrap-js")
141− .children([span(&cx)
142− .attr("class", "js-component")
143− .children([
144− text("Here is some plain text"),
145− b(&cx)
146− .children([text("...and here is some bold text")])
147− .finish(),
148− text("1"),
149− ])
150− .finish()])
151− .finish()
152− }),
153− );
154−
155− drop(vdom);
156− drop(container);
157− drop(closure);
158− })
159− .map_err(|e| e.to_string().into())
133+ receiver.await.unwrap();
134+
135+ assert_rendered(
136+ &container,
137+ &RenderFn(|cx| {
138+ div(&cx)
139+ .attr("class", "wrap-js")
140+ .children([span(&cx)
141+ .attr("class", "js-component")
142+ .children([
143+ text("Here is some plain text"),
144+ b(&cx)
145+ .children([text("...and here is some bold text")])
146+ .finish(),
147+ text("1"),
148+ ])
149+ .finish()])
150+ .finish()
151+ }),
152+ );
160153}
tests/web/keyed.rs+13−16
@@ -1,6 +1,5 @@
11use crate::{assert_rendered, create_element};
22use dodrio::{builder::*, bumpalo, Node, Render, RenderContext, Vdom};
3−use futures::Future;
43use log::*;
54use std::rc::Rc;
65use wasm_bindgen::prelude::*;
@@ -32,10 +31,7 @@ where
3231 parent.finish()
3332}
3433
35−fn assert_keyed<Before, After>(
36− before: Before,
37− after: After,
38−) -> impl Future<Item = (), Error = JsValue>
34+async fn assert_keyed<Before, After>(before: Before, after: After) -> Result<(), JsValue>
3935where
4036 Before: 'static + Render,
4137 After: 'static + Render,
@@ -56,7 +52,7 @@ where
5652
5753 debug!("====== Rendering the *before* DOM into the physical DOM ======");
5854 let vdom1 = Rc::new(Vdom::new(&container, before.clone()));
59− let vdom2 = vdom1.clone();
55+ let _vdom2 = vdom1.clone();
6056 let saved = save_keyed_elements(&container);
6157
6258 debug!("====== Checking the *before* DOM against the physical DOM ======");
@@ -65,13 +61,14 @@ where
6561 debug!("====== Rendering the *after* DOM into the physical DOM ======");
6662 let weak = vdom1.weak();
6763 weak.set_component(Box::new(after.clone()))
68− .map(move |_| {
69− debug!("====== Checking the *after* DOM against the physical DOM ======");
70− assert_rendered(&container, &after);
71− check_keyed_elements(&container, saved);
72− drop(vdom2);
73− })
74− .map_err(|e| JsValue::from(e.to_string()))
64+ .await
65+ .map_err(|e| e.to_string())?;
66+
67+ debug!("====== Checking the *after* DOM against the physical DOM ======");
68+ assert_rendered(&container, &after);
69+ check_keyed_elements(&container, saved);
70+
71+ Ok(())
7572}
7673
7774macro_rules! keyed_tests {
@@ -86,14 +83,14 @@ macro_rules! keyed_tests {
8683 }
8784 )* ) => {
8885 $(
89− #[wasm_bindgen_test(async)]
90− fn $name() -> impl Future<Item = (), Error = wasm_bindgen::JsValue> {
86+ #[wasm_bindgen_test]
87+ async fn $name() {
9188 use crate::RenderFn;
9289 log::debug!("############### {} ###############", stringify!($name));
9390 assert_keyed(
9491 RenderFn(|$before_cx| { $( $before )* }),
9592 RenderFn(|$after_cx| { $( $after )* }),
96− )
93+ ).await.unwrap()
9794 }
9895 )*
9996 }
tests/web/main.rs+13−11
@@ -6,7 +6,6 @@ use bumpalo::Bump;
66use dodrio::{
77 Attribute, CachedSet, ElementNode, Node, NodeKind, Render, RenderContext, TextNode, Vdom,
88};
9−use futures::prelude::*;
109use fxhash::FxHashMap;
1110use log::*;
1211use std::cell::RefCell;
@@ -168,7 +167,7 @@ where
168167/// Assert that if we start by rendering the `before` virtual DOM tree into a
169168/// physical DOM tree, and then diff it with the `after` virtual DOM tree, then
170169/// the physical DOM tree correctly matches `after`.
171−pub fn assert_before_after<R, S>(before: R, after: S) -> impl Future<Item = (), Error = JsValue>
170+pub async fn assert_before_after<R, S>(before: R, after: S) -> Result<(), JsValue>
172171where
173172 R: 'static + Render,
174173 S: 'static + Render,
@@ -180,7 +179,7 @@ where
180179
181180 debug!("====== Rendering the *before* DOM into the physical DOM ======");
182181 let vdom1 = Rc::new(Vdom::new(&container, before.clone()));
183− let vdom2 = vdom1.clone();
182+ let _vdom2 = vdom1.clone();
184183
185184 debug!("====== Checking the *before* DOM against the physical DOM ======");
186185 assert_rendered(&container, &before);
@@ -188,12 +187,13 @@ where
188187 debug!("====== Rendering the *after* DOM into the physical DOM ======");
189188 let weak = vdom1.weak();
190189 weak.set_component(Box::new(after.clone()))
191− .map(move |_| {
192− debug!("====== Checking the *after* DOM against the physical DOM ======");
193− assert_rendered(&container, &after);
194− drop(vdom2);
195− })
196− .map_err(|e| JsValue::from(e.to_string()))
190+ .await
191+ .map_err(|e| e.to_string())?;
192+
193+ debug!("====== Checking the *after* DOM against the physical DOM ======");
194+ assert_rendered(&container, &after);
195+
196+ Ok(())
197197}
198198
199199/// A helper macro for declaring a bunch of `assert_before_after` tests.
@@ -210,14 +210,16 @@ macro_rules! before_after {
210210 }
211211 )* ) => {
212212 $(
213− #[wasm_bindgen_test(async)]
214− fn $name() -> impl Future<Item = (), Error = wasm_bindgen::JsValue> {
213+ #[wasm_bindgen_test]
214+ async fn $name() {
215215 use crate::{assert_before_after, RenderFn};
216216 log::debug!("############### {} ###############", stringify!($name));
217217 assert_before_after(
218218 RenderFn(|$before_bump| { $( $before )* }),
219219 RenderFn(|$after_bump| { $( $after )* })
220220 )
221+ .await
222+ .unwrap()
221223 }
222224 )*
223225 }
tests/web/render.rs−1
@@ -1,6 +1,5 @@
11use super::{assert_rendered, before_after, create_element, RenderFn};
22use dodrio::{builder::*, Vdom};
3−use futures::prelude::*;
43use std::rc::Rc;
54use wasm_bindgen_test::*;
65