feat: initial CTStruct framework
- CTNode: 트리 기본 단위 (전위/후위/BFS 순회, 탐색, 분리) - CTTree: 트리 컨테이너 (빌더 API, TOC, filter/map/merge) - NodeType: 구조/블록/인라인/메타 노드 타입 Enum - MarkdownParser: Markdown → CTTree 파서 - MarkdownRenderer: CTTree → Markdown 렌더러 - JSONRenderer: CTTree → JSON 직렬화 - 27개 단위/통합 테스트 전체 통과
This commit is contained in:
93
tests/test_node.py
Normal file
93
tests/test_node.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
tests/test_node.py
|
||||
CTNode 단위 테스트
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from ctstruct import CTNode, NodeType
|
||||
|
||||
|
||||
class TestCTNodeBasic:
|
||||
def test_create_node(self):
|
||||
n = CTNode(NodeType.PARAGRAPH, "hello")
|
||||
assert n.node_type == NodeType.PARAGRAPH
|
||||
assert n.content == "hello"
|
||||
assert n.is_leaf
|
||||
assert n.is_root
|
||||
|
||||
def test_append_child(self):
|
||||
parent = CTNode(NodeType.SECTION)
|
||||
child = CTNode(NodeType.PARAGRAPH, "child")
|
||||
parent.append(child)
|
||||
assert len(parent) == 1
|
||||
assert child.parent is parent
|
||||
assert not parent.is_leaf
|
||||
|
||||
def test_depth(self):
|
||||
root = CTNode(NodeType.ROOT)
|
||||
sec = CTNode(NodeType.SECTION)
|
||||
para = CTNode(NodeType.PARAGRAPH, "text")
|
||||
root.append(sec)
|
||||
sec.append(para)
|
||||
assert root.depth == 0
|
||||
assert sec.depth == 1
|
||||
assert para.depth == 2
|
||||
|
||||
def test_detach(self):
|
||||
parent = CTNode(NodeType.SECTION)
|
||||
child = CTNode(NodeType.PARAGRAPH, "bye")
|
||||
parent.append(child)
|
||||
child.detach()
|
||||
assert len(parent) == 0
|
||||
assert child.parent is None
|
||||
|
||||
def test_walk_pre(self):
|
||||
root = CTNode(NodeType.ROOT)
|
||||
a = CTNode(NodeType.SECTION)
|
||||
b = CTNode(NodeType.PARAGRAPH, "b")
|
||||
root.append(a)
|
||||
a.append(b)
|
||||
nodes = list(root.walk("pre"))
|
||||
assert nodes[0] is root
|
||||
assert nodes[1] is a
|
||||
assert nodes[2] is b
|
||||
|
||||
def test_walk_bfs(self):
|
||||
root = CTNode(NodeType.ROOT)
|
||||
a = CTNode(NodeType.SECTION)
|
||||
b = CTNode(NodeType.PARAGRAPH, "b")
|
||||
c = CTNode(NodeType.PARAGRAPH, "c")
|
||||
root.append(a)
|
||||
root.append(c)
|
||||
a.append(b)
|
||||
bfs = list(root.walk("bfs"))
|
||||
assert bfs[0] is root
|
||||
# level 1: a, c
|
||||
assert bfs[1] is a
|
||||
assert bfs[2] is c
|
||||
# level 2: b
|
||||
assert bfs[3] is b
|
||||
|
||||
def test_find(self):
|
||||
root = CTNode(NodeType.ROOT)
|
||||
root.append(CTNode(NodeType.HEADING, "h1", {"level": 1}))
|
||||
root.append(CTNode(NodeType.PARAGRAPH, "para"))
|
||||
root.append(CTNode(NodeType.HEADING, "h2", {"level": 2}))
|
||||
headings = root.find(NodeType.HEADING)
|
||||
assert len(headings) == 2
|
||||
|
||||
def test_text_content(self):
|
||||
root = CTNode(NodeType.ROOT)
|
||||
root.append(CTNode(NodeType.PARAGRAPH, "hello "))
|
||||
root.append(CTNode(NodeType.PARAGRAPH, "world"))
|
||||
assert root.text_content() == "hello world"
|
||||
|
||||
def test_siblings(self):
|
||||
parent = CTNode(NodeType.SECTION)
|
||||
a = CTNode(NodeType.PARAGRAPH, "a")
|
||||
b = CTNode(NodeType.PARAGRAPH, "b")
|
||||
c = CTNode(NodeType.PARAGRAPH, "c")
|
||||
parent.append(a)
|
||||
parent.append(b)
|
||||
parent.append(c)
|
||||
assert b.siblings == [a, c]
|
||||
Reference in New Issue
Block a user