Coverage for tests/test_prepare_release.py: 100%

87 statements  

« prev     ^ index     » next       coverage.py v7.11.2, created at 2026-11-04 19:57 +0000

1from datetime import date 1abcdefgh

2from pathlib import Path 1abcdefgh

3 

4import pytest 1abcdefgh

5from typer.testing import CliRunner 1abcdefgh

6 

7from scripts.prepare_release import ( 1abcdefgh

8 BumpType, 

9 app, 

10 bump_version, 

11 get_release_notes_body, 

12 update_release_notes, 

13 update_version_file, 

14) 

15 

16runner = CliRunner() 1abcdefgh

17 

18 

19@pytest.mark.parametrize( 1abcdefgh

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

21 [ 

22 ("0.0.6", "major", "1.0.0"), 

23 ("0.0.6", "minor", "0.1.0"), 

24 ("0.0.6", "patch", "0.0.7"), 

25 ], 

26) 

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

28 assert bump_version(current_version, bump) == new_version 2xbybzbAbBbCbDbEb

29 

30 

31def test_update_version_file() -> None: 1abcdefgh

32 content = '__version__ = "0.0.6"\n' 1OPQRSTUV

33 

34 new_content = update_version_file( 1OPQRSTUV

35 content, "0.0.7", Path("src/fastapi_new/__init__.py") 

36 ) 

37 

38 assert new_content == '__version__ = "0.0.7"\n' 1OPQRSTUV

39 

40 

41def test_update_version_file_requires_newer_version() -> None: 1abcdefgh

42 content = '__version__ = "0.0.6"\n' 1WXYZ0123

43 

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

45 update_version_file(content, "0.0.6", Path("src/fastapi_new/__init__.py")) 1WXYZ0123

46 

47 

48def test_update_release_notes() -> None: 1abcdefgh

49 content = """# Release Notes 1456789!#

50 

51## Latest Changes 

52 

53### Fixes 

54 

55* Fix something. 

56 

57## 0.0.6 (2026-04-03) 

58 

59### Fixes 

60 

61* Previous fix. 

62""" 

63 

64 new_content = update_release_notes( 1456789!#

65 content, "0.0.7", date(2026, 5, 30), Path("release-notes.md") 

66 ) 

67 

68 assert ( 1456789!#

69 new_content 

70 == """# Release Notes 

71 

72## Latest Changes 

73 

74## 0.0.7 (2026-05-30) 

75 

76### Fixes 

77 

78* Fix something. 

79 

80## 0.0.6 (2026-04-03) 

81 

82### Fixes 

83 

84* Previous fix. 

85""" 

86 ) 

87 

88 

89def test_update_release_notes_rejects_existing_version() -> None: 1abcdefgh

90 content = """# Release Notes 1$%'()*+,

91 

92## Latest Changes 

93 

94## 0.0.7 (2026-05-30) 

95""" 

96 

97 with pytest.raises(RuntimeError, match="already contain"): 1$%'()*+,

98 update_release_notes( 1$%'()*+,

99 content, "0.0.7", date(2026, 5, 30), Path("release-notes.md") 

100 ) 

101 

102 

103def test_get_release_notes_body_with_dated_heading() -> None: 1abcdefgh

104 content = """# Release Notes 1-./:;=?@

105 

106## Latest Changes 

107 

108## 0.0.7 (2026-05-30) 

109 

110### Fixes 

111 

112* Fix something. 

113 

114## 0.0.6 (2026-04-03) 

115 

116### Fixes 

117 

118* Previous fix. 

119""" 

120 

121 body = get_release_notes_body(content, "0.0.7", Path("release-notes.md")) 1-./:;=?@

122 

123 assert ( 1-./:;=?@

124 body 

125 == """### Fixes 

126 

127* Fix something. 

128""" 

129 ) 

130 

131 

132def test_get_release_notes_body_with_plain_heading() -> None: 1abcdefgh

133 content = """# Release Notes 1[]^_`{|}

134 

135## Latest Changes 

136 

137## 0.0.7 

138 

139### Fixes 

140 

141* Fix something. 

142""" 

143 

144 body = get_release_notes_body(content, "0.0.7", Path("release-notes.md")) 1[]^_`{|}

145 

146 assert body == "### Fixes\n\n* Fix something.\n" 1[]^_`{|}

147 

148 

149def test_get_release_notes_body_allows_non_version_h2_content() -> None: 1abcdefgh

150 content = """# Release Notes 2~ abbbcbdbebfbgb

151 

152## Latest Changes 

153 

154## 0.0.7 

155 

156## Highlights 

157 

158* Fix something. 

159 

160## 0.0.6 

161 

162* Previous fix. 

163""" 

164 

165 body = get_release_notes_body(content, "0.0.7", Path("release-notes.md")) 2~ abbbcbdbebfbgb

166 

167 assert body == "## Highlights\n\n* Fix something.\n" 2~ abbbcbdbebfbgb

168 

169 

170def test_get_release_notes_body_requires_version_section() -> None: 1abcdefgh

171 content = "# Release Notes\n\n## Latest Changes\n" 2hbibjbkblbmbnbob

172 

173 with pytest.raises(RuntimeError, match="Could not find"): 2hbibjbkblbmbnbob

174 get_release_notes_body(content, "0.0.7", Path("release-notes.md")) 2hbibjbkblbmbnbob

175 

176 

177def test_get_release_notes_body_requires_non_empty_section() -> None: 1abcdefgh

178 content = """# Release Notes 2pbqbrbsbtbubvbwb

179 

180## Latest Changes 

181 

182## 0.0.7 

183 

184## 0.0.6 

185 

186* Previous fix. 

187""" 

188 

189 with pytest.raises(RuntimeError, match="is empty"): 2pbqbrbsbtbubvbwb

190 get_release_notes_body(content, "0.0.7", Path("release-notes.md")) 2pbqbrbsbtbubvbwb

191 

192 

193def test_cli_updates_configured_files(tmp_path: Path) -> None: 1abcdefgh

194 version_file = tmp_path / "src" / "fastapi_new" / "__init__.py" 1qrstuvwx

195 version_file.parent.mkdir(parents=True) 1qrstuvwx

196 version_file.write_text('__version__ = "0.0.6"\n') 1qrstuvwx

197 release_notes_file = tmp_path / "release-notes.md" 1qrstuvwx

198 release_notes_file.write_text( 1qrstuvwx

199 """# Release Notes 

200 

201## Latest Changes 

202 

203### Fixes 

204 

205* Fix something. 

206""" 

207 ) 

208 

209 result = runner.invoke( 1qrstuvwx

210 app, 

211 [ 

212 "prepare", 

213 "patch", 

214 "--version-file", 

215 str(version_file), 

216 "--release-notes-file", 

217 str(release_notes_file), 

218 "--date", 

219 "2026-05-30", 

220 ], 

221 ) 

222 

223 assert result.exit_code == 0, result.output 1qrstuvwx

224 assert "Prepared release 0.0.7 (2026-05-30)" in result.output 1qrstuvwx

225 assert version_file.read_text() == '__version__ = "0.0.7"\n' 1qrstuvwx

226 assert "## 0.0.7 (2026-05-30)" in release_notes_file.read_text() 1qrstuvwx

227 

228 

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

230 version_file = tmp_path / "src" / "fastapi_new" / "__init__.py" 1ijklmnop

231 version_file.parent.mkdir(parents=True) 1ijklmnop

232 version_file.write_text('__version__ = "0.0.6"\n') 1ijklmnop

233 release_notes_file = tmp_path / "release-notes.md" 1ijklmnop

234 release_notes_file.write_text("# Release Notes\n\n## Latest Changes\n") 1ijklmnop

235 monkeypatch.setenv("PREPARE_RELEASE_BUMP", "minor") 1ijklmnop

236 monkeypatch.setenv("PREPARE_RELEASE_VERSION_FILE", str(version_file)) 1ijklmnop

237 monkeypatch.setenv("PREPARE_RELEASE_RELEASE_NOTES_FILE", str(release_notes_file)) 1ijklmnop

238 monkeypatch.setenv("PREPARE_RELEASE_DATE", "2026-05-30") 1ijklmnop

239 

240 result = runner.invoke(app, ["prepare"]) 1ijklmnop

241 

242 assert result.exit_code == 0, result.output 1ijklmnop

243 assert "Prepared release 0.1.0 (2026-05-30)" in result.output 1ijklmnop

244 assert version_file.read_text() == '__version__ = "0.1.0"\n' 1ijklmnop

245 assert "## 0.1.0 (2026-05-30)" in release_notes_file.read_text() 1ijklmnop

246 

247 

248def test_cli_prints_current_version(tmp_path: Path) -> None: 1abcdefgh

249 version_file = tmp_path / "src" / "fastapi_new" / "__init__.py" 1GHIJKLMN

250 version_file.parent.mkdir(parents=True) 1GHIJKLMN

251 version_file.write_text('__version__ = "0.0.6"\n') 1GHIJKLMN

252 

253 result = runner.invoke( 1GHIJKLMN

254 app, 

255 [ 

256 "current-version", 

257 "--version-file", 

258 str(version_file), 

259 ], 

260 ) 

261 

262 assert result.exit_code == 0, result.output 1GHIJKLMN

263 assert result.output == "0.0.6\n" 1GHIJKLMN

264 

265 

266def test_cli_prints_release_notes(tmp_path: Path) -> None: 1abcdefgh

267 version_file = tmp_path / "src" / "fastapi_new" / "__init__.py" 1yzABCDEF

268 version_file.parent.mkdir(parents=True) 1yzABCDEF

269 version_file.write_text('__version__ = "0.0.7"\n') 1yzABCDEF

270 release_notes_file = tmp_path / "release-notes.md" 1yzABCDEF

271 release_notes_file.write_text( 1yzABCDEF

272 """# Release Notes 

273 

274## Latest Changes 

275 

276## 0.0.7 (2026-05-30) 

277 

278### Fixes 

279 

280* Fix something. 

281""" 

282 ) 

283 

284 result = runner.invoke( 1yzABCDEF

285 app, 

286 [ 

287 "release-notes", 

288 "--version-file", 

289 str(version_file), 

290 "--release-notes-file", 

291 str(release_notes_file), 

292 ], 

293 ) 

294 

295 assert result.exit_code == 0, result.output 1yzABCDEF

296 assert result.output == "### Fixes\n\n* Fix something.\n" 1yzABCDEF