Skip to content

Commit e849b3f

Browse files
committed
all unit tests
1 parent 16080b1 commit e849b3f

9 files changed

Lines changed: 231 additions & 97 deletions

plotpy/tests/tools/test_cross_section_line.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""Line cross section test"""
77

88
# guitest: show
9+
from __future__ import annotations
910

1011
from guidata.qthelpers import qt_app_context
1112

plotpy/tests/tools/test_cross_section_oblique.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
# guitest: show
99

10+
from __future__ import annotations
11+
1012
from plotpy.panels.csection.csitem import ObliqueCrossSectionItem
1113
from plotpy.panels.csection.cswidget import ObliqueCrossSection
1214
from plotpy.tests.tools import test_cross_section_line
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# guitest: show
2+
3+
from __future__ import annotations
4+
5+
import qtpy.QtCore as QC
6+
from guidata.qthelpers import exec_dialog, qt_app_context
7+
8+
from plotpy.interfaces.items import IImageItemType
9+
from plotpy.tests.unit.test_point_tools import create_window
10+
from plotpy.tools import AspectRatioTool
11+
12+
13+
def test_aspect_ratio_tool():
14+
with qt_app_context(exec_loop=False):
15+
win, tool = create_window(AspectRatioTool, active_item_type=IImageItemType)
16+
plot = win.manager.get_plot()
17+
18+
initial_aspect_ratio: float = plot.get_aspect_ratio()
19+
20+
new_ratio = 0.5
21+
22+
plot.set_aspect_ratio(new_ratio)
23+
tool.edit_aspect_ratio()
24+
assert plot.get_aspect_ratio() == new_ratio
25+
26+
plot.set_aspect_ratio(initial_aspect_ratio)
27+
tool.edit_aspect_ratio()
28+
assert plot.get_aspect_ratio() == initial_aspect_ratio
29+
30+
tool.lock_aspect_ratio(True)
31+
assert plot.lock_aspect_ratio is True
32+
tool.lock_aspect_ratio(False)
33+
assert plot.lock_aspect_ratio is False
34+
35+
exec_dialog(win)
36+
37+
38+
if __name__ == "__main__":
39+
test_aspect_ratio_tool()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# guitest: show
2+
from __future__ import annotations
3+
4+
import numpy as np
5+
from guidata.qthelpers import qt_app_context
6+
7+
from plotpy.interfaces.items import IImageItemType
8+
from plotpy.tests.unit.test_point_tools import create_window, drag_mouse
9+
from plotpy.tools import DisplayCoordsTool
10+
11+
12+
def test_display_coords_on_curve():
13+
with qt_app_context(exec_loop=False) as qapp:
14+
win, tool = create_window(DisplayCoordsTool)
15+
drag_mouse(win, qapp, np.array([0.5]), np.array([0.5]), click=False)
16+
drag_mouse(win, qapp, np.array([0.5]), np.array([0.5]), click=True)
17+
18+
19+
def test_display_coords_on_image():
20+
with qt_app_context(exec_loop=False) as qapp:
21+
win, tool = create_window(DisplayCoordsTool, active_item_type=IImageItemType)
22+
drag_mouse(win, qapp, np.array([0.5]), np.array([0.5]), click=False)
23+
drag_mouse(win, qapp, np.array([0.5]), np.array([0.5]), click=True)
24+
25+
26+
if __name__ == "__main__":
27+
test_display_coords_on_curve()
28+
test_display_coords_on_image()
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# guitest: show
2+
from __future__ import annotations
3+
4+
import numpy as np
5+
import qtpy.QtCore as QC
6+
from guidata.qthelpers import exec_dialog, qt_app_context
7+
8+
from plotpy.tests.unit.test_point_tools import (
9+
CLICK,
10+
create_window,
11+
keyboard_event,
12+
mouse_event_at_relative_plot_pos,
13+
)
14+
from plotpy.tools import FreeFormTool, MultiLineTool
15+
16+
17+
def test_free_form_tool():
18+
corners = np.array(((0.1, 0.1), (0.1, 0.8), (0.8, 0.8), (0.8, 0.1)))
19+
with qt_app_context(exec_loop=False) as qapp:
20+
win, tool = create_window(FreeFormTool)
21+
22+
# drag_mouse(win, qapp, x_path, y_path)
23+
for x, y in corners:
24+
mouse_event_at_relative_plot_pos(win, qapp, (x, y), CLICK)
25+
26+
assert tool.shape is not None
27+
28+
assert tool.shape.get_points().shape == corners.shape
29+
30+
exec_dialog(win)
31+
32+
33+
def test_multiline_tool():
34+
n = 100
35+
t = np.linspace(0, np.pi * 10, n)
36+
37+
# Create x and y arrays
38+
x_arr = t * np.cos(t) / n + 0.5
39+
y_arr = t * np.sin(t) / n + 0.5
40+
41+
with qt_app_context(exec_loop=False) as qapp:
42+
win, tool = create_window(MultiLineTool)
43+
44+
# drag_mouse(win, qapp, x_path, y_path)
45+
for x, y in zip(x_arr, y_arr):
46+
mouse_event_at_relative_plot_pos(win, qapp, (x, y), CLICK)
47+
48+
assert tool.shape is not None
49+
assert tool.shape.get_points().shape == np.array([x_arr, y_arr]).T.shape
50+
51+
# Delete last point
52+
keyboard_event(win, qapp, QC.Qt.Key.Key_Backspace)
53+
54+
points_count, _ = tool.shape.get_points().shape
55+
56+
assert points_count == (n - 1)
57+
58+
exec_dialog(win)
59+
60+
61+
if __name__ == "__main__":
62+
test_free_form_tool()
63+
test_multiline_tool()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# guitest: show
2+
3+
from __future__ import annotations
4+
5+
import numpy as np
6+
from guidata.qthelpers import exec_dialog, qt_app_context
7+
8+
from plotpy.interfaces.items import IImageItemType
9+
from plotpy.panels.csection.cswidget import ObliqueCrossSection
10+
from plotpy.tests.unit.test_point_tools import create_window, drag_mouse
11+
from plotpy.tools import ObliqueCrossSectionTool
12+
13+
14+
def test_oblique_cross_section():
15+
with qt_app_context(exec_loop=False) as qapp:
16+
win, tool = create_window(
17+
ObliqueCrossSectionTool,
18+
active_item_type=IImageItemType,
19+
panels=[ObliqueCrossSection],
20+
)
21+
n = 100
22+
x_path = np.linspace(0.25, 0.75, n)
23+
y_path = np.linspace(0.25, 0.75, n)
24+
drag_mouse(win, qapp, x_path, y_path)
25+
26+
exec_dialog(win)
27+
28+
29+
if __name__ == "__main__":
30+
test_oblique_cross_section()

plotpy/tests/unit/test_point_tools.py

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,35 @@
11
# guitest: show
2+
from __future__ import annotations
23

3-
from typing import TYPE_CHECKING, TypeVar
4+
from typing import TYPE_CHECKING, TypeVar, Union
45

56
import numpy as np
67
import qtpy.QtCore as QC
78
import qtpy.QtGui as QG
89
import qtpy.QtWidgets as QW
910
from guidata.qthelpers import exec_dialog, qt_app_context
10-
from numpy import linspace, sin
1111

12-
from plotpy.builder import make
13-
from plotpy.interfaces.items import ICurveItemType
12+
from plotpy.interfaces.items import ICurveItemType, IItemType
13+
from plotpy.panels.base import PanelWidget
1414
from plotpy.plot.plotwidget import PlotDialog, PlotWindow
1515
from plotpy.tests import vistools as ptv
16+
from plotpy.tests.features.test_auto_curve_image import make_curve_image_legend
1617
from plotpy.tools import (
18+
CommandTool,
1719
EditPointTool,
1820
InteractiveTool,
1921
SelectPointsTool,
2022
SelectPointTool,
2123
)
24+
from plotpy.tools.curve import DownSamplingTool
2225

2326
if TYPE_CHECKING:
27+
2428
from plotpy.items.curve.base import CurveItem
29+
from plotpy.items.image.base import BaseImageItem
2530

2631
CLICK = (QC.QEvent.Type.MouseButtonPress, QC.QEvent.Type.MouseButtonRelease)
27-
ToolT = TypeVar("ToolT", bound=InteractiveTool)
32+
ToolT = TypeVar("ToolT", bound=Union[InteractiveTool, CommandTool])
2833

2934

3035
def keyboard_event(
@@ -77,7 +82,7 @@ def mouse_event_at_relative_plot_pos(
7782
size = canva.size()
7883
pos_x, pos_y = (
7984
relative_xy[0] * size.width(),
80-
size.height() - relative_xy[1] * size.height(),
85+
relative_xy[1] * size.height(),
8186
)
8287
# pos_x, pos_y = axes_to_canvas(plot.get_active_item(), x, y)
8388
canva_pos = QC.QPointF(pos_x, pos_y).toPoint()
@@ -97,37 +102,44 @@ def mouse_event_at_relative_plot_pos(
97102

98103

99104
def drag_mouse(
100-
win: PlotDialog,
105+
win: PlotWindow,
101106
qapp: QW.QApplication,
102107
x_path: np.ndarray,
103108
y_path: np.ndarray,
104109
mod=QC.Qt.KeyboardModifier.NoModifier,
110+
click=True,
105111
) -> None:
106112
x0, y0 = x_path[0], y_path[0]
107113
xn, yn = x_path[-1], y_path[-1]
108114
press = (QC.QEvent.Type.MouseButtonPress,)
109115
move = (QC.QEvent.Type.MouseMove,)
110116
release = (QC.QEvent.Type.MouseButtonRelease,)
111117

112-
mouse_event_at_relative_plot_pos(win, qapp, (x0, y0), press, mod)
118+
if click:
119+
mouse_event_at_relative_plot_pos(win, qapp, (x0, y0), press, mod)
113120
for x, y in zip(x_path, y_path):
114121
mouse_event_at_relative_plot_pos(win, qapp, (x, y), move, mod)
115-
mouse_event_at_relative_plot_pos(win, qapp, (xn, yn), release, mod)
122+
if click:
123+
mouse_event_at_relative_plot_pos(win, qapp, (xn, yn), release, mod)
116124

117125

118-
def create_window(tool_class: type[ToolT]) -> tuple[PlotWindow, ToolT]:
119-
n = 100
120-
x = linspace(
121-
0,
122-
n,
123-
)
124-
y = (sin(sin(sin(x / (n / 10)))) - 1) * -n
125-
curve = make.curve(x, y, color="b")
126-
win = ptv.show_items(
127-
[curve], wintitle="Unit tests for Point tools", auto_tools=False
128-
)
126+
def create_window(
127+
tool_class: type[ToolT],
128+
active_item_type: type[IItemType] = ICurveItemType,
129+
panels: list[type[PanelWidget]] | None = None,
130+
) -> tuple[PlotWindow, ToolT]:
131+
132+
items: list[CurveItem | BaseImageItem] = make_curve_image_legend()
133+
win = ptv.show_items(items, wintitle="Unit test plot", auto_tools=False)
129134
plot = win.manager.get_plot()
130-
plot.set_active_item(curve) # type: ignore
135+
for item in win.manager.get_plot().get_items()[::-1]:
136+
plot.set_active_item(item)
137+
last_active_item = plot.get_last_active_item(active_item_type)
138+
plot.set_active_item(last_active_item)
139+
140+
if panels is not None:
141+
for panel in panels:
142+
win.manager.add_panel(panel())
131143

132144
tool = win.manager.add_tool(tool_class)
133145
tool.activate()
@@ -137,7 +149,6 @@ def create_window(tool_class: type[ToolT]) -> tuple[PlotWindow, ToolT]:
137149
def test_free_select_point_tool():
138150
with qt_app_context(exec_loop=False) as qapp:
139151
win, tool = create_window(SelectPointTool)
140-
141152
mouse_event_at_relative_plot_pos(
142153
win,
143154
qapp,
@@ -189,15 +200,22 @@ def test_select_points_tool():
189200
def test_edit_point_tool():
190201
with qt_app_context(exec_loop=False) as qapp:
191202
win, tool = create_window(EditPointTool)
192-
curve_item: CurveItem = win.manager.get_plot().get_last_active_item(ICurveItemType) # type: ignore
203+
curve_item: CurveItem = win.manager.get_plot().get_active_item() # type: ignore
193204
orig_x, orig_y = curve_item.get_data()
194205

195206
assert orig_x is not None and orig_y is not None
196207
orig_x, orig_y = orig_x.copy(), orig_y.copy()
197208

198209
assert tool is not None
199210

200-
n = 100
211+
# must activate downsampling because the curve is too dense so the selection
212+
# distance threshold is too small for the programmed drag to select the first
213+
# point
214+
curve_item.param.dsamp_factor = 20
215+
win.manager.add_tool(DownSamplingTool).activate()
216+
# The steps must be very small to ensure the mouse passes close
217+
# enough to the first point of the curve to move it (distance < threshold)
218+
n = 1000
201219
min_v, max_v = 0, 1
202220
x_path = np.full(n, min_v)
203221
y_path = np.linspace(max_v, min_v, n)
@@ -206,7 +224,6 @@ def test_edit_point_tool():
206224
x_path = np.full(n, max_v)
207225

208226
drag_mouse(win, qapp, x_path, y_path)
209-
210227
curve_changes = tool.get_changes()[curve_item]
211228
for i, (x, y) in curve_changes.items():
212229
x_arr, y_arr = curve_item.get_data()

0 commit comments

Comments
 (0)