#!/usr/bin/env python3 """Runner for Kindred Create addon tests. Tier 1 (pure logic) tests run with the system Python — no FreeCAD binary required. Tier 2 (FreeCAD headless) tests are skipped unless FreeCADCmd is found on PATH. Usage: python3 tests/run_kindred_tests.py # Tier 1 only python3 tests/run_kindred_tests.py --all # Tier 1 + Tier 2 (needs FreeCADCmd) Exit codes: 0 All tests passed 1 One or more tests failed """ import os import shutil import subprocess import sys import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent def run_pure_tests() -> bool: """Discover and run Tier 1 pure-logic tests. Returns True on success.""" loader = unittest.TestLoader() suite = loader.discover( start_dir=str(REPO_ROOT / "tests"), pattern="test_kindred_pure.py", top_level_dir=str(REPO_ROOT / "tests"), ) runner = unittest.TextTestRunner(verbosity=2) result = runner.run(suite) return result.wasSuccessful() def run_freecad_tests() -> bool: """Run Tier 2 tests inside FreeCADCmd. Returns True on success.""" freecad_cmd = shutil.which("FreeCADCmd") if not freecad_cmd: # Check build directories for candidate in ( REPO_ROOT / "build" / "debug" / "bin" / "FreeCADCmd", REPO_ROOT / "build" / "release" / "bin" / "FreeCADCmd", ): if candidate.exists(): freecad_cmd = str(candidate) break if not freecad_cmd: print("\n[SKIP] FreeCADCmd not found — skipping Tier 2 tests") return True # Not a failure, just skipped print(f"\n{'=' * 70}") print(f"Tier 2: FreeCAD headless tests via {freecad_cmd}") print(f"{'=' * 70}\n") # Tier 2 test modules registered via FreeCAD.__unit_test__ test_modules = ["TestKindredCreate"] all_ok = True for mod in test_modules: print(f"--- Running {mod} ---") proc = subprocess.run( [freecad_cmd, "-t", mod], cwd=str(REPO_ROOT), timeout=120, ) if proc.returncode != 0: all_ok = False return all_ok def main(): os.chdir(REPO_ROOT) run_all = "--all" in sys.argv print(f"{'=' * 70}") print("Tier 1: Pure-logic tests (no FreeCAD binary required)") print(f"{'=' * 70}\n") tier1_ok = run_pure_tests() tier2_ok = True if run_all: tier2_ok = run_freecad_tests() print(f"\n{'=' * 70}") print(f" Tier 1 (pure): {'PASS' if tier1_ok else 'FAIL'}") if run_all: print(f" Tier 2 (FreeCAD): {'PASS' if tier2_ok else 'FAIL'}") print(f"{'=' * 70}") sys.exit(0 if (tier1_ok and tier2_ok) else 1) if __name__ == "__main__": main()