| import configparser |
| from dataclasses import dataclass |
| from datetime import datetime |
| from decimal import Decimal |
| from pathlib import Path |
| |
| import pytest |
| |
| from mako.testing._config import ConfigValueTypeError |
| from mako.testing._config import MissingConfig |
| from mako.testing._config import MissingConfigItem |
| from mako.testing._config import MissingConfigSection |
| from mako.testing._config import ReadsCfg |
| from mako.testing.assertions import assert_raises_message_with_given_cause |
| from mako.testing.assertions import assert_raises_with_given_cause |
| |
| PATH_TO_TEST_CONFIG = Path(__file__).parent / "dummy.cfg" |
| |
| |
| @dataclass |
| class BasicConfig(ReadsCfg): |
| int_value: int |
| bool_value: bool |
| float_value: float |
| str_value: str |
| |
| section_header = "basic_values" |
| |
| |
| @dataclass |
| class BooleanConfig(ReadsCfg): |
| yes: bool |
| one: bool |
| true: bool |
| on: bool |
| no: bool |
| zero: bool |
| false: bool |
| off: bool |
| |
| section_header = "boolean_values" |
| |
| |
| @dataclass |
| class UnsupportedTypesConfig(ReadsCfg): |
| decimal_value: Decimal |
| datetime_value: datetime |
| |
| section_header = "additional_types" |
| |
| |
| @dataclass |
| class SupportedTypesConfig(ReadsCfg): |
| decimal_value: Decimal |
| datetime_value: datetime |
| |
| section_header = "additional_types" |
| converters = { |
| Decimal: lambda v: Decimal(str(v)), |
| datetime: lambda v: datetime.fromisoformat(v), |
| } |
| |
| |
| @dataclass |
| class NonexistentSectionConfig(ReadsCfg): |
| some_value: str |
| another_value: str |
| |
| section_header = "i_dont_exist" |
| |
| |
| @dataclass |
| class TypeMismatchConfig(ReadsCfg): |
| int_value: int |
| |
| section_header = "type_mismatch" |
| |
| |
| @dataclass |
| class MissingItemConfig(ReadsCfg): |
| present_item: str |
| missing_item: str |
| |
| section_header = "missing_item" |
| |
| |
| class BasicConfigTest: |
| @pytest.fixture(scope="class") |
| def config(self): |
| return BasicConfig.from_cfg_file(PATH_TO_TEST_CONFIG) |
| |
| def test_coercions(self, config): |
| assert isinstance(config.int_value, int) |
| assert isinstance(config.bool_value, bool) |
| assert isinstance(config.float_value, float) |
| assert isinstance(config.str_value, str) |
| |
| def test_values(self, config): |
| assert config.int_value == 15421 |
| assert config.bool_value == True |
| assert config.float_value == 14.01 |
| assert config.str_value == "Ceci n'est pas une chaƮne" |
| |
| def test_error_on_loading_from_nonexistent_file(self): |
| assert_raises_with_given_cause( |
| MissingConfig, |
| FileNotFoundError, |
| BasicConfig.from_cfg_file, |
| "./n/o/f/i/l/e/h.ere", |
| ) |
| |
| def test_error_on_loading_from_nonexistent_section(self): |
| assert_raises_with_given_cause( |
| MissingConfigSection, |
| configparser.NoSectionError, |
| NonexistentSectionConfig.from_cfg_file, |
| PATH_TO_TEST_CONFIG, |
| ) |
| |
| |
| class BooleanConfigTest: |
| @pytest.fixture(scope="class") |
| def config(self): |
| return BooleanConfig.from_cfg_file(PATH_TO_TEST_CONFIG) |
| |
| def test_values(self, config): |
| assert config.yes is True |
| assert config.one is True |
| assert config.true is True |
| assert config.on is True |
| assert config.no is False |
| assert config.zero is False |
| assert config.false is False |
| assert config.off is False |
| |
| |
| class UnsupportedTypesConfigTest: |
| @pytest.fixture(scope="class") |
| def config(self): |
| return UnsupportedTypesConfig.from_cfg_file(PATH_TO_TEST_CONFIG) |
| |
| def test_values(self, config): |
| assert config.decimal_value == "100001.01" |
| assert config.datetime_value == "2021-12-04 00:05:23.283" |
| |
| |
| class SupportedTypesConfigTest: |
| @pytest.fixture(scope="class") |
| def config(self): |
| return SupportedTypesConfig.from_cfg_file(PATH_TO_TEST_CONFIG) |
| |
| def test_values(self, config): |
| assert config.decimal_value == Decimal("100001.01") |
| assert config.datetime_value == datetime(2021, 12, 4, 0, 5, 23, 283000) |
| |
| |
| class TypeMismatchConfigTest: |
| def test_error_on_load(self): |
| assert_raises_message_with_given_cause( |
| ConfigValueTypeError, |
| "Wrong value type for int_value", |
| ValueError, |
| TypeMismatchConfig.from_cfg_file, |
| PATH_TO_TEST_CONFIG, |
| ) |
| |
| |
| class MissingItemConfigTest: |
| def test_error_on_load(self): |
| assert_raises_message_with_given_cause( |
| MissingConfigItem, |
| "No config item for missing_item", |
| configparser.NoOptionError, |
| MissingItemConfig.from_cfg_file, |
| PATH_TO_TEST_CONFIG, |
| ) |