mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-21 02:16:09 -05:00
[V3] Make pytest fixtures available as a plugin (#1858)
* Move all fixtures to pytest plugin folder * Add core dunder all * Update other dunder all's * Black reformat
This commit is contained in:
1
redbot/pytest/__init__.py
Normal file
1
redbot/pytest/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .core import *
|
||||
20
redbot/pytest/admin.py
Normal file
20
redbot/pytest/admin.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from redbot.cogs.admin import Admin
|
||||
from redbot.cogs.admin.announcer import Announcer
|
||||
|
||||
__all__ = ["admin", "announcer"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def admin(config):
|
||||
return Admin(config)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def announcer(admin):
|
||||
a = Announcer(MagicMock(), "Some message", admin.conf)
|
||||
yield a
|
||||
a.cancel()
|
||||
13
redbot/pytest/alias.py
Normal file
13
redbot/pytest/alias.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import pytest
|
||||
|
||||
from redbot.cogs.alias import Alias
|
||||
from redbot.core import Config
|
||||
|
||||
__all__ = ["alias"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def alias(config, monkeypatch):
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr(Config, "get_conf", lambda *args, **kwargs: config)
|
||||
return Alias(None)
|
||||
13
redbot/pytest/cog_manager.py
Normal file
13
redbot/pytest/cog_manager.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import pytest
|
||||
|
||||
__all__ = ["cog_mgr", "default_dir"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def cog_mgr(red):
|
||||
return red.cog_mgr
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def default_dir(red):
|
||||
return red.main_dir
|
||||
184
redbot/pytest/core.py
Normal file
184
redbot/pytest/core.py
Normal file
@@ -0,0 +1,184 @@
|
||||
import random
|
||||
from collections import namedtuple
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from redbot.core import Config
|
||||
from redbot.core.bot import Red
|
||||
|
||||
from redbot.core.drivers import red_json
|
||||
|
||||
__all__ = [
|
||||
"monkeysession",
|
||||
"override_data_path",
|
||||
"coroutine",
|
||||
"json_driver",
|
||||
"config",
|
||||
"config_fr",
|
||||
"red",
|
||||
"guild_factory",
|
||||
"empty_guild",
|
||||
"empty_channel",
|
||||
"empty_member",
|
||||
"empty_message",
|
||||
"empty_role",
|
||||
"empty_user",
|
||||
"member_factory",
|
||||
"user_factory",
|
||||
"ctx",
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def monkeysession(request):
|
||||
mpatch = MonkeyPatch()
|
||||
yield mpatch
|
||||
mpatch.undo()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def override_data_path(tmpdir):
|
||||
from redbot.core import data_manager
|
||||
|
||||
data_manager.basic_config = data_manager.basic_config_default
|
||||
data_manager.basic_config["DATA_PATH"] = str(tmpdir)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def coroutine():
|
||||
async def some_coro(*args, **kwargs):
|
||||
return args, kwargs
|
||||
|
||||
return some_coro
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def json_driver(tmpdir_factory):
|
||||
import uuid
|
||||
|
||||
rand = str(uuid.uuid4())
|
||||
path = Path(str(tmpdir_factory.mktemp(rand)))
|
||||
driver = red_json.JSON("PyTest", identifier=str(uuid.uuid4()), data_path_override=path)
|
||||
return driver
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def config(json_driver):
|
||||
conf = Config(
|
||||
cog_name="PyTest", unique_identifier=json_driver.unique_cog_identifier, driver=json_driver
|
||||
)
|
||||
yield conf
|
||||
conf._defaults = {}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def config_fr(json_driver):
|
||||
"""
|
||||
Mocked config object with force_register enabled.
|
||||
"""
|
||||
conf = Config(
|
||||
cog_name="PyTest",
|
||||
unique_identifier=json_driver.unique_cog_identifier,
|
||||
driver=json_driver,
|
||||
force_registration=True,
|
||||
)
|
||||
yield conf
|
||||
conf._defaults = {}
|
||||
|
||||
|
||||
# region Dpy Mocks
|
||||
@pytest.fixture()
|
||||
def guild_factory():
|
||||
mock_guild = namedtuple("Guild", "id members")
|
||||
|
||||
class GuildFactory:
|
||||
def get(self):
|
||||
return mock_guild(random.randint(1, 999999999), [])
|
||||
|
||||
return GuildFactory()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def empty_guild(guild_factory):
|
||||
return guild_factory.get()
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def empty_channel():
|
||||
mock_channel = namedtuple("Channel", "id")
|
||||
return mock_channel(random.randint(1, 999999999))
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def empty_role():
|
||||
mock_role = namedtuple("Role", "id")
|
||||
return mock_role(random.randint(1, 999999999))
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def member_factory(guild_factory):
|
||||
mock_member = namedtuple("Member", "id guild display_name")
|
||||
|
||||
class MemberFactory:
|
||||
def get(self):
|
||||
return mock_member(random.randint(1, 999999999), guild_factory.get(), "Testing_Name")
|
||||
|
||||
return MemberFactory()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def empty_member(member_factory):
|
||||
return member_factory.get()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def user_factory():
|
||||
mock_user = namedtuple("User", "id")
|
||||
|
||||
class UserFactory:
|
||||
def get(self):
|
||||
return mock_user(random.randint(1, 999999999))
|
||||
|
||||
return UserFactory()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def empty_user(user_factory):
|
||||
return user_factory.get()
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def empty_message():
|
||||
mock_msg = namedtuple("Message", "content")
|
||||
return mock_msg("No content.")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def ctx(empty_member, empty_channel, red):
|
||||
mock_ctx = namedtuple("Context", "author guild channel message bot")
|
||||
return mock_ctx(empty_member, empty_member.guild, empty_channel, empty_message, red)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# region Red Mock
|
||||
@pytest.fixture()
|
||||
def red(config_fr):
|
||||
from redbot.core.cli import parse_cli_flags
|
||||
|
||||
cli_flags = parse_cli_flags(["ignore_me"])
|
||||
|
||||
description = "Red v3 - Alpha"
|
||||
|
||||
Config.get_core_conf = lambda *args, **kwargs: config_fr
|
||||
|
||||
red = Red(cli_flags=cli_flags, description=description, pm_help=None)
|
||||
|
||||
yield red
|
||||
|
||||
red.http._session.close()
|
||||
|
||||
|
||||
# endregion
|
||||
24
redbot/pytest/data_manager.py
Normal file
24
redbot/pytest/data_manager.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import pytest
|
||||
|
||||
from redbot.core import data_manager
|
||||
|
||||
__all__ = ["cleanup_datamanager", "data_mgr_config", "cog_instance"]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def cleanup_datamanager():
|
||||
data_manager.basic_config = None
|
||||
data_manager.jsonio = None
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def data_mgr_config(tmpdir):
|
||||
default = data_manager.basic_config_default.copy()
|
||||
default["BASE_DIR"] = str(tmpdir)
|
||||
return default
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def cog_instance():
|
||||
thing = type("CogTest", (object,), {})
|
||||
return thing()
|
||||
12
redbot/pytest/dataconverter.py
Normal file
12
redbot/pytest/dataconverter.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from pathlib import Path
|
||||
|
||||
from redbot.cogs.dataconverter import core_specs
|
||||
|
||||
__all__ = ["get_specresolver"]
|
||||
|
||||
|
||||
def get_specresolver(path):
|
||||
here = Path(path)
|
||||
|
||||
resolver = core_specs.SpecResolver(here.parent)
|
||||
return resolver
|
||||
103
redbot/pytest/downloader.py
Normal file
103
redbot/pytest/downloader.py
Normal file
@@ -0,0 +1,103 @@
|
||||
from collections import namedtuple
|
||||
from pathlib import Path
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from redbot.cogs.downloader.repo_manager import RepoManager, Repo
|
||||
from redbot.cogs.downloader.installable import Installable
|
||||
|
||||
__all__ = [
|
||||
"patch_relative_to",
|
||||
"repo_manager",
|
||||
"repo",
|
||||
"repo_norun",
|
||||
"bot_repo",
|
||||
"INFO_JSON",
|
||||
"installable",
|
||||
"fake_run_noprint",
|
||||
]
|
||||
|
||||
|
||||
async def fake_run(*args, **kwargs):
|
||||
fake_result_tuple = namedtuple("fake_result", "returncode result")
|
||||
res = fake_result_tuple(0, (args, kwargs))
|
||||
print(args[0])
|
||||
return res
|
||||
|
||||
|
||||
async def fake_run_noprint(*args, **kwargs):
|
||||
fake_result_tuple = namedtuple("fake_result", "returncode result")
|
||||
res = fake_result_tuple(0, (args, kwargs))
|
||||
return res
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def patch_relative_to(monkeysession):
|
||||
def fake_relative_to(self, some_path: Path):
|
||||
return self
|
||||
|
||||
monkeysession.setattr("pathlib.Path.relative_to", fake_relative_to)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repo_manager(tmpdir_factory):
|
||||
rm = RepoManager()
|
||||
# rm.repos_folder = Path(str(tmpdir_factory.getbasetemp())) / 'repos'
|
||||
return rm
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repo(tmpdir):
|
||||
repo_folder = Path(str(tmpdir)) / "repos" / "squid"
|
||||
repo_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
return Repo(
|
||||
url="https://github.com/tekulvw/Squid-Plugins",
|
||||
name="squid",
|
||||
branch="rewrite_cogs",
|
||||
folder_path=repo_folder,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repo_norun(repo):
|
||||
repo._run = fake_run
|
||||
return repo
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bot_repo(event_loop):
|
||||
cwd = Path.cwd()
|
||||
return Repo(
|
||||
name="Red-DiscordBot",
|
||||
branch="WRONG",
|
||||
url="https://empty.com/something.git",
|
||||
folder_path=cwd,
|
||||
loop=event_loop,
|
||||
)
|
||||
|
||||
|
||||
# Installable
|
||||
INFO_JSON = {
|
||||
"author": ("tekulvw",),
|
||||
"bot_version": (3, 0, 0),
|
||||
"description": "A long description",
|
||||
"hidden": False,
|
||||
"install_msg": "A post-installation message",
|
||||
"required_cogs": {},
|
||||
"requirements": ("tabulate"),
|
||||
"short": "A short description",
|
||||
"tags": ("tag1", "tag2"),
|
||||
"type": "COG",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def installable(tmpdir):
|
||||
cog_path = tmpdir.mkdir("test_repo").mkdir("test_cog")
|
||||
info_path = cog_path.join("info.json")
|
||||
info_path.write_text(json.dumps(INFO_JSON), "utf-8")
|
||||
|
||||
cog_info = Installable(Path(str(cog_path)))
|
||||
return cog_info
|
||||
15
redbot/pytest/economy.py
Normal file
15
redbot/pytest/economy.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import pytest
|
||||
|
||||
__all__ = ["bank"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def bank(config, monkeypatch):
|
||||
from redbot.core import Config
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr(Config, "get_conf", lambda *args, **kwargs: config)
|
||||
from redbot.core import bank
|
||||
|
||||
bank._register_defaults()
|
||||
return bank
|
||||
15
redbot/pytest/mod.py
Normal file
15
redbot/pytest/mod.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import pytest
|
||||
|
||||
__all__ = ["mod"]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mod(config, monkeypatch):
|
||||
from redbot.core import Config
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr(Config, "get_conf", lambda *args, **kwargs: config)
|
||||
from redbot.core import modlog
|
||||
|
||||
modlog._register_defaults()
|
||||
return modlog
|
||||
51
redbot/pytest/rpc.py
Normal file
51
redbot/pytest/rpc.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import pytest
|
||||
from redbot.core.rpc import RPC, RPCMixin
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
__all__ = ["rpc", "rpcmixin", "cog", "existing_func", "existing_multi_func"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def rpc():
|
||||
return RPC()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def rpcmixin():
|
||||
r = RPCMixin()
|
||||
r.rpc = MagicMock(spec=RPC)
|
||||
return r
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def cog():
|
||||
class Cog:
|
||||
async def cofunc(*args, **kwargs):
|
||||
pass
|
||||
|
||||
async def cofunc2(*args, **kwargs):
|
||||
pass
|
||||
|
||||
async def cofunc3(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def func(*args, **kwargs):
|
||||
pass
|
||||
|
||||
return Cog()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def existing_func(rpc, cog):
|
||||
rpc.add_method(cog.cofunc)
|
||||
|
||||
return cog.cofunc
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def existing_multi_func(rpc, cog):
|
||||
funcs = [cog.cofunc, cog.cofunc2, cog.cofunc3]
|
||||
rpc.add_multi_method(*funcs)
|
||||
|
||||
return funcs
|
||||
Reference in New Issue
Block a user