11"""Tests for DisplayController class."""
22
3- from datetime import datetime
4- from datetime import timedelta
5- from datetime import timezone
6- from unittest .mock import Mock
7- from unittest .mock import patch
3+ from datetime import datetime , timedelta , timezone
4+ from unittest .mock import Mock , patch
85
96import pytest
107
118from claude_monitor .types import SerializedBlock
12- from claude_monitor .ui .display_controller import DisplayController
13- from claude_monitor .ui .display_controller import LiveDisplayManager
14- from claude_monitor .ui .display_controller import ScreenBufferManager
15- from claude_monitor .ui .display_controller import SessionCalculator
9+ from claude_monitor .ui .display_controller import (
10+ DisplayController ,
11+ LiveDisplayManager ,
12+ ScreenBufferManager ,
13+ SessionCalculator ,
14+ )
1615
1716
1817class TestDisplayController :
@@ -209,7 +208,7 @@ def test_calculate_cost_predictions_valid_plan(
209208
210209 # Testing cost prediction with valid plan - private method access for business logic
211210 result = controller ._calculate_cost_predictions ( # type: ignore[attr-defined]
212- session_data , time_data , sample_args , cost_limit_p90
211+ session_data , time_data , sample_args , cost_limit_p90 # type: ignore[arg-type] # Mock test data
213212 )
214213
215214 assert result ["cost_limit" ] == 5.0
@@ -233,7 +232,7 @@ def test_calculate_cost_predictions_invalid_plan(
233232
234233 # Testing cost prediction with invalid plan - private method access for edge cases
235234 controller ._calculate_cost_predictions ( # type: ignore[attr-defined]
236- session_data , time_data , sample_args , None
235+ session_data , time_data , sample_args , None # type: ignore[arg-type] # Mock test data
237236 )
238237
239238 mock_calc .assert_called_once_with (session_data , time_data , 100.0 )
@@ -400,17 +399,18 @@ def test_calculate_model_distribution_valid_stats(
400399 self , mock_normalize : Mock , controller : DisplayController
401400 ) -> None :
402401 """Test model distribution calculation with valid stats."""
403- mock_normalize .side_effect = lambda x : {
402+ mock_normalize .side_effect = lambda x : { # type: ignore[misc]
404403 "claude-3-opus" : "claude-3-opus" ,
405404 "claude-3-5-sonnet" : "claude-3.5-sonnet" ,
406- }.get (x , "unknown" )
405+ }.get (x , "unknown" ) # type: ignore[misc] # Mock lambda parameter
407406
408407 raw_stats = {
409408 "claude-3-opus" : {"input_tokens" : 5000 , "output_tokens" : 3000 },
410409 "claude-3-5-sonnet" : {"input_tokens" : 4000 , "output_tokens" : 3000 },
411410 }
412411
413- result = controller ._calculate_model_distribution (raw_stats )
412+ # Testing model distribution calculations - private method access for statistical logic
413+ result = controller ._calculate_model_distribution (raw_stats ) # type: ignore[attr-defined,arg-type]
414414
415415 # Total tokens: opus=8000, sonnet=7000, total=15000
416416 expected_opus_pct = (8000 / 15000 ) * 100 # ~53.33%
@@ -423,7 +423,8 @@ def test_create_data_display_no_data(
423423 self , controller : DisplayController , sample_args : Mock
424424 ) -> None :
425425 """Test create_data_display with no data."""
426- result = controller .create_data_display ({}, sample_args , 200000 )
426+ # Test with empty data - using dict literal for edge case testing
427+ result = controller .create_data_display ({}, sample_args , 200000 ) # type: ignore[arg-type] # Mock test data
427428
428429 assert result is not None
429430 # Should return error screen renderable
@@ -434,7 +435,8 @@ def test_create_data_display_no_active_block(
434435 """Test create_data_display with no active blocks."""
435436 data = {"blocks" : [{"isActive" : False , "totalTokens" : 1000 }]}
436437
437- result = controller .create_data_display (data , sample_args , 200000 )
438+ # Test with mock block data - using dict literal for testing edge cases
439+ result = controller .create_data_display (data , sample_args , 200000 ) # type: ignore[arg-type] # Mock test data
438440
439441 assert result is not None
440442 # Should return no active session screen
@@ -492,8 +494,9 @@ def test_create_data_display_with_active_block(
492494 ) as mock_format :
493495 mock_format .return_value = ["Sample screen buffer" ]
494496
497+ # Test with mock data containing SerializedBlock - using dict for edge case testing
495498 result = controller .create_data_display (
496- data , sample_args , 200000
499+ data , sample_args , 200000 # type: ignore[arg-type] # Mock test data
497500 )
498501
499502 assert result is not None
@@ -659,8 +662,8 @@ def sample_args(self) -> Mock:
659662 return args
660663
661664 def test_process_active_session_data_exception_handling (
662- self , controller , sample_args
663- ):
665+ self , controller : DisplayController , sample_args : Mock
666+ ) -> None :
664667 """Test exception handling in _process_active_session_data."""
665668 sample_active_block = {
666669 "isActive" : True ,
@@ -674,23 +677,24 @@ def test_process_active_session_data_exception_handling(
674677 with patch .object (controller , "_extract_session_data" ) as mock_extract :
675678 mock_extract .side_effect = Exception ("Test error" )
676679
677- result = controller .create_data_display (data , sample_args , 200000 )
680+ # Test error handling with mock block data - using dict for exception testing
681+ result = controller .create_data_display (data , sample_args , 200000 ) # type: ignore[arg-type] # Mock test data
678682
679683 # Should return error screen renderable instead of crashing
680684 assert result is not None
681685
682686 def test_format_display_times_invalid_timezone (
683- self , controller , sample_args
684- ):
687+ self , controller : DisplayController , sample_args : Mock
688+ ) -> None :
685689 """Test format_display_times with invalid timezone."""
686690 sample_args .timezone = "Invalid/Timezone"
687691
688692 current_time = datetime .now (timezone .utc )
689693 predicted_end = current_time + timedelta (hours = 2 )
690694 reset_time = current_time + timedelta (hours = 12 )
691695
692- # Should handle invalid timezone gracefully
693- result = controller ._format_display_times (
696+ # Testing timezone handling - private method access for edge case testing
697+ result = controller ._format_display_times ( # type: ignore[attr-defined]
694698 sample_args , current_time , predicted_end , reset_time
695699 )
696700
@@ -707,8 +711,8 @@ def test_calculate_model_distribution_invalid_stats(
707711 "another-model" : {"inputTokens" : "not-a-number" },
708712 }
709713
710- # Should handle invalid data gracefully
711- result = controller ._calculate_model_distribution (invalid_stats )
714+ # Testing invalid model data handling - private method access for error case testing
715+ result = controller ._calculate_model_distribution (invalid_stats ) # type: ignore[attr-defined,arg-type]
712716
713717 # Should return empty or handle gracefully
714718 assert isinstance (result , dict )
@@ -798,8 +802,9 @@ def test_create_data_display_custom_plan(
798802 mock_format .return_value = ["screen" , "buffer" ]
799803 mock_create .return_value = "rendered_screen"
800804
805+ # Test advanced display mode with complex mock data - using dict for testing
801806 result = controller .create_data_display (
802- data , sample_args_custom , 200000
807+ data , sample_args_custom , 200000 # type: ignore[arg-type] # Mock test data
803808 )
804809
805810 assert result == "rendered_screen"
@@ -838,7 +843,8 @@ def test_create_data_display_exception_handling(
838843 mock_error .return_value = ["error" , "screen" ]
839844 mock_create .return_value = "error_rendered"
840845
841- result = controller .create_data_display (data , args , 200000 )
846+ # Test error handling with mock data - using dict for exception testing
847+ result = controller .create_data_display (data , args , 200000 ) # type: ignore[arg-type] # Mock test data
842848
843849 assert result == "error_rendered"
844850 mock_error .assert_called_once_with ("pro" , "UTC" )
@@ -893,7 +899,8 @@ def test_create_data_display_format_session_exception(
893899 mock_error .return_value = ["error" , "screen" ]
894900 mock_create .return_value = "error_rendered"
895901
896- result = controller .create_data_display (data , args , 200000 )
902+ # Test exception handling with complex mock data - using dict for edge cases
903+ result = controller .create_data_display (data , args , 200000 ) # type: ignore[arg-type] # Mock test data
897904
898905 assert result == "error_rendered"
899906 mock_error .assert_called_once_with ("pro" , "UTC" )
@@ -968,9 +975,10 @@ def test_process_active_session_data_comprehensive(
968975 "current_time_str" : "12:30" ,
969976 }
970977
971- result = controller ._process_active_session_data (
972- active_block ,
973- data ,
978+ # Testing active session data processing - private method access for pipeline testing
979+ result = controller ._process_active_session_data ( # type: ignore[attr-defined]
980+ active_block , # type: ignore[arg-type] # Mock test data
981+ data , # type: ignore[arg-type] # Mock test data
974982 args ,
975983 200000 ,
976984 current_time ,
@@ -1019,8 +1027,9 @@ def test_calculate_time_data_with_start_end(
10191027 mock_parse .side_effect = [start_time , end_time ]
10201028 mock_ensure .side_effect = [start_time , end_time ]
10211029
1030+ # Test with mock session data - using dict for testing time calculations
10221031 result = calculator .calculate_time_data (
1023- session_data , current_time
1032+ session_data , current_time # type: ignore[arg-type] # Mock test data
10241033 )
10251034
10261035 assert result ["start_time" ] == start_time
@@ -1046,8 +1055,9 @@ def test_calculate_time_data_no_end_time(
10461055 mock_parse .return_value = start_time
10471056 mock_ensure .return_value = start_time
10481057
1058+ # Test with mock session data - using dict for testing time calculations with no end time
10491059 result = calculator .calculate_time_data (
1050- session_data , current_time
1060+ session_data , current_time # type: ignore[arg-type] # Mock test data
10511061 )
10521062
10531063 assert result ["start_time" ] == start_time
@@ -1062,7 +1072,8 @@ def test_calculate_time_data_no_start_time(
10621072 session_data = dict [str , str | None ]()
10631073 current_time = datetime (2024 , 1 , 1 , 12 , 30 , tzinfo = timezone .utc )
10641074
1065- result = calculator .calculate_time_data (session_data , current_time )
1075+ # Test with empty mock session data - using dict for edge case testing
1076+ result = calculator .calculate_time_data (session_data , current_time ) # type: ignore[arg-type] # Mock test data
10661077
10671078 assert result ["start_time" ] is None
10681079 # Reset time should be current_time + 5 hours
@@ -1084,12 +1095,13 @@ def test_calculate_cost_predictions_with_cost(
10841095 ) as mock_datetime :
10851096 current_time = datetime (2024 , 1 , 1 , 12 , 0 , tzinfo = timezone .utc )
10861097 mock_datetime .now .return_value = current_time
1087- mock_datetime .side_effect = lambda * args , ** kw : datetime (
1088- * args , ** kw
1098+ mock_datetime .side_effect = lambda * args , ** kw : datetime ( # type: ignore[misc] # Mock lambda
1099+ * args , ** kw # type: ignore[misc] # Mock datetime args
10891100 )
10901101
1102+ # Test cost predictions with mock data - using dict for testing calculations
10911103 result = calculator .calculate_cost_predictions (
1092- session_data , time_data , cost_limit
1104+ session_data , time_data , cost_limit # type: ignore[arg-type] # Mock test data
10931105 )
10941106
10951107 assert result ["cost_per_minute" ] == 2.5 / 60 # Approximately 0.0417
@@ -1112,12 +1124,13 @@ def test_calculate_cost_predictions_no_cost_limit(
11121124 ) as mock_datetime :
11131125 current_time = datetime (2024 , 1 , 1 , 12 , 0 , tzinfo = timezone .utc )
11141126 mock_datetime .now .return_value = current_time
1115- mock_datetime .side_effect = lambda * args , ** kw : datetime (
1116- * args , ** kw
1127+ mock_datetime .side_effect = lambda * args , ** kw : datetime ( # type: ignore[misc] # Mock lambda
1128+ * args , ** kw # type: ignore[misc] # Mock datetime args
11171129 )
11181130
1131+ # Test cost predictions without cost limit - using dict for edge case testing
11191132 result = calculator .calculate_cost_predictions (
1120- session_data , time_data , None
1133+ session_data , time_data , None # type: ignore[arg-type] # Mock test data
11211134 )
11221135
11231136 assert result ["cost_limit" ] == 100.0 # Default
@@ -1140,12 +1153,13 @@ def test_calculate_cost_predictions_zero_cost_rate(
11401153 ) as mock_datetime :
11411154 current_time = datetime (2024 , 1 , 1 , 12 , 0 , tzinfo = timezone .utc )
11421155 mock_datetime .now .return_value = current_time
1143- mock_datetime .side_effect = lambda * args , ** kw : datetime (
1144- * args , ** kw
1156+ mock_datetime .side_effect = lambda * args , ** kw : datetime ( # type: ignore[misc] # Mock lambda
1157+ * args , ** kw # type: ignore[misc] # Mock datetime args
11451158 )
11461159
1160+ # Test cost predictions with mock data - using dict for testing calculations
11471161 result = calculator .calculate_cost_predictions (
1148- session_data , time_data , cost_limit
1162+ session_data , time_data , cost_limit # type: ignore[arg-type] # Mock test data
11491163 )
11501164
11511165 assert result ["cost_per_minute" ] == 0.0
@@ -1154,7 +1168,7 @@ def test_calculate_cost_predictions_zero_cost_rate(
11541168
11551169# Test the legacy function
11561170@patch ("claude_monitor.ui.display_controller.ScreenBufferManager" )
1157- def test_create_screen_renderable_legacy (mock_manager_class ) :
1171+ def test_create_screen_renderable_legacy (mock_manager_class : Mock ) -> None :
11581172 """Test the legacy create_screen_renderable function."""
11591173 mock_manager = Mock ()
11601174 mock_manager_class .return_value = mock_manager
0 commit comments