Skip to content

Commit 02d6513

Browse files
committed
100% coverage for repo.py
1 parent 96daea1 commit 02d6513

File tree

1 file changed

+142
-1
lines changed

1 file changed

+142
-1
lines changed

tests/test_repo.py

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import unittest
21
import os, sys
32
import shutil
43
from pathlib import Path
4+
import unittest
5+
from parameterized import parameterized
56
from unittest.mock import patch, MagicMock
67
from agentstack import conf
78
from agentstack import repo
9+
from agentstack.repo import TrackingDisabledError
810
from agentstack.exceptions import EnvironmentError
911
import git
1012

1113

14+
1215
BASE_PATH = Path(__file__).parent
1316

1417

@@ -75,6 +78,81 @@ def test_get_uncommitted_files_modified_file(self):
7578
uncommitted = repo.get_uncommitted_files()
7679
self.assertIn("initial_file.txt", uncommitted)
7780

81+
@patch('agentstack.repo.conf.ConfigFile')
82+
def test_should_track_changes_default(self, mock_config_file):
83+
mock_config = MagicMock()
84+
mock_config.use_git = True
85+
mock_config_file.return_value = mock_config
86+
87+
self.assertTrue(repo.should_track_changes())
88+
89+
@patch('agentstack.repo.conf.ConfigFile')
90+
def test_should_track_changes_disabled(self, mock_config_file):
91+
mock_config = MagicMock()
92+
mock_config.use_git = False
93+
mock_config_file.return_value = mock_config
94+
95+
self.assertFalse(repo.should_track_changes())
96+
97+
@patch('agentstack.repo.conf.ConfigFile')
98+
def test_should_track_changes_file_not_found(self, mock_config_file):
99+
mock_config_file.side_effect = FileNotFoundError
100+
101+
self.assertTrue(repo.should_track_changes())
102+
103+
def test_dont_track_changes(self):
104+
# Ensure tracking is enabled initially
105+
repo._USE_GIT = None
106+
self.assertTrue(repo.should_track_changes())
107+
108+
# Disable tracking
109+
repo.dont_track_changes()
110+
self.assertFalse(repo.should_track_changes())
111+
112+
# Reset _USE_GIT for other tests
113+
repo._USE_GIT = None
114+
115+
@patch('agentstack.repo.should_track_changes', return_value=False)
116+
def test_require_git_when_disabled(self, mock_should_track):
117+
with self.assertRaises(TrackingDisabledError):
118+
repo._require_git()
119+
120+
def test_require_git_when_disabled_manually(self):
121+
# Disable git tracking
122+
repo.dont_track_changes()
123+
124+
with self.assertRaises(repo.TrackingDisabledError):
125+
repo._require_git()
126+
127+
# Reset _USE_GIT for other tests
128+
repo._USE_GIT = None
129+
130+
@parameterized.expand([
131+
("apt", "/usr/bin/apt", "Hint: run `sudo apt install git`"),
132+
("brew", "/usr/local/bin/brew", "Hint: run `brew install git`"),
133+
("port", "/opt/local/bin/port", "Hint: run `sudo port install git`"),
134+
("none", None, ""),
135+
])
136+
@patch('agentstack.repo.should_track_changes', return_value=True)
137+
@patch('agentstack.repo.shutil.which')
138+
def test_require_git_not_installed(self, name, package_manager_path, expected_hint, mock_which, mock_should_track):
139+
mock_which.side_effect = lambda x: None if x != name else package_manager_path
140+
141+
with self.assertRaises(EnvironmentError) as context:
142+
repo._require_git()
143+
144+
error_message = str(context.exception)
145+
self.assertIn("git is not installed.", error_message)
146+
147+
if expected_hint:
148+
self.assertIn(expected_hint, error_message)
149+
150+
@patch('agentstack.repo.should_track_changes', return_value=True)
151+
@patch('agentstack.repo.shutil.which', return_value='/usr/bin/git')
152+
def test_require_git_installed(self, mock_which, mock_should_track):
153+
# This should not raise an exception
154+
repo._require_git()
155+
78156
def test_transaction_context_manager(self):
79157
repo.init()
80158
mock_commit = MagicMock()
@@ -112,3 +190,66 @@ def test_transaction_no_changes(self):
112190
assert repo.get_uncommitted_files() == []
113191

114192
mock_commit.assert_not_called()
193+
194+
def test_transaction_with_exception(self):
195+
repo.init()
196+
mock_commit = MagicMock()
197+
198+
with patch('agentstack.repo.commit', mock_commit):
199+
try:
200+
with repo.Transaction() as transaction:
201+
(self.test_dir / "test_file.txt").touch()
202+
transaction.add_message("This message should not be committed")
203+
raise ValueError("Test exception")
204+
except ValueError:
205+
pass
206+
207+
mock_commit.assert_not_called()
208+
209+
# Verify that the file was created but not committed
210+
self.assertTrue((self.test_dir / "test_file.txt").exists())
211+
self.assertIn("test_file.txt", repo.get_uncommitted_files())
212+
213+
def test_init_when_git_disabled(self):
214+
repo.dont_track_changes()
215+
result = repo.init()
216+
self.assertIsNone(result)
217+
repo._USE_GIT = None # Reset for other tests
218+
219+
def test_commit_when_git_disabled(self):
220+
repo.dont_track_changes()
221+
result = repo.commit("Test message", ["test_file.txt"])
222+
self.assertIsNone(result)
223+
repo._USE_GIT = None # Reset for other tests
224+
225+
def test_commit_all_changes_when_git_disabled(self):
226+
repo.dont_track_changes()
227+
result = repo.commit_all_changes("Test message")
228+
self.assertIsNone(result)
229+
repo._USE_GIT = None # Reset for other tests
230+
231+
def test_get_uncommitted_files_when_git_disabled(self):
232+
repo.dont_track_changes()
233+
result = repo.get_uncommitted_files()
234+
self.assertEqual(result, [])
235+
repo._USE_GIT = None # Reset for other tests
236+
237+
def test_commit_user_changes(self):
238+
repo.init()
239+
240+
# Create a new file
241+
test_file = self.test_dir / "user_file.txt"
242+
test_file.write_text("User content")
243+
244+
# Commit user changes
245+
repo.commit_user_changes()
246+
247+
# Check if the file was committed
248+
git_repo = git.Repo(self.test_dir)
249+
commits = list(git_repo.iter_commits())
250+
251+
self.assertEqual(len(commits), 2) # Initial commit + user changes commit
252+
self.assertEqual(commits[0].message, f"{repo.USER_CHANGES_COMMIT_MESSAGE}{repo.AUTOMATION_NOTE}")
253+
254+
# Check if the file is no longer in uncommitted files
255+
self.assertNotIn("user_file.txt", repo.get_uncommitted_files())

0 commit comments

Comments
 (0)