Add unit tests for shape_utility pure functions#3958
Add unit tests for shape_utility pure functions#3958tarone-saloni wants to merge 1 commit intoGraphiteEditor:masterfrom
Conversation
Closes GraphiteEditor#3954 Tests cover all branches of the following pure functions in shape_utility.rs: - wrap_to_tau: zero, positive within range, exactly TAU, beyond TAU, negative values (wraps correctly into [0, 2π)) - format_rounded: trailing-zero trimming, dot trimming, rounding up, zero precision, zero value, all-significant digits retained - calculate_display_angle: positive within range, positive wrapping past 360°/720°, exactly 360°, negative small angle, negative beyond -360°, positive-zero input - arc_end_points_ignore_layer: zero sweep, quarter sweep, half-circle sweep, radius scaling, identity viewport vs. no viewport - star_vertex_position: even index (outer radius), odd index (inner radius), second outer vertex — verifying angle and radius selection math - polygon_vertex_position: vertex 0 (up), vertex 1 of square (right), vertex 2 of square (down) - inside_polygon: center inside, far point outside (bbox early exit), point beyond vertex outside, point near center inside - inside_star: center inside, far point outside (bbox early exit), point beyond outer tip outside, point near center inside
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive suite of unit tests for shape utility functions, covering angle wrapping, coordinate calculations for arcs, stars, and polygons, and hit-testing logic. The feedback identifies opportunities to improve test maintainability and readability by implementing a custom macro for floating-point approximations and utilizing idiomatic vector comparison methods from the glam library.
|
|
||
| #[test] | ||
| fn wrap_pi_stays_pi() { | ||
| assert!((wrap_to_tau(PI) - PI).abs() < 1e-10); |
There was a problem hiding this comment.
There are many floating-point comparisons in these tests using the pattern (a - b).abs() < 1e-10. To improve readability and provide better failure messages, consider defining a local assert_approx_eq! macro at the top of the tests module.
macro_rules! assert_approx_eq {
($a:expr, $b:expr, $eps:expr) => {
assert!(
($a - $b).abs() < $eps,
"assertion failed: `(left - right).abs() < epsilon`\n left: `{:?}`\n right: `{:?}`\nepsilon: `{:?}`",
$a, $b, $eps
);
};
($a:expr, $b:expr) => {
assert_approx_eq!($a, $b, 1e-10);
};
}This would allow you to write this assertion as assert_approx_eq!(wrap_to_tau(PI), PI); and can be used for all scalar float comparisons in this test module, making them more concise and readable.
| assert!((start.x - 1.).abs() < 1e-10, "start.x expected 1, got {}", start.x); | ||
| assert!(start.y.abs() < 1e-10, "start.y expected 0, got {}", start.y); | ||
| assert!((end.x - 1.).abs() < 1e-10, "end.x expected 1, got {}", end.x); | ||
| assert!(end.y.abs() < 1e-10, "end.y expected 0, got {}", end.y); |
There was a problem hiding this comment.
These per-component assertions can be simplified by using glam::DVec2::abs_diff_eq for a more concise and idiomatic vector comparison.
For example, these four lines can be replaced with:
let expected = DVec2::new(1., 0.);
assert!(start.abs_diff_eq(expected, 1e-10), "start point mismatch");
assert!(end.abs_diff_eq(expected, 1e-10), "end point mismatch");This approach can be applied to other vector comparisons in this file (e.g., in arc_endpoints_with_identity_viewport_matches_no_viewport, star_vertex_*, and polygon_vertex_* tests) to make them cleaner and more readable.
What this does
Adds a
#[cfg(test)]module toeditor/src/messages/tool/common_functionality/shapes/shape_utility.rs, which previously had no test coverage. All tests are pure unit tests — no editor setup or async runtime needed.Functions covered
wrap_to_tau(angle)Normalises an angle in radians to
[0, 2π). Tests verify:TAUwraps to zeroTAUreduce to the remainderformat_rounded(value, precision)Formats a float and trims trailing zeros and the decimal point. Tests verify:
1.000→"1")1.50→"1.5")1.23→"1.23")3.14159with precision 3 →"3.142")calculate_display_angle(angle)Converts an angle in degrees to a display-friendly value, normalising full turns. Tests cover all three branches (positive, negative, zero) and the wrap-at-±360° edge cases.
arc_end_points_ignore_layer(radius, start, sweep, viewport)Calculates arc start/end points in local or viewport space. Tests cover:
Nonestar_vertex_position(viewport, index, n, r1, r2)Computes a star vertex in viewport space. Tests verify:
r1)r2)polygon_vertex_position(viewport, index, n, radius)Computes a regular polygon vertex. Tests verify vertex 0 (top), vertex 1 (right), vertex 2 (bottom) for a square.
inside_polygon(viewport, n, radius, point)andinside_star(viewport, n, r1, r2, point)Winding-number hit-tests. Tests cover: