|
| 1 | +"""Unit tests for changelog_generator.py""" |
| 2 | + |
| 3 | +import unittest |
| 4 | +from unittest.mock import patch |
| 5 | +import cfengine_cli.changelog as cg |
| 6 | + |
| 7 | + |
| 8 | +def _lines(*texts): |
| 9 | + """Return list of byte-lines as fetch_git_output would.""" |
| 10 | + return [t.encode() for t in texts] |
| 11 | + |
| 12 | + |
| 13 | +# =========================================================================== |
| 14 | +# collect_version_updates |
| 15 | +# =========================================================================== |
| 16 | +class TestCollectVersionUpdates(unittest.TestCase): |
| 17 | + |
| 18 | + def _run(self, subjects): |
| 19 | + lines = _lines(*subjects) |
| 20 | + with patch.object(cg, "fetch_git_output", return_value=lines): |
| 21 | + return cg.collect_version_updates(["../somerepo"], ["3.27.0..3.27.1"]) |
| 22 | + |
| 23 | + def test_single_update(self): |
| 24 | + result = self._run(["Updated dependency 'openssl' from version 1.1.1 to 3.0.0"]) |
| 25 | + self.assertEqual( |
| 26 | + result, ["Updated dependency 'openssl' from version 1.1.1 to 3.0.0"] |
| 27 | + ) |
| 28 | + |
| 29 | + def test_revert_cancels_update(self): |
| 30 | + result = self._run( |
| 31 | + [ |
| 32 | + "Updated dependency 'openssl' from version 1.1.1 to 3.0.0", |
| 33 | + "Revert \"Updated dependency 'openssl' from version 1.1.1 to 3.0.0\"", |
| 34 | + ] |
| 35 | + ) |
| 36 | + self.assertEqual(result, []) |
| 37 | + |
| 38 | + def test_reapply_after_revert(self): |
| 39 | + result = self._run( |
| 40 | + [ |
| 41 | + "Updated dependency 'openssl' from version 1.1.1 to 3.0.0", |
| 42 | + "Revert \"Updated dependency 'openssl' from version 1.1.1 to 3.0.0\"", |
| 43 | + "Reapply \"Updated dependency 'openssl' from version 1.1.1 to 3.0.0\"", |
| 44 | + ] |
| 45 | + ) |
| 46 | + self.assertEqual( |
| 47 | + result, ["Updated dependency 'openssl' from version 1.1.1 to 3.0.0"] |
| 48 | + ) |
| 49 | + |
| 50 | + def test_chain_collapses_to_first_from_last_to(self): |
| 51 | + result = self._run( |
| 52 | + [ |
| 53 | + "Updated dependency 'zlib' from version 1.0 to 1.1", |
| 54 | + "Updated dependency 'zlib' from version 1.1 to 1.2", |
| 55 | + ] |
| 56 | + ) |
| 57 | + self.assertEqual(result, ["Updated dependency 'zlib' from version 1.0 to 1.2"]) |
| 58 | + |
| 59 | + def test_multiple_deps_sorted(self): |
| 60 | + result = self._run( |
| 61 | + [ |
| 62 | + "Updated dependency 'zlib' from version 1.0 to 1.1", |
| 63 | + "Updated dependency 'openssl' from version 1.1.1 to 3.0.0", |
| 64 | + ] |
| 65 | + ) |
| 66 | + self.assertEqual(result[0].split("'")[1], "openssl") |
| 67 | + self.assertEqual(result[1].split("'")[1], "zlib") |
| 68 | + |
| 69 | + def test_no_deps(self): |
| 70 | + result = self._run(["Fix some bug", "Add a feature"]) |
| 71 | + self.assertEqual(result, []) |
| 72 | + |
| 73 | + |
| 74 | +# =========================================================================== |
| 75 | +# Main logic / git parsing tests |
| 76 | +# =========================================================================== |
| 77 | +class TestParseSha(unittest.TestCase): |
| 78 | + def __init__(self, *args, **kwargs): |
| 79 | + super(TestParseSha, self).__init__(*args, **kwargs) |
| 80 | + self.repo = "enterprise" |
| 81 | + self.SHA = b"TEST" |
| 82 | + self.SHA_STR = "TEST" |
| 83 | + |
| 84 | + def _run(self, commit_text, entries=None, sha_to_tracker=None, linked_shas=None): |
| 85 | + entries = {} if entries is None else entries |
| 86 | + sha_to_tracker = {} if sha_to_tracker is None else sha_to_tracker |
| 87 | + linked_shas = {} if linked_shas is None else linked_shas |
| 88 | + |
| 89 | + lines = _lines(commit_text) |
| 90 | + with patch.object(cg, "fetch_git_output", return_value=lines): |
| 91 | + cg.parse_sha(self.SHA, entries, sha_to_tracker, linked_shas, self.repo) |
| 92 | + |
| 93 | + return entries, sha_to_tracker, linked_shas |
| 94 | + |
| 95 | + def test_body_keyword(self): |
| 96 | + commit = "fix: something\n\nThis is the body text.\nChangelog: Body" |
| 97 | + entries, *_ = self._run(commit) |
| 98 | + self.assertIn("This is the body text.", entries[self.SHA_STR]) |
| 99 | + |
| 100 | + def test_commit_keyword(self): |
| 101 | + commit = "fix: something\n\nThis is the body text.\nChangelog: Commit" |
| 102 | + entries, *_ = self._run(commit) |
| 103 | + self.assertIn("This is the body text.", entries[self.SHA_STR]) |
| 104 | + |
| 105 | + def test_changelog_none(self): |
| 106 | + lines = "fix: something\n\nA thing was fixed.\nChangelog: none\nSigned-off-by: someone" |
| 107 | + self.assertDictEqual(self._run(lines)[0], {}) |
| 108 | + |
| 109 | + def test_custom_multiline(self): |
| 110 | + commit = "fix: something\n\nChangelog: Line one\n line two continued\nSigned-off-by: x" |
| 111 | + entries, *_ = self._run(commit) |
| 112 | + entry_text = entries[self.SHA_STR][0] |
| 113 | + self.assertIn("Line one", entry_text) |
| 114 | + self.assertIn("line two continued", entry_text) |
| 115 | + |
| 116 | + def test_uses_title(self): |
| 117 | + commit = "feat: shiny new feature\n\nChangelog: Title" |
| 118 | + entries, *_ = self._run(commit) |
| 119 | + self.assertIn("feat: shiny new feature", entries[self.SHA_STR]) |
| 120 | + |
| 121 | + def test_title_with_trailing_period(self): |
| 122 | + commit = "feat: shiny new feature\n\nChangelog: Title." |
| 123 | + entries, *_ = self._run(commit) |
| 124 | + self.assertIn("feat: shiny new feature", entries[self.SHA_STR]) |
| 125 | + |
| 126 | + def test_cherry_pick_links_shas(self): |
| 127 | + other = "aabbccdd" |
| 128 | + commit = ( |
| 129 | + f"fix: something\n\nChangelog: Title\n(cherry picked from commit {other})" |
| 130 | + ) |
| 131 | + _, _, linked_shas = self._run(commit) |
| 132 | + self.assertIn(other, linked_shas.get(self.SHA_STR, [])) |
| 133 | + self.assertIn(self.SHA_STR, linked_shas.get(other, [])) |
| 134 | + |
| 135 | + def test_no_tracker_no_entry(self): |
| 136 | + commit = "fix: plain commit\n\nChangelog: Title" |
| 137 | + _, sha_to_tracker, _ = self._run(commit) |
| 138 | + self.assertNotIn(self.SHA_STR, sha_to_tracker) |
| 139 | + |
| 140 | + def test_jira_tracker_extracted(self): |
| 141 | + commit = "CFE-456 fix something\n\nChangelog: Title" |
| 142 | + _, sha_to_tracker, _ = self._run(commit) |
| 143 | + self.assertIn(self.SHA_STR, sha_to_tracker) |
| 144 | + self.assertTrue( |
| 145 | + any("CFE-456" in t for t in sha_to_tracker[self.SHA_STR]), |
| 146 | + f"Expected CFE-456 in tracker set, got: {sha_to_tracker}", |
| 147 | + ) |
0 commit comments