Coverage for tests / test_prepare_release.py: 100%

88 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-06-01 03:58 +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.0.17", "major", "1.0.0"), 

23 ("0.0.17", "minor", "0.1.0"), 

24 ("0.0.17", "patch", "0.0.18"), 

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.0.17"\n\nfrom ._main import syncify as syncify\n' 1JKLMNOP

33 

34 new_content = update_version_file(content, "0.0.18", Path("asyncer/__init__.py")) 1JKLMNOP

35 

36 assert ( 1JKLMNOP

37 new_content 

38 == '__version__ = "0.0.18"\n\nfrom ._main import syncify as syncify\n' 

39 ) 

40 

41 

42def test_update_version_file_requires_newer_version() -> None: 1abcdefg

43 content = '__version__ = "0.0.17"\n' 1QRSTUVW

44 

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

46 update_version_file(content, "0.0.17", Path("asyncer/__init__.py")) 1QRSTUVW

47 

48 

49def test_update_release_notes() -> None: 1abcdefg

50 content = """# Release Notes 1XYZ0123

51 

52## Latest Changes 

53 

54### Fixes 

55 

56* Fix something. 

57 

58## 0.0.17 (2026-02-21) 

59 

60### Fixes 

61 

62* Previous fix. 

63""" 

64 

65 new_content = update_release_notes( 1XYZ0123

66 content, "0.0.18", date(2026, 5, 30), Path("docs/release-notes.md") 

67 ) 

68 

69 assert ( 1XYZ0123

70 new_content 

71 == """# Release Notes 

72 

73## Latest Changes 

74 

75## 0.0.18 (2026-05-30) 

76 

77### Fixes 

78 

79* Fix something. 

80 

81## 0.0.17 (2026-02-21) 

82 

83### Fixes 

84 

85* Previous fix. 

86""" 

87 ) 

88 

89 

90def test_update_release_notes_rejects_existing_version() -> None: 1abcdefg

91 content = """# Release Notes 1456789!

92 

93## Latest Changes 

94 

95## 0.0.18 (2026-05-30) 

96""" 

97 

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

99 update_release_notes( 1456789!

100 content, "0.0.18", date(2026, 5, 30), Path("docs/release-notes.md") 

101 ) 

102 

103 

104def test_get_release_notes_body_with_dated_heading() -> None: 1abcdefg

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

106 

107## Latest Changes 

108 

109## 0.0.18 (2026-05-30) 

110 

111### Fixes 

112 

113* Fix something. 

114 

115## 0.0.17 (2026-02-21) 

116 

117### Fixes 

118 

119* Previous fix. 

120""" 

121 

122 body = get_release_notes_body(content, "0.0.18", Path("docs/release-notes.md")) 1#$%'()*

123 

124 assert ( 1#$%'()*

125 body 

126 == """### Fixes 

127 

128* Fix something. 

129""" 

130 ) 

131 

132 

133def test_get_release_notes_body_with_plain_heading() -> None: 1abcdefg

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

135 

136## Latest Changes 

137 

138## 0.0.18 

139 

140### Fixes 

141 

142* Fix something. 

143""" 

144 

145 body = get_release_notes_body(content, "0.0.18", Path("docs/release-notes.md")) 1+,-./:;

146 

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

148 

149 

150def test_get_release_notes_body_allows_non_version_h2_content() -> None: 1abcdefg

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

152 

153## Latest Changes 

154 

155## 0.0.18 

156 

157## Highlights 

158 

159* Fix something. 

160 

161## 0.0.17 

162 

163* Previous fix. 

164""" 

165 

166 body = get_release_notes_body(content, "0.0.18", Path("docs/release-notes.md")) 1=?@[]^_

167 

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

169 

170 

171def test_get_release_notes_body_requires_version_section() -> None: 1abcdefg

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

173 

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

175 get_release_notes_body(content, "0.0.18", Path("docs/release-notes.md")) 2` { | } ~ abbb

176 

177 

178def test_get_release_notes_body_requires_non_empty_section() -> None: 1abcdefg

179 content = """# Release Notes 2cbdbebfbgbhbib

180 

181## Latest Changes 

182 

183## 0.0.18 

184 

185## 0.0.17 

186 

187* Previous fix. 

188""" 

189 

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

191 get_release_notes_body(content, "0.0.18", Path("docs/release-notes.md")) 2cbdbebfbgbhbib

192 

193 

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

195 version_file = tmp_path / "asyncer" / "__init__.py" 1opqrstu

196 version_file.parent.mkdir() 1opqrstu

197 version_file.write_text('__version__ = "0.0.17"\n') 1opqrstu

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

199 release_notes_file.write_text( 1opqrstu

200 """# Release Notes 

201 

202## Latest Changes 

203 

204### Fixes 

205 

206* Fix something. 

207""" 

208 ) 

209 

210 result = runner.invoke( 1opqrstu

211 app, 

212 [ 

213 "prepare", 

214 "patch", 

215 "--version-file", 

216 str(version_file), 

217 "--release-notes-file", 

218 str(release_notes_file), 

219 "--date", 

220 "2026-05-30", 

221 ], 

222 ) 

223 

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

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

226 assert version_file.read_text() == '__version__ = "0.0.18"\n' 1opqrstu

227 assert "## 0.0.18 (2026-05-30)" in release_notes_file.read_text() 1opqrstu

228 

229 

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

231 version_file = tmp_path / "asyncer" / "__init__.py" 1hijklmn

232 version_file.parent.mkdir() 1hijklmn

233 version_file.write_text('__version__ = "0.0.17"\n') 1hijklmn

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

235 release_notes_file.parent.mkdir() 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.1.0 (2026-05-30)" in result.output 1hijklmn

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

247 assert "## 0.1.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 / "asyncer" / "__init__.py" 1CDEFGHI

252 version_file.parent.mkdir() 1CDEFGHI

253 version_file.write_text('__version__ = "0.0.17"\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.0.17\n" 1CDEFGHI

266 

267 

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

269 version_file = tmp_path / "asyncer" / "__init__.py" 1vwxyzAB

270 version_file.parent.mkdir() 1vwxyzAB

271 version_file.write_text('__version__ = "0.0.18"\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.0.18 (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