@@ -22,6 +22,113 @@ def setUp(self):
22
22
"menu_theme" : "" ,
23
23
}
24
24
25
+ def _extract_printed_authors (self , mock_print ):
26
+ """
27
+ Return the list of author display lines in the order they were printed.
28
+ """
29
+ authors = []
30
+ for call in mock_print .call_args_list :
31
+ msg = call .args [0 ] if call .args else ""
32
+ # lines look like " John Doe <[email protected] >:"
33
+ if isinstance (msg , str ) and msg .strip ().endswith (">:" ):
34
+ authors .append (msg .strip ()[:- 1 ]) # drop trailing ":"
35
+ return authors
36
+
37
+ @patch ("git_py_stats.generate_cmds.run_git_command" )
38
+ @patch ("builtins.print" )
39
+ def test_sort_by_commits_desc (self , mock_print , mock_run_git_command ):
40
+ """
41
+ Test detailed_git_stats when sorting by commits in descending order.
42
+ """
43
+ # Two authors, B has more commits but fewer insertions
44
+ mock_run_git_command .return_value = (
45
+ # A1 (2 commits total)
46
+ "c1\t Alice\t [email protected] \t 1609459200\n "
47
+ "10\t 1\t a.py\n "
48
+ "c2\t Alice\t [email protected] \t 1609459300\n "
49
+ "5\t 0\t a2.py\n "
50
+ # B1 (3 commits total)
51
+ "c3\t Bob\t [email protected] \t 1609460000\n "
52
+ "1\t 1\t b.py\n "
53
+ "c4\t Bob\t [email protected] \t 1609460100\n "
54
+ "2\t 2\t b2.py\n "
55
+ "c5\t Bob\t [email protected] \t 1609460200\n "
56
+ "3\t 3\t b3.py\n "
57
+ )
58
+
59
+ cfg = dict (self .mock_config )
60
+ cfg ["sort_by" ] = "commits"
61
+ cfg ["sort_dir" ] = "desc"
62
+
63
+ generate_cmds .detailed_git_stats (cfg )
64
+
65
+ authors = self ._extract_printed_authors (mock_print )
66
+ # Expect Bob first (3 commits) then Alice (2)
67
+ self .assertGreaterEqual (len (authors ), 2 )
68
+ self .
assertTrue (
authors [
0 ].
startswith (
"Bob <[email protected] >" ))
69
+ self .
assertTrue (
authors [
1 ].
startswith (
"Alice <[email protected] >" ))
70
+ # Header shows sort choice
71
+ printed = " " .join (a .args [0 ] for a in mock_print .call_args_list if a .args )
72
+ self .assertIn ("Sorting by: commits (desc)" , printed )
73
+
74
+ @patch ("git_py_stats.generate_cmds.run_git_command" )
75
+ @patch ("builtins.print" )
76
+ def test_sort_by_lines_asc_with_name_tiebreaker (self , mock_print , mock_run_git_command ):
77
+ """
78
+ Test detailed_git_stats when sorting by lines in ascending order.
79
+ Attempts to handle a "tiebreaker" when sorting by falling back to
80
+ the person's name in ascending order. So if Alice and Bob have the
81
+ same number of commits, Alice should be chosen.
82
+ """
83
+ mock_run_git_command .return_value = (
84
+ # Alice: 3+3 = 6 lines
85
+ "c1\t Alice\t [email protected] \t 1609459200\n "
86
+ "3\t 3\t a.py\n "
87
+ # Bob: 4+2 = 6 lines
88
+ "c2\t Bob\t [email protected] \t 1609460000\n "
89
+ "4\t 2\t b.py\n "
90
+ )
91
+
92
+ cfg = dict (self .mock_config )
93
+ cfg ["sort_by" ] = "lines"
94
+ cfg ["sort_dir" ] = "asc"
95
+
96
+ generate_cmds .detailed_git_stats (cfg )
97
+
98
+ authors = self ._extract_printed_authors (mock_print )
99
+ self .assertGreaterEqual (len (authors ), 2 )
100
+ self .
assertTrue (
authors [
0 ].
startswith (
"Alice <[email protected] >" ))
101
+ self .
assertTrue (
authors [
1 ].
startswith (
"Bob <[email protected] >" ))
102
+ printed = " " .join (a .args [0 ] for a in mock_print .call_args_list if a .args )
103
+ self .assertIn ("Sorting by: lines (asc)" , printed )
104
+
105
+ @patch ("git_py_stats.generate_cmds.run_git_command" )
106
+ @patch ("builtins.print" )
107
+ def test_sort_by_name_desc (self , mock_print , mock_run_git_command ):
108
+ """
109
+ Test detailed_git_stats when sorting by name in descending order.
110
+ """
111
+ mock_run_git_command .return_value = (
112
+ "c1\t Alice\t [email protected] \t 1609459200\n "
113
+ "1\t 0\t a.py\n "
114
+ "c2\t Bob\t [email protected] \t 1609460000\n "
115
+ "1\t 0\t b.py\n "
116
+ "c3\t Carol\t [email protected] \t 1609470000\n "
117
+ "1\t 0\t c.py\n "
118
+ )
119
+
120
+ cfg = dict (self .mock_config )
121
+ cfg ["sort_by" ] = "name"
122
+ cfg ["sort_dir" ] = "desc"
123
+
124
+ generate_cmds .detailed_git_stats (cfg )
125
+
126
+ authors = self ._extract_printed_authors (mock_print )
127
+ # Descending name: Carol, Bob, Alice
128
+ self .
assertTrue (
authors [
0 ].
startswith (
"Carol <[email protected] >" ))
129
+ self .
assertTrue (
authors [
1 ].
startswith (
"Bob <[email protected] >" ))
130
+ self .
assertTrue (
authors [
2 ].
startswith (
"Alice <[email protected] >" ))
131
+
25
132
@patch ("git_py_stats.generate_cmds.run_git_command" )
26
133
@patch ("builtins.print" )
27
134
def test_detailed_git_stats (self , mock_print , mock_run_git_command ):
0 commit comments