Add CLAUDE.md for project guidance and enhance get_object_subtree_with_fields to handle circular references
- Introduced CLAUDE.md to provide comprehensive guidance on the Penpot MCP Server, including project overview, key commands, architecture, and common workflows. - Enhanced the `get_object_subtree_with_fields` function to track visited nodes and handle circular references, ensuring robust tree structure retrieval. - Added tests for circular reference handling in `test_penpot_tree.py` to validate new functionality.
This commit is contained in:
@@ -1087,4 +1087,61 @@ def test_get_object_subtree_with_fields_root_frame():
|
||||
assert result['tree']['type'] == 'frame'
|
||||
assert 'children' in result['tree']
|
||||
assert len(result['tree']['children']) == 1
|
||||
assert result['tree']['children'][0]['name'] == 'Main Container'
|
||||
assert result['tree']['children'][0]['name'] == 'Main Container'
|
||||
|
||||
|
||||
def test_get_object_subtree_with_fields_circular_reference():
|
||||
"""Test handling of circular references in object tree."""
|
||||
file_data = {
|
||||
'data': {
|
||||
'pagesIndex': {
|
||||
'page1': {
|
||||
'name': 'Test Page',
|
||||
'objects': {
|
||||
# Object A references B as parent
|
||||
'object-a': {
|
||||
'type': 'frame',
|
||||
'name': 'Object A',
|
||||
'parentId': 'object-b'
|
||||
},
|
||||
# Object B references A as parent (circular)
|
||||
'object-b': {
|
||||
'type': 'frame',
|
||||
'name': 'Object B',
|
||||
'parentId': 'object-a'
|
||||
},
|
||||
# Object C references itself as parent
|
||||
'object-c': {
|
||||
'type': 'frame',
|
||||
'name': 'Object C',
|
||||
'parentId': 'object-c'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test getting object A - should handle circular reference with B
|
||||
result = get_object_subtree_with_fields(file_data, 'object-a')
|
||||
assert 'error' not in result
|
||||
assert result['tree']['id'] == 'object-a'
|
||||
assert 'children' in result['tree']
|
||||
# Check that object-b appears as a child
|
||||
assert len(result['tree']['children']) == 1
|
||||
assert result['tree']['children'][0]['id'] == 'object-b'
|
||||
# The circular reference appears when object-a appears again as a child of object-b
|
||||
assert 'children' in result['tree']['children'][0]
|
||||
assert len(result['tree']['children'][0]['children']) == 1
|
||||
assert result['tree']['children'][0]['children'][0]['id'] == 'object-a'
|
||||
assert result['tree']['children'][0]['children'][0]['_circular_reference'] == True
|
||||
|
||||
# Test getting object C - should handle self-reference
|
||||
result = get_object_subtree_with_fields(file_data, 'object-c')
|
||||
assert 'error' not in result
|
||||
assert result['tree']['id'] == 'object-c'
|
||||
assert 'children' in result['tree']
|
||||
# Check that object-c appears as its own child with circular reference marker
|
||||
assert len(result['tree']['children']) == 1
|
||||
assert result['tree']['children'][0]['id'] == 'object-c'
|
||||
assert result['tree']['children'][0]['_circular_reference'] == True
|
||||
Reference in New Issue
Block a user