mirror of
https://github.com/kuhyx/testsAndMisc-archive.git
synced 2026-07-04 14:23:04 +02:00
- Add comprehensive tests for all packages (3572 tests, 100% branch coverage) - Split oversized test files to stay under 500-line limit - Add per-file ruff ignores for test-appropriate suppressions - Fix _cache_decks.py to properly convert JSON lists to tuples - Add session-scoped conftest fixture for logging handler cleanup (Python 3.14) - Update ruff pre-commit hook to v0.15.2 - Add codespell ignore words for test data - Add generated output files to .gitignore
296 lines
8.5 KiB
Python
296 lines
8.5 KiB
Python
"""Tests for Q9/Q12 diagram generation (networking/optimization)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import matplotlib as mpl
|
|
import matplotlib.pyplot as plt
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _patch_savefig(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""Prevent matplotlib from writing files to disk."""
|
|
monkeypatch.setattr(mpl.figure.Figure, "savefig", lambda *_a, **_kw: None)
|
|
monkeypatch.setattr(plt, "savefig", lambda *_a, **_kw: None)
|
|
|
|
|
|
# =====================================================================
|
|
# _q9q12_common
|
|
# =====================================================================
|
|
class TestQ9Q12Common:
|
|
"""Tests for _q9q12_common constants and helpers."""
|
|
|
|
def test_constants_exist(self) -> None:
|
|
from _q9q12_common import (
|
|
_CENTER_Y,
|
|
_LAST_CONDITION_INDEX,
|
|
BG,
|
|
DPI,
|
|
FS,
|
|
FS_EDGE,
|
|
FS_SMALL,
|
|
FS_TITLE,
|
|
GRAY1,
|
|
LIGHT_BLUE,
|
|
LIGHT_GREEN,
|
|
LIGHT_ORANGE,
|
|
LIGHT_RED,
|
|
LIGHT_YELLOW,
|
|
LN,
|
|
OUTPUT_DIR,
|
|
)
|
|
|
|
assert DPI == 300
|
|
assert BG == "white"
|
|
assert LN == "black"
|
|
assert FS == 8
|
|
assert FS_TITLE == 11
|
|
assert _LAST_CONDITION_INDEX == 3
|
|
assert _CENTER_Y == 2.5
|
|
assert isinstance(FS_EDGE, int)
|
|
assert isinstance(FS_SMALL, float)
|
|
assert isinstance(GRAY1, str)
|
|
assert isinstance(LIGHT_GREEN, str)
|
|
assert isinstance(LIGHT_RED, str)
|
|
assert isinstance(LIGHT_BLUE, str)
|
|
assert isinstance(LIGHT_YELLOW, str)
|
|
assert isinstance(LIGHT_ORANGE, str)
|
|
assert isinstance(OUTPUT_DIR, str)
|
|
|
|
def test_draw_box_rounded(self) -> None:
|
|
from _q9q12_common import draw_box
|
|
|
|
fig, ax = plt.subplots()
|
|
draw_box(ax, 1.0, 2.0, 3.0, 1.0, "test")
|
|
assert len(ax.patches) == 1
|
|
plt.close(fig)
|
|
|
|
def test_draw_box_not_rounded(self) -> None:
|
|
from _q9q12_common import draw_box
|
|
|
|
fig, ax = plt.subplots()
|
|
draw_box(ax, 0.0, 0.0, 2.0, 1.0, "rect", rounded=False)
|
|
assert len(ax.patches) == 1
|
|
plt.close(fig)
|
|
|
|
def test_draw_box_custom_edgecolor(self) -> None:
|
|
from _q9q12_common import draw_box
|
|
|
|
fig, ax = plt.subplots()
|
|
draw_box(ax, 0.0, 0.0, 2.0, 1.0, "custom", edgecolor="red")
|
|
assert len(ax.patches) == 1
|
|
plt.close(fig)
|
|
|
|
def test_draw_arrow(self) -> None:
|
|
from _q9q12_common import draw_arrow
|
|
|
|
fig, ax = plt.subplots()
|
|
draw_arrow(ax, 0.0, 0.0, 1.0, 1.0)
|
|
plt.close(fig)
|
|
|
|
def test_save_fig(self) -> None:
|
|
from _q9q12_common import save_fig
|
|
|
|
fig, _ax = plt.subplots()
|
|
save_fig(fig, "test_q9q12.png")
|
|
|
|
def test_draw_network_node(self) -> None:
|
|
from _q9q12_common import draw_network_node
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
draw_network_node(ax, "A", (2.5, 2.5), color="white", fontsize=10, r=0.3)
|
|
assert len(ax.patches) == 1
|
|
plt.close(fig)
|
|
|
|
def test_draw_network_edge_directed(self) -> None:
|
|
from _q9q12_common import draw_network_edge
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
draw_network_edge(
|
|
ax,
|
|
(1.0, 1.0),
|
|
(4.0, 4.0),
|
|
label="10",
|
|
directed=True,
|
|
)
|
|
plt.close(fig)
|
|
|
|
def test_draw_network_edge_undirected(self) -> None:
|
|
from _q9q12_common import draw_network_edge
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
draw_network_edge(
|
|
ax,
|
|
(1.0, 1.0),
|
|
(4.0, 4.0),
|
|
label="5",
|
|
directed=False,
|
|
)
|
|
plt.close(fig)
|
|
|
|
def test_draw_network_edge_no_label(self) -> None:
|
|
from _q9q12_common import draw_network_edge
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
draw_network_edge(ax, (1.0, 1.0), (4.0, 4.0), label="")
|
|
plt.close(fig)
|
|
|
|
def test_draw_network_edge_zero_length(self) -> None:
|
|
from _q9q12_common import draw_network_edge
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
# Same start and end => length 0, should return early
|
|
draw_network_edge(ax, (2.0, 2.0), (2.0, 2.0), label="x")
|
|
plt.close(fig)
|
|
|
|
def test_draw_network_edge_with_offset(self) -> None:
|
|
from _q9q12_common import draw_network_edge
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.set_xlim(0, 5)
|
|
ax.set_ylim(0, 5)
|
|
draw_network_edge(
|
|
ax,
|
|
(1.0, 1.0),
|
|
(4.0, 4.0),
|
|
label="off",
|
|
offset=0.5,
|
|
label_bg="#EEEEEE",
|
|
)
|
|
plt.close(fig)
|
|
|
|
|
|
# =====================================================================
|
|
# _q9q12_network_flow
|
|
# =====================================================================
|
|
class TestQ9Q12NetworkFlow:
|
|
"""Tests for network flow diagrams."""
|
|
|
|
def test_gen_ford_fulkerson(self) -> None:
|
|
from _q9q12_network_flow import gen_ford_fulkerson
|
|
|
|
gen_ford_fulkerson()
|
|
|
|
def test_gen_hungarian(self) -> None:
|
|
from _q9q12_network_flow import gen_hungarian
|
|
|
|
gen_hungarian()
|
|
|
|
def test_gen_min_cost_flow(self) -> None:
|
|
from _q9q12_network_flow import gen_min_cost_flow
|
|
|
|
gen_min_cost_flow()
|
|
|
|
|
|
# =====================================================================
|
|
# _q9q12_network_graph
|
|
# =====================================================================
|
|
class TestQ9Q12NetworkGraph:
|
|
"""Tests for network graph diagrams."""
|
|
|
|
def test_gen_cpm(self) -> None:
|
|
from _q9q12_network_graph import gen_cpm
|
|
|
|
gen_cpm()
|
|
|
|
def test_gen_kruskal(self) -> None:
|
|
from _q9q12_network_graph import gen_kruskal
|
|
|
|
gen_kruskal()
|
|
|
|
def test_gen_tsp(self) -> None:
|
|
from _q9q12_network_graph import gen_tsp
|
|
|
|
gen_tsp()
|
|
|
|
|
|
# =====================================================================
|
|
# _q9q12_processes
|
|
# =====================================================================
|
|
class TestQ9Q12Processes:
|
|
"""Tests for process diagrams (IPC, deadlock, producer-consumer)."""
|
|
|
|
def test_gen_ipc_mechanisms(self) -> None:
|
|
from _q9q12_processes import gen_ipc_mechanisms
|
|
|
|
gen_ipc_mechanisms()
|
|
|
|
def test_gen_deadlock_illustration(self) -> None:
|
|
from _q9q12_processes import gen_deadlock_illustration
|
|
|
|
gen_deadlock_illustration()
|
|
|
|
def test_gen_producer_consumer(self) -> None:
|
|
from _q9q12_processes import gen_producer_consumer
|
|
|
|
gen_producer_consumer()
|
|
|
|
def test_deadlock_coffman_conditions(self) -> None:
|
|
"""Verify all 4 Coffman conditions rendered, with last highlighted."""
|
|
from _q9q12_processes import gen_deadlock_illustration
|
|
|
|
gen_deadlock_illustration()
|
|
|
|
|
|
# =====================================================================
|
|
# generate_q9_q12_diagrams
|
|
# =====================================================================
|
|
class TestGenerateQ9Q12Diagrams:
|
|
"""Tests for the Q9/Q12 diagram generation entrypoint."""
|
|
|
|
def test_imports_work(self) -> None:
|
|
from generate_q9_q12_diagrams import (
|
|
gen_cpm,
|
|
gen_deadlock_illustration,
|
|
gen_ford_fulkerson,
|
|
gen_hungarian,
|
|
gen_ipc_mechanisms,
|
|
gen_kruskal,
|
|
gen_min_cost_flow,
|
|
gen_producer_consumer,
|
|
gen_tsp,
|
|
)
|
|
|
|
assert callable(gen_ford_fulkerson)
|
|
assert callable(gen_hungarian)
|
|
assert callable(gen_min_cost_flow)
|
|
assert callable(gen_cpm)
|
|
assert callable(gen_kruskal)
|
|
assert callable(gen_tsp)
|
|
assert callable(gen_ipc_mechanisms)
|
|
assert callable(gen_deadlock_illustration)
|
|
assert callable(gen_producer_consumer)
|
|
|
|
def test_all_generators_run(self) -> None:
|
|
from generate_q9_q12_diagrams import (
|
|
gen_cpm,
|
|
gen_deadlock_illustration,
|
|
gen_ford_fulkerson,
|
|
gen_hungarian,
|
|
gen_ipc_mechanisms,
|
|
gen_kruskal,
|
|
gen_min_cost_flow,
|
|
gen_producer_consumer,
|
|
gen_tsp,
|
|
)
|
|
|
|
gen_ipc_mechanisms()
|
|
gen_deadlock_illustration()
|
|
gen_producer_consumer()
|
|
gen_ford_fulkerson()
|
|
gen_hungarian()
|
|
gen_cpm()
|
|
gen_kruskal()
|
|
gen_tsp()
|
|
gen_min_cost_flow()
|