Coverage for test\test_HUD_main.py: 99%

345 statements  

« prev     ^ index     » next       coverage.py v7.6.3, created at 2024-10-15 19:33 +0000

1import pytest 

2from unittest.mock import MagicMock, patch 

3from PyQt5.QtWidgets import QApplication 

4import sys 

5import types 

6import zmq 

7 

8from pathlib import Path 

9 

10sys.path.append(str(Path(__file__).parent.parent)) 

11 

12# Create a mock 'WinTables' module 

13win_tables_module = types.ModuleType("WinTables") 

14win_tables_module.Table = MagicMock() 

15 

16with patch.dict("sys.modules", {"WinTables": win_tables_module}): 

17 import HUD_main 

18 

19 

20@pytest.fixture 

21def app(qtbot): 

22 return QApplication.instance() 

23 

24 

25@pytest.fixture 

26def hud_main(app, qtbot): 

27 # Crate mock 

28 options = MagicMock() 

29 options.dbname = "test_db" 

30 options.config = None 

31 options.errorsToConsole = False 

32 options.xloc = None 

33 options.yloc = None 

34 

35 import tempfile 

36 

37 with ( 

38 patch("HUD_main.Configuration.Config") as mock_config, 

39 patch("HUD_main.Configuration.set_logfile"), 

40 patch("HUD_main.Database.Database"), 

41 patch("HUD_main.ZMQReceiver"), 

42 patch("sys.exit"), 

43 patch("PyQt5.QtCore.QCoreApplication.quit"), 

44 ): 

45 mock_config_instance = MagicMock() 

46 mock_config.return_value = mock_config_instance 

47 

48 mock_config_instance.dir_log = tempfile.gettempdir() 

49 mock_config_instance.os_family = "Win7" 

50 mock_config_instance.get_hud_ui_parameters.return_value = { 

51 "deck_type": "default", 

52 "card_back": "blue", 

53 "card_wd": 72, 

54 "card_ht": 96, 

55 "hud_days": 30, 

56 "h_hud_days": 90, 

57 } 

58 mock_config_instance.graphics_path = tempfile.gettempdir() 

59 mock_config_instance.hhcs = {"test_site": MagicMock(converter="some_converter")} 

60 mock_config_instance.get_site_parameters.return_value = { 

61 "layout_set": "some_layout", 

62 "param1": "value1", 

63 } 

64 mock_config_instance.get_layout.return_value = "some_layout" 

65 

66 hm = HUD_main.HUD_main(options, db_name=options.dbname) 

67 qtbot.addWidget(hm.main_window) 

68 yield hm 

69 

70 qtbot.waitExposed(hm.main_window) 

71 hm.main_window.close() 

72 

73 

74# Verifies that all necessary attributes of the HUD_main instance are correctly initialized. 

75def test_hud_main_initialization(hud_main): 

76 assert hud_main.db_name == "test_db" 

77 assert hasattr(hud_main, "config") 

78 assert hasattr(hud_main, "db_connection") 

79 assert hasattr(hud_main, "hud_dict") 

80 assert hasattr(hud_main, "blacklist") 

81 assert hasattr(hud_main, "hud_params") 

82 assert hasattr(hud_main, "deck") 

83 assert hasattr(hud_main, "cache") 

84 assert hasattr(hud_main, "zmq_receiver") 

85 assert hasattr(hud_main, "zmq_worker") 

86 assert hasattr(hud_main, "main_window") 

87 

88 

89# Ensures that the handle_message method correctly calls read_stdin when provided with a hand ID. 

90def test_handle_message(hud_main): 

91 with patch.object(hud_main, "read_stdin") as mock_read_stdin: 

92 hud_main.handle_message("test_hand_id") 

93 mock_read_stdin.assert_called_once_with("test_hand_id") 

94 

95 

96# Checks that the destroy method properly closes connections and stops processes. 

97def test_destroy(hud_main): 

98 with ( 

99 patch.object(hud_main.zmq_receiver, "close") as mock_close, 

100 patch.object(hud_main.zmq_worker, "stop") as mock_stop, 

101 patch("PyQt5.QtCore.QCoreApplication.quit") as mock_quit, 

102 ): 

103 hud_main.destroy() 

104 mock_close.assert_called_once() 

105 mock_stop.assert_called_once() 

106 mock_quit.assert_called_once() 

107 

108 

109# Verifies that check_tables calls the correct methods (client_destroyed, client_moved, client_resized) based on the table's status. 

110@pytest.mark.parametrize( 

111 "status, expected_method", 

112 [ 

113 ("client_destroyed", "client_destroyed"), 

114 ("client_moved", "client_moved"), 

115 ("client_resized", "client_resized"), 

116 ], 

117) 

118def test_check_tables(hud_main, status, expected_method): 

119 mock_hud = MagicMock() 

120 mock_hud.table.check_table.return_value = status 

121 hud_main.hud_dict = {"test_table": mock_hud} 

122 

123 with patch.object(hud_main, expected_method) as mock_method: 

124 hud_main.check_tables() 

125 mock_method.assert_called_once_with(None, mock_hud) 

126 

127 

128# Ensures that create_HUD creates a new HUD and adds it to the hud_dict. 

129def test_create_hud(hud_main): 

130 with ( 

131 patch.object(HUD_main.Hud, "Hud") as mock_hud, 

132 patch.object(hud_main, "idle_create") as mock_idle_create, 

133 patch.object( 

134 hud_main.config, "get_site_parameters", return_value={"layout_set": "some_layout", "param1": "value1"} 

135 ), 

136 patch.object(hud_main.config, "get_layout", return_value="some_layout"), 

137 ): 

138 mock_table = MagicMock() 

139 mock_table.site = "test_site" 

140 hud_main.create_HUD("new_hand_id", mock_table, "temp_key", 9, "poker_game", "cash", {}, {}) 

141 

142 assert "temp_key" in hud_main.hud_dict 

143 mock_hud.assert_called_once() 

144 mock_idle_create.assert_called_once() 

145 

146 

147# Verifies that update_HUD properly calls idle_update. 

148def test_update_hud(hud_main): 

149 with patch.object(hud_main, "idle_update") as mock_idle_update: 

150 hud_main.update_HUD("new_hand_id", "table_name", hud_main.config) 

151 mock_idle_update.assert_called_once_with("new_hand_id", "table_name", hud_main.config) 

152 

153 

154# Ensures that cached data is processed correctly in read_stdin and calls update_HUD. 

155def test_read_stdin_cached(hud_main): 

156 # Configuration env 

157 hud_main.config = MagicMock() 

158 hud_main.config.get_supported_sites.return_value = ["test_site"] 

159 hud_main.config.supported_sites = {"test_site": MagicMock(screen_name="test_hero")} 

160 test_hand_id = "test_hand_id" 

161 hud_main.cache[test_hand_id] = ( 

162 "table_name", 

163 9, 

164 "poker_game", 

165 "cash", 

166 False, 

167 1, 

168 "test_site", 

169 9, 

170 "tour_number", 

171 "tab_number", 

172 ) 

173 temp_key = "table_name" 

174 hud_main.hud_dict[temp_key] = MagicMock() 

175 hud_main.hud_dict[temp_key].hud_params = {"hud_days": 30, "h_hud_days": 90} 

176 hud_main.hud_dict[temp_key].poker_game = "poker_game" 

177 hud_main.hud_dict[temp_key].max = 9 

178 hud_main.hud_dict[temp_key].aux_windows = [] 

179 

180 with ( 

181 patch.object(hud_main.db_connection, "get_site_id", return_value=[(1,)]), 

182 patch.object(hud_main.db_connection, "get_player_id", return_value=123), 

183 patch.object(hud_main.db_connection, "init_hud_stat_vars"), 

184 patch.object( 

185 hud_main.db_connection, "get_stats_from_hand", return_value={"player1": {"screen_name": "test_hero"}} 

186 ), 

187 patch.object(hud_main, "get_cards", return_value={}), 

188 patch.object(hud_main, "update_HUD") as mock_update_hud, 

189 ): 

190 hud_main.read_stdin(test_hand_id) 

191 assert mock_update_hud.called, "update_HUD n'a pas été appelé" 

192 

193 

194# Confirms that cached data is used if available when calling read_stdin. 

195def test_read_stdin_cache_used(hud_main): 

196 hud_main.cache = {"test_hand_id": ("table_name", 9, "poker_game", "cash", False, 1, "test_site", 9, 123, "tab")} 

197 with patch("HUD_main.log.debug") as mock_log_debug: 

198 hud_main.read_stdin("test_hand_id") 

199 mock_log_debug.assert_any_call("Using cached data for hand test_hand_id") 

200 

201 

202# Tests the behavior of read_stdin when no cached data is available, ensuring it calls create_HUD 

203def test_read_stdin_not_cached(hud_main): 

204 hud_main.config = MagicMock() 

205 hud_main.config.get_supported_sites.return_value = ["test_site"] 

206 hud_main.config.supported_sites = {"test_site": MagicMock(screen_name="test_hero")} 

207 hud_main.config.get_site_parameters.return_value = {"aux_enabled": True} 

208 

209 hud_main.Tables = MagicMock() 

210 hud_main.Tables.Table.return_value = MagicMock() 

211 test_hand_id = "test_hand_id" 

212 

213 hud_main.cache = {} 

214 

215 table_info = ("table_name", 9, "poker_game", "tour", False, 1, "test_site", 9, 123456, "Table 789") 

216 

217 with ( 

218 patch.object(hud_main.db_connection, "get_site_id", return_value=[(1,)]), 

219 patch.object(hud_main.db_connection, "get_player_id", return_value=123), 

220 patch.object(hud_main.db_connection, "get_table_info", return_value=table_info), 

221 patch.object(hud_main.db_connection, "init_hud_stat_vars"), 

222 patch.object( 

223 hud_main.db_connection, "get_stats_from_hand", return_value={"player1": {"screen_name": "test_hero"}} 

224 ), 

225 patch.object(hud_main, "get_cards", return_value={}), 

226 patch.object(hud_main.Tables, "Table", return_value=MagicMock()), 

227 patch.object(hud_main, "create_HUD") as mock_create_hud, 

228 ): 

229 hud_main.read_stdin(test_hand_id) 

230 assert mock_create_hud.called, "create_HUD n'a pas été appelé" 

231 

232 

233# Ensures that get_cards retrieves both player and community cards correctly. 

234def test_get_cards(hud_main): 

235 mock_db = MagicMock() 

236 mock_db.get_cards.return_value = {"player1": ["As", "Kh"]} 

237 mock_db.get_common_cards.return_value = {"common": ["Jd", "Qc", "Tc"]} 

238 hud_main.db_connection = mock_db 

239 

240 cards = hud_main.get_cards("test_hand_id", "holdem") 

241 assert "player1" in cards 

242 assert "common" in cards 

243 

244 

245# Verifies that idle_kill removes the HUD from hud_dict and cleans up widgets. 

246def test_idle_kill(hud_main): 

247 mock_hud = MagicMock() 

248 hud_main.hud_dict["test_table"] = mock_hud 

249 hud_main.vb = MagicMock() 

250 

251 hud_main.idle_kill("test_table") 

252 

253 assert "test_table" not in hud_main.hud_dict 

254 mock_hud.kill.assert_called_once() 

255 hud_main.vb.removeWidget.assert_called_once() 

256 

257 

258# Checks exception handling in read_stdin when an error occurs in get_table_info. 

259def test_read_stdin_exception_handling(hud_main): 

260 hud_main.config = MagicMock() 

261 hud_main.config.get_supported_sites.return_value = ["test_site"] 

262 hud_main.config.get_site_parameters.return_value = {"aux_enabled": True} 

263 hud_main.hero = {} 

264 hud_main.hero_ids = {} 

265 

266 hud_main.cache = {} 

267 

268 test_hand_id = "test_hand_id" 

269 

270 with ( 

271 patch.object(hud_main.db_connection, "get_table_info", side_effect=Exception("Database error")), 

272 patch.object(hud_main, "destroy") as mock_destroy, 

273 ): 

274 hud_main.read_stdin(test_hand_id) 

275 

276 mock_destroy.assert_not_called() 

277 

278 

279# Ensures that ZMQWorker.stop stops the worker properly. 

280def test_zmqworker_stop(): 

281 zmq_receiver = MagicMock() 

282 worker = HUD_main.ZMQWorker(zmq_receiver) 

283 worker.wait = MagicMock() 

284 worker.is_running = True 

285 

286 worker.stop() 

287 assert not worker.is_running 

288 worker.wait.assert_called_once() 

289 

290 

291# Verifies that a heartbeat log is generated when no messages are received. 

292def test_process_message_heartbeat(hud_main): 

293 zmq_receiver = HUD_main.ZMQReceiver() 

294 zmq_receiver.socket = MagicMock() 

295 zmq_receiver.poller = MagicMock() 

296 

297 zmq_receiver.poller.poll.return_value = {} 

298 

299 with patch("HUD_main.log.debug") as mock_log_debug: 

300 zmq_receiver.process_message() 

301 mock_log_debug.assert_called_with("Heartbeat: No message received") 

302 

303 

304# Tests the run loop of ZMQWorker, ensuring it stops after processing a message. 

305def test_zmqworker_run(hud_main): 

306 zmq_receiver = MagicMock() 

307 worker = HUD_main.ZMQWorker(zmq_receiver) 

308 

309 # Limit the loop to avoid an infinite blockage 

310 worker.is_running = True 

311 

312 # Use of `side_effect` to stop the loop after the first call to `process_message`. 

313 def stop_after_one_iteration(*args, **kwargs): 

314 worker.is_running = False 

315 

316 with ( 

317 patch("time.sleep", return_value=None), 

318 patch.object(zmq_receiver, "process_message", side_effect=stop_after_one_iteration) as mock_process_message, 

319 ): 

320 worker.run() 

321 mock_process_message.assert_called_once() 

322 

323 

324# Ensures that process_message logs the correct hand ID received from the socket. 

325def test_process_message(hud_main): 

326 zmq_receiver = HUD_main.ZMQReceiver() 

327 zmq_receiver.socket = MagicMock() 

328 zmq_receiver.poller = MagicMock() 

329 

330 zmq_receiver.poller.poll.return_value = {zmq_receiver.socket: zmq.POLLIN} 

331 zmq_receiver.socket.recv_string.return_value = "hand_id" 

332 

333 with patch("HUD_main.log.debug") as mock_log_debug: 

334 zmq_receiver.process_message() 

335 mock_log_debug.assert_called_with("Received hand ID: hand_id") 

336 

337 

338# Verifies that table_title_changed calls kill_hud when the table's title changes. 

339def test_table_title_changed_calls_kill_hud(hud_main): 

340 mock_hud = MagicMock() 

341 mock_hud.table.key = "test_table" 

342 hud_main.hud_dict["test_table"] = mock_hud 

343 

344 with patch.object(hud_main, "kill_hud") as mock_kill_hud: 

345 hud_main.table_title_changed(None, mock_hud) 

346 mock_kill_hud.assert_called_once_with(None, "test_table") 

347 

348 

349# Ensures that table_is_stale calls kill_hud for stale tables. 

350def test_table_is_stale_calls_kill_hud(hud_main): 

351 mock_hud = MagicMock() 

352 mock_hud.table.key = "test_table" 

353 hud_main.hud_dict["test_table"] = mock_hud 

354 

355 with patch.object(hud_main, "kill_hud") as mock_kill_hud: 

356 hud_main.table_is_stale(mock_hud) 

357 mock_kill_hud.assert_called_once_with(None, "test_table") 

358 

359 

360# Verifies that blacklist_hud correctly removes a HUD from hud_dict and adds it to the blacklist. 

361def test_blacklist_hud(hud_main): 

362 mock_hud = MagicMock() 

363 mock_hud.tablenumber = 123 

364 hud_main.hud_dict["test_table"] = mock_hud 

365 hud_main.vb = MagicMock() 

366 

367 hud_main.blacklist_hud(None, "test_table") 

368 

369 assert 123 in hud_main.blacklist 

370 assert "test_table" not in hud_main.hud_dict 

371 mock_hud.kill.assert_called_once() 

372 hud_main.vb.removeWidget.assert_called_once() 

373 

374 

375# Ensures that handle_worker_error logs an error message. 

376def test_handle_worker_error(hud_main): 

377 with patch("HUD_main.log.error") as mock_log_error: 

378 hud_main.handle_worker_error("Test error message") 

379 mock_log_error.assert_called_once_with("ZMQWorker encountered an error: Test error message") 

380 

381 

382# Verifies that close_event_handler calls destroy and accepts the event. 

383def test_close_event_handler(hud_main): 

384 mock_event = MagicMock() 

385 with patch.object(hud_main, "destroy") as mock_destroy: 

386 hud_main.close_event_handler(mock_event) 

387 mock_destroy.assert_called_once() 

388 mock_event.accept.assert_called_once() 

389 

390 

391# Ensures that idle_move moves the table and auxiliary windows. 

392def test_idle_move(hud_main): 

393 mock_hud = MagicMock() 

394 mock_hud.aux_windows = [MagicMock()] 

395 hud_main.idle_move(mock_hud) 

396 

397 mock_hud.move_table_position.assert_called_once() 

398 for aw in mock_hud.aux_windows: 

399 aw.move_windows.assert_called_once() 

400 

401 

402# Verifies that idle_resize resizes the table and auxiliary windows. 

403def test_idle_resize(hud_main): 

404 mock_hud = MagicMock() 

405 mock_hud.aux_windows = [MagicMock()] 

406 hud_main.idle_resize(mock_hud) 

407 

408 mock_hud.resize_windows.assert_called_once() 

409 for aw in mock_hud.aux_windows: 

410 aw.resize_windows.assert_called_once() 

411 

412 

413# Checks that kill_hud removes the HUD from hud_dict and cleans up associated widgets. 

414def test_kill_hud(hud_main): 

415 mock_hud = MagicMock() 

416 hud_main.hud_dict["test_table"] = mock_hud 

417 hud_main.vb = MagicMock() 

418 

419 hud_main.kill_hud(None, "test_table") 

420 

421 assert "test_table" not in hud_main.hud_dict 

422 mock_hud.kill.assert_called_once() 

423 hud_main.vb.removeWidget.assert_called_once() 

424 

425 

426# Verifies that client_moved calls idle_move for the given HUD. 

427def test_client_moved(hud_main): 

428 mock_hud = MagicMock() 

429 with patch.object(hud_main, "idle_move") as mock_idle_move: 

430 hud_main.client_moved(None, mock_hud) 

431 mock_idle_move.assert_called_once_with(mock_hud) 

432 

433 

434# Ensures that client_resized calls idle_resize for the given HUD. 

435def test_client_resized(hud_main): 

436 mock_hud = MagicMock() 

437 with patch.object(hud_main, "idle_resize") as mock_idle_resize: 

438 hud_main.client_resized(None, mock_hud) 

439 mock_idle_resize.assert_called_once_with(mock_hud) 

440 

441 

442# Checks that client_destroyed calls kill_hud for the appropriate HUD. 

443def test_client_destroyed(hud_main): 

444 mock_hud = MagicMock() 

445 mock_hud.table.key = "test_table" 

446 with patch.object(hud_main, "kill_hud") as mock_kill_hud: 

447 hud_main.client_destroyed(None, mock_hud) 

448 mock_kill_hud.assert_called_once_with(None, "test_table") 

449 

450 

451# Verifies that idle_create creates a new HUD and adds it to hud_dict, along with logging. 

452@pytest.mark.parametrize("import_path", ["HUD_main.QLabel", "PyQt5.QtWidgets.QLabel"]) 

453def test_idle_create(import_path, hud_main): 

454 with patch(import_path) as mock_qlabel, patch("HUD_main.log") as mock_log: 

455 # Configuration 

456 mock_hud = MagicMock() 

457 mock_hud.tablehudlabel = MagicMock() 

458 hud_main.hud_dict = {"test_table": mock_hud} 

459 hud_main.vb = MagicMock() 

460 

461 new_hand_id = "new_hand_id" 

462 table = MagicMock() 

463 table.site = "test_site" 

464 table.number = 123 

465 temp_key = "test_table" 

466 max = 9 

467 poker_game = "holdem" 

468 hud_type = "cash" 

469 stat_dict = {} 

470 cards = {} 

471 

472 with ( 

473 patch.object(hud_main, "get_cards", return_value=cards), 

474 patch.object(hud_main.hud_dict["test_table"], "create") as mock_create, 

475 patch.object(hud_main.hud_dict["test_table"], "aux_windows", []), 

476 ): 

477 print("Before calling idle_create") 

478 

479 # Call idle_create 

480 hud_main.idle_create(new_hand_id, table, temp_key, max, poker_game, hud_type, stat_dict, cards) 

481 

482 print("After calling idle_create") 

483 print(f"mock_qlabel.call_count: {mock_qlabel.call_count}") 

484 print(f"mock_qlabel.call_args_list: {mock_qlabel.call_args_list}") 

485 

486 # Checks 

487 tablehudlabel = hud_main.hud_dict[temp_key].tablehudlabel 

488 print(f"tablehudlabel: {tablehudlabel}") 

489 print(f"Type of tablehudlabel: {tablehudlabel.__class__}") 

490 print(f"Is instance of mocked QLabel: {isinstance(tablehudlabel, mock_qlabel.return_value.__class__)}") 

491 

492 # Check taht vb.addWidget is called 

493 try: 

494 hud_main.vb.addWidget.assert_called_once() 

495 print("vb.addWidget assertion passed") 

496 except AssertionError as e: 

497 print(f"vb.addWidget assertion failed: {e}") 

498 

499 # Check attributs 

500 assert hud_main.hud_dict[temp_key].tablehudlabel is not None, "tablehudlabel is None" 

501 assert hud_main.hud_dict[temp_key].tablenumber == table.number, "tablenumber mismatch" 

502 print("hud_dict assertions passed") 

503 

504 # Check call 

505 try: 

506 mock_create.assert_called_once_with(new_hand_id, hud_main.config, stat_dict) 

507 print("create method assertion passed") 

508 except AssertionError as e: 

509 print(f"create method assertion failed: {e}") 

510 

511 # Check logs 

512 expected_log_message = f"adding label {table.site} - {temp_key}" 

513 print(f"Expected log message: {expected_log_message}") 

514 print(f"Actual log calls: {mock_log.debug.call_args_list}") 

515 

516 log_message_found = any(call[0][0] == expected_log_message for call in mock_log.debug.call_args_list) 

517 if log_message_found: 

518 print("Log assertion passed") 

519 else: 

520 print("Log assertion failed: Expected message not found in debug logs") 

521 

522 

523# Ensures that idle_update updates the HUD and auxiliary windows. 

524def test_idle_update(hud_main): 

525 # Create a mock HUD 

526 temp_key = "table_name" 

527 mock_hud = MagicMock() 

528 hud_main.hud_dict[temp_key] = mock_hud 

529 hud_main.hud_dict[temp_key].aux_windows = [MagicMock()] 

530 

531 # Call idle_update 

532 hud_main.idle_update("new_hand_id", temp_key, hud_main.config) 

533 

534 # Assert update method was called 

535 mock_hud.update.assert_called_once_with("new_hand_id", hud_main.config) 

536 

537 # Assert aux_windows update_gui was called 

538 for aw in hud_main.hud_dict[temp_key].aux_windows: 

539 aw.update_gui.assert_called_once_with("new_hand_id") 

540 

541 

542# Confirms that idle_kill removes widgets from the layout and calls the HUD's kill method. 

543def test_idle_kill_widget_removal(hud_main): 

544 mock_hud = MagicMock() 

545 hud_main.hud_dict["test_table"] = mock_hud 

546 hud_main.vb = MagicMock() 

547 

548 # Call idle_kill 

549 hud_main.idle_kill("test_table") 

550 

551 # Assert widget was removed from layout 

552 hud_main.vb.removeWidget.assert_called_once_with(mock_hud.tablehudlabel) 

553 

554 # Assert kill method on HUD was called 

555 mock_hud.kill.assert_called_once() 

556 

557 # Assert HUD is removed from the dictionary 

558 assert "test_table" not in hud_main.hud_dict 

559 

560 

561# Ensures that check_tables calls the correct methods for different table statuses. 

562@pytest.mark.parametrize("status", ["client_destroyed", "client_moved", "client_resized"]) 

563def test_check_tables_full_coverage(hud_main, status): 

564 mock_hud = MagicMock() 

565 mock_hud.table.check_table.return_value = status 

566 hud_main.hud_dict = {"test_table": mock_hud} 

567 

568 # Map status to expected method 

569 method_map = { 

570 "client_destroyed": "client_destroyed", 

571 "client_moved": "client_moved", 

572 "client_resized": "client_resized", 

573 } 

574 

575 with patch.object(hud_main, method_map[status]) as mock_method: 

576 hud_main.check_tables() 

577 mock_method.assert_called_once_with(None, mock_hud) 

578 

579 

580# Verifies that the appropriate idle methods (idle_move, idle_resize, kill_hud) are called for different client actions. 

581@pytest.mark.parametrize( 

582 "method_name, expected_args", 

583 [ 

584 ("client_moved", (MagicMock(),)), 

585 ("client_resized", (MagicMock(),)), 

586 ("client_destroyed", (None, MagicMock().table.key)), 

587 ], 

588) 

589def test_client_methods(hud_main, method_name, expected_args): 

590 mock_hud = MagicMock() 

591 

592 # Map method to expected idle method 

593 idle_method = {"client_moved": "idle_move", "client_resized": "idle_resize", "client_destroyed": "kill_hud"}[ 

594 method_name 

595 ] 

596 

597 with patch.object(hud_main, idle_method) as mock_idle_method: 

598 getattr(hud_main, method_name)(None, mock_hud) 

599 if method_name == "client_destroyed": 

600 mock_idle_method.assert_called_once_with(expected_args[0], mock_hud.table.key) 

601 else: 

602 mock_idle_method.assert_called_once_with(mock_hud) 

603 

604 

605# Ensures that auxiliary windows are created and updated properly. 

606def test_aux_windows_creation_and_update(hud_main): 

607 mock_aux_window = MagicMock() 

608 hud_main.hud_dict["test_key"] = MagicMock() 

609 hud_main.hud_dict["test_key"].aux_windows = [mock_aux_window] 

610 

611 with patch("HUD_main.log.debug") as mock_log_debug: 

612 hud_main.idle_create("new_hand_id", MagicMock(), "test_key", 9, "poker_game", "cash", {}, {}) 

613 

614 mock_aux_window.create.assert_called_once() 

615 mock_aux_window.update_gui.assert_called_once_with("new_hand_id") 

616 mock_log_debug.assert_called_with("idle_create new_hand_id new_hand_id") 

617 

618 

619# Verifies that ZMQReceiver.close properly closes the socket and context, and logs the closure. 

620def test_zmqreceiver_close(hud_main): 

621 zmq_receiver = HUD_main.ZMQReceiver(port="5555") 

622 

623 with ( 

624 patch.object(zmq_receiver.socket, "close") as mock_socket_close, 

625 patch.object(zmq_receiver.context, "term") as mock_context_term, 

626 patch("HUD_main.log.info") as mock_log_info, 

627 ): 

628 zmq_receiver.close() 

629 

630 # Ensure socket.close and context.term were called 

631 mock_socket_close.assert_called_once() 

632 mock_context_term.assert_called_once() 

633 

634 # Ensure the closure was logged 

635 mock_log_info.assert_called_with("ZMQ receiver closed")