11import contextlib
22import pathlib
3+ import subprocess
4+ from operator import attrgetter
35
46import pytest
57
@@ -12,6 +14,52 @@ def change_to_tmp_dir(tmp_path):
1214 yield tmp_path
1315
1416
17+ @pytest .fixture
18+ def create_git_tree (change_to_tmp_dir ):
19+ """Create a test Git repository with a predefined structure.
20+
21+ Creates:
22+ parent_folder/
23+ ├── file1.txt ("hello")
24+ └── child_folder/
25+ └── file2.txt ("world")
26+
27+ Returns:
28+ str: Hash value of the created Git tree
29+ """
30+
31+ parent_folder = change_to_tmp_dir / "parent_folder"
32+ parent_folder .mkdir ()
33+ file1 = parent_folder / "file1.txt"
34+ file1 .write_text ("hello" )
35+ #
36+ child_folder = parent_folder / "child_folder"
37+ child_folder .mkdir ()
38+ file2 = child_folder / "file2.txt"
39+ file2 .write_text ("world" )
40+
41+ for cmd in [
42+ ["git" , "init" , "." ],
43+ ["git" , "add" , "." ],
44+ ]:
45+ result = subprocess .run (
46+ cmd , cwd = change_to_tmp_dir , capture_output = True , text = True
47+ )
48+ if result .returncode != 0 :
49+ raise RuntimeError (f"Failed to run git command: { cmd } \n { result .stderr } " )
50+
51+ result = subprocess .run (
52+ ["git" , "write-tree" ], cwd = change_to_tmp_dir , capture_output = True , text = True
53+ )
54+ if result .returncode != 0 :
55+ raise RuntimeError (f"Failed to run git command: { cmd } \n { result .stderr } " )
56+ hash_value = result .stdout .strip ()
57+ if not hash_value or len (hash_value ) != 40 :
58+ raise RuntimeError (f"Failed to get tree hash: { hash_value } " )
59+
60+ return hash_value
61+
62+
1563class TestGit :
1664 def test_init_repo (self , change_to_tmp_dir ):
1765 git = Git ()
@@ -50,27 +98,45 @@ def test_hash_object(
5098 assert expected_path .exists () == write
5199 assert capsys .readouterr ().out == hash_value
52100
53- def test_write_tree (self , change_to_tmp_dir ):
101+ def test_write_tree (self , create_git_tree ):
54102 git = Git ()
55- git .init_repo ()
103+ entries = git .ls_tree (create_git_tree )
104+
105+ # Test that we have exactly one entry (parent_folder)
106+ assert len (entries ) == 1
107+
108+ # Test parent_folder properties
109+ parent_entry = entries [0 ]
110+ assert parent_entry .mode == b"40000" # Directory mode
111+ assert parent_entry .file_name == b"parent_folder"
112+
113+ # Get the contents of parent_folder
114+ parent_entries = git .ls_tree (parent_entry .hash )
115+
116+ # Should have two entries: file1.txt and child_folder
117+ assert len (parent_entries ) == 2
118+
119+ # Sort entries by filename for consistent testing
120+ parent_entries .sort (key = attrgetter ("file_name" ))
121+
122+ # Test child_folder
123+ child_folder_entry = parent_entries [0 ]
124+ assert child_folder_entry .mode == b"40000" # Directory mode
125+ assert child_folder_entry .file_name == b"child_folder"
126+
127+ # Test file1.txt
128+ file1_entry = parent_entries [1 ]
129+ assert file1_entry .mode == b"100644" # File mode
130+ assert file1_entry .file_name == b"file1.txt"
131+
132+ # Test contents of child_folder
133+ child_entries = git .ls_tree (child_folder_entry .hash )
134+
135+ # Should have one file: file2.txt
136+ assert len (child_entries ) == 1
137+ file2_entry = child_entries [0 ]
138+ assert file2_entry .mode == b"100644" # File mode
139+ assert file2_entry .file_name == b"file2.txt"
56140
57- parent_dir = change_to_tmp_dir / "parent_dir"
58- parent_dir .mkdir ()
59- file1 = parent_dir / "file1.txt"
60- file1 .write_text ("hello" )
61- file2 = parent_dir / "file2.txt"
62- file2 .write_text ("World" )
63- inner_dir = parent_dir / "inner_dir"
64- inner_dir .mkdir ()
65-
66- inner_file1 = inner_dir / "inner_file1.txt"
67- inner_file1 .write_text ("Hello World!" )
68-
69- # Create tree specifically for parent_dir
70- hash_values = git .create_tree ("parent_dir" )
71-
72- # Now we should see both files
73- entries = git .ls_tree (hash_values , name_only = True )
74- print (entries )
75- return
76- assert len (entries ) == 2
141+ assert git .cat_file (file1_entry .hash ).body == b"hello"
142+ assert git .cat_file (file2_entry .hash ).body == b"world"
0 commit comments