Compare commits

..

9 Commits

Author SHA1 Message Date
b6537a50ae Changed path to tests/ 2023-08-06 02:08:02 +02:00
e508f37089 Added pytest to pyproject 2023-08-06 02:07:07 +02:00
d66bb9c93e Locale of _() now defaults to "en" 2023-08-06 01:44:51 +02:00
253c85985b Added some basic test 2023-08-06 01:25:32 +02:00
11d49fd476 Fixed escape_forward_slashes error 2023-08-06 01:25:08 +02:00
dc107ebdb3 Updated to 1.9 2023-07-26 14:12:13 +02:00
33c33d08e2 Allowed passing kwargs 2023-07-26 14:12:05 +02:00
295e77e403 Updated to 1.8 2023-07-03 10:57:00 +02:00
279a8e9d84 reports.chat_id can now be "owner" 2023-07-03 10:56:24 +02:00
15 changed files with 264 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
__name__ = "libbot" __name__ = "libbot"
__version__ = "1.7" __version__ = "1.9"
__license__ = "GPL3" __license__ = "GPL3"
__author__ = "Profitroll" __author__ = "Profitroll"

View File

@@ -35,6 +35,8 @@ async def json_write(data: Any, path: Union[str, Path]) -> None:
async with aiofiles.open(str(path), mode="w", encoding="utf-8") as f: async with aiofiles.open(str(path), mode="w", encoding="utf-8") as f:
await f.write( await f.write(
dumps(data, ensure_ascii=False, escape_forward_slashes=False, indent=4) dumps(data, ensure_ascii=False, escape_forward_slashes=False, indent=4)
if hasattr(dumps, "escape_forward_slashes")
else dumps(data, ensure_ascii=False, indent=4)
) )

View File

@@ -9,7 +9,7 @@ from libbot.i18n.classes.bot_locale import BotLocale
async def _( async def _(
key: str, key: str,
*args: str, *args: str,
locale: str = sync.config_get("locale"), locale: str = "en",
locales_root: Union[str, Path] = Path("locale"), locales_root: Union[str, Path] = Path("locale"),
) -> Any: ) -> Any:
"""Get value of locale string """Get value of locale string
@@ -17,7 +17,7 @@ async def _(
### Args: ### Args:
* key (`str`): The last key of the locale's keys path. * key (`str`): The last key of the locale's keys path.
* *args (`list`): Path to key like: `dict[args][key]`. * *args (`list`): Path to key like: `dict[args][key]`.
* locale (`str`): Locale to looked up in. Defaults to config's `"locale"` value. * locale (`str`): Locale to looked up in. Defaults to `"en"`.
* locales_root (`Union[str, Path]`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. * locales_root (`Union[str, Path]`, *optional*): Folder where locales are located. Defaults to `Path("locale")`.
### Returns: ### Returns:

View File

@@ -9,7 +9,7 @@ from libbot.sync import config_get, json_read
def _( def _(
key: str, key: str,
*args: str, *args: str,
locale: str = sync.config_get("locale"), locale: str = "en",
locales_root: Union[str, Path] = Path("locale"), locales_root: Union[str, Path] = Path("locale"),
) -> Any: ) -> Any:
"""Get value of locale string """Get value of locale string
@@ -17,7 +17,7 @@ def _(
### Args: ### Args:
* key (`str`): The last key of the locale's keys path. * key (`str`): The last key of the locale's keys path.
* *args (`list`): Path to key like: `dict[args][key]`. * *args (`list`): Path to key like: `dict[args][key]`.
* locale (`str`): Locale to looked up in. Defaults to config's `"locale"` value. * locale (`str`): Locale to looked up in. Defaults to `"en"`.
* locales_root (`Union[str, Path]`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. * locales_root (`Union[str, Path]`, *optional*): Folder where locales are located. Defaults to `Path("locale")`.
### Returns: ### Returns:

View File

@@ -59,6 +59,7 @@ class PyroClient(Client):
max_concurrent_transmissions: int = 1, max_concurrent_transmissions: int = 1,
commands_source: Union[Dict[str, dict], None] = None, commands_source: Union[Dict[str, dict], None] = None,
scheduler: Union[AsyncIOScheduler, BackgroundScheduler, None] = None, scheduler: Union[AsyncIOScheduler, BackgroundScheduler, None] = None,
**kwargs,
): ):
if config is None: if config is None:
with open(config_path, "r", encoding="utf-8") as f: with open(config_path, "r", encoding="utf-8") as f:
@@ -90,6 +91,7 @@ class PyroClient(Client):
] ]
if "max_concurrent_transmissions" in self.config["bot"] if "max_concurrent_transmissions" in self.config["bot"]
else max_concurrent_transmissions, else max_concurrent_transmissions,
**kwargs,
) )
self.owner: int = self.config["bot"]["owner"] self.owner: int = self.config["bot"]["owner"]
self.commands: List[PyroCommand] = [] self.commands: List[PyroCommand] = []
@@ -128,7 +130,9 @@ class PyroClient(Client):
try: try:
await self.send_message( await self.send_message(
chat_id=self.config["reports"]["chat_id"], chat_id=self.owner
if self.config["reports"]["chat_id"] == "owner"
else self.config["reports"]["chat_id"],
text=f"Bot started PID `{getpid()}`", text=f"Bot started PID `{getpid()}`",
) )
@@ -150,7 +154,9 @@ class PyroClient(Client):
async def stop(self, exit_completely: bool = True): async def stop(self, exit_completely: bool = True):
try: try:
await self.send_message( await self.send_message(
chat_id=self.config["reports"]["chat_id"], chat_id=self.owner
if self.config["reports"]["chat_id"] == "owner"
else self.config["reports"]["chat_id"],
text=f"Bot stopped with PID `{getpid()}`", text=f"Bot stopped with PID `{getpid()}`",
) )
await asyncio.sleep(0.5) await asyncio.sleep(0.5)

View File

@@ -29,7 +29,11 @@ def json_write(data: Any, path: Union[str, Path]) -> None:
* path (`Union[str, Path]`): Path-like object or path as a string of a destination * path (`Union[str, Path]`): Path-like object or path as a string of a destination
""" """
with open(str(path), mode="w", encoding="utf-8") as f: with open(str(path), mode="w", encoding="utf-8") as f:
f.write(dumps(data, ensure_ascii=False, escape_forward_slashes=False, indent=4)) f.write(
dumps(data, ensure_ascii=False, escape_forward_slashes=False, indent=4)
if hasattr(dumps, "escape_forward_slashes")
else dumps(data, ensure_ascii=False, indent=4)
)
def nested_set(target: dict, value: Any, *path: str, create_missing=True) -> dict: def nested_set(target: dict, value: Any, *path: str, create_missing=True) -> dict:

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "libbot" name = "libbot"
version = "1.7" version = "1.9"
authors = [{ name = "Profitroll" }] authors = [{ name = "Profitroll" }]
description = "Universal bot library with functions needed for basic Discord/Telegram bot development." description = "Universal bot library with functions needed for basic Discord/Telegram bot development."
readme = "README.md" readme = "README.md"
@@ -52,3 +52,9 @@ target-version = ['py38', 'py39', 'py310', 'py311']
[tool.isort] [tool.isort]
profile = "black" profile = "black"
[tool.pytest.ini_options]
minversion = "6.0"
python_files = ["test_*.py"]
pythonpath = "."
testpaths = ["tests"]

6
tests/config.json Normal file
View File

@@ -0,0 +1,6 @@
{
"locale": "en",
"bot": {
"bot_token": "sample_token"
}
}

1
tests/data/empty.json Normal file
View File

@@ -0,0 +1 @@
{}

3
tests/data/invalid.json Normal file
View File

@@ -0,0 +1,3 @@
{
"foo": 'bar'
}

15
tests/data/test.json Normal file
View File

@@ -0,0 +1,15 @@
{
"foo": "bar",
"abcdefg": [
"higklmnop",
{
"lol": {
"kek": [
1.0000035,
0.2542,
1337
]
}
}
]
}

View File

@@ -0,0 +1,49 @@
from pathlib import Path
from typing import Any, List
import pytest
from libbot import config_get, config_set
@pytest.mark.asyncio
@pytest.mark.parametrize(
"args, expected",
[
(["locale"], "en"),
(["bot_token", "bot"], "sample_token"),
],
)
async def test_config_get_valid(args: List[str], expected: str):
assert (
await config_get(args[0], *args[1:], config_file=Path("tests/config.json"))
== expected
)
@pytest.mark.asyncio
@pytest.mark.parametrize(
"args, expected",
[
(["bot_stonks", "bot"], pytest.raises(KeyError)),
],
)
async def test_config_get_invalid(args: List[str], expected: Any):
with expected:
assert (
await config_get(args[0], *args[1:], config_file=Path("tests/config.json"))
== expected
)
@pytest.mark.asyncio
@pytest.mark.parametrize(
"key, path, value",
[
("locale", [], "en"),
("bot_token", ["bot"], "sample_token"),
],
)
async def test_config_set(key: str, path: List[str], value: Any):
await config_set(key, value, *path, config_file=Path("tests/config.json"))
assert await config_get(key, *path, config_file=Path("tests/config.json")) == value

46
tests/test_config_sync.py Normal file
View File

@@ -0,0 +1,46 @@
from pathlib import Path
from typing import Any, List
import pytest
from libbot import sync
@pytest.mark.parametrize(
"args, expected",
[
(["locale"], "en"),
(["bot_token", "bot"], "sample_token"),
],
)
def test_config_get_valid(args: List[str], expected: str):
assert (
sync.config_get(args[0], *args[1:], config_file=Path("tests/config.json"))
== expected
)
@pytest.mark.parametrize(
"args, expected",
[
(["bot_stonks", "bot"], pytest.raises(KeyError)),
],
)
def test_config_get_invalid(args: List[str], expected: Any):
with expected:
assert (
sync.config_get(args[0], *args[1:], config_file=Path("tests/config.json"))
== expected
)
@pytest.mark.parametrize(
"key, path, value",
[
("locale", [], "en"),
("bot_token", ["bot"], "sample_token"),
],
)
def test_config_set(key: str, path: List[str], value: Any):
sync.config_set(key, value, *path, config_file=Path("tests/config.json"))
assert sync.config_get(key, *path, config_file=Path("tests/config.json")) == value

60
tests/test_json_async.py Normal file
View File

@@ -0,0 +1,60 @@
from json import JSONDecodeError, dumps
from pathlib import Path
from typing import Any, Union
import pytest
from libbot import json_read, json_write
@pytest.mark.asyncio
@pytest.mark.parametrize(
"path, expected",
[
(
"tests/data/test.json",
{
"foo": "bar",
"abcdefg": ["higklmnop", {"lol": {"kek": [1.0000035, 0.2542, 1337]}}],
},
),
("tests/data/empty.json", {}),
],
)
async def test_json_read_valid(path: Union[str, Path], expected: Any):
assert await json_read(path) == expected
@pytest.mark.asyncio
@pytest.mark.parametrize(
"path, expected",
[
("tests/data/invalid.json", pytest.raises(JSONDecodeError)),
("tests/data/nonexistent.json", pytest.raises(FileNotFoundError)),
],
)
async def test_json_read_invalid(path: Union[str, Path], expected: Any):
with expected:
assert await json_read(path) == expected
@pytest.mark.asyncio
@pytest.mark.parametrize(
"data, path",
[
(
{
"foo": "bar",
"abcdefg": ["higklmnop", {"lol": {"kek": [1.0000035, 0.2542, 1337]}}],
},
"tests/data/test.json",
),
({}, "tests/data/empty.json"),
],
)
async def test_json_write(data: Any, path: Union[str, Path]):
await json_write(data, path)
assert Path(path).is_file()
with open(path, "r", encoding="utf-8") as f:
assert f.read() == dumps(data, ensure_ascii=False, indent=4)

57
tests/test_json_sync.py Normal file
View File

@@ -0,0 +1,57 @@
from json import JSONDecodeError, dumps
from pathlib import Path
from typing import Any, Union
import pytest
from libbot import sync
@pytest.mark.parametrize(
"path, expected",
[
(
"tests/data/test.json",
{
"foo": "bar",
"abcdefg": ["higklmnop", {"lol": {"kek": [1.0000035, 0.2542, 1337]}}],
},
),
("tests/data/empty.json", {}),
],
)
def test_json_read_valid(path: Union[str, Path], expected: Any):
assert sync.json_read(path) == expected
@pytest.mark.parametrize(
"path, expected",
[
("tests/data/invalid.json", pytest.raises(JSONDecodeError)),
("tests/data/nonexistent.json", pytest.raises(FileNotFoundError)),
],
)
def test_json_read_invalid(path: Union[str, Path], expected: Any):
with expected:
assert sync.json_read(path) == expected
@pytest.mark.parametrize(
"data, path",
[
(
{
"foo": "bar",
"abcdefg": ["higklmnop", {"lol": {"kek": [1.0000035, 0.2542, 1337]}}],
},
"tests/data/test.json",
),
({}, "tests/data/empty.json"),
],
)
def test_json_write(data: Any, path: Union[str, Path]):
sync.json_write(data, path)
assert Path(path).is_file()
with open(path, "r", encoding="utf-8") as f:
assert f.read() == dumps(data, ensure_ascii=False, indent=4)