Add test harness
This commit is contained in:
parent
d55e111767
commit
d9914ca104
|
@ -1,12 +1,9 @@
|
||||||
libs
|
__pycache__
|
||||||
*__pycache__*
|
|
||||||
docs/_build
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
botenv
|
|
||||||
dist
|
/.cache
|
||||||
build
|
/docs/_build
|
||||||
pyircbot.egg-info
|
/testenv
|
||||||
dev
|
/dist
|
||||||
docs/builder/build.sh
|
/build
|
||||||
examples/config.test.json
|
/pyircbot.egg-info
|
||||||
osxenv
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
hello world!
|
|
@ -0,0 +1,40 @@
|
||||||
|
appdirs==1.4.3
|
||||||
|
certifi==2017.4.17
|
||||||
|
chardet==3.0.4
|
||||||
|
cheroot==5.9.1
|
||||||
|
CherryPy==12.0.1
|
||||||
|
decorator==4.0.11
|
||||||
|
idna==2.5
|
||||||
|
ipdb==0.10.3
|
||||||
|
ipython==6.0.0
|
||||||
|
ipython-genutils==0.2.0
|
||||||
|
jaraco.classes==1.4.3
|
||||||
|
jedi==0.10.2
|
||||||
|
mock==2.0.0
|
||||||
|
msgbus==0.0.1
|
||||||
|
packaging==16.8
|
||||||
|
pbr==3.1.1
|
||||||
|
pexpect==4.2.1
|
||||||
|
pickleshare==0.7.4
|
||||||
|
portend==2.2
|
||||||
|
praw==5.0.1
|
||||||
|
prawcore==0.11.0
|
||||||
|
prompt-toolkit==1.0.14
|
||||||
|
ptyprocess==0.5.1
|
||||||
|
py==1.5.2
|
||||||
|
Pygments==2.2.0
|
||||||
|
PyJWT==1.5.3
|
||||||
|
pyparsing==2.2.0
|
||||||
|
PySocks==1.6.7
|
||||||
|
pytest==3.2.5
|
||||||
|
pytz==2017.3
|
||||||
|
pyzmq==16.0.2
|
||||||
|
requests==2.18.1
|
||||||
|
simplegeneric==0.8.1
|
||||||
|
six==1.11.0
|
||||||
|
tempora==1.9
|
||||||
|
traitlets==4.3.2
|
||||||
|
twilio==6.9.0
|
||||||
|
update-checker==0.16
|
||||||
|
urllib3==1.21.1
|
||||||
|
wcwidth==0.1.7
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash -x
|
#!/bin/bash
|
||||||
|
|
||||||
CONFPATH=${1:-examples/config.json}
|
CONFPATH=${1:-examples/config.json}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
export PYTHONPATH=.
|
||||||
|
|
||||||
|
py.test -s tests/
|
|
@ -0,0 +1,41 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import pytest
|
||||||
|
from pyircbot.pyircbot import PrimitiveBot
|
||||||
|
from pyircbot.irccore import IRCEvent, UserPrefix
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), "../pyircbot/modules/"))
|
||||||
|
|
||||||
|
|
||||||
|
class FakeBaseBot(PrimitiveBot):
|
||||||
|
"""
|
||||||
|
Class that simulates a bot base class. You need to add mocks for any methods you expect called, beyond privmsg.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
super().__init__(config)
|
||||||
|
self.act_PRIVMSG = MagicMock()
|
||||||
|
|
||||||
|
def feed_line(self, trailing, cmd="PRIVMSG", args=["#test"], sender=("chatter", "root", "cia.gov")):
|
||||||
|
"""
|
||||||
|
Feed a message into the bot.
|
||||||
|
"""
|
||||||
|
msg = IRCEvent(cmd,
|
||||||
|
args,
|
||||||
|
UserPrefix(*sender),
|
||||||
|
trailing)
|
||||||
|
|
||||||
|
for module_name, module in self.moduleInstances.items():# TODO dedupe this block across the various base classes
|
||||||
|
for hook in module.irchooks:
|
||||||
|
validation = hook.validator(msg, self)
|
||||||
|
if validation:
|
||||||
|
hook.method(msg, validation)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fakebot():
|
||||||
|
bot = FakeBaseBot({"bot": {"datadir": "./examples/data/"},
|
||||||
|
"module_configs": {}})
|
||||||
|
return bot
|
|
@ -0,0 +1,30 @@
|
||||||
|
import pytest
|
||||||
|
from pyircbot.modules.Calc import Calc
|
||||||
|
from pyircbot.pyircbot import ModuleLoader
|
||||||
|
|
||||||
|
|
||||||
|
class FakeBaseBot(ModuleLoader):
|
||||||
|
|
||||||
|
" IRC methods "
|
||||||
|
def act_PRIVMSG(self, towho, message):
|
||||||
|
"""Use the `/msg` command
|
||||||
|
|
||||||
|
:param towho: the target #channel or user's name
|
||||||
|
:type towho: str
|
||||||
|
:param message: the message to send
|
||||||
|
:type message: str"""
|
||||||
|
# self.sendRaw("PRIVMSG %s :%s" % (towho, message))
|
||||||
|
print("act_PRIVMSG(towho={}, message={})".format(towho, message))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fakebot():
|
||||||
|
bot = FakeBaseBot()
|
||||||
|
bot.botconfig = {"bot": {"datadir": "./examples/data/"}}
|
||||||
|
bot.loadmodule("SQLite")
|
||||||
|
bot.loadmodule("Calc")
|
||||||
|
return bot
|
||||||
|
|
||||||
|
|
||||||
|
def test_foo(fakebot):
|
||||||
|
print(fakebot)
|
|
@ -0,0 +1,13 @@
|
||||||
|
import pytest
|
||||||
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def bot(fakebot):
|
||||||
|
fakebot.loadmodule("ASCII")
|
||||||
|
return fakebot
|
||||||
|
|
||||||
|
|
||||||
|
def test_ascii(bot):
|
||||||
|
bot.feed_line(".ascii test")
|
||||||
|
bot.act_PRIVMSG.assert_called_once_with('#test', 'hello world!')
|
|
@ -0,0 +1,81 @@
|
||||||
|
import pytest
|
||||||
|
from contextlib import closing
|
||||||
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def calcbot(fakebot):
|
||||||
|
"""
|
||||||
|
Provide a bot loaded with the Calc module. Clear the database.
|
||||||
|
"""
|
||||||
|
fakebot.botconfig["module_configs"]["Calc"] = {
|
||||||
|
"allowDelete": True,
|
||||||
|
"delaySubmit": 0,
|
||||||
|
"delayCalc": 0,
|
||||||
|
"delayCalcSpecific": 0,
|
||||||
|
"delayMatch": 0}
|
||||||
|
fakebot.loadmodule("SQLite")
|
||||||
|
with closing(fakebot.moduleInstances["SQLite"].opendb("calc.db")) as db:
|
||||||
|
for q in ["DELETE FROM calc_addedby;",
|
||||||
|
"DELETE FROM calc_channels;",
|
||||||
|
"DELETE FROM calc_definitions;",
|
||||||
|
"DELETE FROM calc_words;"]:
|
||||||
|
db.query(q)
|
||||||
|
fakebot.loadmodule("Calc")
|
||||||
|
return fakebot
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_empty(calcbot):
|
||||||
|
calcbot.feed_line("calc")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', 'This channel has no calcs, chatter :(')
|
||||||
|
calcbot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_adds(calcbot):
|
||||||
|
_add_fact(calcbot, "foo", "bar")
|
||||||
|
_add_fact(calcbot, "foo2", "bar2")
|
||||||
|
|
||||||
|
calcbot.feed_line(".quote foo2")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', 'foo2 \x03= bar2 \x0314[added by: chatter]')
|
||||||
|
calcbot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def _add_fact(calcbot, fact, value):
|
||||||
|
calcbot.feed_line("calc {} = {}".format(fact, value))
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', 'Thanks for the info, chatter.')
|
||||||
|
calcbot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_match(calcbot):
|
||||||
|
_add_fact(calcbot, "xxx", "bar")
|
||||||
|
_add_fact(calcbot, "yyy", "bar2")
|
||||||
|
calcbot.feed_line(".match x")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: 1 match (xxx\x03)')
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete(calcbot):
|
||||||
|
_add_fact(calcbot, "xxx", "bar")
|
||||||
|
_add_fact(calcbot, "yyy", "bar2")
|
||||||
|
calcbot.feed_line(".calc xxx =")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', 'Calc deleted, chatter.')
|
||||||
|
calcbot.act_PRIVMSG.reset_mock()
|
||||||
|
calcbot.feed_line(".calc xxx")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', "Sorry chatter, I don't know what 'xxx' is.")
|
||||||
|
|
||||||
|
|
||||||
|
def test_unicode(calcbot):
|
||||||
|
_add_fact(calcbot, "👌👌👌", "uncode keys")
|
||||||
|
_add_fact(calcbot, "uncode values", "👌👌👌")
|
||||||
|
calcbot.feed_line(".calc 👌👌👌")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', '👌👌👌 \x03= uncode keys \x0314[added by: chatter]')
|
||||||
|
calcbot.act_PRIVMSG.reset_mock()
|
||||||
|
calcbot.feed_line(".match 👌")
|
||||||
|
calcbot.act_PRIVMSG.assert_called_once_with('#test', "chatter: 1 match (👌👌👌\x03)")
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_disable(calcbot):
|
||||||
|
calcbot.botconfig["module_configs"]["Calc"]["allowDelete"] = False
|
||||||
|
_add_fact(calcbot, "xxx", "bar")
|
||||||
|
_add_fact(calcbot, "yyy", "bar2")
|
||||||
|
calcbot.feed_line("calc xxx =")
|
||||||
|
calcbot.act_PRIVMSG.assert_not_called()
|
|
@ -0,0 +1,19 @@
|
||||||
|
import pytest
|
||||||
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def bot(fakebot):
|
||||||
|
fakebot.loadmodule("ModInfo")
|
||||||
|
return fakebot
|
||||||
|
|
||||||
|
|
||||||
|
def test_help(bot):
|
||||||
|
bot.feed_line(".help")
|
||||||
|
bot.act_PRIVMSG.assert_called_once_with('#test',
|
||||||
|
'ModInfo: .help [command] show the manual for all or [commands]')
|
||||||
|
|
||||||
|
|
||||||
|
def test_helpindex(bot):
|
||||||
|
bot.feed_line(".helpindex")
|
||||||
|
bot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: commands: .help')
|
|
@ -0,0 +1,74 @@
|
||||||
|
import pytest
|
||||||
|
from contextlib import closing
|
||||||
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# - Responds to pms where the dest != the bot's nick
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def nickbot(fakebot):
|
||||||
|
"""
|
||||||
|
Provide a bot loaded with the Calc module. Clear the database.
|
||||||
|
"""
|
||||||
|
fakebot.botconfig["module_configs"]["Calc"] = {
|
||||||
|
"allowDelete": True,
|
||||||
|
"delaySubmit": 0,
|
||||||
|
"delayCalc": 0,
|
||||||
|
"delayCalcSpecific": 0,
|
||||||
|
"delayMatch": 0}
|
||||||
|
fakebot.loadmodule("SQLite")
|
||||||
|
with closing(fakebot.moduleInstances["SQLite"].opendb("attributes.db")) as db:
|
||||||
|
for q in ["DELETE FROM attribute;",
|
||||||
|
"DELETE FROM items;",
|
||||||
|
"DELETE FROM `values`;"]:
|
||||||
|
db.query(q)
|
||||||
|
fakebot.loadmodule("AttributeStorageLite")
|
||||||
|
fakebot.loadmodule("NickUser")
|
||||||
|
return fakebot
|
||||||
|
|
||||||
|
|
||||||
|
def pm(nickbot, line):
|
||||||
|
nickbot.feed_line(line, args=['bot'])
|
||||||
|
|
||||||
|
|
||||||
|
def test_blind_login(nickbot):
|
||||||
|
pm(nickbot, ".login foobar")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.login: You must first set a password with .setpass')
|
||||||
|
|
||||||
|
|
||||||
|
def test_register(nickbot):
|
||||||
|
pm(nickbot, ".setpass foobar")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.setpass: Your password has been set to "foobar".')
|
||||||
|
nickbot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_register_login(nickbot):
|
||||||
|
test_register(nickbot)
|
||||||
|
pm(nickbot, ".login foobar")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.login: You have been logged in from: cia.gov')
|
||||||
|
nickbot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_badpass(nickbot):
|
||||||
|
test_register(nickbot)
|
||||||
|
pm(nickbot, ".login oopsie")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.login: incorrect password.')
|
||||||
|
|
||||||
|
|
||||||
|
def test_logout(nickbot):
|
||||||
|
test_register_login(nickbot)
|
||||||
|
pm(nickbot, ".logout")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.logout: You have been logged out.')
|
||||||
|
nickbot.act_PRIVMSG.reset_mock()
|
||||||
|
pm(nickbot, ".logout")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.logout: You must first be logged in')
|
||||||
|
|
||||||
|
|
||||||
|
def test_changepass(nickbot):
|
||||||
|
test_register_login(nickbot)
|
||||||
|
pm(nickbot, ".setpass foobar newpass")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.setpass: Your password has been set to "newpass".')
|
||||||
|
nickbot.act_PRIVMSG.reset_mock()
|
||||||
|
pm(nickbot, ".setpass wrong newpass2")
|
||||||
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.setpass: Old password incorrect.')
|
Loading…
Reference in New Issue