@@ -98,10 +98,158 @@ def test_none_theme_option_3(self, mock_stdout, mock_input):
9898        choice  =  interactive_menu (self .config_none )
9999        self .assertEqual (choice , "3" )
100100        output  =  mock_stdout .getvalue ()
101-         self .assertNotIn ("\033 [31m" , output )  # No RED 
102-         self .assertNotIn ("\033 [33m" , output )  # No YELLOW 
103-         self .assertNotIn ("\033 [36m" , output )  # No CYAN 
104-         self .assertIn ("\033 [1m" , output )      # BOLD allowed 
101+         self .assertNotIn ("\033 [31m" , output )
102+         self .assertNotIn ("\033 [33m" , output )
103+         self .assertNotIn ("\033 [36m" , output )
104+         self .assertIn ("\033 [1m" , output )
105+ 
106+     @patch ("builtins.input" , return_value = "22" ) 
107+     @patch ("sys.stdout" , new_callable = StringIO ) 
108+     def  test_default_theme_option_22 (self , mock_stdout , mock_input ):
109+         """ 
110+         Test the interactive_menu with default theme and user selects option '22'. 
111+         """ 
112+         choice  =  interactive_menu (self .config_default )
113+         self .assertEqual (choice , "22" )
114+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
115+         self .assertIn ("Suggest:" , output )
116+         self .assertIn ("22) Code reviewers (based on git history)" , output )
117+ 
118+     @patch ("builtins.input" , return_value = "" ) 
119+     @patch ("sys.stdout" , new_callable = StringIO ) 
120+     def  test_default_theme_exit (self , mock_stdout , mock_input ):
121+         """ 
122+         Test the interactive_menu with default theme and user presses Enter to exit. 
123+         """ 
124+         choice  =  interactive_menu (self .config_default )
125+         self .assertEqual (choice , "" )
126+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
127+         self .assertIn ("press Enter to exit" , output )
128+ 
129+     @patch ("builtins.input" , return_value = "invalid" ) 
130+     @patch ("sys.stdout" , new_callable = StringIO ) 
131+     def  test_default_theme_invalid_input (self , mock_stdout , mock_input ):
132+         """ 
133+         Test the interactive_menu with default theme and user enters an invalid option. 
134+         """ 
135+         choice  =  interactive_menu (self .config_default )
136+         self .assertEqual (choice , "invalid" )
137+         # Since interactive_menu doesn't print 'Invalid selection', we don't assert that here. 
138+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
139+         self .assertIn ("Generate:" , output )
140+ 
141+     @patch ("builtins.input" , return_value = "1" ) 
142+     @patch ("sys.stdout" , new_callable = StringIO ) 
143+     def  test_legacy_theme_option_1 (self , mock_stdout , mock_input ):
144+         """ 
145+         Test the interactive_menu with legacy theme and user selects option '1'. 
146+         """ 
147+         choice  =  interactive_menu (self .config_legacy )
148+         self .assertEqual (choice , "1" )
149+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
150+         self .assertIn ("Generate:" , output )
151+         self .assertIn ("1) Contribution stats (by author)" , output )
152+ 
153+     @patch ("builtins.input" , return_value = "2" ) 
154+     @patch ("sys.stdout" , new_callable = StringIO ) 
155+     def  test_legacy_theme_option_2 (self , mock_stdout , mock_input ):
156+         """ 
157+         Test the interactive_menu with legacy theme and user selects option '2'. 
158+         """ 
159+         choice  =  interactive_menu (self .config_legacy )
160+         self .assertEqual (choice , "2" )
161+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
162+         self .assertIn ("2) Contribution stats (by author) on a specific branch" , output )
163+ 
164+     @patch ("builtins.input" , return_value = "" ) 
165+     @patch ("sys.stdout" , new_callable = StringIO ) 
166+     def  test_legacy_theme_exit (self , mock_stdout , mock_input ):
167+         """ 
168+         Test the interactive_menu with legacy theme and user presses Enter to exit. 
169+         """ 
170+         choice  =  interactive_menu (self .config_legacy )
171+         self .assertEqual (choice , "" )
172+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
173+         self .assertIn ("press Enter to exit" , output )
174+ 
175+     @patch ("builtins.input" , return_value = "invalid" ) 
176+     @patch ("sys.stdout" , new_callable = StringIO ) 
177+     def  test_legacy_theme_invalid_input (self , mock_stdout , mock_input ):
178+         """ 
179+         Test the interactive_menu with legacy theme and user enters an invalid option. 
180+         """ 
181+         choice  =  interactive_menu (self .config_legacy )
182+         self .assertEqual (choice , "invalid" )
183+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
184+         self .assertIn ("Generate:" , output )
185+ 
186+     @patch ("builtins.input" , side_effect = ["1" , "" ]) 
187+     @patch ("sys.stdout" , new_callable = StringIO ) 
188+     def  test_multiple_inputs (self , mock_stdout , mock_input ):
189+         """ 
190+         Test the interactive_menu with multiple inputs in sequence. 
191+         """ 
192+         choice1  =  interactive_menu (self .config_default )
193+         choice2  =  interactive_menu (self .config_default )
194+         self .assertEqual (choice1 , "1" )
195+         self .assertEqual (choice2 , "" )
196+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
197+         self .assertIn ("Generate:" , output )
198+ 
199+     @patch ("builtins.input" , return_value = "   5   " ) 
200+     @patch ("sys.stdout" , new_callable = StringIO ) 
201+     def  test_input_with_whitespace (self , mock_stdout , mock_input ):
202+         """ 
203+         Test the interactive_menu with input that includes leading/trailing whitespace. 
204+         """ 
205+         choice  =  interactive_menu (self .config_default )
206+         self .assertEqual (choice , "5" )
207+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
208+         self .assertIn ("5) My daily status" , output )
209+ 
210+     @patch ("builtins.input" , return_value = "QUIT" ) 
211+     @patch ("sys.stdout" , new_callable = StringIO ) 
212+     def  test_input_quit (self , mock_stdout , mock_input ):
213+         """ 
214+         Test the interactive_menu with input 'QUIT' to simulate exit. 
215+         """ 
216+         choice  =  interactive_menu (self .config_default )
217+         self .assertEqual (choice , "QUIT" )
218+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
219+         self .assertIn ("Generate:" , output )
220+ 
221+     @patch ("builtins.input" , return_value = "EXIT" ) 
222+     @patch ("sys.stdout" , new_callable = StringIO ) 
223+     def  test_input_exit (self , mock_stdout , mock_input ):
224+         """ 
225+         Test the interactive_menu with input 'EXIT' to simulate exit. 
226+         """ 
227+         choice  =  interactive_menu (self .config_default )
228+         self .assertEqual (choice , "EXIT" )
229+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
230+         self .assertIn ("Generate:" , output )
231+ 
232+     @patch ("builtins.input" , return_value = "   " ) 
233+     @patch ("sys.stdout" , new_callable = StringIO ) 
234+     def  test_input_only_whitespace (self , mock_stdout , mock_input ):
235+         """ 
236+         Test the interactive_menu with input that is only whitespace. 
237+         """ 
238+         choice  =  interactive_menu (self .config_default )
239+         self .assertEqual (choice , "" )
240+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
241+         self .assertIn ("press Enter to exit" , output )
242+ 
243+     @patch ("builtins.input" , side_effect = KeyboardInterrupt ) 
244+     @patch ("sys.stdout" , new_callable = StringIO ) 
245+     def  test_keyboard_interrupt (self , mock_stdout , mock_input ):
246+         """ 
247+         Test the interactive_menu handles KeyboardInterrupt (Ctrl+C). 
248+         """ 
249+         with  self .assertRaises (KeyboardInterrupt ):
250+             interactive_menu (self .config_default )
251+         output  =  strip_ansi_codes (mock_stdout .getvalue ())
252+         self .assertIn ("Generate:" , output )
105253
106254if  __name__  ==  "__main__" :
107255    unittest .main ()
0 commit comments