|
20 | 20 | ) |
21 | 21 |
|
22 | 22 |
|
| 23 | +class _FakeArray: |
| 24 | + """Pickle-serializable array-like for testing .tolist() conversion.""" |
| 25 | + |
| 26 | + def tolist(self): |
| 27 | + return [1, 2, 3] |
| 28 | + |
| 29 | + def __iter__(self): |
| 30 | + return iter([1, 2, 3]) |
| 31 | + |
| 32 | + |
23 | 33 | # ==================== Fixtures ==================== |
24 | 34 |
|
25 | 35 |
|
@@ -318,6 +328,86 @@ def test_len_matches_anchor_count(self): |
318 | 328 | assert len(queue) == 3 |
319 | 329 |
|
320 | 330 |
|
| 331 | +@pytest.mark.core |
| 332 | +class TestDISCOQueueLoadAnchorPoints: |
| 333 | + """Tests for DISCOQueue.load_anchor_points static method.""" |
| 334 | + |
| 335 | + def test_load_from_json(self, tmp_path): |
| 336 | + """Should load anchor points from a JSON file.""" |
| 337 | + import json |
| 338 | + |
| 339 | + path = tmp_path / "anchors.json" |
| 340 | + path.write_text(json.dumps([0, 5, 12, 99])) |
| 341 | + |
| 342 | + result = DISCOQueue.load_anchor_points(path) |
| 343 | + |
| 344 | + assert result == [0, 5, 12, 99] |
| 345 | + |
| 346 | + def test_load_from_pickle(self, tmp_path): |
| 347 | + """Should load anchor points from a pickle file.""" |
| 348 | + import pickle |
| 349 | + |
| 350 | + path = tmp_path / "anchors.pkl" |
| 351 | + with open(path, "wb") as f: |
| 352 | + pickle.dump([2, 7, 15], f) |
| 353 | + |
| 354 | + result = DISCOQueue.load_anchor_points(path) |
| 355 | + |
| 356 | + assert result == [2, 7, 15] |
| 357 | + |
| 358 | + def test_load_converts_tolist(self, tmp_path): |
| 359 | + """Should call .tolist() on array-like objects (e.g. numpy arrays).""" |
| 360 | + import pickle |
| 361 | + |
| 362 | + path = tmp_path / "anchors.pkl" |
| 363 | + with open(path, "wb") as f: |
| 364 | + pickle.dump(_FakeArray(), f) |
| 365 | + |
| 366 | + result = DISCOQueue.load_anchor_points(path) |
| 367 | + |
| 368 | + assert result == [1, 2, 3] |
| 369 | + |
| 370 | + def test_file_not_found(self, tmp_path): |
| 371 | + """Should raise FileNotFoundError for missing files.""" |
| 372 | + with pytest.raises(FileNotFoundError, match="not found"): |
| 373 | + DISCOQueue.load_anchor_points(tmp_path / "nonexistent.json") |
| 374 | + |
| 375 | + def test_accepts_string_path(self, tmp_path): |
| 376 | + """Should accept a string path, not just Path objects.""" |
| 377 | + import json |
| 378 | + |
| 379 | + path = tmp_path / "anchors.json" |
| 380 | + path.write_text(json.dumps([10, 20])) |
| 381 | + |
| 382 | + result = DISCOQueue.load_anchor_points(str(path)) |
| 383 | + |
| 384 | + assert result == [10, 20] |
| 385 | + |
| 386 | + def test_init_with_anchor_points_path(self, tmp_path): |
| 387 | + """DISCOQueue should load anchor points from file when anchor_points_path is given.""" |
| 388 | + import json |
| 389 | + |
| 390 | + tasks = [Task(query=f"Q{i}") for i in range(10)] |
| 391 | + path = tmp_path / "anchors.json" |
| 392 | + path.write_text(json.dumps([2, 5, 8])) |
| 393 | + |
| 394 | + queue = DISCOQueue(tasks, anchor_points_path=path) |
| 395 | + |
| 396 | + assert len(queue) == 3 |
| 397 | + assert queue._anchor_points == [2, 5, 8] |
| 398 | + |
| 399 | + def test_init_rejects_both_anchor_args(self, tmp_path): |
| 400 | + """DISCOQueue should raise ValueError when both anchor_points and anchor_points_path are given.""" |
| 401 | + import json |
| 402 | + |
| 403 | + tasks = [Task(query=f"Q{i}") for i in range(5)] |
| 404 | + path = tmp_path / "anchors.json" |
| 405 | + path.write_text(json.dumps([0, 1])) |
| 406 | + |
| 407 | + with pytest.raises(ValueError, match="not both"): |
| 408 | + DISCOQueue(tasks, anchor_points=[0, 1], anchor_points_path=path) |
| 409 | + |
| 410 | + |
321 | 411 | # ==================== PriorityTaskQueue Tests ==================== |
322 | 412 |
|
323 | 413 |
|
|
0 commit comments