c7998de8bb
- config_from_env_py_infra: dataclass + field metadata, tipos str/int/float/bool/list - dotenv_load_py_infra: parser .env con semantica de no-sobreescritura - 15 tests unitarios Python, todos PASS - registry.db actualizado con fn index (685 funciones, 109 tipos) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
93 lines
2.3 KiB
Python
93 lines
2.3 KiB
Python
"""Tests para config_from_env."""
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
|
|
import pytest
|
|
|
|
from config_from_env import config_from_env
|
|
|
|
|
|
@dataclass
|
|
class SimpleConfig:
|
|
host: str = field(default="localhost", metadata={"env": "CFE_PY_HOST", "default": "localhost"})
|
|
port: int = field(default=8080, metadata={"env": "CFE_PY_PORT", "default": "8080"})
|
|
debug: bool = field(default=False, metadata={"env": "CFE_PY_DEBUG", "default": "false"})
|
|
ratio: float = field(default=1.0, metadata={"env": "CFE_PY_RATIO", "default": "1.0"})
|
|
tags: list = field(default_factory=list, metadata={"env": "CFE_PY_TAGS", "default": "a,b"})
|
|
|
|
|
|
@dataclass
|
|
class RequiredConfig:
|
|
api_key: str = field(default="", metadata={"env": "CFE_PY_API_KEY", "required": True})
|
|
|
|
|
|
def _clean(*keys: str) -> None:
|
|
for k in keys:
|
|
os.environ.pop(k, None)
|
|
|
|
|
|
def test_populate_string_desde_env():
|
|
os.environ["CFE_PY_HOST"] = "myhost"
|
|
try:
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert cfg.host == "myhost"
|
|
finally:
|
|
_clean("CFE_PY_HOST")
|
|
|
|
|
|
def test_populate_int_con_conversion():
|
|
os.environ["CFE_PY_PORT"] = "9090"
|
|
try:
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert cfg.port == 9090
|
|
finally:
|
|
_clean("CFE_PY_PORT")
|
|
|
|
|
|
def test_populate_bool_true():
|
|
os.environ["CFE_PY_DEBUG"] = "true"
|
|
try:
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert cfg.debug is True
|
|
finally:
|
|
_clean("CFE_PY_DEBUG")
|
|
|
|
|
|
def test_populate_float_field():
|
|
os.environ["CFE_PY_RATIO"] = "3.14"
|
|
try:
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert abs(cfg.ratio - 3.14) < 1e-9
|
|
finally:
|
|
_clean("CFE_PY_RATIO")
|
|
|
|
|
|
def test_populate_list_comma_separated():
|
|
os.environ["CFE_PY_TAGS"] = "x,y,z"
|
|
try:
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert cfg.tags == ["x", "y", "z"]
|
|
finally:
|
|
_clean("CFE_PY_TAGS")
|
|
|
|
|
|
def test_default_usado_cuando_env_no_seteada():
|
|
_clean("CFE_PY_PORT")
|
|
cfg = config_from_env(SimpleConfig)
|
|
assert cfg.port == 8080
|
|
|
|
|
|
def test_required_sin_valor_lanza_error():
|
|
_clean("CFE_PY_API_KEY")
|
|
with pytest.raises(ValueError, match="required"):
|
|
config_from_env(RequiredConfig)
|
|
|
|
|
|
def test_no_dataclass_lanza_type_error():
|
|
class NotADataclass:
|
|
pass
|
|
|
|
with pytest.raises(TypeError):
|
|
config_from_env(NotADataclass)
|