From a0d9c93cf1692c9a812f6aeceb7d4d32f8fb7eb2 Mon Sep 17 00:00:00 2001 From: Christopher Date: Sat, 13 Dec 2025 08:26:34 +1000 Subject: [PATCH 1/3] Add initial auto_bounds test for Plot Includes the following changes: - Add `egui_kittest`, `log`, `env_logger`, `assertables` as dev-dependencies to egui_plot crate - Add test-only `init_test_logger` function to enable capturing `log::info!` and friends in tests - Add tests for basic auto_bounds behavior to be an example for additional test cases --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + egui_plot/Cargo.toml | 6 ++++++ egui_plot/src/plot.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ egui_plot/src/utils.rs | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 69c14c5d..b286614c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -303,6 +303,12 @@ dependencies = [ "zbus", ] +[[package]] +name = "assertables" +version = "9.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59051ec02907378a67b0ba1b8631121f5388c8dbbb3cec8c749d8f93c2c3c211" + [[package]] name = "async-broadcast" version = "0.7.2" @@ -1192,9 +1198,13 @@ name = "egui_plot" version = "0.34.0" dependencies = [ "ahash", + "assertables", "document-features", "egui", + "egui_kittest", "emath", + "env_logger", + "log", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index e7a3eba6..71bbe37d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ ahash = { version = "0.8.12", default-features = false, features = [ "no-rng", # we don't need DOS-protection, so we let users opt-in to it instead "std", ] } +assertables = "9.8.2" document-features = "0.2.12" eframe = { version = "0.33", default-features = false } egui = { version = "0.33", default-features = false } diff --git a/egui_plot/Cargo.toml b/egui_plot/Cargo.toml index 58e9e31c..624f318c 100644 --- a/egui_plot/Cargo.toml +++ b/egui_plot/Cargo.toml @@ -45,3 +45,9 @@ ahash.workspace = true document-features = { workspace = true, optional = true } serde = { workspace = true, optional = true } + +[dev-dependencies] +assertables.workspace = true +egui_kittest.workspace = true +env_logger.workspace = true +log.workspace = true diff --git a/egui_plot/src/plot.rs b/egui_plot/src/plot.rs index b6fd3085..27d62288 100644 --- a/egui_plot/src/plot.rs +++ b/egui_plot/src/plot.rs @@ -2125,3 +2125,45 @@ impl<'a> PlotUi<'a> { self.items.push(Box::new(heatmap)); } } + +#[cfg(all(test, not(target_arch = "wasm32")))] +mod plot_tests { + use super::*; + use crate::{Plot, Points}; + + use assertables::assert_abs_diff_le_x; + use egui_kittest::Harness; + + /// Test that auto_bounds(true) fits the data exactly when the margin fraction is zero. + #[test] + fn auto_bounds_true() { + crate::utils::init_test_logger(); + + const MIN: [f64; 2] = [-10.0, -10.0]; + const MAX: [f64; 2] = [10.0, 10.0]; + + let harness = { + let bounds = PlotBounds::from_min_max(MIN, MAX); + Harness::new_ui_state( + |ui, bounds| { + let plot = Plot::new("test_plot") + .auto_bounds(true) + .set_margin_fraction(Vec2::splat(0.0)); + + plot.show(ui, |plot_ui| { + let corners = vec![MIN, MAX]; + plot_ui.points(Points::new("filler", corners)); + *bounds = plot_ui.plot_bounds(); + }); + }, + bounds, + ) + }; + + let final_bounds = harness.state(); + assert_abs_diff_le_x!(final_bounds.min[0], MIN[0], f64::EPSILON); + assert_abs_diff_le_x!(final_bounds.min[1], MIN[1], f64::EPSILON); + assert_abs_diff_le_x!(final_bounds.max[0], MAX[0], f64::EPSILON); + assert_abs_diff_le_x!(final_bounds.max[1], MAX[1], f64::EPSILON); + } +} diff --git a/egui_plot/src/utils.rs b/egui_plot/src/utils.rs index e7cbe417..23dd503b 100644 --- a/egui_plot/src/utils.rs +++ b/egui_plot/src/utils.rs @@ -56,3 +56,40 @@ pub(crate) fn find_name_candidate(name: &str, width: f32, painter: &Painter, fon best } + +/// Initialize logging so that the testing framework can capture log output. +/// +/// Call this at the top of a test function to see log output from that test. +/// The logging output will only be shown when the following conditions are met: +/// - The test fails +/// - The RUST_LOG environment variable is set to a level at or below the message level +/// +/// When running a specific test: +/// ```sh +/// RUST_LOG=info cargo test auto_bounds_true +/// ``` +/// +/// If the something causes the test to panic so hard that it nevers shows logging output, +/// you can use `--nocapture` to see log output as it happens: +/// ```sh +/// RUST_LOG=info cargo test auto_bounds_true -- --nocapture +/// ``` +#[allow(dead_code)] // It's ok if it's not currently being used. We just want it to be available. +#[cfg(test)] +pub(crate) fn init_test_logger() { + use std::io::Write as _; + let _ = env_logger::builder() + .is_test(true) + .format(|buf, record| { + let level_style = buf.default_level_style(record.level()); + writeln!( + buf, + "[{level_style}{}{level_style:#} {}:{}] {}", + record.level(), + record.file().unwrap_or("unknown"), + record.line().unwrap_or(0), + record.args() + ) + }) + .try_init(); +} From 6100630061205561019132d8eaf4663e66694401 Mon Sep 17 00:00:00 2001 From: Michal Sustr Date: Sat, 13 Dec 2025 13:49:57 +0100 Subject: [PATCH 2/3] Fixes --- egui_plot/Cargo.toml | 3 +++ egui_plot/src/plot.rs | 11 +++++------ egui_plot/src/utils.rs | 7 +++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/egui_plot/Cargo.toml b/egui_plot/Cargo.toml index 624f318c..1984ce83 100644 --- a/egui_plot/Cargo.toml +++ b/egui_plot/Cargo.toml @@ -51,3 +51,6 @@ assertables.workspace = true egui_kittest.workspace = true env_logger.workspace = true log.workspace = true + +[package.metadata.cargo-shear] +ignored = ["log"] diff --git a/egui_plot/src/plot.rs b/egui_plot/src/plot.rs index 27d62288..491913e3 100644 --- a/egui_plot/src/plot.rs +++ b/egui_plot/src/plot.rs @@ -2131,10 +2131,9 @@ mod plot_tests { use super::*; use crate::{Plot, Points}; - use assertables::assert_abs_diff_le_x; use egui_kittest::Harness; - /// Test that auto_bounds(true) fits the data exactly when the margin fraction is zero. + /// Test that `auto_bounds(true)` fits the data exactly when the margin fraction is zero. #[test] fn auto_bounds_true() { crate::utils::init_test_logger(); @@ -2161,9 +2160,9 @@ mod plot_tests { }; let final_bounds = harness.state(); - assert_abs_diff_le_x!(final_bounds.min[0], MIN[0], f64::EPSILON); - assert_abs_diff_le_x!(final_bounds.min[1], MIN[1], f64::EPSILON); - assert_abs_diff_le_x!(final_bounds.max[0], MAX[0], f64::EPSILON); - assert_abs_diff_le_x!(final_bounds.max[1], MAX[1], f64::EPSILON); + assert!((final_bounds.min[0] - MIN[0]).abs() <= f64::EPSILON); + assert!((final_bounds.min[1] - MIN[1]).abs() <= f64::EPSILON); + assert!((final_bounds.max[0] - MAX[0]).abs() <= f64::EPSILON); + assert!((final_bounds.max[1] - MAX[1]).abs() <= f64::EPSILON); } } diff --git a/egui_plot/src/utils.rs b/egui_plot/src/utils.rs index 23dd503b..739b2868 100644 --- a/egui_plot/src/utils.rs +++ b/egui_plot/src/utils.rs @@ -62,23 +62,22 @@ pub(crate) fn find_name_candidate(name: &str, width: f32, painter: &Painter, fon /// Call this at the top of a test function to see log output from that test. /// The logging output will only be shown when the following conditions are met: /// - The test fails -/// - The RUST_LOG environment variable is set to a level at or below the message level +/// - The `RUST_LOG` environment variable is set to a level at or below the message level /// /// When running a specific test: /// ```sh /// RUST_LOG=info cargo test auto_bounds_true /// ``` /// -/// If the something causes the test to panic so hard that it nevers shows logging output, +/// If the something causes the test to panic so hard that it never shows logging output, /// you can use `--nocapture` to see log output as it happens: /// ```sh /// RUST_LOG=info cargo test auto_bounds_true -- --nocapture /// ``` -#[allow(dead_code)] // It's ok if it's not currently being used. We just want it to be available. #[cfg(test)] pub(crate) fn init_test_logger() { use std::io::Write as _; - let _ = env_logger::builder() + let _result: Result<(), log::SetLoggerError> = env_logger::builder() .is_test(true) .format(|buf, record| { let level_style = buf.default_level_style(record.level()); From e61b451f349d266d039df76db2e443c81be108af Mon Sep 17 00:00:00 2001 From: Michal Sustr Date: Sat, 13 Dec 2025 14:07:34 +0100 Subject: [PATCH 3/3] shear fix --- Cargo.toml | 4 ++++ egui_plot/Cargo.toml | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 71bbe37d..b2920474 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -280,3 +280,7 @@ zero_sized_map_values = "warn" manual_range_contains = "allow" # this is better on 'allow' map_unwrap_or = "allow" # this is better on 'allow' + + +[workspace.metadata.cargo-shear] +ignored = ["log", "assertables"] diff --git a/egui_plot/Cargo.toml b/egui_plot/Cargo.toml index 1984ce83..624f318c 100644 --- a/egui_plot/Cargo.toml +++ b/egui_plot/Cargo.toml @@ -51,6 +51,3 @@ assertables.workspace = true egui_kittest.workspace = true env_logger.workspace = true log.workspace = true - -[package.metadata.cargo-shear] -ignored = ["log"]