add list insertion; redo filter

This commit is contained in:
Jakob Ketterl 2023-05-05 23:41:38 +02:00
parent 5e60bda758
commit 3b04688d1f
2 changed files with 39 additions and 4 deletions

View file

@ -27,6 +27,12 @@ class ActiveListIndexDeleted(ActiveListChange):
self.oldValue = oldValue
class ActiveListIndexInserted(ActiveListChange):
def __init__(self, index: int, newValue):
self.index = index
self.newValue = newValue
class ActiveListListener(ABC):
@abstractmethod
def onListChange(self, changes: list[ActiveListChange]):
@ -66,9 +72,9 @@ class ActiveListFilterListener(ActiveListListener):
del self.target[idx]
del self.keyMap[idx]
elif change.index not in self.keyMap and self.filter(change.newValue):
# TODO insert, not append
self.target.append(change.newValue)
self.keyMap.append(len(self.target) - 1)
idx = len([x for x in self.keyMap if x < change.index])
self.target.insert(idx, change.newValue)
self.keyMap.insert(idx, change.index)
elif isinstance(change, ActiveListIndexDeleted):
if change.index in self.keyMap:
idx = self.keyMap.index(change.index)
@ -105,6 +111,10 @@ class ActiveList:
def remove(self, value):
self.__delitem__(self.delegate.index(value))
def insert(self, index, value):
self.delegate.insert(index, value)
self.__fireChanges([ActiveListIndexInserted(index, value)])
def map(self, transform: callable):
res = ActiveList([transform(v) for v in self])
self.addListener(ActiveListTransformationListener(transform, res))

View file

@ -1,4 +1,4 @@
from owrx.active.list import ActiveList, ActiveListIndexUpdated, ActiveListIndexAppended, ActiveListIndexDeleted
from owrx.active.list import ActiveList, ActiveListIndexUpdated, ActiveListIndexAppended, ActiveListIndexDeleted, ActiveListIndexInserted
from unittest import TestCase
from unittest.mock import Mock
@ -82,6 +82,24 @@ class ActiveListTest(TestCase):
self.assertEqual(len(list), 1)
self.assertEqual(list[0], "value2")
def testListInsert(self):
list = ActiveList(["value1", "value2"])
list.insert(1, "value1.5")
self.assertEqual(len(list), 3)
self.assertEqual(list[1], "value1.5")
def testListInsertNotification(self):
list = ActiveList(["value1", "value2"])
listenerMock = Mock()
list.addListener(listenerMock)
list.insert(1, "value1.5")
listenerMock.onListChange.assert_called_once()
changes, = listenerMock.onListChange.call_args.args
self.assertEqual(len(changes), 1)
self.assertIsInstance(changes[0], ActiveListIndexInserted)
self.assertEqual(changes[0].index, 1)
self.assertEqual(changes[0].newValue, "value1.5")
def testListComprehension(self):
list = ActiveList(["initialvalue"])
x = [m for m in list]
@ -143,6 +161,13 @@ class ActiveListTest(TestCase):
self.assertEqual(len(filteredList), 3)
self.assertEqual(filteredList[2], 0)
def testActiveFilterUpdatePreservesSequence(self):
list = ActiveList([0, 9, 8, 2, 7, 1, 5])
filteredList = list.filter(lambda x: x < 3)
list[1] = 1
self.assertEqual(len(filteredList), 4)
self.assertEqual(filteredList[1], 1)
def testActiveFilterDelete(self):
list = ActiveList([1, 2, 3, 4, 5])
filteredList = list.filter(lambda x: x < 3)