mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 11:30:06 +01:00
PR 68: update unit tests for pubsub
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@76020 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -58,3 +58,4 @@
|
||||
/wx/*.dylib
|
||||
/wx/libwx_*
|
||||
/wx/locale
|
||||
/unittests/lib_pubsub_provider_actual.py
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
# Automatically generated by TopicTreeAsSpec(**kwargs).
|
||||
# Automatically generated by TopicTreeSpecPrinter(**kwargs).
|
||||
# The kwargs were:
|
||||
# - fileObj: file
|
||||
# - width: 70
|
||||
# - treeDoc: 'Tree docs, can be anything you want....'
|
||||
# - indentStep: 4
|
||||
# - footer: '# End of topic tree definition. Note that application may l...'
|
||||
# - indentStep: 4
|
||||
# - treeDoc: 'Tree docs, can be anything you want....'
|
||||
# - width: 70
|
||||
|
||||
|
||||
'''
|
||||
"""
|
||||
Tree docs, can be anything you want.
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
class test_import_export_no_change2:
|
||||
'''
|
||||
"""
|
||||
Root topic 1.
|
||||
'''
|
||||
"""
|
||||
|
||||
class subtopic_1:
|
||||
'''
|
||||
"""
|
||||
Sub topic 1 of root topic. Docs rely on one blank line for
|
||||
topic doc, and indentation for each argument doc.
|
||||
'''
|
||||
"""
|
||||
|
||||
def msgDataSpec(arg1, arg2=None):
|
||||
'''
|
||||
"""
|
||||
- arg1: some multiline doc
|
||||
for arg1
|
||||
- arg2: some multiline doc
|
||||
for arg2
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
# End of topic tree definition. Note that application may load
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Except for one test, this file tests with auto-creation of topics
|
||||
disabled, as it is more rigorous for testing purposes.
|
||||
Except for one test, this file tests with auto-creation of topics
|
||||
disabled, as it is more rigorous for testing purposes.
|
||||
|
||||
:copyright: Copyright 2006-2009 by Oliver Schoenborn, all rights reserved.
|
||||
:license: BSD, see LICENSE.txt for details.
|
||||
@@ -11,6 +11,7 @@ disabled, as it is more rigorous for testing purposes.
|
||||
import imp_unittest, unittest
|
||||
import wtc
|
||||
|
||||
from wx.lib.pubsub.core import getListenerID
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -21,7 +22,7 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
# Verify that a 'temporary' listener (one that will be garbage collected
|
||||
# as soon as subscribe() returns because there are no strong references to
|
||||
# it) gets immediately unregistered
|
||||
|
||||
|
||||
def listener():
|
||||
pass
|
||||
class Wrapper:
|
||||
@@ -29,12 +30,12 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
self.func = func
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
|
||||
self.pub.subscribe( Wrapper(listener), 'testDOAListenerPubsub')
|
||||
assert not self.pub.getTopic('testDOAListenerPubsub').hasListeners()
|
||||
assert not self.pub.getDefaultTopicMgr().getTopic('testDOAListenerPubsub').hasListeners()
|
||||
assert self.pub.isValid(listener, 'testDOAListenerPubsub')
|
||||
|
||||
|
||||
|
||||
|
||||
def testDeadListener(self):
|
||||
# create a listener for listeners that have died
|
||||
from wx.lib.pubsub.utils.notification import IgnoreNotificationsMixin
|
||||
@@ -48,105 +49,105 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
dl.assertEqual = self.assertEqual
|
||||
self.pub.addNotificationHandler(dl)
|
||||
self.pub.setNotificationFlags(deadListener=True)
|
||||
|
||||
|
||||
# define a topic, subscribe to it, and kill its listener:
|
||||
class TempListener:
|
||||
def __call__(self, **kwargs):
|
||||
def __call__(self, **kwargs):
|
||||
pass
|
||||
def __del__(self):
|
||||
pass #print 'being deleted'
|
||||
tempListener = TempListener()
|
||||
expectLisrStr, _ = self.pub.getListenerID(tempListener)
|
||||
expectLisrStr, _ = getListenerID(tempListener)
|
||||
self.pub.subscribe(tempListener, 'sadTopic')
|
||||
del tempListener
|
||||
|
||||
|
||||
# verify:
|
||||
assert DeathListener.listenerStr.startswith(expectLisrStr), \
|
||||
'"%s" !~ "%s"' % (DeathListener.listenerStr, expectLisrStr)
|
||||
|
||||
|
||||
self.pub.addNotificationHandler(None)
|
||||
self.pub.clearNotificationHandlers()
|
||||
|
||||
|
||||
|
||||
|
||||
def testSubscribe(self):
|
||||
topicName = 'testSubscribe'
|
||||
def proto(a, b, c=None):
|
||||
pass
|
||||
self.pub.getOrCreateTopic(topicName, proto)
|
||||
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic(topicName, proto)
|
||||
|
||||
def listener(a, b, c=None): pass
|
||||
# verify that self.pub.isValid() works too
|
||||
self.pub.validate(listener, topicName)
|
||||
assert self.pub.isValid(listener, topicName)
|
||||
|
||||
self.assertEqual(self.pub.getTopic(topicName).getNumListeners(), 0)
|
||||
self.assertEqual(self.pub.getAssociatedTopics(listener), [])
|
||||
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic(topicName).getNumListeners(), 0)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopicsSubscribed(listener), [])
|
||||
assert not self.pub.isSubscribed(listener, topicName)
|
||||
assert self.pub.subscribe(listener, topicName)
|
||||
assert self.pub.isSubscribed(listener, topicName)
|
||||
def topicNames(listener):
|
||||
return [t.getName() for t in self.pub.getAssociatedTopics(listener)]
|
||||
return [t.getName() for t in self.pub.getDefaultTopicMgr().getTopicsSubscribed(listener)]
|
||||
self.assertEqual(topicNames(listener), [topicName])
|
||||
# should do nothing if already subscribed:
|
||||
assert not self.pub.subscribe(listener, topicName)[1]
|
||||
self.assertEqual(self.pub.getTopic(topicName).getNumListeners(), 1)
|
||||
|
||||
# test self.pub.getAssociatedTopics()
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic(topicName).getNumListeners(), 1)
|
||||
|
||||
# test self.pub.getDefaultTopicMgr().getTopics()
|
||||
self.pub.subscribe(listener, 'lt2', )
|
||||
self.assertEqual(set(topicNames(listener)),
|
||||
self.assertEqual(set(topicNames(listener)),
|
||||
set([topicName,'lt2']))
|
||||
self.pub.subscribe(listener, 'lt1.lst1')
|
||||
self.assertEqual(set(topicNames(listener)),
|
||||
self.assertEqual(set(topicNames(listener)),
|
||||
set([topicName,'lt2','lt1.lst1']))
|
||||
|
||||
|
||||
# test ALL_TOPICS
|
||||
def listenToAll():
|
||||
pass
|
||||
self.pub.subscribe(listenToAll, self.pub.ALL_TOPICS)
|
||||
self.assertEqual(topicNames(listenToAll), [self.pub.ALL_TOPICS])
|
||||
|
||||
|
||||
|
||||
|
||||
def testMissingReqdArgs(self):
|
||||
def proto(a, b, c=None):
|
||||
pass
|
||||
self.pub.getOrCreateTopic('missingReqdArgs', proto)
|
||||
self.assertRaises(self.pub.SenderMissingReqdArgs, self.pub.sendMessage,
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('missingReqdArgs', proto)
|
||||
self.assertRaises(self.pub.SenderMissingReqdMsgDataError, self.pub.sendMessage,
|
||||
'missingReqdArgs', a=1)
|
||||
|
||||
|
||||
|
||||
|
||||
def testSendTopicWithMessage(self):
|
||||
class MyListener:
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
self.heardTopic = False
|
||||
self.listen2Topics = []
|
||||
def listen0(self):
|
||||
def listen0(self):
|
||||
pass
|
||||
def listen1(self, **kwarg):
|
||||
def listen1(self, **kwarg):
|
||||
self.count += 1
|
||||
self.heardTopic = True
|
||||
def listen2(self, msgTopic=self.pub.AUTO_TOPIC, **kwarg):
|
||||
self.listen2Topics.append(msgTopic.getName())
|
||||
|
||||
|
||||
my = MyListener()
|
||||
self.pub.subscribe(my.listen0, 'testSendTopic')
|
||||
self.pub.subscribe(my.listen1, 'testSendTopic')
|
||||
self.pub.subscribe(my.listen2, 'testSendTopic')
|
||||
|
||||
|
||||
self.pub.sendMessage('testSendTopic')
|
||||
self.assertEqual(my.count, 1)
|
||||
self.assertEqual(my.heardTopic, True)
|
||||
|
||||
|
||||
self.pub.subscribe(my.listen0, 'testSendTopic.subtopic')
|
||||
self.pub.subscribe(my.listen1, 'testSendTopic.subtopic')
|
||||
self.pub.subscribe(my.listen2, 'testSendTopic.subtopic')
|
||||
|
||||
|
||||
self.pub.sendMessage('testSendTopic.subtopic')
|
||||
self.assertEqual(my.count, 3)
|
||||
self.assertEqual([], [topic for topic in my.listen2Topics
|
||||
self.assertEqual([], [topic for topic in my.listen2Topics
|
||||
if topic not in ('testSendTopic', 'testSendTopic.subtopic')] )
|
||||
|
||||
|
||||
|
||||
|
||||
def testAcceptAllArgs(self):
|
||||
def listen(arg1=None):
|
||||
pass
|
||||
@@ -154,19 +155,19 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
pass
|
||||
def listenAllArgs2(arg1=None, msgTopic=self.pub.AUTO_TOPIC, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
self.pub.subscribe(listen, 'testAcceptAllArgs')
|
||||
|
||||
|
||||
self.pub.subscribe(listenAllArgs, 'testAcceptAllArgs')
|
||||
self.pub.subscribe(listenAllArgs2, 'testAcceptAllArgs')
|
||||
|
||||
|
||||
self.pub.subscribe(listenAllArgs2, 'testAcceptAllArgs.subtopic')
|
||||
self.pub.subscribe(listenAllArgs, 'testAcceptAllArgs.subtopic')
|
||||
|
||||
|
||||
|
||||
|
||||
def testUnsubAll(self):
|
||||
def lisnr1():
|
||||
pass
|
||||
pass
|
||||
def lisnr2():
|
||||
pass
|
||||
class MyListener:
|
||||
@@ -180,127 +181,128 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
lisnr4 = lisnr3.meth
|
||||
def lisnrSub(listener=None, topic=None, newSub=None): pass
|
||||
self.pub.subscribe(lisnrSub, 'pubsub.subscribe')
|
||||
self.assertEqual(self.pub.getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
|
||||
def subAll():
|
||||
self.pub.subscribe(lisnr1, 'testUnsubAll')
|
||||
self.pub.subscribe(lisnr2, 'testUnsubAll')
|
||||
self.pub.subscribe(lisnr3, 'testUnsubAll')
|
||||
self.pub.subscribe(lisnr4, 'testUnsubAll')
|
||||
self.assertEqual(self.pub.getTopic('testUnsubAll').getNumListeners(), 4)
|
||||
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testUnsubAll').getNumListeners(), 4)
|
||||
|
||||
def filter(lisnr):
|
||||
passes = str(lisnr).endswith('meth')
|
||||
return passes
|
||||
|
||||
|
||||
# test unsub many non-pubsub topic listeners
|
||||
subAll()
|
||||
self.pub.unsubAll('testUnsubAll')
|
||||
self.assertEqual(self.pub.getTopic('testUnsubAll').getNumListeners(), 0)
|
||||
self.assertEqual(self.pub.getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testUnsubAll').getNumListeners(), 0)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
# now same but with filter:
|
||||
subAll()
|
||||
unsubed = self.pub.unsubAll('testUnsubAll', listenerFilter=filter)
|
||||
self.assertEqual(self.pub.getTopic('testUnsubAll').getNumListeners(), 3)
|
||||
self.assertEqual(self.pub.getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testUnsubAll').getNumListeners(), 3)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
|
||||
# test unsub all listeners of all topics
|
||||
subAll()
|
||||
self.assertEqual(self.pub.getTopic('testUnsubAll').getNumListeners(), 4)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testUnsubAll').getNumListeners(), 4)
|
||||
unsubed = self.pub.unsubAll(listenerFilter=filter)
|
||||
self.assertEqual(unsubed, [lisnr4])
|
||||
self.assertEqual(self.pub.getTopic('testUnsubAll').getNumListeners(), 3)
|
||||
self.assertEqual(self.pub.getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testUnsubAll').getNumListeners(), 3)
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('pubsub.subscribe').getNumListeners(), 1)
|
||||
unsubed = set( self.pub.unsubAll() )
|
||||
expect = set([lisnr1, lisnrSub, lisnr3, lisnr2])
|
||||
# at least all the 'expected' ones were unsub'd; will be others if this
|
||||
# test is run after other unit tests in same nosetests run
|
||||
assert unsubed >= expect
|
||||
|
||||
|
||||
|
||||
|
||||
def testSendForUndefinedTopic(self):
|
||||
self.pub.sendMessage('testSendForUndefinedTopic')
|
||||
assert self.pub.getTopic('testSendForUndefinedTopic')
|
||||
self.assertEqual(self.pub.getTopic('testSendForUndefinedTopic').getArgs(),
|
||||
assert self.pub.getDefaultTopicMgr().getTopic('testSendForUndefinedTopic')
|
||||
self.assertEqual(self.pub.getDefaultTopicMgr().getTopic('testSendForUndefinedTopic').getArgs(),
|
||||
(None, None))
|
||||
|
||||
|
||||
# must also check for subtopics if parents have listeners since
|
||||
# filtering of args is affected
|
||||
def listener():
|
||||
pass
|
||||
self.pub.subscribe(listener, 'testSendForUndefinedTopic')
|
||||
self.pub.sendMessage('testSendForUndefinedTopic.subtopic', msg='something')
|
||||
|
||||
|
||||
def testTopicUnspecifiedError(self):
|
||||
self.assertRaises(self.pub.ListenerSpecIncomplete, self.pub.setTopicUnspecifiedFatal)
|
||||
#pub.TopicDefnError, pub.setTopicUnspecifiedFatal
|
||||
self.assertRaises(self.pub.TopicDefnError, self.pub.setTopicUnspecifiedFatal)
|
||||
self.pub.setTopicUnspecifiedFatal(checkExisting=False)
|
||||
def fn():
|
||||
pass
|
||||
LSI = self.pub.ListenerSpecIncomplete
|
||||
LSI = self.pub.TopicDefnError
|
||||
self.assertRaises(LSI, self.pub.sendMessage, 'testTopicUnspecifiedError')
|
||||
self.assertRaises(LSI, self.pub.subscribe, fn, 'testTopicUnspecifiedError')
|
||||
self.pub.setTopicUnspecifiedFatal(False)
|
||||
self.pub.sendMessage('testTopicUnspecifiedError')
|
||||
self.pub.subscribe(fn, 'testTopicUnspecifiedError')
|
||||
|
||||
|
||||
|
||||
|
||||
def testArgSpecDerivation(self):
|
||||
def ok_0():
|
||||
pass
|
||||
|
||||
|
||||
def ok_1(arg1):
|
||||
pass
|
||||
def err_11(arg1=None):
|
||||
pass # required can't become optional!
|
||||
def err_12(arg2):
|
||||
pass # parent's arg1 missing
|
||||
|
||||
|
||||
def ok_2(arg1=None):
|
||||
pass
|
||||
def ok_21(arg1):
|
||||
pass # optional can become required
|
||||
def err_22(arg2):
|
||||
pass # parent's arg1 missing
|
||||
|
||||
|
||||
# with getOrCreateTopic(topic, proto), the 'required args' set
|
||||
# is garanteed to be a subset of 'all args'
|
||||
self.pub.getOrCreateTopic('tasd', ok_0)
|
||||
self.pub.getOrCreateTopic('tasd.t_1', ok_1)
|
||||
self.assertRaises(self.pub.ListenerSpecInvalid, self.pub.getOrCreateTopic,
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('tasd', ok_0)
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('tasd.t_1', ok_1)
|
||||
self.assertRaises(self.pub.MessageDataSpecError, self.pub.getDefaultTopicMgr().getOrCreateTopic,
|
||||
'tasd.t_1.t_11', err_11)
|
||||
self.assertRaises(self.pub.ListenerSpecInvalid, self.pub.getOrCreateTopic,
|
||||
self.assertRaises(self.pub.MessageDataSpecError, self.pub.getDefaultTopicMgr().getOrCreateTopic,
|
||||
'tasd.t_1.t_12', err_12)
|
||||
self.pub.getOrCreateTopic('tasd.t_2', ok_2)
|
||||
self.pub.getOrCreateTopic('tasd.t_2.t_21', ok_21)
|
||||
self.assertRaises(self.pub.ListenerSpecInvalid, self.pub.getOrCreateTopic,
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('tasd.t_2', ok_2)
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('tasd.t_2.t_21', ok_21)
|
||||
self.assertRaises(self.pub.MessageDataSpecError, self.pub.getDefaultTopicMgr().getOrCreateTopic,
|
||||
'tasd.t_2.t_22', err_22)
|
||||
|
||||
|
||||
# with newTopic(), 'required args' specified separately so
|
||||
# verify that errors caught
|
||||
def check(subName, required=(), **args):
|
||||
tName = 'tasd.'+subName
|
||||
try:
|
||||
self.pub.newTopic(tName, 'desc', required, **args)
|
||||
msg = 'Should have raised self.pub.ListenerSpecInvalid for %s, %s, %s'
|
||||
self.pub.getDefaultTopicMgr().newTopic(tName, 'desc', required, **args)
|
||||
msg = 'Should have raised self.pub.MessageDataSpecError for %s, %s, %s'
|
||||
assert False, msg % (tName, required, args)
|
||||
except self.pub.ListenerSpecInvalid, exc:
|
||||
except self.pub.MessageDataSpecError, exc:
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
self.pub.newTopic('tasd.t_1.t_13', 'desc', ('arg1',), arg1='docs for arg1') # ok_1
|
||||
|
||||
self.pub.getDefaultTopicMgr().newTopic('tasd.t_1.t_13', 'desc', ('arg1',), arg1='docs for arg1') # ok_1
|
||||
check('t_1.t_14', arg1='docs for arg1') # err_11
|
||||
check('t_1.t_15', ('arg2',), arg2='docs for arg2') # err_12
|
||||
|
||||
self.pub.newTopic('tasd.t_2.t_23', 'desc', ('arg1',), arg1='docs for arg1') # ok_21
|
||||
|
||||
self.pub.getDefaultTopicMgr().newTopic('tasd.t_2.t_23', 'desc', ('arg1',), arg1='docs for arg1') # ok_21
|
||||
check('t_2.t_24', ('arg2',), arg2='docs for arg2') # err_22
|
||||
|
||||
|
||||
# check when no inheritence involved
|
||||
# reqd args wrong
|
||||
check('t_1.t_16', ('arg1',), arg2='docs for arg2')
|
||||
check('t_1.t_17', ('arg2',), arg1='docs for arg1')
|
||||
check('t_3', ('arg1',), arg2='docs for arg2')
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -308,4 +310,3 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -18,19 +18,19 @@ def throws():
|
||||
|
||||
class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
|
||||
|
||||
|
||||
def testHandleExcept1a(self):
|
||||
from wx.lib.pubsub.utils.exchandling import ExcPublisher
|
||||
excPublisher = ExcPublisher(self.pub.getDefaultTopicMgr() )
|
||||
self.pub.setListenerExcHandler(excPublisher)
|
||||
|
||||
|
||||
# create a listener that raises an exception:
|
||||
from lib_pubsub_except_raisinglistener import getRaisingListener
|
||||
raisingListener = getRaisingListener()
|
||||
|
||||
|
||||
self.pub.setNotificationFlags(all=False)
|
||||
self.pub.subscribe(raisingListener, 'testHandleExcept1a')
|
||||
|
||||
|
||||
# first test when a listener raises an exception and exception listener also raises!
|
||||
class BadUncaughtExcListener:
|
||||
def __call__(self, listenerStr=None, excTraceback=None):
|
||||
@@ -39,13 +39,13 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
self.pub.subscribe(handler, ExcPublisher.topicUncaughtExc)
|
||||
self.assertRaises(self.pub.ExcHandlerError, self.pub.sendMessage,
|
||||
'testHandleExcept1a')
|
||||
|
||||
|
||||
def testHandleExcept1b(self):
|
||||
# create a listener that raises an exception:
|
||||
from lib_pubsub_except_raisinglistener import getRaisingListener
|
||||
raisingListener = getRaisingListener()
|
||||
self.pub.subscribe(raisingListener, 'testHandleExcept1b')
|
||||
|
||||
|
||||
# subscribe a good exception listener and validate
|
||||
# create the listener for uncaught exceptions in listeners:
|
||||
class UncaughtExcListener:
|
||||
@@ -67,43 +67,43 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
msg = excTraceback.getFormattedString()
|
||||
assert msg.startswith(' File')
|
||||
assert msg.endswith("global name 'RuntimeError2' is not defined\n")
|
||||
|
||||
|
||||
from wx.lib.pubsub.utils.exchandling import ExcPublisher
|
||||
topic = self.pub.getTopic(ExcPublisher.topicUncaughtExc)
|
||||
topic = self.pub.getDefaultTopicMgr().getTopic(ExcPublisher.topicUncaughtExc)
|
||||
assert not topic.hasListeners()
|
||||
handler = UncaughtExcListener()
|
||||
handler.assertEqual = self.assertEqual
|
||||
self.pub.subscribe(handler, ExcPublisher.topicUncaughtExc)
|
||||
self.pub.sendMessage('testHandleExcept1b')
|
||||
|
||||
|
||||
# verify that listener isn't stuck in a cyclic reference by sys.exc_info()
|
||||
del raisingListener
|
||||
assert not self.pub.getTopic('testHandleExcept1b').hasListeners()
|
||||
|
||||
|
||||
assert not self.pub.getDefaultTopicMgr().getTopic('testHandleExcept1b').hasListeners()
|
||||
|
||||
|
||||
def testHandleExcept2(self):
|
||||
#Test sendMessage when one handler, then change handler and verify changed
|
||||
testTopic = 'testTopics.testHandleExcept2'
|
||||
self.pub.subscribe(throws, testTopic)
|
||||
self.pub.setListenerExcHandler(None)
|
||||
#pubsub.utils.notification.useNotifyByWriteFile()
|
||||
#assert_equal( self.pub.getTopic(testTopic).getNumListeners(), 1 )
|
||||
|
||||
#assert_equal( self.pub.getDefaultTopicMgr().getTopic(testTopic).getNumListeners(), 1 )
|
||||
|
||||
expect = None
|
||||
|
||||
|
||||
def validate(className):
|
||||
global expect
|
||||
assert expect == className
|
||||
expect = None
|
||||
|
||||
|
||||
class MyExcHandler:
|
||||
def __call__(self, listener, topicObj):
|
||||
validate(self.__class__.__name__)
|
||||
|
||||
|
||||
class MyExcHandler2:
|
||||
def __call__(self, listener, topicObj):
|
||||
validate(self.__class__.__name__)
|
||||
|
||||
|
||||
def doHandling(HandlerClass):
|
||||
global expect
|
||||
expect = HandlerClass.__name__ #'MyExcHandler'
|
||||
@@ -111,32 +111,32 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
self.pub.setListenerExcHandler(excHandler)
|
||||
self.pub.sendMessage(testTopic)
|
||||
assert expect is None
|
||||
|
||||
|
||||
doHandling(MyExcHandler)
|
||||
doHandling(MyExcHandler2)
|
||||
|
||||
|
||||
# restore to no handling and verify:
|
||||
self.pub.setListenerExcHandler(None)
|
||||
self.assertRaises(RuntimeError, self.pub.sendMessage, testTopic)
|
||||
|
||||
|
||||
|
||||
|
||||
def testNoExceptionHandling1(self):
|
||||
self.pub.setListenerExcHandler(None)
|
||||
|
||||
|
||||
def raises():
|
||||
raise RuntimeError('test')
|
||||
self.pub.getOrCreateTopic('testNoExceptionTrapping')
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('testNoExceptionTrapping')
|
||||
self.pub.subscribe(raises, 'testNoExceptionTrapping')
|
||||
self.assertRaises(RuntimeError, self.pub.sendMessage, 'testNoExceptionTrapping')
|
||||
|
||||
|
||||
|
||||
|
||||
def testNoExceptionHandling2(self):
|
||||
testTopic = 'testTopics.testNoExceptionHandling'
|
||||
self.pub.subscribe(throws, testTopic)
|
||||
assert self.pub.getListenerExcHandler() is None
|
||||
self.assertRaises(RuntimeError, self.pub.sendMessage, testTopic)
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import wtc
|
||||
|
||||
from wx.lib.pubsub.core.weakmethod import WeakMethod
|
||||
from wx.lib.pubsub.core import listener
|
||||
from wx.lib.pubsub.core.listener import (
|
||||
from wx.lib.pubsub.core.listener import (
|
||||
Listener, ListenerValidator,
|
||||
#ListenerInadequate,
|
||||
ListenerMismatchError,
|
||||
CallArgsInfo,
|
||||
getArgs)
|
||||
|
||||
@@ -32,7 +32,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
def listener0(msgTopic = Listener.AUTO_TOPIC):
|
||||
pass
|
||||
CallArgsInfo(listener0, 0)
|
||||
|
||||
|
||||
def listener1(arg1, msgTopic = Listener.AUTO_TOPIC):
|
||||
pass
|
||||
CallArgsInfo(listener1, 1)
|
||||
@@ -42,7 +42,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
# Test when ValidatorSameKwargsOnly used, ie when args in
|
||||
# listener and topic must be exact match (unless *arg).
|
||||
AA = Listener.AUTO_TOPIC
|
||||
|
||||
|
||||
# test for topic that has no arg/kwargs in topic message spec (TMS)
|
||||
def same():
|
||||
pass
|
||||
@@ -54,22 +54,22 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
def extraKwarg(a=1):
|
||||
pass
|
||||
|
||||
|
||||
# no arg/kwarg in topic message spec (TMS)
|
||||
validator = ListenerValidator([], [])
|
||||
validate = validator.validate
|
||||
|
||||
|
||||
validate(same) # ok: same
|
||||
validate(varargs) # ok: *args/**kwargs
|
||||
validate(autoArg) # ok: extra but AUTO_TOPIC
|
||||
self.assertRaises(ListenerInadequate, validate, extraArg) # E: extra arg
|
||||
self.assertRaises(ListenerInadequate, validate, extraKwarg) # E: extra kwarg
|
||||
|
||||
self.assertRaises(ListenerMismatchError, validate, extraArg) # E: extra arg
|
||||
self.assertRaises(ListenerMismatchError, validate, extraKwarg) # E: extra kwarg
|
||||
|
||||
def test2_Validation1(self):
|
||||
# one arg/kwarg in topic
|
||||
validator = ListenerValidator(['a'], ['b'])
|
||||
validate = validator.validate
|
||||
|
||||
|
||||
def same(a, b=1):
|
||||
pass
|
||||
def same2(a=2, b=1):
|
||||
@@ -78,7 +78,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
def varkwargs_a(a, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def opt_reqd(b, **kwargs):
|
||||
pass
|
||||
def missing_arg(b=1):
|
||||
@@ -93,30 +93,30 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
def extra_arg2(a,b,c=2):
|
||||
pass
|
||||
|
||||
|
||||
validate(same) # ok: same
|
||||
validate(same2) # ok: same even if a now has default value
|
||||
validate(varkwargs_a) # ok: has **kwargs
|
||||
validate(varkwargs) # ok: has **kwargs
|
||||
|
||||
self.assertRaises(ListenerInadequate, validate, opt_reqd) # E: b now required
|
||||
self.assertRaises(ListenerInadequate, validate, missing_arg) # E: missing arg
|
||||
self.assertRaises(ListenerInadequate, validate, missing_kwarg) # E: missing kwarg
|
||||
self.assertRaises(ListenerInadequate, validate, extra_kwarg1) # E: extra kwarg
|
||||
self.assertRaises( ListenerInadequate, validate, extra_kwarg2) # E: extra kwarg
|
||||
self.assertRaises( ListenerInadequate, validate, extra_arg1) # E: extra arg
|
||||
self.assertRaises( ListenerInadequate, validate, extra_arg2) # E: extra arg
|
||||
|
||||
self.assertRaises(ListenerMismatchError, validate, opt_reqd) # E: b now required
|
||||
self.assertRaises(ListenerMismatchError, validate, missing_arg) # E: missing arg
|
||||
self.assertRaises(ListenerMismatchError, validate, missing_kwarg) # E: missing kwarg
|
||||
self.assertRaises(ListenerMismatchError, validate, extra_kwarg1) # E: extra kwarg
|
||||
self.assertRaises( ListenerMismatchError, validate, extra_kwarg2) # E: extra kwarg
|
||||
self.assertRaises( ListenerMismatchError, validate, extra_arg1) # E: extra arg
|
||||
self.assertRaises( ListenerMismatchError, validate, extra_arg2) # E: extra arg
|
||||
|
||||
|
||||
def test3_IsCallable(self):
|
||||
# Test the proper trapping of non-callable and certain types of
|
||||
# callable objects.
|
||||
|
||||
|
||||
# validate different types of callables
|
||||
validator = ListenerValidator([], [])
|
||||
# not a function:
|
||||
notAFunc = 1 # just pick something that is not a function
|
||||
self.assertRaises(ListenerInadequate, validator.validate, notAFunc)
|
||||
self.assertRaises(ListenerMismatchError, validator.validate, notAFunc)
|
||||
# a regular function:
|
||||
def aFunc():
|
||||
pass
|
||||
@@ -131,18 +131,18 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
foo = Foo()
|
||||
validator.validate(foo)
|
||||
validator.validate(foo.meth)
|
||||
|
||||
|
||||
|
||||
|
||||
def test4_WantTopic(self):
|
||||
# Test the correct determination of whether want topic
|
||||
# auto-passed during sendMessage() calls.
|
||||
|
||||
|
||||
# first check proper breakdown of listener args:
|
||||
def listener(a, b=1):
|
||||
pass
|
||||
argsInfo = CallArgsInfo(listener, 0)
|
||||
self.assertEqual(None, argsInfo.autoTopicArgName )
|
||||
|
||||
|
||||
msgTopic = 'auto'
|
||||
class MyListener:
|
||||
def method(self, a, b=1, auto=Listener.AUTO_TOPIC):
|
||||
@@ -151,13 +151,13 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
argsInfo = getArgs(listener.method)
|
||||
self.assertEqual(msgTopic, argsInfo.autoTopicArgName )
|
||||
self.assertEqual(['a','b'], argsInfo.allParams )
|
||||
|
||||
|
||||
# now some white box testing of validator that makes use of args info:
|
||||
def checkWantTopic(validate, listener, wantTopicAsArg=None):
|
||||
argsInfo = getArgs(listener)
|
||||
self.assertEqual(argsInfo.autoTopicArgName, wantTopicAsArg)
|
||||
validate(listener)
|
||||
|
||||
|
||||
validator = ListenerValidator([], ['a'])
|
||||
validate = validator.validate
|
||||
def noWant(a=1):
|
||||
@@ -166,7 +166,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
checkWantTopic(validate, noWant)
|
||||
checkWantTopic(validate, want1, msgTopic)
|
||||
|
||||
|
||||
validator = ListenerValidator(['a'], ['b'])
|
||||
validate = validator.validate
|
||||
|
||||
@@ -176,18 +176,18 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
checkWantTopic(validate, noWant2)
|
||||
checkWantTopic(validate, want2, msgTopic)
|
||||
|
||||
|
||||
# topic that has Listener.AUTO_TOPIC as an arg rather than kwarg
|
||||
validator = ListenerValidator([msgTopic], ['b'])
|
||||
validate = validator.validate
|
||||
def noWant3(auto, b=1):
|
||||
pass
|
||||
checkWantTopic(validate, noWant3)
|
||||
|
||||
|
||||
def test5_DOAListeners(self):
|
||||
|
||||
|
||||
def test5_DOAListeners(self):
|
||||
# Test "dead on arrival"
|
||||
|
||||
|
||||
# test DOA of unbound method
|
||||
def getListener1():
|
||||
class DOA:
|
||||
@@ -195,7 +195,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
Listener( DOA.tmpFn, ArgsInfoMock() )
|
||||
self.assertRaises(ValueError, getListener1)
|
||||
|
||||
|
||||
# test DOA of tmp callable:
|
||||
def getListener2():
|
||||
def fn():
|
||||
@@ -207,25 +207,25 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
def onDead(listenerObj):
|
||||
pass
|
||||
|
||||
|
||||
# check dead-on-arrival when no death callback specified:
|
||||
doa1 = Listener( Wrapper(fn), ArgsInfoMock() )
|
||||
assert doa1.getCallable() is None
|
||||
assert doa1.isDead()
|
||||
self.assertRaises(RuntimeError, doa1, None, {})
|
||||
|
||||
|
||||
# check dead-on-arrival when a death callback specified:
|
||||
doa2 = Listener( Wrapper(fn), ArgsInfoMock(), onDead )
|
||||
assert doa2.getCallable() is None
|
||||
assert doa2.isDead()
|
||||
self.assertRaises(RuntimeError, doa2, None, {})
|
||||
|
||||
|
||||
getListener2()
|
||||
|
||||
|
||||
|
||||
|
||||
def test6_ListenerEq(self):
|
||||
# Test equality tests of two listeners
|
||||
|
||||
|
||||
def listener1():
|
||||
pass
|
||||
def listener2():
|
||||
@@ -241,7 +241,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
assert listener1 in ll
|
||||
assert listener2 not in ll
|
||||
self.assertEqual(ll.index(listener1), 0)
|
||||
|
||||
|
||||
# now for class method listener:
|
||||
class MyListener:
|
||||
def __call__(self):
|
||||
@@ -256,22 +256,22 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
self.assertEqual (l3, l3)
|
||||
self.assertEqual (l3, listener3)
|
||||
self.assertNotEqual (l3, listener3.__call__)
|
||||
|
||||
|
||||
l4 = Listener(listener3.meth, ArgsInfoMock())
|
||||
self.assertEqual (l4, l4)
|
||||
self.assertNotEqual (l4, l3)
|
||||
self.assertNotEqual (l4, l2)
|
||||
self.assertNotEqual (l4, listener3.__call__)
|
||||
self.assertEqual (l4, listener3.meth)
|
||||
|
||||
|
||||
|
||||
|
||||
def test7_DyingListenersClass(self):
|
||||
# Test notification callbacks when listener dies
|
||||
|
||||
|
||||
# test dead listener notification
|
||||
def onDead(weakListener):
|
||||
lsrs.remove(weakListener)
|
||||
|
||||
|
||||
def listener1():
|
||||
pass
|
||||
def listener2():
|
||||
@@ -282,7 +282,7 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
lsrs.append(Listener(listener1, ArgsInfoMock(False), onDead=onDead))
|
||||
lsrs.append(Listener(listener2, ArgsInfoMock(False), onDead=onDead))
|
||||
lsrs.append(Listener(listener3, ArgsInfoMock(False), onDead=onDead))
|
||||
|
||||
|
||||
# now force some listeners to die, verify lsrs list
|
||||
self.assertEqual(len(lsrs), 3)
|
||||
del listener1
|
||||
@@ -294,17 +294,17 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
self.assertEqual(lsrs[0], listener3)
|
||||
del listener3
|
||||
self.assertEqual(len(lsrs), 0)
|
||||
|
||||
|
||||
|
||||
|
||||
def test8_getArgsBadListener(self):
|
||||
self.assertRaises(ListenerInadequate, getArgs, 1)
|
||||
self.assertRaises(ListenerMismatchError, getArgs, 1)
|
||||
try:
|
||||
getArgs(1)
|
||||
except ListenerInadequate, exc:
|
||||
except ListenerMismatchError, exc:
|
||||
msg = 'Listener "int" (from module "__main__") inadequate: type "int" not supported'
|
||||
self.assertEqual(str(exc), msg)
|
||||
|
||||
|
||||
|
||||
|
||||
def test10_weakMethod(self):
|
||||
class Foo:
|
||||
def meth(self):
|
||||
@@ -312,11 +312,11 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
foo = Foo()
|
||||
wm = WeakMethod(foo.meth)
|
||||
str(wm)
|
||||
|
||||
|
||||
|
||||
|
||||
def test11_testNaming(self):
|
||||
aiMock = ArgsInfoMock()
|
||||
|
||||
|
||||
# define various type of listeners
|
||||
def fn():
|
||||
pass
|
||||
@@ -325,23 +325,23 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTestCase):
|
||||
pass
|
||||
def meth(self):
|
||||
pass
|
||||
|
||||
|
||||
ll = Listener(fn, aiMock)
|
||||
self.assertEqual(ll.typeName(), "fn")
|
||||
self.assertEqual(ll.module(), "test_lib_pubsub_listener")
|
||||
assert not ll.wantsTopicObjOnCall()
|
||||
|
||||
|
||||
foo = Foo()
|
||||
ll = Listener(foo, aiMock)
|
||||
self.assertEqual(ll.typeName(), "Foo")
|
||||
self.assertEqual(ll.module(), "test_lib_pubsub_listener")
|
||||
assert not ll.wantsTopicObjOnCall()
|
||||
|
||||
|
||||
ll = Listener(foo.meth, ArgsInfoMock('argName'))
|
||||
self.assertEqual(ll.typeName(), "Foo.meth")
|
||||
self.assertEqual(ll.module(), "test_lib_pubsub_listener")
|
||||
assert ll.wantsTopicObjOnCall()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import wtc
|
||||
|
||||
from difflib import ndiff, unified_diff, context_diff
|
||||
|
||||
import wx.lib.six as six
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -22,27 +23,27 @@ class lib_pubsub_Notify(wtc.PubsubTestCase):
|
||||
from wx.lib.pubsub.utils.notification import useNotifyByWriteFile
|
||||
|
||||
def captureStdout():
|
||||
from StringIO import StringIO
|
||||
from six import StringIO
|
||||
capture = StringIO()
|
||||
useNotifyByWriteFile( fileObj = capture )
|
||||
return capture
|
||||
capture = captureStdout()
|
||||
|
||||
|
||||
|
||||
def listener1(arg1):
|
||||
pass
|
||||
self.pub.subscribe(listener1, 'baz')
|
||||
self.pub.sendMessage('baz', arg1=123)
|
||||
self.pub.unsubscribe(listener1, 'baz')
|
||||
|
||||
|
||||
def doa():
|
||||
def listener2():
|
||||
pass
|
||||
self.pub.subscribe(listener2, 'bar')
|
||||
doa()
|
||||
|
||||
self.pub.delTopic('baz')
|
||||
|
||||
|
||||
self.pub.getDefaultTopicMgr().delTopic('baz')
|
||||
|
||||
expect = '''\
|
||||
PUBSUB: New topic "baz" created
|
||||
PUBSUB: Subscribed listener "listener1" to topic "baz"
|
||||
@@ -59,8 +60,8 @@ PUBSUB: Topic "baz" destroyed
|
||||
# strip as other wise one has \n, at least on windows
|
||||
assert captured == expect, \
|
||||
'\n'.join( unified_diff(expect.splitlines(), captured.splitlines(), n=0) )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@ import wtc
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class lib_pubsub_Notify2_1(wtc.PubsubTestCase):
|
||||
|
||||
|
||||
class lib_pubsub_Notify2_1(wtc.PubsubTestCase):
|
||||
|
||||
|
||||
def test1_SubscribeNotify(self):
|
||||
from wx.lib.pubsub.utils.notification import useNotifyByPubsubMessage
|
||||
|
||||
|
||||
useNotifyByPubsubMessage()
|
||||
|
||||
|
||||
class MyListener:
|
||||
countSub = 0
|
||||
countUnsub = 0
|
||||
@@ -40,12 +40,12 @@ class lib_pubsub_Notify2_1(wtc.PubsubTestCase):
|
||||
self.countUnsub += 1
|
||||
def listenerTest(self):
|
||||
raise NotImplementedError # should never get here
|
||||
|
||||
|
||||
self.pub.setNotificationFlags(subscribe=True, unsubscribe=True)
|
||||
self.pub.getOrCreateTopic('testSubscribeNotify')
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('testSubscribeNotify')
|
||||
tmp = MyListener()
|
||||
tmp.assertEqual = self.assertEqual
|
||||
|
||||
|
||||
self.pub.subscribe(tmp.listenerSub, 'pubsub.subscribe')
|
||||
self.assertEqual(tmp.countSub, 0) # don't notify of self subscription
|
||||
self.assertEqual(tmp.countUnsub, 0)
|
||||
@@ -53,20 +53,20 @@ class lib_pubsub_Notify2_1(wtc.PubsubTestCase):
|
||||
assert ok
|
||||
self.assertEqual(tmp.countSub, 1)
|
||||
self.assertEqual(tmp.countUnsub, 0)
|
||||
|
||||
|
||||
self.pub.subscribe(tmp.listenerTest, 'testSubscribeNotify')
|
||||
self.assertEqual(tmp.countUnsub, 0)
|
||||
self.pub.unsubscribe(tmp.listenerTest, 'testSubscribeNotify')
|
||||
self.assertEqual(tmp.countUnsub, 1)
|
||||
|
||||
|
||||
self.pub.unsubscribe(tmp.listenerSub, 'pubsub.subscribe')
|
||||
self.assertEqual(tmp.countSub, 2)
|
||||
self.assertEqual(tmp.countUnsub, 2)
|
||||
self.pub.unsubscribe(tmp.listenerUnsub, 'pubsub.unsubscribe')
|
||||
self.assertEqual(tmp.countSub, 2)
|
||||
self.assertEqual(tmp.countUnsub, 2) # don't notify of self unsubscription
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ import wtc
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class lib_pubsub_Notify2_2(wtc.PubsubTestCase):
|
||||
class lib_pubsub_Notify2_2(wtc.PubsubTestCase):
|
||||
|
||||
def test2_SendNotify(self):
|
||||
from wx.lib.pubsub.utils.notification import useNotifyByPubsubMessage
|
||||
|
||||
def test2_SendNotify(self):
|
||||
from wx.lib.pubsub.utils.notification import useNotifyByPubsubMessage
|
||||
|
||||
useNotifyByPubsubMessage()
|
||||
|
||||
|
||||
# trap the pubsub.sendMessage topic:
|
||||
class SendHandler:
|
||||
def __init__(self):
|
||||
@@ -38,18 +38,18 @@ class lib_pubsub_Notify2_2(wtc.PubsubTestCase):
|
||||
|
||||
sh = SendHandler()
|
||||
sh.assertEqual = self.assertEqual
|
||||
|
||||
|
||||
self.pub.subscribe(sh, 'pubsub.sendMessage')
|
||||
self.pub.setNotificationFlags(sendMessage=True)
|
||||
|
||||
|
||||
# generate a message that will cause pubsub.sendMessage to be generated too
|
||||
assert sh.pre == 0
|
||||
assert sh.post == 0
|
||||
self.pub.getOrCreateTopic('testSendNotify')
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('testSendNotify')
|
||||
self.pub.sendMessage('testSendNotify')
|
||||
assert sh.pre == 1
|
||||
assert sh.post == 1
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -9,18 +9,19 @@
|
||||
import imp_unittest, unittest
|
||||
import wtc
|
||||
|
||||
import wx.lib.six as six
|
||||
from difflib import ndiff, unified_diff, context_diff
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class lib_pubsub_NotifyN(wtc.PubsubTestCase):
|
||||
|
||||
|
||||
def testNotifications(self):
|
||||
from wx.lib.pubsub.utils.notification import INotificationHandler
|
||||
|
||||
|
||||
class Handler(INotificationHandler):
|
||||
def __init__(self):
|
||||
self.resetCounts()
|
||||
@@ -38,44 +39,44 @@ class lib_pubsub_NotifyN(wtc.PubsubTestCase):
|
||||
self.counts['newt'] += 1
|
||||
def notifyDelTopic(self, topicName):
|
||||
self.counts['delt'] += 1
|
||||
|
||||
|
||||
notifiee = Handler()
|
||||
self.pub.addNotificationHandler(notifiee)
|
||||
self.pub.setNotificationFlags(all=True)
|
||||
|
||||
|
||||
def verify(**ref):
|
||||
for key, val in notifiee.counts.iteritems():
|
||||
for key, val in six.iteritems(notifiee.counts):
|
||||
if key in ref:
|
||||
self.assertEqual(val, ref[key], "\n%s\n%s" % (notifiee.counts, ref) )
|
||||
else:
|
||||
self.assertEqual(val, 0, "%s = %s, expected 0" % (key, val))
|
||||
notifiee.resetCounts()
|
||||
|
||||
|
||||
verify()
|
||||
def testListener():
|
||||
pass
|
||||
def testListener2():
|
||||
pass
|
||||
|
||||
self.pub.getOrCreateTopic('newTopic')
|
||||
|
||||
self.pub.getDefaultTopicMgr().getOrCreateTopic('newTopic')
|
||||
verify(newt=1)
|
||||
|
||||
|
||||
self.pub.subscribe(testListener, 'newTopic')
|
||||
self.pub.subscribe(testListener2, 'newTopic')
|
||||
verify(sub=2)
|
||||
|
||||
|
||||
self.pub.sendMessage('newTopic')
|
||||
verify(send=1)
|
||||
|
||||
|
||||
del testListener
|
||||
verify(dead=1)
|
||||
|
||||
|
||||
self.pub.unsubscribe(testListener2,'newTopic')
|
||||
verify(unsub=1)
|
||||
|
||||
self.pub.delTopic('newTopic')
|
||||
|
||||
self.pub.getDefaultTopicMgr().delTopic('newTopic')
|
||||
verify(delt=1)
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -51,9 +51,9 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
|
||||
def test1(self):
|
||||
|
||||
self.pub.importTopicTree(my_topics)
|
||||
|
||||
|
||||
self.pub.addTopicDefnProvider(my_topics, self.pub.TOPIC_TREE_FROM_CLASS)
|
||||
|
||||
|
||||
provString = """
|
||||
class rootTopic1:
|
||||
class subtopic_1:
|
||||
@@ -68,12 +68,13 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
- arg4: doc for arg4
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
"""
|
||||
|
||||
self.pub.importTopicTree(provString, format=self.pub.TOPIC_TREE_FROM_STRING)
|
||||
|
||||
|
||||
|
||||
self.pub.addTopicDefnProvider(provString,
|
||||
format=self.pub.TOPIC_TREE_FROM_STRING)
|
||||
|
||||
|
||||
provFile = """
|
||||
class rootTopic1:
|
||||
class subtopic_2:
|
||||
@@ -87,30 +88,31 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
'''
|
||||
pass
|
||||
"""
|
||||
|
||||
|
||||
myTopicTree = file('myTopicTree.py', 'w')
|
||||
myTopicTree.write(dedent(provFile))
|
||||
myTopicTree.close()
|
||||
self.pub.importTopicTree('myTopicTree', format=self.pub.TOPIC_TREE_FROM_MODULE, lazy=True)
|
||||
self.pub.addTopicDefnProvider('myTopicTree',
|
||||
format=self.pub.TOPIC_TREE_FROM_MODULE)
|
||||
import os
|
||||
os.remove('myTopicTree.py')
|
||||
if os.path.exists('myTopicTree.pyc'):
|
||||
os.remove('myTopicTree.pyc')
|
||||
|
||||
assert not self.pub.getTopic('rootTopic1.subtopic_2', okIfNone=True)
|
||||
|
||||
assert not self.pub.getDefaultTopicMgr().getTopic('rootTopic1.subtopic_2', okIfNone=True)
|
||||
# the following should create all topic tree since parent
|
||||
# topics are automatically created
|
||||
assert self.pub.getOrCreateTopic('rootTopic1.subtopic_1.subsubtopic_11')
|
||||
assert self.pub.getOrCreateTopic('rootTopic1.subtopic_1.subsubtopic_12')
|
||||
assert self.pub.getOrCreateTopic('rootTopic1.subtopic_2.subsubtopic_21')
|
||||
|
||||
assert self.pub.getDefaultTopicMgr().getOrCreateTopic('rootTopic1.subtopic_1.subsubtopic_11')
|
||||
assert self.pub.getDefaultTopicMgr().getOrCreateTopic('rootTopic1.subtopic_1.subsubtopic_12')
|
||||
assert self.pub.getDefaultTopicMgr().getOrCreateTopic('rootTopic1.subtopic_2.subsubtopic_21')
|
||||
|
||||
# validate that topic specs were properly parsed
|
||||
def isValid(topicName, listener):
|
||||
topic = self.pub.getTopic(topicName)
|
||||
topic = self.pub.getDefaultTopicMgr().getTopic(topicName)
|
||||
assert topic.getDescription()
|
||||
assert topic.isSendable()
|
||||
assert topic.hasMDS()
|
||||
return topic.isValid(listener)
|
||||
|
||||
|
||||
def sub():
|
||||
pass
|
||||
def sub_1(arg1, arg2=123):
|
||||
@@ -121,13 +123,13 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
assert isValid('rootTopic1.subtopic_1', sub_1)
|
||||
assert isValid('rootTopic1.subtopic_1.subsubtopic_11', sub_11)
|
||||
# no providers have spec for subtopic_2
|
||||
assert not self.pub.getTopic('rootTopic1.subtopic_2').isSendable()
|
||||
|
||||
assert not self.pub.getDefaultTopicMgr().getTopic('rootTopic1.subtopic_2').hasMDS()
|
||||
|
||||
#printTreeSpec()
|
||||
|
||||
self.pub.exportTopicTree('newTopicTree')
|
||||
root2Defn = self.pub.exportTopicTree(rootTopicName='rootTopic1')
|
||||
|
||||
|
||||
self.pub.exportTopicTreeSpec('newTopicTree')
|
||||
root2Defn = self.pub.exportTopicTreeSpec(rootTopic='rootTopic1')
|
||||
|
||||
import os
|
||||
os.remove('newTopicTree.py')
|
||||
if os.path.exists('newTopicTree.pyc'):
|
||||
@@ -138,116 +140,120 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
#
|
||||
# Test that import/export/import does not change the import
|
||||
#
|
||||
|
||||
importStr = """
|
||||
'''Tree docs, can be anything you want.'''
|
||||
|
||||
class test_import_export_no_change:
|
||||
'''Root topic 1.'''
|
||||
|
||||
class subtopic_1:
|
||||
'''
|
||||
Sub topic 1 of root topic. Docs rely on one
|
||||
blank line for topic doc, and indentation for
|
||||
each argument doc.
|
||||
'''
|
||||
|
||||
def msgDataSpec(arg1, arg2=None):
|
||||
'''
|
||||
- arg1: some multiline doc
|
||||
for arg1
|
||||
- arg2: some multiline doc
|
||||
for arg2
|
||||
'''
|
||||
pass
|
||||
"""
|
||||
|
||||
importStr = '''
|
||||
"""Tree docs, can be anything you want."""
|
||||
|
||||
class test_import_export_no_change:
|
||||
"""Root topic 1."""
|
||||
|
||||
class subtopic_1:
|
||||
"""
|
||||
Sub topic 1 of root topic. Docs rely on one
|
||||
blank line for topic doc, and indentation for
|
||||
each argument doc.
|
||||
"""
|
||||
|
||||
def msgDataSpec(arg1, arg2=None):
|
||||
"""
|
||||
- arg1: some multiline doc
|
||||
for arg1
|
||||
- arg2: some multiline doc
|
||||
for arg2
|
||||
"""
|
||||
pass
|
||||
'''
|
||||
self.pub.clearTopicDefnProviders()
|
||||
treeDoc = self.pub.importTopicTree(importStr, lazy = True,
|
||||
format = self.pub.TOPIC_TREE_FROM_STRING)
|
||||
provider = self.pub.addTopicDefnProvider(importStr,
|
||||
self.pub.TOPIC_TREE_FROM_STRING)
|
||||
treeDoc = provider.getTreeDoc()
|
||||
assert treeDoc == '''Tree docs, can be anything you want.'''
|
||||
root = self.pub.getOrCreateTopic('test_import_export_no_change.subtopic_1')
|
||||
root = self.pub.getDefaultTopicMgr().getOrCreateTopic('test_import_export_no_change.subtopic_1')
|
||||
# few sanity checks
|
||||
def sub_1(arg1, arg2=None):
|
||||
pass
|
||||
assert root.isSendable()
|
||||
assert root.hasMDS()
|
||||
assert self.pub.isValid(sub_1, 'test_import_export_no_change.subtopic_1')
|
||||
|
||||
|
||||
# export tree
|
||||
exported = self.pub.exportTopicTree(rootTopicName='test_import_export_no_change', moduleDoc=treeDoc)
|
||||
exported = self.pub.exportTopicTreeSpec(rootTopic='test_import_export_no_change', moduleDoc=treeDoc)
|
||||
#print exported
|
||||
|
||||
expectExport = """\
|
||||
# Automatically generated by TopicTreeAsSpec(**kwargs).
|
||||
# The kwargs were:
|
||||
# - fileObj: StringIO
|
||||
# - width: 70
|
||||
# - treeDoc: 'Tree docs, can be anything you want....'
|
||||
# - indentStep: 4
|
||||
# - footer: '# End of topic tree definition. Note that application may l...'
|
||||
|
||||
|
||||
'''
|
||||
Tree docs, can be anything you want.
|
||||
'''
|
||||
|
||||
|
||||
class test_import_export_no_change:
|
||||
'''
|
||||
Root topic 1.
|
||||
'''
|
||||
|
||||
class subtopic_1:
|
||||
'''
|
||||
Sub topic 1 of root topic. Docs rely on one
|
||||
blank line for topic doc, and indentation for
|
||||
each argument doc.
|
||||
'''
|
||||
|
||||
def msgDataSpec(arg1, arg2=None):
|
||||
'''
|
||||
- arg1: some multiline doc
|
||||
for arg1
|
||||
- arg2: some multiline doc
|
||||
for arg2
|
||||
'''
|
||||
|
||||
|
||||
# End of topic tree definition. Note that application may load
|
||||
# more than one definitions provider.
|
||||
|
||||
expectExport = '''\
|
||||
# Automatically generated by TopicTreeSpecPrinter(**kwargs).
|
||||
# The kwargs were:
|
||||
# - fileObj: StringIO
|
||||
# - footer: '# End of topic tree definition. Note that application may l...'
|
||||
# - indentStep: 4
|
||||
# - treeDoc: 'Tree docs, can be anything you want....'
|
||||
# - width: 70
|
||||
|
||||
|
||||
"""
|
||||
Tree docs, can be anything you want.
|
||||
"""
|
||||
|
||||
|
||||
class test_import_export_no_change:
|
||||
"""
|
||||
|
||||
Root topic 1.
|
||||
"""
|
||||
|
||||
class subtopic_1:
|
||||
"""
|
||||
Sub topic 1 of root topic. Docs rely on one
|
||||
blank line for topic doc, and indentation for
|
||||
each argument doc.
|
||||
"""
|
||||
|
||||
def msgDataSpec(arg1, arg2=None):
|
||||
"""
|
||||
- arg1: some multiline doc
|
||||
for arg1
|
||||
- arg2: some multiline doc
|
||||
for arg2
|
||||
"""
|
||||
|
||||
|
||||
# End of topic tree definition. Note that application may load
|
||||
# more than one definitions provider.
|
||||
'''
|
||||
|
||||
# check there are no differences
|
||||
from difflib import context_diff, ndiff
|
||||
diffs = ndiff( dedent(expectExport).splitlines(), exported.splitlines())
|
||||
diffs = [d for d in diffs if not d.startswith(' ')]
|
||||
#print '\n'.join(diffs)
|
||||
assert diffs == ['- ', '+ ']
|
||||
|
||||
|
||||
# now for module:
|
||||
modDoc = self.pub.importTopicTree('lib_pubsub_provider_expect',
|
||||
format=self.pub.TOPIC_TREE_FROM_MODULE,
|
||||
lazy=False)
|
||||
provider = self.pub.addTopicDefnProvider('lib_pubsub_provider_expect',
|
||||
self.pub.TOPIC_TREE_FROM_MODULE)
|
||||
self.pub.instantiateAllDefinedTopics(provider)
|
||||
modDoc = provider.getTreeDoc()
|
||||
assert modDoc.startswith('\nTree docs, can be anything you')
|
||||
basepath = os.path.dirname(__file__)
|
||||
self.pub.exportTopicTree(os.path.join(basepath,'lib_pubsub_provider_actual'),
|
||||
rootTopicName='test_import_export_no_change2',
|
||||
moduleDoc=treeDoc)
|
||||
lines1 = file(os.path.join(basepath,'lib_pubsub_provider_actual.py'), 'r').readlines()
|
||||
lines2 = file(os.path.join(basepath,'lib_pubsub_provider_expect.py'), 'r').readlines()
|
||||
diffs = context_diff( lines1, lines2 )
|
||||
os.unlink(os.path.join(basepath,'lib_pubsub_provider_actual.py'))
|
||||
assert not list(diffs)
|
||||
|
||||
self.pub.exportTopicTreeSpec(os.path.join(basepath,'lib_pubsub_provider_actual'),
|
||||
rootTopic='test_import_export_no_change2',
|
||||
moduleDoc=treeDoc)
|
||||
lines1 = open(os.path.join(basepath,'lib_pubsub_provider_actual.py'), 'r').readlines()
|
||||
lines2 = open(os.path.join(basepath,'lib_pubsub_provider_expect.py'), 'r').readlines()
|
||||
diffs = ndiff( lines1, lines2 )
|
||||
diffs = [d for d in diffs if not d.startswith(' ')]
|
||||
assert not list(diffs) or list(diffs) == ['- # - fileObj: TextIOWrapper\n', '+ # - fileObj: file\n']
|
||||
|
||||
def test_module_as_class(self):
|
||||
assert self.pub.getTopic('root_topic1', True) is None
|
||||
assert self.pub.getTopic('root_topic2.sub_topic21', True) is None
|
||||
|
||||
assert self.pub.getDefaultTopicMgr().getTopic('root_topic1', True) is None
|
||||
assert self.pub.getDefaultTopicMgr().getTopic('root_topic2.sub_topic21', True) is None
|
||||
|
||||
import lib_pubsub_provider_my_import_topics
|
||||
self.pub.importTopicTree(lib_pubsub_provider_my_import_topics)
|
||||
|
||||
assert self.pub.getTopic('root_topic1') is not None
|
||||
assert self.pub.getTopic('root_topic2.sub_topic21') is not None
|
||||
|
||||
provider = self.pub.addTopicDefnProvider(lib_pubsub_provider_my_import_topics,
|
||||
self.pub.TOPIC_TREE_FROM_CLASS)
|
||||
self.pub.instantiateAllDefinedTopics(provider)
|
||||
|
||||
assert self.pub.getDefaultTopicMgr().getTopic('root_topic1') is not None
|
||||
assert self.pub.getDefaultTopicMgr().getTopic('root_topic2.sub_topic21') is not None
|
||||
|
||||
self.pub.sendMessage(lib_pubsub_provider_my_import_topics.root_topic1)
|
||||
|
||||
|
||||
@@ -257,4 +263,3 @@ class lib_pubsub_Except(wtc.PubsubTestCase):
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import wtc
|
||||
|
||||
|
||||
from wx.lib.pubsub.core.topicargspec import (
|
||||
ArgsInfo,
|
||||
ArgSpecGiven,
|
||||
#SenderMissingReqdArgs,
|
||||
#SenderUnknownOptArgs
|
||||
ArgsInfo,
|
||||
ArgSpecGiven,
|
||||
SenderMissingReqdMsgDataError ,
|
||||
SenderUnknownMsgDataError
|
||||
)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -30,7 +30,7 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai1.numArgs() == 0
|
||||
assert ai1.getArgs() == ()
|
||||
assert ai1.getCompleteAI() is ai1
|
||||
|
||||
|
||||
# sub, complete
|
||||
td2 = ArgSpecGiven(
|
||||
argsDocs = dict(arg1='doc for arg1', arg2='doc for arg2'),
|
||||
@@ -40,7 +40,7 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai2.numArgs() == 2
|
||||
assert ai2.getArgs() == ('arg1', 'arg2')
|
||||
assert ai2.getCompleteAI() is ai2
|
||||
|
||||
|
||||
# sub, missing
|
||||
td2.argsSpecType = ArgSpecGiven.SPEC_GIVEN_NONE
|
||||
ai4 = ArgsInfo(('t1','st3'), td2, ai1)
|
||||
@@ -48,7 +48,7 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai4.numArgs() == 0
|
||||
assert ai4.getArgs() == ()
|
||||
assert ai4.getCompleteAI() is ai1
|
||||
|
||||
|
||||
# sub, of incomplete spec, given ALL args
|
||||
td3 = ArgSpecGiven(
|
||||
argsDocs = dict(arg1='doc for arg1', arg2='doc for arg2'),
|
||||
@@ -58,7 +58,7 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai5.numArgs() == 2
|
||||
assert ai5.hasSameArgs('arg1', 'arg2')
|
||||
assert ai5.getCompleteAI() is ai5
|
||||
|
||||
|
||||
def test2_update(self):
|
||||
td1 = ArgSpecGiven(dict())
|
||||
td2 = ArgSpecGiven()
|
||||
@@ -68,12 +68,12 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
arg1='doc for arg1', arg2='doc for arg2',
|
||||
arg3='doc for arg3', arg4='doc for arg4'),
|
||||
reqdArgs = ('arg4','arg2'))
|
||||
|
||||
|
||||
ai1 = ArgsInfo(('t1',), td1, None) # root, complete
|
||||
ai2 = ArgsInfo(('t1','st1'), td2, ai1) # sub 1, empty
|
||||
ai4 = ArgsInfo(('t1','st1','sst2'), td4, ai2) # empty sub of sub 1
|
||||
ai5 = ArgsInfo(('t1','st1','sst3'), td5, ai2) # completed sub of sub 1
|
||||
|
||||
|
||||
# check assumptions before we start:
|
||||
assert not ai2.isComplete()
|
||||
assert not ai4.isComplete()
|
||||
@@ -81,7 +81,7 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai2.numArgs() == 0
|
||||
assert ai4.numArgs() == 0
|
||||
assert ai5.numArgs() == 4
|
||||
|
||||
|
||||
# pretend we have an update for ai2: all args now available
|
||||
ai2.updateAllArgsFinal( ArgSpecGiven(
|
||||
dict(arg1='doc for arg1', arg2='doc for arg2'),
|
||||
@@ -90,41 +90,41 @@ class lib_pubsub_Specs(wtc.PubsubTestCase):
|
||||
assert ai2.numArgs() == 2
|
||||
assert ai2.hasSameArgs('arg1', 'arg2')
|
||||
assert ai2.getCompleteAI() is ai2
|
||||
|
||||
|
||||
assert not ai4.isComplete()
|
||||
|
||||
|
||||
assert ai2.numArgs() == 2
|
||||
assert ai4.numArgs() == 0
|
||||
assert ai5.numArgs() == 4
|
||||
|
||||
|
||||
assert ai4.getCompleteAI() is ai2
|
||||
|
||||
|
||||
assert ai2.hasSameArgs('arg1', 'arg2')
|
||||
assert ai5.hasSameArgs('arg1', 'arg2', 'arg3', 'arg4')
|
||||
|
||||
|
||||
def test3_filter(self):
|
||||
td = ArgSpecGiven(
|
||||
argsDocs = dict(arg1='doc for arg1', arg2='doc for arg2'),
|
||||
reqdArgs = ('arg2',))
|
||||
ai = ArgsInfo(('t1',), td, None)
|
||||
|
||||
|
||||
# check:
|
||||
argsMissingReqd = {}
|
||||
self.assertRaises(SenderMissingReqdArgs, ai.check, argsMissingReqd)
|
||||
|
||||
self.assertRaises(SenderMissingReqdMsgDataError , ai.check, argsMissingReqd)
|
||||
|
||||
argsExtraOpt = dict(arg2=2, arg5=5)
|
||||
self.assertRaises(SenderUnknownOptArgs, ai.check, argsExtraOpt)
|
||||
|
||||
self.assertRaises(SenderUnknownMsgDataError , ai.check, argsExtraOpt)
|
||||
|
||||
args = dict(arg1=1, arg2=2)
|
||||
ai.check(args)
|
||||
|
||||
|
||||
# filter:
|
||||
msgArgs = dict(arg1=1, arg2=2)
|
||||
argsOK = msgArgs.copy()
|
||||
assert ai.filterArgs( msgArgs ) == argsOK
|
||||
msgArgs.update(arg3=3, arg4=4)
|
||||
assert ai.filterArgs( msgArgs ) == argsOK
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ from wx.lib.pubsub.core.topicobj import Topic
|
||||
from wx.lib.pubsub.core.treeconfig import TreeConfig
|
||||
from wx.lib.pubsub.core.topicutils import ALL_TOPICS
|
||||
from wx.lib.pubsub.core.topicargspec import ArgsInfo, ArgSpecGiven
|
||||
#from wx.lib.pubsub.core.listener import ListenerInadequate
|
||||
#from wx.lib.pubsub.core.topicexc import ListenerSpecInvalid
|
||||
from wx.lib.pubsub.core.listener import ListenerMismatchError
|
||||
from wx.lib.pubsub.core.topicexc import MessageDataSpecError
|
||||
|
||||
|
||||
|
||||
@@ -30,26 +30,26 @@ class lib_pubsub_Topic(wtc.PubsubTestCase):
|
||||
#
|
||||
# Test create and then modify state of a topic object
|
||||
#
|
||||
|
||||
|
||||
nameTuple = ('root',)
|
||||
description = 'root description'
|
||||
msgArgsInfo = None
|
||||
|
||||
|
||||
# when parent is None, only nameTuple=ALL_TOPICS is allowed, thereby
|
||||
# guaranteeing that only one tree root can be created
|
||||
self.assertRaises(ValueError, Topic, self.treeConfig, nameTuple, description, msgArgsInfo)
|
||||
|
||||
|
||||
# create the ALL TOPICS topic; it has no message args
|
||||
nameTuple = (ALL_TOPICS,)
|
||||
argSpec = ArgSpecGiven(dict() )
|
||||
msgArgsInfo = ArgsInfo(nameTuple, argSpec, None)
|
||||
obj = Topic(self.treeConfig, nameTuple, description, msgArgsInfo)
|
||||
|
||||
|
||||
# verify its state is as expected after creation:
|
||||
assert obj.getListeners() == []
|
||||
assert obj.getNumListeners() == 0
|
||||
assert obj.hasListeners() == False
|
||||
|
||||
|
||||
def listener1():
|
||||
pass
|
||||
def listener2():
|
||||
@@ -61,15 +61,15 @@ class lib_pubsub_Topic(wtc.PubsubTestCase):
|
||||
assert obj.isValid(listener1)
|
||||
assert not obj.isValid(badListener1)
|
||||
assert not obj.isValid(badListener2)
|
||||
|
||||
|
||||
self.rootTopic = obj
|
||||
|
||||
|
||||
|
||||
|
||||
def test1_SubUnsub(self):
|
||||
#
|
||||
# Test subscription and unsubscription of listeners
|
||||
#
|
||||
|
||||
|
||||
def listener1():
|
||||
pass
|
||||
def listener2():
|
||||
@@ -77,28 +77,28 @@ class lib_pubsub_Topic(wtc.PubsubTestCase):
|
||||
# need to run this here again to get rootTopic setup for this test
|
||||
self.test0_CreateRoot()
|
||||
obj = self.rootTopic
|
||||
|
||||
|
||||
# now modify its state by subscribing listeners
|
||||
obj.subscribe(listener1)
|
||||
obj.subscribe(listener2)
|
||||
|
||||
|
||||
obj.hasListener(listener1)
|
||||
obj.hasListener(listener2)
|
||||
assert obj.hasListeners() == True
|
||||
assert set(obj.getListeners()) == set([listener1, listener2])
|
||||
assert obj.getNumListeners() == 2
|
||||
|
||||
|
||||
# try to subscribe an invalid listener
|
||||
def badListener(arg1):
|
||||
pass # extra required arg
|
||||
self.assertRaises(ListenerInadequate, obj.subscribe, badListener)
|
||||
|
||||
self.assertRaises(ListenerMismatchError, obj.subscribe, badListener)
|
||||
|
||||
# try unsubscribe
|
||||
obj.unsubscribe(listener1)
|
||||
assert obj.hasListeners() == True
|
||||
assert obj.getListeners() == [listener2]
|
||||
assert obj.getNumListeners() == 1
|
||||
|
||||
|
||||
# try unsubscribe all, with filtering
|
||||
obj.subscribe(listener1)
|
||||
def listener3(): pass
|
||||
@@ -116,13 +116,13 @@ class lib_pubsub_Topic(wtc.PubsubTestCase):
|
||||
assert obj.getNumListeners() == 3
|
||||
obj.unsubscribeAllListeners()
|
||||
assert obj.getNumListeners() == 0
|
||||
|
||||
|
||||
|
||||
|
||||
def test2_CreateChild(self):
|
||||
#
|
||||
# Test creation of a child topic, subscription of listeners
|
||||
#
|
||||
|
||||
|
||||
# need to run this here again to get rootTopic setup for this test
|
||||
self.test0_CreateRoot()
|
||||
|
||||
@@ -135,30 +135,30 @@ class lib_pubsub_Topic(wtc.PubsubTestCase):
|
||||
parent = Topic(self.treeConfig, nameTuple, description, msgArgsInfo,
|
||||
parent=self.rootTopic)
|
||||
assert parent.getParent() is self.rootTopic
|
||||
|
||||
|
||||
# now create a child of child with wrong arguments so we can test exceptions
|
||||
nameTuple = ('childOfAll', 'grandChild')
|
||||
description = 'grandchild description'
|
||||
|
||||
|
||||
def tryCreate(ad, r):
|
||||
argSpec = ArgSpecGiven(argsDocs=ad, reqdArgs = r)
|
||||
msgArgsInfo = ArgsInfo(nameTuple, argSpec, parent._getListenerSpec())
|
||||
obj = Topic(self.treeConfig, nameTuple, description, msgArgsInfo,
|
||||
parent=parent)
|
||||
|
||||
|
||||
# test when all OK
|
||||
argsDocs = dict(arg1='arg1 desc', arg2='arg2 desc')
|
||||
reqdArgs = ('arg2',)
|
||||
tryCreate(argsDocs, reqdArgs)
|
||||
# test when requiredArg wrong
|
||||
reqdArgs = ('arg3',)
|
||||
self.assertRaises(ListenerSpecInvalid, tryCreate, argsDocs, reqdArgs)
|
||||
self.assertRaises(MessageDataSpecError, tryCreate, argsDocs, reqdArgs)
|
||||
reqdArgs = ()
|
||||
self.assertRaises(ListenerSpecInvalid, tryCreate, argsDocs, reqdArgs)
|
||||
self.assertRaises(MessageDataSpecError, tryCreate, argsDocs, reqdArgs)
|
||||
# test when missing opt arg
|
||||
argsDocs = dict(arg1='arg1 desc', arg2='arg2 desc')
|
||||
reqdArgs = ('arg2',)
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -10,22 +10,19 @@ import imp_unittest, unittest
|
||||
import wtc
|
||||
|
||||
from wx.lib.pubsub.pub import (
|
||||
ALL_TOPICS,
|
||||
#ListenerSpecInvalid,
|
||||
#ITopicDefnProvider,
|
||||
TopicTreeTraverser,
|
||||
#UndefinedTopic,
|
||||
#UndefinedSubtopic,
|
||||
#ListenerNotValidatable
|
||||
ALL_TOPICS,
|
||||
MessageDataSpecError,
|
||||
TopicTreeTraverser,
|
||||
TopicNameError,
|
||||
TopicDefnError
|
||||
)
|
||||
|
||||
from wx.lib.pubsub.core import ITopicDefnProvider
|
||||
|
||||
from wx.lib.pubsub.core.topicmgr import \
|
||||
ArgSpecGiven
|
||||
|
||||
from wx.lib.pubsub.core.topicutils import (
|
||||
#TopicNameInvalid,
|
||||
validateName
|
||||
)
|
||||
from wx.lib.pubsub.core.topicutils import validateName
|
||||
|
||||
from wx.lib.pubsub.utils.topictreeprinter import \
|
||||
printTreeDocs, ITopicTreeVisitor
|
||||
@@ -36,7 +33,7 @@ class lib_pubsub_TopicMgr0_Basic(wtc.PubsubTestCase):
|
||||
topic objects to validate that TopicMgr did it's job properly.
|
||||
"""
|
||||
def failTopicName(self, name):
|
||||
self.assertRaises(TopicNameInvalid, validateName, name)
|
||||
self.assertRaises(TopicNameError, validateName, name)
|
||||
|
||||
def test10_GoodTopicNames(self):
|
||||
#
|
||||
@@ -79,8 +76,8 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
|
||||
def verifyNonSendable(topicObj, nameTuple, parent):
|
||||
"""Any non-sendable topic will satisfy these conditions:"""
|
||||
self.assertEqual(0, topicMgr.isTopicSpecified(nameTuple))
|
||||
assert not topicObj.isSendable()
|
||||
self.assertEqual(0, topicMgr.hasTopicDefinition(nameTuple))
|
||||
assert not topicObj.hasMDS()
|
||||
assert topicObj.getListeners() == []
|
||||
assert topicObj.getNameTuple() == nameTuple
|
||||
assert topicObj.getNumListeners() == 0
|
||||
@@ -92,8 +89,8 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
assert not topicObj.hasListeners()
|
||||
assert not topicObj.hasSubtopic('asdfafs')
|
||||
assert not topicObj.isAll()
|
||||
self.assertRaises(ListenerNotValidatable, topicObj.isValid, foobar)
|
||||
self.assertRaises(ListenerNotValidatable, topicObj.validate, foobar)
|
||||
self.assertRaises(TopicDefnError, topicObj.isValid, foobar)
|
||||
self.assertRaises(TopicDefnError, topicObj.validate, foobar)
|
||||
# check that getTopic and getOrCreateTopic won't create again:
|
||||
assert topicMgr.getOrCreateTopic(nameTuple) is topicObj
|
||||
assert topicMgr.getTopic(nameTuple) is topicObj
|
||||
@@ -105,7 +102,7 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
assert topicMgr.getTopic(tName, True) is None
|
||||
# ok create it, unsendable
|
||||
rootTopic = topicMgr.getOrCreateTopic(tName)
|
||||
verifyNonSendable(rootTopic, (rootName,), topicMgr.getRootTopic())
|
||||
verifyNonSendable(rootTopic, (rootName,), topicMgr.getRootAllTopics())
|
||||
DESC_NO_SPEC = 'UNDOCUMENTED: created without spec'
|
||||
assert rootTopic.getDescription() == DESC_NO_SPEC
|
||||
assert rootTopic.isRoot()
|
||||
@@ -135,9 +132,9 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
|
||||
# check that getTopic raises expected exception when undefined topic:
|
||||
tName = 'Undefined'
|
||||
self.assertRaises(UndefinedTopic, topicMgr.getTopic, tName)
|
||||
self.assertRaises(TopicNameError, topicMgr.getTopic, tName)
|
||||
tName = rootName + '.Undefined'
|
||||
self.assertRaises(UndefinedSubtopic, topicMgr.getTopic, tName)
|
||||
self.assertRaises(TopicNameError, topicMgr.getTopic, tName)
|
||||
|
||||
def test20_WithProtoListener(self):
|
||||
#
|
||||
@@ -156,8 +153,8 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
# check that getTopic and getOrCreateTopic won't create again:
|
||||
assert topicMgr.getOrCreateTopic(tName) is rootTopic
|
||||
assert topicMgr.getTopic(tName) is rootTopic
|
||||
assert rootTopic.isSendable()
|
||||
assert topicMgr.isTopicSpecified(tName)
|
||||
assert rootTopic.hasMDS()
|
||||
assert topicMgr.hasTopicDefinition(tName)
|
||||
expectDesc = 'UNDOCUMENTED: created from protoListener "protoListener" in module test_lib_pubsub_topicmgr'
|
||||
assert rootTopic.getDescription() == expectDesc
|
||||
|
||||
@@ -179,8 +176,8 @@ class lib_pubsub_TopicMgr1_GetOrCreate_NoDefnProv(wtc.PubsubTestCase):
|
||||
tName = (tName, 'stA', 'sstB')
|
||||
subsubTopic = topicMgr.getOrCreateTopic(tName, protoListener2)
|
||||
subTopic = topicMgr.getTopic( tName[:-1] )
|
||||
assert not topicMgr.isTopicSpecified( tName[:-1] )
|
||||
assert topicMgr.isTopicSpecified( tName )
|
||||
assert not topicMgr.hasTopicDefinition( tName[:-1] )
|
||||
assert topicMgr.hasTopicDefinition( tName )
|
||||
assert subsubTopic.isValid(protoListener2)
|
||||
|
||||
|
||||
@@ -196,18 +193,26 @@ class lib_pubsub_TopicMgr2_GetOrCreate_DefnProv(wtc.PubsubTestCase):
|
||||
#
|
||||
topicMgr = self.pub.getDefaultTopicMgr()
|
||||
|
||||
class DefnProvider:
|
||||
class DefnProvider(ITopicDefnProvider):
|
||||
pass
|
||||
dp1 = DefnProvider()
|
||||
dp2 = DefnProvider()
|
||||
assert 1 == topicMgr.addDefnProvider(dp1)
|
||||
assert 1 == topicMgr.addDefnProvider(dp1)
|
||||
assert 2 == topicMgr.addDefnProvider(dp2)
|
||||
assert 2 == topicMgr.addDefnProvider(dp2)
|
||||
assert 2 == topicMgr.addDefnProvider(dp1)
|
||||
topicMgr.addDefnProvider(dp1)
|
||||
assert 1 == topicMgr.getNumDefnProviders()
|
||||
topicMgr.addDefnProvider(dp1)
|
||||
assert 1 == topicMgr.getNumDefnProviders()
|
||||
topicMgr.addDefnProvider(dp2)
|
||||
assert 2 == topicMgr.getNumDefnProviders()
|
||||
topicMgr.addDefnProvider(dp2)
|
||||
assert 2 == topicMgr.getNumDefnProviders()
|
||||
topicMgr.addDefnProvider(dp1)
|
||||
assert 2 == topicMgr.getNumDefnProviders()
|
||||
|
||||
topicMgr.clearDefnProviders()
|
||||
topicMgr.getNumDefnProviders()
|
||||
assert 0 == topicMgr.getNumDefnProviders()
|
||||
assert 1 == topicMgr.addDefnProvider(dp1)
|
||||
topicMgr.addDefnProvider(dp1)
|
||||
assert 1 == topicMgr.getNumDefnProviders()
|
||||
topicMgr.clearDefnProviders()
|
||||
|
||||
def test20_UseProvider(self):
|
||||
@@ -278,36 +283,36 @@ class lib_pubsub_TopicMgr2_GetOrCreate_DefnProv(wtc.PubsubTestCase):
|
||||
# create some topics that will use defn provider
|
||||
topic = topicMgr.getOrCreateTopic('a')
|
||||
assert topic.getDescription() == 'a desc'
|
||||
assert topic.isSendable()
|
||||
assert topic.hasMDS()
|
||||
topic = topicMgr.getOrCreateTopic('a.b')
|
||||
assert topic.getDescription() == 'a.b desc'
|
||||
assert topic.isSendable()
|
||||
assert topic.hasMDS()
|
||||
topic = topicMgr.getOrCreateTopic('a.c.d')
|
||||
assert topic.getDescription() == 'a.c.d desc'
|
||||
assert topic.isSendable()
|
||||
assert not topicMgr.isTopicSpecified('a.c')
|
||||
assert topic.hasMDS()
|
||||
assert not topicMgr.hasTopicDefinition('a.c')
|
||||
# check
|
||||
parent = topicMgr.getTopic('a.c')
|
||||
assert not parent.isSendable()
|
||||
assert not parent.hasMDS()
|
||||
def protoListener(arg1, arg3, arg2=None, arg4=None): pass
|
||||
parent = topicMgr.getOrCreateTopic('a.c', protoListener)
|
||||
assert parent.isSendable()
|
||||
assert topic.isSendable()
|
||||
assert parent.hasMDS()
|
||||
assert topic.hasMDS()
|
||||
|
||||
# now the erroneous ones:
|
||||
def testRaises(topicName, expectMsg):
|
||||
self.assertRaises(ListenerSpecInvalid, topicMgr.getOrCreateTopic,
|
||||
self.assertRaises(MessageDataSpecError, topicMgr.getOrCreateTopic,
|
||||
topicName)
|
||||
try:
|
||||
assert topicMgr.getOrCreateTopic(topicName) is None
|
||||
except ListenerSpecInvalid, exc:
|
||||
except MessageDataSpecError, exc:
|
||||
# ok, did raise but is it correct message?
|
||||
try:
|
||||
str(exc).index(expectMsg)
|
||||
except ValueError:
|
||||
msg = 'Wrong message, expected \n "%s", got \n "%s"'
|
||||
raise RuntimeError(msg % (expectMsg, str(exc)) )
|
||||
|
||||
|
||||
testRaises('a.err1', 'Params [arg1] missing inherited [arg2] for topic "a.err1"')
|
||||
testRaises('a.err2', 'Params [arg2] missing inherited [arg1] for topic "a.err2"')
|
||||
testRaises('a.err3', 'Params [] missing inherited [arg1] for topic "a.err3" required args')
|
||||
@@ -364,7 +369,7 @@ class lib_pubsub_TopicMgr3_TreeTraverser(wtc.PubsubTestCase):
|
||||
# Test traversing with and without filtering, breadth and depth
|
||||
#
|
||||
topicMgr = self.pub.getDefaultTopicMgr()
|
||||
|
||||
|
||||
class MyTraverser(ITopicTreeVisitor):
|
||||
def __init__(self, pub):
|
||||
self.traverser = pub.TopicTreeTraverser(self)
|
||||
|
||||
Reference in New Issue
Block a user