Skip to content

Commit

Permalink
✨ Feature: 优化自动获取插件名并添加测试 (#27)
Browse files Browse the repository at this point in the history
Co-authored-by: Ju4tCode <[email protected]>
  • Loading branch information
he0119 and yanyongyu authored Aug 3, 2024
1 parent b829d05 commit 6864231
Show file tree
Hide file tree
Showing 10 changed files with 587 additions and 59 deletions.
1 change: 0 additions & 1 deletion .github/actions/setup-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ runs:
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
architecture: "x64"
cache: "poetry"

- run: poetry install
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Code Coverage

on:
push:
branches:
- "main"
pull_request:

jobs:
test:
name: Test Coverage
runs-on: ${{ matrix.os }}
concurrency:
group: test-coverage-${{ github.ref }}-${{ matrix.os }}-${{ matrix.python-version }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest, macos-latest]
env:
OS: ${{ matrix.os }}
PYTHON_VERSION: ${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4

- name: Setup Python environment
uses: ./.github/actions/setup-python
with:
python-version: ${{ matrix.python-version }}

- name: Run Pytest
run: |
poetry run pytest -n auto --cov-append --cov-report xml
- name: Upload coverage report
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS,PYTHON_VERSION
28 changes: 13 additions & 15 deletions nonebot_plugin_localstore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,31 @@ def get_data_file(plugin_name: Optional[str], filename: str) -> Path:
return get_data_dir(plugin_name) / filename


def _get_caller_plugin(depth: int = 0) -> Optional[Plugin]:
def _get_caller_plugin() -> Optional[Plugin]:
current_frame = inspect.currentframe()
if current_frame is None:
return None

# skip depth of frames
frame = current_frame
while depth > 0:
frame = frame.f_back
if frame is None:
raise ValueError("Depth out of range")
depth -= 1

# find plugin
frame = current_frame
while frame := frame.f_back:
module_name = (module := inspect.getmodule(frame)) and module.__name__
if module_name is None:
return None

if plugin := get_plugin_by_module_name(module_name):
# skip nonebot_plugin_localstore it self
if module_name.split(".", maxsplit=1)[0] == "nonebot_plugin_localstore":
continue

plugin = get_plugin_by_module_name(module_name)
if plugin and plugin.id_ != "nonebot_plugin_localstore":
return plugin

return None


def _try_get_caller_plugin(depth: int = 0) -> Plugin:
if plugin := _get_caller_plugin(depth + 1):
def _try_get_caller_plugin() -> Plugin:
if plugin := _get_caller_plugin():
return plugin
raise RuntimeError("Cannot detect caller plugin")

Expand All @@ -131,7 +129,7 @@ def _get_plugin_path(base_dir: Path, plugin: Plugin) -> Path:

@_auto_create_dir
def get_plugin_cache_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_CACHE_DIR, plugin)


Expand All @@ -141,7 +139,7 @@ def get_plugin_cache_file(filename: str) -> Path:

@_auto_create_dir
def get_plugin_config_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_CONFIG_DIR, plugin)


Expand All @@ -151,7 +149,7 @@ def get_plugin_config_file(filename: str) -> Path:

@_auto_create_dir
def get_plugin_data_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_DATA_DIR, plugin)


Expand Down
464 changes: 421 additions & 43 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ pydantic = ">=1.10.0,<3.0.0,!=2.5.0,!=2.5.1"
ruff = "^0.5.0"
isort = "^5.10.1"
black = "^24.0.0"
nonebug = "^0.3.7"
nonemoji = "^0.1.2"
pre-commit = "^3.5.0"
pytest-cov = "^5.0.0"
pytest-xdist = "^3.6.1"

[tool.poetry.plugins.nb_scripts]
localstore = "nonebot_plugin_localstore.script:main"

[tool.pytest.ini_options]
addopts = "--cov=./nonebot_plugin_localstore --cov-report=term-missing"

[tool.black]
line-length = 88
target-version = ["py39", "py310", "py311", "py312"]
Expand Down
27 changes: 27 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path

import pytest
import nonebot
from nonebug import NONEBOT_INIT_KWARGS


def pytest_configure(config: pytest.Config) -> None:
config.stash[NONEBOT_INIT_KWARGS] = {"driver": "~none"}


@pytest.fixture(scope="session")
def tmp_path(tmp_path_factory: pytest.TempPathFactory) -> Path:
return tmp_path_factory.mktemp("nonebot_plugin_localstore")


@pytest.fixture(scope="session", autouse=True)
def _load_plugin(nonebug_init: None, tmp_path: Path):
nonebot.load_plugin("nonebot_plugin_localstore")

with pytest.MonkeyPatch.context() as m:
m.setattr("nonebot_plugin_localstore.BASE_DATA_DIR", tmp_path / "data")
m.setattr("nonebot_plugin_localstore.BASE_CACHE_DIR", tmp_path / "cache")
m.setattr("nonebot_plugin_localstore.BASE_CONFIG_DIR", tmp_path / "config")

nonebot.load_plugin("tests.plugin")
yield
23 changes: 23 additions & 0 deletions tests/plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pathlib import Path

import nonebot

from nonebot_plugin_localstore import (
get_plugin_data_dir,
get_plugin_cache_dir,
get_plugin_data_file,
get_plugin_cache_file,
get_plugin_config_dir,
get_plugin_config_file,
)

data_dir = get_plugin_data_dir()
cache_dir = get_plugin_cache_dir()
config_dir = get_plugin_config_dir()

data_file = get_plugin_data_file("data_file")
cache_file = get_plugin_cache_file("cache_file")
config_file = get_plugin_config_file("config_file")

_sub_plugins = set()
_sub_plugins |= nonebot.load_plugins(str((Path(__file__).parent / "plugins").resolve()))
16 changes: 16 additions & 0 deletions tests/plugin/plugins/sub_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from nonebot_plugin_localstore import (
get_plugin_data_dir,
get_plugin_cache_dir,
get_plugin_data_file,
get_plugin_cache_file,
get_plugin_config_dir,
get_plugin_config_file,
)

data_dir = get_plugin_data_dir()
cache_dir = get_plugin_cache_dir()
config_dir = get_plugin_config_dir()

data_file = get_plugin_data_file("data_file")
cache_file = get_plugin_cache_file("cache_file")
config_file = get_plugin_config_file("config_file")
23 changes: 23 additions & 0 deletions tests/test_get_plugin_dir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pathlib import Path


def test_plugin_dir(tmp_path: Path):
from tests.plugin import data_dir, cache_dir, config_dir

assert data_dir == tmp_path / "data" / "plugin"
assert data_dir.is_dir()
assert cache_dir == tmp_path / "cache" / "plugin"
assert cache_dir.is_dir()
assert config_dir == tmp_path / "config" / "plugin"
assert config_dir.is_dir()


def test_sub_plugin_dir(tmp_path: Path):
from tests.plugin.plugins.sub_plugin import data_dir, cache_dir, config_dir

assert data_dir == tmp_path / "data" / "plugin" / "sub_plugin"
assert data_dir.is_dir()
assert cache_dir == tmp_path / "cache" / "plugin" / "sub_plugin"
assert cache_dir.is_dir()
assert config_dir == tmp_path / "config" / "plugin" / "sub_plugin"
assert config_dir.is_dir()
17 changes: 17 additions & 0 deletions tests/test_get_plugin_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from pathlib import Path


def test_plugin_file(tmp_path: Path):
from tests.plugin import data_file, cache_file, config_file

assert data_file == tmp_path / "data" / "plugin" / "data_file"
assert cache_file == tmp_path / "cache" / "plugin" / "cache_file"
assert config_file == tmp_path / "config" / "plugin" / "config_file"


def test_sub_plugin_file(tmp_path: Path):
from tests.plugin.plugins.sub_plugin import data_file, cache_file, config_file

assert data_file == tmp_path / "data" / "plugin" / "sub_plugin" / "data_file"
assert cache_file == tmp_path / "cache" / "plugin" / "sub_plugin" / "cache_file"
assert config_file == tmp_path / "config" / "plugin" / "sub_plugin" / "config_file"

0 comments on commit 6864231

Please sign in to comment.