Skip to content

Commit 9a5126a

Browse files
committed
Add test cases for list commands
* Added majority of tests for list commands. Should handle most cases and bring the coverage up to 90+% now. * Fixed some small instances in the git commit per year function where some values might not be legit thanks to the test cases.
1 parent 013abc7 commit 9a5126a

File tree

3 files changed

+244
-29
lines changed

3 files changed

+244
-29
lines changed

git_py_stats/list_cmds.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -646,15 +646,26 @@ def git_commits_per_year(config: Dict[str, Union[str, int]]) -> None:
646646
output = run_git_command(cmd)
647647
if output:
648648
print("Git commits by year:\n")
649+
649650
# Split the output into individual years
651+
# Handle cases in case there are no commits found
650652
years = output.split("\n")
651-
counter = collections.Counter(years)
653+
years = [year for year in years if year.strip()]
654+
if not years:
655+
print("No valid years found in commits.")
656+
return
652657

653-
# Determine the range of years
654-
# TODO: This will need to be adjustable later
658+
# Count the frequency of each year
659+
# Handle cases in case years weren't valid
660+
counter = collections.Counter(years)
655661
all_years = sorted(counter.keys())
656-
start_year = int(all_years[0])
657-
end_year = int(all_years[-1])
662+
try:
663+
start_year = int(all_years[0])
664+
end_year = int(all_years[-1])
665+
except (ValueError, IndexError):
666+
# In case the conversion fails
667+
print("No valid years found in commits.")
668+
return
658669

659670
# Initialize commit counts for all years in range
660671
commit_counts = {year: 0 for year in range(start_year, end_year + 1)}

git_py_stats/tests/test_list_cmds.py

+216-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class TestListCmds(unittest.TestCase):
77
"""
8-
Unit test class for testing list_cmds.
8+
Unit test class for testing list_cmds functions.
99
"""
1010

1111
def setUp(self):
@@ -24,26 +24,231 @@ def setUp(self):
2424
@patch("git_py_stats.list_cmds.print")
2525
def test_branch_tree(self, mock_print, mock_run_git_command) -> None:
2626
"""
27-
Test case for the branch_tree function in the list_cmds module.
28-
29-
Checks if `branch_tree` executes without errors and returns `None`.
30-
The print function is mocked to prevent actual output during testing.
31-
32-
The test verifies that the function runs without raising any exceptions and
33-
calls the print function at least once, indicating that some output was generated.
27+
Test case for the branch_tree function.
3428
"""
35-
# Mock git command output to provide a sample branch tree
3629
mock_run_git_command.return_value = (
3730
"* 12345 Commit message\n"
3831
"| * 67890 Another commit message\n"
3932
"| * abcde Yet another commit message\n"
4033
)
4134

42-
# Call function with mock configuration
4335
list_cmds.branch_tree(self.mock_config)
4436

45-
# Assert that print was called at least once
4637
mock_print.assert_called()
38+
mock_run_git_command.assert_called_once()
39+
40+
@patch("git_py_stats.list_cmds.run_git_command")
41+
@patch("git_py_stats.list_cmds.print")
42+
def test_branch_tree_no_data(self, mock_print, mock_run_git_command) -> None:
43+
"""
44+
Test case for branch_tree with no data.
45+
"""
46+
mock_run_git_command.return_value = ""
47+
list_cmds.branch_tree(self.mock_config)
48+
49+
mock_print.assert_called_with("No data available.")
50+
51+
@patch("git_py_stats.list_cmds.run_git_command")
52+
@patch("git_py_stats.list_cmds.print")
53+
def test_branches_by_date(self, mock_print, mock_run_git_command) -> None:
54+
"""
55+
Test case for branches_by_date function.
56+
"""
57+
mock_run_git_command.return_value = (
58+
"[2021-01-01] Author1 branch1\n" "[2021-01-02] Author2 branch2\n"
59+
)
60+
list_cmds.branches_by_date()
61+
62+
mock_print.assert_called()
63+
mock_run_git_command.assert_called_once()
64+
65+
@patch("git_py_stats.list_cmds.run_git_command")
66+
@patch("git_py_stats.list_cmds.print")
67+
def test_branches_by_date_no_data(self, mock_print, mock_run_git_command) -> None:
68+
"""
69+
Test case for branches_by_date with no data.
70+
"""
71+
mock_run_git_command.return_value = ""
72+
list_cmds.branches_by_date()
73+
74+
mock_print.assert_called_with("No commits found.")
75+
76+
@patch("git_py_stats.list_cmds.run_git_command")
77+
@patch("git_py_stats.list_cmds.print")
78+
def test_contributors(self, mock_print, mock_run_git_command) -> None:
79+
"""
80+
Test case for the contributors function.
81+
"""
82+
mock_run_git_command.return_value = "Author1\nAuthor2\nAuthor3\n"
83+
list_cmds.contributors(self.mock_config)
84+
85+
mock_print.assert_called()
86+
mock_run_git_command.assert_called_once()
87+
88+
@patch("git_py_stats.list_cmds.run_git_command")
89+
@patch("git_py_stats.list_cmds.print")
90+
def test_contributors_no_data(self, mock_print, mock_run_git_command) -> None:
91+
"""
92+
Test case for contributors with no data.
93+
"""
94+
mock_run_git_command.return_value = ""
95+
list_cmds.contributors(self.mock_config)
96+
97+
mock_print.assert_called_with("No contributors found.")
98+
99+
@patch("git_py_stats.list_cmds.run_git_command")
100+
@patch("git_py_stats.list_cmds.print")
101+
def test_new_contributors(self, mock_print, mock_run_git_command) -> None:
102+
"""
103+
Test case for new_contributors function.
104+
"""
105+
mock_run_git_command.return_value = "[email protected]|1577836800\n"
106+
list_cmds.new_contributors(self.mock_config, "2020-01-01")
107+
108+
mock_print.assert_called()
109+
mock_run_git_command.assert_called_once()
110+
111+
@patch("git_py_stats.list_cmds.run_git_command")
112+
@patch("git_py_stats.list_cmds.print")
113+
def test_new_contributors_invalid_date(self, mock_print, mock_run_git_command) -> None:
114+
"""
115+
Test case for new_contributors with invalid date.
116+
"""
117+
list_cmds.new_contributors(self.mock_config, "invalid-date")
118+
119+
mock_print.assert_called_with("Invalid date format. Please use YYYY-MM-DD.")
120+
mock_run_git_command.assert_not_called()
121+
122+
@patch("git_py_stats.list_cmds.run_git_command")
123+
@patch("git_py_stats.list_cmds.print")
124+
def test_git_commits_per_author(self, mock_print, mock_run_git_command) -> None:
125+
"""
126+
Test case for git_commits_per_author function.
127+
"""
128+
mock_run_git_command.return_value = "Author:Author1 <[email protected]>\n"
129+
list_cmds.git_commits_per_author(self.mock_config)
130+
131+
mock_print.assert_called()
132+
mock_run_git_command.assert_called_once()
133+
134+
@patch("git_py_stats.list_cmds.run_git_command")
135+
@patch("git_py_stats.list_cmds.print")
136+
def test_git_commits_per_author_no_data(self, mock_print, mock_run_git_command) -> None:
137+
"""
138+
Test case for git_commits_per_author with no data.
139+
"""
140+
mock_run_git_command.return_value = ""
141+
list_cmds.git_commits_per_author(self.mock_config)
142+
143+
mock_print.assert_called_with("No commits found.")
144+
145+
@patch("git_py_stats.list_cmds.run_git_command")
146+
@patch("git_py_stats.list_cmds.print")
147+
def test_git_commits_per_date(self, mock_print, mock_run_git_command) -> None:
148+
"""
149+
Test case for git_commits_per_date function.
150+
"""
151+
mock_run_git_command.return_value = "2021-01-01\n2021-01-01\n2021-01-02\n"
152+
list_cmds.git_commits_per_date(self.mock_config)
153+
154+
mock_print.assert_called()
155+
mock_run_git_command.assert_called_once()
156+
157+
@patch("git_py_stats.list_cmds.run_git_command")
158+
@patch("git_py_stats.list_cmds.print")
159+
def test_git_commits_per_date_no_data(self, mock_print, mock_run_git_command) -> None:
160+
"""
161+
Test case for git_commits_per_date with no data.
162+
"""
163+
mock_run_git_command.return_value = ""
164+
list_cmds.git_commits_per_date(self.mock_config)
165+
166+
mock_print.assert_called_with("No commits found.")
167+
168+
@patch("git_py_stats.list_cmds.run_git_command")
169+
@patch("git_py_stats.list_cmds.print")
170+
def test_git_commits_per_month(self, mock_print, mock_run_git_command) -> None:
171+
"""
172+
Test case for git_commits_per_month function.
173+
"""
174+
mock_run_git_command.return_value = "Jan\nJan\nFeb\n"
175+
list_cmds.git_commits_per_month(self.mock_config)
176+
177+
mock_print.assert_called()
178+
mock_run_git_command.assert_called_once()
179+
180+
@patch("git_py_stats.list_cmds.run_git_command")
181+
@patch("git_py_stats.list_cmds.print")
182+
def test_git_commits_per_year(self, mock_print, mock_run_git_command) -> None:
183+
"""
184+
Test case for git_commits_per_year function.
185+
"""
186+
mock_run_git_command.return_value = "2020\n2021\n2021\n2022\n"
187+
list_cmds.git_commits_per_year(self.mock_config)
188+
189+
mock_print.assert_any_call("Git commits by year:\n")
190+
self.assertGreater(mock_print.call_count, 1)
191+
mock_run_git_command.assert_called_once()
192+
193+
@patch("git_py_stats.list_cmds.run_git_command")
194+
@patch("git_py_stats.list_cmds.print")
195+
def test_git_commits_per_year_empty(self, mock_print, mock_run_git_command) -> None:
196+
"""
197+
Test case for git_commits_per_year with empty data.
198+
"""
199+
mock_run_git_command.return_value = "" # No output
200+
list_cmds.git_commits_per_year(self.mock_config)
201+
202+
mock_print.assert_called_with("No commits found.")
203+
mock_run_git_command.assert_called_once()
204+
205+
@patch("git_py_stats.list_cmds.run_git_command")
206+
@patch("git_py_stats.list_cmds.print")
207+
def test_git_commits_per_year_invalid_data(self, mock_print, mock_run_git_command) -> None:
208+
"""
209+
Test case for git_commits_per_year with invalid data.
210+
"""
211+
mock_run_git_command.return_value = "\n\n\n" # Invalid output, just new lines
212+
list_cmds.git_commits_per_year(self.mock_config)
213+
214+
mock_print.assert_called_with("No valid years found in commits.")
215+
mock_run_git_command.assert_called_once()
216+
217+
@patch("git_py_stats.list_cmds.run_git_command")
218+
@patch("git_py_stats.list_cmds.print")
219+
def test_git_commits_per_weekday(self, mock_print, mock_run_git_command) -> None:
220+
"""
221+
Test case for git_commits_per_weekday function.
222+
"""
223+
mock_run_git_command.return_value = "Mon\nTue\nWed\n"
224+
list_cmds.git_commits_per_weekday(self.mock_config)
225+
226+
mock_print.assert_called()
227+
mock_run_git_command.assert_called_once()
228+
229+
@patch("git_py_stats.list_cmds.run_git_command")
230+
@patch("git_py_stats.list_cmds.print")
231+
def test_git_commits_per_hour(self, mock_print, mock_run_git_command) -> None:
232+
"""
233+
Test case for git_commits_per_hour function.
234+
"""
235+
mock_run_git_command.return_value = "10\n11\n12\n"
236+
list_cmds.git_commits_per_hour(self.mock_config)
237+
238+
mock_print.assert_called()
239+
mock_run_git_command.assert_called_once()
240+
241+
@patch("git_py_stats.list_cmds.run_git_command")
242+
@patch("git_py_stats.list_cmds.print")
243+
def test_git_commits_per_timezone(self, mock_print, mock_run_git_command) -> None:
244+
"""
245+
Test case for git_commits_per_timezone function.
246+
"""
247+
mock_run_git_command.return_value = "+0200\n-0500\n+0200\n"
248+
list_cmds.git_commits_per_timezone(self.mock_config)
249+
250+
mock_print.assert_called()
251+
mock_run_git_command.assert_called_once()
47252

48253

49254
if __name__ == "__main__":

setup.py

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
from setuptools import setup, find_packages
22

33
setup(
4-
name='git-py-stats',
5-
version='0.1',
4+
name="git-py-stats",
5+
version="0.1",
66
packages=find_packages(
77
exclude=["*.tests", "*.tests.*", "tests.*", "tests"]
88
), # Exclude test packages
99
entry_points={
10-
'console_scripts': [
11-
'git-py-stats=git_py_stats.main:main',
10+
"console_scripts": [
11+
"git-py-stats=git_py_stats.main:main",
1212
],
1313
},
1414
install_requires=[
1515
# Nothing
1616
],
1717
data_files=[
1818
# Manpages
19-
('share/man/man1', ['man/git-py-stats.1']),
19+
("share/man/man1", ["man/git-py-stats.1"]),
2020
],
21-
description='A Python Implementation of git-quick-stats',
22-
long_description=open('README.md').read(),
23-
long_description_content_type='text/markdown',
24-
author='Tom Ice',
25-
license='MIT',
26-
url='https://github.com/tomice/git-py-stats',
27-
python_requires='>=3.6',
21+
description="A Python Implementation of git-quick-stats",
22+
long_description=open("README.md").read(),
23+
long_description_content_type="text/markdown",
24+
author="Tom Ice",
25+
license="MIT",
26+
url="https://github.com/tomice/git-py-stats",
27+
python_requires=">=3.6",
2828
)
29-

0 commit comments

Comments
 (0)