@@ -1,5 +1,3 @@ | |||||
# Ignore python bytecode: | |||||
*.pyc | *.pyc | ||||
# Ignore OS X's stuff: | |||||
*.egg-info | |||||
.DS_Store | .DS_Store |
@@ -59,7 +59,7 @@ class BaseCommand(object): | |||||
""" | """ | ||||
self.bot = bot | self.bot = bot | ||||
self.config = bot.config | self.config = bot.config | ||||
self.logger = bot.commands.getLogger(self.name) | |||||
self.logger = bot.commands.logger.getChild(self.name) | |||||
def _wrap_process(self, data): | def _wrap_process(self, data): | ||||
"""Make a quick connection alias and then process() the message.""" | """Make a quick connection alias and then process() the message.""" | ||||
@@ -95,7 +95,7 @@ class BaseCommand(object): | |||||
class CommandManager(object): | class CommandManager(object): | ||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getLogger("commands") | |||||
self.logger = bot.logger.getChild("commands") | |||||
self._commands = {} | self._commands = {} | ||||
self._command_access_lock = Lock() | self._command_access_lock = Lock() | ||||
@@ -40,7 +40,7 @@ class Frontend(IRCConnection): | |||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getLogger("frontend") | |||||
self.logger = bot.logger.getChild("frontend") | |||||
cf = bot.config.irc["frontend"] | cf = bot.config.irc["frontend"] | ||||
base = super(Frontend, self) | base = super(Frontend, self) | ||||
@@ -39,7 +39,7 @@ class Watcher(IRCConnection): | |||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getLogger("watcher") | |||||
self.logger = bot.logger.getChild("watcher") | |||||
cf = bot.config.irc["watcher"] | cf = bot.config.irc["watcher"] | ||||
base = super(Watcher, self) | base = super(Watcher, self) | ||||
@@ -51,7 +51,7 @@ class BaseTask(object): | |||||
""" | """ | ||||
self.bot = bot | self.bot = bot | ||||
self.config = bot.config | self.config = bot.config | ||||
self.logger = bot.tasks.logger.getLogger(self.name) | |||||
self.logger = bot.tasks.logger.getChild(self.name) | |||||
self.setup() | self.setup() | ||||
def setup(self): | def setup(self): | ||||
@@ -135,7 +135,7 @@ class BaseTask(object): | |||||
class TaskManager(object): | class TaskManager(object): | ||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getLogger("tasks") | |||||
self.logger = bot.logger.getChild("tasks") | |||||
self._tasks = {} | self._tasks = {} | ||||
self._task_access_lock = Lock() | self._task_access_lock = Lock() | ||||
@@ -21,7 +21,7 @@ | |||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
# SOFTWARE. | # SOFTWARE. | ||||
from setuptools import setup | |||||
from setuptools import setup, find_packages | |||||
from earwigbot import __version__ | from earwigbot import __version__ | ||||
@@ -30,7 +30,7 @@ with open("README.rst") as fp: | |||||
setup( | setup( | ||||
name = "earwigbot", | name = "earwigbot", | ||||
packages = ["earwigbot"], | |||||
packages = find_packages(exclude=("tests",)), | |||||
entry_points = {"console_scripts": ["earwigbot = earwigbot.util:main"]}, | entry_points = {"console_scripts": ["earwigbot = earwigbot.util:main"]}, | ||||
install_requires = ["PyYAML >= 3.10", # Config parsing | install_requires = ["PyYAML >= 3.10", # Config parsing | ||||
"oursql >= 0.9.3", # Talking with MediaWiki databases | "oursql >= 0.9.3", # Talking with MediaWiki databases | ||||
@@ -23,26 +23,41 @@ | |||||
""" | """ | ||||
EarwigBot's Unit Tests | EarwigBot's Unit Tests | ||||
This package __init__ file provides some support code for unit tests. | |||||
This __init__ file provides some support code for unit tests. | |||||
Test cases: | |||||
-- CommandTestCase provides setUp() for creating a fake connection, plus | |||||
some other helpful methods for testing IRC commands. | |||||
Fake objects: | |||||
-- FakeBot implements Bot, using the Fake* equivalents of all objects | |||||
whenever possible. | |||||
-- FakeBotConfig implements BotConfig with silent logging. | |||||
-- FakeIRCConnection implements IRCConnection, using an internal string | |||||
buffer for data instead of sending it over a socket. | |||||
CommandTestCase is a subclass of unittest.TestCase that provides setUp() for | |||||
creating a fake connection and some other helpful methods. It uses | |||||
FakeConnection, a subclass of classes.Connection, but with an internal string | |||||
instead of a socket for data. | |||||
""" | """ | ||||
import logging | |||||
from os import path | |||||
import re | import re | ||||
from threading import Lock | |||||
from unittest import TestCase | from unittest import TestCase | ||||
from earwigbot.bot import Bot | |||||
from earwigbot.commands import CommandManager | |||||
from earwigbot.config import BotConfig | |||||
from earwigbot.irc import IRCConnection, Data | from earwigbot.irc import IRCConnection, Data | ||||
from earwigbot.tasks import TaskManager | |||||
from earwigbot.wiki import SitesDBManager | |||||
class CommandTestCase(TestCase): | class CommandTestCase(TestCase): | ||||
re_sender = re.compile(":(.*?)!(.*?)@(.*?)\Z") | re_sender = re.compile(":(.*?)!(.*?)@(.*?)\Z") | ||||
def setUp(self, command): | def setUp(self, command): | ||||
self.connection = FakeConnection() | |||||
self.connection._connect() | |||||
self.command = command(self.connection) | |||||
self.bot = FakeBot(path.dirname(__file__)) | |||||
self.command = command(self.bot) | |||||
self.command.connection = self.connection = self.bot.frontend | |||||
def get_single(self): | def get_single(self): | ||||
data = self.connection._get().split("\n") | data = self.connection._get().split("\n") | ||||
@@ -93,15 +108,37 @@ class CommandTestCase(TestCase): | |||||
return self.maker(line, line[2][1:]) | return self.maker(line, line[2][1:]) | ||||
class FakeConnection(IRCConnection): | |||||
def __init__(self): | |||||
pass | |||||
class FakeBot(Bot): | |||||
def __init__(self, root_dir): | |||||
self.config = FakeBotConfig(root_dir) | |||||
self.logger = logging.getLogger("earwigbot") | |||||
self.commands = CommandManager(self) | |||||
self.tasks = TaskManager(self) | |||||
self.wiki = SitesDBManager(self.config) | |||||
self.frontend = FakeIRCConnection(self) | |||||
self.watcher = FakeIRCConnection(self) | |||||
self.component_lock = Lock() | |||||
self._keep_looping = True | |||||
class FakeBotConfig(BotConfig): | |||||
def _setup_logging(self): | |||||
logger = logging.getLogger("earwigbot") | |||||
logger.addHandler(logging.NullHandler()) | |||||
class FakeIRCConnection(IRCConnection): | |||||
def __init__(self, bot): | |||||
self.bot = bot | |||||
self._is_running = False | |||||
self._connect() | |||||
def _connect(self): | def _connect(self): | ||||
self._buffer = "" | self._buffer = "" | ||||
def _close(self): | def _close(self): | ||||
pass | |||||
self._buffer = "" | |||||
def _get(self, size=4096): | def _get(self, size=4096): | ||||
data, self._buffer = self._buffer, "" | data, self._buffer = self._buffer, "" | ||||
@@ -23,7 +23,7 @@ | |||||
import unittest | import unittest | ||||
from earwigbot.commands.calc import Command | from earwigbot.commands.calc import Command | ||||
from earwigbot.tests import CommandTestCase | |||||
from tests import CommandTestCase | |||||
class TestCalc(CommandTestCase): | class TestCalc(CommandTestCase): | ||||
@@ -23,7 +23,7 @@ | |||||
import unittest | import unittest | ||||
from earwigbot.commands.test import Command | from earwigbot.commands.test import Command | ||||
from earwigbot.tests import CommandTestCase | |||||
from tests import CommandTestCase | |||||
class TestTest(CommandTestCase): | class TestTest(CommandTestCase): | ||||
@@ -38,12 +38,12 @@ class TestTest(CommandTestCase): | |||||
self.assertTrue(self.command.check(self.make_msg("TEST", "foo"))) | self.assertTrue(self.command.check(self.make_msg("TEST", "foo"))) | ||||
def test_process(self): | def test_process(self): | ||||
def _test(): | |||||
def test(): | |||||
self.command.process(self.make_msg("test")) | self.command.process(self.make_msg("test")) | ||||
self.assertSaidIn(["Hey \x02Foo\x0F!", "'sup \x02Foo\x0F?"]) | self.assertSaidIn(["Hey \x02Foo\x0F!", "'sup \x02Foo\x0F?"]) | ||||
for i in xrange(64): | for i in xrange(64): | ||||
_test() | |||||
test() | |||||
if __name__ == "__main__": | if __name__ == "__main__": | ||||
unittest.main(verbosity=2) | unittest.main(verbosity=2) |