Skip to content

Commit 9e91663

Browse files
introduce helpers for more compact version inference test writing
1 parent 9293e51 commit 9e91663

File tree

2 files changed

+71
-51
lines changed

2 files changed

+71
-51
lines changed

src/setuptools_scm/_integration/version_inference.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def apply(self, dist: Distribution) -> None:
6060
warnings.warn(self.message)
6161

6262

63+
@dataclass(frozen=True)
6364
class VersionInferenceNoOp:
6465
"""No operation result - silent skip."""
6566

testing/test_version_inference.py

Lines changed: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from __future__ import annotations
22

3+
from types import SimpleNamespace
34
from typing import Any
45

5-
import pytest
6-
76
from setuptools_scm._integration.pyproject_reading import PyProjectData
87
from setuptools_scm._integration.version_inference import VersionInferenceConfig
98
from setuptools_scm._integration.version_inference import VersionInferenceNoOp
9+
from setuptools_scm._integration.version_inference import VersionInferenceResult
1010
from setuptools_scm._integration.version_inference import VersionInferenceWarning
1111
from setuptools_scm._integration.version_inference import get_version_inference_config
1212

@@ -15,15 +15,41 @@
1515
is_required=True, section_present=True, project_present=True
1616
)
1717

18+
PYPROJECT_WITHOUT_TOOL_SECTION = PyProjectData.for_testing(
19+
is_required=True, section_present=False, project_present=True
20+
)
21+
22+
PYPROJECT_ONLY_REQUIRED = PyProjectData.for_testing(
23+
is_required=True, section_present=False, project_present=False
24+
)
25+
26+
OVERRIDES = SimpleNamespace(
27+
EMPTY={},
28+
CALVER={"version_scheme": "calver"},
29+
UNRELATED={"key": "value"},
30+
INFER_VERSION=None,
31+
)
32+
33+
34+
WARNING_PACKAGE = VersionInferenceWarning(
35+
message="version of test_package already set",
36+
)
37+
WARNING_NO_PACKAGE = VersionInferenceWarning(
38+
message="version of None already set",
39+
)
40+
41+
NOOP = VersionInferenceNoOp()
42+
1843

1944
def expect_config(
2045
*,
2146
dist_name: str | None = "test_package",
2247
current_version: str | None,
2348
pyproject_data: PyProjectData = DEFAULT_PYPROJECT_DATA,
2449
overrides: dict[str, Any] | None = None,
25-
expected_type: type = VersionInferenceConfig,
26-
expected_message: str | None = None,
50+
expected: type[VersionInferenceConfig]
51+
| VersionInferenceWarning
52+
| VersionInferenceNoOp,
2753
) -> None:
2854
"""Helper to test get_version_inference_config and assert expected result type."""
2955
__tracebackhide__ = True
@@ -34,16 +60,18 @@ def expect_config(
3460
overrides=overrides,
3561
)
3662

37-
if not isinstance(result, expected_type):
38-
pytest.fail(f"{type(result).__name__} != {expected_type.__name__}")
63+
expectation: VersionInferenceResult
64+
if expected == VersionInferenceConfig:
65+
expectation = VersionInferenceConfig(
66+
dist_name=dist_name,
67+
pyproject_data=pyproject_data,
68+
overrides=overrides,
69+
)
70+
else:
71+
assert isinstance(expected, (VersionInferenceNoOp, VersionInferenceWarning))
72+
expectation = expected
3973

40-
if expected_type == VersionInferenceWarning and expected_message:
41-
assert isinstance(result, VersionInferenceWarning)
42-
assert expected_message in result.message
43-
elif expected_type == VersionInferenceConfig:
44-
assert isinstance(result, VersionInferenceConfig)
45-
assert result.dist_name == dist_name
46-
assert result.overrides == overrides
74+
assert result == expectation
4775

4876

4977
class TestVersionInferenceDecision:
@@ -53,93 +81,85 @@ def test_missing_version_with_overrides_triggers(self) -> None:
5381
"""Test that version_keyword context with overrides infers when no existing version."""
5482
expect_config(
5583
current_version=None, # version_keyword passes None when version was set by infer
56-
overrides={"key": "value"},
84+
overrides=OVERRIDES.UNRELATED,
85+
expected=VersionInferenceConfig,
5786
)
5887

5988
def test_overrides_on_existing_version_warns(self) -> None:
6089
"""note: version_keyword opts out of inference if
6190
version is set by something else or overrides are empty"""
6291
expect_config(
6392
current_version="1.0.0", # version set by something else (setup.cfg, etc.)
64-
overrides={"key": "value"},
65-
expected_type=VersionInferenceWarning,
66-
expected_message="version of test_package already set",
93+
overrides=OVERRIDES.UNRELATED,
94+
expected=WARNING_PACKAGE,
6795
)
6896

6997
def test_version_already_set_no_overrides(self) -> None:
7098
"""infer_version call with existing version warns when inference is implied."""
7199
expect_config(
72100
current_version="1.0.0",
73101
overrides=None,
74-
expected_type=VersionInferenceWarning,
75-
expected_message="version of test_package already set",
102+
expected=WARNING_PACKAGE,
76103
)
77104

78105
def test_version_keyword_with_empty_overrides(self) -> None:
79106
"""Test that version_keyword context with empty overrides infers when no existing version."""
80107
expect_config(
81108
current_version=None, # version_keyword handles early exit, so this is what we see
82-
overrides={},
109+
overrides=OVERRIDES.EMPTY,
110+
expected=VersionInferenceConfig,
83111
)
84112

85113
def test_version_keyword_empty_overrides_existing_version(self) -> None:
86114
"""Test that version_keyword context with empty overrides and existing version errors."""
87115
expect_config(
88116
current_version="1.0.0", # version set by something else (setup.cfg, etc.)
89-
overrides={},
90-
expected_type=VersionInferenceWarning,
91-
expected_message="version of test_package already set",
117+
overrides=OVERRIDES.EMPTY,
118+
expected=WARNING_PACKAGE,
92119
)
93120

94121
def test_version_already_set_by_something_else(self) -> None:
95122
"""infer_version call with existing version warns when inference is implied."""
96123
expect_config(
97124
current_version="1.0.0",
98125
overrides=None,
99-
expected_type=VersionInferenceWarning,
100-
expected_message="version of test_package already set",
126+
expected=WARNING_PACKAGE,
101127
)
102128

103129
def test_no_setuptools_scm_config_infer_version(self) -> None:
104130
"""Test that we don't infer when setuptools-scm is not configured and infer_version called."""
105131
expect_config(
106132
current_version=None,
107-
pyproject_data=PyProjectData.for_testing(
108-
is_required=False, section_present=False, project_present=True
109-
),
133+
pyproject_data=PYPROJECT_WITHOUT_TOOL_SECTION,
110134
overrides=None,
111-
expected_type=VersionInferenceNoOp,
135+
expected=NOOP,
112136
)
113137

114138
def test_no_setuptools_scm_config_version_keyword(self) -> None:
115139
"""We infer when setuptools-scm is not configured but use_scm_version=True."""
116140
expect_config(
117141
current_version=None,
118-
pyproject_data=PyProjectData.for_testing(
119-
is_required=False, section_present=False, project_present=True
120-
),
121-
overrides={},
142+
pyproject_data=PYPROJECT_WITHOUT_TOOL_SECTION,
143+
overrides=OVERRIDES.EMPTY,
144+
expected=VersionInferenceConfig,
122145
)
123146

124147
def test_setuptools_scm_required_no_project_section_infer_version(self) -> None:
125148
"""We don't infer without tool section even if required: infer_version path."""
126149
expect_config(
127150
current_version=None,
128-
pyproject_data=PyProjectData.for_testing(
129-
is_required=True, section_present=False, project_present=False
130-
),
151+
pyproject_data=PYPROJECT_ONLY_REQUIRED,
131152
overrides=None,
132-
expected_type=VersionInferenceNoOp,
153+
expected=NOOP,
133154
)
134155

135156
def test_setuptools_scm_required_no_project_section_version_keyword(self) -> None:
136157
"""Test that we DO infer when setuptools-scm is required but no project section and use_scm_version=True."""
137158
expect_config(
138159
current_version=None,
139-
pyproject_data=PyProjectData.for_testing(
140-
is_required=True, section_present=False, project_present=False
141-
),
142-
overrides={},
160+
pyproject_data=PYPROJECT_ONLY_REQUIRED,
161+
overrides=OVERRIDES.EMPTY,
162+
expected=VersionInferenceConfig,
143163
)
144164

145165
def test_setuptools_scm_required_no_project_section_version_keyword_with_config(
@@ -148,20 +168,17 @@ def test_setuptools_scm_required_no_project_section_version_keyword_with_config(
148168
"""Test that we DO infer when setuptools-scm is required but no project section and use_scm_version={config}."""
149169
expect_config(
150170
current_version=None,
151-
pyproject_data=PyProjectData.for_testing(
152-
is_required=True, section_present=False, project_present=False
153-
),
154-
overrides={"version_scheme": "calver"},
171+
pyproject_data=PYPROJECT_ONLY_REQUIRED,
172+
overrides=OVERRIDES.CALVER,
173+
expected=VersionInferenceConfig,
155174
)
156175

157176
def test_setuptools_scm_required_with_project_section(self) -> None:
158177
"""We only infer when tool section present, regardless of required/project presence."""
159178
expect_config(
160179
current_version=None,
161-
pyproject_data=PyProjectData.for_testing(
162-
is_required=True, section_present=False, project_present=True
163-
),
164-
expected_type=VersionInferenceNoOp,
180+
pyproject_data=PYPROJECT_WITHOUT_TOOL_SECTION,
181+
expected=NOOP,
165182
)
166183

167184
def test_tool_section_present(self) -> None:
@@ -171,19 +188,22 @@ def test_tool_section_present(self) -> None:
171188
pyproject_data=PyProjectData.for_testing(
172189
is_required=False, section_present=True, project_present=False
173190
),
191+
expected=VersionInferenceConfig,
174192
)
175193

176194
def test_both_required_and_tool_section(self) -> None:
177195
"""Test that we infer when both required and tool section are present."""
178196
expect_config(
179197
current_version=None,
198+
expected=VersionInferenceConfig,
180199
)
181200

182201
def test_none_dist_name(self) -> None:
183202
"""Test that we handle None dist_name correctly."""
184203
expect_config(
185204
dist_name=None,
186205
current_version=None,
206+
expected=VersionInferenceConfig,
187207
)
188208

189209
def test_version_already_set_none_dist_name(self) -> None:
@@ -192,6 +212,5 @@ def test_version_already_set_none_dist_name(self) -> None:
192212
dist_name=None,
193213
current_version="1.0.0",
194214
overrides=None,
195-
expected_type=VersionInferenceWarning,
196-
expected_message="version of None already set",
215+
expected=WARNING_NO_PACKAGE,
197216
)

0 commit comments

Comments
 (0)