diff --git a/src/main/java/com/bc/zarr/ArrayParams.java b/src/main/java/com/bc/zarr/ArrayParams.java index 125f162..f203066 100644 --- a/src/main/java/com/bc/zarr/ArrayParams.java +++ b/src/main/java/com/bc/zarr/ArrayParams.java @@ -191,7 +191,9 @@ public ArrayParams dimensionSeparator(DimensionSeparator sep) { if (sep == null) { this.separator = DimensionSeparator.DOT; } - this.separator = sep; + else { + this.separator = sep; + } return this; } diff --git a/src/main/java/com/bc/zarr/ZarrHeader.java b/src/main/java/com/bc/zarr/ZarrHeader.java index f0e51a7..87f5f49 100644 --- a/src/main/java/com/bc/zarr/ZarrHeader.java +++ b/src/main/java/com/bc/zarr/ZarrHeader.java @@ -70,7 +70,14 @@ public ZarrHeader(int[] shape, int[] chunks, String dtype, ByteOrder byteOrder, } this.fill_value = fill_value; this.shape = shape; - this.dimension_separator = dimension_separator; + + if (dimension_separator != null) { + this.dimension_separator = dimension_separator; + } + else { + // consistent with ArrayParams' handling of null separators + this.dimension_separator = "."; + } } public int[] getChunks() { diff --git a/src/test/java/com/bc/zarr/ZarrUtilsTest.java b/src/test/java/com/bc/zarr/ZarrUtilsTest.java index 8f2fde8..ac18fe9 100644 --- a/src/test/java/com/bc/zarr/ZarrUtilsTest.java +++ b/src/test/java/com/bc/zarr/ZarrUtilsTest.java @@ -156,6 +156,11 @@ public void computeChunkFilename() { assertEquals("1.2.3.42", ZarrUtils.createChunkFilename(new int[]{1, 2, 3, 42}, ".")); } + @Test + public void computeChunkFilename2() { + assertEquals("1/2/3/42", ZarrUtils.createChunkFilename(new int[]{1, 2, 3, 42}, "/")); + } + private String expectedJson(boolean nullCompressor) { final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); @@ -201,4 +206,4 @@ public void computeSize() { assertEquals(24, intSize); assertEquals(intSize, longSize); } -} \ No newline at end of file +} diff --git a/src/test/java/com/bc/zarr/storage/FileSystemStoreTest.java b/src/test/java/com/bc/zarr/storage/FileSystemStoreTest.java index 81ae8ff..ab39610 100644 --- a/src/test/java/com/bc/zarr/storage/FileSystemStoreTest.java +++ b/src/test/java/com/bc/zarr/storage/FileSystemStoreTest.java @@ -32,6 +32,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import ucar.ma2.InvalidRangeException; import java.io.IOException; @@ -44,10 +46,12 @@ import static com.bc.zarr.ZarrConstants.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; /** * Test along https://zarr.readthedocs.io/en/stable/api/storage.html#zarr.storage.DirectoryStore */ +@RunWith(Parameterized.class) public class FileSystemStoreTest { private String testDataStr; @@ -57,9 +61,24 @@ public class FileSystemStoreTest { private Path rootPath; private Path testDataPath; + private final DimensionSeparator separator; + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][] { + {DimensionSeparator.DOT}, + {DimensionSeparator.SLASH}, + {null} + }); + } + + public FileSystemStoreTest(DimensionSeparator sep) { + this.separator = sep; + } + @Before public void setUp() throws Exception { - testDataStr = "testData"; + testDataStr = String.format("testData_%s", separator); rootPathStr = "group.zarr"; final int fileSystemAlternative = 1; @@ -198,7 +217,7 @@ public void createArray() throws IOException, JZarrException { .byteOrder(ByteOrder.LITTLE_ENDIAN) .fillValue(0) .compressor(null) - .dimensionSeparator(DimensionSeparator.SLASH); + .dimensionSeparator(separator); final ZarrArray fooArray = rootGrp.createArray("foo", parameters, attributes); //verification @@ -208,7 +227,7 @@ public void createArray() throws IOException, JZarrException { assertThat(Files.isReadable(fooPath.resolve(FILENAME_DOT_ZARRAY)), is(true)); assertThat(Files.isReadable(fooPath.resolve(FILENAME_DOT_ZATTRS)), is(true)); final ZarrHeader header = new ZarrHeader(shape, chunks, DataType.i1.toString(), ByteOrder.LITTLE_ENDIAN, - 0, null, DimensionSeparator.SLASH.getSeparatorChar()); + 0, null, separator == null ? null : separator.getSeparatorChar()); final String expected = strip(ZarrUtils.toJson(header, true)); assertThat(strip(getZarrayContent(fooPath)), is(equalToIgnoringWhiteSpace(expected))); assertThat(strip(getZattrsContent(fooPath)), is("{\"data\":[4.0,5.0,6.0,7.0,8.0]}")); @@ -225,7 +244,7 @@ public void writeArrayDataChunked() throws IOException, InvalidRangeException { final ArrayParams parameters = new ArrayParams() .dataType(DataType.i1).shape(shape).chunks(chunks) - .fillValue(0).compressor(null); + .fillValue(0).compressor(null).dimensionSeparator(separator); //execution final ZarrGroup rootGrp = ZarrGroup.create(store, null); @@ -235,10 +254,22 @@ public void writeArrayDataChunked() throws IOException, InvalidRangeException { //verification final Path fooPath = rootPath.resolve("foo"); assertThat(Files.isDirectory(fooPath), is(true)); - assertThat(Files.list(fooPath).filter( - path -> !path.getFileName().toString().startsWith(".") - ).count(), is(4L)); - final String[] chunkFileNames = {"0.0", "0.1", "1.0", "1.1"}; + + String[] chunkFileNames; + if (separator == DimensionSeparator.SLASH) { + List names = Files.list(fooPath).collect(Collectors.toList()); + assertThat(names.toString(), + Files.list(fooPath).filter( + path -> !path.getFileName().toString().startsWith(".") + ).count(), is(2L)); + chunkFileNames = new String[]{"0/0", "0/1", "1/0", "1/1"}; + } else { + assertThat(Files.list(fooPath).filter( + path -> !path.getFileName().toString().startsWith(".") + ).count(), is(4L)); + chunkFileNames = new String[]{"0.0", "0.1", "1.0", "1.1"}; + } + final byte[] expectedBytes = new byte[25]; Arrays.fill(expectedBytes, (byte) 42); for (String name : chunkFileNames) { @@ -247,6 +278,16 @@ public void writeArrayDataChunked() throws IOException, InvalidRangeException { assertThat(Files.size(chunkPath), is(5L * 5)); assertThat(Files.readAllBytes(chunkPath), is(expectedBytes)); } + + // Reopen the array to check that nesting v. flatness is detected. + final ZarrGroup rootGrp2 = ZarrGroup.create(store, null); + final ZarrArray fooArray2 = rootGrp.openArray("foo"); + if (separator == null) { + assertEquals(DimensionSeparator.DOT, fooArray2.getDimensionSeparator()); + } + else { + assertEquals(separator, fooArray2.getDimensionSeparator()); + } } @Test @@ -276,4 +317,4 @@ private String strip(String s) { } -} \ No newline at end of file +}