From abf78b8afed8f4184c18acc4c791854980ea6ff0 Mon Sep 17 00:00:00 2001 From: rly Date: Thu, 11 Jan 2024 17:50:52 -0800 Subject: [PATCH] Add test and fix for cpd type with isodatetime --- src/hdmf/validate/validator.py | 5 +- tests/unit/validator_tests/test_validate.py | 65 +++++++++++++++++---- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/hdmf/validate/validator.py b/src/hdmf/validate/validator.py index 6c400d7b1..304ad084d 100644 --- a/src/hdmf/validate/validator.py +++ b/src/hdmf/validate/validator.py @@ -54,7 +54,10 @@ def check_type(expected, received, string_format=None): rec = received[i] if exp == "isodatetime": # short circuit for isodatetime sub_string_format = string_format[i] - return rec in ("utf", "ascii") and sub_string_format == "isodatetime" + return ( + rec in __allowable[exp] or + rec in ("utf", "ascii") and sub_string_format == "isodatetime" + ) if rec not in __allowable[exp]: return False return True diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index f019b830a..d4c132cd7 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -116,7 +116,18 @@ def getSpecs(self): ), DatasetSpec('an example time dataset', 'isodatetime', name='datetime'), DatasetSpec('an example time dataset', 'isodatetime', name='date', quantity='?'), - DatasetSpec('an array of times', 'isodatetime', name='time_array', dims=('num_times',), shape=(None,)) + DatasetSpec('an array of times', 'isodatetime', name='time_array', dims=('num_times',), shape=(None,)), + DatasetSpec( + doc='an array with compound dtype that includes an isodatetime', + dtype=[ + DtypeSpec('x', doc='x', dtype='int'), + DtypeSpec('y', doc='y', dtype='isodatetime'), + ], + name='cpd_array', + dims=('num_times',), + shape=(None,), + quantity="?", + ), ], attributes=[AttributeSpec('attr1', 'an example string attribute', 'text')]) return ret, @@ -129,7 +140,15 @@ def test_valid_isodatetime(self): DatasetBuilder('data', 100, attributes={'attr2': 10}), DatasetBuilder('datetime', datetime(2017, 5, 1, 12, 0, 0)), DatasetBuilder('date', date(2017, 5, 1)), - DatasetBuilder('time_array', [datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())]) + DatasetBuilder('time_array', [datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())]), + DatasetBuilder( + name='cpd_array', + data=[(1, datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()))], + dtype=[ + DtypeSpec('x', doc='x', dtype='int'), + DtypeSpec('y', doc='y', dtype='isodatetime'), + ], + ), ] ) validator = self.vmap.get_validator('Bar') @@ -143,7 +162,7 @@ def test_invalid_isodatetime(self): datasets=[ DatasetBuilder('data', 100, attributes={'attr2': 10}), DatasetBuilder('datetime', 100), - DatasetBuilder('time_array', [datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())]) + DatasetBuilder('time_array', [datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())]), ] ) validator = self.vmap.get_validator('Bar') @@ -152,18 +171,44 @@ def test_invalid_isodatetime(self): self.assertValidationError(result[0], DtypeError, name='Bar/datetime') def test_invalid_isodatetime_array(self): - builder = GroupBuilder('my_bar', - attributes={'data_type': 'Bar', 'attr1': 'a string attribute'}, - datasets=[DatasetBuilder('data', 100, attributes={'attr2': 10}), - DatasetBuilder('datetime', - datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())), - DatasetBuilder('time_array', - datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()))]) + builder = GroupBuilder( + 'my_bar', + attributes={'data_type': 'Bar', 'attr1': 'a string attribute'}, + datasets=[ + DatasetBuilder('data', 100, attributes={'attr2': 10}), + DatasetBuilder('datetime', datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())), + DatasetBuilder('time_array', datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())), + ], + ) validator = self.vmap.get_validator('Bar') result = validator.validate(builder) self.assertEqual(len(result), 1) self.assertValidationError(result[0], ExpectedArrayError, name='Bar/time_array') + def test_invalid_cpd_isodatetime_array(self): + builder = GroupBuilder( + 'my_bar', + attributes={'data_type': 'Bar', 'attr1': 'a string attribute'}, + datasets=[ + DatasetBuilder('data', 100, attributes={'attr2': 10}), + DatasetBuilder('datetime', datetime(2017, 5, 1, 12, 0, 0)), + DatasetBuilder('date', date(2017, 5, 1)), + DatasetBuilder('time_array', [datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())]), + DatasetBuilder( + name='cpd_array', + data=[(1, "wrong")], + dtype=[ + DtypeSpec('x', doc='x', dtype='int'), + DtypeSpec('y', doc='y', dtype='isodatetime'), + ], + ), + ], + ) + validator = self.vmap.get_validator('Bar') + result = validator.validate(builder) + self.assertEqual(len(result), 1) + self.assertValidationError(result[0], DtypeError, name='Bar/cpd_array') + class TestNestedTypes(ValidatorTestBase):