Merge pull request #154 from progval/docstrings

Toplevel docstring maintainance + show them on dashboard
This commit is contained in:
Val Lorentz 2022-04-10 16:22:57 +02:00 committed by GitHub
commit 0d64e5c1e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 371 additions and 115 deletions

View File

@ -401,7 +401,7 @@ jobs:
- name: Install dashboard dependencies - name: Install dashboard dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install defusedxml pip install defusedxml docutils -r requirements.txt
- name: Generate dashboard - name: Generate dashboard
run: |- run: |-
shopt -s globstar shopt -s globstar

View File

@ -86,7 +86,7 @@ jobs:
- name: Install dashboard dependencies - name: Install dashboard dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install defusedxml pip install defusedxml docutils -r requirements.txt
- name: Generate dashboard - name: Generate dashboard
run: |- run: |-
shopt -s globstar shopt -s globstar

View File

@ -444,7 +444,7 @@ jobs:
- name: Install dashboard dependencies - name: Install dashboard dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install defusedxml pip install defusedxml docutils -r requirements.txt
- name: Generate dashboard - name: Generate dashboard
run: |- run: |-
shopt -s globstar shopt -s globstar

View File

@ -1,3 +1,5 @@
"""Format of ``CAP LS`` sent by IRCv3 clients."""
from irctest import cases from irctest import cases
from irctest.irc_utils.message_parser import Message from irctest.irc_utils.message_parser import Message

View File

@ -1,3 +1,8 @@
"""SASL authentication from clients, for all known mechanisms.
For now, only `SASLv3.1 <https://ircv3.net/specs/extensions/sasl-3.1>`_
is tested, not `SASLv3.2 <https://ircv3.net/specs/extensions/sasl-3.2>`_."""
import base64 import base64
import pytest import pytest

View File

@ -1,3 +1,5 @@
"""Clients should validate certificates; either with a CA or fingerprints."""
import socket import socket
import ssl import ssl

View File

@ -2,6 +2,7 @@ import base64
import dataclasses import dataclasses
import gzip import gzip
import hashlib import hashlib
import importlib
from pathlib import Path from pathlib import Path
import re import re
import sys import sys
@ -16,10 +17,10 @@ from typing import (
Tuple, Tuple,
TypeVar, TypeVar,
) )
import xml.dom.minidom
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from defusedxml.ElementTree import parse as parse_xml from defusedxml.ElementTree import parse as parse_xml
import docutils.core
NETLIFY_CHAR_BLACKLIST = frozenset('":<>|*?\r\n#') NETLIFY_CHAR_BLACKLIST = frozenset('":<>|*?\r\n#')
"""Characters not allowed in output filenames""" """Characters not allowed in output filenames"""
@ -117,9 +118,24 @@ def iter_job_results(job_file_name: Path, job: ET.ElementTree) -> Iterator[CaseR
) )
def rst_to_element(s: str) -> ET.Element:
html = docutils.core.publish_parts(s, writer_name="xhtml")["html_body"]
htmltree = ET.fromstring(html)
return htmltree
def append_docstring(element: ET.Element, obj: object) -> None:
if obj.__doc__ is None:
return
element.append(rst_to_element(obj.__doc__))
def build_module_html( def build_module_html(
jobs: List[str], results: List[CaseResult], module_name: str jobs: List[str], results: List[CaseResult], module_name: str
) -> ET.Element: ) -> ET.Element:
module = importlib.import_module(module_name)
root = ET.Element("html") root = ET.Element("html")
head = ET.SubElement(root, "head") head = ET.SubElement(root, "head")
ET.SubElement(head, "title").text = module_name ET.SubElement(head, "title").text = module_name
@ -129,6 +145,8 @@ def build_module_html(
ET.SubElement(body, "h1").text = module_name ET.SubElement(body, "h1").text = module_name
append_docstring(body, module)
results_by_class = group_by(results, lambda r: r.class_name) results_by_class = group_by(results, lambda r: r.class_name)
table = ET.SubElement(body, "table") table = ET.SubElement(body, "table")
@ -153,6 +171,7 @@ def build_module_html(
id=row_anchor, id=row_anchor,
) )
section_header.text = class_name section_header.text = class_name
append_docstring(th, getattr(module, class_name))
# Header row: one column for each implementation # Header row: one column for each implementation
table.append(job_row) table.append(job_row)
@ -213,10 +232,6 @@ def build_module_html(
else: else:
cell.text = text or "?" cell.text = text or "?"
# Hacky: ET expects the namespace to be present in every tag we create instead;
# but it would be excessively verbose.
root.set("xmlns", "http://www.w3.org/1999/xhtml")
return root return root
@ -261,13 +276,15 @@ def write_html_index(output_dir: Path, pages: List[Tuple[str, str]]) -> None:
ET.SubElement(body, "h1").text = "irctest dashboard" ET.SubElement(body, "h1").text = "irctest dashboard"
ul = ET.SubElement(body, "ul") dl = ET.SubElement(body, "dl")
dl.set("class", "module-index")
for (module_name, file_name) in sorted(pages): for (module_name, file_name) in sorted(pages):
link = ET.SubElement(ET.SubElement(ul, "li"), "a", href=f"./{file_name}") module = importlib.import_module(module_name)
link.text = module_name
root.set("xmlns", "http://www.w3.org/1999/xhtml") link = ET.SubElement(ET.SubElement(dl, "dt"), "a", href=f"./{file_name}")
link.text = module_name
append_docstring(ET.SubElement(dl, "dd"), module)
write_xml_file(output_dir / "index.xhtml", root) write_xml_file(output_dir / "index.xhtml", root)
@ -281,14 +298,15 @@ def write_assets(output_dir: Path) -> None:
def write_xml_file(filename: Path, root: ET.Element) -> None: def write_xml_file(filename: Path, root: ET.Element) -> None:
# Hacky: ET expects the namespace to be present in every tag we create instead;
# but it would be excessively verbose.
root.set("xmlns", "http://www.w3.org/1999/xhtml")
# Serialize # Serialize
s = ET.tostring(root) s = ET.tostring(root)
# Prettify with filename.open("wb") as fd:
s = xml.dom.minidom.parseString(s).toprettyxml(indent=" ") fd.write(s)
with filename.open("wt") as fd:
fd.write(s) # type: ignore
def parse_xml_file(filename: Path) -> ET.ElementTree: def parse_xml_file(filename: Path) -> ET.ElementTree:

View File

@ -8,6 +8,10 @@
} }
} }
dl.module-index {
column-width: 40em; /* Magic constant for 2 columns on average laptop/desktop */
}
/* Only 1px solid border between cells */ /* Only 1px solid border between cells */
table.test-matrix { table.test-matrix {
border-spacing: 0; border-spacing: 0;

View File

@ -1,3 +1,5 @@
"""Internal checks of assertion implementations."""
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
import pytest import pytest

View File

@ -1,3 +1,8 @@
"""
`Draft IRCv3 account-registration
<https://ircv3.net/specs/extensions/account-registration>`_
"""
from irctest import cases from irctest import cases
from irctest.patma import ANYSTR from irctest.patma import ANYSTR

View File

@ -1,5 +1,5 @@
""" """
<http://ircv3.net/specs/extensions/account-tag-3.2.html> `IRCv3 account-tag <https://ircv3.net/specs/extensions/account-tag>`_
""" """
from irctest import cases from irctest import cases

View File

@ -1,3 +1,8 @@
"""
AWAY command (`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-4.1>`__,
`Modern <https://modern.ircdocs.horse/#away-message>`__)
"""
from irctest import cases from irctest import cases
from irctest.numerics import RPL_AWAY, RPL_NOWAWAY, RPL_UNAWAY, RPL_USERHOST from irctest.numerics import RPL_AWAY, RPL_NOWAWAY, RPL_UNAWAY, RPL_USERHOST
from irctest.patma import StrRe from irctest.patma import StrRe
@ -32,7 +37,7 @@ class AwayTestCase(cases.BaseServerTestCase):
""" """
"The server acknowledges the change in away status by returning the "The server acknowledges the change in away status by returning the
`RPL_NOWAWAY` and `RPL_UNAWAY` numerics." `RPL_NOWAWAY` and `RPL_UNAWAY` numerics."
-- https://github.com/ircdocs/modern-irc/pull/100 -- https://modern.ircdocs.horse/#away-message
""" """
self.connectClient("bar") self.connectClient("bar")
self.sendLine(1, "AWAY :I'm not here right now") self.sendLine(1, "AWAY :I'm not here right now")
@ -48,7 +53,7 @@ class AwayTestCase(cases.BaseServerTestCase):
""" """
"Servers SHOULD notify clients when a user they're interacting with "Servers SHOULD notify clients when a user they're interacting with
is away when relevant" is away when relevant"
-- https://github.com/ircdocs/modern-irc/pull/100 -- https://modern.ircdocs.horse/#away-message
"<client> <nick> :<message>" "<client> <nick> :<message>"
-- https://modern.ircdocs.horse/#rplaway-301 -- https://modern.ircdocs.horse/#rplaway-301
@ -75,7 +80,7 @@ class AwayTestCase(cases.BaseServerTestCase):
""" """
"Servers SHOULD notify clients when a user they're interacting with "Servers SHOULD notify clients when a user they're interacting with
is away when relevant" is away when relevant"
-- https://github.com/ircdocs/modern-irc/pull/100 -- https://modern.ircdocs.horse/#away-message
"<client> <nick> :<message>" "<client> <nick> :<message>"
-- https://modern.ircdocs.horse/#rplaway-301 -- https://modern.ircdocs.horse/#rplaway-301
@ -113,7 +118,7 @@ class AwayTestCase(cases.BaseServerTestCase):
""" """
"Servers SHOULD notify clients when a user they're interacting with "Servers SHOULD notify clients when a user they're interacting with
is away when relevant" is away when relevant"
-- https://github.com/ircdocs/modern-irc/pull/100 -- https://modern.ircdocs.horse/#away-message
"<client> <nick> :<message>" "<client> <nick> :<message>"
-- https://modern.ircdocs.horse/#rplaway-301 -- https://modern.ircdocs.horse/#rplaway-301

View File

@ -1,5 +1,5 @@
""" """
<https://ircv3.net/specs/extensions/away-notify-3.1> `IRCv3 away-notify <https://ircv3.net/specs/extensions/away-notify>`_
""" """
from irctest import cases from irctest import cases

View File

@ -1,6 +1,5 @@
""" """
Draft bot mode specification, as defined in `IRCv3 draft bot mode <https://ircv3.net/specs/extensions/bot-mode>`_
<https://ircv3.net/specs/extensions/bot-mode>
""" """
from irctest import cases, runner from irctest import cases, runner

View File

@ -1,3 +1,9 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of
`multiclient features
<https://github.com/ergochat/ergo/blob/master/docs/MANUAL.md#multiclient-bouncer>`_
"""
from irctest import cases from irctest import cases
from irctest.irc_utils.sasl import sasl_plain_blob from irctest.irc_utils.sasl import sasl_plain_blob
from irctest.numerics import ERR_NICKNAMEINUSE, RPL_WELCOME from irctest.numerics import ERR_NICKNAMEINUSE, RPL_WELCOME

View File

@ -1,5 +1,7 @@
"""Sends packets with various length to check the server reassembles them """
correctly. Also checks truncation""" Sends packets with various length to check the server reassembles them
correctly. Also checks truncation.
"""
import socket import socket
import time import time

View File

@ -1,3 +1,8 @@
"""
`IRCv3 Capability negotiation
<https://ircv3.net/specs/extensions/capability-negotiation>`_
"""
from irctest import cases from irctest import cases
from irctest.patma import ANYSTR from irctest.patma import ANYSTR
from irctest.runner import CapabilityNotSupported, ImplementationChoice from irctest.runner import CapabilityNotSupported, ImplementationChoice
@ -172,3 +177,60 @@ class CapTestCase(cases.BaseServerTestCase, cases.OptionalityHelper):
enabled_caps.discard("cap-notify") # implicitly added by some impls enabled_caps.discard("cap-notify") # implicitly added by some impls
self.assertEqual(enabled_caps, {cap1}) self.assertEqual(enabled_caps, {cap1})
self.assertNotIn("time", cap_list.tags) self.assertNotIn("time", cap_list.tags)
@cases.mark_specifications("IRCv3")
def testIrc301CapLs(self):
"""
Current version:
"The LS subcommand is used to list the capabilities supported by the server.
The client should send an LS subcommand with no other arguments to solicit
a list of all capabilities."
"If a client has not indicated support for CAP LS 302 features,
the server MUST NOT send these new features to the client."
-- <https://ircv3.net/specs/core/capability-negotiation.html>
Before the v3.1 / v3.2 merge:
IRCv3.1: The LS subcommand is used to list the capabilities
supported by the server. The client should send an LS subcommand with
no other arguments to solicit a list of all capabilities.
-- <http://ircv3.net/specs/core/capability-negotiation-3.1.html#the-cap-ls-subcommand>
IRCv3.2: Servers MUST NOT send messages described by this document if
the client only supports version 3.1.
-- <http://ircv3.net/specs/core/capability-negotiation-3.2.html#version-in-cap-ls>
""" # noqa
self.addClient()
self.sendLine(1, "CAP LS")
m = self.getRegistrationMessage(1)
self.assertNotEqual(
m.params[2],
"*",
m,
fail_msg="Server replied with multi-line CAP LS to a "
"“CAP LS” (ie. IRCv3.1) request: {msg}",
)
self.assertFalse(
any("=" in cap for cap in m.params[2].split()),
"Server replied with a name-value capability in "
"CAP LS reply as a response to “CAP LS” (ie. IRCv3.1) "
"request: {}".format(m),
)
@cases.mark_specifications("IRCv3")
def testEmptyCapList(self):
"""“If no capabilities are active, an empty parameter must be sent.”
-- <http://ircv3.net/specs/core/capability-negotiation-3.1.html#the-cap-list-subcommand>
""" # noqa
self.addClient()
self.sendLine(1, "CAP LIST")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="CAP",
params=["*", "LIST", ""],
fail_msg="Sending “CAP LIST” as first message got a reply "
"that is not “CAP * LIST :”: {msg}",
)

View File

@ -1,3 +1,7 @@
"""
Channel casemapping
"""
import pytest import pytest
from irctest import cases, client_mock, runner from irctest import cases, client_mock, runner

View File

@ -1,3 +1,9 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of channel forwarding
TODO: Should be extended to other servers, once a specification is written.
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_CHANOPRIVSNEEDED, ERR_INVALIDMODEPARAM, ERR_LINKCHANNEL from irctest.numerics import ERR_CHANOPRIVSNEEDED, ERR_INVALIDMODEPARAM, ERR_LINKCHANNEL

View File

@ -1,24 +1,22 @@
"""
`Draft IRCv3 channel-rename <https://ircv3.net/specs/extensions/channel-rename>`_
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_CHANOPRIVSNEEDED from irctest.numerics import ERR_CHANOPRIVSNEEDED
MODERN_CAPS = [
"server-time",
"message-tags",
"batch",
"labeled-response",
"echo-message",
"account-tag",
]
RENAME_CAP = "draft/channel-rename" RENAME_CAP = "draft/channel-rename"
@cases.mark_specifications("IRCv3")
class ChannelRenameTestCase(cases.BaseServerTestCase): class ChannelRenameTestCase(cases.BaseServerTestCase):
"""Basic tests for channel-rename.""" """Basic tests for channel-rename."""
@cases.mark_specifications("Ergo")
def testChannelRename(self): def testChannelRename(self):
self.connectClient("bar", name="bar", capabilities=MODERN_CAPS + [RENAME_CAP]) self.connectClient(
self.connectClient("baz", name="baz", capabilities=MODERN_CAPS) "bar", name="bar", capabilities=[RENAME_CAP], skip_if_cap_nak=True
)
self.connectClient("baz", name="baz")
self.joinChannel("bar", "#bar") self.joinChannel("bar", "#bar")
self.joinChannel("baz", "#bar") self.joinChannel("baz", "#bar")
self.getMessages("bar") self.getMessages("bar")

View File

@ -1,3 +1,7 @@
"""
`IRCv3 draft chathistory <https://ircv3.net/specs/extensions/chathistory>`_
"""
import secrets import secrets
import time import time

View File

@ -1,3 +1,9 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of auditorium mode
TODO: Should be extended to other servers, once a specification is written.
"""
import math import math
import time import time

View File

@ -1,3 +1,10 @@
"""
Channel ban (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.3.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.3>`__,
`Modern <https://modern.ircdocs.horse/#ban-channel-mode>`__)
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_BANNEDFROMCHAN, RPL_BANLIST, RPL_ENDOFBANLIST from irctest.numerics import ERR_BANNEDFROMCHAN, RPL_BANLIST, RPL_ENDOFBANLIST
from irctest.patma import ANYSTR, StrRe from irctest.patma import ANYSTR, StrRe
@ -26,7 +33,7 @@ class BanModeTestCase(cases.BaseServerTestCase):
@cases.mark_specifications("Modern") @cases.mark_specifications("Modern")
def testBanList(self): def testBanList(self):
"""https://github.com/ircdocs/modern-irc/pull/125""" """`RPL_BANLIST <https://modern.ircdocs.horse/#rplbanlist-367>`"""
self.connectClient("chanop") self.connectClient("chanop")
self.joinChannel(1, "#chan") self.joinChannel(1, "#chan")
self.getMessages(1) self.getMessages(1)

View File

@ -1,3 +1,7 @@
"""
Various Ergo-specific channel modes
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_CANNOTSENDTOCHAN, ERR_CHANOPRIVSNEEDED from irctest.numerics import ERR_CANNOTSENDTOCHAN, ERR_CHANOPRIVSNEEDED

View File

@ -1,3 +1,10 @@
"""
Channel key (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.3.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.3>`__,
`Modern <https://modern.ircdocs.horse/#key-channel-mode>`__)
"""
import pytest import pytest
from irctest import cases from irctest import cases

View File

@ -1,3 +1,9 @@
"""
Channel moderation mode (`RFC 2812
<https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.3>`__,
`Modern <https://modern.ircdocs.horse/#ban-channel-mode>`__)
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_CANNOTSENDTOCHAN from irctest.numerics import ERR_CANNOTSENDTOCHAN

View File

@ -1,3 +1,7 @@
"""
Mute extban, currently no specifications or ways to discover it.
"""
from irctest import cases, runner from irctest import cases, runner
from irctest.numerics import ERR_CANNOTSENDTOCHAN, ERR_CHANOPRIVSNEEDED from irctest.numerics import ERR_CANNOTSENDTOCHAN, ERR_CHANOPRIVSNEEDED
from irctest.patma import ANYLIST, StrRe from irctest.patma import ANYLIST, StrRe

View File

@ -1,3 +1,10 @@
"""
Channel secrecy mode (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.3.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.3>`__,
`Modern <https://modern.ircdocs.horse/#secret-channel-mode>`__)
"""
from irctest import cases from irctest import cases
from irctest.numerics import RPL_LIST from irctest.numerics import RPL_LIST

View File

@ -1,3 +1,8 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests for nick collisions based on Unicode
confusable characters
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_NICKNAMEINUSE, RPL_WELCOME from irctest.numerics import ERR_NICKNAMEINUSE, RPL_WELCOME

View File

@ -1,6 +1,8 @@
""" """
Tests section 4.1 of RFC 1459. Tests section 4.1 of RFC 1459.
<https://tools.ietf.org/html/rfc1459#section-4.1> <https://tools.ietf.org/html/rfc1459#section-4.1>
TODO: cross-reference Modern and RFC 2812 too
""" """
from irctest import cases from irctest import cases
@ -183,60 +185,3 @@ class ConnectionRegistrationTestCase(cases.BaseServerTestCase):
command=ERR_NEEDMOREPARAMS, command=ERR_NEEDMOREPARAMS,
params=[StrRe(r"(\*|foo)"), "USER", ANYSTR], params=[StrRe(r"(\*|foo)"), "USER", ANYSTR],
) )
@cases.mark_specifications("IRCv3")
def testIrc301CapLs(self):
"""
Current version:
"The LS subcommand is used to list the capabilities supported by the server.
The client should send an LS subcommand with no other arguments to solicit
a list of all capabilities."
"If a client has not indicated support for CAP LS 302 features,
the server MUST NOT send these new features to the client."
-- <https://ircv3.net/specs/core/capability-negotiation.html>
Before the v3.1 / v3.2 merge:
IRCv3.1: The LS subcommand is used to list the capabilities
supported by the server. The client should send an LS subcommand with
no other arguments to solicit a list of all capabilities.
-- <http://ircv3.net/specs/core/capability-negotiation-3.1.html#the-cap-ls-subcommand>
IRCv3.2: Servers MUST NOT send messages described by this document if
the client only supports version 3.1.
-- <http://ircv3.net/specs/core/capability-negotiation-3.2.html#version-in-cap-ls>
""" # noqa
self.addClient()
self.sendLine(1, "CAP LS")
m = self.getRegistrationMessage(1)
self.assertNotEqual(
m.params[2],
"*",
m,
fail_msg="Server replied with multi-line CAP LS to a "
"“CAP LS” (ie. IRCv3.1) request: {msg}",
)
self.assertFalse(
any("=" in cap for cap in m.params[2].split()),
"Server replied with a name-value capability in "
"CAP LS reply as a response to “CAP LS” (ie. IRCv3.1) "
"request: {}".format(m),
)
@cases.mark_specifications("IRCv3")
def testEmptyCapList(self):
"""“If no capabilities are active, an empty parameter must be sent.”
-- <http://ircv3.net/specs/core/capability-negotiation-3.1.html#the-cap-list-subcommand>
""" # noqa
self.addClient()
self.sendLine(1, "CAP LIST")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="CAP",
params=["*", "LIST", ""],
fail_msg="Sending “CAP LIST” as first message got a reply "
"that is not “CAP * LIST :”: {msg}",
)

View File

@ -1,5 +1,5 @@
""" """
<http://ircv3.net/specs/extensions/echo-message-3.2.html> `IRCv3 echo-message <https://ircv3.net/specs/extensions/echo-message>`_
""" """
import pytest import pytest

View File

@ -1,3 +1,7 @@
"""
`Ergo <https://ergo.chat/>`-specific tests of NickServ.
"""
from irctest import cases from irctest import cases
from irctest.numerics import RPL_YOUREOPER from irctest.numerics import RPL_YOUREOPER

View File

@ -1,5 +1,5 @@
""" """
<http://ircv3.net/specs/extensions/extended-join-3.1.html> `IRCv3 extended-join <https://ircv3.net/specs/extensions/extended-join>`_
""" """
from irctest import cases from irctest import cases

View File

@ -1,5 +1,5 @@
""" """
The HELP and HELPOP command. The HELP and HELPOP command (`Modern <https://modern.ircdocs.horse/#help-message>`__)
""" """
import re import re

View File

@ -1,5 +1,8 @@
""" """
The INFO command. The INFO command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.3.8>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.4.10>`__,
`Modern <https://modern.ircdocs.horse/#info-message>`__)
""" """
import pytest import pytest

View File

@ -1,3 +1,10 @@
"""
The INVITE command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.7>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.7>`__,
`Modern <https://modern.ircdocs.horse/#invite-message>`__)
"""
import pytest import pytest
from irctest import cases from irctest import cases

View File

@ -1,3 +1,8 @@
"""
RPL_ISUPPORT: `format <https://modern.ircdocs.horse/#rplisupport-005>`__
and various `tokens <https://modern.ircdocs.horse/#rplisupport-parameters>`__
"""
import re import re
from irctest import cases, runner from irctest import cases, runner

View File

@ -1,3 +1,10 @@
"""
The JOIN command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.1>`__,
`Modern <https://modern.ircdocs.horse/#join-message>`__)
"""
from irctest import cases from irctest import cases
from irctest.irc_utils import ambiguities from irctest.irc_utils import ambiguities

View File

@ -1,3 +1,10 @@
"""
The INFO command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.>`__,
`Modern <https://modern.ircdocs.horse/#kick-message>`__)
"""
import pytest import pytest
from irctest import cases, client_mock, runner from irctest import cases, client_mock, runner

View File

@ -1,8 +1,8 @@
""" """
`IRCv3 labeled-response <https://ircv3.net/specs/extensions/labeled-response>`_
This specification is a little hard to test because all labels are optional; This specification is a little hard to test because all labels are optional;
so there may be many false positives. so there may be many false positives.
<https://ircv3.net/specs/extensions/labeled-response.html>
""" """
import re import re

View File

@ -1,3 +1,12 @@
"""
The LIST command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.6>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.6>`__,
`Modern <https://modern.ircdocs.horse/#list-message>`__)
TODO: check with Modern
"""
from irctest import cases from irctest import cases

View File

@ -1,3 +1,11 @@
"""
The LUSERS command (`RFC 2812
<https://datatracker.ietf.org/doc/html/rfc2812#section-3.4.2>`__,
`Modern <https://modern.ircdocs.horse/#lusers-message>`__),
which provides statistics on user counts.
"""
from dataclasses import dataclass from dataclasses import dataclass
import re import re
from typing import Optional from typing import Optional

View File

@ -1,5 +1,5 @@
""" """
https://ircv3.net/specs/extensions/message-tags.html `IRCv3 message-tags <https://ircv3.net/specs/extensions/message-tags>`_
""" """
import pytest import pytest

View File

@ -1,6 +1,5 @@
""" """
Section 3.2 of RFC 2812 The PRIVMSG and NOTICE commands.
<https://tools.ietf.org/html/rfc2812#section-3.3>
""" """
from irctest import cases from irctest import cases

View File

@ -1,6 +1,5 @@
""" """
Tests METADATA features. `Deprecated IRCv3 Metadata <https://ircv3.net/specs/core/metadata-3.2>`_
<http://ircv3.net/specs/core/metadata-3.2.html>
""" """
from irctest import cases from irctest import cases

View File

@ -1,5 +1,5 @@
""" """
<http://ircv3.net/specs/core/monitor-3.2.html> `IRCv3 MONITOR <https://ircv3.net/specs/extensions/monitor>`_
""" """
from irctest import cases from irctest import cases

View File

@ -1,6 +1,5 @@
""" """
Tests multi-prefix. `IRCv3 multi-prefix <https://ircv3.net/specs/extensions/multi-prefix>`_
<http://ircv3.net/specs/extensions/multi-prefix-3.1.html>
""" """
from irctest import cases from irctest import cases

View File

@ -1,5 +1,5 @@
""" """
draft/multiline `Draft IRCv3 multiline <https://ircv3.net/specs/extensions/multiline>`_
""" """
from irctest import cases from irctest import cases

View File

@ -1,3 +1,10 @@
"""
The NAMES command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.5>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.5>`__,
`Modern <https://modern.ircdocs.horse/#names-message>`__)
"""
from irctest import cases from irctest import cases
from irctest.numerics import RPL_ENDOFNAMES from irctest.numerics import RPL_ENDOFNAMES
from irctest.patma import ANYSTR from irctest.patma import ANYSTR

View File

@ -1,3 +1,12 @@
"""
The PART command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-6.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-5.2>`__,
`Modern <https://modern.ircdocs.horse/#part-message>`__)
TODO: cross-reference Modern
"""
import time import time
from irctest import cases from irctest import cases

View File

@ -1,3 +1,7 @@
"""
The PING and PONG commands
"""
from irctest import cases from irctest import cases
from irctest.numerics import ERR_NEEDMOREPARAMS, ERR_NOORIGIN from irctest.numerics import ERR_NEEDMOREPARAMS, ERR_NOORIGIN
from irctest.patma import ANYSTR from irctest.patma import ANYSTR

View File

@ -1,3 +1,12 @@
"""
The QUITcommand (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.1.6>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.1>`__,
`Modern <https://modern.ircdocs.horse/#quit-message>`__)
TODO: cross-reference RFC 1459 and Modern
"""
import time import time
from irctest import cases from irctest import cases

View File

@ -1,9 +1,12 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of responses to DoS attacks
using long lines.
"""
from irctest import cases from irctest import cases
class ReadqTestCase(cases.BaseServerTestCase): class ReadqTestCase(cases.BaseServerTestCase):
"""Test responses to DoS attacks using long lines."""
@cases.mark_specifications("Ergo") @cases.mark_specifications("Ergo")
@cases.mark_capabilities("message-tags") @cases.mark_capabilities("message-tags")
def testReadqTags(self): def testReadqTags(self):

View File

@ -1,5 +1,5 @@
""" """
Regression tests for bugs in oragono. Regression tests for bugs in `Ergo <https://ergo.chat/>`_.
""" """
import time import time

View File

@ -1,3 +1,7 @@
"""
RELAYMSG command of `Ergo <https://ergo.chat/>`_
"""
from irctest import cases from irctest import cases
from irctest.irc_utils.junkdrawer import random_name from irctest.irc_utils.junkdrawer import random_name
from irctest.patma import ANYSTR from irctest.patma import ANYSTR

View File

@ -1,3 +1,7 @@
"""
Roleplay features of `Ergo <https://ergo.chat/>`_
"""
from irctest import cases from irctest import cases
from irctest.irc_utils.junkdrawer import random_name from irctest.irc_utils.junkdrawer import random_name
from irctest.numerics import ERR_CANNOTSENDRP from irctest.numerics import ERR_CANNOTSENDRP

View File

@ -1,3 +1,10 @@
"""
STATUSMSG ISUPPORT token and related PRIVMSG (`Modern
<https://modern.ircdocs.horse/#statusmsg-parameter>`__)
TODO: cross-reference Modern
"""
from irctest import cases, runner from irctest import cases, runner
from irctest.numerics import RPL_NAMREPLY from irctest.numerics import RPL_NAMREPLY

View File

@ -1,3 +1,10 @@
"""
The TOPIC command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.1>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.1>`__,
`Modern <https://modern.ircdocs.horse/#topic-message>`__)
"""
from irctest import cases, client_mock, runner from irctest import cases, client_mock, runner
from irctest.numerics import ERR_CHANOPRIVSNEEDED, RPL_NOTOPIC, RPL_TOPIC, RPL_TOPICTIME from irctest.numerics import ERR_CHANOPRIVSNEEDED, RPL_NOTOPIC, RPL_TOPIC, RPL_TOPICTIME

View File

@ -1,3 +1,10 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of non-Unicode filtering
TODO: turn this into a test of `IRCv3 UTF8ONLY
<https://ircv3.net/specs/extensions/utf8-only>`_
"""
from irctest import cases from irctest import cases
from irctest.patma import ANYSTR from irctest.patma import ANYSTR

View File

@ -1,3 +1,9 @@
"""
The WALLOPS command (`RFC 2812
<https://datatracker.ietf.org/doc/html/rfc2812#section-3.7>`__,
`Modern <https://modern.ircdocs.horse/#wallops-message>`__)
"""
from irctest import cases, runner from irctest import cases, runner
from irctest.numerics import ERR_NOPRIVILEGES, ERR_UNKNOWNCOMMAND, RPL_YOUREOPER from irctest.numerics import ERR_NOPRIVILEGES, ERR_UNKNOWNCOMMAND, RPL_YOUREOPER
from irctest.patma import ANYSTR, StrRe from irctest.patma import ANYSTR, StrRe

View File

@ -1,3 +1,10 @@
"""
The WHO command (`Modern <https://modern.ircdocs.horse/#who-message>`__)
and `IRCv3 WHOX <https://ircv3.net/specs/extensions/whox>`_
TODO: cross-reference RFC 1459 and RFC 2812
"""
import re import re
import pytest import pytest

View File

@ -1,3 +1,9 @@
"""
The WHOIS command (`Modern <https://modern.ircdocs.horse/#whois-message>`__)
TODO: cross-reference RFC 1459 and RFC 2812
"""
import pytest import pytest
from irctest import cases from irctest import cases

View File

@ -1,3 +1,13 @@
"""
The WHOSWAS command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.5.3>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.6.3>`__,
`Modern <https://modern.ircdocs.horse/#whowas-message>`__)
TODO: cross-reference Modern
"""
import pytest import pytest
from irctest import cases, runner from irctest import cases, runner

View File

@ -1,3 +1,7 @@
"""
`Ergo <https://ergo.chat/>`_-specific tests of ZNC-like message playback
"""
import time import time
from irctest import cases from irctest import cases

View File

@ -367,7 +367,7 @@ def generate_workflow(config: dict, version_flavor: VersionFlavor):
"name": "Install dashboard dependencies", "name": "Install dashboard dependencies",
"run": script( "run": script(
"python -m pip install --upgrade pip", "python -m pip install --upgrade pip",
"pip install defusedxml", "pip install defusedxml docutils -r requirements.txt",
), ),
}, },
{ {