Refactor example tests to run more efficiently

This commit is contained in:
Olivier FAURE 2025-03-18 17:24:26 +01:00
parent 6d1d6b9217
commit 406d4b9932
20 changed files with 119 additions and 145 deletions

View File

@ -75,34 +75,13 @@ profiling = { version = "1.0.15", features = ["profile-with-tracing"] }
[target.'cfg(target_os = "android")'.dependencies]
tracing_android_trace = "0.1.0"
[[example]]
name = "calc_masonry"
test = true
[[example]]
name = "custom_widget"
test = true
[[example]]
name = "grid_masonry"
test = true
[[example]]
name = "hello_masonry"
test = true
[[example]]
name = "simple_image"
test = true
#required-features = ["image", "png"]
# This actually enables scraping for all examples, not just this one.
# However it is possible to set doc-scrape-examples to false for other specific examples.
doc-scrape-examples = true
[[example]]
name = "to_do_list"
test = true
[[example]]
name = "two_textboxes"
name = "tests"
test = true

View File

@ -4,7 +4,7 @@
//! Simple calculator.
// On Windows platform, don't show a console when opening the app.
#![windows_subsystem = "windows"]
#![cfg_attr(not(test), windows_subsystem = "windows")]
#![allow(
variant_size_differences,
clippy::single_match,
@ -341,7 +341,8 @@ fn flex_row(
.with_flex_child(w4, 1.0)
}
fn build_calc() -> impl Widget {
/// Builds the calculator widget.
pub fn build_calc() -> impl Widget {
let display = Label::new(String::new()).with_style(StyleProperty::FontSize(32.));
Flex::column()
.gap(0.0)
@ -423,22 +424,3 @@ fn main() {
)
.unwrap();
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::*;
#[test]
fn screenshot_test() {
let mut harness = TestHarness::create(build_calc());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
}
}

View File

@ -5,7 +5,7 @@
//! We draw an image, some text, a shape, and a curve.
// On Windows platform, don't show a console when opening the app.
#![windows_subsystem = "windows"]
#![cfg_attr(not(test), windows_subsystem = "windows")]
#![expect(elided_lifetimes_in_paths, reason = "Deferred: Noisy")]
#![expect(clippy::shadow_unrelated, reason = "Deferred: Noisy")]
#![expect(clippy::cast_possible_truncation, reason = "Deferred: Noisy")]
@ -34,7 +34,14 @@ impl AppDriver for Driver {
fn on_action(&mut self, _ctx: &mut DriverCtx<'_>, _widget_id: WidgetId, _action: Action) {}
}
struct CustomWidget(String);
/// A struct that implements the Widget trait.
///
/// This struct will be the root widget of the application.
#[derive(Debug)]
pub struct CustomWidget(
/// A string that will be displayed in the widget.
pub String,
);
impl Widget for CustomWidget {
fn on_pointer_event(
@ -202,22 +209,3 @@ fn make_image_data(width: usize, height: usize) -> Vec<u8> {
}
result
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::*;
#[test]
fn screenshot_test() {
let my_string = "Masonry + Vello".to_string();
let mut harness = TestHarness::create(CustomWidget(my_string));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "initial_screenshot");
}
}

View File

@ -4,7 +4,7 @@
//! Shows how to use a grid layout in Masonry.
// On Windows platform, don't show a console when opening the app.
#![windows_subsystem = "windows"]
#![cfg_attr(not(test), windows_subsystem = "windows")]
use masonry::app::{AppDriver, DriverCtx};
use masonry::core::{Action, PointerButton, StyleProperty, WidgetId};
@ -45,7 +45,8 @@ fn grid_button(params: GridParams) -> Button {
))
}
fn make_grid(grid_spacing: f64) -> Grid {
/// Create a grid layout with buttons that change the grid spacing.
pub fn make_grid(grid_spacing: f64) -> Grid {
let label = SizedBox::new(Prose::from_text_area(
TextArea::new_immutable("Change spacing by right and left clicking on the buttons")
.with_style(StyleProperty::FontSize(14.0))
@ -127,22 +128,3 @@ fn main() {
)
.unwrap();
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::*;
#[test]
fn screenshot_test() {
let mut harness = TestHarness::create(make_grid(1.0));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
}
}

View File

@ -1,8 +1,13 @@
# Masonry examples
## `tests.rs`
This module imports the widgets generated by most other examples and runs screenshot tests to check that the examples render correctly.
The screenshots below are generated from those tests.
## `hello_masonry`
Simples possible Masonry app.
Simplest possible Masonry app.
## `two_textboxes`

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -6,7 +6,7 @@
//! everything behaves.
// On Windows platform, don't show a console when opening the app.
#![windows_subsystem = "windows"]
#![cfg_attr(not(test), windows_subsystem = "windows")]
use masonry::app::{AppDriver, DriverCtx};
use masonry::core::{Action, ObjectFit, WidgetId};
@ -21,7 +21,8 @@ impl AppDriver for Driver {
fn on_action(&mut self, _ctx: &mut DriverCtx<'_>, _widget_id: WidgetId, _action: Action) {}
}
fn make_image() -> Image {
/// Creates an image widget with a PNG image.
pub fn make_image() -> Image {
let image_bytes = include_bytes!("./assets/PicWithAlpha.png");
let image_data = image::load_from_memory(image_bytes).unwrap().to_rgba8();
let (width, height) = image_data.dimensions();
@ -50,20 +51,3 @@ fn main() {
)
.unwrap();
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::*;
#[test]
fn screenshot_test() {
let mut harness = TestHarness::create(make_image());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "initial_screenshot");
}
}

View File

@ -1,6 +0,0 @@
---
source: masonry/examples/custom_widget.rs
assertion_line: 195
expression: harness.root_widget()
---
CustomWidget

View File

@ -1,6 +0,0 @@
---
source: masonry/examples/simple_image.rs
assertion_line: 65
expression: harness.root_widget()
---
Image

View File

@ -1,6 +1,6 @@
---
source: masonry/examples/calc_masonry.rs
assertion_line: 416
source: masonry/examples/tests.rs
assertion_line: 30
expression: harness.root_widget()
---
Flex(

View File

@ -0,0 +1,6 @@
---
source: masonry/examples/tests.rs
assertion_line: 41
expression: harness.root_widget()
---
CustomWidget

View File

@ -1,6 +1,6 @@
---
source: masonry/examples/grid_masonry.rs
assertion_line: 142
source: masonry/examples/tests.rs
assertion_line: 48
expression: harness.root_widget()
---
Grid(

View File

@ -0,0 +1,6 @@
---
source: masonry/examples/tests.rs
assertion_line: 57
expression: harness.root_widget()
---
Image

View File

@ -1,6 +1,6 @@
---
source: masonry/examples/to_do_list.rs
assertion_line: 90
source: masonry/examples/tests.rs
assertion_line: 64
expression: harness.root_widget()
---
Portal(

73
masonry/examples/tests.rs Normal file
View File

@ -0,0 +1,73 @@
// Copyright 2025 the Xilem Authors
// SPDX-License-Identifier: Apache-2.0
#![allow(missing_docs)]
fn main() {
println!("This example is only used to compile other examples.")
}
#[cfg(test)]
#[allow(dead_code)]
#[path = "."]
pub mod others {
pub mod calc_masonry;
pub mod custom_widget;
pub mod grid_masonry;
pub mod simple_image;
pub mod to_do_list;
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::others::*;
#[test]
fn calc_masonry_screenshot() {
let mut harness = TestHarness::create(calc_masonry::build_calc());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "calc_masonry_initial");
// TODO - Test clicking buttons
}
#[test]
fn custom_widget_screenshot() {
let my_string = "Masonry + Vello".to_string();
let mut harness = TestHarness::create(custom_widget::CustomWidget(my_string));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "custom_widget_initial");
}
#[test]
fn grid_masonry_screenshot() {
let mut harness = TestHarness::create(grid_masonry::make_grid(1.0));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "grid_masonry_initial");
// TODO - Test clicking buttons
}
#[test]
fn simple_image_screenshot() {
let mut harness = TestHarness::create(simple_image::make_image());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "simple_image_initial");
}
#[test]
fn to_do_list_screenshot() {
let mut harness = TestHarness::create(to_do_list::make_widget_tree());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "to_do_list_initial");
// TODO - Test clicking buttons
// TODO - Test typing text
}
}

View File

@ -5,7 +5,7 @@
//! It does the almost bare minimum while still being useful.
// On Windows platform, don't show a console when opening the app.
#![windows_subsystem = "windows"]
#![cfg_attr(not(test), windows_subsystem = "windows")]
use masonry::app::{AppDriver, DriverCtx};
use masonry::core::{Action, Widget, WidgetId};
@ -46,7 +46,8 @@ impl AppDriver for Driver {
}
}
fn make_widget_tree() -> impl Widget {
/// Create a widget tree for an empty to-do list.
pub fn make_widget_tree() -> impl Widget {
Portal::new(
Flex::column()
.with_child(
@ -75,23 +76,3 @@ fn main() {
)
.unwrap();
}
// --- MARK: TESTS ---
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use masonry::assert_render_snapshot;
use masonry::testing::TestHarness;
use super::*;
#[test]
fn screenshot_test() {
let mut harness = TestHarness::create(make_widget_tree());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
// TODO - Test typing text
}
}