def validate(**kwargs): """Validate an NWB file against a namespace""" io, namespace = getargs('io', 'namespace', kwargs) builder = io.read_builder() validator = ValidatorMap( io.manager.namespace_catalog.get_namespace(name=namespace)) return validator.validate(builder)
def test_roundtrip(self): # NOTE this does not use H5RoundTripMixin because this requires custom validation test_table = self.TestTable(name='test_table', description='my test table') test_table.add_column('dynamic_column', 'this is a dynamic column') test_table.add_row( my_col=3.0, indexed_col=[1.0, 3.0], dynamic_column=4, optional_col2=.5, ) self.filename = os.path.join(self.test_dir, 'test_TestTable.h5') with HDF5IO(self.filename, manager=self.manager, mode='w') as write_io: write_io.write(test_table, cache_spec=True) self.reader = HDF5IO(self.filename, manager=self.manager, mode='r') read_container = self.reader.read() self.assertIsNotNone(str(test_table)) # added as a test to make sure printing works self.assertIsNotNone(str(read_container)) # make sure we get a completely new object self.assertNotEqual(id(test_table), id(read_container)) # the name of the root container of a file is always 'root' (see h5tools.py ROOT_NAME) # thus, ignore the name of the container when comparing original container vs read container self.assertContainerEqual(read_container, test_table, ignore_name=True) builder = self.reader.read_builder() # TODO fix ValueError: No specification for 'Container' in namespace 'test_core' validator = ValidatorMap(self.manager.namespace_catalog.get_namespace(name=CORE_NAMESPACE)) errors = validator.validate(builder) if errors: for err in errors: raise Exception(err) self.reader.close()
class Test1DArrayValidation(TestCase): def set_up_spec(self, dtype): spec_catalog = SpecCatalog() spec = GroupSpec('A test group specification with a data type', data_type_def='Bar', datasets=[ DatasetSpec('an example dataset', dtype, name='data', shape=(None, )) ], attributes=[ AttributeSpec('attr1', 'an example attribute', dtype, shape=(None, )) ]) spec_catalog.register_spec(spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], version='0.1.0', catalog=spec_catalog) self.vmap = ValidatorMap(self.namespace) def test_scalar(self): """Test that validator does not allow a scalar where an array is specified.""" self.set_up_spec('text') value = 'a string' bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) result_strings = set([str(s) for s in results]) expected_errors = { ("Bar/attr1 (my_bar.attr1): incorrect shape - expected an array of shape '(None,)', " "got non-array data 'a string'"), ("Bar/data (my_bar/data): incorrect shape - expected an array of shape '(None,)', " "got non-array data 'a string'") } self.assertEqual(result_strings, expected_errors) def test_empty_list(self): """Test that validator allows an empty list where an array is specified.""" self.set_up_spec('text') value = [] bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) self.assertEqual(len(results), 0) def test_empty_nparray(self): """Test that validator allows an empty numpy array where an array is specified.""" self.set_up_spec('text') value = np.array([]) # note: dtype is float64 bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) self.assertEqual(len(results), 0)
class TestDtypeValidation(TestCase): def set_up_spec(self, dtype): spec_catalog = SpecCatalog() spec = GroupSpec( 'A test group specification with a data type', data_type_def='Bar', datasets=[DatasetSpec('an example dataset', dtype, name='data')], attributes=[AttributeSpec('attr1', 'an example attribute', dtype)]) spec_catalog.register_spec(spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], version='0.1.0', catalog=spec_catalog) self.vmap = ValidatorMap(self.namespace) def test_ascii_for_utf8(self): """Test that validator allows ASCII data where UTF8 is specified.""" self.set_up_spec('text') value = b'an ascii string' bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) self.assertEqual(len(results), 0) def test_utf8_for_ascii(self): """Test that validator does not allow UTF8 where ASCII is specified.""" self.set_up_spec('bytes') value = 'a utf8 string' bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) result_strings = set([str(s) for s in results]) expected_errors = { "Bar/attr1 (my_bar.attr1): incorrect type - expected 'bytes', got 'utf'", "Bar/data (my_bar/data): incorrect type - expected 'bytes', got 'utf'" } self.assertEqual(result_strings, expected_errors) def test_int64_for_int8(self): """Test that validator allows int64 data where int8 is specified.""" self.set_up_spec('int8') value = np.int64(1) bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) self.assertEqual(len(results), 0) def test_int8_for_int64(self): """Test that validator does not allow int8 data where int64 is specified.""" self.set_up_spec('int64') value = np.int8(1) bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) result_strings = set([str(s) for s in results]) expected_errors = { "Bar/attr1 (my_bar.attr1): incorrect type - expected 'int64', got 'int8'", "Bar/data (my_bar/data): incorrect type - expected 'int64', got 'int8'" } self.assertEqual(result_strings, expected_errors) def test_int64_for_numeric(self): """Test that validator allows int64 data where numeric is specified.""" self.set_up_spec('numeric') value = np.int64(1) bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) self.assertEqual(len(results), 0) def test_bool_for_numeric(self): """Test that validator does not allow bool data where numeric is specified.""" self.set_up_spec('numeric') value = np.bool(1) bar_builder = GroupBuilder('my_bar', attributes={ 'data_type': 'Bar', 'attr1': value }, datasets=[DatasetBuilder('data', value)]) results = self.vmap.validate(bar_builder) result_strings = set([str(s) for s in results]) expected_errors = { "Bar/attr1 (my_bar.attr1): incorrect type - expected 'numeric', got 'bool'", "Bar/data (my_bar/data): incorrect type - expected 'numeric', got 'bool'" } self.assertEqual(result_strings, expected_errors)
def validate(**kwargs): """Validate an NWB file against a namespace""" io, namespace = getargs('io', 'namespace', kwargs) builder = io.read_builder() validator = ValidatorMap(__NS_CATALOG.get_namespace(namespace)) return validator.validate(builder)