Files
2026-10-15 17:21:05 +08:00

148 lines
5.2 KiB
Python

import ast
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
class PackagingTests(unittest.TestCase):
def test_core_has_no_framework_imports_and_uses_python310_syntax(self):
for path in (
* (ROOT / "src/farm_core").glob("*.py"),
* (ROOT / "src/farm_render").glob("*.py"),
):
self.assertTrue(all(
len(line) <= 80
for line in path.read_text(encoding="utf-8").splitlines()
), path.name)
tree = ast.parse(
path.read_text(encoding="utf-8"), feature_version=(3, 10),
)
for node in ast.walk(tree):
names = []
if isinstance(node, ast.Import):
names = [alias.name for alias in node.names]
if isinstance(node, ast.ImportFrom) and node.level == 0:
names = [node.module or ""]
self.assertFalse(
any(name.split(".")[0] in (
"nonebot", "astrbot", "zhenxun",
) for name in names),
path.name,
)
def test_import_has_no_runtime_files_or_background_threads(self):
code = (
"import os,sys,threading; "
"before=set(os.listdir('.')); "
"threads=len(threading.enumerate()); "
"sys.path.insert(0,sys.argv[1]); import farm_core; "
"assert set(os.listdir('.'))==before; "
"assert len(threading.enumerate())==threads"
)
with tempfile.TemporaryDirectory(
prefix="farm-import-test-",
) as temporary:
subprocess.run(
[sys.executable, "-I", "-B", "-c", code, str(ROOT / "src")],
cwd=temporary, check=True, timeout=30,
)
def test_wheel_runs_without_source_legacy_or_frameworks(self):
with tempfile.TemporaryDirectory(
prefix="farm-wheel-test-",
) as temporary:
temporary = Path(temporary).resolve()
self.assertTrue(temporary.is_relative_to(
Path(tempfile.gettempdir()).resolve()
))
wheels = temporary / "wheels"
installed = temporary / "installed"
self.run_checked([
sys.executable, "-m", "pip", "--disable-pip-version-check",
"wheel", "--no-index", "--no-deps", "--no-build-isolation",
"--wheel-dir", str(wheels), str(ROOT),
])
wheel, = wheels.glob("farm_core-*.whl")
self.run_checked([
sys.executable, "-m", "pip", "--disable-pip-version-check",
"install", "--no-index", "--no-deps", "--no-compile",
"--target", str(installed), str(wheel),
])
code = """
import asyncio
from pathlib import Path
import sys
target = Path(sys.argv[1])
sys.path.insert(0, str(target))
import farm_core
from farm_core import Catalogue, FarmService, Identity, SQLiteStore
from farm_render import FarmRenderer, RenderOptions
from PIL import Image
from io import BytesIO
assert Path(farm_core.__file__).is_relative_to(target)
assert len(Catalogue.bundled()) == 202
async def check():
store = SQLiteStore(sys.argv[2])
await store.initialize()
try:
service = FarmService(store, Catalogue.bundled(), lambda: 0)
who = Identity("installed", "local", "local", "user")
registered = await service.register(who, "installed", "register")
assert registered.data["account"]["point"] == 500
plant = next(
p for p in service.catalogue
if p.level == 0 and not p.is_vip and p.cost <= 500
)
await service.buy(who, plant.name, 1, "buy")
assert (await service.snapshot(who)).inventory[0].seeds == 1
font = Path(sys.argv[3])
renderer = FarmRenderer(font)
assert len(renderer.assets.metadata["images"]) > 600
result = renderer.render(
who, await service.snapshot(who), 0,
RenderOptions(format="PNG"),
)
assert Image.open(BytesIO(result.content)).size == (1024, 624)
finally:
await store.close()
asyncio.run(check())
"""
self.run_checked(
[
sys.executable, "-I", "-B", "-c", code, str(installed),
str(temporary / "installed.sqlite3"),
str(Path(os.environ.get(
"FARM_TEST_FONT", (
"C:/Windows/Fonts/msyh.ttc" if os.name == "nt"
else "/usr/share/fonts/truetype/"
"dejavu/DejaVuSans.ttf"
),
))),
],
cwd=temporary,
)
def run_checked(self, command, cwd=ROOT):
result = subprocess.run(
command, cwd=cwd, capture_output=True, text=True,
encoding="utf-8", errors="replace", timeout=90,
env={**os.environ, "PIP_NO_INDEX": "1"},
)
self.assertEqual(
result.returncode, 0, result.stdout + result.stderr,
)
if __name__ == "__main__":
unittest.main()