mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-25 13:13:48 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """Fixtures for component tests."""
 | |
| 
 | |
| from __future__ import annotations
 | |
| 
 | |
| from collections.abc import Callable, Generator
 | |
| from pathlib import Path
 | |
| import sys
 | |
| from typing import Any
 | |
| 
 | |
| import pytest
 | |
| 
 | |
| from esphome import config, final_validate
 | |
| from esphome.const import (
 | |
|     KEY_CORE,
 | |
|     KEY_TARGET_FRAMEWORK,
 | |
|     KEY_TARGET_PLATFORM,
 | |
|     PlatformFramework,
 | |
| )
 | |
| from esphome.types import ConfigType
 | |
| 
 | |
| # Add package root to python path
 | |
| here = Path(__file__).parent
 | |
| package_root = here.parent.parent
 | |
| sys.path.insert(0, package_root.as_posix())
 | |
| 
 | |
| from esphome.__main__ import generate_cpp_contents  # noqa: E402
 | |
| from esphome.config import Config, read_config  # noqa: E402
 | |
| from esphome.core import CORE  # noqa: E402
 | |
| 
 | |
| from .types import SetCoreConfigCallable  # noqa: E402
 | |
| 
 | |
| 
 | |
| @pytest.fixture(autouse=True)
 | |
| def config_path(request: pytest.FixtureRequest) -> Generator[None]:
 | |
|     """Set CORE.config_path to the component's config directory and reset it after the test."""
 | |
|     original_path = CORE.config_path
 | |
|     config_dir = Path(request.fspath).parent / "config"
 | |
| 
 | |
|     # Check if config directory exists, if not use parent directory
 | |
|     if config_dir.exists():
 | |
|         # Set config_path to a dummy yaml file in the config directory
 | |
|         # This ensures CORE.config_dir points to the config directory
 | |
|         CORE.config_path = str(config_dir / "dummy.yaml")
 | |
|     else:
 | |
|         CORE.config_path = str(Path(request.fspath).parent / "dummy.yaml")
 | |
| 
 | |
|     yield
 | |
|     CORE.config_path = original_path
 | |
| 
 | |
| 
 | |
| @pytest.fixture(autouse=True)
 | |
| def reset_core() -> Generator[None]:
 | |
|     """Reset CORE after each test."""
 | |
|     yield
 | |
|     CORE.reset()
 | |
| 
 | |
| 
 | |
| @pytest.fixture
 | |
| def set_core_config() -> Generator[SetCoreConfigCallable]:
 | |
|     """Fixture to set up the core configuration for tests."""
 | |
| 
 | |
|     def setter(
 | |
|         platform_framework: PlatformFramework,
 | |
|         /,
 | |
|         *,
 | |
|         core_data: ConfigType | None = None,
 | |
|         platform_data: ConfigType | None = None,
 | |
|         full_config: dict[str, ConfigType] | None = None,
 | |
|     ) -> None:
 | |
|         platform, framework = platform_framework.value
 | |
| 
 | |
|         # Set base core configuration
 | |
|         CORE.data[KEY_CORE] = {
 | |
|             KEY_TARGET_PLATFORM: platform.value,
 | |
|             KEY_TARGET_FRAMEWORK: framework.value,
 | |
|         }
 | |
| 
 | |
|         # Update with any additional core data
 | |
|         if core_data:
 | |
|             CORE.data[KEY_CORE].update(core_data)
 | |
| 
 | |
|         # Set platform-specific data
 | |
|         if platform_data:
 | |
|             CORE.data[platform.value] = platform_data
 | |
| 
 | |
|         config.path_context.set([])
 | |
|         final_validate.full_config.set(full_config or Config())
 | |
| 
 | |
|     yield setter
 | |
| 
 | |
| 
 | |
| @pytest.fixture
 | |
| def set_component_config() -> Callable[[str, Any], None]:
 | |
|     """
 | |
|     Fixture to set a component configuration in the mock config.
 | |
|     This must be used after the core configuration has been set up.
 | |
|     """
 | |
| 
 | |
|     def setter(name: str, value: Any) -> None:
 | |
|         final_validate.full_config.get()[name] = value
 | |
| 
 | |
|     return setter
 | |
| 
 | |
| 
 | |
| @pytest.fixture
 | |
| def component_fixture_path(request: pytest.FixtureRequest) -> Callable[[str], Path]:
 | |
|     """Return a function to get absolute paths relative to the component's fixtures directory."""
 | |
| 
 | |
|     def _get_path(file_name: str) -> Path:
 | |
|         """Get the absolute path of a file relative to the component's fixtures directory."""
 | |
|         return (Path(request.fspath).parent / "fixtures" / file_name).absolute()
 | |
| 
 | |
|     return _get_path
 | |
| 
 | |
| 
 | |
| @pytest.fixture
 | |
| def component_config_path(request: pytest.FixtureRequest) -> Callable[[str], Path]:
 | |
|     """Return a function to get absolute paths relative to the component's config directory."""
 | |
| 
 | |
|     def _get_path(file_name: str) -> Path:
 | |
|         """Get the absolute path of a file relative to the component's config directory."""
 | |
|         return (Path(request.fspath).parent / "config" / file_name).absolute()
 | |
| 
 | |
|     return _get_path
 | |
| 
 | |
| 
 | |
| @pytest.fixture
 | |
| def generate_main() -> Generator[Callable[[str | Path], str]]:
 | |
|     """Generates the C++ main.cpp from a given yaml file and returns it in string form."""
 | |
| 
 | |
|     def generator(path: str | Path) -> str:
 | |
|         CORE.config_path = str(path)
 | |
|         CORE.config = read_config({})
 | |
|         generate_cpp_contents(CORE.config)
 | |
|         return CORE.cpp_main_section
 | |
| 
 | |
|     yield generator
 |