simi 0.2.1

A framework for building wasm front-end web application in Rust
#![feature(proc_macro_hygiene)]
#![cfg(target_arch = "wasm32")]

use simi::prelude::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;

wasm_bindgen_test_configure!(run_in_browser);

mod component;

#[simi_app]
struct TestApp {
    message: String,
    month: i32,
    year: i32,
}

enum Msg {
    SetMessage(&'static str),
    MonthUp,
    MonthDown,
    YearUp,
    YearDown,
}

impl Application for TestApp {
    type Message = Msg;
    type Context = ();
    type Parent = ();
    fn init() -> Self {
        Self {
            message: "Test message".to_string(),
            month: 11,
            year: 2018,
        }
    }

    fn update(&mut self, m: Self::Message, _main: ContextPlus<Self>) -> UpdateView {
        match m {
            Msg::SetMessage(s) => self.message = s.to_string(),
            Msg::MonthDown => {
                self.month -= 1;
                if self.month < 1 {
                    self.month = 12;
                    self.year -= 1
                }
            }
            Msg::MonthUp => {
                self.month += 1;
                if self.month > 12 {
                    self.month = 1;
                    self.year += 1
                }
            }
            Msg::YearUp => self.year += 1,
            Msg::YearDown => self.year -= 1,
        }
        true
    }
    fn render(&self, context: RenderContext<Self>) {
        use crate::component::{Counter, MessagePanel, ParentComponent, ValueDisplay};

        application! {
            div (id="message") {
                MessagePanel { message: &self.message }
            }
            div (id="year") {
                ValueDisplay { value: self.year }
            }
            div (id="month") {
                ValueDisplay { value: self.month }
            }
            Counter {
                id: "month-in-counter",
                title: "Month: ",
                value: &self.month,
                up: onclick=#Msg::MonthUp,
                down: onclick=#Msg::MonthDown,
            }
            Counter {
                id: "year-in-counter",
                title: "Year: ",
                value: &self.year,
                up: onclick=#Msg::YearUp,
                down: onclick=#Msg::YearDown
            }
            ParentComponent {
                child1: Counter {
                    id: "month-in-nested-counter",
                    title: "Month: ",
                    value: &self.month,
                    up: onclick=#Msg::MonthUp,
                    down: onclick=#Msg::MonthDown,
                }
                child2: Counter {
                    id: "year-in-nested-counter",
                    title: "Year: ",
                    value: &self.year,
                    up: onclick=#Msg::YearUp,
                    down: onclick=#Msg::YearDown
                }
            }
        }
    }
}

#[wasm_bindgen_test]
fn simple_component() {
    let main: RcMain<TestApp> = simi_test::start_app();
    let msg = simi_test::Element::id("message");
    let y = simi_test::Element::id("year");
    let m = simi_test::Element::id("month");

    assert_eq!(
        "Message: Test message",
        msg.as_node().text_content().expect("msg text")
    );
    assert_eq!(
        "Value: 2018",
        y.as_node().text_content().expect("year value")
    );
    assert_eq!(
        "Value: 11",
        m.as_node().text_content().expect("month value")
    );

    main.send_message(Msg::SetMessage("New test message"));
    assert_eq!(
        "Message: New test message",
        msg.as_node().text_content().expect("msg text")
    );

    main.send_message(Msg::MonthDown);
    main.send_message(Msg::YearDown);
    assert_eq!(
        "Value: 2017",
        y.as_node().text_content().expect("year value")
    );
    assert_eq!(
        "Value: 10",
        m.as_node().text_content().expect("month value")
    );

    main.send_message(Msg::MonthUp);
    main.send_message(Msg::YearUp);
    main.send_message(Msg::MonthUp);
    main.send_message(Msg::YearUp);
    assert_eq!(
        "Value: 2019",
        y.as_node().text_content().expect("year value")
    );
    assert_eq!(
        "Value: 12",
        m.as_node().text_content().expect("month value")
    );
}

#[wasm_bindgen_test]
fn pass_events_to_a_component() {
    let _main: RcMain<TestApp> = simi_test::start_app();
    let y = simi_test::Element::selector("#year-in-counter p");
    let m = simi_test::Element::selector("#month-in-counter p");
    let yup = simi_test::Element::selector("#year-in-counter button.up");
    let ydown = simi_test::Element::selector("#year-in-counter button.down");
    let mup = simi_test::Element::selector("#month-in-counter button.up");
    let mdown = simi_test::Element::selector("#month-in-counter button.down");

    assert_eq!("Month: 11", m.as_node().text_content().expect("month text"));
    assert_eq!("Year: 2018", y.as_node().text_content().expect("year text"));

    yup.click();
    assert_eq!("Year: 2019", y.as_node().text_content().expect("year text"));
    mup.click();
    assert_eq!("Month: 12", m.as_node().text_content().expect("month text"));

    ydown.click();
    ydown.click();
    assert_eq!("Year: 2017", y.as_node().text_content().expect("year text"));
    mdown.click();
    mdown.click();
    assert_eq!("Month: 10", m.as_node().text_content().expect("month text"));
}

#[wasm_bindgen_test]
fn nested_component() {
    let _main: RcMain<TestApp> = simi_test::start_app();
    let y = simi_test::Element::selector("#year-in-nested-counter p");
    let m = simi_test::Element::selector("#month-in-nested-counter p");
    let yup = simi_test::Element::selector("#year-in-nested-counter button.up");
    let ydown = simi_test::Element::selector("#year-in-nested-counter button.down");
    let mup = simi_test::Element::selector("#month-in-nested-counter button.up");
    let mdown = simi_test::Element::selector("#month-in-nested-counter button.down");

    assert_eq!("Month: 11", m.as_node().text_content().expect("month text"));
    assert_eq!("Year: 2018", y.as_node().text_content().expect("year text"));

    yup.click();
    assert_eq!("Year: 2019", y.as_node().text_content().expect("year text"));
    mup.click();
    assert_eq!("Month: 12", m.as_node().text_content().expect("month text"));

    ydown.click();
    ydown.click();
    assert_eq!("Year: 2017", y.as_node().text_content().expect("year text"));
    mdown.click();
    mdown.click();
    assert_eq!("Month: 10", m.as_node().text_content().expect("month text"));
}