diff --git a/src/napari_matplotlib/tests/test_util.py b/src/napari_matplotlib/tests/test_util.py index b8ebaff4..3f27f608 100644 --- a/src/napari_matplotlib/tests/test_util.py +++ b/src/napari_matplotlib/tests/test_util.py @@ -18,17 +18,21 @@ def test_interval(): def test_get_size_from_css(mocker): """Test getting the max-width and max-height from something in css""" + # some weird (but valid) css to check we can skip things correctly test_css = """ Flibble { + padding: 0 0 1px 2px; + color: rgb(3, 4, 555); min-width : 0; max-width : 123px; - min-height : 0px; + min-height : 0%; max-height : 456px; - padding: 0px; } """ mocker.patch("napari.qt.get_current_stylesheet").return_value = test_css - assert from_napari_css_get_size_of("Flibble", (1, 2)) == QSize(123, 456) + assert from_napari_css_get_size_of("Flibble", fallback=(1, 2)) == QSize( + 123, 456 + ) def test_fallback_if_missing_dimensions(mocker): @@ -36,11 +40,15 @@ def test_fallback_if_missing_dimensions(mocker): test_css = " Flobble { background-color: rgb(0, 97, 163); } " mocker.patch("napari.qt.get_current_stylesheet").return_value = test_css with pytest.warns(RuntimeWarning, match="Unable to find DimensionToken"): - assert from_napari_css_get_size_of("Flobble", (1, 2)) == QSize(1, 2) + assert from_napari_css_get_size_of( + "Flobble", fallback=(1, 2) + ) == QSize(1, 2) def test_fallback_if_prelude_not_in_css(): """Test fallback if given something not in the css""" doesntexist = "AQButtonThatDoesntExist" with pytest.warns(RuntimeWarning, match=f"Unable to find {doesntexist}"): - assert from_napari_css_get_size_of(doesntexist, (1, 2)) == QSize(1, 2) + assert from_napari_css_get_size_of( + doesntexist, fallback=(1, 2) + ) == QSize(1, 2) diff --git a/src/napari_matplotlib/util.py b/src/napari_matplotlib/util.py index 17965caf..ed586816 100644 --- a/src/napari_matplotlib/util.py +++ b/src/napari_matplotlib/util.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Tuple, Union +from typing import Generator, List, Optional, Tuple, Union from warnings import warn import napari.qt @@ -47,6 +47,21 @@ def __contains__(self, val: int) -> bool: return True +def _logical_lines( + nodes: List[tinycss2.ast.Node], +) -> Generator[Tuple[tinycss2.ast.Node, tinycss2.ast.Node], None, None]: + """Generator to provide logical lines (thing: value) of css (terminated by ';')""" + ident, dimension = None, None + for node in nodes: + if node == ";": + yield (ident, dimension) + ident, dimension = None, None + elif node.type == "ident": + ident = node + elif node.type == "dimension": + dimension = node + + def _has_id(nodes: List[tinycss2.ast.Node], id_name: str) -> bool: """ Is `id_name` in IdentTokens in the list of CSS `nodes`? @@ -66,13 +81,8 @@ def _get_dimension( ------- None if no IdentToken is found. """ - cleaned_nodes = [node for node in nodes if node.type != "whitespace"] - for name, _, value, _ in zip(*(iter(cleaned_nodes),) * 4): - if ( - name.type == "ident" - and value.type == "dimension" - and name.value == id_name - ): + for name, value in _logical_lines(nodes): + if name.value == id_name: return value.int_value warn(f"Unable to find DimensionToken for {id_name}", RuntimeWarning) return None