Crate freya_testing
source ·Expand description
§Testing
freya-testing is a headless renderer for freya components, which means you can simulate a graphical environment
with no need to actually draw anything, a perfect fit for testing.
You can use the launch_test function to run the tests of the component.
It returns a set of utilities to interact with the component.
§Stateless example
Simply asserts that the component renders a label with the text "Hello World!".
#[tokio::test]
async fn test() {
    fn our_component() -> Element {
        rsx!(
            label {
                "Hello World!"
            }
        )
    }
    let mut utils = launch_test(our_component);
    let root = utils.root(); // Get the root element of your app
    let label = root.get(0); // Get the children of the root in the index 0
    let label_text = label.get(0);
    assert_eq!(label_text.text(), Some("Hello World!"));
}§Stateful example
If the component has logic that might execute asynchronously, you need to wait for the component
to update using the wait_for_update function before asserting the result.
Here, the component has a state that is false by default, but once mounted, it updates the state to true.
#[tokio::test]
async fn dynamic_test() {
    fn dynamic_component() -> Element {
        let mut state = use_signal(|| false);
        use_hook(move || {
            state.set(true);
        });
        rsx!(
            label {
                "Is enabled? {state}"
            }
        )
    }
    let mut utils = launch_test(dynamic_component);
    let root = utils.root();
    let label = root.get(0);
    assert_eq!(label.get(0).text(), Some("Is enabled? false"));
    // This will poll the VirtualDOM and apply the new changes
    utils.wait_for_update().await;
    assert_eq!(label.get(0).text(), Some("Is enabled? true"));
}§Events example
You can simulate events on the component, for example, simulate a click event on a rect and assert that the state was updated.
#[tokio::test]
async fn event_test() {
    fn event_component() -> Element {
        let mut enabled = use_signal(|| false);
        rsx!(
            rect {
                width: "100%",
                height: "100%",
                background: "red",
                onclick: move |_| {
                    enabled.set(true);
                },
                label {
                    "Is enabled? {enabled}"
                }
            }
        )
    }
    let mut utils = launch_test(event_component);
    let rect = utils.root().get(0);
    let label = rect.get(0);
    utils.wait_for_update().await;
    let text = label.get(0);
    assert_eq!(text.text(), Some("Is enabled? false"));
    // Push a click event to the events queue
    utils.push_event(PlatformEvent::Mouse {
        name: "click",
        cursor: (5.0, 5.0).into(),
        button: Some(MouseButton::Left),
    });
    // Poll the VirtualDOM with the new events
    utils.wait_for_update().await;
    // Because the click event was sent, and the state updated, the text was changed as well!
    let text = label.get(0);
    assert_eq!(text.text(), Some("Is enabled? true"));
}§Configuration example
The launch_test comes with a default configuration, but you can pass your own config with the launch_test_with_config function.
Here is an example of how to can set our custom window size:
#[tokio::test]
async fn test() {
    fn our_component() -> Element {
        rsx!(
            label {
                "Hello World!"
            }
        )
    }
    let mut utils = launch_test_with_config(
        our_component,
        TestingConfig {
            size: (500.0, 800.0).into(),
            ..TestingConfig::default()
        },
    );
    let root = utils.root();
    let label = root.get(0);
    let label_text = label.get(0);
    assert_eq!(label_text.text(), Some("Hello World!"));
}