Skip to content

Commit

Permalink
Add test for synerrmixin behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
vEpiphyte committed Dec 31, 2024
1 parent ab0196a commit b4585d1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
4 changes: 3 additions & 1 deletion synapse/lib/stormctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ class StormCtrlFlow(Exception):
'''
Base class all StormCtlFlow exceptions derive from.
'''
def __init__(self):
raise NotImplementedError

class _SynErrMixin(Exception):
'''
An exception mixin to give some control flow classes functionality like SynErr
'''
def __init__(self, **info):
def __init__(self, *args, **info):
self.errinfo = info
Exception.__init__(self, self._getExcMsg())

Expand Down
65 changes: 65 additions & 0 deletions synapse/tests/test_lib_stormctrl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import pickle

import synapse.lib.stormctrl as s_stormctrl

import synapse.tests.utils as s_t_utils

class StormctrlTest(s_t_utils.SynTest):
def test_basic(self):

# Classes inherit as expected
self.isinstance(s_stormctrl.StormReturn(), s_stormctrl.StormCtrlFlow)
self.isinstance(s_stormctrl.StormExit(), s_stormctrl.StormCtrlFlow)
self.isinstance(s_stormctrl.StormBreak(), s_stormctrl.StormCtrlFlow)
self.isinstance(s_stormctrl.StormContinue(), s_stormctrl.StormCtrlFlow)
self.isinstance(s_stormctrl.StormStop(), s_stormctrl.StormCtrlFlow)

# Subtypes are noted as well
self.isinstance(s_stormctrl.StormBreak(), s_stormctrl.StormLoopCtrl)
self.isinstance(s_stormctrl.StormContinue(), s_stormctrl.StormLoopCtrl)
self.isinstance(s_stormctrl.StormStop(), s_stormctrl.StormGenrCtrl)

# control flow and exist constructs inherit from the SynErrMixin
# return does not to keep it thin. it is used often.
self.isinstance(s_stormctrl.StormExit(), s_stormctrl._SynErrMixin)
self.isinstance(s_stormctrl.StormBreak(), s_stormctrl._SynErrMixin)
self.isinstance(s_stormctrl.StormContinue(), s_stormctrl._SynErrMixin)
self.isinstance(s_stormctrl.StormStop(), s_stormctrl._SynErrMixin)
self.false(isinstance(s_stormctrl.StormReturn(), s_stormctrl._SynErrMixin))

# The base class cannot be used on its own.
with self.raises(NotImplementedError):
s_stormctrl.StormCtrlFlow()

# The _SynErrMixin classes have several methods that let us treat
# instance of htem like SynErr exceptions.
e = s_stormctrl.StormExit(mesg='words', foo='bar')

self.eq(e.get('foo'), 'bar')
self.eq("StormExit: foo='bar' mesg='words'", str(e))
e.set('hehe', 1234)
e.set('foo', 'words')
self.eq("StormExit: foo='words' hehe=1234 mesg='words'", str(e))

e.setdefault('defv', 1)
self.eq("StormExit: defv=1 foo='words' hehe=1234 mesg='words'", str(e))

e.setdefault('defv', 2)
self.eq("StormExit: defv=1 foo='words' hehe=1234 mesg='words'", str(e))

e.update({'foo': 'newwords', 'bar': 'baz'})
self.eq("StormExit: bar='baz' defv=1 foo='newwords' hehe=1234 mesg='words'", str(e))

# But it does not have an errname property
self.false(hasattr(e, 'errname'))

# StormReturn is used to move objects around.
e = s_stormctrl.StormReturn('weee')
self.eq(e.item, 'weee')

async def test_pickled_stormctrlflow(self):
e = s_stormctrl.StormExit(mesg='words', foo='bar')
buf = pickle.dumps(e)
new_e = pickle.loads(buf)
self.eq(new_e.get('foo'), 'bar')
self.eq("StormExit: foo='bar' mesg='words'", str(new_e))

0 comments on commit b4585d1

Please sign in to comment.