From 8caa526727d3c6e0b68cacdb5027cb6be46a90a3 Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Fri, 15 May 2026 18:01:30 +0000 Subject: [PATCH] test(strategy_crypto): smoke regression + import-mode importlib per workspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NEW src/strategy_crypto/tests/test_imports.py: - test_backend_imports — verifica re-export PaperExecutor/Portfolio/PaperRepository + schema - test_frontend_imports — strategy_crypto.frontend.{data,nicegui_app} importabili - test_strategies_json_loadable — i JSON sono in importlib.resources e ben formati - test_init_schema_creates_tables — PaperRepository.init_schema() crea 5 tabelle Fix pytest collection: add --import-mode=importlib agli addopts per evitare collisione dei due tests/__init__.py (core + strategy_crypto) sotto stesso nome module 'tests'. Verifica: uv run pytest → 186 passed (182 core + 4 strategy_crypto) Co-Authored-By: Claude Opus 4.7 (1M context) --- pyproject.toml | 2 +- src/strategy_crypto/tests/test_imports.py | 67 +++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/strategy_crypto/tests/test_imports.py diff --git a/pyproject.toml b/pyproject.toml index a7cc6a9..756c244 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ strict = true [tool.pytest.ini_options] testpaths = ["src/multi_swarm_core/tests", "src/strategy_crypto/tests"] -addopts = "-v --tb=short" +addopts = "-v --tb=short --import-mode=importlib" markers = [ "integration: tests that require external services (Cerbero, LLM API)", "slow: tests that take more than 5 seconds", diff --git a/src/strategy_crypto/tests/test_imports.py b/src/strategy_crypto/tests/test_imports.py new file mode 100644 index 0000000..c606949 --- /dev/null +++ b/src/strategy_crypto/tests/test_imports.py @@ -0,0 +1,67 @@ +"""Smoke regression: il package strategy_crypto importa senza errori +e i JSON freezate sono accessibili via importlib.resources. + +Sostituisce la responsabilita' di un test di integrazione: serve solo +a catturare regressioni di import/packaging dopo refactor cross-modulo. +""" + +from __future__ import annotations + +import importlib.resources +import json + + +def test_backend_imports() -> None: + from strategy_crypto.backend import ( + PaperExecutor, + PaperRepository, + Portfolio, + ) + from strategy_crypto.backend.schema import PAPER_SCHEMA_SQL, init_schema + + assert PaperExecutor.__name__ == "PaperExecutor" + assert PaperRepository.__name__ == "PaperRepository" + assert Portfolio.__name__ == "Portfolio" + assert "CREATE TABLE" in PAPER_SCHEMA_SQL + assert callable(init_schema) + + +def test_frontend_imports() -> None: + import strategy_crypto.frontend.data # noqa: F401 + import strategy_crypto.frontend.nicegui_app # noqa: F401 + + +def test_strategies_json_loadable() -> None: + files = importlib.resources.files("strategy_crypto") / "strategies" + found = sorted(p.name for p in files.iterdir() if p.name.endswith(".json")) + assert "btc_fb63e851.json" in found + assert "eth_facd6af85d5d.json" in found + for fname in found: + data = json.loads((files / fname).read_text()) + assert "rules" in data, f"{fname} missing 'rules' key" + assert isinstance(data["rules"], list) + + +def test_init_schema_creates_tables(tmp_path) -> None: + import sqlite3 + + from strategy_crypto.backend.schema import init_schema + + db = tmp_path / "paper.db" + init_schema(db) + conn = sqlite3.connect(str(db)) + try: + rows = conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'paper_%'" + ).fetchall() + names = {r[0] for r in rows} + finally: + conn.close() + expected = { + "paper_trading_runs", + "paper_trading_positions", + "paper_trading_trades", + "paper_trading_equity", + "paper_trading_ticks", + } + assert expected.issubset(names), f"missing tables: {expected - names}"