3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-12-26 04:32:51 +01:00

utils.joinModes: support joining modes with prefixes

This commit is contained in:
James Lu 2015-07-08 16:58:59 -07:00
parent b92a9ce950
commit 7a37f50a1a
2 changed files with 56 additions and 6 deletions

View File

@ -60,14 +60,40 @@ class TestUtils(unittest.TestCase):
self.assertFalse(utils.isServerName(' i lost th.e game')) self.assertFalse(utils.isServerName(' i lost th.e game'))
def testJoinModes(self): def testJoinModes(self):
res = utils.joinModes({('l', '50'), ('n', None), ('t', None)}) res = utils.joinModes({('+l', '50'), ('+n', None), ('+t', None)})
# Sets are orderless, so the end mode could be scrambled in a number of ways. # Sets are orderless, so the end mode could be scrambled in a number of ways.
# Basically, we're looking for a string that looks like '+ntl 50' or '+lnt 50'. # Basically, we're looking for a string that looks like '+ntl 50' or '+lnt 50'.
possible = ['+%s 50' % ''.join(x) for x in itertools.permutations('lnt', 3)] possible = ['+%s 50' % ''.join(x) for x in itertools.permutations('lnt', 3)]
self.assertIn(res, possible) self.assertIn(res, possible)
# Without any arguments, make sure there is no trailing space. # Without any arguments, make sure there is no trailing space.
self.assertEqual(utils.joinModes({('t', None)}), '+t') self.assertEqual(utils.joinModes({('+t', None)}), '+t')
# The +/- in the mode is not required; if it doesn't exist, assume we're
# adding modes always.
self.assertEqual(utils.joinModes([('t', None), ('n', None)]), '+tn')
# An empty query should return just '+'
self.assertEqual(utils.joinModes(set()), '+') self.assertEqual(utils.joinModes(set()), '+')
# More complex query now with both + and - modes being set
res = utils.joinModes([('+l', '50'), ('-n', None)])
self.assertEqual(res, '+l-n 50')
# If one modepair in the list lacks a +/- prefix, just follow the
# previous one's.
res = utils.joinModes([('+l', '50'), ('-n', None), ('m', None)])
self.assertEqual(res, '+l-nm 50')
res = utils.joinModes([('+l', '50'), ('m', None)])
self.assertEqual(res, '+lm 50')
res = utils.joinModes([('l', '50'), ('-m', None)])
self.assertEqual(res, '+l-m 50')
# Rarely in real life will we get a mode string this complex.
# Let's make sure it works, just in case.
res = utils.joinModes([('-o', '9PYAAAAAA'), ('+l', '50'), ('-n', None),
('-m', None), ('+k', 'hello'),
('+b', '*!*@*.badisp.net')])
self.assertEqual(res, '-o+l-nm+kb 9PYAAAAAA 50 hello *!*@*.badisp.net')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -190,17 +190,41 @@ def applyModes(irc, target, changedmodes):
log.debug('(%s) Final modelist: %s', irc.name, modelist) log.debug('(%s) Final modelist: %s', irc.name, modelist)
def joinModes(modes): def joinModes(modes):
"""<mode list>
Takes a list of (mode, arg) tuples in parseModes() format, and
joins them into a string. See testJoinModes in tests/test_utils.py
for some examples."""
prefix = '+' # Assume we're adding modes unless told otherwise
modelist = '' modelist = ''
args = [] args = []
for modepair in modes: for modepair in modes:
mode, arg = modepair mode, arg = modepair
assert len(mode) in (1, 2), "Incorrect length of a mode (received %r)" % mode
try:
# If the mode has a prefix, use that.
curr_prefix, mode = mode
except ValueError:
# If not, the current prefix stays the same; move on to the next
# modepair.
pass
else:
# If the prefix of this mode isn't the same as the last one, add
# the prefix to the modestring. This prevents '+nt-lk' from turning
# into '+n+t-l-k' or '+ntlk'.
if prefix != curr_prefix:
modelist += curr_prefix
prefix = curr_prefix
modelist += mode modelist += mode
if arg is not None: if arg is not None:
args.append(arg) args.append(arg)
s = '+%s' % modelist if not modelist.startswith(('+', '-')):
# Our starting mode didn't have a prefix with it. Assume '+'.
modelist = '+' + modelist
if args: if args:
s += ' %s' % ' '.join(args) # Add the args if there are any.
return s modelist += ' %s' % ' '.join(args)
return modelist
def isInternalClient(irc, numeric): def isInternalClient(irc, numeric):
"""<irc object> <client numeric> """<irc object> <client numeric>