Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mar10 committed Oct 6, 2024
1 parent 5961935 commit 5d70297
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 160 deletions.
14 changes: 7 additions & 7 deletions nutree/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,12 +636,13 @@ def add_child(
else:
node = factory(child, parent=self, data_id=data_id, node_id=node_id)

if before is True:
before = 0 # prepend

children = self._children
if children is None:
assert before in (None, True, int, False)
self._children = [node]
elif before is True: # prepend
children.insert(0, node)
elif isinstance(before, int):
children.insert(before, node)
elif before:
Expand Down Expand Up @@ -744,11 +745,9 @@ def move_to(
See :meth:`add_child` for a description of `before`.
"""
assert new_parent is not None
# if new_parent is None:
# new_parent = self._tree._root
# elif
if not isinstance(new_parent, Node):
# it's a Tree
assert isinstance(new_parent, self.tree.__class__)
new_parent = new_parent._root

if new_parent._tree is not self._tree:
Expand All @@ -759,12 +758,13 @@ def move_to(
self._parent._children = None
self._parent = new_parent

if before is True:
before = 0 # prepend

target_siblings = new_parent._children
if target_siblings is None:
assert before in (None, True, False, 0), before
new_parent._children = [self] # type: ignore
elif before is True: # prepend
target_siblings.insert(0, self)
elif isinstance(before, Node):
assert before._parent is new_parent, before
idx = target_siblings.index(before) # raise ValueError if not found
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ addopts = "-ra -q --cov=nutree"
# branch = true
omit = [
"tests/*",
"setup.py",
# nutree/leaves_cli.py
# nutree/cli_common.py
# nutree/monitor/*
Expand Down
270 changes: 179 additions & 91 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def test_basic(self):
# assert tree.last_child() is tree["The Little Prince"]

assert len(records.children) == 2
assert records.children == records.get_children()
assert records.depth() == 1
with pytest.raises(NotImplementedError):
assert tree == tree # __eq__ not implemented
Expand Down Expand Up @@ -301,97 +302,6 @@ def test_relations(self):
assert tree["a11"].get_index() == 0
assert tree["a12"].get_index() == 1

def test_data_id(self):
"""
Tree<'fixture'>
├── A
│ ├── a1
│ │ ├── a11
│ │ ╰── a12
│ ╰── a2
╰── B
├── a1 <-- Clone
╰── b1
╰── b11
"""
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

print(tree.format(repr="{node.data}"))

tree["A"].rename("new_A")

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- new_A
| +- a1
| | +- a11
| | `- a12
| `- a2
`- B
+- a1
`- b1
`- b11
""",
)
assert tree._self_check()

# Reset tree
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

with pytest.raises(AmbiguousMatchError): # not allowed for clones
tree.find_first("a1").rename("new_a1")

with pytest.raises(ValueError): # missing args
tree.find_first("a1").set_data(None)

# Only rename first occurrence:
tree.find_first("a1").set_data("new_a1", with_clones=False)

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- A
| +- new_a1
| | +- a11
| | `- a12
| `- a2
`- B
+- a1
`- b1
`- b11
""",
)
assert tree._self_check()

# Reset tree
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

# Rename all occurences:
tree.find_first("a1").set_data("new_a1", with_clones=True)

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- A
| +- new_a1
| | +- a11
| | `- a12
| `- a2
`- B
+- new_a1
`- b1
`- b11
""",
)
assert tree._self_check()

def test_find(self):
tree = self.tree

Expand Down Expand Up @@ -771,6 +681,7 @@ def test_add(self):
b = tree["B"]
a11 = tree["a11"]
b.prepend_child(a11)
b.add("pre_b", before=True)

a1 = tree["a1"]
a1.prepend_sibling("pre_a1")
Expand All @@ -792,12 +703,143 @@ def test_add(self):
| +- post_a1
| `- a2
`- B
+- pre_b
+- a11
`- b1
`- b11
""",
)

def test_add_tree(self):
tree = fixture.create_tree()

subtree = Tree()
subtree.add("x").add("x1").up(2).add("y").add("y1")

tree.add(subtree, before=1)
assert fixture.check_content(
tree,
"""
Tree<*>
+- A
| +- a1
| | +- a11
| | `- a12
| `- a2
+- x
| `- x1
+- y
| `- y1
`- B
`- b1
`- b11
""",
)

def test_set_data(self):
"""
Tree<'fixture'>
├── A
│ ├── a1
│ │ ├── a11
│ │ ╰── a12
│ ╰── a2
╰── B
├── a1 <-- Clone
╰── b1
╰── b11
"""
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

print(tree.format(repr="{node.data}"))

tree["A"].rename("new_A")

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- new_A
| +- a1
| | +- a11
| | `- a12
| `- a2
`- B
+- a1
`- b1
`- b11
""",
)
assert tree._self_check()

# Reset tree
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

with pytest.raises(AmbiguousMatchError): # not allowed for clones
tree.find_first("a1").rename("new_a1")

with pytest.raises(ValueError): # missing args
tree.find_first("a1").set_data(None)

# Only rename first occurrence:
tree.find_first("a1").set_data("new_a1", with_clones=False)

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- A
| +- new_a1
| | +- a11
| | `- a12
| `- a2
`- B
+- a1
`- b1
`- b11
""",
)
assert tree._self_check()

# Reset tree
tree = fixture.create_tree()
tree["B"].prepend_child("a1")

# Rename all occurences:
tree.find_first("a1").set_data("new_a1", with_clones=True)

assert fixture.check_content(
tree,
"""
Tree<'fixture'>
+- A
| +- new_a1
| | +- a11
| | `- a12
| `- a2
`- B
+- new_a1
`- b1
`- b11
""",
)

assert tree["a2"].data_id == hash("a2")
tree.find("a2").set_data(data=None, data_id=123, with_clones=True)
with pytest.raises(KeyError):
_ = tree["a2"].data_id
assert tree.find(data_id=123)

tree.find(data_id=123).set_data(data="a2_new", data_id=123, with_clones=True)
assert tree.find(data_id=123)

tree.find(data_id=123).set_data(data="a2_new2", data_id=123, with_clones=False)
assert tree.find(data_id=123)

assert tree._self_check()

def test_copy_branch(self):
# Copy a node
tree = fixture.create_tree()
Expand Down Expand Up @@ -1010,6 +1052,45 @@ def _tm(
""",
)

_tm(
source="b1",
target="a1",
before=True,
result="""
Tree<'fixture'>
+- A
| +- a1
| | +- b1
| | | `- b11
| | +- a11
| | `- a12
| `- a2
`- B
""",
)

tree = fixture.create_tree()
tree["b1"].move_to(tree)

assert fixture.check_content(
tree,
"""
Tree<*>
+- A
| +- a1
| | +- a11
| | `- a12
| `- a2
+- B
`- b1
`- b11
""",
)

target_tree = Tree()
with pytest.raises(NotImplementedError):
tree["b1"].move_to(target_tree)


class TestCopy:
def test_node_copy(self):
Expand Down Expand Up @@ -1154,6 +1235,11 @@ def test_filter(self):
"""
tree = fixture.create_tree()

with pytest.raises(ValueError, match="Predicate is required"):
tree.filter(predicate=None) # type: ignore
with pytest.raises(ValueError, match="Predicate is required"):
tree.system_root.filter(predicate=None) # type: ignore

def pred(node):
return "2" not in node.name.lower()

Expand Down Expand Up @@ -1242,6 +1328,8 @@ def pred(node):
# Should use tree.copy() instead:
with pytest.raises(ValueError, match="Predicate is required"):
tree_2 = tree.filtered(predicate=None) # type: ignore
with pytest.raises(ValueError, match="Predicate is required"):
tree_2 = tree.system_root.filtered(predicate=None) # type: ignore

tree_2 = tree.copy()

Expand Down
Loading

0 comments on commit 5d70297

Please sign in to comment.