phml.utilities.validate.check

phml.utilities.validate.test

Logic that allows nodes to be tested against a series of conditions.

 1"""phml.utilities.validate.test
 2
 3Logic that allows nodes to be tested against a series of conditions.
 4"""
 5
 6from __future__ import annotations
 7
 8from typing import Callable
 9
10from phml.nodes import Element, Node
11
12Test = list | str | dict | Callable[[Node], bool]
13
14
15def check(
16    node: Node,
17    _test: Test,
18    strict: bool = True,
19) -> bool:
20    """Test if a node passes the given test(s).
21
22    Test Types:
23        - `None`: Just checks that the node is a valid node.
24        - `str`: Checks that the node is an element and the condition == node.tag.
25        - `dict`: Checks all items are valid attributes on the node.
26        and that the values are strictly equal.
27        - `Callable`: Passes the given function the node and it's index, if provided,
28        and checks if the callable returned true.
29        - `list[Test]`: Apply all the rules above for each Test in the list.
30
31    If the `parent` arg is passed so should the `index` arg.
32
33    Args:
34        node (Node): Node to test. Can be any phml node.
35        test (Test): Test to apply to the node. See previous section
36            for more info.
37
38    Returns:
39        True if all tests pass.
40    """
41
42    if isinstance(_test, str):
43        return isinstance(node, Element) and node.tag == _test
44
45    if isinstance(_test, dict):
46        # If dict validate all items with properties are the same
47        # Either in attributes or in
48        if strict:
49            return bool(
50                isinstance(node, Element)
51                and all(
52                    (key in node and (value is True or value == node[key]))
53                    for key, value in _test.items()
54                ),
55            )
56        return bool(
57            isinstance(node, Element)
58            and any(
59                (key in node and (value is True or value == node[key]))
60                for key, value in _test.items()
61            ),
62        )
63
64    if isinstance(_test, list):
65        # If list then recursively apply tests
66        if strict:
67            return bool(
68                all(isinstance(cond, Test) and check(node, cond) for cond in _test),
69            )
70
71        return bool(
72            any(isinstance(cond, Test) and check(node, cond) for cond in _test),
73        )
74
75    if isinstance(_test, Callable):
76        # If callable return result of collable after passing node, index, and parent
77        return _test(node)
78
79    raise TypeError(f"Invalid test condition: {_test}")
def check( node: phml.nodes.Node, _test: Union[list, str, dict, Callable[[phml.nodes.Node], bool]], strict: bool = True) -> bool:
16def check(
17    node: Node,
18    _test: Test,
19    strict: bool = True,
20) -> bool:
21    """Test if a node passes the given test(s).
22
23    Test Types:
24        - `None`: Just checks that the node is a valid node.
25        - `str`: Checks that the node is an element and the condition == node.tag.
26        - `dict`: Checks all items are valid attributes on the node.
27        and that the values are strictly equal.
28        - `Callable`: Passes the given function the node and it's index, if provided,
29        and checks if the callable returned true.
30        - `list[Test]`: Apply all the rules above for each Test in the list.
31
32    If the `parent` arg is passed so should the `index` arg.
33
34    Args:
35        node (Node): Node to test. Can be any phml node.
36        test (Test): Test to apply to the node. See previous section
37            for more info.
38
39    Returns:
40        True if all tests pass.
41    """
42
43    if isinstance(_test, str):
44        return isinstance(node, Element) and node.tag == _test
45
46    if isinstance(_test, dict):
47        # If dict validate all items with properties are the same
48        # Either in attributes or in
49        if strict:
50            return bool(
51                isinstance(node, Element)
52                and all(
53                    (key in node and (value is True or value == node[key]))
54                    for key, value in _test.items()
55                ),
56            )
57        return bool(
58            isinstance(node, Element)
59            and any(
60                (key in node and (value is True or value == node[key]))
61                for key, value in _test.items()
62            ),
63        )
64
65    if isinstance(_test, list):
66        # If list then recursively apply tests
67        if strict:
68            return bool(
69                all(isinstance(cond, Test) and check(node, cond) for cond in _test),
70            )
71
72        return bool(
73            any(isinstance(cond, Test) and check(node, cond) for cond in _test),
74        )
75
76    if isinstance(_test, Callable):
77        # If callable return result of collable after passing node, index, and parent
78        return _test(node)
79
80    raise TypeError(f"Invalid test condition: {_test}")

Test if a node passes the given test(s).

Test Types
  • None: Just checks that the node is a valid node.
  • str: Checks that the node is an element and the condition == node.tag.
  • dict: Checks all items are valid attributes on the node. and that the values are strictly equal.
  • Callable: Passes the given function the node and it's index, if provided, and checks if the callable returned true.
  • list[Test]: Apply all the rules above for each Test in the list.

If the parent arg is passed so should the index arg.

Args
  • node (Node): Node to test. Can be any phml node.
  • test (Test): Test to apply to the node. See previous section for more info.
Returns

True if all tests pass.