"""Tests for the private OpenCV facade.""" from __future__ import annotations import importlib import subprocess import sys import numpy as np import pytest from supervision import _cv2 try: cv2 = importlib.import_module("cv2") except (ImportError, OSError): pytest.skip( "OpenCV is required as the reference implementation for this test module", allow_module_level=True, ) REQUIRED_SYMBOLS = { "VideoCapture", "VideoWriter", "VideoWriter_fourcc", "addWeighted", "approxPolyDP", "blur", "circle", "connectedComponents", "connectedComponentsWithStats", "contourArea", "convertScaleAbs", "copyMakeBorder", "cvtColor", "drawContours", "ellipse", "fillPoly", "find_contours", "flip", "getTextSize", "imread", "imwrite", "intersectConvexConvex", "line", "mean", "merge", "polylines", "putText", "rectangle", "resize", "split", } @pytest.mark.parametrize( "symbol", [ pytest.param(symbol, id=symbol.lower().replace("_", "-")) for symbol in sorted(REQUIRED_SYMBOLS) ], ) def test_facade_exports_required_opencv_symbol(symbol: str) -> None: """Expose each OpenCV symbol used by production call sites.""" assert symbol in _cv2.__all__ assert hasattr(_cv2, symbol) def test_facade_reports_opencv_backend() -> None: """Report OpenCV when the native backend is available.""" assert _cv2.BACKEND_NAME == "opencv" def test_facade_routes_color_calls_to_opencv() -> None: """Route color conversion calls through the Supervision facade.""" image = np.array([[[10, 20, 30], [40, 50, 60]]], dtype=np.uint8) np.testing.assert_array_equal( _cv2.cvtColor(image, _cv2.COLOR_BGR2RGB), cv2.cvtColor(image, cv2.COLOR_BGR2RGB), ) def test_facade_routes_resize_calls_to_opencv() -> None: """Route resize calls through the Supervision facade.""" image = np.array([[[10, 20, 30], [40, 50, 60]]], dtype=np.uint8) np.testing.assert_array_equal( _cv2.resize(image, (4, 2), interpolation=_cv2.INTER_NEAREST), cv2.resize(image, (4, 2), interpolation=cv2.INTER_NEAREST), ) def test_facade_does_not_hide_a_breaking_opencv_import() -> None: """Raise when cv2 imports but no longer exposes a required symbol.""" code = """ import sys import types sys.modules["cv2"] = types.ModuleType("cv2") from supervision import _cv2 """ result = subprocess.run( [sys.executable, "-c", code], capture_output=True, text=True, ) assert result.returncode != 0 assert "cannot import name" in result.stderr