Skip to content

Commit a9cfbf9

Browse files
committed
Remove test-only methods from production: openImage()
Drop the openImage() methods from ZarrOpener and ZarrOpenActions. Success tests now load via ZarrOpener.getContents() (no UI) Rejection tests use the real openIJWithImage(), which is window-free on failure paths.
1 parent 2cebce7 commit a9cfbf9

3 files changed

Lines changed: 55 additions & 101 deletions

File tree

ome-zarr-fiji-ui/src/main/java/ome/zarr/fijiui/open/ZarrOpenActions.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,12 @@
4141
import java.nio.file.Paths;
4242
import java.util.Collections;
4343
import java.util.function.Consumer;
44-
import java.util.function.Function;
4544

46-
import net.imglib2.img.Img;
4745

4846
import ij.IJ;
4947
import ome.zarr.fijiui.open.options.ZarrOpenBehavior;
5048
import ome.zarr.fijiui.open.options.ZarrOpeningSettings;
5149
import ome.zarr.fijiui.open.options.ZarrReaderBackend;
52-
import ome.zarr.fiji.PyramidalDataset;
5350
import ome.zarr.fiji.open.ZarrOpener;
5451
import ome.zarr.fijiui.dialog.DnDActionChooser;
5552
import ome.zarr.fijiui.util.ScriptUtils;
@@ -238,11 +235,6 @@ public Object openBDVWithImage()
238235
return opener.openBDVWithImage();
239236
}
240237

241-
Object openImage( final Function< PyramidalDataset, Object > multiScaleImageOpener,
242-
final Function< Img< ? >, Object > singleScaleImageOpener )
243-
{
244-
return opener.openImage( multiScaleImageOpener, singleScaleImageOpener );
245-
}
246238

247239
/**
248240
* Opens the Fiji script editor pre-filled with a scriptlet that opens the

ome-zarr-fiji-ui/src/test/java/ome/zarr/fijiui/open/ZarrOpenActionsTest.java

Lines changed: 55 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import static org.junit.jupiter.api.Assertions.assertFalse;
3535
import static org.junit.jupiter.api.Assertions.assertNotNull;
3636
import static org.junit.jupiter.api.Assertions.assertNotSame;
37-
import static org.junit.jupiter.api.Assertions.assertNull;
3837
import static org.junit.jupiter.api.Assertions.assertSame;
3938
import static org.junit.jupiter.api.Assertions.assertTrue;
4039
import static org.mockito.Mockito.any;
@@ -78,10 +77,8 @@
7877
import java.util.Arrays;
7978
import java.util.List;
8079
import java.util.concurrent.atomic.AtomicBoolean;
81-
import java.util.concurrent.atomic.AtomicInteger;
8280
import java.util.concurrent.atomic.AtomicReference;
8381
import java.util.function.Consumer;
84-
import java.util.function.Function;
8582
import java.util.stream.Stream;
8683

8784
import bdv.tools.brightness.ConverterSetup;
@@ -100,7 +97,9 @@
10097
import ome.zarr.fiji.Pyramidal;
10198
import ome.zarr.zarrjava.ZarrJavaPyramidBackend;
10299
import ome.zarr.imglib2.exceptions.StoreAccessException;
100+
import ome.zarr.imglib2.PyramidBackend;
103101
import ome.zarr.imglib2.PyramidContents;
102+
import ome.zarr.fiji.open.ZarrOpener;
104103
import ome.zarr.fiji.PyramidalBdv;
105104
import ome.zarr.fiji.PyramidalDataset;
106105
import ome.zarr.fijiui.open.options.ZarrOpeningSettings;
@@ -113,11 +112,28 @@
113112

114113
class ZarrOpenActionsTest
115114
{
115+
116116
static Stream< ZarrReaderBackend > readerBackends()
117117
{
118118
return Stream.of( ZarrReaderBackend.N5, ZarrReaderBackend.ZARR_JAVA );
119119
}
120120

121+
/**
122+
* Loads the dataset headlessly through {@link ZarrOpener#getContents()} with
123+
* the given backend, without instantiating any UI. Returns the loaded
124+
* {@link PyramidContents}; throws the relevant domain exception (e.g.
125+
* {@link ome.zarr.imglib2.exceptions.NotAMultiscaleImageException} or
126+
* {@link ome.zarr.imglib2.exceptions.MultiImageDatasetException}).
127+
* Lets tests assert that a dataset opens as a multiscale image without showing a window.
128+
*/
129+
private static PyramidContents< ? > loadMultiscaleHeadless( final URI uri, final Context context,
130+
final ZarrReaderBackend backend )
131+
{
132+
final PyramidBackend pyramidBackend = backend.createBackend();
133+
final ZarrOpener opener = new ZarrOpener( uri, context, pyramidBackend, null, error -> {} );
134+
return opener.getContents();
135+
}
136+
121137
static Stream< String > omeZarrExamples()
122138
{
123139
return Stream.of(
@@ -290,18 +306,13 @@ void testOpenValidMultiScaleImagePath( String resource ) throws URISyntaxExcepti
290306
Path path = ZarrTestUtils.resourcePath( resource );
291307
try (Context context = new Context())
292308
{
293-
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context );
294-
AtomicInteger multiScaleCounter = new AtomicInteger( 0 );
295-
AtomicInteger singleScaleCounter = new AtomicInteger( 0 );
296-
Function< PyramidalDataset, Object > multiScaleOpeningCounter = dataset -> multiScaleCounter.incrementAndGet();
297-
Function< Img< ? >, Object > singleScaleOpeningCounter = img -> singleScaleCounter.incrementAndGet();
298-
actions.openImage( multiScaleOpeningCounter, singleScaleOpeningCounter );
299-
assertEquals( 1, multiScaleCounter.get() );
300-
assertEquals( 0, singleScaleCounter.get() );
309+
assertNotNull( loadMultiscaleHeadless( path.toUri(), context, ZarrOpeningSettings.DEFAULT_READER_BACKEND ),
310+
"Expected " + resource + " to open as a multiscale image" );
301311
}
302312
}
303313

304314
@Test
315+
@SuppressWarnings( "java:S1612" )
305316
void testOpenValidSingleScaleImagePath() throws URISyntaxException
306317
{
307318
String[] validPaths = {
@@ -313,19 +324,19 @@ void testOpenValidSingleScaleImagePath() throws URISyntaxException
313324
for ( String invalidPath : validPaths )
314325
{
315326
Path path = ZarrTestUtils.resourcePath( invalidPath );
316-
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, null, System.out::println );
317-
AtomicInteger multiScaleCounter = new AtomicInteger( 0 );
318-
AtomicInteger singleScaleCounter = new AtomicInteger( 0 );
319-
Function< PyramidalDataset, Object > multiScaleOpeningCounter = dataset -> multiScaleCounter.incrementAndGet();
320-
Function< Img< ? >, Object > singleScaleOpeningCounter = img -> singleScaleCounter.incrementAndGet();
321-
actions.openImage( multiScaleOpeningCounter, singleScaleOpeningCounter );
322-
assertEquals( 0, multiScaleCounter.get() );
323-
assertEquals( 0, singleScaleCounter.get() ); // currently not supported
327+
AtomicReference< String > capturedError = new AtomicReference<>();
328+
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, null, capturedError::set );
329+
assertDoesNotThrow( () -> {
330+
actions.openIJWithImage();
331+
} );
332+
assertNotNull( capturedError.get(),
333+
"Single-scale path " + invalidPath + " should be reported as not (yet) supported" );
324334
}
325335
}
326336
}
327337

328338
@Test
339+
@SuppressWarnings( "java:S1612" )
329340
void testOpenInvalidImagePaths() throws URISyntaxException
330341
{
331342
String[] invalidPaths = {
@@ -338,15 +349,16 @@ void testOpenInvalidImagePaths() throws URISyntaxException
338349
{
339350
Path path = ZarrTestUtils.resourcePath( invalidPath );
340351
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, null, System.out::println );
341-
Function< PyramidalDataset, Object > multiScaleNoOp = pyramidalDataset -> null;
342-
Function< Img< ? >, Object > singleScaleNoOp = img -> null;
343-
assertDoesNotThrow( () -> actions.openImage( multiScaleNoOp, singleScaleNoOp ) );
352+
assertDoesNotThrow( () -> {
353+
actions.openIJWithImage();
354+
} );
344355
}
345356
}
346357
}
347358

348359
@ParameterizedTest
349360
@MethodSource( "readerBackends" )
361+
@SuppressWarnings( "java:S1612" )
350362
void testOpenBioformats2rawCollectionRootReportsMultiImage( ZarrReaderBackend backend ) throws URISyntaxException
351363
{
352364
Path path = ZarrTestUtils.resourcePath( "ome/zarr/testdata/bioformats2raw_testing/bf2raw_dataset_v5.ome.zarr" );
@@ -357,13 +369,9 @@ void testOpenBioformats2rawCollectionRootReportsMultiImage( ZarrReaderBackend ba
357369
ZarrOpeningSettings settings = new ZarrOpeningSettings();
358370
settings.setReaderBackend( backend );
359371
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, settings, errorHandler );
360-
AtomicInteger multiScaleCounter = new AtomicInteger( 0 );
361-
AtomicInteger singleScaleCounter = new AtomicInteger( 0 );
362-
Function< PyramidalDataset, Object > multiScaleOpener = dataset -> multiScaleCounter.incrementAndGet();
363-
Function< Img< ? >, Object > singleScaleOpener = img -> singleScaleCounter.incrementAndGet();
364-
assertDoesNotThrow( () -> actions.openImage( multiScaleOpener, singleScaleOpener ) );
365-
assertEquals( 0, multiScaleCounter.get(), "Multi-image collection must not be opened as a single multiscale image" );
366-
assertEquals( 0, singleScaleCounter.get() );
372+
assertDoesNotThrow( () -> {
373+
actions.openIJWithImage();
374+
} );
367375
assertNotNull( capturedError.get(), "Error handler should have been called for backend " + backend );
368376
assertTrue( capturedError.get().contains( "multiple images" ),
369377
"Expected multi-image message from backend, got: " + capturedError.get() );
@@ -383,37 +391,24 @@ void testOpenBioformats2rawCollectionChildOpens( ZarrReaderBackend backend ) thr
383391
for ( String childPath : childPaths )
384392
{
385393
Path path = ZarrTestUtils.resourcePath( childPath );
386-
AtomicReference< String > capturedError = new AtomicReference<>();
387-
Consumer< String > errorHandler = capturedError::set;
388-
ZarrOpeningSettings settings = new ZarrOpeningSettings();
389-
settings.setReaderBackend( backend );
390-
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, settings, errorHandler );
391-
AtomicInteger multiScaleCounter = new AtomicInteger( 0 );
392-
AtomicInteger singleScaleCounter = new AtomicInteger( 0 );
393-
Function< PyramidalDataset, Object > multiScaleOpener = dataset -> multiScaleCounter.incrementAndGet();
394-
Function< Img< ? >, Object > singleScaleOpener = img -> singleScaleCounter.incrementAndGet();
395-
assertDoesNotThrow( () -> actions.openImage( multiScaleOpener, singleScaleOpener ),
396-
"Opening child image " + childPath + " should not throw" );
397-
assertEquals( 1, multiScaleCounter.get(),
398-
"Child image " + childPath + " should be opened as a multiscale image" );
399-
assertEquals( 0, singleScaleCounter.get() );
400-
assertNull( capturedError.get(),
401-
"Error handler should not have been called for child " + childPath + ", got: " + capturedError.get() );
394+
assertNotNull( loadMultiscaleHeadless( path.toUri(), context, backend ),
395+
"Child image " + childPath + " should open as a multiscale image" );
402396
}
403397
}
404398
}
405399

406400
@Test
401+
@SuppressWarnings( "java:S1612" )
407402
void testOpenNonMatchingResolution() throws URISyntaxException
408403
{
409404
try (Context context = new Context())
410405
{
411406
Path path = ZarrTestUtils.resourcePath( "ome/zarr/testdata/5d_testing/5d_dataset_v4.ome.zarr" );
412407
ZarrOpeningSettings settings = new ZarrOpeningSettings( ZarrOpenBehavior.IMAGEJ_CUSTOM_RESOLUTION, 10 );
413408
ZarrOpenActions actions = new ZarrOpenActions( path.toUri(), context, settings, System.out::println );
414-
Function< PyramidalDataset, Object > multiScaleNoOp = pyramidalDataset -> null;
415-
Function< Img< ? >, Object > singleScaleNoOp = img -> null;
416-
assertDoesNotThrow( () -> actions.openImage( multiScaleNoOp, singleScaleNoOp ) );
409+
assertDoesNotThrow( () -> {
410+
actions.openIJWithImage();
411+
} );
417412
}
418413
}
419414

@@ -673,25 +668,17 @@ void openImageFromS3( final ZarrReaderBackend backend )
673668
{
674669
try (Context context = new Context())
675670
{
676-
final AtomicReference< String > error = new AtomicReference<>();
677-
final ZarrOpeningSettings settings = new ZarrOpeningSettings();
678-
settings.setReaderBackend( backend );
679-
final ZarrOpenActions actions = new ZarrOpenActions( S3_JANELIA_CHOROID_PLEXUS, context, settings, error::set );
680-
final AtomicInteger multiScaleCounter = new AtomicInteger( 0 );
681-
final AtomicInteger singleScaleCounter = new AtomicInteger( 0 );
682-
actions.openImage( dataset -> multiScaleCounter.incrementAndGet(), img -> singleScaleCounter.incrementAndGet() );
683-
assertNull( error.get(), "Error handler called for backend " + backend + ": " + error.get() );
684-
assertEquals( 1, multiScaleCounter.get() );
685-
assertEquals( 0, singleScaleCounter.get() );
671+
final PyramidContents< ? > contents = loadMultiscaleHeadless( S3_JANELIA_CHOROID_PLEXUS, context, backend );
672+
assertNotNull( contents, "Expected the S3 dataset to open as a multiscale image for backend " + backend );
686673
}
687674
}
688675

689676
@ParameterizedTest
690677
@MethodSource( "readerBackends" )
691-
@SuppressWarnings( "rawtypes" )
678+
@SuppressWarnings( "java:S1612" )
692679
void storeAccessErrorIsReportedToErrorHandler( final ZarrReaderBackend backend )
693680
{
694-
try ( Context context = new Context() )
681+
try (Context context = new Context())
695682
{
696683
final URI uri = URI.create( "s3://nonexistent-bucket/some/path" );
697684
final AtomicReference< String > capturedError = new AtomicReference<>();
@@ -700,22 +687,26 @@ void storeAccessErrorIsReportedToErrorHandler( final ZarrReaderBackend backend )
700687

701688
if ( backend == ZarrReaderBackend.ZARR_JAVA )
702689
{
703-
try ( MockedConstruction< ZarrJavaPyramidBackend > mock = mockConstruction(
690+
try (MockedConstruction< ZarrJavaPyramidBackend > mock = mockConstruction(
704691
ZarrJavaPyramidBackend.class,
705692
( mockBackend, ctx ) -> when( mockBackend.load( any() ) )
706693
.thenThrow( new StoreAccessException( uri.toString(),
707-
new RuntimeException( "Access Denied (403)" ) ) ) ) )
694+
new RuntimeException( "Access Denied (403)" ) ) ) ))
708695
{
709696
final ZarrOpenActions actions = new ZarrOpenActions( uri, context, settings, capturedError::set );
710-
assertDoesNotThrow( () -> actions.openImage( dataset -> null, img -> null ) );
697+
assertDoesNotThrow( () -> {
698+
actions.openIJWithImage();
699+
} );
711700
assertEquals( 1, mock.constructed().size(), "Expected exactly one ZarrJavaPyramidBackend to be constructed" );
712701
}
713702
}
714703
else
715704
{
716705
// N5 backend throws N5Exception.N5IOException immediately (local failure, no network needed)
717706
final ZarrOpenActions actions = new ZarrOpenActions( uri, context, settings, capturedError::set );
718-
assertDoesNotThrow( () -> actions.openImage( dataset -> null, img -> null ) );
707+
assertDoesNotThrow( () -> {
708+
actions.openIJWithImage();
709+
} );
719710
}
720711

721712
assertNotNull( capturedError.get(), "Error handler should have been called for backend " + backend );

ome-zarr-fiji/src/main/java/ome/zarr/fiji/open/ZarrOpener.java

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -257,35 +257,6 @@ private Object openPyramidImage( final Supplier< Object > multiScaleOpener, fina
257257
return null;
258258
}
259259

260-
/**
261-
* Opens the dataset and applies a caller-supplied function to it: the
262-
* multiscale function receives a {@link PyramidalDataset} at the preferred
263-
* resolution level, the single-scale function an {@link Img} (single-scale
264-
* support is still pending). Returns the function's result, or {@code null}
265-
* if opening failed.
266-
*/
267-
public Object openImage( final Function< PyramidalDataset, Object > multiScaleImageOpener,
268-
final Function< Img< ? >, Object > singleScaleImageOpener )
269-
{
270-
try
271-
{
272-
return openPyramidImage(
273-
() -> {
274-
final PyramidContents< ? > contents = getContents();
275-
final PyramidalDataset dataset = new PyramidalDataset( context, contents, preferredResolutionLevel );
276-
final Object result = multiScaleImageOpener.apply( dataset );
277-
logger.info( "Opened dataset: {}", inputUri );
278-
return result;
279-
},
280-
singleScaleImageOpener );
281-
}
282-
catch ( NoMatchingResolutionException e )
283-
{
284-
showNonMatchingResolutionError( e );
285-
}
286-
return null;
287-
}
288-
289260
private Object openSingleScaleImage( final Function< Img< ? >, Object > singleScaleImageOpener ) throws NotASingleScaleImageException
290261
{
291262
N5Reader reader = new N5Factory().openReader( inputUri.toString() );

0 commit comments

Comments
 (0)