diff --git a/.gitignore b/.gitignore index f8b9d412..9d89f28e 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ /wx/*.dylib /wx/libwx_* /wx/locale +/unittests/lib_pubsub_provider_actual.py diff --git a/unittests/lib_pubsub_provider_expect.py b/unittests/lib_pubsub_provider_expect.py index b8ccadd1..d3b87d2c 100644 --- a/unittests/lib_pubsub_provider_expect.py +++ b/unittests/lib_pubsub_provider_expect.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 diff --git a/unittests/test_lib_pubsub_api3.py b/unittests/test_lib_pubsub_api3.py index 269a1476..eb28f311 100644 --- a/unittests/test_lib_pubsub_api3.py +++ b/unittests/test_lib_pubsub_api3.py @@ -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() - \ No newline at end of file diff --git a/unittests/test_lib_pubsub_except.py b/unittests/test_lib_pubsub_except.py index 1aac0fe2..e6222f6e 100644 --- a/unittests/test_lib_pubsub_except.py +++ b/unittests/test_lib_pubsub_except.py @@ -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) - - + + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_listener.py b/unittests/test_lib_pubsub_listener.py index 039d629d..d02dd127 100644 --- a/unittests/test_lib_pubsub_listener.py +++ b/unittests/test_lib_pubsub_listener.py @@ -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() - + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_notify.py b/unittests/test_lib_pubsub_notify.py index 07c6a58a..0479ab50 100644 --- a/unittests/test_lib_pubsub_notify.py +++ b/unittests/test_lib_pubsub_notify.py @@ -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) ) - - + + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_notify2_1.py b/unittests/test_lib_pubsub_notify2_1.py index 2775d2d9..ac1e8fd4 100644 --- a/unittests/test_lib_pubsub_notify2_1.py +++ b/unittests/test_lib_pubsub_notify2_1.py @@ -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 - - + + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_notify2_2.py b/unittests/test_lib_pubsub_notify2_2.py index 2c95c96a..fe30933d 100644 --- a/unittests/test_lib_pubsub_notify2_2.py +++ b/unittests/test_lib_pubsub_notify2_2.py @@ -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 - + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_notify4.py b/unittests/test_lib_pubsub_notify4.py index 71d84e0d..58230ff2 100644 --- a/unittests/test_lib_pubsub_notify4.py +++ b/unittests/test_lib_pubsub_notify4.py @@ -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) - + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_provider.py b/unittests/test_lib_pubsub_provider.py index c021dd93..db081d86 100644 --- a/unittests/test_lib_pubsub_provider.py +++ b/unittests/test_lib_pubsub_provider.py @@ -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() - \ No newline at end of file diff --git a/unittests/test_lib_pubsub_spec.py b/unittests/test_lib_pubsub_spec.py index b538a81a..deebb1d3 100644 --- a/unittests/test_lib_pubsub_spec.py +++ b/unittests/test_lib_pubsub_spec.py @@ -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 - + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_topic.py b/unittests/test_lib_pubsub_topic.py index b0631627..033d41c7 100644 --- a/unittests/test_lib_pubsub_topic.py +++ b/unittests/test_lib_pubsub_topic.py @@ -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',) - + #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_pubsub_topicmgr.py b/unittests/test_lib_pubsub_topicmgr.py index 5caf08a1..feb6e294 100644 --- a/unittests/test_lib_pubsub_topicmgr.py +++ b/unittests/test_lib_pubsub_topicmgr.py @@ -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)