mirror of https://github.com/progval/irctest.git
Compare commits
6 Commits
1b1fb61d2f
...
3f11248b8d
Author | SHA1 | Date | |
---|---|---|---|
Val Lorentz | 3f11248b8d | ||
Val Lorentz | f4a01cfe49 | ||
Val Lorentz | e6dfb87759 | ||
Val Lorentz | e9c54b1f8f | ||
Val Lorentz | 2b1369fa46 | ||
Val Lorentz | 45c2561764 |
|
@ -1106,7 +1106,7 @@ jobs:
|
|||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: sable
|
||||
ref: dcf8b53cac54f460b86861908d36d67969cf1eb2
|
||||
ref: fe337a036c3ab5f8548e2578b65568e628f4c32f
|
||||
repository: Libera-Chat/sable
|
||||
- name: Install rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
|
|
|
@ -160,6 +160,7 @@ class _IrcTestCase(Generic[TController]):
|
|||
def messageDiffers(
|
||||
self,
|
||||
msg: Message,
|
||||
command: Union[str, None, patma.Operator] = None,
|
||||
params: Optional[List[Union[str, None, patma.Operator]]] = None,
|
||||
target: Optional[str] = None,
|
||||
tags: Optional[
|
||||
|
@ -186,6 +187,14 @@ class _IrcTestCase(Generic[TController]):
|
|||
msg=msg,
|
||||
)
|
||||
|
||||
if command is not None and not patma.match_string(msg.command, command):
|
||||
fail_msg = (
|
||||
fail_msg or "expected command to match {expects}, got {got}: {msg}"
|
||||
)
|
||||
return fail_msg.format(
|
||||
*extra_format, got=msg.command, expects=command, msg=msg
|
||||
)
|
||||
|
||||
if prefix is not None and not patma.match_string(msg.prefix, prefix):
|
||||
fail_msg = (
|
||||
fail_msg or "expected prefix to match {expects}, got {got}: {msg}"
|
||||
|
@ -214,7 +223,7 @@ class _IrcTestCase(Generic[TController]):
|
|||
or "expected nick to be {expects}, got {got} instead: {msg}"
|
||||
)
|
||||
return fail_msg.format(
|
||||
*extra_format, got=got_nick, expects=nick, param=key, msg=msg
|
||||
*extra_format, got=got_nick, expects=nick, msg=msg
|
||||
)
|
||||
|
||||
return None
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
"""
|
||||
Handles ambiguities of RFCs.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
def normalize_namreply_params(params: List[str]) -> List[str]:
|
||||
# So… RFC 2812 says:
|
||||
# "( "=" / "*" / "@" ) <channel>
|
||||
# :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
|
||||
# but spaces seem to be missing (eg. before the colon), so we
|
||||
# don't know if there should be one before the <channel> and its
|
||||
# prefix.
|
||||
# So let's normalize this to “with space”, and strip spaces at the
|
||||
# end of the nick list.
|
||||
params = list(params) # copy the list
|
||||
if len(params) == 3:
|
||||
assert params[1][0] in "=*@", params
|
||||
params.insert(1, params[1][0])
|
||||
params[2] = params[2][1:]
|
||||
params[3] = params[3].rstrip()
|
||||
return params
|
|
@ -173,7 +173,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
|||
],
|
||||
# and they each error with:
|
||||
[
|
||||
"expected command to be PRIVMSG, got PRIVMG",
|
||||
"expected command to match PRIVMSG, got PRIVMG",
|
||||
"expected tags to match {'tag1': 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
||||
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
||||
|
@ -206,7 +206,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
|||
],
|
||||
# and they each error with:
|
||||
[
|
||||
"expected command to be PRIVMSG, got PRIVMG",
|
||||
"expected command to match PRIVMSG, got PRIVMG",
|
||||
"expected tags to match {StrRe(r'tag[12]'): 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
||||
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
||||
|
@ -235,7 +235,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
|||
],
|
||||
# and they each error with:
|
||||
[
|
||||
"expected command to be PRIVMSG, got PRIVMG",
|
||||
"expected command to match PRIVMSG, got PRIVMG",
|
||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': ''}",
|
||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': 'baz'}",
|
||||
|
@ -345,7 +345,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
|||
],
|
||||
# and they each error with:
|
||||
[
|
||||
"expected command to be PING, got PONG"
|
||||
"expected command to match PING, got PONG"
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -56,10 +56,6 @@ class CapTestCase(cases.BaseServerTestCase):
|
|||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["Sable"],
|
||||
"does not support multi-prefix",
|
||||
)
|
||||
def testReqOne(self):
|
||||
"""Tests requesting a single capability"""
|
||||
self.addClient(1)
|
||||
|
@ -93,7 +89,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
|||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd", "Sable"],
|
||||
["ngIRCd"],
|
||||
"does not support userhost-in-names",
|
||||
)
|
||||
def testReqTwo(self):
|
||||
|
@ -135,7 +131,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
|||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd", "Sable"],
|
||||
["ngIRCd"],
|
||||
"does not support userhost-in-names",
|
||||
)
|
||||
def testReqOneThenOne(self):
|
||||
|
@ -187,7 +183,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
|||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd", "Sable"],
|
||||
["ngIRCd"],
|
||||
"does not support userhost-in-names",
|
||||
)
|
||||
def testReqPostRegistration(self):
|
||||
|
|
|
@ -6,7 +6,6 @@ The JOIN command (`RFC 1459
|
|||
"""
|
||||
|
||||
from irctest import cases, runner
|
||||
from irctest.irc_utils import ambiguities
|
||||
from irctest.numerics import (
|
||||
ERR_BADCHANMASK,
|
||||
ERR_FORBIDDENCHANNEL,
|
||||
|
@ -75,33 +74,23 @@ class JoinTestCase(cases.BaseServerTestCase):
|
|||
|
||||
for m in self.getMessages(1):
|
||||
if m.command == "353":
|
||||
self.assertIn(
|
||||
len(m.params),
|
||||
(3, 4),
|
||||
m,
|
||||
fail_msg="RPL_NAM_REPLY with number of arguments "
|
||||
"<3 or >4: {msg}",
|
||||
self.assertMessageMatch(
|
||||
m, params=["foo", StrRe(r"[=\*@]"), "#chan", StrRe("[@+]?foo")]
|
||||
)
|
||||
params = ambiguities.normalize_namreply_params(m.params)
|
||||
self.assertIn(
|
||||
params[1],
|
||||
"=*@",
|
||||
|
||||
self.connectClient("bar")
|
||||
self.sendLine(2, "JOIN #chan")
|
||||
|
||||
for m in self.getMessages(2):
|
||||
if m.command == "353":
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
fail_msg="Bad channel prefix: {item} not in {list}: {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}",
|
||||
params=[
|
||||
"bar",
|
||||
StrRe(r"[=\*@]"),
|
||||
"#chan",
|
||||
StrRe("([@+]?foo bar|bar [@+]?foo)"),
|
||||
],
|
||||
)
|
||||
|
||||
def testJoinTwice(self):
|
||||
|
@ -115,34 +104,8 @@ class JoinTestCase(cases.BaseServerTestCase):
|
|||
# if the join is successful, or has an error among the given set.
|
||||
for m in self.getMessages(1):
|
||||
if m.command == "353":
|
||||
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,
|
||||
fail_msg="Bad channel prefix: {item} not in {list}: {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 after user "foo" joined twice '
|
||||
"the same channel: should contain only user "
|
||||
'"foo" with an optional "+" or "@" prefix, but got: '
|
||||
"{msg}",
|
||||
self.assertMessageMatch(
|
||||
m, params=["foo", StrRe(r"[=\*@]"), "#chan", StrRe("[@+]?foo")]
|
||||
)
|
||||
|
||||
def testJoinPartiallyInvalid(self):
|
||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
|||
from irctest import cases, runner
|
||||
from irctest.client_mock import NoMessageException
|
||||
from irctest.numerics import (
|
||||
ERR_ERRONEUSNICKNAME,
|
||||
RPL_ENDOFMONLIST,
|
||||
RPL_MONLIST,
|
||||
RPL_MONOFFLINE,
|
||||
|
@ -190,14 +191,15 @@ class MonitorTestCase(_BaseMonitorTestCase):
|
|||
self.check_server_support()
|
||||
self.sendLine(1, "MONITOR + *!username@localhost")
|
||||
self.sendLine(1, "MONITOR + *!username@127.0.0.1")
|
||||
expected_command = StrRe(f"({RPL_MONOFFLINE}|{ERR_ERRONEUSNICKNAME})")
|
||||
try:
|
||||
m = self.getMessage(1)
|
||||
self.assertMessageMatch(m, command="731")
|
||||
self.assertMessageMatch(m, command=expected_command)
|
||||
except NoMessageException:
|
||||
pass
|
||||
else:
|
||||
m = self.getMessage(1)
|
||||
self.assertMessageMatch(m, command="731")
|
||||
self.assertMessageMatch(m, command=expected_command)
|
||||
self.connectClient("bar")
|
||||
try:
|
||||
m = self.getMessage(1)
|
||||
|
|
|
@ -24,11 +24,6 @@ class MultiPrefixTestCase(cases.BaseServerTestCase):
|
|||
|
||||
self.sendLine(1, "NAMES #chan")
|
||||
reply = self.getMessage(1)
|
||||
self.assertMessageMatch(
|
||||
reply,
|
||||
command="353",
|
||||
fail_msg="Expected NAMES response (353) with @+foo, got: {msg}",
|
||||
)
|
||||
self.assertMessageMatch(
|
||||
reply,
|
||||
command="353",
|
||||
|
@ -47,9 +42,57 @@ class MultiPrefixTestCase(cases.BaseServerTestCase):
|
|||
8,
|
||||
"Expected WHO response (352) with 8 params, got: {msg}".format(msg=msg),
|
||||
)
|
||||
self.assertTrue(
|
||||
"@+" in msg.params[6],
|
||||
self.assertIn(
|
||||
"@+",
|
||||
msg.params[6],
|
||||
'Expected WHO response (352) with "@+" in param 7, got: {msg}'.format(
|
||||
msg=msg
|
||||
),
|
||||
)
|
||||
|
||||
@cases.xfailIfSoftware(
|
||||
["irc2", "Bahamut"], "irc2 and Bahamut send a trailing space"
|
||||
)
|
||||
def testNoMultiPrefix(self):
|
||||
"""When not requested, only the highest prefix should be sent"""
|
||||
self.connectClient("foo")
|
||||
self.joinChannel(1, "#chan")
|
||||
self.sendLine(1, "MODE #chan +v foo")
|
||||
self.getMessages(1)
|
||||
|
||||
# TODO(dan): Make sure +v is voice
|
||||
|
||||
self.sendLine(1, "NAMES #chan")
|
||||
reply = self.getMessage(1)
|
||||
self.assertMessageMatch(
|
||||
reply,
|
||||
command="353",
|
||||
params=["foo", ANYSTR, "#chan", "@foo"],
|
||||
fail_msg="Expected NAMES response (353) with @foo, got: {msg}",
|
||||
)
|
||||
self.getMessages(1)
|
||||
|
||||
self.sendLine(1, "WHO #chan")
|
||||
msg = self.getMessage(1)
|
||||
self.assertEqual(
|
||||
msg.command, "352", msg, fail_msg="Expected WHO response (352), got: {msg}"
|
||||
)
|
||||
self.assertGreaterEqual(
|
||||
len(msg.params),
|
||||
8,
|
||||
"Expected WHO response (352) with 8 params, got: {msg}".format(msg=msg),
|
||||
)
|
||||
self.assertIn(
|
||||
"@",
|
||||
msg.params[6],
|
||||
'Expected WHO response (352) with "@" in param 7, got: {msg}'.format(
|
||||
msg=msg
|
||||
),
|
||||
)
|
||||
self.assertNotIn(
|
||||
"+",
|
||||
msg.params[6],
|
||||
'Expected WHO response (352) with no "+" in param 7, got: {msg}'.format(
|
||||
msg=msg
|
||||
),
|
||||
)
|
||||
|
|
|
@ -249,7 +249,7 @@ software:
|
|||
name: Sable
|
||||
repository: Libera-Chat/sable
|
||||
refs:
|
||||
stable: dcf8b53cac54f460b86861908d36d67969cf1eb2
|
||||
stable: fe337a036c3ab5f8548e2578b65568e628f4c32f
|
||||
release: null
|
||||
devel: master
|
||||
devel_release: null
|
||||
|
|
Loading…
Reference in New Issue