Coverage for tests/test_end_to_end.py: 100.00%
83 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-02 00:26 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-02 00:26 +0200
1"""End-to-end tests."""
3from __future__ import annotations
5import re
6from typing import TYPE_CHECKING
7from urllib.parse import urlsplit, urlunsplit
9import pytest
11from git_changelog import Changelog
12from git_changelog.cli import build_and_render
13from git_changelog.commit import AngularConvention
14from git_changelog.templates import get_template
15from git_changelog.versioning import bump_semver
17if TYPE_CHECKING:
18 from pathlib import Path
20 from tests.helpers import GitRepo
22VERSIONS = ("0.1.0", "0.2.0", "0.2.1", "1.0.0", "1.1.0", "")
23VERSIONS_V = ("v0.1.0", "v0.2.0", "v0.2.1", "v1.0.0", "v1.1.0", "")
24KEEP_A_CHANGELOG = get_template("keepachangelog")
27@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
28def test_bumping_latest(repo: GitRepo) -> None:
29 """Bump latest version.
31 Parameters:
32 repo: Temporary Git repository (fixture).
33 """
34 changelog = Changelog(repo.path, convention=AngularConvention, bump="auto")
35 # features, no breaking changes: minor bumped
36 assert changelog.versions_list[0].planned_tag is not None
37 assert changelog.versions_list[0].planned_tag.lstrip("v") == bump_semver(
38 VERSIONS[-2],
39 "minor",
40 )
41 rendered = KEEP_A_CHANGELOG.render(changelog=changelog)
42 assert "Unreleased" not in rendered
45@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
46def test_not_bumping_latest(repo: GitRepo) -> None:
47 """Don't bump latest version.
49 Parameters:
50 repo: Temporary Git repository (fixture).
51 """
52 changelog = Changelog(repo.path, convention=AngularConvention, bump=None)
53 assert changelog.versions_list[0].planned_tag is None
54 rendered = KEEP_A_CHANGELOG.render(changelog=changelog)
55 assert "Unreleased" in rendered
58@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
59def test_rendering_custom_sections(repo: GitRepo) -> None:
60 """Render custom sections.
62 Parameters:
63 repo: Temporary Git repository (fixture).
64 """
65 changelog = Changelog(repo.path, convention=AngularConvention, sections=["feat"])
66 rendered = KEEP_A_CHANGELOG.render(changelog=changelog)
67 for section_type, section_title in AngularConvention.TYPES.items():
68 if section_type != "feat":
69 assert section_title not in rendered
72@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
73def test_rendering_in_place(repo: GitRepo, tmp_path: Path) -> None:
74 """Render changelog in-place.
76 Parameters:
77 repo: Temporary Git repository (fixture).
78 tmp_path: A temporary path to write the changelog into.
79 """
80 output = tmp_path.joinpath("changelog.md")
81 _, rendered = build_and_render(
82 str(repo.path),
83 convention="angular",
84 bump=None,
85 output=output.as_posix(),
86 template="keepachangelog",
87 )
88 assert len(re.findall("<!-- insertion marker -->", rendered)) == 2
89 assert "Unreleased" in rendered
90 latest_tag = "91.6.14"
91 assert latest_tag not in rendered
92 repo.git("tag", latest_tag)
93 build_and_render(
94 str(repo.path),
95 convention="angular",
96 bump="auto",
97 output=output.as_posix(),
98 template="keepachangelog",
99 in_place=True,
100 )
101 rendered = output.read_text()
102 assert len(re.findall("<!-- insertion marker -->", rendered)) == 1
103 assert "Unreleased" not in rendered
104 assert latest_tag in rendered
105 repo.git("tag", "-d", latest_tag)
108@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
109def test_no_duplicate_rendering(repo: GitRepo, tmp_path: Path) -> None:
110 """Render changelog in-place, and check for duplicate entries.
112 Parameters:
113 repo: Temporary Git repository (fixture).
114 tmp_path: A temporary path to write the changelog into.
115 """
116 output = tmp_path.joinpath("changelog.md")
117 _, rendered = build_and_render(
118 str(repo.path),
119 convention="angular",
120 bump="auto",
121 output=output.as_posix(),
122 template="keepachangelog",
123 )
125 # When bump_latest is True, there's only one insertion marker
126 assert len(re.findall("<!-- insertion marker -->", rendered)) == 1
127 latest_tag = "1.2.0"
128 assert latest_tag in rendered
130 rendered = output.read_text()
131 # The latest tag should appear exactly three times in the changelog
132 assert rendered.count(latest_tag) == 3
134 # Without tagging a new version, we should get an error
135 with pytest.raises(ValueError, match=r"Version .* already in changelog"):
136 build_and_render(
137 str(repo.path),
138 convention="angular",
139 bump="auto",
140 output=output.as_posix(),
141 template="keepachangelog",
142 in_place=True,
143 )
145 rendered = output.read_text()
146 # The latest tag should still appear exactly three times in the changelog
147 assert rendered.count(latest_tag) == 3
150@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
151def test_removing_credentials_from_remotes(repo: GitRepo) -> None:
152 """Remove credentials from remotes.
154 Parameters:
155 repo: Temporary Git repository (fixture).
156 """
157 credentials = [
158 "ghp_abcdefghijklmnOPQRSTUVWXYZ0123456789",
159 "ghs_abcdefghijklmnOPQRSTUVWXYZ0123456789",
160 "github_pat_abcdefgOPQRS0123456789_abcdefghijklmnOPQRSTUVWXYZ0123456789abcdefgOPQRS0123456789A",
161 "user:password",
162 ]
163 for creds in credentials:
164 repo.git("remote", "set-url", "origin", f"https://{creds}@github.com:example/example")
165 changelog = Changelog(repo.path)
166 assert creds not in changelog.remote_url
167 assert urlunsplit(urlsplit(changelog.remote_url)) == changelog.remote_url
170@pytest.mark.parametrize("repo", [VERSIONS, VERSIONS_V], indirect=True)
171def test_filter_commits_option(repo: GitRepo) -> None:
172 """Filter commit by revision-range argument.
174 Parameters:
175 repo: Temporary Git repository (fixture).
176 """
177 is_tag_with_v = repo.git("tag").split("\n")[0].startswith("v")
179 range = "1.0.0.."
180 expected = ["", "1.1.0"]
181 if is_tag_with_v:
182 range = "v1.0.0.."
183 expected = ["", "v1.1.0"]
185 changelog = Changelog(repo.path, filter_commits=range)
186 taglist = [version.tag for version in changelog.versions_list]
188 assert taglist == expected
190 err_msg = "Maybe the provided git-log revision-range is not valid"
191 with pytest.raises(ValueError, match=err_msg):
192 changelog = Changelog(repo.path, filter_commits="invalid")