phml.utils.validate.check
phml.utils.validate.test
Logic that allows nodes to be tested against a series of conditions.
1"""phml.utils.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 TYPE_CHECKING, Callable, Optional 9 10from phml.nodes import Element 11 12if TYPE_CHECKING: 13 from phml.nodes import All_Nodes, Root 14 15Test = None | str | list | dict | Callable 16 17 18def check( 19 node: All_Nodes, 20 _test: Test, 21 index: Optional[int] = None, 22 parent: Optional[Root | Element] = None, 23 strict: bool = True, 24) -> bool: 25 """Test if a node passes the given test(s). 26 27 Test Types: 28 - `None`: Just checks that the node is a valid node. 29 - `str`: Checks that the test value is == the `node.type`. 30 - `dict`: Checks all items are valid attributes on the node. 31 and that the values are strictly equal. 32 - `Callable`: Passes the given function the node and it's index, if provided, 33 and checks if the callable returned true. 34 - `list[Test]`: Apply all the rules above for each Test in the list. 35 36 If the `parent` arg is passed so should the `index` arg. 37 38 Args: 39 node (All_Nodes): Node to test. Can be any phml node. 40 test (Test): Test to apply to the node. See previous section 41 for more info. 42 index (Optional[int], optional): Index in the parent where the 43 node exists. Defaults to None. 44 parent (Optional[Root | Element], optional): The nodes parent. Defaults to None. 45 46 Returns: 47 True if all tests pass. 48 """ 49 50 if parent is not None: 51 # If parent is given then index has to be also. 52 # Validate index is correct in parent.children 53 if index is None or parent.children[index] != node: 54 return False 55 56 if isinstance(_test, str): 57 # If string then validate that the type is the same 58 return hasattr(node, "type") and node.type == _test 59 60 if isinstance(_test, dict): 61 # If dict validate all items with properties are the same 62 # Either in attributes or in 63 return bool( 64 isinstance(node, Element) 65 and all( 66 (hasattr(node, key) and value == getattr(node, key)) 67 or (hasattr(node, "properties") and key in node.properties and value == node[key]) 68 for key, value in _test.items() 69 ) 70 ) 71 72 if isinstance(_test, list): 73 # If list then recursively apply tests 74 if strict: 75 return bool( 76 all(isinstance(cond, Test) and check(node, cond, index, parent) for cond in _test) 77 ) 78 79 return bool( 80 any(isinstance(cond, Test) and check(node, cond, index, parent) for cond in _test) 81 ) 82 83 if isinstance(_test, Callable): 84 # If callable return result of collable after passing node, index, and parent 85 return _test(node, index, node.parent) 86 87 raise Exception("Invalid test condition")
def
check( node: phml.nodes.root.Root | phml.nodes.element.Element | phml.nodes.text.Text | phml.nodes.comment.Comment | phml.nodes.doctype.DocType | phml.nodes.parent.Parent | phml.nodes.node.Node | phml.nodes.literal.Literal, _test: Union[NoneType, str, list, dict, Callable], index: Optional[int] = None, parent: Union[phml.nodes.element.Element, phml.nodes.root.Root, NoneType] = None, strict: bool = True) -> bool:
19def check( 20 node: All_Nodes, 21 _test: Test, 22 index: Optional[int] = None, 23 parent: Optional[Root | Element] = None, 24 strict: bool = True, 25) -> bool: 26 """Test if a node passes the given test(s). 27 28 Test Types: 29 - `None`: Just checks that the node is a valid node. 30 - `str`: Checks that the test value is == the `node.type`. 31 - `dict`: Checks all items are valid attributes on the node. 32 and that the values are strictly equal. 33 - `Callable`: Passes the given function the node and it's index, if provided, 34 and checks if the callable returned true. 35 - `list[Test]`: Apply all the rules above for each Test in the list. 36 37 If the `parent` arg is passed so should the `index` arg. 38 39 Args: 40 node (All_Nodes): Node to test. Can be any phml node. 41 test (Test): Test to apply to the node. See previous section 42 for more info. 43 index (Optional[int], optional): Index in the parent where the 44 node exists. Defaults to None. 45 parent (Optional[Root | Element], optional): The nodes parent. Defaults to None. 46 47 Returns: 48 True if all tests pass. 49 """ 50 51 if parent is not None: 52 # If parent is given then index has to be also. 53 # Validate index is correct in parent.children 54 if index is None or parent.children[index] != node: 55 return False 56 57 if isinstance(_test, str): 58 # If string then validate that the type is the same 59 return hasattr(node, "type") and node.type == _test 60 61 if isinstance(_test, dict): 62 # If dict validate all items with properties are the same 63 # Either in attributes or in 64 return bool( 65 isinstance(node, Element) 66 and all( 67 (hasattr(node, key) and value == getattr(node, key)) 68 or (hasattr(node, "properties") and key in node.properties and value == node[key]) 69 for key, value in _test.items() 70 ) 71 ) 72 73 if isinstance(_test, list): 74 # If list then recursively apply tests 75 if strict: 76 return bool( 77 all(isinstance(cond, Test) and check(node, cond, index, parent) for cond in _test) 78 ) 79 80 return bool( 81 any(isinstance(cond, Test) and check(node, cond, index, parent) for cond in _test) 82 ) 83 84 if isinstance(_test, Callable): 85 # If callable return result of collable after passing node, index, and parent 86 return _test(node, index, node.parent) 87 88 raise Exception("Invalid test condition")
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 test value is == thenode.type
.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 (All_Nodes): Node to test. Can be any phml node.
- test (Test): Test to apply to the node. See previous section
- for more info.
- index (Optional[int], optional): Index in the parent where the
- node exists. Defaults to None.
- parent (Optional[Root | Element], optional): The nodes parent. Defaults to None.
Returns
True if all tests pass.