Merge pull request 'fix(vision): Kameraindex 0 erhalten und hardwarefrei testen' (#1) from auron/beerbot-camera-0-6529edad into main

This commit was merged in pull request #1.
This commit is contained in:
2026-10-17 10:11:46 +00:00
2 changed files with 86 additions and 1 deletions

View File

@@ -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()

View File

@@ -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: