mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-29 22:24:26 +00:00 
			
		
		
		
	Merge branch 'fix_double_move' into integration
This commit is contained in:
		| @@ -101,3 +101,10 @@ def mock_get_idedata() -> Generator[Mock, None, None]: | ||||
|     """Mock get_idedata for platformio_api.""" | ||||
|     with patch("esphome.platformio_api.get_idedata") as mock: | ||||
|         yield mock | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def mock_get_component() -> Generator[Mock, None, None]: | ||||
|     """Mock get_component for config module.""" | ||||
|     with patch("esphome.config.get_component") as mock: | ||||
|         yield mock | ||||
|   | ||||
							
								
								
									
										10
									
								
								tests/unit_tests/fixtures/auto_load_dynamic.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/unit_tests/fixtures/auto_load_dynamic.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| esphome: | ||||
|   name: test-device | ||||
|  | ||||
| esp32: | ||||
|   board: esp32dev | ||||
|  | ||||
| # Test component with dynamic AUTO_LOAD | ||||
| test_component: | ||||
|   enable_logger: true | ||||
|   enable_api: false | ||||
							
								
								
									
										8
									
								
								tests/unit_tests/fixtures/auto_load_static.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								tests/unit_tests/fixtures/auto_load_static.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| esphome: | ||||
|   name: test-device | ||||
|  | ||||
| esp32: | ||||
|   board: esp32dev | ||||
|  | ||||
| # Test component with static AUTO_LOAD | ||||
| test_component: | ||||
							
								
								
									
										131
									
								
								tests/unit_tests/test_config_auto_load.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								tests/unit_tests/test_config_auto_load.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| """Tests for AUTO_LOAD functionality including dynamic AUTO_LOAD.""" | ||||
|  | ||||
| from pathlib import Path | ||||
| from typing import Any | ||||
| from unittest.mock import Mock | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from esphome import config, config_validation as cv, yaml_util | ||||
| from esphome.core import CORE | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def fixtures_dir() -> Path: | ||||
|     """Get the fixtures directory.""" | ||||
|     return Path(__file__).parent / "fixtures" | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def default_component() -> Mock: | ||||
|     """Create a default mock component for unmocked components.""" | ||||
|     return Mock( | ||||
|         auto_load=[], | ||||
|         is_platform_component=False, | ||||
|         is_platform=False, | ||||
|         multi_conf=False, | ||||
|         multi_conf_no_default=False, | ||||
|         dependencies=[], | ||||
|         conflicts_with=[], | ||||
|         config_schema=cv.Schema({}, extra=cv.ALLOW_EXTRA), | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def static_auto_load_component() -> Mock: | ||||
|     """Create a mock component with static AUTO_LOAD.""" | ||||
|     return Mock( | ||||
|         auto_load=["logger"], | ||||
|         is_platform_component=False, | ||||
|         is_platform=False, | ||||
|         multi_conf=False, | ||||
|         multi_conf_no_default=False, | ||||
|         dependencies=[], | ||||
|         conflicts_with=[], | ||||
|         config_schema=cv.Schema({}, extra=cv.ALLOW_EXTRA), | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def test_static_auto_load_adds_components( | ||||
|     mock_get_component: Mock, | ||||
|     fixtures_dir: Path, | ||||
|     static_auto_load_component: Mock, | ||||
|     default_component: Mock, | ||||
| ) -> None: | ||||
|     """Test that static AUTO_LOAD triggers loading of specified components.""" | ||||
|     CORE.config_path = fixtures_dir / "auto_load_static.yaml" | ||||
|  | ||||
|     config_file = fixtures_dir / "auto_load_static.yaml" | ||||
|     raw_config = yaml_util.load_yaml(config_file) | ||||
|  | ||||
|     component_mocks = {"test_component": static_auto_load_component} | ||||
|     mock_get_component.side_effect = lambda name: component_mocks.get( | ||||
|         name, default_component | ||||
|     ) | ||||
|  | ||||
|     result = config.validate_config(raw_config, {}) | ||||
|  | ||||
|     # Check for validation errors | ||||
|     assert not result.errors, f"Validation errors: {result.errors}" | ||||
|  | ||||
|     # Logger should have been auto-loaded by test_component | ||||
|     assert "logger" in result | ||||
|     assert "test_component" in result | ||||
|  | ||||
|  | ||||
| def test_dynamic_auto_load_with_config_param( | ||||
|     mock_get_component: Mock, | ||||
|     fixtures_dir: Path, | ||||
|     default_component: Mock, | ||||
| ) -> None: | ||||
|     """Test that dynamic AUTO_LOAD evaluates based on configuration.""" | ||||
|     CORE.config_path = fixtures_dir / "auto_load_dynamic.yaml" | ||||
|  | ||||
|     config_file = fixtures_dir / "auto_load_dynamic.yaml" | ||||
|     raw_config = yaml_util.load_yaml(config_file) | ||||
|  | ||||
|     # Track if auto_load was called with config | ||||
|     auto_load_calls = [] | ||||
|  | ||||
|     def dynamic_auto_load(conf: dict[str, Any]) -> list[str]: | ||||
|         """Dynamically load components based on config.""" | ||||
|         auto_load_calls.append(conf) | ||||
|         component_map = { | ||||
|             "enable_logger": "logger", | ||||
|             "enable_api": "api", | ||||
|         } | ||||
|         return [comp for key, comp in component_map.items() if conf.get(key)] | ||||
|  | ||||
|     dynamic_component = Mock( | ||||
|         auto_load=dynamic_auto_load, | ||||
|         is_platform_component=False, | ||||
|         is_platform=False, | ||||
|         multi_conf=False, | ||||
|         multi_conf_no_default=False, | ||||
|         dependencies=[], | ||||
|         conflicts_with=[], | ||||
|         config_schema=cv.Schema({}, extra=cv.ALLOW_EXTRA), | ||||
|     ) | ||||
|  | ||||
|     component_mocks = {"test_component": dynamic_component} | ||||
|     mock_get_component.side_effect = lambda name: component_mocks.get( | ||||
|         name, default_component | ||||
|     ) | ||||
|  | ||||
|     result = config.validate_config(raw_config, {}) | ||||
|  | ||||
|     # Check for validation errors | ||||
|     assert not result.errors, f"Validation errors: {result.errors}" | ||||
|  | ||||
|     # Verify auto_load was called with the validated config | ||||
|     assert len(auto_load_calls) == 1, "auto_load should be called exactly once" | ||||
|     assert auto_load_calls[0].get("enable_logger") is True | ||||
|     assert auto_load_calls[0].get("enable_api") is False | ||||
|  | ||||
|     # Only logger should be auto-loaded (enable_logger=true in YAML) | ||||
|     assert "logger" in result, ( | ||||
|         f"Logger not found in result. Result keys: {list(result.keys())}" | ||||
|     ) | ||||
|     # API should NOT be auto-loaded (enable_api=false in YAML) | ||||
|     assert "api" not in result | ||||
|     assert "test_component" in result | ||||
| @@ -10,13 +10,6 @@ from esphome import config, yaml_util | ||||
| from esphome.core import CORE | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def mock_get_component() -> Generator[Mock, None, None]: | ||||
|     """Fixture for mocking get_component.""" | ||||
|     with patch("esphome.config.get_component") as mock_get_component: | ||||
|         yield mock_get_component | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def mock_get_platform() -> Generator[Mock, None, None]: | ||||
|     """Fixture for mocking get_platform.""" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user