#![feature(proc_macro_hygiene)]
#![cfg(target_arch = "wasm32")]
use simi::interop::element_events::Event;
use simi::prelude::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[simi_app]
struct TestApp {
count: i32,
string_value: String,
bool_value: bool,
check_value: bool,
radio_value: &'static str,
controlled_select_value: Option<String>,
controlled_select_index: Option<usize>,
}
enum Msg {
Up,
Down,
InputTextChange(simi::interop::element_events::Event),
ToggleBoolValue,
TextAreaChange(simi::interop::element_events::Event),
SetStringValue(String),
CheckValue(Event),
RadioValue(&'static str),
ControlledValueSelect(Event),
ControlledIndexSelect(Event),
}
impl Application for TestApp {
type Message = Msg;
type Context = ();
type Parent = ();
fn init() -> Self {
Self {
count: 2018,
string_value: "Simi".to_string(),
bool_value: false,
radio_value: "DefaultValue",
check_value: true,
controlled_select_value: None,
controlled_select_index: None,
}
}
fn update(&mut self, m: Self::Message, _main: ContextPlus<Self>) -> UpdateView {
match m {
Msg::Up => self.count += 1,
Msg::Down => self.count -= 1,
Msg::InputTextChange(input) => self.update_string_value_from_input(input),
Msg::ToggleBoolValue => self.bool_value = !self.bool_value,
Msg::TextAreaChange(input) => self.update_string_value_from_textarea(input),
Msg::SetStringValue(value) => self.string_value = value.to_string(),
Msg::CheckValue(input) => self.update_check_value(input),
Msg::RadioValue(value) => self.radio_value = value,
Msg::ControlledValueSelect(event) => self.update_controlled_select_value(event),
Msg::ControlledIndexSelect(event) => self.update_controlled_select_index(event),
}
true
}
fn render(&self, context: RenderContext<Self>) {
let default_init_index = 1usize;
application! {
div (id="classes" class="class1 class2" class="class3" "toggle-class1"=self.bool_value "toggle-class2"=!self.bool_value)
div (id="count-value") { "Count value: " self.count }
button (id="button-count-up" onclick=#Msg::Up) { "Up" }
button (id="button-count-down" onclick=#Msg::Down) { "Down" }
div (id="no-update-count") { "Initial value of count: " #self.count }
#div (id="no-update-element") { "Initial value of count: " self.count }
div (id="string-value"){ self.string_value }
input (id="input-string-value" value=self.string_value onchange=#Msg::InputTextChange(?))
input (id="checkbox" type="checkbox" checked=self.bool_value onclick=#Msg::ToggleBoolValue)
textarea (id="textarea" value=self.string_value onchange=#Msg::TextAreaChange(?))
div (id="custom-attributes" data-user-name="Limira" data-user-skill="0" data-to-update=self.string_value)
div {
input (id="literal-check-true" type="checkbox" name="test-check" value="literal-true" checked=true)
input (id="literal-check-false" type="checkbox" name="test-check" value="literal-false" checked=false)
input (id="no-update-check" type="checkbox" name="test-check" value="expr-value-no-update" checked=#self.check_value)
input (id="tracking-check" type="checkbox" name="test-check" value="expr-value" checked=self.check_value onchange=Msg::CheckValue(?))
}
div {
input (id="radio1" type="radio" name="test-radio" value="radio-value1"
checked=self.radio_checked("RadioValue1")
onchange=Msg::RadioValue("RadioValue1"))
input (id="radio2" type="radio" name="test-radio" value="radio-value2"
checked=self.radio_checked("RadioValue2")
onchange=Msg::RadioValue("RadioValue2"))
input (id="radio3" type="radio" name="test-radio" value="radio-value3"
checked=self.radio_checked("RadioValue3")
onchange=Msg::RadioValue("RadioValue3"))
input (id="radio4" type="radio" name="test-radio" value="radio-value4"
checked=self.radio_checked("RadioValue4")
onchange=Msg::RadioValue("RadioValue4"))
}
div {
select (id="init-value-select" value="second".to_string()) {
option (id="init-value-select-option1" value="first") { "First Option" }
option (id="init-value-select-option2" value="second") { "Second Option" }
option (id="init-value-select-option3" value="third") { "Third Option" }
}
select (id="controlled-by-value-select"
size="6"
value=?self.controlled_select_value
onchange=Msg::ControlledValueSelect(?)
) {
option (id="controlled-by-value-select-option1" value="first") { "First Option" }
option (id="controlled-by-value-select-option2" value="second") { "Second Option" }
option (id="controlled-by-value-select-option3" value="third") { "Third Option" }
}
}
div {
select (id="init-index-select" index=default_init_index){
option (id="init-index-select-option1" value="first") { "First Option" }
option (id="init-index-select-option2" value="second") { "Second Option" }
option (id="init-index-select-option3" value="third") { "Third Option" }
}
select (id="controlled-by-index-select"
index=?self.controlled_select_index
onchange=Msg::ControlledIndexSelect(?)
) {
option (id="controlled-by-index-select-option1" value="first") { "First Option" }
option (id="controlled-by-index-select-option2" value="second") { "Second Option" }
option (id="controlled-by-index-select-option3" value="third") { "Third Option" }
}
}
}
}
}
impl TestApp {
fn update_string_value_from_input(&mut self, event: simi::interop::element_events::Event) {
let target = event.target().expect("Must have a target");
let input: &web_sys::HtmlInputElement = target.unchecked_ref();
self.string_value = input.value();
}
fn update_string_value_from_textarea(&mut self, event: simi::interop::element_events::Event) {
let target = event.target().expect("Must have a target");
let input: &web_sys::HtmlTextAreaElement = target.unchecked_ref();
self.string_value = input.value();
}
fn update_check_value(&mut self, event: Event) {
let target = event.target().expect("Must have a target");
let input: &web_sys::HtmlInputElement = target.unchecked_ref();
self.check_value = input.checked();
}
fn radio_checked(&self, value: &str) -> bool {
self.radio_value == value
}
fn update_controlled_select_value(&mut self, event: Event) {
let target = event.target().expect("Must have a target");
let se: &web_sys::HtmlSelectElement = target.unchecked_ref();
if se.selected_index() < 0 {
self.controlled_select_value = None;
} else {
self.controlled_select_value = Some(se.value());
}
}
fn update_controlled_select_index(&mut self, event: Event) {
let target = event.target().expect("Must have a target");
let se: &web_sys::HtmlSelectElement = target.unchecked_ref();
if se.selected_index() < 0 {
self.controlled_select_index = None;
} else {
self.controlled_select_index = Some(se.selected_index() as usize);
}
}
}
#[wasm_bindgen_test]
fn classes_and_conditional_classes() {
let main: RcMain<TestApp> = simi_test::start_app();
let div = simi_test::Element::id("classes");
let classes = div.as_element().class_list();
assert_eq!(true, classes.contains("class1"));
assert_eq!(true, classes.contains("class2"));
assert_eq!(true, classes.contains("class3"));
assert_eq!(false, classes.contains("toggle-class1"));
assert_eq!(true, classes.contains("toggle-class2"));
main.send_message(Msg::ToggleBoolValue);
assert_eq!(true, classes.contains("class1"));
assert_eq!(true, classes.contains("class2"));
assert_eq!(true, classes.contains("class3"));
assert_eq!(true, classes.contains("toggle-class1"));
assert_eq!(false, classes.contains("toggle-class2"));
}
fn check_no_update() {
let nu1 = simi_test::Element::id("no-update-count");
let nu2 = simi_test::Element::id("no-update-element");
assert_eq!(
"Initial value of count: 2018",
nu1.as_node().text_content().expect("div content")
);
assert_eq!(
"Initial value of count: 2018",
nu2.as_node().text_content().expect("div content")
);
}
#[wasm_bindgen_test]
fn content_and_no_update() {
let main: RcMain<TestApp> = simi_test::start_app();
let div = simi_test::Element::id("count-value");
assert_eq!(
"Count value: 2018",
div.as_node().text_content().expect("div content")
);
check_no_update();
main.send_message(Msg::Down);
assert_eq!(
"Count value: 2017",
div.as_node().text_content().expect("div content")
);
check_no_update();
main.send_message(Msg::Up);
assert_eq!(
"Count value: 2018",
div.as_node().text_content().expect("div content")
);
check_no_update();
let bup = simi_test::Element::id("button-count-up");
bup.click();
assert_eq!(
"Count value: 2019",
div.as_node().text_content().expect("div content")
);
check_no_update();
let bdown = simi_test::Element::id("button-count-down");
bdown.click();
assert_eq!(
"Count value: 2018",
div.as_node().text_content().expect("div content")
);
check_no_update();
}
#[wasm_bindgen_test]
fn input_checkbox() {
let main: RcMain<TestApp> = simi_test::start_app();
let cb = simi_test::Element::id("checkbox");
assert_eq!(false, cb.as_input().checked());
cb.click();
assert_eq!(true, cb.as_input().checked());
main.send_message(Msg::ToggleBoolValue);
assert_eq!(false, cb.as_input().checked());
}
#[wasm_bindgen_test]
fn input_text() {
let _main: RcMain<TestApp> = simi_test::start_app();
let div = simi_test::Element::id("string-value");
let input = simi_test::Element::id("input-string-value");
assert_eq!("Simi", div.as_node().text_content().expect("div content"));
assert_eq!("Simi", input.as_input().value());
input.change_input("Simi v0.2");
assert_eq!(
"Simi v0.2",
div.as_node().text_content().expect("div content")
);
assert_eq!("Simi v0.2", input.as_input().value());
}
#[wasm_bindgen_test]
fn textarea() {
let _main: RcMain<TestApp> = simi_test::start_app();
let div = simi_test::Element::id("string-value");
let ta = simi_test::Element::id("textarea");
assert_eq!("Simi", div.as_node().text_content().expect("div content"));
assert_eq!("Simi", ta.as_textarea().value());
ta.change_textarea("Simi v0.2");
assert_eq!(
"Simi v0.2",
div.as_node().text_content().expect("div content")
);
assert_eq!("Simi v0.2", ta.as_textarea().value());
}
#[wasm_bindgen_test]
fn custom_attributes() {
let main: RcMain<TestApp> = simi_test::start_app();
let div = simi_test::Element::id("custom-attributes");
assert_eq!(
Some("Limira".to_string()),
div.as_element().get_attribute("data-user-name")
);
assert_eq!(
Some("0".to_string()),
div.as_element().get_attribute("data-user-skill")
);
assert_eq!(
Some("Simi".to_string()),
div.as_element().get_attribute("data-to-update")
);
main.send_message(Msg::SetStringValue("Simi v0.2".to_string()));
assert_eq!(
Some("Simi v0.2".to_string()),
div.as_element().get_attribute("data-to-update")
);
}
#[wasm_bindgen_test]
fn checkboxes() {
let _main: RcMain<TestApp> = simi_test::start_app();
let no_update = simi_test::Element::id("no-update-check");
let to_update = simi_test::Element::id("tracking-check");
let i = simi_test::Element::id("literal-check-true");
assert_eq!(true, i.as_input().checked());
let i = simi_test::Element::id("literal-check-false");
assert_eq!(false, i.as_input().checked());
assert_eq!(true, to_update.as_input().checked());
assert_eq!(true, no_update.as_input().checked());
to_update.click();
assert_eq!(false, to_update.as_input().checked());
assert_eq!(true, no_update.as_input().checked());
to_update.click();
assert_eq!(true, to_update.as_input().checked());
assert_eq!(true, no_update.as_input().checked());
}
#[wasm_bindgen_test]
fn radios() {
let _main: RcMain<TestApp> = simi_test::start_app();
let radio1 = simi_test::Element::id("radio1");
let radio2 = simi_test::Element::id("radio2");
let radio3 = simi_test::Element::id("radio3");
let radio4 = simi_test::Element::id("radio4");
assert_eq!(false, radio1.as_input().checked());
assert_eq!(false, radio2.as_input().checked());
assert_eq!(false, radio3.as_input().checked());
assert_eq!(false, radio4.as_input().checked());
radio1.click();
assert_eq!(true, radio1.as_input().checked());
assert_eq!(false, radio2.as_input().checked());
assert_eq!(false, radio3.as_input().checked());
assert_eq!(false, radio4.as_input().checked());
radio2.click();
assert_eq!(false, radio1.as_input().checked());
assert_eq!(true, radio2.as_input().checked());
assert_eq!(false, radio3.as_input().checked());
assert_eq!(false, radio4.as_input().checked());
}
#[wasm_bindgen_test]
fn select_value() {
let _main: RcMain<TestApp> = simi_test::start_app();
let s = simi_test::Element::id("init-value-select");
assert_eq!("second", s.as_select().value());
assert_eq!(1, s.as_select().selected_index());
let s = simi_test::Element::id("controlled-by-value-select");
assert_eq!(6, s.as_select().size());
assert_eq!("", s.as_select().value());
assert_eq!(-1, s.as_select().selected_index());
let select = s;
select.change_select("third");
assert_eq!("third", select.as_select().value());
assert_eq!(2, select.as_select().selected_index());
let o = simi_test::Element::id("controlled-by-value-select-option3");
assert_eq!(true, o.as_option().selected());
assert_eq!(2, o.as_option().index());
}
#[wasm_bindgen_test]
fn select_index() {
let _main: RcMain<TestApp> = simi_test::start_app();
let s = simi_test::Element::id("init-index-select");
assert_eq!("second", s.as_select().value());
assert_eq!(1, s.as_select().selected_index());
let s = simi_test::Element::id("controlled-by-index-select");
assert_eq!("", s.as_select().value());
assert_eq!(-1, s.as_select().selected_index());
let select = s;
select.change_index(0);
assert_eq!("first", select.as_select().value());
assert_eq!(0, select.as_select().selected_index());
let o = simi_test::Element::id("controlled-by-index-select-option1");
assert_eq!(true, o.as_option().selected());
assert_eq!(0, o.as_option().index());
select.change_index(2);
assert_eq!("third", select.as_select().value());
assert_eq!(2, select.as_select().selected_index());
let o = simi_test::Element::id("controlled-by-index-select-option3");
assert_eq!(true, o.as_option().selected());
assert_eq!(2, o.as_option().index());
}