Skip to content

Commit d91bdce

Browse files
committed
Reformat documentation string so clear intent, move to outward file, extend tests
1 parent c8d7c0a commit d91bdce

File tree

6 files changed

+135
-98
lines changed

6 files changed

+135
-98
lines changed

exasol/toolbox/BaseConfig/__init__.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

exasol/toolbox/config.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from typing import (
2+
Annotated,
3+
)
4+
5+
from pydantic import (
6+
AfterValidator,
7+
BaseModel,
8+
ConfigDict,
9+
Field,
10+
computed_field,
11+
)
12+
13+
from exasol.toolbox.util.version import Version
14+
15+
16+
def valid_version_string(version_string: str) -> str:
17+
Version.from_string(version_string)
18+
return version_string
19+
20+
21+
ValidVersionStr = Annotated[str, AfterValidator(valid_version_string)]
22+
23+
24+
class BaseConfig(BaseModel):
25+
"""
26+
Basic configuration for projects using the PTB
27+
28+
This configuration class defines the necessary attributes for using the PTB's
29+
various nox sessions and GitHub CI workflows. Defaults are provided via the
30+
attributes, which makes it easy for a specific project to modify these values
31+
as needed. There are properties provided which automate some configuration aspects
32+
so that the project-specific modifications are reduced.
33+
34+
pydantic has been used so that altered attributes are quickly validated.
35+
This allows for immediate feedback, instead of waiting for various failed CI
36+
runs.
37+
"""
38+
39+
python_versions: tuple[ValidVersionStr, ...] = Field(
40+
default=(
41+
"3.9",
42+
"3.10",
43+
"3.11",
44+
"3.12",
45+
"3.13",
46+
),
47+
description="Python versions to use in running CI workflows",
48+
)
49+
50+
exasol_versions: tuple[ValidVersionStr, ...] = Field(
51+
default=("7.1.9",),
52+
description="Exasol versions to use in running CI workflows for integration tests using the DB",
53+
)
54+
model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)
55+
56+
@computed_field # type: ignore[misc]
57+
@property
58+
def min_py_version(self) -> str:
59+
"""
60+
Minimum Python version declared from the `python_versions` list
61+
62+
This is used in specific testing scenarios where it would be either
63+
costly to run the tests for all `python_versions` or we need a single metric.
64+
"""
65+
return str(min([Version.from_string(v) for v in self.python_versions]))

noxconfig.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
from __future__ import annotations
44

55
from collections.abc import Iterable
6-
from dataclasses import dataclass
76
from pathlib import Path
87

9-
from exasol.toolbox.BaseConfig import BaseConfig
8+
from exasol.toolbox.config import BaseConfig
109
from exasol.toolbox.nox.plugin import hookimpl
1110
from exasol.toolbox.tools.replace_version import update_github_yml
1211

project-template/{{cookiecutter.repo_name}}/noxconfig.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
from __future__ import annotations
22

3-
from dataclasses import dataclass
43
from pathlib import Path
54
from typing import Iterable
6-
from exasol.toolbox.BaseConfig import BaseConfig
5+
6+
from exasol.toolbox.config import BaseConfig
77

88

99
class Config(BaseConfig):
1010
root: Path = Path(__file__).parent
1111
doc: Path = Path(__file__).parent / "doc"
1212
source: Path = Path("exasol/{{cookiecutter.package_name}}")
1313
version_file: Path = (
14-
Path(__file__).parent
15-
/ "exasol"
16-
/ "{{cookiecutter.package_name}}"
17-
/ "version.py"
14+
Path(__file__).parent
15+
/ "exasol"
16+
/ "{{cookiecutter.package_name}}"
17+
/ "version.py"
1818
)
1919
path_filters: Iterable[str] = ()
20-
pyupgrade_args: Iterable[str] = ("--py{{cookiecutter.python_version_min | replace('.', '')}}-plus",)
20+
pyupgrade_args: Iterable[str] = (
21+
"--py{{cookiecutter.python_version_min | replace('.', '')}}-plus",)
2122
plugins: Iterable[object] = ()
2223

2324

test/unit/BaseConfig/base_config_test.py

Lines changed: 0 additions & 40 deletions
This file was deleted.

test/unit/config_test.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import pytest
2+
from pydantic_core._pydantic_core import ValidationError
3+
4+
from exasol.toolbox.config import (
5+
BaseConfig,
6+
valid_version_string,
7+
)
8+
9+
10+
class TestBaseConfig:
11+
@staticmethod
12+
def test_works_as_defined():
13+
BaseConfig()
14+
15+
@staticmethod
16+
@pytest.mark.parametrize(
17+
"wrong_input,expected_message",
18+
[
19+
pytest.param(
20+
{"python_versions": ["1.2.3.1"]},
21+
"Version has an invalid format",
22+
id="python_versions",
23+
),
24+
pytest.param(
25+
{"exasol_versions": ["1.2.3.1"]},
26+
"Version has an invalid format",
27+
id="exasol_versions",
28+
),
29+
],
30+
)
31+
def test_raises_exception_when_incorrect_modification(
32+
wrong_input: dict, expected_message: str
33+
):
34+
with pytest.raises(ValidationError, match=expected_message):
35+
BaseConfig(**wrong_input)
36+
37+
38+
class TestValidVersionString:
39+
@staticmethod
40+
def test_work_as_expected():
41+
version_string = "1.2.3"
42+
result = valid_version_string(version_string=version_string)
43+
assert result == version_string
44+
45+
@staticmethod
46+
def test_raises_exception_when_not_valid():
47+
with pytest.raises(ValueError):
48+
valid_version_string("$.2.3")
49+
50+
51+
class BaseConfigExpansion(BaseConfig):
52+
expansion1: str = "test1"
53+
54+
55+
def test_expansion_validation():
56+
BaseConfigExpansion()
57+
58+
59+
def test_min_py_version():
60+
conf = BaseConfig(python_versions=("5.5.5", "1.1.1", "9.9.9"))
61+
assert conf.min_py_version == "1.1.1"

0 commit comments

Comments
 (0)