From 429b2ffc896747bc6798dcfe7e12e3ae0cc132f2 Mon Sep 17 00:00:00 2001 From: TEKK Date: Fri, 16 Oct 2026 09:05:18 +0000 Subject: [PATCH] fix(vision): Kameraindex 0 erhalten und hardwarefrei testen --- .../tests/test_camera_selection.py | 85 +++++++++++++++++++ .../beerbot_vision/vision.py | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/tests/test_camera_selection.py diff --git a/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/tests/test_camera_selection.py b/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/tests/test_camera_selection.py new file mode 100644 index 0000000..8577342 --- /dev/null +++ b/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/tests/test_camera_selection.py @@ -0,0 +1,85 @@ +"""Hardware-free constructor regression checks, prepared separately from BeerBot. +These tests are new local review artifacts, not files present in the base commit. +They load the real vision.py and config.py only inside the isolated test container. +""" +import importlib.util +from pathlib import Path +import sys +import types +import unittest +from unittest.mock import patch + +SOURCE = Path(__file__).resolve().parents[1] + +class CameraSelectionTests(unittest.TestCase): + def check_camera(self, requested, expected): + events = [] + forbidden = [] + + def deny(operation): + def blocked(*args, **kwargs): + forbidden.append(operation) + raise AssertionError('External operation forbidden: ' + operation) + return blocked + + cv2 = types.ModuleType('cv2') + for name in ('VideoCapture', 'imshow', 'imwrite', 'waitKey', 'destroyAllWindows'): + setattr(cv2, name, deny('cv2.' + name)) + numpy = types.ModuleType('numpy') + numpy.load = deny('numpy.load') + rpc = types.ModuleType('DobotRPC') + rpc.RPCClient = deny('DobotRPC.RPCClient') + rpc.DobotlinkAdapter = deny('DobotRPC.DobotlinkAdapter') + + class InertModel: + def __init__(self, model_path): + events.append(('inert_model', model_path)) + __call__ = deny('YOLO inference') + predict = deny('YOLO.predict') + train = deny('YOLO.train') + + class InertCalibrator: + def __init__(self): + events.append(('inert_calibrator',)) + + class InertUI: + def __init__(self): + events.append(('inert_ui',)) + + ultralytics = types.ModuleType('ultralytics') + ultralytics.YOLO = InertModel + calibrator = types.ModuleType('calibrator') + calibrator.CameraCalibrator = InertCalibrator + interface = types.ModuleType('user_interface') + interface.ModernUI = InertUI + config_spec = importlib.util.spec_from_file_location('_reviewed_beerbot_config', SOURCE / 'config.py') + config = importlib.util.module_from_spec(config_spec) + config_spec.loader.exec_module(config) + self.assertEqual(config.Config.CAMERA_ID, 1, 'The reviewed base configuration changed') + doubles = {'cv2': cv2, 'numpy': numpy, 'config': config, + 'calibrator': calibrator, 'user_interface': interface, + 'ultralytics': ultralytics, 'DobotRPC': rpc} + with patch.dict(sys.modules, doubles): + spec = importlib.util.spec_from_file_location('_reviewed_beerbot_vision', SOURCE / 'vision.py') + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + # The constructor and camera assignment are actual repository code. + instance = module.BeerBotVision(camera_id=requested, model_path='inert-local-test-model') + self.assertIsNone(instance.cap) + self.assertFalse(instance.camera_initialized) + self.assertEqual(events, [('inert_model', 'inert-local-test-model'), + ('inert_calibrator',), ('inert_ui',)]) + self.assertEqual(forbidden, []) + self.assertEqual(instance.camera_id, expected) + + def test_camera_zero(self): + self.check_camera(0, 0) + + def test_camera_none(self): + self.check_camera(None, 1) + + def test_camera_two(self): + self.check_camera(2, 2) + +if __name__ == '__main__': + unittest.main() diff --git a/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/vision.py b/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/vision.py index 6811200..3a4e7ef 100644 --- a/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/vision.py +++ b/PROJECT_SOURCE_CODE/python_dobot_yolo/beerbot_vision/vision.py @@ -19,7 +19,7 @@ except ImportError: class BeerBotVision: def __init__(self, camera_id=None, model_path=None): - self.camera_id = camera_id or Config.CAMERA_ID + self.camera_id = Config.CAMERA_ID if camera_id is None else camera_id self.model_path = model_path or Config.YOLO_MODEL if YOLO_AVAILABLE: