Coverage for tests / test_prepare_release.py: 100%

88 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-11-09 00:15 +0000

1from datetime import date 1abcdefg

2from pathlib import Path 1abcdefg

3 

4import pytest 1abcdefg

5from typer.testing import CliRunner 1abcdefg

6 

7from scripts.prepare_release import ( 1abcdefg

8 BumpType, 

9 app, 

10 bump_version, 

11 get_release_notes_body, 

12 update_release_notes, 

13 update_version_file, 

14) 

15 

16runner = CliRunner() 1abcdefg

17 

18 

19@pytest.mark.parametrize( 1abcdefg

20 ("current_version", "bump", "new_version"), 

21 [ 

22 ("0.26.2", "major", "1.0.0"), 

23 ("0.26.2", "minor", "0.27.0"), 

24 ("0.26.2", "patch", "0.26.3"), 

25 ], 

26) 

27def test_bump_version(current_version: str, bump: BumpType, new_version: str) -> None: 1abcdefg

28 assert bump_version(current_version, bump) == new_version 1abcdefg

29 

30 

31def test_update_version_file() -> None: 1abcdefg

32 content = '"""Typer."""\n\n__version__ = "0.26.2"\n' 1abcdefg

33 

34 new_content = update_version_file(content, "0.26.3", Path("typer/__init__.py")) 1abcdefg

35 

36 assert new_content == '"""Typer."""\n\n__version__ = "0.26.3"\n' 1abcdefg

37 

38 

39def test_update_version_file_requires_newer_version() -> None: 1abcdefg

40 content = '__version__ = "0.26.2"\n' 1abcdefg

41 

42 with pytest.raises(RuntimeError, match="must be greater"): 1abcdefg

43 update_version_file(content, "0.26.2", Path("typer/__init__.py")) 1abcdefg

44 

45 

46def test_update_release_notes() -> None: 1abcdefg

47 content = """# Release Notes 1abcdefg

48 

49## Latest Changes 

50 

51### Fixes 

52 

53* Fix something. 

54 

55## 0.26.2 (2026-05-27) 

56 

57### Fixes 

58 

59* Previous fix. 

60""" 

61 

62 new_content = update_release_notes( 1abcdefg

63 content, "0.26.3", date(2026, 5, 28), Path("docs/release-notes.md") 

64 ) 

65 

66 assert ( 1abcdefg

67 new_content 

68 == """# Release Notes 

69 

70## Latest Changes 

71 

72## 0.26.3 (2026-05-28) 

73 

74### Fixes 

75 

76* Fix something. 

77 

78## 0.26.2 (2026-05-27) 

79 

80### Fixes 

81 

82* Previous fix. 

83""" 

84 ) 

85 

86 

87def test_update_release_notes_rejects_existing_version() -> None: 1abcdefg

88 content = """# Release Notes 1abcdefg

89 

90## Latest Changes 

91 

92## 0.26.3 (2026-05-28) 

93""" 

94 

95 with pytest.raises(RuntimeError, match="already contain"): 1abcdefg

96 update_release_notes( 1abcdefg

97 content, "0.26.3", date(2026, 5, 28), Path("docs/release-notes.md") 

98 ) 

99 

100 

101def test_get_release_notes_body_with_dated_heading() -> None: 1abcdefg

102 content = """# Release Notes 1abcdefg

103 

104## Latest Changes 

105 

106## 0.26.3 (2026-05-28) 

107 

108### Fixes 

109 

110* Fix something. 

111 

112## 0.26.2 (2026-05-27) 

113 

114### Fixes 

115 

116* Previous fix. 

117""" 

118 

119 body = get_release_notes_body(content, "0.26.3", Path("docs/release-notes.md")) 1abcdefg

120 

121 assert ( 1abcdefg

122 body 

123 == """### Fixes 

124 

125* Fix something. 

126""" 

127 ) 

128 

129 

130def test_get_release_notes_body_with_plain_heading() -> None: 1abcdefg

131 content = """# Release Notes 1abcdefg

132 

133## Latest Changes 

134 

135## 0.26.3 

136 

137### Fixes 

138 

139* Fix something. 

140""" 

141 

142 body = get_release_notes_body(content, "0.26.3", Path("docs/release-notes.md")) 1abcdefg

143 

144 assert body == "### Fixes\n\n* Fix something.\n" 1abcdefg

145 

146 

147def test_get_release_notes_body_allows_non_version_h2_content() -> None: 1abcdefg

148 content = """# Release Notes 1abcdefg

149 

150## Latest Changes 

151 

152## 0.26.3 

153 

154## Highlights 

155 

156* Fix something. 

157 

158## 0.26.2 

159 

160* Previous fix. 

161""" 

162 

163 body = get_release_notes_body(content, "0.26.3", Path("docs/release-notes.md")) 1abcdefg

164 

165 assert body == "## Highlights\n\n* Fix something.\n" 1abcdefg

166 

167 

168def test_get_release_notes_body_requires_version_section() -> None: 1abcdefg

169 content = "# Release Notes\n\n## Latest Changes\n" 1abcdefg

170 

171 with pytest.raises(RuntimeError, match="Could not find"): 1abcdefg

172 get_release_notes_body(content, "0.26.3", Path("docs/release-notes.md")) 1abcdefg

173 

174 

175def test_get_release_notes_body_requires_non_empty_section() -> None: 1abcdefg

176 content = """# Release Notes 1abcdefg

177 

178## Latest Changes 

179 

180## 0.26.3 

181 

182## 0.26.2 

183 

184* Previous fix. 

185""" 

186 

187 with pytest.raises(RuntimeError, match="is empty"): 1abcdefg

188 get_release_notes_body(content, "0.26.3", Path("docs/release-notes.md")) 1abcdefg

189 

190 

191def test_cli_updates_configured_files(tmp_path: Path) -> None: 1abcdefg

192 version_file = tmp_path / "package" / "__init__.py" 1abcdefg

193 version_file.parent.mkdir() 1abcdefg

194 version_file.write_text('__version__ = "0.26.2"\n') 1abcdefg

195 release_notes_file = tmp_path / "release-notes.md" 1abcdefg

196 release_notes_file.write_text( 1abcdefg

197 """# Release Notes 

198 

199## Latest Changes 

200 

201### Fixes 

202 

203* Fix something. 

204""" 

205 ) 

206 

207 result = runner.invoke( 1abcdefg

208 app, 

209 [ 

210 "prepare", 

211 "patch", 

212 "--version-file", 

213 str(version_file), 

214 "--release-notes-file", 

215 str(release_notes_file), 

216 "--date", 

217 "2026-05-28", 

218 ], 

219 ) 

220 

221 assert result.exit_code == 0, result.output 1abcdefg

222 assert "Prepared release 0.26.3 (2026-05-28)" in result.output 1abcdefg

223 assert version_file.read_text() == '__version__ = "0.26.3"\n' 1abcdefg

224 assert "## 0.26.3 (2026-05-28)" in release_notes_file.read_text() 1abcdefg

225 

226 

227def test_cli_accepts_env_vars(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: 1abcdefg

228 version_file = tmp_path / "package" / "__init__.py" 1abcdefg

229 version_file.parent.mkdir() 1abcdefg

230 version_file.write_text('__version__ = "0.26.2"\n') 1abcdefg

231 release_notes_file = tmp_path / "docs" / "release-notes.md" 1abcdefg

232 release_notes_file.parent.mkdir() 1abcdefg

233 release_notes_file.write_text("# Release Notes\n\n## Latest Changes\n") 1abcdefg

234 monkeypatch.setenv("PREPARE_RELEASE_BUMP", "minor") 1abcdefg

235 monkeypatch.setenv("PREPARE_RELEASE_VERSION_FILE", str(version_file)) 1abcdefg

236 monkeypatch.setenv("PREPARE_RELEASE_RELEASE_NOTES_FILE", str(release_notes_file)) 1abcdefg

237 monkeypatch.setenv("PREPARE_RELEASE_DATE", "2026-05-28") 1abcdefg

238 

239 result = runner.invoke(app, ["prepare"]) 1abcdefg

240 

241 assert result.exit_code == 0, result.output 1abcdefg

242 assert "Prepared release 0.27.0 (2026-05-28)" in result.output 1abcdefg

243 assert version_file.read_text() == '__version__ = "0.27.0"\n' 1abcdefg

244 assert "## 0.27.0 (2026-05-28)" in release_notes_file.read_text() 1abcdefg

245 

246 

247def test_cli_prints_current_version(tmp_path: Path) -> None: 1abcdefg

248 version_file = tmp_path / "package" / "__init__.py" 1abcdefg

249 version_file.parent.mkdir() 1abcdefg

250 version_file.write_text('__version__ = "0.26.2"\n') 1abcdefg

251 

252 result = runner.invoke( 1abcdefg

253 app, 

254 [ 

255 "current-version", 

256 "--version-file", 

257 str(version_file), 

258 ], 

259 ) 

260 

261 assert result.exit_code == 0, result.output 1abcdefg

262 assert result.output == "0.26.2\n" 1abcdefg

263 

264 

265def test_cli_prints_release_notes(tmp_path: Path) -> None: 1abcdefg

266 version_file = tmp_path / "package" / "__init__.py" 1abcdefg

267 version_file.parent.mkdir() 1abcdefg

268 version_file.write_text('__version__ = "0.26.3"\n') 1abcdefg

269 release_notes_file = tmp_path / "release-notes.md" 1abcdefg

270 release_notes_file.write_text( 1abcdefg

271 """# Release Notes 

272 

273## Latest Changes 

274 

275## 0.26.3 (2026-05-28) 

276 

277### Fixes 

278 

279* Fix something. 

280""" 

281 ) 

282 

283 result = runner.invoke( 1abcdefg

284 app, 

285 [ 

286 "release-notes", 

287 "--version-file", 

288 str(version_file), 

289 "--release-notes-file", 

290 str(release_notes_file), 

291 ], 

292 ) 

293 

294 assert result.exit_code == 0, result.output 1abcdefg

295 assert result.output == "### Fixes\n\n* Fix something.\n" 1abcdefg