예제 #1
0
    def test_mark(self):
        f = mocks.FE()
        w = messager.Messager(f)
        self.assertIsNone(w.the_mark)
        m = f.context.backends._messages
        m.append(mocks.Message())
        m.append(mocks.Message())
        w.set_mark()
        self.assertEqual(w.the_mark, w.cursor)
        w.set_mark(m[-1])
        self.assertEqual(w.the_mark, m[-1])
        self.assertEqual(w.mark_ring[-1], m[0])

        where = w.cursor
        there = w.the_mark
        anywhere = w.mark_ring[-1]
        w.set_mark(prefix=[4])
        self.assertEqual(w.mark_ring[0], where)
        self.assertEqual(w.the_mark, anywhere)
        self.assertEqual(w.cursor, there)

        o = object()
        self.assertIs(o, w.make_mark(o))  # pass through

        self.assertNotEqual(w.cursor, m[0])
        w.go_mark(m[0])
        self.assertEqual(w.cursor, m[0])
        w.the_mark = m[-1]
        w.exchange_point_and_mark()
        self.assertEqual(w.cursor, m[-1])
        self.assertEqual(w.the_mark, m[0])
예제 #2
0
    async def test_send(self):
        f = mocks.FE()
        m = mocks.Message()
        m.omega = True
        f.context.backends._messages.append(m)
        w = messager.Messager(f)
        w.renderer = mocks.Renderer((f.context.backends._messages[0],
                                     f.context.backends._messages[-1]))

        c = w.cursor

        _read_args = None
        _read_kw = None
        _read_result = 'foo\nbar'

        async def read_string(*args, **kw):
            nonlocal _read_args, _read_kw
            _read_args, _read_kw = args, kw
            return _read_result

        w.read_string = read_string
        await w.send()

        self.assertEqual(f.context.backends._sent[-1], ('foo', 'bar'))
        self.assertNotIn('modes', _read_kw)
        self.assertEqual(w.secondary, c)

        w.cursor = c
        _read_result = 'foo'

        await w.send(msg=c)

        self.assertIn('modes', _read_kw)
        self.assertEqual(f.context.backends._sent[-1], ('foo', ''))
예제 #3
0
    def test_FilterLookup(self):
        self.assertEqual(snipe.filters.FilterLookup('foo'),
                         snipe.filters.FilterLookup('foo'))
        self.assertEqual(hash(snipe.filters.FilterLookup('foo')),
                         hash(snipe.filters.FilterLookup('foo')))
        self.assertNotEqual(snipe.filters.FilterLookup('foo'),
                            snipe.filters.FilterLookup('bar'))
        self.assertNotEqual(hash(snipe.filters.FilterLookup('foo')),
                            hash(snipe.filters.FilterLookup('bar')))
        m = mocks.Message()
        self.assertFalse(snipe.filters.FilterLookup('default')(m))
        m.conf['filter'] = {'default': 'yes'}
        self.assertTrue(snipe.filters.FilterLookup('default')(m))
        # naughty
        m.conf['filter']['self_reference'] = 'filter self_reference'
        self.assertFalse(snipe.filters.FilterLookup('self_reference')(m))
        m.conf['filter']['bad'] = '== == =='
        self.assertFalse(snipe.filters.FilterLookup('bad')(m))

        self.assertFalse(
            snipe.filters.FilterLookup('nonexistent').simplify({'context': m}))
        self.assertFalse(
            snipe.filters.FilterLookup('self_reference').simplify(
                {'context': m}))

        m.conf['filter']['wrong'] = 'and and and nope'
        self.assertFalse(
            snipe.filters.FilterLookup('wrong').simplify({'context': m}))
        self.assertEqual(repr(snipe.filters.FilterLookup('foo')),
                         "FilterLookup('foo')")
        self.assertEqual(str(snipe.filters.FilterLookup('foo')), 'filter foo')
예제 #4
0
    def test_format(self):
        Decor = zulip.ZulipMessage.Decor
        msg = mocks.Message(data={'content': 'bar'})

        self.assertEqual(Decor.format(msg), [
            (set(), 'bar\n'),
        ])
예제 #5
0
 def test_cursor_set_walk(self):
     f = mocks.FE()
     w = messager.Messager(f)
     m = mocks.Message()
     m.omega = True
     f.context.backends._messages.append(m)
     self.assertEqual(w.cursor, f.context.backends._messages[0])
     w.cursor_set_walk_mark(None, False)
     self.assertEqual(w.cursor, f.context.backends._messages[1])
예제 #6
0
    def test_move_cleverly(self):
        f = mocks.FE()
        w = messager.Messager(f)
        f.context.backends._messages.append(mocks.Message())

        self.assertIs(w.cursor, f.context.backends._messages[0])
        w.next_message_cleverly()
        self.assertIs(w.cursor, f.context.backends._messages[1])
        w.prev_message_cleverly()
        self.assertIs(w.cursor, f.context.backends._messages[0])
예제 #7
0
 def test_after_command(self):
     f = mocks.FE()
     w = messager.Messager(f)
     m = mocks.Message()
     m.omega = True
     f.context.backends._messages.append(m)
     w.next_message()
     w.after_command()
     self.assertEqual(f.context.starks[-1],
                      f.context.backends._messages[0].time)
예제 #8
0
 def test_end_beginning(self):
     f = mocks.FE()
     w = messager.Messager(f)
     m = mocks.Message()
     m.omega = True
     f.context.backends._messages.append(m)
     self.assertEqual(w.cursor, f.context.backends._messages[0])
     w.end()
     self.assertEqual(w.cursor, f.context.backends._messages[1])
     w.beginning()
     self.assertEqual(w.cursor, f.context.backends._messages[0])
예제 #9
0
 def test_move_starks(self):
     w = messager.Messager(mocks.FE())
     m = w.context.backends._messages
     m.append(mocks.Message())
     m.append(mocks.Message())
     self.assertEqual(w.cursor, m[0])
     w.end()
     self.assertEqual(w.cursor, m[-1])
     w.previous_stark()
     self.assertEqual(w.cursor, m[-1])
     w.beginning()
     self.assertEqual(w.cursor, m[0])
     w.context.starks = [m[0].time, m[2].time]
     w.next_stark()
     self.assertEqual(w.cursor, m[2])
     w.previous_stark()
     self.assertEqual(w.cursor, m[0])
     w.next_stark()
     m.append(mocks.Message())
     w.next_stark()
     self.assertEqual(w.cursor, m[3])
예제 #10
0
 def test_walk(self):
     a = mocks.Aggregator()
     self.assertEqual(
         list(a.walk(None, True)),
         [a._messages[0]])  # explicit is better than implicit
     self.assertEqual(
         list(a.walk(float('Inf'), False)),
         [a._messages[0]])
     a._messages.append(mocks.Message())
     self.assertEqual(
         list(a.walk(None, True)),
         [a._messages[0], a._messages[1]])
     self.assertEqual(
         list(a.walk(float('Inf'), False)),
         [a._messages[1], a._messages[0]])
     a._messages.append(mocks.Message())
     self.assertEqual(
         list(a.walk(a._messages[1], True)),
         [a._messages[1], a._messages[2]])
     self.assertEqual(
         list(a.walk(a._messages[1], False)),
         [a._messages[1], a._messages[0]])
예제 #11
0
 def test_find(self):
     f = mocks.FE()
     w = messager.Messager(f)
     self.assertFalse(w.find('foo', True))
     self.assertEqual([[({'visible', 'bar'}, '\n')]],
                      [chunk.tagsets() for (mark, chunk) in w.view(0)])
     f.context.backends._messages.append(mocks.Message())
     f.context.backends._messages[-1]._display = chunks.Chunk([((), 'foo\n')
                                                               ])
     self.assertEqual([[({'visible', 'bar'}, '\n')], [((), 'foo\n')]],
                      [chunk.tagsets() for (mark, chunk) in w.view(0)])
     self.assertTrue(w.find('foo', True))
     self.assertEqual([[((), '\n')], [({'visible', 'bar'}, 'foo\n')]],
                      [chunk.tagsets() for (mark, chunk) in w.view(0)])
예제 #12
0
    async def test_write_region(self):
        w = messager.Messager(mocks.FE())
        w.context.backends._messages[0].body = 'foo'
        w.context.backends._messages.append(mocks.Message())
        fp = io.StringIO('')
        w.read_filename = returning('/nope')

        @contextlib.contextmanager
        def mock_open(*args):
            print(args)
            yield fp

        messager.open = mock_open
        await w.write_region()
        del messager.open
        self.assertEqual(fp.getvalue(), 'foo')
예제 #13
0
    def test_format(self):
        Decor = roost.RoostMessage.Decor
        msg = mocks.Message()

        self.assertEqual(Decor.format(msg), [])

        msg.body = '@[foo]'

        msg.backend.format_body = 'format'
        self.assertEqual(Decor.format(msg), [
            (set(), 'foo\n'),
        ])

        msg.backend.format_body = 'strip'
        self.assertEqual(Decor.format(msg), [
            (set(), 'foo\n'),
        ])
예제 #14
0
    def test_headline(self):
        Decor = zulip.ZulipMessage.Decor
        msg = mocks.Message(data={
            'timestamp': 0.0,
            'sender_email': 'baz',
        })
        msg._chat = 'foo'
        msg.sender = messages.SnipeAddress(mocks.Backend())
        os.environ['TZ'] = 'GMT'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [({'bold'}, '·foo>'), ((), ' <'),
                                            ({'bold'}, 'baz'), ((), '>'),
                                            ({'right'}, ' 00:00:00\n')])

        msg.data['subject'] = 'zog'
        msg.data['sender_full_name'] = 'The Great Quux'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [({'bold'}, '·foo>'),
                                            ((), ' zog <'), ({'bold'}, 'baz'),
                                            ((), '> The Great Quux'),
                                            ({'right'}, ' 00:00:00\n')])
예제 #15
0
    def test(self):
        Decor = irccloud.IRCCloudMessage.Decor
        msg = mocks.Message(data={
            'type': 'buffer_msg',
            })
        msg.time = 0.0
        msg.channel = '#foo'
        msg.body = 'bar'
        msg.sender = messages.SnipeAddress(mocks.Backend())
        os.environ['TZ'] = 'GMT'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                (('bold',), 'mock'),
                (('fill',), ': bar'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'error'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'bar'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'banned'
        msg.data['server'] = 'quux'
        msg.data['reason'] = 'because'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'quux: because'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'hidden_host_set'
        msg.data['hidden_host'] = 'thing'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'quux: thing bar'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'myinfo'
        msg.data['version'] = '0'
        msg.data['user_modes'] = 'user'
        msg.data['channel_modes'] = 'b'
        msg.data['rest'] = 'a'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'quux: 0, user modes: user, channel modes: ab'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'connecting_failed'
        msg.data['hostname'] = 'jupiter'
        msg.data['port'] = 1999
        msg.data['ssl'] = True
        msg.data['reason'] = 'doubtful'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'jupiter:1999 (ssl) connection failed: doubtful'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'quit_server'
        msg.data['nick'] = 'She'
        msg.data['msg'] = 'umami'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'jupiter:1999 (ssl) She quit: umami'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'you_nickchange'
        msg.data['newnick'] = 'red'
        msg.data['oldnick'] = 'blue'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'you are now red (née blue)'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'channel_topic'
        msg.data['from_name'] = 'some luser'
        msg.data['topic'] = 'something boring'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'some luser set topic to '),
                (('bold',), 'something boring'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'channel_timestamp'
        msg.data['timestamp'] = 0

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'created Thu Jan  1 00:00:00 1970'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'user_channel_mode'
        msg.data['ops'] = {
            'add': [{'mode': 'mode', 'param': 'param'}],
            'remove': [{'mode': 'mode', 'param': 'param'}],
            }

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'some luser set '),
                (('bold',), '+mode param -mode param'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'user_mode'
        msg.data['from'] = 'droid'
        msg.data['diff'] = '9000'
        msg.data['newmode'] = 'ants'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'droid set '),
                (('bold',), '9000'),
                ((), ' ('),
                (('bold',), 'ants'),
                ((), ') on you'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'channel_mode_is'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'mode '),
                (('bold',), '9000'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'channel_url'
        msg.data['url'] = 'file:///'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'url: '),
                (('bold',), 'file:///'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'channel_mode_list_change'
        msg.data['url'] = 'file:///'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'channel mode '),
                (('bold',), '9000'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'joined_channel'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), '+ '),
                (('bold',), 'mock'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'parted_channel'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), '- '),
                (('bold',), 'mock'),
                ((), ': bar'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = 'nickchange'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'blue'),
                ((), ' -> '),
                (('bold',), 'mock'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data = {}

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), 'mock [no type] eid - bid - cid -\n{}'),
                (('right',), ' 00:00:00'),
                ]))
예제 #16
0
    def test_Parser(self):
        snipe.filters.parser = Parser(debug=True)
        self.assertEqual(makefilter('yes'), Yes())
        self.assertEqual(makefilter('yes and no'), And(Yes(), No()))
        self.assertEqual(makefilter('foo = "bar"'), Compare('=', 'foo', 'bar'))
        self.assertEqual(makefilter('foo < "bar"'), Compare('<', 'foo', 'bar'))
        self.assertEqual(makefilter('"bar" = foo'), Compare('=', 'foo', 'bar'))
        self.assertEqual(makefilter('foo = bar'),
                         Compare('=', 'foo', Identifier('bar')))
        self.assertEqual(makefilter('foo = /bar/'),
                         RECompare('=', 'foo', 'bar'))
        self.assertEqual(makefilter('/bar/ = foo'),
                         RECompare('=', 'foo', 'bar'))
        self.assertEqual(makefilter('1 = 1'), Yes())
        self.assertEqual(makefilter('1 = 2'), No())
        self.assertEqual(makefilter('"foo" = /foo/'), Yes())
        self.assertEqual(makefilter('"foo" = /bar/'), No())
        self.assertEqual(makefilter('"Foo" = /foo/i'), Yes())
        self.assertEqual(makefilter('"Foo" != /foo/i'), No())
        self.assertEqual(makefilter('(yes or no) and yes'),
                         And(Or(Yes(), No()), Yes()))
        self.assertEqual(makefilter('yes xor no'), Xor(Yes(), No()))

        self.assertTrue(makefilter('foo = "bar"')(mocks.Message(foo='bar')))
        self.assertFalse(makefilter('foo = "bar"')(mocks.Message(foo='baz')))

        self.assertTrue(makefilter('foo = /b.*/')(mocks.Message(foo='bar')))
        self.assertTrue(makefilter('foo = /b.*/')(mocks.Message(foo='baz')))
        self.assertFalse(makefilter('foo = /b.*/')(mocks.Message(foo='quux')))

        self.assertTrue(
            makefilter('foo = bar')(mocks.Message(foo='quux', bar='quux')))

        self.assertFalse(
            makefilter('foo = bar')(mocks.Message(foo='quux', bar='quuux')))

        self.assertTrue(
            makefilter('foo = "bar"')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))
        self.assertFalse(
            makefilter('not foo = "bar"')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))
        self.assertFalse(
            makefilter('foo == "bar"')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))
        self.assertTrue(
            makefilter('foo = /bar/')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))
        self.assertFalse(
            makefilter('foo == /bar/')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))
        self.assertFalse(
            makefilter('foo == /bar[/')(mocks.Message(
                foo='Bar',
                Foo='bar',
            )))

        self.assertEqual(str(makefilter('foo == "bar"')), 'foo == "bar"')
        self.assertEqual(str(makefilter('"bar" == foo')), 'foo == "bar"')

        self.assertEqual(str(makefilter('yes and yes and yes')),
                         'yes and yes and yes')

        self.assertEqual(str(makefilter('no and yes and yes')),
                         'no and yes and yes')

        self.assertEqual(str(makefilter('yes and no and yes')),
                         'yes and no and yes')

        self.assertEqual(str(makefilter('yes and yes and no')),
                         'yes and yes and no')

        self.assertTrue(makefilter('foo')(mocks.Message(foo=True)))
        self.assertFalse(makefilter('foo')(mocks.Message(foo=0)))
        self.assertFalse(makefilter('foo')(mocks.Message(foo=0)))

        self.assertIs(makefilter(''), None)

        self.assertFalse(makefilter('filter foo')(mocks.Message()))
예제 #17
0
    def test(self):
        Decor = slack.SlackMessage.Decor
        msg = mocks.Message(data={
            'type': 'message',
            'subtype': 'me_message',
            'edited': '?',
            'is_starred': True,
            'pinned_to': True,
            'text': 'baz',
            })
        msg.time = 0.0
        msg.channel = '#foo'
        msg.body = 'bar'
        msg.sender = messages.SnipeAddress(mocks.Backend())
        os.environ['TZ'] = 'GMT'
        msg.slackmarkup = lambda text, tags: [(tags, text)]

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), '~'),
                ((), '*'),
                ((), '+'),
                (('bold',), 'mock'),
                ((), ' '),
                ((), 'baz'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['is_starred'] = False
        msg.data['pinned_to'] = False
        del msg.data['edited']
        msg.data['subtype'] = ''

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                (('bold',), 'mock'),
                ((), ': '),
                ((), 'baz'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['file'] = {'url': 'file:///'}

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                (('bold',), 'mock'),
                ((), ': '),
                ((), 'baz'),
                ((), '\nfile:///'),
                (('right',), ' 00:00:00'),
                ]))

        del msg.data['file']

        msg.data['reactions'] = [{'name': 'over', 'count': 9000}]

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                (('bold',), 'mock'),
                ((), ': '),
                ((), 'baz'),
                ((), '\n:over: 9000'),
                (('right',), ' 00:00:00'),
                ]))

        del msg.data['reactions']
        msg.data['attachments'] = [
            {
                'color': 'danger',
                'title_link': 'file:///',
                'text': 'things',
                'fields': [{'title': 'key', 'value': 'value'}],
            }, {
                'color': 'f0f0f0',
                'text': 'stuff',
            }]

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                (('bold',), 'mock'),
                ((), ': '),
                ((), 'baz'),
                ((), '\n'),
                (('bg:red',), ' '),
                ((), ' '),
                ((), 'file:///'),
                ((), '\n'),
                (('bg:red',), ' '),
                ((), ' '),
                ((), 'things'),
                ((), '\n'),
                (('bg:red',), ' '),
                ((), ' '),
                (('bold',), 'key'),
                ((), '\n'),
                (('bg:red',), ' '),
                ((), ' '),
                ((), 'value'),
                ((), '\n'),
                (('bg:#f0f0f0',), ' '),
                ((), ' '),
                ((), 'stuff'),
                (('right',), ' 00:00:00'),
                ]))

        del msg.data['attachments']

        msg.data['type'] = 'presence_change'
        msg.data['presence'] = 'active'

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), '+ '),
                (('bold',), 'mock'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['presence'] = 'passive'  # ?

        self.assertEqual(
            Decor.headline(msg), Chunk([
                (('bold',), '#foo '),
                ((), '- '),
                (('bold',), 'mock'),
                (('right',), ' 00:00:00'),
                ]))

        msg.data['type'] = None

        self.assertEqual(
            Decor.headline(msg, {'fg:white', 'bg:blue'}), [
                    ({'fg:white', 'bg:blue', 'bold'}, 'followup'),
                    ({'fg:white', 'bg:blue'}, ' : '),
                    ({'fg:white', 'bg:blue', 'bold'}, 'mock'),
                    ({'fg:white', 'bg:blue', 'right'}, ' 00:00:00'),
                    ({'fg:white', 'bg:blue'}, 'bar\n')
                ])
예제 #18
0
    def test_headline(self):
        Decor = roost.RoostMessage.Decor
        msg = mocks.Message(data={
            'class': 'foo',
            'instance': 'bar',
            'recipient': '',
            'opcode': 'baz',
            'time': 0.0,
            })
        msg.sender = messages.SnipeAddress(mocks.Backend())
        os.environ['TZ'] = 'GMT'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar [baz] <'),
                ({'bold'}, 'mock'),
                ((), '>'),
                ({'right'}, ' 00:00:00')])

        msg.data['recipient'] = '@QUUX'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar'),
                ({'bold'}, ' @QUUX'),
                ((), ' [baz] <'),
                ({'bold'}, 'mock'),
                ((), '>'),
                ({'right'}, ' 00:00:00')])

        msg.data['recipient'] = 'someone'
        msg.personal = True

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ({'bold'}, '<personal)'),
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar [baz] <'),
                ({'bold'}, 'mock'),
                ((), '>'),
                ({'right'}, ' 00:00:00')])

        msg.outgoing = True

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ({'bold'}, '(personal> <>'),
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar [baz] <'),
                ({'bold'}, 'mock'),
                ((), '>'),
                ({'right'}, ' 00:00:00')])

        msg.data['opcode'] = ''
        msg.data['recipient'] = ''
        msg.personal = False
        msg.outgoing = False

        msg.data['signature'] = '@{The Great Quux}'

        msg.backend.format_zsig = 'format'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar <'),
                ({'bold'}, 'mock'),
                ((), '> The Great Quux'),
                ({'right'}, ' 00:00:00')])

        msg.backend.format_zsig = 'strip'

        self.assertEqual(
            Decor.headline(msg).tagsets(), [
                ((), '-c '),
                ({'bold'}, 'foo'),
                ((), ' -i bar <'),
                ({'bold'}, 'mock'),
                ((), '> The Great Quux'),
                ({'right'}, ' 00:00:00')])