import unittest class TestNode(unittest.TestCase): def test_is_class(self): from dragiyski.vulkan.registry.xml import Node assert isinstance(Node, type) def test_function_exists_parse_xml(self): from dragiyski.vulkan.registry.xml import parse_xml assert callable(parse_xml) def test_node_simple_xml(self): from dragiyski.vulkan.registry.xml import Node, parse_xml xml_content = ''' Text More Text Some Text More Text Even More Text ''' root = parse_xml(xml_content) assert isinstance(root, Node) assert root.node_name == 'root' assert root.has_attribute('attr') assert root.get_attribute('attr') == 'value' assert 'child' in root.children assert 'child2' in root.children assert root.get('child') is root.children['child'][0] assert root.get('child2') is root.children['child2'][0] child_index = root.child_nodes.index(root.get('child')) child2_index = root.child_nodes.index(root.get('child2')) child3_index = root.child_nodes.index(root.get('child3')) assert child_index < child2_index assert child2_index < child3_index for i in range(len(root.child_nodes)): if i not in (child_index, child2_index, child3_index): assert root.child_nodes[i].node_type == 'text' assert root.child_nodes[i].node_name == '#text' root.set_attribute('attr', 'foo') assert root.get_attribute('attr') == 'foo' assert root.has_attribute('new_attr') is False root.set_attribute('new_attr', 'new_value') assert root.has_attribute('new_attr') is True assert root.get_attribute('new_attr') == 'new_value' root.set_attribute('new_attr', None) assert root.has_attribute('new_attr') is False assert root.get_attribute('new_attr', 'default') == 'default' assert root.get_attribute('new_attr', 5) == 5 assert root.get_attribute('new_attr') is None assert root.has_attribute('not_existing') is False root.set_attribute('not_existing', None) assert root.has_attribute('not_existing') is False assert root.get('not_existing', 'default') == 'default' assert root.get('not_existing', 5) == 5 assert root.get('not_existing') is None child1_node = root.get('child') assert isinstance(child1_node, Node) assert child1_node.node_name == 'child' child2_node = root.get('child2') assert isinstance(child2_node, Node) assert child2_node.node_name == 'child2' child3_node = root.get('child3') assert isinstance(child3_node, Node) assert child3_node.node_name == 'child3' self.assertRaises(Node.MultipleChildrenError, lambda: child3_node.get('text')) assert child1_node.next_sibling_element is child2_node assert child2_node.previous_sibling_element is child1_node assert child2_node.next_sibling_element is child3_node assert child3_node.previous_sibling_element is child2_node assert child1_node.previous_sibling_element is None assert child3_node.next_sibling_element is None assert child3_node.root == root assert root.root == root child3_node.children['text'].clear() assert child3_node.get('text', 'default') == 'default' assert child3_node.get('text', 5) == 5 assert child3_node.get('text') is None assert root.previous_sibling is None assert root.next_sibling is None assert root.child_nodes[0].previous_sibling is None assert root.child_nodes[0].next_sibling is root.child_nodes[1] assert root.child_nodes[1].previous_sibling is root.child_nodes[0] assert root.child_nodes[1].next_sibling is root.child_nodes[2] assert root.child_nodes[-1].previous_sibling is root.child_nodes[-2] assert root.child_nodes[-1].next_sibling is None assert root.get_all('not_existing') == [] def test_node_tree_get_all(self): from dragiyski.vulkan.registry.xml import Node, parse_xml xml_content = ''' Text0 Text1 Text1 With some Text2 before and after. ''' result = parse_xml(xml_content) assert isinstance(result, Node) i = 0 paths = [ [ 'root', 'child', 'test' ], [ 'root', 'child', 'other', 'test'], [ 'root', 'other', 'other', 'subchild', 'nested', 'test' ], ] for node in result.tree_get_all('test'): assert node.get_text() == f'Text{i}' assert node.path == paths[i] i += 1 assert i == 3 def test_node_get_text(self): from dragiyski.vulkan.registry.xml import Node, parse_xml xml_content = ''' Copyright 2015-2025 The Khronos Group Inc. SPDX-License-Identifier: Apache-2.0 OR MIT VkStructureType sType const VkTensorARM tensorTensor that this allocation will be bound to const void* pNext ''' result = parse_xml(xml_content) assert isinstance(result, Node) assert result.get('types').get('type').get_all('member')[0].get_text() == 'VkStructureType sType' assert result.get('types').get('type').get_all('member')[1].get_text() == 'VkTensorARM tensor' assert result.get('types').get('type').get_all('member')[2].get_text() == 'const void* pNext' assert result.get('types').get('type').get_all('member')[0].get_text(skip_comments=True) == 'VkStructureType sType' assert result.get('types').get('type').get_all('member')[1].get_text(skip_comments=True) == 'VkTensorARM tensor' assert result.get('types').get('type').get_all('member')[2].get_text(skip_comments=True) == 'const void* pNext' assert result.get('types').get('type').get_all('member')[0].get_text(skip_comments=False) == 'VkStructureType sType' assert result.get('types').get('type').get_all('member')[1].get_text(skip_comments=False) == 'const VkTensorARM tensorTensor that this allocation will be bound to' assert result.get('types').get('type').get_all('member')[2].get_text(skip_comments=False) == 'const void* pNext' s = result.get('types').get('type').get_text() assert result.get('types').get('type').get_text() == ''' VkStructureType sType VkTensorARM tensor const void* pNext ''' text_list = [ [ '\n', ' ', 'VkStructureType', ' ', 'sType', '\n', ' ', ], [ 'VkTensorARM', ' ', 'tensor', ], [ '\n', ' ', 'const ', 'void', '* ', 'pNext', '\n', ' ', ] ] text_list_without_comment = [ *text_list[0], *text_list[1], *text_list[2], ] text_list_with_comment = [ *text_list[0], 'const ', *text_list[1], 'Tensor that this allocation will be bound to', *text_list[2], ] type_node = result.get('types').get('type') i = 0 for node in type_node.get_text_nodes(): assert node.node_type == 'text' assert node.node_name == '#text' assert node.node_value == text_list_without_comment[i], f'''result.get('types').get('type').child_nodes[{i}].get_text() == {text_list_without_comment[i]!r}''' assert node.get_text() == node.node_value i += 1 i = 0 for node in type_node.get_text_nodes(skip_comments=False): assert node.node_type == 'text' assert node.node_name == '#text' assert node.node_value == text_list_with_comment[i], f'''result.get('types').get('type').child_nodes[{i}].get_text() == {text_list_with_comment[i]!r}''' assert node.get_text() == node.node_value i += 1 invalid_text_node_before = type_node.get_all('member')[0].get('name').child_nodes[0] invalid_text_node_before.node_type = 'invalid' assert invalid_text_node_before.get_text() == '' text_list_without_comment = text_list_without_comment[0:4] + text_list_without_comment[5:] text_list_with_comment = text_list_with_comment[0:4] + text_list_with_comment[5:] invalid_text_node_after = type_node.get_all('member')[2].get('name') invalid_text_node_after.node_type = 'invalid' assert invalid_text_node_after.get_text() == '' text_list_without_comment = text_list_without_comment[:14] + text_list_without_comment[15:] text_list_with_comment = text_list_with_comment[:16] + text_list_with_comment[17:] i = 0 for node in type_node.get_text_nodes(): assert node.node_type == 'text' assert node.node_name == '#text' assert node.node_value == text_list_without_comment[i], f'''result.get('types').get('type').child_nodes[{i}].get_text() == {text_list_without_comment[i]!r}''' assert node.get_text() == node.node_value i += 1 i = 0 for node in type_node.get_text_nodes(skip_comments=False): assert node.node_type == 'text' assert node.node_name == '#text' assert node.node_value == text_list_with_comment[i], f'''result.get('types').get('type').child_nodes[{i}].get_text() == {text_list_with_comment[i]!r}''' assert node.get_text() == node.node_value i += 1 tensor_member_node = type_node.get_all('member')[1] tensor_member_name_node = tensor_member_node.get('name') assert tensor_member_node.get_text_before(tensor_member_name_node) == 'VkTensorARM ' assert tensor_member_node.get_text_after(tensor_member_name_node) == '' assert tensor_member_node.get_text_before(tensor_member_name_node, skip_comments=False) == 'const VkTensorARM ' assert tensor_member_node.get_text_after(tensor_member_name_node, skip_comments=False) == 'Tensor that this allocation will be bound to' assert [node.get_text() for node in type_node.get_text_nodes_before(tensor_member_name_node)] == text_list_without_comment[:8] assert [node.get_text() for node in type_node.get_text_nodes_after(tensor_member_name_node)] == text_list_without_comment[9:] def test_file_path(self): from dragiyski.vulkan.registry.xml import Node, parse_xml from pathlib import Path file = Path(__file__).absolute().parent.joinpath('test_node/xml-test-1.xml') root = parse_xml(file, is_file=True) assert isinstance(root, Node) assert root.line == 2 assert root.column == 0 assert root.file_path == f'{file}:{root.line}:{root.column}' child3_node = root.get('child3') assert isinstance(child3_node, Node) assert child3_node.line == 6 assert child3_node.column == 4 assert child3_node.file_path == f'{file}:{child3_node.line}:{child3_node.column}' def test_file_url(self): from dragiyski.vulkan.registry.xml import Node, parse_xml from pathlib import Path file = Path(__file__).resolve().parent.joinpath('test_node/xml-test-1.xml') root = parse_xml(file, is_file=True) url = file.as_uri() assert isinstance(root, Node) assert root.line == 2 assert root.column == 0 assert root.file_url == f'{url}:{root.line}:{root.column}' child3_node = root.get('child3') assert isinstance(child3_node, Node) assert child3_node.line == 6 assert child3_node.column == 4 assert child3_node.file_url == f'{url}:{child3_node.line}:{child3_node.column}' def test_repr(self): from dragiyski.vulkan.registry.xml import Node, parse_xml from pathlib import Path file = Path(__file__).resolve().parent.joinpath('test_node/xml-test-1.xml') root = parse_xml(file, is_file=True) url = file.as_uri() path = '/'.join(root.path) assert repr(root) == f'' child3_node = root.get('child3') path = '/'.join(child3_node.path) assert repr(child3_node) == f''