100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
"""
|
|
GUI smoke tests — headless PySide6 (QT_QPA_PLATFORM=offscreen).
|
|
Verifies that all modules import and core widgets instantiate without crashing.
|
|
No network calls, no DB, no real data.
|
|
|
|
Run automatically via PostToolUse hook on every edit to screener_gui.py.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).parent.parent
|
|
DIST_DIR = PROJECT_ROOT / "dist"
|
|
PYTHON = sys.executable
|
|
|
|
|
|
def _run(code: str) -> subprocess.CompletedProcess:
|
|
"""Run Python code in a subprocess with offscreen Qt platform."""
|
|
env = os.environ.copy()
|
|
env["QT_QPA_PLATFORM"] = "offscreen"
|
|
return subprocess.run(
|
|
[PYTHON, "-c", code],
|
|
capture_output=True,
|
|
text=True,
|
|
cwd=str(DIST_DIR),
|
|
env=env,
|
|
timeout=30,
|
|
)
|
|
|
|
|
|
def test_stock_screener_imports():
|
|
"""stock_screener.py imports and exposes expected symbols."""
|
|
result = _run("""
|
|
import stock_screener as ss
|
|
required = [
|
|
'compute_value_score', 'compute_quality_score',
|
|
'compute_growth_score', 'compute_profitability_score',
|
|
'compute_sentiment_score', 'score_stocks',
|
|
'STRATEGY_PRESETS', 'WEIGHTS',
|
|
]
|
|
missing = [s for s in required if not hasattr(ss, s)]
|
|
assert not missing, f"Missing symbols: {missing}"
|
|
print("SCREENER_OK")
|
|
""")
|
|
assert "SCREENER_OK" in result.stdout, f"stock_screener import failed:\n{result.stderr}"
|
|
|
|
|
|
def test_screener_gui_imports():
|
|
"""screener_gui.py imports without error (PySide6, matplotlib, etc.)."""
|
|
result = _run("""
|
|
from PySide6.QtWidgets import QApplication
|
|
import sys
|
|
app = QApplication(sys.argv)
|
|
import screener_gui
|
|
print("GUI_IMPORT_OK")
|
|
""")
|
|
assert "GUI_IMPORT_OK" in result.stdout, (
|
|
f"screener_gui import failed:\n{result.stderr[-2000:]}"
|
|
)
|
|
|
|
|
|
def test_stock_table_model():
|
|
"""StockTableModel can be created and populated via set_data."""
|
|
result = _run("""
|
|
import sys
|
|
from PySide6.QtWidgets import QApplication
|
|
app = QApplication(sys.argv)
|
|
from screener_gui import StockTableModel
|
|
model = StockTableModel()
|
|
assert model.rowCount() == 0
|
|
model.set_data([("AAPL", "Apple Inc", 82.5, "Technology")])
|
|
assert model.rowCount() == 1
|
|
assert model.columnCount() == 5
|
|
print("TABLE_MODEL_OK")
|
|
""")
|
|
assert "TABLE_MODEL_OK" in result.stdout, (
|
|
f"StockTableModel test failed:\n{result.stderr[-2000:]}"
|
|
)
|
|
|
|
|
|
def test_screener_app_instantiates():
|
|
"""ScreenerApp (main window) instantiates without crashing."""
|
|
result = _run("""
|
|
import sys
|
|
from PySide6.QtWidgets import QApplication
|
|
app = QApplication(sys.argv)
|
|
from screener_gui import ScreenerApp
|
|
win = ScreenerApp()
|
|
# Verify expected attributes exist
|
|
assert hasattr(win, '_screener_page')
|
|
assert hasattr(win, '_search_page')
|
|
assert hasattr(win, '_sidebar')
|
|
print("APP_OK")
|
|
""")
|
|
assert "APP_OK" in result.stdout, (
|
|
f"ScreenerApp instantiation failed:\n{result.stderr[-2000:]}"
|
|
)
|