vorta/tests/test_treemodel.py

351 lines
11 KiB
Python

from pathlib import PurePath
import pytest
from PyQt6.QtCore import QModelIndex
from vorta.views.partials.treemodel import FileSystemItem, FileTreeModel
class TreeModelImp(FileTreeModel):
def columnCount(self, parent: QModelIndex = QModelIndex()) -> int:
return 1
def _make_filesystemitem(self, path, data):
return super()._make_filesystemitem(path, data)
def _merge_data(self, item, data):
return super()._merge_data(item, data)
class TestFileSystemItem:
def test_tuple(self):
item = FileSystemItem(PurePath('test').parts, 0)
assert item[0] == item.path
assert item[1] == item.data
def test_add(self):
item = FileSystemItem(PurePath('test').parts, 0)
assert len(item.children) == 0
child = FileSystemItem(PurePath('test/hello').parts, 4)
item.add(child)
assert len(item.children) == 1
assert item.children[0] == child
assert child.subpath == 'hello'
assert child._parent == item
child = FileSystemItem(PurePath('test/hello').parts, 8)
with pytest.raises(RuntimeError):
# may not add a child with the same subpath
item.add(child)
# not implemented due to performance reasons:
# child = FileSystemItem((), 8)
# with pytest.raises(ValueError):
# item.add(child) # may not add a child with an empty path
def test_remove(self):
item = FileSystemItem(PurePath('test').parts, 0)
child1 = FileSystemItem(PurePath('test/a').parts, 4)
child2 = FileSystemItem(PurePath('test/b').parts, 3)
child3 = FileSystemItem(PurePath('test/c').parts, 2)
item.add(child1)
item.add(child2)
item.add(child3)
assert len(item.children) == 3
# test remove subpath
item.remove('b')
assert len(item.children) == 2
assert child2 not in item.children
# test remove item
item.remove(child3)
assert len(item.children) == 1
assert child3 not in item.children
# test remove item not present
child = FileSystemItem(PurePath('notpresent').parts, 2)
with pytest.raises(ValueError):
item.remove(child)
child = FileSystemItem((), 2)
with pytest.raises(ValueError):
item.remove(child)
def test_get(self):
item = FileSystemItem(PurePath('test').parts, 0)
child1 = FileSystemItem(PurePath('test/a').parts, 4)
child2 = FileSystemItem(PurePath('test/b').parts, 3)
child3 = FileSystemItem(PurePath('test/c').parts, 2)
item.add(child1)
item.add(child2)
item.add(child3)
# test get inexistent subpath
assert item.get('unknown') is None
assert item.get('unknown', default='default') == 'default'
# get subpath
res = item.get('a')
assert res is not None
assert res[1] == child1
res = item.get('b')
assert res is not None
assert res[1] == child2
# get subpath of empty list
assert child1.get('a') is None
def test_get_subpath(self):
item = FileSystemItem(('test',), 0)
child1 = FileSystemItem(PurePath('test/a').parts, 4)
child2 = FileSystemItem(PurePath('test/b').parts, 3)
child3 = FileSystemItem(PurePath('test/c').parts, 2)
item.add(child1)
item.add(child2)
item.add(child3)
child11 = FileSystemItem(PurePath('test/a/aa').parts, 4)
child1.add(child11)
assert item.get_path(PurePath('a/aa').parts) is child11
assert item.get_path(('b',)) is child2
# test get empty path
assert item.get_path(()) is item
class TestFileTreeModel:
def test_basic_setup(self):
model = TreeModelImp()
assert model.rowCount() == 0
# test FileTreeModel.addItem
model.addItem((('test',), 0))
assert model.rowCount() == 1
item = model.getItem(('test',))
assert item is not None
assert item.subpath == 'test'
assert len(item.children) == 0
assert item.data == 0 # test id
model.addItem((PurePath('/hello'), 1))
model.addItem(FileSystemItem(PurePath('/hello/test').parts, 2))
assert model.rowCount() == 2
item = model.getItem(('/',))
assert item is not None
assert item.subpath == '/'
assert len(item.children) == 1
item = model.getItem(PurePath('/hello/test').parts)
assert item is not None and item.data == 2
# test adding Item to existing parent
model.addItem((PurePath('test/subtest'), 3))
assert model.rowCount() == 2
item = model.getItem(PurePath('test/subtest').parts)
assert item is not None and item.data == 3
# test parent
assert model.parent(model.indexPath(PurePath('test/subtest'))) == model.indexPath(PurePath('test'))
# test index
item1 = model.getItem(('test',))
item2 = model.getItem(PurePath('test/subtest'))
index1 = model.index(1, 0)
assert index1.internalPointer() == item1
assert index1 == model.indexPath(PurePath('test'))
index2 = model.index(0, 0, index1)
assert index2.internalPointer() == item2
assert index2 == model.indexPath(PurePath('test/subtest'))
# test rowCount
assert model.rowCount() == 2
assert model.rowCount(index1) == 1
# test remove
model.removeItem(('test',))
assert model.rowCount() == 1
assert item1 not in model.root.children
model.removeItem(PurePath('/hello/test').parts)
assert model.rowCount() == 1
assert model.getItem(PurePath('/hello/test')) is None
item3 = model.getItem(PurePath('/hello'))
assert len(item3.children) == 0
def test_empty_path(self):
model = TreeModelImp()
assert model.rowCount() == 0
model.addItem(((), None))
assert model.rowCount() == 0
model.addItem((PurePath('.'), None))
assert model.rowCount() == 0
def test_root(self):
model = TreeModelImp()
assert model.getItem(PurePath()) == model.root
def test_flat(self):
items = [
(PurePath('a'), 0),
(PurePath('a/a'), 1),
(PurePath('a/c'), 3),
(PurePath('a/b/a'), 4),
(PurePath('a/b/b'), 5),
(PurePath('a/b'), 2),
(PurePath('b'), 6),
(PurePath('b/a'), 7),
(PurePath('b/b'), 8),
]
model = TreeModelImp()
model.addItems(items)
# test flat representation
model.setMode(model.DisplayMode.FLAT)
assert model.rowCount() == len(items)
assert model.parent(model.index(4, 0)) == QModelIndex()
assert model.rowCount(model.index(3, 0)) == 0
item = model.getItem(PurePath('a/b/a'))
assert item is not None and item.data == 4
# test flat add
model.addItem((PurePath('a/a/a'), 10))
assert model.rowCount() == len(items) + 1
item = model.getItem(PurePath('a/a/a'))
assert item is not None and item.data == 10
# test flat remove
model.removeItem(PurePath('a/a/a'))
assert model.rowCount() == len(items)
assert item not in model._flattened
# test flat indexPath
index = model.indexPath(PurePath('a/b'))
assert index.internalPointer().data == 2
assert model._flattened[index.row()].data == 2
assert index.parent() == QModelIndex()
# test
model.setMode(model.DisplayMode.TREE)
assert model.rowCount() == 2
def test_simplified_tree(self):
items = [
(PurePath('a'), 0),
(PurePath('a/a'), 1),
(PurePath('a/c'), 3),
(PurePath('a/b/a'), 4),
(PurePath('a/b/b'), 5),
(PurePath('a/b'), 2),
(PurePath('b'), 6),
(PurePath('b/a'), 7),
(PurePath('b/b'), 8),
(PurePath('c'), 9),
(PurePath('c/a'), 10),
(PurePath('c/a/b'), 11),
(PurePath('c/a/b/c'), 12),
(PurePath('c/a/b/a'), 13),
(PurePath('c/a/b/a/b/c'), 14),
(PurePath('c/a/b/b/c/a'), 15),
]
model = TreeModelImp()
model.addItems(items)
# test tree representation
model.setMode(model.DisplayMode.SIMPLIFIED_TREE)
assert model.rowCount() == 3
a = model.index(0, 0)
assert model.rowCount(a) == 3
ab = model.index(1, 0, a)
assert model.rowCount(ab) == 2
assert model.parent(ab) == a
# test combined representation
cab = model.index(2, 0)
assert model.rowCount(cab) == 3
assert cab.internalPointer().data == 11
assert model.rowCount(cab) == 3
assert model.parent(cab) == QModelIndex()
cabc = model.index(2, 0, cab)
cababc = model.index(0, 0, cab)
cabbca = model.index(1, 0, cab)
assert cababc.internalPointer().data == 14
assert model.parent(cababc).internalId() == cab.internalId()
assert cabbca.internalPointer().data == 15
assert model.parent(cabbca).internalId() == cab.internalId()
assert cabc.internalPointer().data == 12
# test combined add
model.addItem((PurePath('a/a/a'), 30))
aaa = model.index(0, 0, a)
assert aaa.internalPointer().data == 30
assert model.rowCount(aaa) == 0
model.addItem((PurePath('c/a/a'), 31))
ca = model.index(2, 0)
assert ca.internalPointer().data == 10
assert ca.parent() == QModelIndex()
assert model.rowCount(ca) == 2
caa = model.index(0, 0, ca)
assert caa.internalPointer().data == 31
assert caa.parent().internalId() == ca.internalId()
# test combined remove
model.removeItem(PurePath('a/a/a').parts)
aa = model.index(0, 0, a)
assert aa.internalPointer().data == 1
assert model.rowCount(aa) == 0
model.removeItem(PurePath('c/a/a'))
cab = model.index(2, 0)
assert cab.internalPointer().data == 11
assert model.rowCount(cab) == 3
# test combined indexPath
index = model.indexPath(PurePath('a/b'))
assert index.internalPointer().data == 2
assert index.parent() == a
index = model.indexPath(PurePath('c/a/b'))
assert model.parent(index) == QModelIndex()
assert index.internalPointer().data == 11
assert model.rowCount(index) == 3
index = model.indexPath(PurePath('c/a'))
assert index == QModelIndex()
# test mode change
model.setMode(model.DisplayMode.TREE)
assert model.rowCount() == 3