Skip to content

Commit c8aad80

Browse files
authored
docs: added docs for test files (coderamp-labs#104)
1 parent 56a945e commit c8aad80

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

tests/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def sample_query() -> dict[str, Any]:
2525

2626
@pytest.fixture
2727
def temp_directory(tmp_path: Path) -> Path:
28+
"""
2829
# Creates the following structure:
2930
# test_repo/
3031
# ├── file1.txt
@@ -39,6 +40,7 @@ def temp_directory(tmp_path: Path) -> Path:
3940
# | └── file_dir1.txt
4041
# └── dir2/
4142
# └── file_dir2.txt
43+
"""
4244

4345
test_dir = tmp_path / "test_repo"
4446
test_dir.mkdir()

tests/test_clone.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
@pytest.mark.asyncio
1111
async def test_clone_repo_with_commit() -> None:
12+
"""
13+
Test the `clone_repo` function when a specific commit hash is provided.
14+
Verifies that the repository is cloned and checked out to the specified commit.
15+
"""
1216
clone_config = CloneConfig(
1317
url="https://github.com/user/repo",
1418
local_path="/tmp/repo",
@@ -28,6 +32,10 @@ async def test_clone_repo_with_commit() -> None:
2832

2933
@pytest.mark.asyncio
3034
async def test_clone_repo_without_commit() -> None:
35+
"""
36+
Test the `clone_repo` function when no commit hash is provided.
37+
Verifies that only the repository clone operation is performed.
38+
"""
3139
query = CloneConfig(url="https://github.com/user/repo", local_path="/tmp/repo", commit=None, branch="main")
3240

3341
with patch("gitingest.clone._check_repo_exists", return_value=True) as mock_check:
@@ -43,6 +51,10 @@ async def test_clone_repo_without_commit() -> None:
4351

4452
@pytest.mark.asyncio
4553
async def test_clone_repo_nonexistent_repository() -> None:
54+
"""
55+
Test the `clone_repo` function when the repository does not exist.
56+
Verifies that a ValueError is raised with an appropriate error message.
57+
"""
4658
clone_config = CloneConfig(
4759
url="https://github.com/user/nonexistent-repo",
4860
local_path="/tmp/repo",
@@ -57,6 +69,10 @@ async def test_clone_repo_nonexistent_repository() -> None:
5769

5870
@pytest.mark.asyncio
5971
async def test_check_repo_exists() -> None:
72+
"""
73+
Test the `_check_repo_exists` function to verify if a repository exists.
74+
Covers cases for existing repositories, non-existing repositories (404), and failed requests.
75+
"""
6076
url = "https://github.com/user/repo"
6177

6278
with patch("asyncio.create_subprocess_exec", new_callable=AsyncMock) as mock_exec:
@@ -80,6 +96,10 @@ async def test_check_repo_exists() -> None:
8096

8197
@pytest.mark.asyncio
8298
async def test_clone_repo_invalid_url() -> None:
99+
"""
100+
Test the `clone_repo` function when an invalid or empty URL is provided.
101+
Verifies that a ValueError is raised with an appropriate error message.
102+
"""
83103
clone_config = CloneConfig(
84104
url="",
85105
local_path="/tmp/repo",
@@ -90,6 +110,10 @@ async def test_clone_repo_invalid_url() -> None:
90110

91111
@pytest.mark.asyncio
92112
async def test_clone_repo_invalid_local_path() -> None:
113+
"""
114+
Test the `clone_repo` function when an invalid or empty local path is provided.
115+
Verifies that a ValueError is raised with an appropriate error message.
116+
"""
93117
clone_config = CloneConfig(
94118
url="https://github.com/user/repo",
95119
local_path="",
@@ -100,6 +124,10 @@ async def test_clone_repo_invalid_local_path() -> None:
100124

101125
@pytest.mark.asyncio
102126
async def test_clone_repo_with_custom_branch() -> None:
127+
"""
128+
Test the `clone_repo` function when a custom branch is specified.
129+
Verifies that the repository is cloned with the specified branch using a shallow clone.
130+
"""
103131
clone_config = CloneConfig(
104132
url="https://github.com/user/repo",
105133
local_path="/tmp/repo",
@@ -122,6 +150,10 @@ async def test_clone_repo_with_custom_branch() -> None:
122150

123151
@pytest.mark.asyncio
124152
async def test_git_command_failure() -> None:
153+
"""
154+
Test the `clone_repo` function when a Git command fails during execution.
155+
Verifies that a RuntimeError is raised with an appropriate error message.
156+
"""
125157
clone_config = CloneConfig(
126158
url="https://github.com/user/repo",
127159
local_path="/tmp/repo",
@@ -134,6 +166,10 @@ async def test_git_command_failure() -> None:
134166

135167
@pytest.mark.asyncio
136168
async def test_clone_repo_default_shallow_clone() -> None:
169+
"""
170+
Test the `clone_repo` function with default shallow clone behavior.
171+
Verifies that the repository is cloned with `--depth=1` and `--single-branch` options.
172+
"""
137173
clone_config = CloneConfig(
138174
url="https://github.com/user/repo",
139175
local_path="/tmp/repo",
@@ -148,6 +184,10 @@ async def test_clone_repo_default_shallow_clone() -> None:
148184

149185
@pytest.mark.asyncio
150186
async def test_clone_repo_commit_without_branch() -> None:
187+
"""
188+
Test the `clone_repo` function when a commit hash is provided but no branch is specified.
189+
Verifies that the repository is cloned and checked out to the specified commit.
190+
"""
151191
clone_config = CloneConfig(
152192
url="https://github.com/user/repo",
153193
local_path="/tmp/repo",
@@ -163,6 +203,10 @@ async def test_clone_repo_commit_without_branch() -> None:
163203

164204
@pytest.mark.asyncio
165205
async def test_check_repo_exists_with_redirect() -> None:
206+
"""
207+
Test the `_check_repo_exists` function for handling HTTP redirects (302 Found).
208+
Verifies that it correctly identifies the repository's existence.
209+
"""
166210
url = "https://github.com/user/repo"
167211
with patch("asyncio.create_subprocess_exec", new_callable=AsyncMock) as mock_exec:
168212
mock_process = AsyncMock()

tests/test_parse_query.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010

1111
def test_parse_url_valid_https() -> None:
12+
"""
13+
Test `_parse_url` with valid HTTPS URLs from supported platforms (GitHub, GitLab, Bitbucket).
14+
Verifies that user and repository names are correctly extracted.
15+
"""
1216
test_cases = [
1317
"https://github.com/user/repo",
1418
"https://gitlab.com/user/repo",
@@ -22,6 +26,10 @@ def test_parse_url_valid_https() -> None:
2226

2327

2428
def test_parse_url_valid_http() -> None:
29+
"""
30+
Test `_parse_url` with valid HTTP URLs from supported platforms.
31+
Verifies that user and repository names, as well as the slug, are correctly extracted.
32+
"""
2533
test_cases = [
2634
"http://github.com/user/repo",
2735
"http://gitlab.com/user/repo",
@@ -35,12 +43,20 @@ def test_parse_url_valid_http() -> None:
3543

3644

3745
def test_parse_url_invalid() -> None:
46+
"""
47+
Test `_parse_url` with an invalid URL that does not include a repository structure.
48+
Verifies that a ValueError is raised with an appropriate error message.
49+
"""
3850
url = "https://only-domain.com"
3951
with pytest.raises(ValueError, match="Invalid repository URL"):
4052
_parse_url(url)
4153

4254

4355
def test_parse_query_basic() -> None:
56+
"""
57+
Test `parse_query` with basic inputs including valid repository URLs.
58+
Verifies that user and repository names, URL, and ignore patterns are correctly parsed.
59+
"""
4460
test_cases = ["https://github.com/user/repo", "https://gitlab.com/user/repo"]
4561
for url in test_cases:
4662
result = parse_query(url, max_file_size=50, from_web=True, ignore_patterns="*.txt")
@@ -51,19 +67,31 @@ def test_parse_query_basic() -> None:
5167

5268

5369
def test_parse_query_include_pattern() -> None:
70+
"""
71+
Test `parse_query` with an include pattern.
72+
Verifies that the include pattern is set correctly and default ignore patterns are applied.
73+
"""
5474
url = "https://github.com/user/repo"
5575
result = parse_query(url, max_file_size=50, from_web=True, include_patterns="*.py")
5676
assert result["include_patterns"] == ["*.py"]
5777
assert set(result["ignore_patterns"]) == set(DEFAULT_IGNORE_PATTERNS)
5878

5979

6080
def test_parse_query_invalid_pattern() -> None:
81+
"""
82+
Test `parse_query` with an invalid pattern containing special characters.
83+
Verifies that a ValueError is raised with an appropriate error message.
84+
"""
6185
url = "https://github.com/user/repo"
6286
with pytest.raises(ValueError, match="Pattern.*contains invalid characters"):
6387
parse_query(url, max_file_size=50, from_web=True, include_patterns="*.py;rm -rf")
6488

6589

6690
def test_parse_url_with_subpaths() -> None:
91+
"""
92+
Test `_parse_url` with a URL containing a branch and subpath.
93+
Verifies that user name, repository name, branch, and subpath are correctly extracted.
94+
"""
6795
url = "https://github.com/user/repo/tree/main/subdir/file"
6896
result = _parse_url(url)
6997
assert result["user_name"] == "user"
@@ -73,38 +101,62 @@ def test_parse_url_with_subpaths() -> None:
73101

74102

75103
def test_parse_url_invalid_repo_structure() -> None:
104+
"""
105+
Test `_parse_url` with an invalid repository structure in the URL.
106+
Verifies that a ValueError is raised with an appropriate error message.
107+
"""
76108
url = "https://github.com/user"
77109
with pytest.raises(ValueError, match="Invalid repository URL"):
78110
_parse_url(url)
79111

80112

81113
def test_parse_patterns_valid() -> None:
114+
"""
115+
Test `_parse_patterns` with valid patterns separated by commas.
116+
Verifies that the patterns are correctly parsed into a list.
117+
"""
82118
patterns = "*.py, *.md, docs/*"
83119
result = _parse_patterns(patterns)
84120
assert result == ["*.py", "*.md", "docs/*"]
85121

86122

87123
def test_parse_patterns_invalid_characters() -> None:
124+
"""
125+
Test `_parse_patterns` with invalid patterns containing special characters.
126+
Verifies that a ValueError is raised with an appropriate error message.
127+
"""
88128
patterns = "*.py;rm -rf"
89129
with pytest.raises(ValueError, match="Pattern.*contains invalid characters"):
90130
_parse_patterns(patterns)
91131

92132

93133
def test_parse_query_with_large_file_size() -> None:
134+
"""
135+
Test `parse_query` with a very large file size limit.
136+
Verifies that the file size limit and default ignore patterns are set correctly.
137+
"""
94138
url = "https://github.com/user/repo"
95139
result = parse_query(url, max_file_size=10**9, from_web=True)
96140
assert result["max_file_size"] == 10**9
97141
assert result["ignore_patterns"] == DEFAULT_IGNORE_PATTERNS
98142

99143

100144
def test_parse_query_empty_patterns() -> None:
145+
"""
146+
Test `parse_query` with empty include and ignore patterns.
147+
Verifies that the include patterns are set to None and default ignore patterns are applied.
148+
"""
101149
url = "https://github.com/user/repo"
102150
result = parse_query(url, max_file_size=50, from_web=True, include_patterns="", ignore_patterns="")
103151
assert result["include_patterns"] is None
104152
assert result["ignore_patterns"] == DEFAULT_IGNORE_PATTERNS
105153

106154

107155
def test_parse_query_include_and_ignore_overlap() -> None:
156+
"""
157+
Test `parse_query` with overlapping include and ignore patterns.
158+
Verifies that overlapping patterns are removed from the ignore patterns.
159+
"""
108160
url = "https://github.com/user/repo"
109161
result = parse_query(
110162
url,
@@ -119,6 +171,10 @@ def test_parse_query_include_and_ignore_overlap() -> None:
119171

120172

121173
def test_parse_query_local_path() -> None:
174+
"""
175+
Test `parse_query` with a local file path.
176+
Verifies that the local path is set, a unique ID is generated, and the slug is correctly created.
177+
"""
122178
path = "/home/user/project"
123179
result = parse_query(path, max_file_size=100, from_web=False)
124180
tail = Path("home/user/project")
@@ -128,6 +184,10 @@ def test_parse_query_local_path() -> None:
128184

129185

130186
def test_parse_query_relative_path() -> None:
187+
"""
188+
Test `parse_query` with a relative file path.
189+
Verifies that the local path and slug are correctly resolved.
190+
"""
131191
path = "./project"
132192
result = parse_query(path, max_file_size=100, from_web=False)
133193
tail = Path("project")
@@ -136,11 +196,19 @@ def test_parse_query_relative_path() -> None:
136196

137197

138198
def test_parse_query_empty_source() -> None:
199+
"""
200+
Test `parse_query` with an empty source input.
201+
Verifies that a ValueError is raised with an appropriate error message.
202+
"""
139203
with pytest.raises(ValueError, match="Invalid repository URL"):
140204
parse_query("", max_file_size=100, from_web=True)
141205

142206

143207
def test_parse_url_branch_and_commit_distinction() -> None:
208+
"""
209+
Test `_parse_url` with URLs containing either a branch name or a commit hash.
210+
Verifies that the branch and commit are correctly distinguished.
211+
"""
144212
url_branch = "https://github.com/user/repo/tree/main"
145213
url_commit = "https://github.com/user/repo/tree/abcd1234abcd1234abcd1234abcd1234abcd1234"
146214

@@ -155,13 +223,20 @@ def test_parse_url_branch_and_commit_distinction() -> None:
155223

156224

157225
def test_parse_query_uuid_uniqueness() -> None:
226+
"""
227+
Test `parse_query` to ensure that each call generates a unique UUID for the query result.
228+
"""
158229
path = "/home/user/project"
159230
result1 = parse_query(path, max_file_size=100, from_web=False)
160231
result2 = parse_query(path, max_file_size=100, from_web=False)
161232
assert result1["id"] != result2["id"]
162233

163234

164235
def test_parse_url_with_query_and_fragment() -> None:
236+
"""
237+
Test `_parse_url` with a URL containing query parameters and a fragment.
238+
Verifies that the URL is cleaned and other fields are correctly extracted.
239+
"""
165240
url = "https://github.com/user/repo?arg=value#fragment"
166241
result = _parse_url(url)
167242
assert result["user_name"] == "user"

0 commit comments

Comments
 (0)