|
| 1 | +"""Test attrs read/write for all SpatialData container formats.""" |
| 2 | + |
| 3 | +import tempfile |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +import pytest |
| 7 | + |
| 8 | +from spatialdata import SpatialData, read_zarr |
| 9 | +from spatialdata._io.format import ( |
| 10 | + SpatialDataContainerFormats, |
| 11 | + SpatialDataContainerFormatType, |
| 12 | +) |
| 13 | + |
| 14 | +FORMAT_V01 = SpatialDataContainerFormats["0.1"] |
| 15 | +FORMAT_V02 = SpatialDataContainerFormats["0.2"] |
| 16 | + |
| 17 | + |
| 18 | +@pytest.mark.parametrize("sdata_container_format", [FORMAT_V01, FORMAT_V02]) |
| 19 | +class TestAttrsIO: |
| 20 | + """Test SpatialData.attrs read/write for all container formats.""" |
| 21 | + |
| 22 | + def test_attrs_write_and_read( |
| 23 | + self, |
| 24 | + sdata_container_format: SpatialDataContainerFormatType, |
| 25 | + ) -> None: |
| 26 | + """Test attrs with complex nested structures.""" |
| 27 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 28 | + f = Path(tmpdir) / "data.zarr" |
| 29 | + |
| 30 | + # Set complex attrs |
| 31 | + my_attrs = { |
| 32 | + "string_key": "test_value", |
| 33 | + "int_key": 123, |
| 34 | + "float_key": 3.14, |
| 35 | + "bool_key": True, |
| 36 | + "list_key": [1, 2, 3], |
| 37 | + "nested_dict": { |
| 38 | + "inner_key1": None, |
| 39 | + "inner_key2": 456, |
| 40 | + "nested_list": ["a", "b", "c"], |
| 41 | + }, |
| 42 | + } |
| 43 | + sdata = SpatialData() |
| 44 | + sdata.attrs = my_attrs |
| 45 | + |
| 46 | + # Write to disk with sdata_container_format |
| 47 | + sdata.write(f, sdata_formats=sdata_container_format) |
| 48 | + |
| 49 | + # Read back and verify attrs |
| 50 | + sdata_read = read_zarr(f) |
| 51 | + assert sdata_read.attrs == my_attrs |
| 52 | + |
| 53 | + def test_attrs_incremental_write( |
| 54 | + self, |
| 55 | + sdata_container_format: SpatialDataContainerFormatType, |
| 56 | + ) -> None: |
| 57 | + """Test incremental write of attrs using write_attrs() and write_metadata().""" |
| 58 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 59 | + f = Path(tmpdir) / "data.zarr" |
| 60 | + |
| 61 | + # Initial write with attrs using sdata_container_format |
| 62 | + initial_attrs = {"initial_key": "initial_value", "counter": 0} |
| 63 | + sdata = SpatialData() |
| 64 | + sdata.attrs = initial_attrs |
| 65 | + sdata.write(f, sdata_formats=sdata_container_format) |
| 66 | + |
| 67 | + # Verify initial attrs |
| 68 | + sdata_read1 = read_zarr(f) |
| 69 | + assert sdata_read1.attrs == initial_attrs |
| 70 | + |
| 71 | + # Update attrs using write_attrs() |
| 72 | + sdata_read1.attrs["counter"] = 1 |
| 73 | + sdata_read1.attrs["new_key"] = "new_value" |
| 74 | + sdata_read1.write_attrs(sdata_format=sdata_container_format) |
| 75 | + |
| 76 | + # Read back and verify updated attrs |
| 77 | + sdata_read2 = read_zarr(f) |
| 78 | + assert sdata_read2.attrs["counter"] == 1 |
| 79 | + assert sdata_read2.attrs["new_key"] == "new_value" |
| 80 | + assert sdata_read2.attrs["initial_key"] == "initial_value" |
| 81 | + |
| 82 | + # Update attrs using write_metadata() |
| 83 | + sdata_read2.attrs["counter"] = 2 |
| 84 | + sdata_read2.attrs["another_key"] = "another_value" |
| 85 | + sdata_read2.write_metadata(sdata_format=sdata_container_format) |
| 86 | + |
| 87 | + # Read back and verify all attrs |
| 88 | + sdata_read3 = read_zarr(f) |
| 89 | + assert sdata_read3.attrs["counter"] == 2 |
| 90 | + assert sdata_read3.attrs["new_key"] == "new_value" |
| 91 | + assert sdata_read3.attrs["another_key"] == "another_value" |
| 92 | + assert sdata_read3.attrs["initial_key"] == "initial_value" |
| 93 | + |
| 94 | + |
| 95 | +def test_attrs_v1_to_v2() -> None: |
| 96 | + """Test that attrs are preserved when converting from V01 to V02.""" |
| 97 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 98 | + f_v1 = Path(tmpdir) / "data_v1.zarr" |
| 99 | + f_v2 = Path(tmpdir) / "data_v2.zarr" |
| 100 | + |
| 101 | + # Set attrs and write with V01 |
| 102 | + my_attrs = { |
| 103 | + "test_key": "test_value", |
| 104 | + "counter": 1, |
| 105 | + "nested": {"inner": "value"}, |
| 106 | + } |
| 107 | + sdata = SpatialData() |
| 108 | + sdata.attrs = my_attrs |
| 109 | + sdata.write(f_v1, sdata_formats=FORMAT_V01) |
| 110 | + |
| 111 | + # Read with V01 |
| 112 | + sdata_v1 = read_zarr(f_v1) |
| 113 | + assert sdata_v1.attrs == my_attrs |
| 114 | + |
| 115 | + # Write with V02 |
| 116 | + sdata_v1.write(f_v2, sdata_formats=FORMAT_V02) |
| 117 | + |
| 118 | + # Read with V02 and verify attrs are preserved |
| 119 | + sdata_v2 = read_zarr(f_v2) |
| 120 | + assert sdata_v2.attrs == my_attrs |
0 commit comments