Пример #1
0
class TestObjectMapperBadValue(TestCase):
    def test_bad_value(self):
        """Test that an error is raised if the container attribute value for a spec with a data type is not a container
        or collection of containers.
        """
        class Qux(Container):
            @docval(
                {
                    'name': 'name',
                    'type': str,
                    'doc': 'the name of this Qux'
                }, {
                    'name': 'foo',
                    'type': int,
                    'doc': 'a group'
                })
            def __init__(self, **kwargs):
                name, foo = getargs('name', 'foo', kwargs)
                super().__init__(name=name)
                self.__foo = foo
                if isinstance(foo, Foo):
                    self.__foo.parent = self

            @property
            def foo(self):
                return self.__foo

        self.qux_spec = GroupSpec(
            doc='A test group specification with data type Qux',
            data_type_def='Qux',
            groups=[GroupSpec('an example dataset', data_type_inc='Foo')])
        self.foo_spec = GroupSpec(
            'A test group specification with data type Foo',
            data_type_def='Foo')
        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.qux_spec, 'test.yaml')
        self.spec_catalog.register_spec(self.foo_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       version='0.1.0',
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Qux', Qux)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Foo', Foo)
        self.manager = BuildManager(self.type_map)
        self.mapper = ObjectMapper(self.qux_spec)

        container = Qux('my_qux', foo=1)
        msg = "Qux 'my_qux' attribute 'foo' has unexpected type."
        with self.assertRaisesWith(ContainerConfigurationError, msg):
            self.mapper.build(container, self.manager)
Пример #2
0
class TestDataMap(unittest.TestCase):
    def setUp(self):
        self.setUpBazSpec()
        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.baz_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Baz', Baz)
        self.type_map.register_map(Baz, ObjectMapper)
        self.manager = BuildManager(self.type_map)
        self.mapper = ObjectMapper(self.baz_spec)

    def setUpBazSpec(self):
        self.baz_spec = DatasetSpec(
            'an Baz type',
            'int',
            name='MyBaz',
            data_type_def='Baz',
            attributes=[
                AttributeSpec('baz_attr', 'an example string attribute',
                              'text')
            ])

    def test_build(self):
        ''' Test default mapping functionality when no attributes are nested '''
        container = Baz('my_baz', list(range(10)),
                        'abcdefghijklmnopqrstuvwxyz')
        builder = self.mapper.build(container, self.manager)
        expected = DatasetBuilder(
            'my_baz',
            list(range(10)),
            attributes={'baz_attr': 'abcdefghijklmnopqrstuvwxyz'})
        self.assertDictEqual(builder, expected)
Пример #3
0
class TestDataMap(BazSpecMixin, TestCase):
    def setUp(self):
        self.setUpBazSpec()
        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.baz_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       version='0.1.0',
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Baz', Baz)
        self.type_map.register_map(Baz, ObjectMapper)
        self.manager = BuildManager(self.type_map)
        self.mapper = ObjectMapper(self.baz_spec)

    def setUpBazSpec(self):
        self.baz_spec = DatasetSpec(
            doc='an Baz type',
            dtype='int',
            name='MyBaz',
            data_type_def='Baz',
            shape=[None],
            attributes=[
                AttributeSpec('baz_attr', 'an example string attribute',
                              'text')
            ])

    def test_build(self):
        ''' Test default mapping functionality when no attributes are nested '''
        container = Baz('MyBaz', list(range(10)), 'abcdefghijklmnopqrstuvwxyz')
        builder = self.mapper.build(container, self.manager)
        expected = DatasetBuilder(
            'MyBaz',
            list(range(10)),
            attributes={'baz_attr': 'abcdefghijklmnopqrstuvwxyz'})
        self.assertBuilderEqual(builder, expected)

    def test_build_empty_data(self):
        """Test building of a Data object with empty data."""
        baz_inc_spec = DatasetSpec(doc='doc',
                                   data_type_inc='Baz',
                                   quantity=ZERO_OR_MANY)
        baz_holder_spec = GroupSpec(doc='doc',
                                    data_type_def='BazHolder',
                                    datasets=[baz_inc_spec])
        self.spec_catalog.register_spec(baz_holder_spec, 'test.yaml')
        self.type_map.register_container_type(CORE_NAMESPACE, 'BazHolder',
                                              BazHolder)
        self.holder_mapper = ObjectMapper(baz_holder_spec)

        baz = Baz('MyBaz', [], 'abcdefghijklmnopqrstuvwxyz')
        holder = BazHolder('holder', [baz])

        builder = self.holder_mapper.build(holder, self.manager)
        expected = GroupBuilder(
            name='holder',
            datasets=[
                DatasetBuilder(name='MyBaz',
                               data=[],
                               attributes={
                                   'baz_attr': 'abcdefghijklmnopqrstuvwxyz',
                                   'data_type': 'Baz',
                                   'namespace': 'test_core',
                                   'object_id': baz.object_id
                               })
            ])
        self.assertBuilderEqual(builder, expected)

    def test_append(self):
        with h5py.File('test.h5', 'w') as file:
            test_ds = file.create_dataset('test_ds',
                                          data=[1, 2, 3],
                                          chunks=True,
                                          maxshape=(None, ))
            container = Baz('MyBaz', test_ds, 'abcdefghijklmnopqrstuvwxyz')
            container.append(4)
            np.testing.assert_array_equal(container[:], [1, 2, 3, 4])
        os.remove('test.h5')

    def test_extend(self):
        with h5py.File('test.h5', 'w') as file:
            test_ds = file.create_dataset('test_ds',
                                          data=[1, 2, 3],
                                          chunks=True,
                                          maxshape=(None, ))
            container = Baz('MyBaz', test_ds, 'abcdefghijklmnopqrstuvwxyz')
            container.extend([4, 5])
            np.testing.assert_array_equal(container[:], [1, 2, 3, 4, 5])
        os.remove('test.h5')
Пример #4
0
class TestReference(TestCase):
    def setUp(self):
        self.foo_spec = GroupSpec(
            'A test group specification with data type Foo',
            data_type_def='Foo')
        self.bar_spec = GroupSpec(
            'A test group specification with a data type Bar',
            data_type_def='Bar',
            datasets=[DatasetSpec('an example dataset', 'int', name='data')],
            attributes=[
                AttributeSpec('attr1', 'an example string attribute', 'text'),
                AttributeSpec('attr2', 'an example integer attribute', 'int'),
                AttributeSpec('foo',
                              'a referenced foo',
                              RefSpec('Foo', 'object'),
                              required=False)
            ])

        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.foo_spec, 'test.yaml')
        self.spec_catalog.register_spec(self.bar_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       version='0.1.0',
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Foo', Foo)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar)
        self.manager = BuildManager(self.type_map)
        self.foo_mapper = ObjectMapper(self.foo_spec)
        self.bar_mapper = ObjectMapper(self.bar_spec)

    def test_build_attr_ref(self):
        ''' Test default mapping functionality when one container contains an attribute reference to another container.
        '''
        foo_inst = Foo('my_foo')
        bar_inst1 = Bar('my_bar1', list(range(10)), 'value1', 10, foo=foo_inst)
        bar_inst2 = Bar('my_bar2', list(range(10)), 'value1', 10)

        foo_builder = self.manager.build(foo_inst, root=True)
        bar1_builder = self.manager.build(bar_inst1, root=True)  # adds refs
        bar2_builder = self.manager.build(bar_inst2, root=True)

        foo_expected = GroupBuilder('my_foo',
                                    attributes={
                                        'data_type': 'Foo',
                                        'namespace': CORE_NAMESPACE,
                                        'object_id': foo_inst.object_id
                                    })
        bar1_expected = GroupBuilder(
            'n/a',  # name doesn't matter
            datasets={'data': DatasetBuilder('data', list(range(10)))},
            attributes={
                'attr1': 'value1',
                'attr2': 10,
                'foo': ReferenceBuilder(foo_expected),
                'data_type': 'Bar',
                'namespace': CORE_NAMESPACE,
                'object_id': bar_inst1.object_id
            })
        bar2_expected = GroupBuilder(
            'n/a',  # name doesn't matter
            datasets={'data': DatasetBuilder('data', list(range(10)))},
            attributes={
                'attr1': 'value1',
                'attr2': 10,
                'data_type': 'Bar',
                'namespace': CORE_NAMESPACE,
                'object_id': bar_inst2.object_id
            })
        self.assertDictEqual(foo_builder, foo_expected)
        self.assertDictEqual(bar1_builder, bar1_expected)
        self.assertDictEqual(bar2_builder, bar2_expected)

    def test_build_attr_ref_invalid(self):
        ''' Test default mapping functionality when one container contains an attribute reference to another container.
        '''
        bar_inst1 = Bar('my_bar1', list(range(10)), 'value1', 10)
        bar_inst1._Bar__foo = object()  # make foo object a non-container type

        msg = "invalid type for reference 'foo' (<class 'object'>) - must be AbstractContainer"
        with self.assertRaisesWith(ValueError, msg):
            self.bar_mapper.build(bar_inst1, self.manager)
Пример #5
0
class TestLinkedContainer(TestCase):
    def setUp(self):
        self.foo_spec = GroupSpec(
            'A test group specification with data type Foo',
            data_type_def='Foo')
        self.bar_spec = GroupSpec(
            'A test group specification with a data type Bar',
            data_type_def='Bar',
            groups=[self.foo_spec],
            datasets=[DatasetSpec('an example dataset', 'int', name='data')],
            attributes=[
                AttributeSpec('attr1', 'an example string attribute', 'text'),
                AttributeSpec('attr2', 'an example integer attribute', 'int')
            ])

        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.foo_spec, 'test.yaml')
        self.spec_catalog.register_spec(self.bar_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       version='0.1.0',
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Foo', Foo)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar)
        self.manager = BuildManager(self.type_map)
        self.foo_mapper = ObjectMapper(self.foo_spec)
        self.bar_mapper = ObjectMapper(self.bar_spec)

    def test_build_child_link(self):
        ''' Test default mapping functionality when one container contains a child link to another container '''
        foo_inst = Foo('my_foo')
        bar_inst1 = Bar('my_bar1', list(range(10)), 'value1', 10, foo=foo_inst)
        # bar_inst2.foo should link to bar_inst1.foo
        bar_inst2 = Bar('my_bar2', list(range(10)), 'value1', 10, foo=foo_inst)

        foo_builder = self.foo_mapper.build(foo_inst, self.manager)
        bar1_builder = self.bar_mapper.build(bar_inst1, self.manager)
        bar2_builder = self.bar_mapper.build(bar_inst2, self.manager)

        foo_expected = GroupBuilder('my_foo')

        inner_foo_builder = GroupBuilder('my_foo',
                                         attributes={
                                             'data_type': 'Foo',
                                             'namespace': CORE_NAMESPACE,
                                             'object_id': foo_inst.object_id
                                         })
        bar1_expected = GroupBuilder(
            'my_bar1',
            datasets={'data': DatasetBuilder('data', list(range(10)))},
            groups={'foo': inner_foo_builder},
            attributes={
                'attr1': 'value1',
                'attr2': 10
            })
        link_foo_builder = LinkBuilder(builder=inner_foo_builder)
        bar2_expected = GroupBuilder(
            'my_bar2',
            datasets={'data': DatasetBuilder('data', list(range(10)))},
            links={'foo': link_foo_builder},
            attributes={
                'attr1': 'value1',
                'attr2': 10
            })
        self.assertBuilderEqual(foo_builder, foo_expected)
        self.assertBuilderEqual(bar1_builder, bar1_expected)
        self.assertBuilderEqual(bar2_builder, bar2_expected)

    @unittest.expectedFailure
    def test_build_broken_link_parent(self):
        ''' Test that building a container with a broken link that has a parent raises an error. '''
        foo_inst = Foo('my_foo')
        Bar('my_bar1', list(range(10)), 'value1', 10,
            foo=foo_inst)  # foo_inst.parent is this bar
        # bar_inst2.foo should link to bar_inst1.foo
        bar_inst2 = Bar('my_bar2', list(range(10)), 'value1', 10, foo=foo_inst)

        # TODO bar_inst.foo.parent exists but is never built - this is a tricky edge case that should raise an error
        with self.assertRaises(OrphanContainerBuildError):
            self.bar_mapper.build(bar_inst2, self.manager)

    def test_build_broken_link_no_parent(self):
        ''' Test that building a container with a broken link that has no parent raises an error. '''
        foo_inst = Foo('my_foo')
        bar_inst1 = Bar('my_bar1', list(range(10)), 'value1', 10,
                        foo=foo_inst)  # foo_inst.parent is this bar
        # bar_inst2.foo should link to bar_inst1.foo
        bar_inst2 = Bar('my_bar2', list(range(10)), 'value1', 10, foo=foo_inst)
        bar_inst1.remove_foo()

        msg = (
            "my_bar2 (my_bar2): Linked Foo 'my_foo' has no parent. Remove the link or ensure the linked container "
            "is added properly.")
        with self.assertRaisesWith(OrphanContainerBuildError, msg):
            self.bar_mapper.build(bar_inst2, self.manager)
Пример #6
0
class TestDataMap(TestCase):
    def setUp(self):
        self.setUpBazSpec()
        self.spec_catalog = SpecCatalog()
        self.spec_catalog.register_spec(self.baz_spec, 'test.yaml')
        self.namespace = SpecNamespace('a test namespace',
                                       CORE_NAMESPACE, [{
                                           'source': 'test.yaml'
                                       }],
                                       version='0.1.0',
                                       catalog=self.spec_catalog)
        self.namespace_catalog = NamespaceCatalog()
        self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace)
        self.type_map = TypeMap(self.namespace_catalog)
        self.type_map.register_container_type(CORE_NAMESPACE, 'Baz', Baz)
        self.type_map.register_map(Baz, ObjectMapper)
        self.manager = BuildManager(self.type_map)
        self.mapper = ObjectMapper(self.baz_spec)

    def setUpBazSpec(self):
        self.baz_spec = DatasetSpec(
            'an Baz type',
            'int',
            name='MyBaz',
            data_type_def='Baz',
            shape=[None],
            attributes=[
                AttributeSpec('baz_attr', 'an example string attribute',
                              'text')
            ])

    def test_build(self):
        ''' Test default mapping functionality when no attributes are nested '''
        container = Baz('my_baz', list(range(10)),
                        'abcdefghijklmnopqrstuvwxyz')
        builder = self.mapper.build(container, self.manager)
        expected = DatasetBuilder(
            'my_baz',
            list(range(10)),
            attributes={'baz_attr': 'abcdefghijklmnopqrstuvwxyz'})
        self.assertDictEqual(builder, expected)

    def test_append(self):
        with h5py.File('test.h5', 'w') as file:
            test_ds = file.create_dataset('test_ds',
                                          data=[1, 2, 3],
                                          chunks=True,
                                          maxshape=(None, ))
            container = Baz('my_baz', test_ds, 'abcdefghijklmnopqrstuvwxyz')
            container.append(4)
            np.testing.assert_array_equal(container[:], [1, 2, 3, 4])
        os.remove('test.h5')

    def test_extend(self):
        with h5py.File('test.h5', 'w') as file:
            test_ds = file.create_dataset('test_ds',
                                          data=[1, 2, 3],
                                          chunks=True,
                                          maxshape=(None, ))
            container = Baz('my_baz', test_ds, 'abcdefghijklmnopqrstuvwxyz')
            container.extend([4, 5])
            np.testing.assert_array_equal(container[:], [1, 2, 3, 4, 5])
        os.remove('test.h5')