Coverage for tests/test_prepare_release.py: 100%

87 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-11-09 00:25 +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.18.0", BumpType.major, "1.0.0"), 

23 ("0.18.0", BumpType.minor, "0.19.0"), 

24 ("0.18.0", BumpType.patch, "0.18.1"), 

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 2jbkblbmbnbobpb

29 

30 

31def test_update_version_file() -> None: 1abcdefg

32 content = '__version__ = "0.18.0"\n' 1JKLMNOP

33 

34 new_content = update_version_file( 1JKLMNOP

35 content, "0.18.1", Path("src/fastapi_cloud_cli/__init__.py") 

36 ) 

37 

38 assert new_content == '__version__ = "0.18.1"\n' 1JKLMNOP

39 

40 

41def test_update_version_file_requires_newer_version() -> None: 1abcdefg

42 content = '__version__ = "0.18.0"\n' 1QRSTUVW

43 

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

45 update_version_file( 1QRSTUVW

46 content, "0.18.0", Path("src/fastapi_cloud_cli/__init__.py") 

47 ) 

48 

49 

50def test_update_release_notes() -> None: 1abcdefg

51 content = """# Release Notes 1XYZ0123

52 

53## Latest Changes 

54 

55### Fixes 

56 

57* Fix something. 

58 

59## 0.18.0 (2026-05-22) 

60 

61### Fixes 

62 

63* Previous fix. 

64""" 

65 

66 new_content = update_release_notes( 1XYZ0123

67 content, "0.18.1", date(2026, 5, 30), Path("release-notes.md") 

68 ) 

69 

70 assert ( 1XYZ0123

71 new_content 

72 == """# Release Notes 

73 

74## Latest Changes 

75 

76## 0.18.1 (2026-05-30) 

77 

78### Fixes 

79 

80* Fix something. 

81 

82## 0.18.0 (2026-05-22) 

83 

84### Fixes 

85 

86* Previous fix. 

87""" 

88 ) 

89 

90 

91def test_update_release_notes_rejects_existing_version() -> None: 1abcdefg

92 content = """# Release Notes 1456789!

93 

94## Latest Changes 

95 

96## 0.18.1 (2026-05-30) 

97""" 

98 

99 with pytest.raises(RuntimeError, match="already contain"): 1456789!

100 update_release_notes( 1456789!

101 content, "0.18.1", date(2026, 5, 30), Path("release-notes.md") 

102 ) 

103 

104 

105def test_get_release_notes_body_with_dated_heading() -> None: 1abcdefg

106 content = """# Release Notes 1#$%'()*

107 

108## Latest Changes 

109 

110## 0.18.1 (2026-05-30) 

111 

112### Fixes 

113 

114* Fix something. 

115 

116## 0.18.0 (2026-05-22) 

117 

118### Fixes 

119 

120* Previous fix. 

121""" 

122 

123 body = get_release_notes_body(content, "0.18.1", Path("release-notes.md")) 1#$%'()*

124 

125 assert ( 1#$%'()*

126 body 

127 == """### Fixes 

128 

129* Fix something. 

130""" 

131 ) 

132 

133 

134def test_get_release_notes_body_with_plain_heading() -> None: 1abcdefg

135 content = """# Release Notes 1+,-./:;

136 

137## Latest Changes 

138 

139## 0.18.1 

140 

141### Fixes 

142 

143* Fix something. 

144""" 

145 

146 body = get_release_notes_body(content, "0.18.1", Path("release-notes.md")) 1+,-./:;

147 

148 assert body == "### Fixes\n\n* Fix something.\n" 1+,-./:;

149 

150 

151def test_get_release_notes_body_allows_non_version_h2_content() -> None: 1abcdefg

152 content = """# Release Notes 1=?@[]^_

153 

154## Latest Changes 

155 

156## 0.18.1 

157 

158## Highlights 

159 

160* Fix something. 

161 

162## 0.18.0 

163 

164* Previous fix. 

165""" 

166 

167 body = get_release_notes_body(content, "0.18.1", Path("release-notes.md")) 1=?@[]^_

168 

169 assert body == "## Highlights\n\n* Fix something.\n" 1=?@[]^_

170 

171 

172def test_get_release_notes_body_requires_version_section() -> None: 1abcdefg

173 content = "# Release Notes\n\n## Latest Changes\n" 2` { | } ~ abbb

174 

175 with pytest.raises(RuntimeError, match="Could not find"): 2` { | } ~ abbb

176 get_release_notes_body(content, "0.18.1", Path("release-notes.md")) 2` { | } ~ abbb

177 

178 

179def test_get_release_notes_body_requires_non_empty_section() -> None: 1abcdefg

180 content = """# Release Notes 2cbdbebfbgbhbib

181 

182## Latest Changes 

183 

184## 0.18.1 

185 

186## 0.18.0 

187 

188* Previous fix. 

189""" 

190 

191 with pytest.raises(RuntimeError, match="is empty"): 2cbdbebfbgbhbib

192 get_release_notes_body(content, "0.18.1", Path("release-notes.md")) 2cbdbebfbgbhbib

193 

194 

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

196 version_file = tmp_path / "src" / "fastapi_cloud_cli" / "__init__.py" 1opqrstu

197 version_file.parent.mkdir(parents=True) 1opqrstu

198 version_file.write_text('__version__ = "0.18.0"\n') 1opqrstu

199 release_notes_file = tmp_path / "release-notes.md" 1opqrstu

200 release_notes_file.write_text( 1opqrstu

201 """# Release Notes 

202 

203## Latest Changes 

204 

205### Fixes 

206 

207* Fix something. 

208""" 

209 ) 

210 

211 result = runner.invoke( 1opqrstu

212 app, 

213 [ 

214 "prepare", 

215 "patch", 

216 "--version-file", 

217 str(version_file), 

218 "--release-notes-file", 

219 str(release_notes_file), 

220 "--date", 

221 "2026-05-30", 

222 ], 

223 ) 

224 

225 assert result.exit_code == 0, result.output 1opqrstu

226 assert "Prepared release 0.18.1 (2026-05-30)" in result.output 1opqrstu

227 assert version_file.read_text() == '__version__ = "0.18.1"\n' 1opqrstu

228 assert "## 0.18.1 (2026-05-30)" in release_notes_file.read_text() 1opqrstu

229 

230 

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

232 version_file = tmp_path / "src" / "fastapi_cloud_cli" / "__init__.py" 1hijklmn

233 version_file.parent.mkdir(parents=True) 1hijklmn

234 version_file.write_text('__version__ = "0.18.0"\n') 1hijklmn

235 release_notes_file = tmp_path / "release-notes.md" 1hijklmn

236 release_notes_file.write_text("# Release Notes\n\n## Latest Changes\n") 1hijklmn

237 monkeypatch.setenv("PREPARE_RELEASE_BUMP", "minor") 1hijklmn

238 monkeypatch.setenv("PREPARE_RELEASE_VERSION_FILE", str(version_file)) 1hijklmn

239 monkeypatch.setenv("PREPARE_RELEASE_RELEASE_NOTES_FILE", str(release_notes_file)) 1hijklmn

240 monkeypatch.setenv("PREPARE_RELEASE_DATE", "2026-05-30") 1hijklmn

241 

242 result = runner.invoke(app, ["prepare"]) 1hijklmn

243 

244 assert result.exit_code == 0, result.output 1hijklmn

245 assert "Prepared release 0.19.0 (2026-05-30)" in result.output 1hijklmn

246 assert version_file.read_text() == '__version__ = "0.19.0"\n' 1hijklmn

247 assert "## 0.19.0 (2026-05-30)" in release_notes_file.read_text() 1hijklmn

248 

249 

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

251 version_file = tmp_path / "src" / "fastapi_cloud_cli" / "__init__.py" 1CDEFGHI

252 version_file.parent.mkdir(parents=True) 1CDEFGHI

253 version_file.write_text('__version__ = "0.18.0"\n') 1CDEFGHI

254 

255 result = runner.invoke( 1CDEFGHI

256 app, 

257 [ 

258 "current-version", 

259 "--version-file", 

260 str(version_file), 

261 ], 

262 ) 

263 

264 assert result.exit_code == 0, result.output 1CDEFGHI

265 assert result.output == "0.18.0\n" 1CDEFGHI

266 

267 

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

269 version_file = tmp_path / "src" / "fastapi_cloud_cli" / "__init__.py" 1vwxyzAB

270 version_file.parent.mkdir(parents=True) 1vwxyzAB

271 version_file.write_text('__version__ = "0.18.1"\n') 1vwxyzAB

272 release_notes_file = tmp_path / "release-notes.md" 1vwxyzAB

273 release_notes_file.write_text( 1vwxyzAB

274 """# Release Notes 

275 

276## Latest Changes 

277 

278## 0.18.1 (2026-05-30) 

279 

280### Fixes 

281 

282* Fix something. 

283""" 

284 ) 

285 

286 result = runner.invoke( 1vwxyzAB

287 app, 

288 [ 

289 "release-notes", 

290 "--version-file", 

291 str(version_file), 

292 "--release-notes-file", 

293 str(release_notes_file), 

294 ], 

295 ) 

296 

297 assert result.exit_code == 0, result.output 1vwxyzAB

298 assert result.output == "### Fixes\n\n* Fix something.\n" 1vwxyzAB