Get child by ID

This commit is contained in:
Darren Burns
2022-02-22 11:35:01 +00:00
parent 154ada427f
commit 2b304cc9f7
4 changed files with 24 additions and 27 deletions

View File

@@ -279,18 +279,18 @@ class App(DOMNode):
return DOMQuery(self.view, selector) return DOMQuery(self.view, selector)
def get_child(self, selector: str) -> DOMNode: def get_child(self, id: str) -> DOMNode:
"""Shorthand for self.view.get_child(selector: str) """Shorthand for self.view.get_child(id: str)
Returns the first child (immediate descendent) of this DOMNode Returns the first child (immediate descendent) of this DOMNode
matching the selector. with the given ID.
Args: Args:
selector (str): A CSS selector. id (str): The ID of the node to search for.
Returns: Returns:
DOMNode: The first child of this node which matches the selector. DOMNode: The first child of this node with the specified ID.
""" """
return self.view.get_child(selector) return self.view.get_child(id)
def update_styles(self) -> None: def update_styles(self) -> None:
"""Request update of styles. """Request update of styles.

View File

@@ -12,8 +12,9 @@ from ._node_list import NodeList
from .css._error_tools import friendly_list from .css._error_tools import friendly_list
from .css.constants import VALID_DISPLAY, VALID_VISIBILITY from .css.constants import VALID_DISPLAY, VALID_VISIBILITY
from .css.errors import StyleValueError from .css.errors import StyleValueError
from .css.styles import Styles, RenderStyles
from .css.parse import parse_declarations from .css.parse import parse_declarations
from .css.styles import Styles, RenderStyles
from .css.query import NoMatchingNodesError
from .message_pump import MessagePump from .message_pump import MessagePump
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -282,19 +283,19 @@ class DOMNode(MessagePump):
if node.children: if node.children:
push(iter(node.children)) push(iter(node.children))
def get_child(self, selector: str) -> DOMNode: def get_child(self, id: str) -> DOMNode:
"""Return the first child (immediate descendent) of this DOMNode matching a selector. """Return the first child (immediate descendent) of this node with the given ID.
Args: Args:
selector (str): A CSS selector. id (str): The ID of the child.
Returns: Returns:
DOMNode: The first child of this node which matches the selector. DOMNode: The first child of this node with the ID.
""" """
from .css.query import DOMQuery for child in self.children:
if child.id == id:
query = DOMQuery(selector=selector, nodes=list(self.children)) return child
return query.first() raise NoMatchingNodesError(f"No child found with id={id!r}")
def query(self, selector: str | None = None) -> DOMQuery: def query(self, selector: str | None = None) -> DOMQuery:
"""Get a DOM query. """Get a DOM query.

View File

@@ -169,7 +169,7 @@ def test_animatable():
assert animate_test.bar.value == 50.0 assert animate_test.bar.value == 50.0
class TestAnimator(Animator): class MockAnimator(Animator):
"""A mock animator.""" """A mock animator."""
def __init__(self, *args) -> None: def __init__(self, *args) -> None:
@@ -187,7 +187,7 @@ class TestAnimator(Animator):
def test_animator(): def test_animator():
target = Mock() target = Mock()
animator = TestAnimator(target) animator = MockAnimator(target)
animate_test = AnimateTest() animate_test = AnimateTest()
# Animate attribute "foo" on animate_test to 100.0 in 10 seconds # Animate attribute "foo" on animate_test to 100.0 in 10 seconds
@@ -226,7 +226,7 @@ def test_animator():
def test_bound_animator(): def test_bound_animator():
target = Mock() target = Mock()
animator = TestAnimator(target) animator = MockAnimator(target)
animate_test = AnimateTest() animate_test = AnimateTest()
# Bind an animator so it animates attributes on the given object # Bind an animator so it animates attributes on the given object

View File

@@ -29,12 +29,8 @@ def test_display_set_invalid_value():
@pytest.fixture @pytest.fixture
def parent(): def parent():
parent = DOMNode(id="parent") parent = DOMNode(id="parent")
child1 = DOMNode(id="child1") child1 = DOMNode(id="child1")
child1.add_class("foo")
child2 = DOMNode(id="child2") child2 = DOMNode(id="child2")
child2.add_class("bar")
grandchild1 = DOMNode(id="grandchild1") grandchild1 = DOMNode(id="grandchild1")
child1.add_child(grandchild1) child1.add_child(grandchild1)
@@ -45,17 +41,17 @@ def parent():
def test_get_child_gets_first_child(parent): def test_get_child_gets_first_child(parent):
child = parent.get_child(".foo") child = parent.get_child(id="child1")
assert child.id == "child1" assert child.id == "child1"
assert child.get_child("#grandchild1").id == "grandchild1" assert child.get_child(id="grandchild1").id == "grandchild1"
assert parent.get_child(".bar").id == "child2" assert parent.get_child(id="child2").id == "child2"
def test_get_child_no_matching_child(parent): def test_get_child_no_matching_child(parent):
with pytest.raises(NoMatchingNodesError): with pytest.raises(NoMatchingNodesError):
parent.get_child("#doesnt-exist") parent.get_child(id="doesnt-exist")
def test_get_child_only_immediate_descendents(parent): def test_get_child_only_immediate_descendents(parent):
with pytest.raises(NoMatchingNodesError): with pytest.raises(NoMatchingNodesError):
parent.get_child("#grandchild1") parent.get_child(id="grandchild1")