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:
Robin Dunn
2014-02-26 03:53:59 +00:00
parent fe2d0b3a8b
commit 207c1f294c
13 changed files with 458 additions and 444 deletions

1
.gitignore vendored
View File

@@ -58,3 +58,4 @@
/wx/*.dylib
/wx/libwx_*
/wx/locale
/unittests/lib_pubsub_provider_actual.py

View File

@@ -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

View File

@@ -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()

View File

@@ -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)
#---------------------------------------------------------------------------

View File

@@ -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()
#---------------------------------------------------------------------------

View File

@@ -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) )
#---------------------------------------------------------------------------

View File

@@ -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
#---------------------------------------------------------------------------

View File

@@ -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
#---------------------------------------------------------------------------

View File

@@ -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)
#---------------------------------------------------------------------------

View File

@@ -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()

View File

@@ -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
#---------------------------------------------------------------------------

View File

@@ -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',)
#---------------------------------------------------------------------------

View File

@@ -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)