Skip to content

Commit 604effd

Browse files
committed
test_release_do_nothing.
1 parent 41ee980 commit 604effd

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

noxfile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def tests(session: nox.sessions.Session):
186186
"-n",
187187
"auto",
188188
"lib/iris/tests",
189+
"tools",
189190
]
190191
if "-c" in session.posargs or "--coverage" in session.posargs:
191192
run_args[-1:-1] = ["--cov=lib/iris", "--cov-report=xml"]

tools/test_release_do_nothing.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Copyright Iris contributors
2+
#
3+
# This file is part of Iris and is released under the BSD license.
4+
# See LICENSE in the root of the repository for full licensing details.
5+
"""Tests for the ``release_do_nothing.py`` file."""
6+
7+
from typing import NamedTuple
8+
9+
import pytest
10+
11+
import nothing
12+
from release_do_nothing import IrisRelease
13+
14+
15+
@pytest.fixture(autouse=True)
16+
def mock_fast_print(mocker) -> None:
17+
"""Prevent the mod:`nothing` print methods from sleeping."""
18+
mocker.patch.object(nothing, "sleep", return_value=None)
19+
20+
21+
@pytest.fixture(autouse=True)
22+
def mock_git_commands(mocker) -> None:
23+
"""Detach testing from reliance on .git directory."""
24+
mocker.patch.object(
25+
IrisRelease,
26+
"_git_remote_v",
27+
return_value="origin\nupstream\nfoo\n",
28+
)
29+
30+
mocker.patch.object(
31+
IrisRelease,
32+
"_git_remote_get_url",
33+
return_value="git@github.com:foo/iris.git",
34+
)
35+
36+
mocker.patch.object(
37+
IrisRelease,
38+
"_git_ls_remote_tags",
39+
# TODO: make this as minimal as possible while still enabling the tests.
40+
return_value=(
41+
"abcd1234 refs/tags/1.0.0\n"
42+
"abcd1235 refs/tags/1.0.1\n"
43+
"abcd1236 refs/tags/1.0.2\n"
44+
"abcd1237 refs/tags/1.1.0rc1\n"
45+
"abcd1238 refs/tags/1.1.0rc2\n"
46+
"abcd1239 refs/tags/1.1.0\n"
47+
"abcd1240 refs/tags/1.2.0rc0\n"
48+
),
49+
)
50+
51+
52+
def mock_input(mocker, input_str: str) -> None:
53+
"""Mock :func:`input` to return a specific value."""
54+
mocker.patch("builtins.input", return_value=input_str)
55+
56+
57+
class TestValidate:
58+
"""Tests for the :func:`release_do_nothing.validate` function."""
59+
@pytest.fixture(autouse=True)
60+
def _setup(self) -> None:
61+
self.instance = IrisRelease(
62+
_dry_run=True,
63+
latest_complete_step=IrisRelease.get_steps().index(IrisRelease.validate) - 1,
64+
github_user="user",
65+
patch_min_max_tag=("8.0.0", "9.0.0")
66+
)
67+
68+
class Case(NamedTuple):
69+
git_tag: str
70+
match: str
71+
72+
@pytest.fixture(params=[
73+
pytest.param(
74+
Case("9.1.dev0", "development release.*cannot handle"),
75+
id="dev release",
76+
),
77+
pytest.param(
78+
Case("9.1.post0", "post release.*cannot handle"),
79+
id="post release",
80+
),
81+
pytest.param(
82+
Case("9.1.alpha0", "release candidate.*got 'a'"),
83+
id="pre-release non-rc",
84+
),
85+
pytest.param(
86+
Case("9.1.1rc0", "PATCH release AND a release candidate.*cannot handle"),
87+
id="patch release rc",
88+
),
89+
pytest.param(
90+
Case("9.1.1", "No previous releases.*cannot handle a PATCH"),
91+
id="first in series patch",
92+
),
93+
])
94+
def unhandled_cases(self, request) -> Case:
95+
case = request.param
96+
self.instance.git_tag = case.git_tag
97+
return case
98+
99+
def test_unhandled_cases(self, unhandled_cases):
100+
case = unhandled_cases
101+
with pytest.raises(RuntimeError, match=case.match):
102+
self.instance.validate()
103+
pass
104+
105+
@pytest.fixture
106+
def first_in_series_not_rc(self) -> None:
107+
self.instance.git_tag = "9.1.0"
108+
109+
def test_first_in_series_not_rc_message(self, first_in_series_not_rc, capfd, mocker):
110+
mock_input(mocker, "y")
111+
self.instance.validate()
112+
out, err = capfd.readouterr()
113+
assert "No previous releases" in out
114+
assert "expected to be a release candidate" in out
115+
assert "sure you want to continue" in out
116+
117+
def test_first_in_series_not_rc_exit(self, first_in_series_not_rc, mocker):
118+
mock_input(mocker, "n")
119+
with pytest.raises(SystemExit):
120+
self.instance.validate()
121+
122+
def test_first_in_series_not_rc_continue(self, first_in_series_not_rc, mocker):
123+
mock_input(mocker, "y")
124+
self.instance.validate()
125+
126+
# Not an exhaustive list, just the inverse of the unhandled cases.
127+
@pytest.fixture(params=[
128+
pytest.param("9.0.0rc0", id="major release RC"),
129+
pytest.param("9.1.0rc0", id="minor release RC"),
130+
pytest.param("1.2.0", id="minor release existing series"),
131+
pytest.param("1.1.1", id="patch release existing series"),
132+
pytest.param("9.1.0", id="first in series not RC"),
133+
])
134+
def handled_cases(self, request) -> None:
135+
self.instance.git_tag = request.param
136+
137+
def test_handled_cases(self, handled_cases, mocker):
138+
message = "Confirm that the details above are correct"
139+
mock_input(mocker, "y")
140+
mocked = mocker.patch.object(IrisRelease, "wait_for_done")
141+
self.instance.validate()
142+
mocked.assert_called_once()
143+
assert message in mocked.call_args[0][0]

0 commit comments

Comments
 (0)