⬆️ upgrade to nonebot beta1

This commit is contained in:
yanyongyu 2022-01-13 21:07:26 +08:00
parent 6a553d5e20
commit 46276b9e62
7 changed files with 357 additions and 38 deletions

160
poetry.lock generated
View File

@ -37,6 +37,40 @@ python-versions = ">=3.6"
[package.extras]
tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
[[package]]
name = "async-asgi-testclient"
version = "1.4.9"
description = "Async client for testing ASGI web applications"
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
multidict = ">=4.0,<6.0"
requests = ">=2.21,<3.0"
[[package]]
name = "atomicwrites"
version = "1.4.0"
description = "Atomic file writes."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "attrs"
version = "21.4.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
[[package]]
name = "binaryornot"
version = "0.4.4"
@ -280,6 +314,14 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
perf = ["ipython"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "isort"
version = "5.10.1"
@ -431,6 +473,20 @@ websockets = ["websockets (>=9.1)"]
aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"]
httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"]
[[package]]
name = "nonebug"
version = "0.2.0"
description = "nonebot2 test framework"
category = "dev"
optional = false
python-versions = ">=3.7.3,<4.0.0"
[package.dependencies]
async-asgi-testclient = ">=1.4.8,<2.0.0"
nonebot2 = ">=2.0.0-beta.1,<3.0.0"
pytest = ">=6.2.5,<7.0.0"
pytest-asyncio = ">=0.16.0,<0.17.0"
[[package]]
name = "packaging"
version = "21.3"
@ -476,6 +532,18 @@ pyee = ">=8.0.1"
typing-extensions = {version = "*", markers = "python_version <= \"3.8\""}
websockets = ">=8.1"
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "poyo"
version = "0.5.0"
@ -506,6 +574,14 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.extras]
test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
[[package]]
name = "py"
version = "1.11.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pydantic"
version = "1.9.0"
@ -557,6 +633,41 @@ python-versions = ">=3.6"
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
version = "6.2.5"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
py = ">=1.8.2"
toml = "*"
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
name = "pytest-asyncio"
version = "0.16.0"
description = "Pytest support for asyncio."
category = "dev"
optional = false
python-versions = ">= 3.6"
[package.dependencies]
pytest = ">=5.4.0"
[package.extras]
testing = ["coverage", "hypothesis (>=5.7.1)"]
[[package]]
name = "python-dateutil"
version = "2.8.2"
@ -718,6 +829,14 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "tomli"
version = "1.2.3"
@ -869,7 +988,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "47d2bd44315abb73403e6831fdaf3d0158f8bff7ce244b83bc6b861e224df6ba"
content-hash = "a7504f9a385171f0a9de5dd0cc13aac72d2d414586a8d71ac0967e2f4b763e64"
[metadata.files]
anyio = [
@ -884,6 +1003,17 @@ asgiref = [
{file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
{file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
]
async-asgi-testclient = [
{file = "async-asgi-testclient-1.4.9.tar.gz", hash = "sha256:ae507f44a53699611cff81ad548090dad24055fba02cce398e1ca9b84d1e1288"},
]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
]
attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
]
binaryornot = [
{file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"},
{file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
@ -1065,6 +1195,10 @@ importlib-metadata = [
{file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"},
{file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"},
]
iniconfig = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
isort = [
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
@ -1246,6 +1380,10 @@ nonebot2 = [
{file = "nonebot2-2.0.0b1-py3-none-any.whl", hash = "sha256:76ee4271a0ba9b1fbdcb34c50a23df391bed00d5d32d63b7fd018685de8130a4"},
{file = "nonebot2-2.0.0b1.tar.gz", hash = "sha256:e23b6656943738a9f8559e20ac51a8c3af799a2eea01e3e2188be01959f36455"},
]
nonebug = [
{file = "nonebug-0.2.0-py3-none-any.whl", hash = "sha256:aa0f639f3fc039803640a952b1c12088e8b1ec5a30d1632e43301f215f96de22"},
{file = "nonebug-0.2.0.tar.gz", hash = "sha256:2b1dd24a68cff940037f847dab8ca710e305cd183cf7104019d34a935eceb31c"},
]
packaging = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
@ -1267,6 +1405,10 @@ playwright = [
{file = "playwright-1.17.2-py3-none-win32.whl", hash = "sha256:8fefe383ba1baf474534c6fc2338113318725c420639bdbe1a57a371c20245b3"},
{file = "playwright-1.17.2-py3-none-win_amd64.whl", hash = "sha256:f64403941e0d6bfcc92d451150bbdb4d8eefdaa0c26866c27304106f86923d60"},
]
pluggy = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
poyo = [
{file = "poyo-0.5.0-py2.py3-none-any.whl", hash = "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a"},
{file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"},
@ -1309,6 +1451,10 @@ psutil = [
{file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"},
{file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"},
]
py = [
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
]
pydantic = [
{file = "pydantic-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5"},
{file = "pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4"},
@ -1361,6 +1507,14 @@ pyparsing = [
{file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
{file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
]
pytest = [
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
{file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
]
pytest-asyncio = [
{file = "pytest-asyncio-0.16.0.tar.gz", hash = "sha256:7496c5977ce88c34379df64a66459fe395cd05543f0a2f837016e7144391fcfb"},
{file = "pytest_asyncio-0.16.0-py3-none-any.whl", hash = "sha256:5f2a21273c47b331ae6aa5b36087047b4899e40f03f18397c0e65fa5cca54e9b"},
]
python-dateutil = [
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
@ -1440,6 +1594,10 @@ text-unidecode = [
{file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
{file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
tomli = [
{file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"},
{file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"},

View File

@ -25,6 +25,7 @@ redis = {version = "^4.0.0", extras = ["hiredis"]}
isort = "^5.9.3"
black = "^21.8b0"
nb-cli = "^0.6.0"
nonebug = "^0.2.0"
# [[tool.poetry.source]]
# name = "aliyun"

View File

@ -2,13 +2,15 @@
* @Author : yanyongyu
* @Date : 2020-11-15 14:40:25
* @LastEditors : yanyongyu
* @LastEditTime : 2021-09-10 12:42:40
* @LastEditTime : 2022-01-13 16:32:41
* @Description : None
* @GitHub : https://github.com/yanyongyu
-->
<!-- markdownlint-disable MD033 MD036 MD041 -->
<p align="center">
<a href="https://v2.nonebot.dev/"><img src="https://raw.githubusercontent.com/nonebot/nonebot2/master/docs/.vuepress/public/logo.png" width="200" height="200" alt="nonebot"></a>
<a href="https://v2.nonebot.dev/"><img src="https://v2.nonebot.dev/logo.png" width="200" height="200" alt="nonebot"></a>
</p>
<div align="center">
@ -31,7 +33,12 @@ _✨ NoneBot 服务器状态CPU, Memory, Disk Usage查看插件 ✨_
## 使用方式
通用:
- 发送 Command `状态`
OneBot:
- 向机器人发送戳一戳表情
- 双击机器人头像戳一戳

View File

@ -4,18 +4,15 @@
@Author : yanyongyu
@Date : 2020-09-18 00:00:13
@LastEditors : yanyongyu
@LastEditTime : 2021-09-10 12:47:59
@LastEditTime : 2022-01-13 21:01:33
@Description : None
@GitHub : https://github.com/yanyongyu
"""
__author__ = "yanyongyu"
from nonebot.typing import T_State
from nonebot.matcher import Matcher
from nonebot.adapters import Bot, Event
from nonebot.permission import SUPERUSER
from nonebot import on_notice, get_driver, on_command, on_message
from nonebot.adapters.cqhttp import PokeNotifyEvent, PrivateMessageEvent
from .config import Config
from .data_source import cpu_status, disk_usage, memory_status, per_cpu_status
@ -25,14 +22,13 @@ status_config = Config(**global_config.dict())
command = on_command(
"状态",
permission=(status_config.server_status_only_superusers or None)
and SUPERUSER,
permission=(status_config.server_status_only_superusers or None) and SUPERUSER,
priority=10,
)
@command.handle()
async def server_status(bot: Bot, matcher: Matcher):
async def server_status(matcher: Matcher):
data = []
if status_config.server_status_cpu:
@ -54,33 +50,27 @@ async def server_status(bot: Bot, matcher: Matcher):
await matcher.send(message="\n".join(data))
async def _group_poke(bot: Bot, event: Event, state: T_State) -> bool:
return (
isinstance(event, PokeNotifyEvent)
and event.is_tome()
and (
try:
from nonebot.adapters.onebot.v11 import PokeNotifyEvent, PrivateMessageEvent
except ImportError:
pass
else:
async def _group_poke(event: PokeNotifyEvent) -> bool:
return event.is_tome() and (
not status_config.server_status_only_superusers
or str(event.user_id) in global_config.superusers
)
group_poke = on_notice(_group_poke, priority=10, block=True)
group_poke.handle()(server_status)
async def _poke(event: PrivateMessageEvent) -> bool:
return event.sub_type == "friend" and event.message[0].type == "poke"
poke = on_message(
_poke,
permission=(status_config.server_status_only_superusers or None) and SUPERUSER,
priority=10,
)
group_poke = on_notice(_group_poke, priority=10, block=True)
group_poke.handle()(server_status)
async def _poke(bot: Bot, event: Event, state: T_State) -> bool:
return (
isinstance(event, PrivateMessageEvent)
and event.sub_type == "friend"
and event.message[0].type == "poke"
)
poke = on_message(
_poke,
permission=(status_config.server_status_only_superusers or None)
and SUPERUSER,
priority=10,
)
poke.handle()(server_status)
poke.handle()(server_status)

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "nonebot-plugin-status"
version = "0.2.2"
version = "0.3.0"
description = "Check your server status (CPU, Memory, Disk Usage) via nonebot"
license = "MIT"
authors = ["yanyongyu <yanyongyu_1@126.com>"]
@ -16,10 +16,14 @@ packages = [
[tool.poetry.dependencies]
python = "^3.7.3"
psutil = "^5.7.2"
nonebot2 = "^2.0.0-alpha.8"
nonebot2 = "^2.0.0-beta.1"
nonebot-adapter-onebot = { version = "^2.0.0-beta.1", optional = true }
[tool.poetry.dev-dependencies]
[tool.poetry.extras]
onebot = ["nonebot-adapter-onebot"]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

13
tests/conftest.py Normal file
View File

@ -0,0 +1,13 @@
import pytest
@pytest.fixture(autouse=True)
async def load_plugins(nonebug_init):
import nonebot
from nonebot.adapters.onebot.v11 import Adapter as ONEBOT_V11_Adapter
driver = nonebot.get_driver()
driver.register_adapter(ONEBOT_V11_Adapter)
config = driver.config
nonebot.load_all_plugins(set(config.plugins), set(config.plugin_dirs))

146
tests/test_status.py Normal file
View File

@ -0,0 +1,146 @@
from typing import Dict, List
import psutil
import pytest
from nonebug import App
@pytest.mark.asyncio
async def test_status(app: App, monkeypatch: pytest.MonkeyPatch):
import nonebot
from nonebot.adapters.onebot.v11 import Bot, Adapter, Message
from nonebot.adapters.onebot.v11.event import (
Sender,
PokeNotifyEvent,
PrivateMessageEvent,
)
from src.plugins.nonebot_plugin_status import (
command,
group_poke,
status_config,
)
driver = nonebot.get_driver()
# patch status
def _cpu_status() -> float:
return 10.0
def _disk_usage() -> Dict[str, psutil._common.sdiskusage]:
return {"test": psutil._common.sdiskusage(0, 0, 0, 0)}
def _memory_status() -> float:
return 10.0
def _per_cpu_status() -> List[float]:
return [10.0, 11.0]
monkeypatch.setattr(
"src.plugins.nonebot_plugin_status.cpu_status", _cpu_status
)
monkeypatch.setattr(
"src.plugins.nonebot_plugin_status.disk_usage", _disk_usage
)
monkeypatch.setattr(
"src.plugins.nonebot_plugin_status.memory_status", _memory_status
)
monkeypatch.setattr(
"src.plugins.nonebot_plugin_status.per_cpu_status", _per_cpu_status
)
with monkeypatch.context() as m:
m.setattr(driver.config, "superusers", {"123"})
async with app.test_matcher(command) as ctx:
adapter = ctx.create_adapter(base=Adapter)
bot = ctx.create_bot(base=Bot, adapter=adapter)
event = PrivateMessageEvent(
time=0,
self_id=0,
post_type="message",
sub_type="friend",
user_id=123,
message_type="private",
message_id=0,
message=Message("/状态"),
raw_message="/状态",
font=0,
sender=Sender(),
)
ctx.receive_event(bot, event)
ctx.should_call_send(
event,
"\n".join(
[
"CPU: 10%",
"Memory: 10%",
"Disk:",
" test: 00%",
]
),
True,
)
async with app.test_matcher(group_poke) as ctx:
adapter = ctx.create_adapter(base=Adapter)
bot = ctx.create_bot(base=Bot, adapter=adapter)
event = PokeNotifyEvent(
time=0,
self_id=0,
post_type="notice",
notice_type="notify",
sub_type="poke",
user_id=123,
target_id=0,
)
ctx.receive_event(bot, event)
ctx.should_call_send(
event,
"\n".join(
[
"CPU: 10%",
"Memory: 10%",
"Disk:",
" test: 00%",
]
),
True,
)
m.setattr(status_config, "server_status_per_cpu", True)
async with app.test_matcher(command) as ctx:
adapter = ctx.create_adapter(base=Adapter)
bot = ctx.create_bot(base=Bot, adapter=adapter)
event = PrivateMessageEvent(
time=0,
self_id=0,
post_type="message",
sub_type="friend",
user_id=123,
message_type="private",
message_id=0,
message=Message("/状态"),
raw_message="/状态",
font=0,
sender=Sender(),
)
ctx.receive_event(bot, event)
ctx.should_call_send(
event,
"\n".join(
[
"CPU:",
" core1: 10%",
" core2: 11%",
"Memory: 10%",
"Disk:",
" test: 00%",
]
),
True,
)