Skip to content

Commit d27faa7

Browse files
committed
add more tests
1 parent 54b28f4 commit d27faa7

4 files changed

Lines changed: 204 additions & 11 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import napari
2+
import numpy as np
3+
import pytest
4+
from yt.data_objects.static_output import Dataset
5+
6+
from yt_napari.viewer import layers_to_yt
7+
8+
9+
@pytest.fixture
10+
def some_images():
11+
12+
sh = (8, 16, 32)
13+
n_images = 4
14+
images = []
15+
16+
for im in range(n_images):
17+
images.append(
18+
{
19+
"value": np.random.random(sh),
20+
"name": f"image_{im}",
21+
}
22+
)
23+
24+
return images
25+
26+
27+
def test_layers_to_yt(
28+
make_napari_viewer,
29+
some_images,
30+
):
31+
32+
viewer: napari.Viewer = make_napari_viewer()
33+
34+
for im in some_images:
35+
viewer.add_image(im["value"], name=im["name"])
36+
37+
bbox = np.array([[-1.0, 1.0], [-1.0, 1.0], [-1.5, 2.0]])
38+
ds = layers_to_yt(viewer, layers=["image_0", "image_1"], bbox=bbox)
39+
40+
assert isinstance(ds, Dataset)
41+
assert len(ds.field_list) == 2
42+
43+
44+
def test_layers_bad_names(make_napari_viewer, some_images):
45+
viewer: napari.Viewer = make_napari_viewer()
46+
for im in some_images:
47+
viewer.add_image(im["value"], name=im["name"])
48+
49+
with pytest.raises(RuntimeError, match="Layer notalayer not found"):
50+
_ = layers_to_yt(viewer, layers=["image_0", "notalayer"])
51+
52+
with pytest.raises(RuntimeError, match="Layer 100 not found"):
53+
_ = layers_to_yt(viewer, layers=[0, 100])
54+
55+
56+
def test_layers_bad_shape(make_napari_viewer, some_images):
57+
viewer: napari.Viewer = make_napari_viewer()
58+
for im in some_images:
59+
viewer.add_image(im["value"], name=im["name"])
60+
61+
viewer.add_image(np.random.random((10, 10, 20)), name="bad_shape")
62+
63+
with pytest.raises(RuntimeError, match="Layer notalayer not found"):
64+
_ = layers_to_yt(viewer, layers=["image_0", "notalayer"])
65+
66+
with pytest.raises(RuntimeError, match="Can only export layers as a yt dataset"):
67+
_ = layers_to_yt(viewer)
68+
69+
70+
def test_additional_kwargs(
71+
make_napari_viewer,
72+
some_images,
73+
):
74+
viewer: napari.Viewer = make_napari_viewer()
75+
76+
for im in some_images:
77+
viewer.add_image(im["value"], name=im["name"])
78+
79+
ds = layers_to_yt(viewer, length_unit="km")
80+
assert len(ds.field_list) == len(some_images)
81+
assert ds.domain_right_edge.to("km")[2].d == 1

src/yt_napari/_tests/test_phaseplot_widget.py

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import numpy as np
44
import pytest
55
from napari import Viewer
6+
from qtpy.QtWidgets import QComboBox, QVBoxLayout
67
from yt.visualization.profile_plotter import PhasePlot
78

8-
from yt_napari._widget_2d_plots import YTPhasePlot
9+
from yt_napari._widget_2d_plots import YTPhasePlot, _validate_cmyt_name
910

1011

1112
@pytest.fixture
@@ -49,7 +50,7 @@ def test_phaseplot_widget(
4950
r.callback_container.apply_logx.value = True
5051
r.callback_container.apply_logy.value = True
5152
r.callback_container.apply_logz.value = True
52-
53+
r.callback_container.reverse_cmap.value = True
5354
r.callback_container.save.value = True
5455

5556
svfig = str(tmp_path / "pp_fig.png")
@@ -58,3 +59,112 @@ def test_phaseplot_widget(
5859
assert os.path.isfile(svfig)
5960

6061
r.deleteLater()
62+
63+
64+
def test_phaseplot_fields(
65+
make_napari_viewer,
66+
some_images,
67+
):
68+
viewer: Viewer = make_napari_viewer()
69+
r = YTPhasePlot(napari_viewer=viewer)
70+
71+
for im in some_images:
72+
viewer.add_image(im["value"], name=im["name"])
73+
74+
r.update_layers.native.click()
75+
76+
r.layer_1.setCurrentIndex(len(some_images))
77+
assert r.layer_1.currentText() == r._default_index_fields[0]
78+
assert r.layer_1.currentIndex() == len(some_images)
79+
80+
r.render_button.native.click()
81+
82+
r.deleteLater()
83+
84+
85+
def test_weight_field(
86+
make_napari_viewer,
87+
some_images,
88+
):
89+
viewer: Viewer = make_napari_viewer()
90+
r = YTPhasePlot(napari_viewer=viewer)
91+
92+
for im in some_images:
93+
viewer.add_image(im["value"], name=im["name"])
94+
95+
r.update_layers.native.click()
96+
97+
r.layer_4_weight.setCurrentIndex(1)
98+
assert r.layer_4_weight.currentText() == some_images[0]["name"]
99+
100+
r.render_button.native.click()
101+
r.deleteLater()
102+
103+
104+
def test_apply_callbacks_without_render(
105+
make_napari_viewer,
106+
some_images,
107+
):
108+
viewer: Viewer = make_napari_viewer()
109+
r = YTPhasePlot(napari_viewer=viewer)
110+
111+
for im in some_images:
112+
viewer.add_image(im["value"], name=im["name"])
113+
114+
r.update_layers.native.click()
115+
116+
assert r.phase_plot is None
117+
r.run_callback_button.native.click()
118+
assert isinstance(r.phase_plot, PhasePlot)
119+
r.deleteLater()
120+
121+
122+
@pytest.mark.parametrize(
123+
"input_name,expected",
124+
[("cmapname.cmyt", "cmyt.cmapname"), ("notacmytcmap", "notacmytcmap")],
125+
)
126+
def test_validate_cmyt_name(input_name: str, expected: str):
127+
result = _validate_cmyt_name(input_name)
128+
assert result == expected
129+
130+
131+
def test_add_layer_dropdown(
132+
make_napari_viewer,
133+
some_images,
134+
):
135+
viewer: Viewer = make_napari_viewer()
136+
r = YTPhasePlot(napari_viewer=viewer)
137+
138+
for im in some_images:
139+
viewer.add_image(im["value"], name=im["name"])
140+
141+
r.update_layers.native.click()
142+
143+
sub_QVbox = QVBoxLayout()
144+
145+
r.add_layer_dropdown(
146+
"teststr",
147+
"teststr2",
148+
sub_QVbox,
149+
value=None,
150+
)
151+
n_items = sub_QVbox.count()
152+
index = n_items - 1
153+
# dropdown gets added to an inner layout
154+
layer_hbox = sub_QVbox.itemAt(index).layout()
155+
# should be 2 widgets here
156+
n_items = layer_hbox.count()
157+
assert n_items == 2
158+
assert isinstance(layer_hbox.itemAt(1).widget(), QComboBox)
159+
160+
r.add_layer_dropdown(
161+
"teststr",
162+
"teststr2",
163+
sub_QVbox,
164+
value=None,
165+
value_index=100,
166+
)
167+
168+
sub_QVbox.deleteLater()
169+
170+
r.deleteLater()

src/yt_napari/_widget_2d_plots.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from yt_napari._gui_utilities import clearLayout
1818
from yt_napari.viewer import layers_to_yt
1919

20-
if TYPE_CHECKING:
20+
if TYPE_CHECKING: # pragma: no cover
2121
import matplotlib.figure
2222

2323

@@ -144,13 +144,21 @@ def set_figure(self, figure: "matplotlib.figure.Figure"):
144144

145145

146146
class YTPhasePlot(QWidget):
147+
148+
_default_index_fields = ["x", "y", "z", "ones"]
149+
147150
def __init__(self, napari_viewer: "napari.viewer.Viewer", parent=None):
148151
super().__init__(parent)
149152
self.viewer = napari_viewer
150153
root_vbox = QVBoxLayout()
151154

152155
active_layers = self.available_layer_list
153156
self.current_layers = active_layers
157+
158+
self.layer_1: QComboBox = None
159+
self.layer_2: QComboBox = None
160+
self.layer_3: QComboBox = None
161+
self.layer_4_weight: QComboBox = None
154162
self.add_layer_dropdown("layer_1", "x field", root_vbox, value_index=0)
155163
self.add_layer_dropdown("layer_2", "y field", root_vbox, value_index=1)
156164
self.add_layer_dropdown("layer_3", "z field", root_vbox, value_index=2)
@@ -304,8 +312,8 @@ def apply_callbacks_and_render(self):
304312
def available_layer_list(self):
305313
layers = [layer.name for layer in self.viewer.layers]
306314

307-
dims = ["x", "y", "z", "ones"] # TODO: check ndim
308-
layers += dims
315+
# TODO: check ndim
316+
layers += self._default_index_fields
309317
return layers
310318

311319

src/yt_napari/viewer.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,12 +678,6 @@ def layers_to_yt(
678678
f"{available_layer_names}."
679679
)
680680
raise RuntimeError(msg)
681-
elif not isinstance(layer, str) and not isinstance(layer, int):
682-
msg = (
683-
f"Unexpected layer type, type({layer})={type(layer)} but it "
684-
f" must be a str or int."
685-
)
686-
raise TypeError(msg)
687681

688682
layer_shape = available_layers[layers[0]].data.shape
689683
# ndim = available_layers[layers[0]].ndim # use below...

0 commit comments

Comments
 (0)