Files
vtt_work/nucleares_monitor/tests/test_arrangement_fixes.py
2025-10-29 15:51:25 +01:00

241 lines
7.7 KiB
Python

#!/usr/bin/env python3
"""
Test script to verify the fixed arrange_plot_windows function.
This tests:
1. Column-first arrangement (a-z in first column, then second column, etc.)
2. Corrected padding (Qt gets less padding, matplotlib gets more padding)
3. No double size calculation issues
4. Proper window detection from unified storage
"""
# Mock window classes for testing
class MockQtWindow:
def __init__(self, name):
self.name = name
self.geometry_calls = []
def setGeometry(self, x, y, w, h):
self.geometry_calls.append((x, y, w, h))
print(f"Qt Window '{self.name}': setGeometry({x}, {y}, {w}, {h})")
class MockTkWindow:
def __init__(self, name):
self.name = name
self.geometry_calls = []
def geometry(self, geom_str):
self.geometry_calls.append(geom_str)
print(f"Tk Window '{self.name}': geometry('{geom_str}')")
def test_arrangement_and_padding():
"""Test the column-first arrangement and corrected padding values."""
print("=== Testing Column-First Arrangement and Corrected Padding ===\n")
# Test case: 6 windows arranged in a 3x2 grid (3 rows, 2 columns)
windows = [
("qt", MockQtWindow("PlotA"), "PlotA"),
("tk", MockTkWindow("PlotB"), "PlotB"),
("qt", MockQtWindow("PlotC"), "PlotC"),
("tk", MockTkWindow("PlotD"), "PlotD"),
("qt", MockQtWindow("PlotE"), "PlotE"),
("tk", MockTkWindow("PlotF"), "PlotF"),
]
# Grid parameters
cols = 2
rows = 3
cell_w = 400
cell_h = 300
CELL_PAD = 10
# Mock monitor bounds
L, T, R, B = 100, 100, 1500, 900
SIDE_MARGIN = 20
TOP_MARGIN = 50
BOTTOM_MARGIN = 50
# Calculate grid layout (similar to real function)
grid_w = cell_w * cols + (cols + 1) * CELL_PAD
grid_h = cell_h * rows + (rows + 1) * CELL_PAD
mon_w = R - L
mon_h = B - T
origin_x = L + SIDE_MARGIN + max(0, (mon_w - grid_w - 2 * SIDE_MARGIN) // 2)
origin_y = (
T + TOP_MARGIN + max(0, (mon_h - grid_h - TOP_MARGIN - BOTTOM_MARGIN) // 2)
)
print(f"Grid: {cols}x{rows}, Cell: {cell_w}x{cell_h}")
print(f"Monitor: ({L},{T}) to ({R},{B})")
print(f"Grid origin: ({origin_x},{origin_y})")
print("Expected arrangement (column-first):")
print(" Column 1: PlotA(0,0), PlotB(0,1), PlotC(0,2)")
print(" Column 2: PlotD(1,0), PlotE(1,1), PlotF(1,2)")
print()
# Test the column-first arrangement with corrected padding
arrangement_results = []
i = 0
for c in range(cols): # Column-first: iterate columns first
for r in range(rows): # Then rows within each column
if i >= len(windows):
break
kind, win, name = windows[i]
# Calculate position
x = origin_x + CELL_PAD + c * (cell_w + CELL_PAD)
y = origin_y + CELL_PAD + r * (cell_h + CELL_PAD)
# Apply corrected padding (Qt less, Tk/matplotlib more)
if kind == "qt":
w_pad, h_pad = (8, 15) # Qt: minimal frames, precise sizing
else: # "tk" (matplotlib/canvas)
w_pad, h_pad = (20, 50) # Tk/matplotlib: toolbar + larger decorations
adj_w = max(50, cell_w - w_pad)
adj_h = max(50, cell_h - h_pad)
# Clamp to monitor bounds
final_x = max(L + SIDE_MARGIN, min(x, R - SIDE_MARGIN - adj_w))
final_y = max(T + TOP_MARGIN, min(y, B - BOTTOM_MARGIN - adj_h))
arrangement_results.append(
{
"name": name,
"kind": kind,
"column": c,
"row": r,
"padding": (w_pad, h_pad),
"size": (adj_w, adj_h),
"position": (final_x, final_y),
}
)
# Apply geometry
if kind == "qt":
win.setGeometry(final_x, final_y, adj_w, adj_h)
else:
win.geometry(f"{adj_w}x{adj_h}+{final_x}+{final_y}")
i += 1
print("\n=== Arrangement Results ===")
for result in arrangement_results:
name = result["name"]
kind = result["kind"]
col = result["column"]
row = result["row"]
w_pad, h_pad = result["padding"]
adj_w, adj_h = result["size"]
final_x, final_y = result["position"]
print(f"{name} ({kind}): Column {col}, Row {row}")
print(
f" Padding: {w_pad}x{h_pad} ({'minimal' if kind == 'qt' else 'toolbar+margins'})"
)
print(f" Final size: {adj_w}x{adj_h}")
print(f" Position: ({final_x},{final_y})")
print()
# Verify column-first arrangement
print("=== Verification ===")
expected_order = [
("PlotA", 0, 0),
("PlotB", 0, 1),
("PlotC", 0, 2), # Column 1
("PlotD", 1, 0),
("PlotE", 1, 1),
("PlotF", 1, 2), # Column 2
]
success = True
for i, (expected_name, expected_col, expected_row) in enumerate(expected_order):
actual = arrangement_results[i]
if (
actual["name"] != expected_name
or actual["column"] != expected_col
or actual["row"] != expected_row
):
print(
f"❌ Position {i}: Expected {expected_name} at ({expected_col},{expected_row}), "
f"got {actual['name']} at ({actual['column']},{actual['row']})"
)
success = False
if success:
print("✅ Column-first arrangement verified correctly!")
# Verify padding corrections
qt_windows = [r for r in arrangement_results if r["kind"] == "qt"]
tk_windows = [r for r in arrangement_results if r["kind"] == "tk"]
if qt_windows and tk_windows:
qt_pad = qt_windows[0]["padding"]
tk_pad = tk_windows[0]["padding"]
if qt_pad[0] < tk_pad[0] and qt_pad[1] < tk_pad[1]:
print(
"✅ Padding correction verified: Qt windows have less padding than Tk/matplotlib"
)
print(f" Qt padding: {qt_pad[0]}x{qt_pad[1]}")
print(f" Tk padding: {tk_pad[0]}x{tk_pad[1]}")
else:
print(f"❌ Padding incorrect: Qt {qt_pad} should be less than Tk {tk_pad}")
success = False
return success
def test_grid_calculation():
"""Test the grid calculation logic that prefers horizontal layouts."""
def best_grid(n):
"""Find best grid dimensions preferring horizontal layouts for small n."""
if n <= 0:
return (0, 0)
if n == 1:
return (1, 1)
if n <= 3:
return (n, 1) # Horizontal preference for small counts
best_ratio = float("inf")
best_cols, best_rows = 1, n
for cols in range(1, n + 1):
rows = (n + cols - 1) // cols
if cols * rows >= n:
ratio = max(cols / rows, rows / cols)
if ratio < best_ratio:
best_ratio = ratio
best_cols, best_rows = cols, rows
return (best_cols, best_rows)
print("\n=== Testing Grid Calculation ===")
test_cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 16]
for n in test_cases:
cols, rows = best_grid(n)
ratio = max(cols / rows, rows / cols) if rows > 0 else float("inf")
print(f"Windows: {n:2d} → Grid: {cols}x{rows} (ratio: {ratio:.2f})")
return True
if __name__ == "__main__":
print("Testing arrange_plot_windows fixes...\n")
result1 = test_arrangement_and_padding()
result2 = test_grid_calculation()
if result1 and result2:
print(
"\n🎉 All tests passed! The arrangement and padding fixes are working correctly."
)
else:
print("\n❌ Some tests failed. Check the implementation.")