mirror of
https://github.com/progval/irctest.git
synced 2025-04-06 23:39:46 +00:00
Make assertion messages readable by people who are not me.
This commit is contained in:
@ -32,7 +32,7 @@ class _IrcTestCase(unittest.TestCase):
|
||||
if self.show_io:
|
||||
print('---- new test ----')
|
||||
def assertMessageEqual(self, msg, subcommand=None, subparams=None,
|
||||
target=None, **kwargs):
|
||||
target=None, fail_msg=None, **kwargs):
|
||||
"""Helper for partially comparing a message.
|
||||
|
||||
Takes the message as first arguments, and comparisons to be made
|
||||
@ -41,19 +41,27 @@ class _IrcTestCase(unittest.TestCase):
|
||||
Deals with subcommands (eg. `CAP`) if any of `subcommand`,
|
||||
`subparams`, and `target` are given."""
|
||||
for (key, value) in kwargs.items():
|
||||
#with self.subTest(key=key):
|
||||
self.assertEqual(getattr(msg, key), value, msg)
|
||||
self.assertEqual(getattr(msg, key), value, msg, fail_msg)
|
||||
if subcommand is not None or subparams is not None:
|
||||
self.assertGreater(len(msg.params), 2, msg)
|
||||
self.assertGreater(len(msg.params), 2, fail_msg)
|
||||
msg_target = msg.params[0]
|
||||
msg_subcommand = msg.params[1]
|
||||
msg_subparams = msg.params[2:]
|
||||
if subcommand:
|
||||
with self.subTest(key='subcommand'):
|
||||
self.assertEqual(msg_subcommand, subcommand, msg)
|
||||
self.assertEqual(msg_subcommand, subcommand, msg, fail_msg)
|
||||
if subparams is not None:
|
||||
with self.subTest(key='subparams'):
|
||||
self.assertEqual(msg_subparams, subparams, msg)
|
||||
self.assertEqual(msg_subparams, subparams, msg, fail_msg)
|
||||
|
||||
def assertIn(self, got, expects, msg=None, fail_msg=None):
|
||||
if fail_msg:
|
||||
fail_msg = fail_msg.format(got=got, expects=expects, msg=msg)
|
||||
super().assertIn(got, expects, fail_msg)
|
||||
def assertEqual(self, got, expects, msg=None, fail_msg=None):
|
||||
if fail_msg:
|
||||
fail_msg = fail_msg.format(got=got, expects=expects, msg=msg)
|
||||
super().assertEqual(got, expects, fail_msg)
|
||||
|
||||
class BaseClientTestCase(_IrcTestCase):
|
||||
"""Basic class for client tests. Handles spawning a client and exchanging
|
||||
|
@ -17,7 +17,8 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(1, 'NICK foo')
|
||||
self.sendLine(1, 'CAP END')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='001')
|
||||
self.assertMessageEqual(m, command='001',
|
||||
fail_msg='Expected 001 after sending CAP END, got {msg}.')
|
||||
|
||||
def testReqUnavailable(self):
|
||||
"""Test the server handles gracefully clients which request
|
||||
@ -32,10 +33,13 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(1, 'CAP REQ :foo')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='NAK', subparams=['foo'])
|
||||
subcommand='NAK', subparams=['foo'],
|
||||
fail_msg='Expected CAP NAK after requesting non-existing '
|
||||
'capability, got {msg}.')
|
||||
self.sendLine(1, 'CAP END')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertEqual(m.command, '001')
|
||||
self.assertMessageEqual(m, command='001',
|
||||
fail_msg='Expected 001 after sending CAP END, got {msg}.')
|
||||
|
||||
def testNakExactString(self):
|
||||
"""“The argument of the NAK subcommand MUST consist of at least the
|
||||
@ -48,10 +52,12 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.getCapLs(1)
|
||||
# Five should be enough to check there is no reordering, even
|
||||
# alphabetical
|
||||
self.sendLine(1, 'CAP REQ :foo bar baz qux quux')
|
||||
self.sendLine(1, 'CAP REQ :foo qux bar baz qux quux')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='NAK', subparams=['foo bar baz qux quux'])
|
||||
subcommand='NAK', subparams=['foo qux bar baz qux quux'],
|
||||
fail_msg='Expected “CAP NAK :foo qux bar baz qux quux” after '
|
||||
'sending “CAP REQ :foo qux bar baz qux quux”, but got {msg}.')
|
||||
|
||||
def testNakWhole(self):
|
||||
"""“The capability identifier set must be accepted as a whole, or
|
||||
@ -64,17 +70,25 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(1, 'CAP REQ :foo multi-prefix bar')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='NAK', subparams=['foo multi-prefix bar'])
|
||||
subcommand='NAK', subparams=['foo multi-prefix bar'],
|
||||
fail_msg='Expected “CAP NAK :foo multi-prefix bar” after '
|
||||
'sending “CAP REQ :foo multi-prefix bar”, but got {msg}.')
|
||||
self.sendLine(1, 'CAP REQ :multi-prefix bar')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='NAK', subparams=['multi-prefix bar'])
|
||||
subcommand='NAK', subparams=['multi-prefix bar'],
|
||||
fail_msg='Expected “CAP NAK :foo multi-prefix bar” after '
|
||||
'sending “CAP REQ :foo multi-prefix bar”, but got {msg}.')
|
||||
self.sendLine(1, 'CAP REQ :foo multi-prefix')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='NAK', subparams=['foo multi-prefix'])
|
||||
subcommand='NAK', subparams=['foo multi-prefix'],
|
||||
fail_msg='Expected “CAP NAK :foo multi-prefix bar” after '
|
||||
'sending “CAP REQ :foo multi-prefix bar”, but got {msg}.')
|
||||
# TODO: make sure multi-prefix is not enabled at this point
|
||||
self.sendLine(1, 'CAP REQ :multi-prefix')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='CAP',
|
||||
subcommand='ACK', subparams=['multi-prefix'])
|
||||
subcommand='ACK', subparams=['multi-prefix'],
|
||||
fail_msg='Expected “CAP NAK :foo multi-prefix bar” after '
|
||||
'sending “CAP REQ :foo multi-prefix bar”, but got {msg}.')
|
||||
|
@ -38,17 +38,27 @@ class JoinTestCase(cases.BaseServerTestCase):
|
||||
"( "=" / "*" / "@" ) <channel>
|
||||
:[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )”
|
||||
-- <https://tools.ietf.org/html/rfc2812#section-5.2>
|
||||
|
||||
This test makes a user join and check what is sent to them.
|
||||
"""
|
||||
self.connectClient('foo')
|
||||
self.sendLine(1, 'JOIN #chan')
|
||||
|
||||
for m in self.getMessages(1):
|
||||
if m.command == '353':
|
||||
self.assertIn(len(m.params), (3, 4), m)
|
||||
self.assertIn(len(m.params), (3, 4), m,
|
||||
fail_msg='RPL_NAM_REPLY with number of arguments '
|
||||
'<3 or >4: {msg}')
|
||||
params = ambiguities.normalize_namreply_params(m.params)
|
||||
self.assertIn(params[1], '=*@', m)
|
||||
self.assertEqual(params[2], '#chan', m)
|
||||
self.assertIn(params[3], {'foo', '@foo', '+foo'}, m)
|
||||
self.assertIn(params[1], '=*@', m,
|
||||
fail_msg='Bad channel prefix: {got} not in {expects}: {msg}')
|
||||
self.assertEqual(params[2], '#chan', m,
|
||||
fail_msg='Bad channel name: {got} instead of '
|
||||
'{expects}: {msg}')
|
||||
self.assertIn(params[3], {'foo', '@foo', '+foo'}, m,
|
||||
fail_msg='Bad user list: should contain only user '
|
||||
'"foo" with an optional "+" or "@" prefix, but got: '
|
||||
'{msg}')
|
||||
|
||||
|
||||
def testPartNotInEmptyChannel(self):
|
||||
@ -77,16 +87,24 @@ class JoinTestCase(cases.BaseServerTestCase):
|
||||
self.connectClient('foo')
|
||||
self.sendLine(1, 'PART #chan')
|
||||
m = self.getMessage(1)
|
||||
self.assertIn(m.command, {'442', '403'}) # ERR_NOTONCHANNEL, ERR_NOSUCHCHANNEL
|
||||
self.assertIn(m.command, {'442', '403'}, m, # ERR_NOTONCHANNEL, ERR_NOSUCHCHANNEL
|
||||
fail_msg='Expected ERR_NOTONCHANNEL (442) or '
|
||||
'ERR_NOSUCHCHANNEL (403) after PARTing an empty channel '
|
||||
'one is not on, but got: {msg}')
|
||||
|
||||
def testPartNotInNonEmptyChannel(self):
|
||||
self.connectClient('foo')
|
||||
self.connectClient('bar')
|
||||
self.sendLine(1, 'JOIN #chan')
|
||||
self.getMessages(1) # Synchronize
|
||||
self.sendLine(2, 'PART #chan')
|
||||
self.getMessages(1)
|
||||
m = self.getMessage(2)
|
||||
self.assertMessageEqual(m, command='442') # ERR_NOTONCHANNEL
|
||||
self.assertMessageEqual(m, command='442', # ERR_NOTONCHANNEL
|
||||
fail_msg='Expected ERR_NOTONCHANNEL (442) '
|
||||
'after PARTing a non-empty channel '
|
||||
'one is not on, but got: {msg}')
|
||||
self.assertEqual(self.getMessages(2), [])
|
||||
testPartNotInNonEmptyChannel.__doc__ = testPartNotInEmptyChannel.__doc__
|
||||
|
||||
def testJoinTwice(self):
|
||||
self.connectClient('foo')
|
||||
|
@ -18,14 +18,16 @@ class PasswordedConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(1, 'USER username * * :Realname')
|
||||
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageEqual(m, command='001')
|
||||
self.assertMessageEqual(m, command='001',
|
||||
fail_msg='Did not get 001 after correct PASS+NICK+USER: {msg}')
|
||||
|
||||
def testNoPassword(self):
|
||||
self.addClient()
|
||||
self.sendLine(1, 'NICK foo')
|
||||
self.sendLine(1, 'USER username * * :Realname')
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertNotEqual(m.command, '001')
|
||||
self.assertNotEqual(m.command, '001',
|
||||
msg='Got 001 NICK+USER but missing PASS')
|
||||
|
||||
def testPassAfterNickuser(self):
|
||||
"""“The password can and must be set before any attempt to register
|
||||
@ -43,7 +45,8 @@ class PasswordedConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(1, 'USER username * * :Realname')
|
||||
self.sendLine(1, 'PASS {}'.format(self.password))
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertNotEqual(m.command, '001')
|
||||
self.assertNotEqual(m.command, '001',
|
||||
'Got 001 NICK+USER but incorrect PASS')
|
||||
|
||||
class ConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
def testQuitDisconnects(self):
|
||||
@ -54,7 +57,7 @@ class ConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
self.connectClient('foo')
|
||||
self.getMessages(1)
|
||||
self.sendLine(1, 'QUIT')
|
||||
self.assertRaises(ConnectionClosed, self.getMessages, 1)
|
||||
self.assertRaises(ConnectionClosed, self.getMessages, 1) # Connection was not closed after QUIT.
|
||||
|
||||
def testNickCollision(self):
|
||||
"""A user connects and requests the same nickname as an already
|
||||
@ -65,7 +68,9 @@ class ConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(2, 'NICK foo')
|
||||
self.sendLine(2, 'USER username * * :Realname')
|
||||
m = self.getRegistrationMessage(2)
|
||||
self.assertNotEqual(m.command, '001')
|
||||
self.assertNotEqual(m.command, '001',
|
||||
'Received 001 after registering with the nick of a '
|
||||
'registered user.')
|
||||
|
||||
def testEarlyNickCollision(self):
|
||||
"""Two users register simultaneously with the same nick."""
|
||||
@ -77,4 +82,6 @@ class ConnectionRegistrationTestCase(cases.BaseServerTestCase):
|
||||
self.sendLine(2, 'USER username * * :Realname')
|
||||
m1 = self.getRegistrationMessage(1)
|
||||
m2 = self.getRegistrationMessage(2)
|
||||
self.assertNotEqual((m1.command, m2.command), ('001', '001'))
|
||||
self.assertNotEqual((m1.command, m2.command), ('001', '001'),
|
||||
'Two concurrently registering requesting the same nickname '
|
||||
'both got 001.')
|
||||
|
@ -15,13 +15,19 @@ class SaslTestCase(cases.BaseServerTestCase, cases.OptionalityHelper):
|
||||
self.addClient()
|
||||
self.sendLine(1, 'CAP LS 302')
|
||||
capabilities = self.getCapLs(1)
|
||||
self.assertIn('sasl', capabilities)
|
||||
self.assertIn('sasl', capabilities,
|
||||
fail_msg='Does not have SASL as the controller claims.')
|
||||
if capabilities['sasl'] is not None:
|
||||
self.assertIn('PLAIN', capabilities['sasl'])
|
||||
self.sendLine(1, 'AUTHENTICATE PLAIN')
|
||||
m = self.getMessage(1, filter_pred=lambda m:m.command != 'NOTICE')
|
||||
self.assertMessageEqual(m, command='AUTHENTICATE', params=['+'])
|
||||
self.assertMessageEqual(m, command='AUTHENTICATE', params=['+'],
|
||||
fail_msg='Sent “AUTHENTICATE PLAIN”, server should have '
|
||||
'replied with “AUTHENTICATE +”, but instead sent: {msg}')
|
||||
self.sendLine(1, 'AUTHENTICATE amlsbGVzAGppbGxlcwBzZXNhbWU=')
|
||||
m = self.getMessage(1, filter_pred=lambda m:m.command != 'NOTICE')
|
||||
self.assertMessageEqual(m, command='900')
|
||||
self.assertEqual(m.params[2], 'jilles', m)
|
||||
self.assertMessageEqual(m, command='900',
|
||||
fail_msg='Did not send 900 after correct SASL authentication.')
|
||||
self.assertEqual(m.params[2], 'jilles', m,
|
||||
fail_msg='900 should contain the account name as 3rd argument '
|
||||
'({expected}), not {got}: {msg}')
|
||||
|
Reference in New Issue
Block a user