2019-09-11 03:04:05 +02:00
|
|
|
"""
|
2019-09-11 04:19:16 +02:00
|
|
|
Runs IRC parser tests from ircdocs/parser-tests.
|
|
|
|
|
|
|
|
This test suite runs static code only.
|
2019-09-11 03:04:05 +02:00
|
|
|
"""
|
|
|
|
from pathlib import Path
|
2019-09-16 01:26:44 +02:00
|
|
|
import sys
|
2019-09-11 03:04:05 +02:00
|
|
|
import unittest
|
|
|
|
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
PARSER_DATA_PATH = Path(__file__).parent.resolve() / 'parser-tests' / 'tests'
|
|
|
|
print(PARSER_DATA_PATH)
|
|
|
|
|
2019-09-11 03:42:40 +02:00
|
|
|
from pylinkirc import utils
|
2019-09-11 03:04:05 +02:00
|
|
|
from pylinkirc.protocols.ircs2s_common import IRCCommonProtocol
|
|
|
|
|
|
|
|
class MessageParserTest(unittest.TestCase):
|
2019-09-11 03:42:40 +02:00
|
|
|
@classmethod
|
|
|
|
def setUpClass(cls):
|
2019-09-16 01:26:44 +02:00
|
|
|
|
|
|
|
if sys.version_info >= (3, 6):
|
|
|
|
_open = open
|
|
|
|
else:
|
|
|
|
def _open(f): # Coerse pathlib paths to str for py3.5 compat
|
|
|
|
return open(str(f))
|
|
|
|
|
|
|
|
with _open(PARSER_DATA_PATH / 'msg-split.yaml') as f:
|
2019-09-11 03:42:40 +02:00
|
|
|
cls.MESSAGE_SPLIT_TEST_DATA = yaml.safe_load(f)
|
2019-09-16 01:26:44 +02:00
|
|
|
with _open(PARSER_DATA_PATH / 'userhost-split.yaml') as f:
|
2019-09-11 03:42:40 +02:00
|
|
|
cls.USER_HOST_SPLIT_TEST_DATA = yaml.safe_load(f)
|
2019-09-16 01:26:44 +02:00
|
|
|
with _open(PARSER_DATA_PATH / 'mask-match.yaml') as f:
|
2019-09-11 04:19:16 +02:00
|
|
|
cls.MASK_MATCH_TEST_DATA = yaml.safe_load(f)
|
2019-09-16 01:26:44 +02:00
|
|
|
with _open(PARSER_DATA_PATH / 'validate-hostname.yaml') as f:
|
2019-09-11 04:21:56 +02:00
|
|
|
cls.VALIDATE_HOSTNAME_TEST_DATA = yaml.safe_load(f)
|
2019-09-11 03:04:05 +02:00
|
|
|
|
2019-09-11 03:42:40 +02:00
|
|
|
def testMessageSplit(self):
|
|
|
|
for testdata in self.MESSAGE_SPLIT_TEST_DATA['tests']:
|
2019-09-11 03:04:05 +02:00
|
|
|
inp = testdata['input']
|
|
|
|
atoms = testdata['atoms']
|
|
|
|
|
|
|
|
with self.subTest():
|
|
|
|
expected = []
|
|
|
|
has_source = False
|
|
|
|
if 'source' in atoms:
|
|
|
|
has_source = True
|
|
|
|
expected.append(atoms['source'])
|
|
|
|
|
|
|
|
if 'verb' in atoms:
|
|
|
|
expected.append(atoms['verb'])
|
|
|
|
|
|
|
|
if 'params' in atoms:
|
|
|
|
expected.extend(atoms['params'])
|
|
|
|
|
|
|
|
if 'tags' in atoms:
|
2019-09-11 03:42:40 +02:00
|
|
|
# Remove message tags before parsing
|
2019-09-11 03:04:05 +02:00
|
|
|
_, inp = inp.split(" ", 1)
|
2019-09-11 03:42:40 +02:00
|
|
|
|
2019-09-11 03:04:05 +02:00
|
|
|
if has_source:
|
|
|
|
parts = IRCCommonProtocol.parse_prefixed_args(inp)
|
|
|
|
else:
|
|
|
|
parts = IRCCommonProtocol.parse_args(inp)
|
|
|
|
self.assertEqual(expected, parts, "Parse test failed for string: %r" % inp)
|
|
|
|
|
2019-09-11 03:42:40 +02:00
|
|
|
@unittest.skip("Not quite working yet")
|
|
|
|
def testMessageTags(self):
|
|
|
|
for testdata in self.MESSAGE_SPLIT_TEST_DATA['tests']:
|
|
|
|
inp = testdata['input']
|
|
|
|
atoms = testdata['atoms']
|
|
|
|
|
|
|
|
with self.subTest():
|
|
|
|
if 'tags' in atoms:
|
|
|
|
self.assertEqual(atoms['tags'], IRCCommonProtocol.parse_message_tags(inp.split(" ")),
|
|
|
|
"Parse test failed for message tags: %r" % inp)
|
|
|
|
|
2019-09-11 04:12:04 +02:00
|
|
|
def testUserHostSplit(self):
|
|
|
|
for test in self.USER_HOST_SPLIT_TEST_DATA['tests']:
|
|
|
|
inp = test['source']
|
|
|
|
atoms = test['atoms']
|
|
|
|
|
|
|
|
with self.subTest():
|
|
|
|
if 'nick' not in atoms or 'user' not in atoms or 'host' not in atoms:
|
|
|
|
# Trying to parse a hostmask with missing atoms is an error in split_hostmask()
|
|
|
|
with self.assertRaises(ValueError):
|
|
|
|
utils.split_hostmask(inp)
|
|
|
|
else:
|
|
|
|
expected = [atoms['nick'], atoms['user'], atoms['host']]
|
|
|
|
self.assertEqual(expected, utils.split_hostmask(inp))
|
2019-09-11 03:42:40 +02:00
|
|
|
|
2019-09-11 04:19:16 +02:00
|
|
|
def testHostMatch(self):
|
|
|
|
for test in self.MASK_MATCH_TEST_DATA['tests']:
|
|
|
|
mask = test['mask']
|
|
|
|
|
|
|
|
# N.B.: utils.match_text() does Unicode case-insensitive match by default,
|
|
|
|
# which might not be the right thing to do on IRC.
|
|
|
|
# But irc.to_lower() isn't a static function so we're not testing it here...
|
|
|
|
for match in test['matches']:
|
|
|
|
with self.subTest():
|
|
|
|
self.assertTrue(utils.match_text(mask, match))
|
|
|
|
|
|
|
|
for fail in test['fails']:
|
|
|
|
with self.subTest():
|
|
|
|
self.assertFalse(utils.match_text(mask, fail))
|
|
|
|
|
2019-09-11 04:21:56 +02:00
|
|
|
def testValidateHostname(self):
|
|
|
|
for test in self.VALIDATE_HOSTNAME_TEST_DATA['tests']:
|
|
|
|
with self.subTest():
|
|
|
|
self.assertEqual(test['valid'], IRCCommonProtocol.is_server_name(test['host']),
|
|
|
|
"Failed test for %r; should be %s" % (test['host'], test['valid']))
|
|
|
|
|
|
|
|
|
|
|
|
# N.B. skipping msg-join tests because PyLink doesn't think about messages that way
|
|
|
|
|
2019-09-11 03:04:05 +02:00
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|