g13gui: Fix param names and migrate ObserverTestCase

ObserverTestCase is code, not test stuff, so migrate that into the observer
module properly.
This commit is contained in:
June Tate-Gans 2021-04-27 14:57:19 -05:00
parent d5b4957916
commit 3183ae8b2b
2 changed files with 70 additions and 39 deletions

View File

@ -1,5 +1,7 @@
#!/usr/bin/python
import unittest
from enum import Enum
@ -12,7 +14,7 @@ class ChangeType(Enum):
class Observer(object):
"""Simple interface class to handle Observer-style notifications"""
def onSubjectChanged(self, subject, changeType, key, changeData):
def onSubjectChanged(self, subject, changeType, key, data=None):
"""Event handler for observer notifications.
Each subclass of Observer MUST override this method. There is no default
@ -22,7 +24,7 @@ class Observer(object):
changed in its data model.
changeType[ChangeType]: the type of change that occurred.
key[string]: a required name for what field changed.
whatChanged[object]: an optional context-dependent object, dict, or
data[object]: an optional context-dependent object, dict, or
None, specifying what changed. In the case of an ADD or MODIFY,
whatChanged should be the new data. In the case of a DELETE, it should
be the old data (or None).
@ -47,20 +49,20 @@ class Subject(object):
if observer in self._observers:
self._observers.discard(observer)
def addChange(self, type, key, whatChanged=None):
def addChange(self, type, key, data=None):
"""Schedules a change notification for transmitting later.
type[ChangeType]: the type of change that occurred.
key[string]: a required name for what field changed.
whatChanged[object]: an optional context-dependent object, dict, or
data[object]: an optional context-dependent object, dict, or
None, specifying what changed. In the case of an ADD or MODIFY,
whatChanged should be the new data. In the case of a DELETE, it should
be the old data (or None).
"""
if '_changes' not in self.__dict__:
self._changes = [(type, key, whatChanged)]
self._changes = [(type, key, data)]
else:
self._changes.append((type, key, whatChanged))
self._changes.append((type, key, data))
def clearChanges(self):
"""Removes all scheduled changes from the change buffer."""
@ -82,3 +84,53 @@ class Subject(object):
for change in self._changes:
observer.onSubjectChanged(self, *change)
self._changes = []
class ObserverTestCase(Observer, unittest.TestCase):
def __init__(self, methodName):
unittest.TestCase.__init__(self, methodName)
self.changes = []
self.clearChanges()
def onSubjectChanged(self, subject, type, key, data=None):
self.changes.insert(0, {
'subject': subject,
'type': type,
'key': key,
'data': data
})
def assertChangeCount(self, count):
try:
self.assertEqual(len(self.changes), count)
except AssertionError as e:
message = [repr(e), '']
message.append('Changes were:')
num = 1
self.changes.reverse()
for change in self.changes:
message.append('%s: %s' % (num, repr(change)))
num = num + 1
raise AssertionError('\n'.join(message))
def assertChangeNotified(self, subject, type, key):
change = self.changes[-1]
self.assertEqual(change['subject'], subject)
self.assertEqual(change['type'], type)
self.assertEqual(change['key'], key)
def getChangeData(self):
return self.changes[-1]['data']
def assertChangeDataEquals(self, data):
change = self.changes[-1]
self.assertEqual(change['data'], data)
def skipChange(self):
self.nextChange()
def nextChange(self):
self.changes.pop()
def clearChanges(self):
self.changes = []

View File

@ -3,25 +3,6 @@
import unittest
import observer
class TestObserver(observer.Observer):
def __init__(self):
self.changes = []
def onSubjectChanged(self, subject, type, key, whatChanged):
self.changes.insert(0, {
'subject': subject,
'type': type,
'key': key,
'whatChanged': whatChanged
})
def assertChangeNotified(self, subject, type, key):
change = self.changes.pop()
assert(change['subject'] == subject)
assert(change['type'] == type)
assert(change['key'] == key)
return change['whatChanged']
class TestIncorrectObserver(observer.Observer):
pass
@ -31,22 +12,21 @@ class TestSubject(observer.Subject):
pass
class ObserverTestCase(unittest.TestCase):
class ObserverTestCase(observer.ObserverTestCase):
def setUp(self):
self.subject = TestSubject()
def testRegistration(self):
observer = TestObserver()
self.subject.registerObserver(observer)
assert(len(self.subject._observers) == 1)
self.subject.registerObserver(self)
self.assertEqual(len(self.subject._observers), 1)
self.subject.registerObserver(observer)
assert(len(self.subject._observers) == 1)
self.subject.registerObserver(self)
self.assertEqual(len(self.subject._observers), 1)
self.subject.removeObserver(observer)
assert(len(self.subject._observers) == 0)
self.subject.removeObserver(self)
self.assertEqual(len(self.subject._observers), 0)
self.subject.removeObserver(observer)
self.subject.removeObserver(self)
def testSubclassNotificationError(self):
testObserver = TestIncorrectObserver()
@ -61,15 +41,14 @@ class ObserverTestCase(unittest.TestCase):
unittest.fail('Expected NotImplementedError')
def testSubclassNotification(self):
o = TestObserver()
self.subject.registerObserver(o)
self.subject.registerObserver(self)
self.subject.addChange(observer.ChangeType.ADD, 'foo', 'bar')
self.subject.notifyChanged()
result = o.assertChangeNotified(
self.subject, observer.ChangeType.ADD, 'foo')
assert(result == 'bar')
self.assertChangeCount(1)
self.assertChangeNotified(self.subject, observer.ChangeType.ADD, 'foo')
self.assertChangeDataEquals('bar')
if __name__ == '__main__':