From ab10c7c326a7f8a2cc23eb275a8f64e5fdacbb20 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 28 May 2023 14:56:05 +0100 Subject: [PATCH] fix zero division error (#2674) * fix zero division error * push tests --- CHANGELOG.md | 5 +++++ src/textual/_resolve.py | 6 ++++-- tests/test_resolve.py | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0676b51aa..83ff8f179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +### Fixed + +- Fixed zero division error https://github.com/Textualize/textual/issues/2673 + ### Added - `work` decorator accepts `description` parameter to add debug string https://github.com/Textualize/textual/issues/2597 diff --git a/src/textual/_resolve.py b/src/textual/_resolve.py index 79a1a1e3e..ff8c792f6 100644 --- a/src/textual/_resolve.py +++ b/src/textual/_resolve.py @@ -101,6 +101,8 @@ def resolve_fraction_unit( if not remaining_space or not widget_styles: return Fraction(1) + initial_space = remaining_space + def resolve_scalar( scalar: Scalar | None, fraction_unit: Fraction = Fraction(1) ) -> Fraction | None: @@ -166,8 +168,8 @@ def resolve_fraction_unit( return ( Fraction(remaining_space, remaining_fraction) - if remaining_space > 0 - else Fraction(1) + if remaining_fraction > 0 + else initial_space ) diff --git a/tests/test_resolve.py b/tests/test_resolve.py index 202299747..ef1961edc 100644 --- a/tests/test_resolve.py +++ b/tests/test_resolve.py @@ -5,6 +5,7 @@ import pytest from textual._resolve import resolve, resolve_fraction_unit from textual.css.scalar import Scalar +from textual.css.styles import Styles from textual.geometry import Size from textual.widget import Widget @@ -125,6 +126,30 @@ def test_resolve_fraction_unit(): ) == Fraction(2) +def test_resolve_fraction_unit_stress_test(): + """Check for zero division errors.""" + # https://github.com/Textualize/textual/issues/2673 + widget = Widget() + styles = widget.styles + styles.width = "1fr" + + # We're mainly checking for the absence of zero division errors, + # which is a reoccurring theme for this code. + for remaining_space in range(1, 101, 10): + for max_width in range(1, remaining_space): + styles.max_width = max_width + + for width in range(1, remaining_space): + resolved_unit = resolve_fraction_unit( + [styles, styles, styles], + Size(width, 24), + Size(width, 24), + Fraction(remaining_space), + "width", + ) + assert resolved_unit <= remaining_space + + def test_resolve_issue_2502(): """Test https://github.com/Textualize/textual/issues/2502"""