Feat: docs, code frm percy
This commit is contained in:
commit
2b9c8d09d9
72 files changed
+5130
No files matched your search
@@ -0,0 +1,116 @@
|
||||
//! Ensure that our DomUpdater maintains Rc's to closures so that they work even
|
||||
//! after dropping virtual dom nodes.
|
||||
//!
|
||||
//! To run all tests in this file:
|
||||
//!
|
||||
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test closures
|
||||
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::rc::Rc;
|
||||
use virtual_dom_rs::prelude::*;
|
||||
use virtual_dom_rs::DomUpdater;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_test;
|
||||
use wasm_bindgen_test::*;
|
||||
use web_sys::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
// TODO: This test current fails in headless browsers but works in non headless browsers
|
||||
// (tested in both geckodriver and chromedriver)
|
||||
// Need to figure out why
|
||||
#[wasm_bindgen_test]
|
||||
fn closure_not_dropped() {
|
||||
let text = Rc::new(RefCell::new("Start Text".to_string()));
|
||||
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
|
||||
let mut dom_updater = None;
|
||||
|
||||
{
|
||||
let mut input = make_input_component(Rc::clone(&text));
|
||||
input
|
||||
.as_velement_mut()
|
||||
.expect("Not an element")
|
||||
.attrs
|
||||
.insert("id".into(), "old-input-elem".into());
|
||||
|
||||
let mount = document.create_element("div").unwrap();
|
||||
mount.set_id("mount");
|
||||
document.body().unwrap().append_child(&mount).unwrap();
|
||||
|
||||
dom_updater = Some(DomUpdater::new_replace_mount(input, mount));
|
||||
|
||||
let mut dom_updater = dom_updater.as_mut().unwrap();
|
||||
|
||||
// Input VirtualNode from above gets dropped at the end of this block,
|
||||
// yet that element held Rc's to the Closure's that power the oninput event.
|
||||
//
|
||||
// We're patching the DOM with a new vdom, but since our new vdom doesn't contain any
|
||||
// new elements, `.create_element` won't get called and so no new Closures will be
|
||||
// created.
|
||||
//
|
||||
// So, we're testing that our old Closure's still work. The reason that they work is
|
||||
// that dom_updater maintains Rc's to those Closures.
|
||||
let mut new_node = make_input_component(Rc::clone(&text));
|
||||
new_node
|
||||
.as_velement_mut()
|
||||
.expect("Not an element")
|
||||
.attrs
|
||||
.insert("id".into(), "new-input-elem".into());
|
||||
|
||||
dom_updater.update(new_node);
|
||||
}
|
||||
|
||||
let dom_updater = dom_updater.as_ref().unwrap();
|
||||
|
||||
let input: HtmlInputElement = document
|
||||
.get_element_by_id("new-input-elem")
|
||||
.expect("Input element")
|
||||
.dyn_into()
|
||||
.unwrap();
|
||||
let input_event = InputEvent::new("input").unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "Start Text");
|
||||
|
||||
// After dispatching the oninput event our `text` should have a value of the input elements value.
|
||||
web_sys::EventTarget::from(input)
|
||||
.dispatch_event(&input_event)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "End Text");
|
||||
|
||||
assert_eq!(
|
||||
dom_updater.active_closures.get(&1).as_ref().unwrap().len(),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
// We're just making sure that things compile - other tests give us confidence that the closure
|
||||
// will work just fine.
|
||||
//
|
||||
// https://github.com/chinedufn/percy/issues/81
|
||||
//
|
||||
//#[wasm_bindgen_test]
|
||||
//fn closure_with_no_params_compiles() {
|
||||
// let _making_sure_this_works = html! {
|
||||
// <div onclick=|| {}></div>
|
||||
// };
|
||||
//}
|
||||
|
||||
fn make_input_component(text_clone: Rc<RefCell<String>>) -> VirtualNode {
|
||||
html! {
|
||||
<input
|
||||
// On input we'll set our Rc<RefCell<String>> value to the input elements value
|
||||
oninput=move |event: Event| {
|
||||
let input_elem = event.target().unwrap();
|
||||
let input_elem = input_elem.dyn_into::<HtmlInputElement>().unwrap();
|
||||
*text_clone.borrow_mut() = input_elem.value();
|
||||
}
|
||||
value="End Text"
|
||||
>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//! Tests that ensure that we create the right DOM element from a VirtualNode
|
||||
//!
|
||||
//! To run all tests in this file:
|
||||
//!
|
||||
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element
|
||||
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
extern crate web_sys;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_test::*;
|
||||
use web_sys::{Element, Event, EventTarget, MouseEvent};
|
||||
|
||||
use virtual_dom_rs::prelude::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element nested_divs
|
||||
#[wasm_bindgen_test]
|
||||
fn nested_divs() {
|
||||
let vdiv = html! { <div> <div> <div></div> </div> </div> };
|
||||
let div: Element = vdiv.create_dom_node().node.unchecked_into();
|
||||
|
||||
assert_eq!(&div.inner_html(), "<div><div></div></div>");
|
||||
}
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element svg_element
|
||||
/// TODO: Temporarily disabled until we figure out why it's failing in CI but not failing locally
|
||||
// #[wasm_bindgen_test]
|
||||
// fn svg_element() {
|
||||
// let vdiv = html! { <div><svg xmlns="http://www.w3.org/2000/svg">
|
||||
// <circle cx="50" cy="50" r="50"/>
|
||||
// </svg></div> };
|
||||
// let div: Element = vdiv.create_dom_node().node.unchecked_into();
|
||||
|
||||
// assert_eq!(
|
||||
// &div.inner_html(),
|
||||
// r#"<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"></circle></svg>"#
|
||||
// );
|
||||
// }
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element div_with_attributes
|
||||
#[wasm_bindgen_test]
|
||||
fn div_with_attributes() {
|
||||
let vdiv = html! { <div id="id-here" class="two classes"></div> };
|
||||
let div: Element = vdiv.create_dom_node().node.unchecked_into();
|
||||
|
||||
assert_eq!(&div.id(), "id-here");
|
||||
|
||||
assert!(div.class_list().contains("two"));
|
||||
assert!(div.class_list().contains("classes"));
|
||||
|
||||
assert_eq!(div.class_list().length(), 2);
|
||||
}
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element click_event
|
||||
#[wasm_bindgen_test]
|
||||
fn click_event() {
|
||||
let clicked = Rc::new(Cell::new(false));
|
||||
let clicked_clone = Rc::clone(&clicked);
|
||||
|
||||
let div = html! {
|
||||
<div
|
||||
onclick=move |_ev: MouseEvent| {
|
||||
clicked_clone.set(true);
|
||||
}
|
||||
>
|
||||
</div>
|
||||
};
|
||||
|
||||
let click_event = Event::new("click").unwrap();
|
||||
|
||||
let div = div.create_dom_node().node;
|
||||
|
||||
(EventTarget::from(div))
|
||||
.dispatch_event(&click_event)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(*clicked, Cell::new(true));
|
||||
}
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element inner_html
|
||||
/// @book start inner-html
|
||||
#[wasm_bindgen_test]
|
||||
fn inner_html() {
|
||||
let div = html! {
|
||||
<div
|
||||
unsafe_inner_html="<span>hi</span>"
|
||||
>
|
||||
</div>
|
||||
};
|
||||
let div: Element = div.create_dom_node().node.unchecked_into();
|
||||
|
||||
assert_eq!(div.inner_html(), "<span>hi</span>");
|
||||
}
|
||||
// @book end inner-html
|
||||
|
||||
/// wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element on_create_elem
|
||||
/// @book start on-create-elem
|
||||
#[wasm_bindgen_test]
|
||||
fn on_create_elem() {
|
||||
let div = html! {
|
||||
<div
|
||||
on_create_elem=|elem: web_sys::Element| {
|
||||
elem.set_inner_html("Hello world");
|
||||
}
|
||||
>
|
||||
<span>This span should get replaced</span>
|
||||
</div>
|
||||
};
|
||||
let div: Element = div.create_dom_node().node.unchecked_into();
|
||||
|
||||
assert_eq!(div.inner_html(), "Hello world");
|
||||
}
|
||||
// @book end on-create-elem
|
||||
@@ -0,0 +1,197 @@
|
||||
//! Tests that ensure that diffing and patching work properly in a real browser.
|
||||
//!
|
||||
//! To run all tests in this file:
|
||||
//!
|
||||
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test diff_patch
|
||||
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
extern crate web_sys;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
use virtual_dom_rs::prelude::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
mod diff_patch_test_case;
|
||||
use self::diff_patch_test_case::DiffPatchTest;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn replace_child() {
|
||||
DiffPatchTest {
|
||||
desc: "Replace a root node attribute attribute and a child text node",
|
||||
old: html! {
|
||||
<div>
|
||||
Original element
|
||||
</div>
|
||||
},
|
||||
new: html! { <div> Patched element</div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn truncate_children() {
|
||||
DiffPatchTest {
|
||||
desc: "Truncates extra children",
|
||||
old: html! {
|
||||
<div>
|
||||
<div> <div> <b></b> <em></em> </div> </div>
|
||||
</div>
|
||||
},
|
||||
new: html! {
|
||||
<div>
|
||||
<div> <div> <b></b> </div> </div>
|
||||
</div>
|
||||
},
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
|
||||
DiffPatchTest {
|
||||
desc: "https://github.com/chinedufn/percy/issues/48",
|
||||
old: html! {
|
||||
<div>
|
||||
ab <p></p> c
|
||||
</div>
|
||||
},
|
||||
new: html! {
|
||||
<div>
|
||||
ab <p></p>
|
||||
</div>
|
||||
},
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn remove_attributes() {
|
||||
DiffPatchTest {
|
||||
desc: "Removes attributes",
|
||||
old: html! { <div style=""> </div>
|
||||
},
|
||||
new: html! { <div></div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn append_children() {
|
||||
DiffPatchTest {
|
||||
desc: "Append a child node",
|
||||
old: html! { <div> </div>
|
||||
},
|
||||
new: html! { <div> <span></span> </div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn text_node_siblings() {
|
||||
// NOTE: Since there are two text nodes next to eachother we expect a `<!--ptns-->` separator in
|
||||
// between them.
|
||||
// @see virtual_node/mod.rs -> create_dom_node() for more information
|
||||
// TODO: A little more spacing than there should be in between the text nodes ... but doesn't
|
||||
// impact the user experience so we can look into that later..
|
||||
let override_expected = Some(
|
||||
r#"<div id="after"><span> The button has been clicked: <!--ptns--> world </span></div>"#,
|
||||
);
|
||||
|
||||
let old1 = VirtualNode::text("The button has been clicked: ");
|
||||
let old2 = VirtualNode::text("hello");
|
||||
|
||||
let new1 = VirtualNode::text("The button has been clicked: ");
|
||||
let new2 = VirtualNode::text("world");
|
||||
|
||||
DiffPatchTest {
|
||||
desc: "Diff patch on text node siblings",
|
||||
old: html! {
|
||||
<div id="before">
|
||||
<span> { {old1} {old2} } </span>
|
||||
</div>
|
||||
},
|
||||
new: html! {
|
||||
<div id="after">
|
||||
<span> { {new1} {new2} } </span>
|
||||
</div>
|
||||
},
|
||||
override_expected,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn append_text_node() {
|
||||
DiffPatchTest {
|
||||
desc: "Append text node",
|
||||
old: html! { <div> </div> },
|
||||
new: html! { <div> Hello </div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn append_sibling_text_nodes() {
|
||||
let text1 = VirtualNode::text("Hello");
|
||||
let text2 = VirtualNode::text("World");
|
||||
|
||||
DiffPatchTest {
|
||||
desc: "Append sibling text nodes",
|
||||
old: html! { <div> </div> },
|
||||
new: html! { <div> {text1} {text2} </div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn replace_with_children() {
|
||||
DiffPatchTest {
|
||||
desc: "Replace node that has children",
|
||||
old: html! { <table><tr><th>0</th></tr><tr><td>1</td></tr></table> },
|
||||
new: html! { <table><tr><td>2</td></tr><tr><th>3</th></tr></table> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
// https://github.com/chinedufn/percy/issues/62
|
||||
#[wasm_bindgen_test]
|
||||
fn replace_element_with_text_node() {
|
||||
DiffPatchTest {
|
||||
desc: "#62: Replace element with text node",
|
||||
old: html! { <span> <br> </span> },
|
||||
new: html! { <span> a </span> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
// https://github.com/chinedufn/percy/issues/68
|
||||
#[wasm_bindgen_test]
|
||||
fn text_root_node() {
|
||||
DiffPatchTest {
|
||||
desc: "Patching of text root node works",
|
||||
old: html! { Old text },
|
||||
new: html! { New text },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn replace_text_with_element() {
|
||||
DiffPatchTest {
|
||||
desc: "Replacing a text node with an element works",
|
||||
old: html! { <div>a</div> },
|
||||
new: html! { <div><br></div> },
|
||||
override_expected: None,
|
||||
}
|
||||
.test();
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//! Kept in its own file to more easily import into the book
|
||||
|
||||
use console_error_panic_hook;
|
||||
use virtual_dom_rs::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{Element, Node};
|
||||
|
||||
/// A test case that both diffing and patching are working in a real browser
|
||||
pub struct DiffPatchTest<'a> {
|
||||
/// Description of the test case.
|
||||
pub desc: &'static str,
|
||||
/// The old virtual node.
|
||||
pub old: VirtualNode,
|
||||
/// The new virtual node.
|
||||
pub new: VirtualNode,
|
||||
/// By default we generate the expected based on `new.to_string()`. You can
|
||||
/// use this field to override the expected HTML after patching.
|
||||
pub override_expected: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> DiffPatchTest<'a> {
|
||||
pub fn test(&mut self) {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
|
||||
// Create a DOM node of the virtual root node
|
||||
let root_node: Node = self.old.create_dom_node().node;
|
||||
|
||||
// Clone since virtual_dom_rs::patch takes ownership of the root node.
|
||||
let patched_root_node: Node = root_node.clone();
|
||||
|
||||
// Generate patches
|
||||
let patches = virtual_dom_rs::diff(&self.old, &self.new);
|
||||
|
||||
// Patch our root node. It should now look like `self.new`
|
||||
virtual_dom_rs::patch(root_node, &patches);
|
||||
|
||||
// Determine the expected outer HTML
|
||||
let expected_outer_html = match self.override_expected {
|
||||
Some(ref expected) => expected.to_string(),
|
||||
None => self.new.to_string(),
|
||||
};
|
||||
|
||||
let actual_outer_html = match patched_root_node.node_type() {
|
||||
Node::ELEMENT_NODE => patched_root_node.unchecked_into::<Element>().outer_html(),
|
||||
Node::TEXT_NODE => patched_root_node.text_content().unwrap_or("".into()),
|
||||
_ => panic!("Unhandled node type"),
|
||||
};
|
||||
|
||||
assert_eq!(&actual_outer_html, &expected_outer_html, "{}", self.desc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
//! Ensure that our DomUpdater maintains Rc's to closures so that they work even
|
||||
//! after dropping virtual dom nodes.
|
||||
//!
|
||||
//! To run all tests in this file:
|
||||
//!
|
||||
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test dom_updater
|
||||
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
|
||||
use console_error_panic_hook;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use virtual_dom_rs::prelude::*;
|
||||
use virtual_dom_rs::DomUpdater;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_test;
|
||||
use wasm_bindgen_test::*;
|
||||
use web_sys::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
// Verify that our DomUpdater's patch method works.
|
||||
// We test a simple case here, since diff_patch.rs is responsible for testing more complex
|
||||
// diffing and patching.
|
||||
#[wasm_bindgen_test]
|
||||
fn patches_dom() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
|
||||
let vdom = html! { <div></div> };
|
||||
|
||||
let mut dom_updater = DomUpdater::new(vdom);
|
||||
|
||||
let new_vdom = html! { <div id="patched"></div> };
|
||||
dom_updater.update(new_vdom);
|
||||
|
||||
document
|
||||
.body()
|
||||
.unwrap()
|
||||
.append_child(&dom_updater.root_node());
|
||||
assert_eq!(document.query_selector("#patched").unwrap().is_some(), true);
|
||||
}
|
||||
|
||||
// When you replace a DOM node with another DOM node we need to make sure that the closures
|
||||
// from the new DOM node are stored by the DomUpdater otherwise they'll get dropped and
|
||||
// won't work.
|
||||
#[wasm_bindgen_test]
|
||||
fn updates_active_closure_on_replace() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
let body = document.body().unwrap();
|
||||
|
||||
let old = html! { <div> </div> };
|
||||
let mut dom_updater = DomUpdater::new_append_to_mount(old, &body);
|
||||
|
||||
let text = Rc::new(RefCell::new("Start Text".to_string()));
|
||||
let text_clone = Rc::clone(&text);
|
||||
|
||||
let id = "update-active-closures-on-replace";
|
||||
|
||||
{
|
||||
let replace_node = html! {
|
||||
<input
|
||||
id=id
|
||||
oninput=move |event: Event| {
|
||||
let input_elem = event.target().unwrap();
|
||||
let input_elem = input_elem.dyn_into::<HtmlInputElement>().unwrap();
|
||||
*text_clone.borrow_mut() = input_elem.value();
|
||||
}
|
||||
value="End Text"
|
||||
>
|
||||
};
|
||||
|
||||
// New node replaces old node.
|
||||
// We are testing that we've stored this new node's closures even though `new` will be dropped
|
||||
// at the end of this block.
|
||||
dom_updater.update(replace_node);
|
||||
}
|
||||
|
||||
let input_event = InputEvent::new("input").unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "Start Text");
|
||||
|
||||
// After dispatching the oninput event our `text` should have a value of the input elements value.
|
||||
let input = document.get_element_by_id(&id).unwrap();
|
||||
web_sys::EventTarget::from(input)
|
||||
.dispatch_event(&input_event)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "End Text");
|
||||
}
|
||||
|
||||
// When you replace a DOM node with another DOM node we need to make sure that the closures
|
||||
// from the new DOM node are stored by the DomUpdater otherwise they'll get dropped and
|
||||
// won't work.
|
||||
#[wasm_bindgen_test]
|
||||
fn updates_active_closures_on_append() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
let body = document.body().unwrap();
|
||||
|
||||
let old = html! { <div> </div> };
|
||||
let mut dom_updater = DomUpdater::new_append_to_mount(old, &body);
|
||||
|
||||
let text = Rc::new(RefCell::new("Start Text".to_string()));
|
||||
let text_clone = Rc::clone(&text);
|
||||
|
||||
let id = "update-active-closures-on-append";
|
||||
|
||||
{
|
||||
let append_node = html! {
|
||||
<div>
|
||||
<input
|
||||
id=id
|
||||
oninput=move |event: Event| {
|
||||
let input_elem = event.target().unwrap();
|
||||
let input_elem = input_elem.dyn_into::<HtmlInputElement>().unwrap();
|
||||
*text_clone.borrow_mut() = input_elem.value();
|
||||
}
|
||||
value="End Text"
|
||||
>
|
||||
</div>
|
||||
};
|
||||
|
||||
// New node gets appended into the DOM.
|
||||
// We are testing that we've stored this new node's closures even though `new` will be dropped
|
||||
// at the end of this block.
|
||||
dom_updater.update(append_node);
|
||||
}
|
||||
|
||||
let input_event = InputEvent::new("input").unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "Start Text");
|
||||
|
||||
// After dispatching the oninput event our `text` should have a value of the input elements value.
|
||||
let input = document.get_element_by_id(id).unwrap();
|
||||
web_sys::EventTarget::from(input)
|
||||
.dispatch_event(&input_event)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "End Text");
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
extern crate web_sys;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::*;
|
||||
|
||||
use virtual_dom_rs::prelude::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
// Make sure that we successfully attach an event listener and see it work.
|
||||
#[wasm_bindgen_test]
|
||||
fn on_input() {
|
||||
let text = Rc::new(RefCell::new("Start Text".to_string()));
|
||||
let text_clone = Rc::clone(&text);
|
||||
|
||||
let input = html! {
|
||||
<input
|
||||
// On input we'll set our Rc<RefCell<String>> value to the input elements value
|
||||
oninput=move |event: Event| {
|
||||
let input_elem = event.target().unwrap();
|
||||
let input_elem = input_elem.dyn_into::<HtmlInputElement>().unwrap();
|
||||
*text_clone.borrow_mut() = input_elem.value();
|
||||
}
|
||||
value="End Text"
|
||||
>
|
||||
};
|
||||
|
||||
let input_event = InputEvent::new("input").unwrap();
|
||||
let input = input.create_dom_node().node;
|
||||
|
||||
assert_eq!(&*text.borrow(), "Start Text");
|
||||
|
||||
// After dispatching the oninput event our `text` should have a value of the input elements value.
|
||||
web_sys::EventTarget::from(input)
|
||||
.dispatch_event(&input_event)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&*text.borrow(), "End Text");
|
||||
}
|
||||
Reference in new issue
Block a user