test: add tests for commit author/committer attribution logic

Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) <noreply@aider.dev>
This commit is contained in:
Andrew Grigorev 2025-04-12 19:56:18 +03:00
parent d991cb6721
commit 3e1bc77bf2

View file

@ -420,6 +420,121 @@ class TestRepo(unittest.TestCase):
self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified (default True)
self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified (default True)
def test_commit_ai_edits_no_coauthor_explicit_false(self):
# Test AI edits (aider_edits=True) when co-authored-by is False,
# but author or committer attribution is explicitly disabled.
if platform.system() == "Windows":
return
with GitTemporaryDirectory():
# Setup repo
raw_repo = git.Repo()
raw_repo.config_writer().set_value("user", "name", "Test User").release()
raw_repo.config_writer().set_value("user", "email", "test@example.com").release()
fname = Path("file.txt")
fname.touch()
raw_repo.git.add(str(fname))
raw_repo.git.commit("-m", "initial commit")
io = InputOutput()
# Case 1: attribute_author = False, attribute_committer = None (default True)
mock_coder_no_author = MagicMock()
mock_coder_no_author.args.attribute_co_authored_by = False
mock_coder_no_author.args.attribute_author = False # Explicit False
mock_coder_no_author.args.attribute_committer = None # Default True
mock_coder_no_author.args.attribute_commit_message_author = False
mock_coder_no_author.args.attribute_commit_message_committer = False
mock_coder_no_author.main_model = MagicMock()
mock_coder_no_author.main_model.name = "gpt-test-no-author"
git_repo_no_author = GitRepo(io, None, None)
fname.write_text("no author content")
commit_result = git_repo_no_author.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder_no_author, message="Aider no author")
self.assertIsNotNone(commit_result)
commit = raw_repo.head.commit
self.assertNotIn("Co-authored-by:", commit.message)
self.assertEqual(commit.author.name, "Test User") # Explicit False
self.assertEqual(commit.committer.name, "Test User (aider)") # Default True
# Case 2: attribute_author = None (default True), attribute_committer = False
mock_coder_no_committer = MagicMock()
mock_coder_no_committer.args.attribute_co_authored_by = False
mock_coder_no_committer.args.attribute_author = None # Default True
mock_coder_no_committer.args.attribute_committer = False # Explicit False
mock_coder_no_committer.args.attribute_commit_message_author = False
mock_coder_no_committer.args.attribute_commit_message_committer = False
mock_coder_no_committer.main_model = MagicMock()
mock_coder_no_committer.main_model.name = "gpt-test-no-committer"
git_repo_no_committer = GitRepo(io, None, None)
fname.write_text("no committer content")
commit_result = git_repo_no_committer.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder_no_committer, message="Aider no committer")
self.assertIsNotNone(commit_result)
commit = raw_repo.head.commit
self.assertNotIn("Co-authored-by:", commit.message)
self.assertEqual(commit.author.name, "Test User (aider)") # Default True
self.assertEqual(commit.committer.name, "Test User") # Explicit False
def test_commit_user_edits_ignores_co_author(self):
# Test user edits (aider_edits=False) behavior regarding co-author and name attribution.
# Co-author should be ignored, Author never modified, Committer follows flag.
if platform.system() == "Windows":
return
with GitTemporaryDirectory():
# Setup repo
raw_repo = git.Repo()
raw_repo.config_writer().set_value("user", "name", "Test User").release()
raw_repo.config_writer().set_value("user", "email", "test@example.com").release()
fname = Path("file.txt")
fname.touch()
raw_repo.git.add(str(fname))
raw_repo.git.commit("-m", "initial commit")
io = InputOutput()
# Case 1: co_author=True, committer=None (default True)
mock_coder_user_default = MagicMock()
mock_coder_user_default.args.attribute_co_authored_by = True # Should be ignored
mock_coder_user_default.args.attribute_author = True # Should be ignored
mock_coder_user_default.args.attribute_committer = None # Default True
mock_coder_user_default.args.attribute_commit_message_author = False
mock_coder_user_default.args.attribute_commit_message_committer = False
mock_coder_user_default.main_model = MagicMock()
mock_coder_user_default.main_model.name = "gpt-user-default"
git_repo_user_default = GitRepo(io, None, None)
fname.write_text("user default content")
commit_result = git_repo_user_default.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_default, message="User default")
self.assertIsNotNone(commit_result)
commit = raw_repo.head.commit
self.assertNotIn("Co-authored-by:", commit.message) # Ignored
self.assertEqual(commit.author.name, "Test User") # Never modified
self.assertEqual(commit.committer.name, "Test User (aider)") # Default True
# Case 2: co_author=True, committer=False
mock_coder_user_no_committer = MagicMock()
mock_coder_user_no_committer.args.attribute_co_authored_by = True # Should be ignored
mock_coder_user_no_committer.args.attribute_author = True # Should be ignored
mock_coder_user_no_committer.args.attribute_committer = False # Explicit False
mock_coder_user_no_committer.args.attribute_commit_message_author = False
mock_coder_user_no_committer.args.attribute_commit_message_committer = False
mock_coder_user_no_committer.main_model = MagicMock()
mock_coder_user_no_committer.main_model.name = "gpt-user-no-committer"
# Need to init GitRepo with attribute_committer=False for this case
git_repo_user_no_committer = GitRepo(io, None, None, attribute_committer=False)
fname.write_text("user no committer content")
# Pass coder to simulate args being present, though GitRepo init matters more here
commit_result = git_repo_user_no_committer.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_no_committer, message="User no committer")
self.assertIsNotNone(commit_result)
commit = raw_repo.head.commit
self.assertNotIn("Co-authored-by:", commit.message) # Ignored
self.assertEqual(commit.author.name, "Test User") # Never modified
self.assertEqual(commit.committer.name, "Test User") # Explicit False
def test_get_tracked_files(self):
# Create a temporary directory