Testing
Testing is a important part of any project. Natrix doesnt have a dedicated testing framework, instead we recommend you use wasm-pack to run your tests.
But natrix does provide the test_utils
module to help with testing, which is enabled with the test_utils
feature flag.
The primary functions are mount_test
and get
.
Example
extern crate natrix;
extern crate wasm_bindgen_test;
use natrix::prelude::*;
#[derive(Component)]
struct HelloWorld;
impl Component for HelloWorld {
fn render() -> impl Element<Self> {
e::div()
.text("Hello World")
.id("HELLO")
}
}
mod tests {
use super::*;
use natrix::test_utils;
use wasm_bindgen_test::wasm_bindgen_test;
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn test_hello_world() {
test_utils::mount_test(HelloWorld);
let hello = test_utils::get("HELLO");
assert_eq!(hello.text_content(), Some("Hello World".to_string()));
}
}
fn main() {}
This will mount the HelloWorld
component and then check if the text content of the element with id HELLO
is "Hello World". This is a simple test, but it shows how to use the test_utils
module to test your components.
These tests can be run as follows:
wasm-pack test --headless --chrome --firefox
note
From out experience the firefox webdriver is very slow to spin up, and even fails at semmingly random times.
Message Passing
Due to the fact message passing between components uses async, you will need to make your test async as well to observe the changes.
Luckily wasm-bindgen-test
already natively supports async tests, so you can just use the async
keyword in your test function.
To wait until all messages have been processed, you can use next_animation_frame
from the async_utils
feature flag.
extern crate natrix;
extern crate wasm_bindgen_test;
use natrix::prelude::*;
#[derive(Component)]
struct Child;
impl Component for Child {
type EmitMessage = u8;
fn render() -> impl Element<Self> {
e::div().id("CHILD").on::<events::Click>(|ctx: E<Self>, _| {
ctx.emit(1);
})
}
}
#[derive(Component)]
struct Parent {
state: u8,
}
impl Component for Parent {
fn render() -> impl Element<Self> {
e::div()
.child(e::div().id("PARENT").text(|ctx: R<Self>| *ctx.state))
.child(C::new(Child).on(|ctx: E<Self>, msg| {
*ctx.state += msg;
}))
}
}
mod tests {
use super::*;
use natrix::test_utils;
use natrix::async_utils;
use wasm_bindgen_test::wasm_bindgen_test;
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
async fn test_message_passing() {
test_utils::mount_test(Parent {state: 0});
let parent_element = test_utils::get("PARENT");
let child_element = test_utils::get("CHILD");
assert_eq!(parent_element.text_content(), Some("0".to_string()));
child_element.click();
assert_eq!(parent_element.text_content(), Some("0".to_string()));
async_utils::next_animation_frame().await;
assert_eq!(parent_element.text_content(), Some("1".to_string()));
}
}
fn main() {}