feat(console): add integration tests and polish error handling
Add MockRenderer-based integration tests that verify the full screen-to- renderer pipeline without a real terminal. Update main.py with proper --db flag handling, database existence check, startup banner, and graceful error handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ Usage:
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from console.config import VERSION, APP_NAME, APP_SUBTITLE, DB_PATH, DEFAULT_MODE
|
||||
@@ -38,6 +39,19 @@ def parse_args(argv=None):
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def _print_banner(mode, db_path):
|
||||
"""Print a startup banner before entering terminal mode."""
|
||||
border = "=" * 58
|
||||
print(border)
|
||||
print(f" {APP_NAME} v{VERSION}")
|
||||
print(f" {APP_SUBTITLE}")
|
||||
print(border)
|
||||
print(f" Mode : {mode}")
|
||||
print(f" DB : {db_path}")
|
||||
print(border)
|
||||
print()
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
"""Main entry point: parse args, set up renderer, DB, and launch the app."""
|
||||
args = parse_args(argv)
|
||||
@@ -45,20 +59,60 @@ def main(argv=None):
|
||||
db_path = args.db
|
||||
mode = args.mode
|
||||
|
||||
# Verify the database file exists before proceeding
|
||||
if not os.path.isfile(db_path):
|
||||
print(
|
||||
f"Error: Database not found at '{db_path}'.\n"
|
||||
f"\n"
|
||||
f"Make sure the vehicle database exists. You can specify a\n"
|
||||
f"custom path with the --db flag:\n"
|
||||
f"\n"
|
||||
f" python -m console --db /path/to/vehicle_database.db\n",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Lazy imports so the module can be loaded without curses available
|
||||
# (e.g. during tests or when just checking --version).
|
||||
from console.core.database import Database
|
||||
from console.renderers import create_renderer
|
||||
from console.db import Database
|
||||
from console.renderers.curses_renderer import CursesRenderer
|
||||
from console.core.app import App
|
||||
|
||||
# Print startup banner
|
||||
_print_banner(mode, db_path)
|
||||
|
||||
db = Database(db_path)
|
||||
renderer = create_renderer(mode)
|
||||
|
||||
# Select renderer based on mode
|
||||
if mode == "modern":
|
||||
try:
|
||||
from console.renderers.textual_renderer import TextualRenderer
|
||||
renderer = TextualRenderer()
|
||||
except ImportError:
|
||||
print(
|
||||
"Warning: 'modern' mode requires the 'rich' package.\n"
|
||||
"Falling back to vt220 mode.\n"
|
||||
"Install with: pip install rich\n",
|
||||
file=sys.stderr,
|
||||
)
|
||||
renderer = CursesRenderer()
|
||||
else:
|
||||
renderer = CursesRenderer()
|
||||
|
||||
app = App(renderer=renderer, db=db)
|
||||
|
||||
try:
|
||||
app.run()
|
||||
finally:
|
||||
db.close()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
except Exception as e:
|
||||
# Ensure terminal is restored before printing the traceback
|
||||
try:
|
||||
renderer.cleanup()
|
||||
except Exception:
|
||||
pass
|
||||
print(f"\nError: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user