Esempio n. 1
0
 def setUp(self):
     self.conn = Queue.Queue()
     self.conn.out = ''
     self.wrapper = IrcWrapper(self.conn, 'test', 'tester', None, ['#test'], None)
     self.assertTrue(self.wrapper.nick == 'test')
     self.assertTrue(self.wrapper.realname == 'tester')
     self.assertTrue(self.wrapper.channels == ['#test'])
Esempio n. 2
0
File: bot.py Progetto: karipe/irctk
    def _create_connection(self):
        self.connection = TcpClient(self.config['SERVER'],
                                    self.config['PORT'],
                                    self.config['SSL'],
                                    self.config['TIMEOUT'],
                                    logger=self.logger)

        self.irc = IrcWrapper(self.connection,
                              self.config['NICK'],
                              self.config['REALNAME'],
                              self.config['PASSWORD'],
                              self.config['CHANNELS'],
                              logger=self.logger,
                              user=self.config['USER'])
Esempio n. 3
0
 def setUp(self):
     self.conn = Queue.Queue()
     self.conn.out = ''
     self.wrapper = IrcWrapper(self.conn, 'test', 'tester', None, ['#test'], None)
     self.assertTrue(self.wrapper.nick == 'test')
     self.assertTrue(self.wrapper.realname == 'tester')
     self.assertTrue(self.wrapper.channels == ['#test'])
Esempio n. 4
0
 def setUp(self):
     self.conn = Queue.Queue()
     self.conn.out = ""
     self.wrapper = IrcWrapper(self.conn, "test", "tester", ["#test"], None)
     self.assertTrue(self.wrapper.nick == "test")
     self.assertTrue(self.wrapper.realname == "tester")
     self.assertTrue(self.wrapper.channels == ["#test"])
Esempio n. 5
0
File: bot.py Progetto: edk0/irctk
    def _create_connection(self):
        self.connection = TcpClient(self.config['SERVER'],
                                    self.config['PORT'],
                                    self.config['SSL'],
                                    self.config['TIMEOUT'],
                                    logger=self.logger)

        self.irc = IrcWrapper(self.connection,
                              self.config['NICK'],
                              self.config['REALNAME'],
                              self.config['PASSWORD'],
                              self.config['CHANNELS'],
                              logger=self.logger)
Esempio n. 6
0
class IrcWrapperTestCase(unittest.TestCase):
    '''This test case is used to test the IRC wrapper methods.'''
    
    def setUp(self):
        self.conn = Queue.Queue()
        self.conn.out = ''
        self.wrapper = IrcWrapper(self.conn, 'test', 'tester', None, ['#test'], None)
        self.assertTrue(self.wrapper.nick == 'test')
        self.assertTrue(self.wrapper.realname == 'tester')
        self.assertTrue(self.wrapper.channels == ['#test'])
    
    def test_register(self):
        self.wrapper._register()
        nick = 'NICK test\r\n'
        user = '******'
        self.assertTrue(nick in self.wrapper.out_buffer and user in self.wrapper.out_buffer)
        self.assertEqual(nick, self.wrapper.out_buffer.split('\r\n')[0] + '\r\n')
        self.assertEqual(user, self.wrapper.out_buffer.split('\r\n')[1] + '\r\n')
    
    def test_send(self):
        pass
    
    def test_recv(self):
        pass
    
    def test_parse_line(self):
        line = 'PRIVMSG #testing :test message'
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, '')
        self.assertEqual(command, 'PRIVMSG')
        self.assertEqual(args, ['#testing', 'test message'])
        
        line = ':server.example.net NOTICE Auth :*** Looking up your hostname...'
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, 'server.example.net')
        self.assertEqual(command, 'NOTICE')
        self.assertEqual(args, ['Auth', '*** Looking up your hostname...'])
    
    def test_send_line(self):
        line = 'test'
        self.wrapper._send_line(line)
        self.assertEqual('test\r\n', self.wrapper.out_buffer)
    
    def test_send_lines(self):
        lines = ['foo', 'bar', 'baz']
        expected_result = 'foo\r\nbar\r\nbaz\r\n'
        self.wrapper._send_lines(lines)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
    
    def test_run(self):
        pass
    
    def test_send_command(self):
        command = 'PRIVMSG'
        args = ['#test' + ' :' + 'test']
        expected_result = 'PRIVMSG #test :test\r\n'
        self.wrapper.send_command(command, args)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
    
    def test_send_message(self):
        recipient = '#test'
        message = 'test'
        expected_result = 'PRIVMSG #test :test\r\n'
        self.wrapper.send_message(recipient, message)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ''
        
        recipient = '#test'
        message = 'dances'
        expected_result = 'PRIVMSG #test :\x01ACTION dances\x01\r\n'
        self.wrapper.send_message(recipient, message, action=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ''
        
        recipient = '#test'
        message = 'attention!'
        expected_result = 'NOTICE #test :attention!\r\n'
        self.wrapper.send_message(recipient, message, notice=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        
    def test_send_notice(self):
        pass
    
    def test_send_action(self):
        pass
Esempio n. 7
0
File: bot.py Progetto: karipe/irctk
class Bot(object):
    # used to track the instance of the Bot class
    __shared_state = {}

    # initialize the logger as None
    logger = None

    # initlialize the config as None
    config = None

    # initalize the plugin as None
    plugin = None

    # initalize the reloader as None
    reloader = None

    # set our root path
    root_path = os.path.abspath('')

    # base configuration
    default_config = {'SERVER': '',
                      'PORT': 6667,
                      'PASSWORD': None,
                      'SSL': False,
                      'TIMEOUT': 300,
                      'NICK': '',
                      'USER': None,
                      'REALNAME': '',
                      'CHANNELS': [],
                      'PLUGINS': [],
                      'EVENTS': [],
                      'REGEX': [],
                      'MAX_WORKERS': 7,
                      'MIN_WORKERS': 3,
                      'CMD_PREFIX': '.'}

    def __init__(self):
        self.__dict__ = self.__shared_state

        if self.logger is None:
            self.logger = create_logger()

        # configure the bot instance
        if self.config is None:
            self.config = Config(self, self.root_path, self.default_config)
        else:
            # make sure we clear these upon reloads
            self.config['PLUGINS'] = []
            self.config['EVENTS'] = []
            self.config['REGEX'] = []

        # initialize the plugin handler
        if self.plugin is None:
            self.plugin = PluginHandler(self)

        # initalize the reload handler
        if self.reloader is None:
            self.reloader = ReloadHandler(self)

    def _create_connection(self):
        self.connection = TcpClient(self.config['SERVER'],
                                    self.config['PORT'],
                                    self.config['SSL'],
                                    self.config['TIMEOUT'],
                                    logger=self.logger)

        self.irc = IrcWrapper(self.connection,
                              self.config['NICK'],
                              self.config['REALNAME'],
                              self.config['PASSWORD'],
                              self.config['CHANNELS'],
                              logger=self.logger,
                              user=self.config['USER'])

    def _parse_input(self, wait=0.01):
        '''This internal method handles the parsing of commands and events.
        Hooks for commands are prefixed with a character, by default `.`. This
        may be overriden by specifying `prefix`.

        A context is maintained by our IRC wrapper, `IrcWrapper`; referenced
        as `self.irc`. In order to prevent a single line from being parsed
        repeatedly a variable `stale` is set to either True or False.

        If the context is fresh, i.e. not `stale`, we loop over the line
        looking for matches to plugins.

        Once the context is consumed, we set the context variable `stale` to
        True.
        '''
        prefix = self.config['CMD_PREFIX']

        while True:
            time.sleep(wait)

            with self.irc.lock:
                args = self.irc.context.get('args')
                command = self.irc.context.get('command')
                message = self.irc.context.get('message')
                raw = self.irc.context.get('raw')

                while not self.context_stale and args:

                    # process regex
                    for regex in self.config['REGEX']:
                        hook = regex['hook']
                        search = re.search(hook, raw)
                        if not search:
                            continue
                        regex['context'] = dict(self.irc.context)
                        regex['context']['regex_search'] = search
                        self.plugin.enqueue_plugin(regex,
                                                   hook,
                                                   raw,
                                                   regex=True)

                    # process for a message
                    if message.startswith(prefix):
                        for plugin in self.config['PLUGINS']:
                            plugin['context'] = dict(self.irc.context)
                            hook = prefix + plugin['hook']
                            self.plugin.enqueue_plugin(plugin, hook, message)

                    # process for a command
                    if command and command.isupper():
                        for event in self.config['EVENTS']:
                            event['context'] = dict(self.irc.context)
                            hook = event['hook']
                            self.plugin.enqueue_plugin(event, hook, command)

                    # irc context consumed; mark it as such
                    self.irc.context['stale'] = True

    @property
    def context_stale(self):
        return self.irc.context.get('stale', True)

    def command(self, hook=None, **kwargs):
        '''This method provides a decorator that can be used to load a
        function into the global plugins list.

        If the `hook` parameter is provided the decorator will assign the hook
        key to the value of `hook`, update the `plugin` dict, and then return
        the wrapped function to the wrapper.

        Therein the plugin dictionary is updated with the `func` key whose
        value is set to the wrapped function.

        Otherwise if no `hook` parameter is passed the, `hook` is assumed to
        be the wrapped function and handled accordingly.
        '''
        plugin = {}

        def wrapper(func):
            plugin.setdefault('hook', func.func_name)
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'PLUGINS')
            return func

        if kwargs or not inspect.isfunction(hook):
            if hook:
                plugin['hook'] = hook
            plugin.update(kwargs)
            return wrapper
        else:
            return wrapper(hook)

    def event(self, hook, **kwargs):
        '''This method provides a decorator that can be used to load a
        function into the global events list.

        It assumes one parameter, `hook`, i.e. the event you wish to bind
        this wrapped function to. For example, JOIN, which would call the
        function on all JOIN events.
        '''
        plugin = {}

        def wrapper(func):
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'EVENTS')
            return func

        plugin['hook'] = hook
        plugin.update(kwargs)
        return wrapper

    def regex(self, hook, **kwargs):
        '''Takes a regular expression as a hook.'''
        plugin = {}

        def wrapper(func):
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'REGEX')
            return func

        plugin['hook'] = hook
        plugin.update(kwargs)
        return wrapper

    def add_command(self, hook, func):
        self.plugin._add_plugin(hook, func, command=True)

    def add_event(self, hook, func):
        self.plugin._add_plugin(hook, func, event=True)

    def add_regex(self, hook, func):
        self.plugin._add_plugin(hook, func, regex=True)

    def remove_command(self, hook, func):
        self.plugin._remove_plugin(hook, func, command=True)

    def remove_event(self, hook, func):
        self.plugin._remove_plugin(hook, func, event=True)

    def remove_regex(self, hook, func):
        self.plugin._remove_plugin(hook, func, regex=True)

    def reply(self, message, context, action=False, notice=False,
            recipient=None, line_limit=400):

        # conditionally set the recipient automatically
        if recipient is None:
            if context['sender'].startswith('#'):
                recipient = context['sender']
            else:
                recipient = context['user']

        def messages(message):
            message, extra = message[:line_limit], message[line_limit:]
            yield message
            if extra:
                for message in messages(extra):
                    yield message

        for message in messages(message):
            self.irc.send_message(recipient, message, action, notice)

    def run(self, wait=0.1):
        # create connection
        self._create_connection()

        # connect
        self.connection.connect()

        # start the irc wrapper
        self.irc.run()

        # start the input parsing loop in a new thread
        thread.start_new_thread(self._parse_input, ())

        while True:
            time.sleep(wait)
Esempio n. 8
0
File: bot.py Progetto: karipe/irctk
class Bot(object):
    # used to track the instance of the Bot class
    __shared_state = {}

    # initialize the logger as None
    logger = None

    # initlialize the config as None
    config = None

    # initalize the plugin as None
    plugin = None

    # initalize the reloader as None
    reloader = None

    # set our root path
    root_path = os.path.abspath('')

    # base configuration
    default_config = {
        'SERVER': '',
        'PORT': 6667,
        'PASSWORD': None,
        'SSL': False,
        'TIMEOUT': 300,
        'NICK': '',
        'USER': None,
        'REALNAME': '',
        'CHANNELS': [],
        'PLUGINS': [],
        'EVENTS': [],
        'REGEX': [],
        'MAX_WORKERS': 7,
        'MIN_WORKERS': 3,
        'CMD_PREFIX': '.'
    }

    def __init__(self):
        self.__dict__ = self.__shared_state

        if self.logger is None:
            self.logger = create_logger()

        # configure the bot instance
        if self.config is None:
            self.config = Config(self, self.root_path, self.default_config)
        else:
            # make sure we clear these upon reloads
            self.config['PLUGINS'] = []
            self.config['EVENTS'] = []
            self.config['REGEX'] = []

        # initialize the plugin handler
        if self.plugin is None:
            self.plugin = PluginHandler(self)

        # initalize the reload handler
        if self.reloader is None:
            self.reloader = ReloadHandler(self)

    def _create_connection(self):
        self.connection = TcpClient(self.config['SERVER'],
                                    self.config['PORT'],
                                    self.config['SSL'],
                                    self.config['TIMEOUT'],
                                    logger=self.logger)

        self.irc = IrcWrapper(self.connection,
                              self.config['NICK'],
                              self.config['REALNAME'],
                              self.config['PASSWORD'],
                              self.config['CHANNELS'],
                              logger=self.logger,
                              user=self.config['USER'])

    def _parse_input(self, wait=0.01):
        '''This internal method handles the parsing of commands and events.
        Hooks for commands are prefixed with a character, by default `.`. This
        may be overriden by specifying `prefix`.

        A context is maintained by our IRC wrapper, `IrcWrapper`; referenced
        as `self.irc`. In order to prevent a single line from being parsed
        repeatedly a variable `stale` is set to either True or False.

        If the context is fresh, i.e. not `stale`, we loop over the line
        looking for matches to plugins.

        Once the context is consumed, we set the context variable `stale` to
        True.
        '''
        prefix = self.config['CMD_PREFIX']

        while True:
            time.sleep(wait)

            with self.irc.lock:
                args = self.irc.context.get('args')
                command = self.irc.context.get('command')
                message = self.irc.context.get('message')
                raw = self.irc.context.get('raw')

                while not self.context_stale and args:

                    # process regex
                    for regex in self.config['REGEX']:
                        hook = regex['hook']
                        search = re.search(hook, raw)
                        if not search:
                            continue
                        regex['context'] = dict(self.irc.context)
                        regex['context']['regex_search'] = search
                        self.plugin.enqueue_plugin(regex,
                                                   hook,
                                                   raw,
                                                   regex=True)

                    # process for a message
                    if message.startswith(prefix):
                        for plugin in self.config['PLUGINS']:
                            plugin['context'] = dict(self.irc.context)
                            hook = prefix + plugin['hook']
                            self.plugin.enqueue_plugin(plugin, hook, message)

                    # process for a command
                    if command and command.isupper():
                        for event in self.config['EVENTS']:
                            event['context'] = dict(self.irc.context)
                            hook = event['hook']
                            self.plugin.enqueue_plugin(event, hook, command)

                    # irc context consumed; mark it as such
                    self.irc.context['stale'] = True

    @property
    def context_stale(self):
        return self.irc.context.get('stale', True)

    def command(self, hook=None, **kwargs):
        '''This method provides a decorator that can be used to load a
        function into the global plugins list.

        If the `hook` parameter is provided the decorator will assign the hook
        key to the value of `hook`, update the `plugin` dict, and then return
        the wrapped function to the wrapper.

        Therein the plugin dictionary is updated with the `func` key whose
        value is set to the wrapped function.

        Otherwise if no `hook` parameter is passed the, `hook` is assumed to
        be the wrapped function and handled accordingly.
        '''
        plugin = {}

        def wrapper(func):
            plugin.setdefault('hook', func.func_name)
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'PLUGINS')
            return func

        if kwargs or not inspect.isfunction(hook):
            if hook:
                plugin['hook'] = hook
            plugin.update(kwargs)
            return wrapper
        else:
            return wrapper(hook)

    def event(self, hook, **kwargs):
        '''This method provides a decorator that can be used to load a
        function into the global events list.

        It assumes one parameter, `hook`, i.e. the event you wish to bind
        this wrapped function to. For example, JOIN, which would call the
        function on all JOIN events.
        '''
        plugin = {}

        def wrapper(func):
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'EVENTS')
            return func

        plugin['hook'] = hook
        plugin.update(kwargs)
        return wrapper

    def regex(self, hook, **kwargs):
        '''Takes a regular expression as a hook.'''
        plugin = {}

        def wrapper(func):
            plugin['funcs'] = [func]
            self.plugin._update_plugin(plugin, 'REGEX')
            return func

        plugin['hook'] = hook
        plugin.update(kwargs)
        return wrapper

    def add_command(self, hook, func):
        self.plugin._add_plugin(hook, func, command=True)

    def add_event(self, hook, func):
        self.plugin._add_plugin(hook, func, event=True)

    def add_regex(self, hook, func):
        self.plugin._add_plugin(hook, func, regex=True)

    def remove_command(self, hook, func):
        self.plugin._remove_plugin(hook, func, command=True)

    def remove_event(self, hook, func):
        self.plugin._remove_plugin(hook, func, event=True)

    def remove_regex(self, hook, func):
        self.plugin._remove_plugin(hook, func, regex=True)

    def reply(self,
              message,
              context,
              action=False,
              notice=False,
              recipient=None,
              line_limit=400):

        # conditionally set the recipient automatically
        if recipient is None:
            if context['sender'].startswith('#'):
                recipient = context['sender']
            else:
                recipient = context['user']

        def messages(message):
            message, extra = message[:line_limit], message[line_limit:]
            yield message
            if extra:
                for message in messages(extra):
                    yield message

        for message in messages(message):
            self.irc.send_message(recipient, message, action, notice)

    def run(self, wait=0.1):
        # create connection
        self._create_connection()

        # connect
        self.connection.connect()

        # start the irc wrapper
        self.irc.run()

        # start the input parsing loop in a new thread
        thread.start_new_thread(self._parse_input, ())

        while True:
            time.sleep(wait)
Esempio n. 9
0
class IrcWrapperTestCase(unittest.TestCase):
    '''This test case is used to test the IRC wrapper methods.'''
    
    def setUp(self):
        self.conn = Queue.Queue()
        self.conn.out = ''
        self.wrapper = IrcWrapper(self.conn, 'test', 'tester', None, ['#test'], None)
        self.assertTrue(self.wrapper.nick == 'test')
        self.assertTrue(self.wrapper.realname == 'tester')
        self.assertTrue(self.wrapper.channels == ['#test'])
    
    def test_register(self):
        self.wrapper._register()
        nick = 'NICK test\r\n'
        user = '******'
        self.assertTrue((nick and user) in self.wrapper.out_buffer)
        self.assertEqual(nick, self.wrapper.out_buffer.split('\r\n')[0] + '\r\n')
        self.assertEqual(user, self.wrapper.out_buffer.split('\r\n')[1] + '\r\n')
    
    def test_send(self):
        pass
    
    def test_recv(self):
        pass
    
    def test_parse_line(self):
        line = 'PRIVMSG #testing :test message'
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, '')
        self.assertEqual(command, 'PRIVMSG')
        self.assertEqual(args, ['#testing', 'test message'])
        
        line = ':server.example.net NOTICE Auth :*** Looking up your hostname...'
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, 'server.example.net')
        self.assertEqual(command, 'NOTICE')
        self.assertEqual(args, ['Auth', '*** Looking up your hostname...'])
    
    def test_send_line(self):
        line = 'test'
        self.wrapper._send_line(line)
        self.assertEqual('test\r\n', self.wrapper.out_buffer)
    
    def test_send_lines(self):
        lines = ['foo', 'bar', 'baz']
        expected_result = 'foo\r\nbar\r\nbaz\r\n'
        self.wrapper._send_lines(lines)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
    
    def test_run(self):
        pass
    
    def test_send_command(self):
        command = 'PRIVMSG'
        args = ['#test' + ' :' + 'test']
        expected_result = 'PRIVMSG #test :test\r\n'
        self.wrapper.send_command(command, args)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
    
    def test_send_message(self):
        recipient = '#test'
        message = 'test'
        expected_result = 'PRIVMSG #test :test\r\n'
        self.wrapper.send_message(recipient, message)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ''
        
        recipient = '#test'
        message = 'dances'
        expected_result = 'PRIVMSG #test :\x01ACTION dances\x01\r\n'
        self.wrapper.send_message(recipient, message, action=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ''
        
        recipient = '#test'
        message = 'attention!'
        expected_result = 'NOTICE #test :attention!\r\n'
        self.wrapper.send_message(recipient, message, notice=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        
    def test_send_notice(self):
        pass
    
    def test_send_action(self):
        pass
Esempio n. 10
0
class IrcWrapperTestCase(unittest.TestCase):
    """This test case is used to test the IRC wrapper methods."""

    def setUp(self):
        self.conn = Queue.Queue()
        self.conn.out = ""
        self.wrapper = IrcWrapper(self.conn, "test", "tester", ["#test"], None)
        self.assertTrue(self.wrapper.nick == "test")
        self.assertTrue(self.wrapper.realname == "tester")
        self.assertTrue(self.wrapper.channels == ["#test"])

    def test_register(self):
        self.wrapper._register()
        nick = "NICK test\r\n"
        user = "******"
        self.assertTrue((nick and user) in self.wrapper.out_buffer)
        self.assertEqual(nick, self.wrapper.out_buffer.split("\r\n")[0] + "\r\n")
        self.assertEqual(user, self.wrapper.out_buffer.split("\r\n")[1] + "\r\n")

    def test_send(self):
        pass

    def test_recv(self):
        pass

    def test_parse_line(self):
        line = "PRIVMSG #testing :test message"
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, "")
        self.assertEqual(command, "PRIVMSG")
        self.assertEqual(args, ["#testing", "test message"])

        line = ":server.example.net NOTICE Auth :*** Looking up your hostname..."
        prefix, command, args = self.wrapper._parse_line(line)
        self.assertEqual(prefix, "server.example.net")
        self.assertEqual(command, "NOTICE")
        self.assertEqual(args, ["Auth", "*** Looking up your hostname..."])

    def test_send_line(self):
        line = "test"
        self.wrapper._send_line(line)
        self.assertEqual("test\r\n", self.wrapper.out_buffer)

    def test_send_lines(self):
        lines = ["foo", "bar", "baz"]
        expected_result = "foo\r\nbar\r\nbaz\r\n"
        self.wrapper._send_lines(lines)
        self.assertEqual(expected_result, self.wrapper.out_buffer)

    def test_run(self):
        pass

    def test_send_command(self):
        command = "PRIVMSG"
        args = ["#test" + " :" + "test"]
        expected_result = "PRIVMSG #test :test\r\n"
        self.wrapper.send_command(command, args)
        self.assertEqual(expected_result, self.wrapper.out_buffer)

    def test_send_message(self):
        recipient = "#test"
        message = "test"
        expected_result = "PRIVMSG #test :test\r\n"
        self.wrapper.send_message(recipient, message)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ""

        recipient = "#test"
        message = "dances"
        expected_result = "PRIVMSG #test :\x01ACTION dances\x01\r\n"
        self.wrapper.send_message(recipient, message, action=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)
        self.wrapper.out_buffer = ""

        recipient = "#test"
        message = "attention!"
        expected_result = "NOTICE #test :attention!\r\n"
        self.wrapper.send_message(recipient, message, notice=True)
        self.assertEqual(expected_result, self.wrapper.out_buffer)

    def test_send_notice(self):
        pass

    def test_send_action(self):
        pass