diff --git a/docs/source/storage.rst b/docs/source/storage.rst index 44061902..45500c67 100644 --- a/docs/source/storage.rst +++ b/docs/source/storage.rst @@ -176,7 +176,7 @@ as JSON. Each dict (i.e., element) in the list defines a link, with each dict co the other Zarr file relative to the root path of the Zarr file containing the link. * ``path`` : Path to the linked object within the Zarr file idenfied by the ``source`` key * ``object_id``: Object id of the reference object. May be None in case the referenced object - does not have and assigned object_id (e.g., in the case we reference a dataset with a fixed + does not have an assigned object_id (e.g., in the case we reference a dataset with a fixed name but without and assigned ``data_type`` (or ``neurodata_type`` in the case of NWB). * ``source_object_id``: Object id of the source Zarr file indicated by the ``source`` key. The ``source`` should always have an ``object_id`` (at least if the ``source`` file is diff --git a/tests/unit/base_tests_zarrio.py b/tests/unit/base_tests_zarrio.py index a66a0aa8..f5bc5520 100644 --- a/tests/unit/base_tests_zarrio.py +++ b/tests/unit/base_tests_zarrio.py @@ -12,7 +12,8 @@ # Try to import Zarr and disable tests if Zarr is not available import zarr from hdmf_zarr.backend import ZarrIO -from hdmf_zarr.utils import ZarrDataIO +from hdmf_zarr.utils import ZarrDataIO, ZarrReference +from tests.unit.utils import (Baz, BazData, BazBucket, get_baz_buildmanager) # Try to import numcodecs and disable compression tests if it is not available try: @@ -290,6 +291,41 @@ def test_write_reference(self): writer.write_builder(builder) writer.close() + def test_write_references_roundtrip(self): + # Setup a file container with references + num_bazs = 10 + bazs = [] # set up dataset of references + for i in range(num_bazs): + bazs.append(Baz(name='baz%d' % i)) + baz_data = BazData(name='baz_data', data=bazs) + container = BazBucket(bazs=bazs, baz_data=baz_data) + manager=get_baz_buildmanager() + # write to file + with ZarrIO(self.store, manager=manager, mode='w') as writer: + writer.write(container=container) + # read from file and validate references + with ZarrIO(self.store, manager=manager, mode='r') as reader: + read_container = reader.read() + for i in range(num_bazs): + baz_name = 'baz%d' % i + expected_container = read_container.bazs[baz_name] + expected_value = {'source': '.', + 'path': '/bazs/' + baz_name, + 'object_id': expected_container.object_id, + 'source_object_id': read_container.object_id} + # Read the dict with the definition of the reference from the raw Zarr file and compare + # to also check that reference (included object id's) are defined correctly + self.assertDictEqual(reader.file['baz_data'][i], expected_value) + # Also test using the low-level reference functions + zarr_ref = ZarrReference(**expected_value) + # Check the ZarrReference first + self.assertEqual(zarr_ref.object_id, expected_value['object_id']) + self.assertEqual(zarr_ref.source_object_id, expected_value['source_object_id']) + # Check that the ZarReference is being resolved via the ZarrIO.resolve_ref + target_name, target_zarr_obj = reader.resolve_ref(zarr_ref) + self.assertEqual(target_name, baz_name) + self.assertEqual(target_zarr_obj.attrs['object_id'], expected_container.object_id) + def test_write_reference_compound(self): builder = self.createReferenceCompoundBuilder() writer = ZarrIO(self.store, manager=self.manager, mode='a')