Skip to content

Commit 58c118f

Browse files
committed
Add unit tests for PyramidalService covering active pyramidal behavior and window focus
1 parent 4dccd1a commit 58c118f

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*-
2+
* #%L
3+
* OME-Zarr extras for Fiji
4+
* %%
5+
* Copyright (C) 2022 - 2026 SciJava developers
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package sc.fiji.ome.zarr.util;
30+
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
import static org.junit.jupiter.api.Assertions.assertNotNull;
33+
import static org.junit.jupiter.api.Assertions.assertNull;
34+
import static org.junit.jupiter.api.Assertions.assertSame;
35+
import static org.junit.jupiter.api.Assertions.assertTrue;
36+
37+
import org.junit.jupiter.api.Test;
38+
import org.scijava.Context;
39+
40+
import java.lang.reflect.InvocationTargetException;
41+
import java.net.URISyntaxException;
42+
import java.nio.file.Path;
43+
44+
import bdv.util.BdvHandle;
45+
import ij.IJ;
46+
import ij.ImagePlus;
47+
import ij.gui.ImageWindow;
48+
49+
import javax.swing.SwingUtilities;
50+
51+
import sc.fiji.ome.zarr.open.ZarrOpenActions;
52+
import sc.fiji.ome.zarr.pyramid.Pyramidal;
53+
54+
class PyramidalServiceTest
55+
{
56+
private static final String ZARR_2D = "sc/fiji/ome/zarr/util/2d_testing/2d_dataset_v4.ome.zarr";
57+
58+
private static final String ZARR_3D = "sc/fiji/ome/zarr/util/3d_testing/xyz/3d_dataset_v4.ome.zarr";
59+
60+
/**
61+
* Opening an OME-Zarr in BigDataViewer automatically registers the dataset and sets it as active.
62+
* Closing the BDV window unregisters it and clears the active pyramidal.
63+
*/
64+
@Test
65+
void openInBdv_setsActivePyramidal_closingClearsIt() throws URISyntaxException, InterruptedException, InvocationTargetException
66+
{
67+
Path path = ZarrTestUtils.resourcePath( ZARR_2D );
68+
try (Context context = new Context())
69+
{
70+
PyramidalService pyramidalService = context.getService( PyramidalService.class );
71+
BdvHandle bdvHandle = ( BdvHandle ) new ZarrOpenActions( path.toUri(), context ).openBDVWithImage();
72+
try
73+
{
74+
assertNotNull( pyramidalService.getActivePyramidal() );
75+
assertSame( pyramidalService.getPyramidals().get( 0 ), pyramidalService.getActivePyramidal() );
76+
assertEquals( 1, pyramidalService.getPyramidals().size() );
77+
}
78+
finally
79+
{
80+
bdvHandle.close();
81+
SwingUtilities.invokeAndWait( () -> {} );
82+
}
83+
assertNull( pyramidalService.getActivePyramidal() );
84+
assertTrue( pyramidalService.getPyramidals().isEmpty() );
85+
}
86+
}
87+
88+
/**
89+
* Focusing on a plain (non-OME-Zarr) IJ image clears the active pyramidal.
90+
* Focusing the BDV window again restores it.
91+
*/
92+
@Test
93+
void focusingNonOmeZarrIJWindow_clearsActivePyramidal() throws URISyntaxException, InterruptedException, InvocationTargetException
94+
{
95+
Path path = ZarrTestUtils.resourcePath( ZARR_2D );
96+
try (Context context = new Context())
97+
{
98+
PyramidalService pyramidalService = context.getService( PyramidalService.class );
99+
BdvHandle bdvHandle = ( BdvHandle ) new ZarrOpenActions( path.toUri(), context ).openBDVWithImage();
100+
ImagePlus nonOmeZarrImagePlus = null;
101+
try
102+
{
103+
Pyramidal bdvPyramidal = pyramidalService.getActivePyramidal();
104+
assertNotNull( bdvPyramidal );
105+
106+
// Create and show a plain ImageJ image (FIJI built-in synthetic sample)
107+
nonOmeZarrImagePlus = IJ.createImage( "Demo", "8-bit ramp", 64, 64, 1 );
108+
nonOmeZarrImagePlus.show();
109+
SwingUtilities.invokeAndWait( () -> {} );
110+
ImageWindow nonOmeZarrWindow = nonOmeZarrImagePlus.getWindow();
111+
assertNotNull( nonOmeZarrWindow );
112+
113+
// Focusing on a non-OME-Zarr window clears the active pyramidal
114+
pyramidalService.notifyImageJWindowFocused( nonOmeZarrWindow );
115+
assertNull( pyramidalService.getActivePyramidal() );
116+
assertEquals( 1, pyramidalService.getPyramidals().size() ); // BDV still tracked
117+
118+
// Focusing BDV again restores it
119+
pyramidalService.notifyBdvWindowFocused( bdvPyramidal );
120+
assertSame( bdvPyramidal, pyramidalService.getActivePyramidal() );
121+
}
122+
finally
123+
{
124+
if ( nonOmeZarrImagePlus != null )
125+
nonOmeZarrImagePlus.close();
126+
bdvHandle.close();
127+
SwingUtilities.invokeAndWait( () -> {} );
128+
}
129+
}
130+
}
131+
132+
/**
133+
* With two OME-Zarr datasets open in BDV, the active pyramidal tracks focus correctly.
134+
* Closing the non-active window preserves the active one; closing the active window clears it.
135+
*/
136+
@Test
137+
void openTwoBdvDatasets_switchFocusAndCloseInReverseOrder() throws URISyntaxException, InterruptedException, InvocationTargetException
138+
{
139+
Path path1 = ZarrTestUtils.resourcePath( ZARR_2D );
140+
Path path2 = ZarrTestUtils.resourcePath( ZARR_3D );
141+
try (Context context = new Context())
142+
{
143+
PyramidalService pyramidalService = context.getService( PyramidalService.class );
144+
BdvHandle bdvHandle1 = ( BdvHandle ) new ZarrOpenActions( path1.toUri(), context ).openBDVWithImage();
145+
BdvHandle bdvHandle2 = ( BdvHandle ) new ZarrOpenActions( path2.toUri(), context ).openBDVWithImage();
146+
try
147+
{
148+
assertEquals( 2, pyramidalService.getPyramidals().size() );
149+
Pyramidal bdv1 = pyramidalService.getPyramidals().get( 0 ); // first dataset opened
150+
Pyramidal bdv2 = pyramidalService.getPyramidals().get( 1 ); // second dataset opened, active
151+
assertSame( bdv2, pyramidalService.getActivePyramidal() );
152+
153+
// Switch focus to first dataset
154+
pyramidalService.notifyBdvWindowFocused( bdv1 );
155+
assertSame( bdv1, pyramidalService.getActivePyramidal() );
156+
157+
// Close the second (non-active) window — first remains active
158+
bdvHandle2.close();
159+
SwingUtilities.invokeAndWait( () -> {} );
160+
assertSame( bdv1, pyramidalService.getActivePyramidal() );
161+
assertEquals( 1, pyramidalService.getPyramidals().size() );
162+
assertSame( bdv1, pyramidalService.getPyramidals().get( 0 ) );
163+
}
164+
finally
165+
{
166+
bdvHandle1.close();
167+
SwingUtilities.invokeAndWait( () -> {} );
168+
}
169+
assertNull( pyramidalService.getActivePyramidal() );
170+
assertTrue( pyramidalService.getPyramidals().isEmpty() );
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)