예제 #1
0
def _make_namespace_with_nested_types():
    # type: (...) -> ApiNamespace
    ns = ApiNamespace('ns_w_nested_types')

    struct = Struct(name='NestedTypes', namespace=ns, ast_node=None)
    struct.set_attributes(
        doc=None,
        fields=[
            StructField(
                name='NullableList',
                data_type=Nullable(
                    List(UInt64())
                ),
                doc=None,
                ast_node=None,
            ),
            StructField(
                name='ListOfNullables',
                data_type=List(
                    Nullable(UInt64())
                ),
                doc=None,
                ast_node=None,
            )
        ]
    )
    ns.add_data_type(struct)

    return ns
    def test_strip_alias(self):
        first_alias = Alias(None, None, None)
        second_alias = Alias(None, None, None)
        third_alias = Alias(None, None, None)
        first_alias.data_type = second_alias
        second_alias.data_type = third_alias
        third_alias.data_type = String()

        test_struct = Struct('TestStruct', None, None)
        test_struct.set_attributes(
            None,
            [StructField('field1', List(Nullable(first_alias)), None, None)])

        curr_type = first_alias
        while hasattr(curr_type, 'data_type'):
            curr_type.data_type = resolve_aliases(curr_type.data_type)
            curr_type = curr_type.data_type

        self.assertIsInstance(first_alias.data_type, String)

        self.assertEqual(len(test_struct.fields), 1)
        field = test_struct.fields[0]

        strip_alias(field.data_type)

        list_type = field.data_type
        self.assertIsInstance(list_type, List)
        nullable_type = list_type.data_type
        self.assertIsInstance(nullable_type, Nullable)
        string_type = nullable_type.data_type
        self.assertIsInstance(string_type, String)
예제 #3
0
def _make_namespace_with_nullable_and_dafault_fields():
    # type: (...) -> ApiNamespace
    ns = ApiNamespace('ns_w_nullable__fields')

    struct = Struct(name='Struct1', namespace=ns, ast_node=None)
    default_field = StructField(
        name='DefaultField',
        data_type=UInt64(),
        doc=None,
        ast_node=None,
    )
    default_field.set_default(1)
    struct.set_attributes(doc=None,
                          fields=[
                              StructField(
                                  name='NullableField',
                                  data_type=Nullable(UInt64()),
                                  doc=None,
                                  ast_node=None,
                              ), default_field,
                              StructField(
                                  name='RequiredField',
                                  data_type=UInt64(),
                                  doc=None,
                                  ast_node=None,
                              )
                          ])
    ns.add_data_type(struct)

    return ns
예제 #4
0
    def __init__(self, rust_generator: TestBackend, stone_type: ir.Struct, reference_impls, no_optional_fields=False):
        super(TestStruct, self).__init__(rust_generator)

        if stone_type.has_enumerated_subtypes():
            stone_type = stone_type.get_enumerated_subtypes()[0].data_type

        self._stone_type = stone_type
        self._reference_impls = reference_impls
        self._no_optional_fields = no_optional_fields

        py_name = fmt_py_class(stone_type.name)
        try:
            self.value = reference_impls[stone_type.namespace.name].__dict__[py_name]()
        except Exception as e:
            raise RuntimeError(u'Error instantiating value for {}: {}'.format(stone_type.name, e))

        for field in (stone_type.all_required_fields if no_optional_fields else stone_type.all_fields):
            field_value = make_test_field(
                    field.name, field.data_type, rust_generator, reference_impls)
            if field_value is None:
                raise RuntimeError(u'Error: incomplete type generated: {}'.format(stone_type.name))
            self.fields.append(field_value)
            try:
                setattr(self.value, field.name, field_value.value)
            except Exception as e:
                raise RuntimeError(u'Error generating value for {}.{}: {}'
                                   .format(stone_type.name, field.name, e))
예제 #5
0
    def test_strip_alias(self):
        first_alias = Alias(None, None, None)
        second_alias = Alias(None, None, None)
        third_alias = Alias(None, None, None)
        first_alias.data_type = second_alias
        second_alias.data_type = third_alias
        third_alias.data_type = String()

        test_struct = Struct('TestStruct', None, None)
        test_struct.set_attributes(None, [
            StructField('field1', List(Nullable(first_alias)), None, None)
        ])

        curr_type = first_alias
        while hasattr(curr_type, 'data_type'):
            curr_type.data_type = resolve_aliases(curr_type.data_type)
            curr_type = curr_type.data_type

        self.assertIsInstance(first_alias.data_type, String)

        self.assertEqual(len(test_struct.fields), 1)
        field = test_struct.fields[0]

        strip_alias(field.data_type)

        list_type = field.data_type
        self.assertIsInstance(list_type, List)
        nullable_type = list_type.data_type
        self.assertIsInstance(nullable_type, Nullable)
        string_type = nullable_type.data_type
        self.assertIsInstance(string_type, String)
예제 #6
0
    def test_struct_with_custom_annotations(self):
        # type: () -> None
        ns = ApiNamespace('files')
        annotation_type = AnnotationType('MyAnnotationType', ns, None, [
            AnnotationTypeParam('test_param', Int32(), None, False, None, None)
        ])
        ns.add_annotation_type(annotation_type)
        annotation = CustomAnnotation('MyAnnotation', ns, None,
                                      'MyAnnotationType', None, [],
                                      {'test_param': 42})
        annotation.set_attributes(annotation_type)
        ns.add_annotation(annotation)
        struct = Struct('MyStruct', ns, None)
        struct.set_attributes(None, [
            StructField('annotated_field', Int32(), None, None),
            StructField('unannotated_field', Int32(), None, None),
        ])
        struct.fields[0].set_annotations([annotation])
        struct.recursive_custom_annotations = set([annotation])

        result = self._evaluate_struct(ns, struct)

        expected = textwrap.dedent('''\
            class MyStruct(bb.Struct):

                __slots__ = [
                    '_annotated_field_value',
                    '_unannotated_field_value',
                ]

                _has_required_fields = True

                def __init__(self,
                             annotated_field=None,
                             unannotated_field=None):
                    self._annotated_field_value = bb.NOT_SET
                    self._unannotated_field_value = bb.NOT_SET
                    if annotated_field is not None:
                        self.annotated_field = annotated_field
                    if unannotated_field is not None:
                        self.unannotated_field = unannotated_field

                # Instance attribute type: int (validator is set below)
                annotated_field = bb.Attribute("annotated_field")

                # Instance attribute type: int (validator is set below)
                unannotated_field = bb.Attribute("unannotated_field")

                def _process_custom_annotations(self, annotation_type, field_path, processor):
                    super(MyStruct, self)._process_custom_annotations(annotation_type, field_path, processor)

                    if annotation_type is MyAnnotationType:
                        self.annotated_field = bb.partially_apply(processor, MyAnnotationType(test_param=42))('{}.annotated_field'.format(field_path), self.annotated_field)

            MyStruct_validator = bv.Struct(MyStruct)

        ''')  # noqa
        self.maxDiff = None
        self.assertEqual(result, expected)
예제 #7
0
def _make_namespace_with_alias():
    # type: (...) -> ApiNamespace
    ns = ApiNamespace('ns_with_alias')

    struct1 = Struct(name='Struct1', namespace=ns, ast_node=None)
    struct1.set_attributes(None, [StructField('f1', Boolean(), None, None)])
    ns.add_data_type(struct1)

    alias = Alias(name='AliasToStruct1', namespace=ns, ast_node=None)
    alias.set_attributes(doc=None, data_type=struct1)
    ns.add_alias(alias)

    return ns
예제 #8
0
    def test_api_namespace(self):
        ns = ApiNamespace('files')
        a1 = Struct('A1', None, ns)
        a1.set_attributes(None, [StructField('f1', Boolean(), None, None)])
        a2 = Struct('A2', None, ns)
        a2.set_attributes(None, [StructField('f2', Boolean(), None, None)])
        l1 = List(a1)
        s = String()
        route = ApiRoute('test/route', 1, None)
        route.set_attributes(None, None, l1, a2, s, None)
        ns.add_route(route)

        # Test that only user-defined types are returned.
        route_io = ns.get_route_io_data_types()
        self.assertIn(a1, route_io)
        self.assertIn(a2, route_io)
        self.assertNotIn(l1, route_io)
        self.assertNotIn(s, route_io)
예제 #9
0
def _make_namespace_with_many_structs():
    # type: (...) -> ApiNamespace
    ns = ApiNamespace('ns_with_many_structs')

    struct1 = Struct(name='Struct1', namespace=ns, ast_node=None)
    struct1.set_attributes(None, [StructField('f1', Boolean(), None, None)])
    ns.add_data_type(struct1)

    struct2 = Struct(name='Struct2', namespace=ns, ast_node=None)
    struct2.set_attributes(
        doc=None,
        fields=[
            StructField('f2', List(UInt64()), None, None),
            StructField('f3', Timestamp(ISO_8601_FORMAT), None, None),
            StructField('f4', Map(String(), UInt64()), None, None)
        ]
    )
    ns.add_data_type(struct2)

    return ns
예제 #10
0
    def test_api_namespace(self):
        ns = ApiNamespace('files')
        a1 = Struct('A1', None, ns)
        a1.set_attributes(None, [StructField('f1', Boolean(), None, None)])
        a2 = Struct('A2', None, ns)
        a2.set_attributes(None, [StructField('f2', Boolean(), None, None)])
        l1 = List(a1)
        s = String()
        route = ApiRoute('test/route', 1, None)
        route.set_attributes(None, None, l1, a2, s, None)
        ns.add_route(route)

        # Test that only user-defined types are returned.
        route_io = ns.get_route_io_data_types()
        self.assertIn(a1, route_io)
        self.assertIn(a2, route_io)
        self.assertNotIn(l1, route_io)
        self.assertNotIn(s, route_io)
예제 #11
0
    def test_struct_with_custom_annotations(self):
        # type: () -> None
        ns = ApiNamespace('files')
        annotation_type = AnnotationType('MyAnnotationType', ns, None, [
            AnnotationTypeParam('test_param', Int32(), None, False, None, None)
        ])
        ns.add_annotation_type(annotation_type)
        annotation = CustomAnnotation('MyAnnotation', ns, None, 'MyAnnotationType',
            None, [], {'test_param': 42})
        annotation.set_attributes(annotation_type)
        ns.add_annotation(annotation)
        struct = Struct('MyStruct', ns, None)
        struct.set_attributes(None, [
            StructField('annotated_field', Int32(), None, None),
            StructField('unannotated_field', Int32(), None, None),
        ])
        struct.fields[0].set_annotations([annotation])

        result = self._evaluate_struct(ns, struct)

        expected = textwrap.dedent('''\
            class MyStruct(bb.Struct):

                __slots__ = [
                    '_annotated_field_value',
                    '_annotated_field_present',
                    '_unannotated_field_value',
                    '_unannotated_field_present',
                ]

                _has_required_fields = True

                def __init__(self,
                             annotated_field=None,
                             unannotated_field=None):
                    self._annotated_field_value = None
                    self._annotated_field_present = False
                    self._unannotated_field_value = None
                    self._unannotated_field_present = False
                    if annotated_field is not None:
                        self.annotated_field = annotated_field
                    if unannotated_field is not None:
                        self.unannotated_field = unannotated_field

                @property
                def annotated_field(self):
                    """
                    :rtype: int
                    """
                    if self._annotated_field_present:
                        return self._annotated_field_value
                    else:
                        raise AttributeError("missing required field 'annotated_field'")

                @annotated_field.setter
                def annotated_field(self, val):
                    val = self._annotated_field_validator.validate(val)
                    self._annotated_field_value = val
                    self._annotated_field_present = True

                @annotated_field.deleter
                def annotated_field(self):
                    self._annotated_field_value = None
                    self._annotated_field_present = False

                @property
                def unannotated_field(self):
                    """
                    :rtype: int
                    """
                    if self._unannotated_field_present:
                        return self._unannotated_field_value
                    else:
                        raise AttributeError("missing required field 'unannotated_field'")

                @unannotated_field.setter
                def unannotated_field(self, val):
                    val = self._unannotated_field_validator.validate(val)
                    self._unannotated_field_value = val
                    self._unannotated_field_present = True

                @unannotated_field.deleter
                def unannotated_field(self):
                    self._unannotated_field_value = None
                    self._unannotated_field_present = False

                def _process_custom_annotations(self, annotation_type, field_path, processor):
                    super(MyStruct, self)._process_custom_annotations(annotation_type, field_path, processor)

                    if annotation_type is MyAnnotationType:
                        self.annotated_field = bb.partially_apply(processor, MyAnnotationType(test_param=42))('{}.annotated_field'.format(field_path), self.annotated_field)

                def __repr__(self):
                    return 'MyStruct(annotated_field={!r}, unannotated_field={!r})'.format(
                        self._annotated_field_value,
                        self._unannotated_field_value,
                    )

            MyStruct_validator = bv.Struct(MyStruct)

        ''') # noqa
        self.maxDiff = None
        self.assertEqual(result, expected)
예제 #12
0
 def _mk_route_schema(self):
     s = Struct('Route', ApiNamespace('stone_cfg'), None)
     s.set_attributes(None, [], None)
     return s
예제 #13
0
    def test_struct_with_custom_annotations(self):
        # type: () -> None
        ns = ApiNamespace('files')
        annotation_type = AnnotationType('MyAnnotationType', ns, None, [
            AnnotationTypeParam('test_param', Int32(), None, False, None, None)
        ])
        ns.add_annotation_type(annotation_type)
        annotation = CustomAnnotation('MyAnnotation', ns, None,
                                      'MyAnnotationType', None, [],
                                      {'test_param': 42})
        annotation.set_attributes(annotation_type)
        ns.add_annotation(annotation)
        struct = Struct('MyStruct', ns, None)
        struct.set_attributes(None, [
            StructField('annotated_field', Int32(), None, None),
            StructField('unannotated_field', Int32(), None, None),
        ])
        struct.fields[0].set_annotations([annotation])

        result = self._evaluate_struct(ns, struct)

        expected = textwrap.dedent('''\
            class MyStruct(bb.Struct):

                __slots__ = [
                    '_annotated_field_value',
                    '_annotated_field_present',
                    '_unannotated_field_value',
                    '_unannotated_field_present',
                ]

                _has_required_fields = True

                def __init__(self,
                             annotated_field=None,
                             unannotated_field=None):
                    self._annotated_field_value = None
                    self._annotated_field_present = False
                    self._unannotated_field_value = None
                    self._unannotated_field_present = False
                    if annotated_field is not None:
                        self.annotated_field = annotated_field
                    if unannotated_field is not None:
                        self.unannotated_field = unannotated_field

                @property
                def annotated_field(self):
                    """
                    :rtype: long
                    """
                    if self._annotated_field_present:
                        return self._annotated_field_value
                    else:
                        raise AttributeError("missing required field 'annotated_field'")

                @annotated_field.setter
                def annotated_field(self, val):
                    val = self._annotated_field_validator.validate(val)
                    self._annotated_field_value = val
                    self._annotated_field_present = True

                @annotated_field.deleter
                def annotated_field(self):
                    self._annotated_field_value = None
                    self._annotated_field_present = False

                @property
                def unannotated_field(self):
                    """
                    :rtype: long
                    """
                    if self._unannotated_field_present:
                        return self._unannotated_field_value
                    else:
                        raise AttributeError("missing required field 'unannotated_field'")

                @unannotated_field.setter
                def unannotated_field(self, val):
                    val = self._unannotated_field_validator.validate(val)
                    self._unannotated_field_value = val
                    self._unannotated_field_present = True

                @unannotated_field.deleter
                def unannotated_field(self):
                    self._unannotated_field_value = None
                    self._unannotated_field_present = False

                def _process_custom_annotations(self, annotation_type, processor):
                    super(MyStruct, self)._process_custom_annotations(annotation_type, processor)

                    if annotation_type is MyAnnotationType:
                        self.annotated_field = bb.partially_apply(processor, MyAnnotationType(test_param=42))(self.annotated_field)

                def __repr__(self):
                    return 'MyStruct(annotated_field={!r}, unannotated_field={!r})'.format(
                        self._annotated_field_value,
                        self._unannotated_field_value,
                    )

            MyStruct_validator = bv.Struct(MyStruct)

        ''')  # noqa

        self.assertEqual(result, expected)
    def test_preserve_aliases_from_api(self):
        api = Api(version=None)
        # Ensure imports come after 'preserve_alias' lexiographicaly
        # to catch namespace ordering bugs
        api.ensure_namespace('preserve_alias')
        api.ensure_namespace('zzzz')

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        namespace_id = Alias('NamespaceId', ns, None)
        namespace_id.data_type = String()
        shared_folder_id = Alias('SharedFolderId', ns, None)
        shared_folder_id.set_attributes(None, namespace_id)
        path_root_id = Alias('PathRootId', ns, None)
        path_root_id.set_attributes(None, shared_folder_id)
        foo_alias = Alias('FooAlias', None, None)
        foo_alias.set_attributes(None, String())
        bar_alias = Alias('BarAlias', None, None)
        bar_alias.set_attributes(None, foo_alias)

        ns.add_alias(namespace_id)
        ns.add_alias(shared_folder_id)
        ns.add_alias(path_root_id)
        imported.add_alias(foo_alias)
        imported.add_alias(bar_alias)

        test_struct = Struct('TestStruct', ns, None)
        test_struct.set_attributes(
            None, [StructField('field1', path_root_id, None, None)])
        test_union = Union('TestUnion', ns, None, None)
        test_union.set_attributes(
            None, [UnionField('test', path_root_id, None, None)])
        dependent_struct = Struct('DependentStruct', ns, None)
        dependent_struct.set_attributes(None, [
            StructField('field_alias', imported.alias_by_name['BarAlias'],
                        None, None)
        ])

        ns.add_data_type(test_struct)
        ns.add_data_type(test_union)
        ns.add_data_type(dependent_struct)

        struct_alias = Alias('StructAlias', ns, None)
        struct_alias.set_attributes(None, test_struct)

        ns.add_alias(struct_alias)

        # Ensure namespace exists
        self.assertEqual(len(api.namespaces), 2)
        self.assertTrue('preserve_alias' in api.namespaces)
        self.assertTrue('zzzz' in api.namespaces)

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Ensure aliases exist
        self.assertEqual(len(ns.aliases), 4)
        self.assertEqual(len(imported.aliases), 2)

        aliases = {alias._name: alias for alias in ns.aliases}
        imported_aliases = {alias.name: alias for alias in imported.aliases}
        data_types = {
            data_type._name: data_type
            for data_type in ns.data_types
        }

        # Ensure aliases are in the namespace
        self.assertTrue('NamespaceId' in aliases)
        self.assertTrue('SharedFolderId' in aliases)
        self.assertTrue('PathRootId' in aliases)
        self.assertTrue('StructAlias' in aliases)
        self.assertTrue('FooAlias' in imported_aliases)
        self.assertTrue('BarAlias' in imported_aliases)

        # Ensure aliases resolve to proper types
        self.assertIsInstance(aliases['NamespaceId'].data_type, String)
        self.assertIsInstance(aliases['SharedFolderId'].data_type, Alias)
        self.assertIsInstance(aliases['PathRootId'].data_type, Alias)
        self.assertIsInstance(aliases['StructAlias'].data_type, Struct)
        self.assertIsInstance(imported_aliases['FooAlias'].data_type, String)
        self.assertIsInstance(imported_aliases['BarAlias'].data_type, Alias)

        # Ensure struct and union field aliases resolve to proper types
        self.assertIsInstance(data_types['TestStruct'], Struct)

        test_struct = data_types.get('TestStruct')
        dependent_struct = data_types.get('DependentStruct')

        self.assertTrue(len(test_struct.fields), 1)
        self.assertTrue(len(dependent_struct.fields), 1)

        field = test_struct.fields[0]
        self.assertEqual(field.name, 'field1')
        self.assertIsInstance(field.data_type, Alias)

        field = dependent_struct.fields[0]
        self.assertEqual(field.name, 'field_alias')
        self.assertIsInstance(field.data_type, Alias)

        test_union = data_types['TestUnion']

        self.assertTrue(len(test_union.fields), 1)
        field = test_union.fields[0]

        self.assertEqual(field.name, 'test')
        self.assertIsInstance(field.data_type, Alias)
예제 #15
0
def _make_struct(struct_name, struct_field_name, namespace):
    # type: (typing.Text, typing.Text, ApiNamespace) -> Struct
    struct = Struct(name=struct_name, namespace=namespace, ast_node=None)
    struct.set_attributes(None, [StructField(struct_field_name, Boolean(), None, None)])
    return struct
예제 #16
0
    def test_no_preserve_aliases_from_api(self):
        api = Api(version=None)
        # Ensure imports come after 'preserve_alias' lexiographicaly
        # to catch namespace ordering bugs
        api.ensure_namespace('preserve_alias')
        api.ensure_namespace('zzzz')

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Setup aliases
        namespace_id = Alias('NamespaceId', ns, None)
        namespace_id.data_type = String()
        shared_folder_id = Alias('SharedFolderId', ns, None)
        shared_folder_id.set_attributes(None, namespace_id)
        path_root_id = Alias('PathRootId', ns, None)
        path_root_id.set_attributes(None, shared_folder_id)
        nullable_alias = Alias('NullableAlias', ns, None)
        nullable_alias.set_attributes(None, Nullable(path_root_id))
        foo_alias = Alias('FooAlias', None, None)
        foo_alias.set_attributes(None, String())
        bar_alias = Alias('BarAlias', None, None)
        bar_alias.set_attributes(None, foo_alias)

        ns.add_alias(namespace_id)
        ns.add_alias(shared_folder_id)
        ns.add_alias(path_root_id)
        ns.add_alias(nullable_alias)
        imported.add_alias(foo_alias)
        imported.add_alias(bar_alias)

        # Setup composite types
        test_struct = Struct('TestStruct', ns, None)
        test_struct.set_attributes(None, [
            StructField('field_alias', path_root_id, None, None),
            StructField('field_nullable_alias', nullable_alias, None, None),
            StructField('field_list_of_alias', List(path_root_id), None, None)
        ])
        test_union = Union('TestUnion', ns, None, None)
        test_union.set_attributes(None, [UnionField('test', path_root_id, None, None)])
        dependent_struct = Struct('DependentStruct', ns, None)
        dependent_struct.set_attributes(None, [
            StructField('field_alias', imported.alias_by_name['BarAlias'], None, None)
        ])

        ns.add_data_type(test_struct)
        ns.add_data_type(test_union)
        ns.add_data_type(dependent_struct)

        # Setup aliases on composite types
        struct_alias = Alias('StructAlias', ns, None)
        struct_alias.set_attributes(None, test_struct)

        ns.add_alias(struct_alias)

        api = remove_aliases_from_api(api)

        # Ensure namespace exists
        self.assertEqual(len(api.namespaces), 2)
        self.assertTrue('preserve_alias' in api.namespaces)
        self.assertTrue('zzzz' in api.namespaces)

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Ensure aliases are gone
        self.assertEqual(len(ns.aliases), 0)
        self.assertEqual(len(imported.aliases), 0)

        data_types = {
            data_type._name: data_type for data_type in ns.data_types
        }

        # Ensure struct and union field aliases resolve to proper types
        test_struct = data_types.get('TestStruct')
        self.assertIsInstance(test_struct, Struct)

        self.assertEqual(len(test_struct.fields), 3)

        for field in test_struct.fields:
            if field.name == 'field_list_of_alias':
                self.assertIsInstance(field.data_type, List)
                list_type = field.data_type.data_type
                self.assertIsInstance(list_type, String)
            elif field.name == 'field_nullable_alias':
                field_type = field.data_type
                self.assertIsInstance(field_type, Nullable)
                self.assertIsInstance(field_type.data_type, String)
            else:
                self.assertIsInstance(field.data_type, String)

        test_union = data_types['TestUnion']

        self.assertTrue(len(test_union.fields), 1)
        field = test_union.fields[0]

        self.assertEqual(field.name, 'test')
        self.assertIsInstance(field.data_type, String)

        # Ensure struct using imported alias resolves properly
        dependent_struct = data_types.get('DependentStruct')
        self.assertIsInstance(dependent_struct, Struct)

        self.assertEqual(len(dependent_struct.fields), 1)

        field = dependent_struct.fields[0]
        self.assertIsInstance(field.data_type, String)
예제 #17
0
    def test_preserve_aliases_from_api(self):
        api = Api(version=None)
        # Ensure imports come after 'preserve_alias' lexiographicaly
        # to catch namespace ordering bugs
        api.ensure_namespace('preserve_alias')
        api.ensure_namespace('zzzz')

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        namespace_id = Alias('NamespaceId', ns, None)
        namespace_id.data_type = String()
        shared_folder_id = Alias('SharedFolderId', ns, None)
        shared_folder_id.set_attributes(None, namespace_id)
        path_root_id = Alias('PathRootId', ns, None)
        path_root_id.set_attributes(None, shared_folder_id)
        foo_alias = Alias('FooAlias', None, None)
        foo_alias.set_attributes(None, String())
        bar_alias = Alias('BarAlias', None, None)
        bar_alias.set_attributes(None, foo_alias)

        ns.add_alias(namespace_id)
        ns.add_alias(shared_folder_id)
        ns.add_alias(path_root_id)
        imported.add_alias(foo_alias)
        imported.add_alias(bar_alias)

        test_struct = Struct('TestStruct', ns, None)
        test_struct.set_attributes(None, [StructField('field1', path_root_id, None, None)])
        test_union = Union('TestUnion', ns, None, None)
        test_union.set_attributes(None, [UnionField('test', path_root_id, None, None)])
        dependent_struct = Struct('DependentStruct', ns, None)
        dependent_struct.set_attributes(None, [
            StructField('field_alias', imported.alias_by_name['BarAlias'], None, None)
        ])

        ns.add_data_type(test_struct)
        ns.add_data_type(test_union)
        ns.add_data_type(dependent_struct)

        struct_alias = Alias('StructAlias', ns, None)
        struct_alias.set_attributes(None, test_struct)

        ns.add_alias(struct_alias)

        # Ensure namespace exists
        self.assertEqual(len(api.namespaces), 2)
        self.assertTrue('preserve_alias' in api.namespaces)
        self.assertTrue('zzzz' in api.namespaces)

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Ensure aliases exist
        self.assertEqual(len(ns.aliases), 4)
        self.assertEqual(len(imported.aliases), 2)

        aliases = {
            alias._name: alias for alias in ns.aliases
        }
        imported_aliases = {
            alias.name: alias for alias in imported.aliases
        }
        data_types = {
            data_type._name: data_type for data_type in ns.data_types
        }

        # Ensure aliases are in the namespace
        self.assertTrue('NamespaceId' in aliases)
        self.assertTrue('SharedFolderId' in aliases)
        self.assertTrue('PathRootId' in aliases)
        self.assertTrue('StructAlias' in aliases)
        self.assertTrue('FooAlias' in imported_aliases)
        self.assertTrue('BarAlias' in imported_aliases)

        # Ensure aliases resolve to proper types
        self.assertIsInstance(aliases['NamespaceId'].data_type, String)
        self.assertIsInstance(aliases['SharedFolderId'].data_type, Alias)
        self.assertIsInstance(aliases['PathRootId'].data_type, Alias)
        self.assertIsInstance(aliases['StructAlias'].data_type, Struct)
        self.assertIsInstance(imported_aliases['FooAlias'].data_type, String)
        self.assertIsInstance(imported_aliases['BarAlias'].data_type, Alias)

        # Ensure struct and union field aliases resolve to proper types
        self.assertIsInstance(data_types['TestStruct'], Struct)

        test_struct = data_types.get('TestStruct')
        dependent_struct = data_types.get('DependentStruct')

        self.assertTrue(len(test_struct.fields), 1)
        self.assertTrue(len(dependent_struct.fields), 1)

        field = test_struct.fields[0]
        self.assertEqual(field.name, 'field1')
        self.assertIsInstance(field.data_type, Alias)

        field = dependent_struct.fields[0]
        self.assertEqual(field.name, 'field_alias')
        self.assertIsInstance(field.data_type, Alias)

        test_union = data_types['TestUnion']

        self.assertTrue(len(test_union.fields), 1)
        field = test_union.fields[0]

        self.assertEqual(field.name, 'test')
        self.assertIsInstance(field.data_type, Alias)
예제 #18
0
 def _mk_route_schema(self):
     s = Struct('Route', ApiNamespace('stone_cfg'), None)
     s.set_attributes(None, [], None)
     return s
예제 #19
0
def _make_struct(struct_name, struct_field_name, namespace):
    # type: (typing.Text, typing.Text, ApiNamespace) -> Struct
    struct = Struct(name=struct_name, namespace=namespace, ast_node=None)
    struct.set_attributes(
        None, [StructField(struct_field_name, Boolean(), None, None)])
    return struct
예제 #20
0
    def test_check_example(self):

        #
        # Test string
        #

        s = String(min_length=1, max_length=5)
        s.check_example(
            AstExampleField(
                path='test.stone',
                lineno=1,
                lexpos=0,
                name='v',
                value='hello',
            ))

        with self.assertRaises(InvalidSpec) as cm:
            s.check_example(
                AstExampleField(
                    path='test.stone',
                    lineno=1,
                    lexpos=0,
                    name='v',
                    value='',
                ))
        self.assertIn("'' has fewer than 1 character(s)", cm.exception.msg)

        #
        # Test list
        #

        l1 = List(String(min_length=1), min_items=1, max_items=3)

        l1.check_example(
            AstExampleField(
                path='test.stone',
                lineno=1,
                lexpos=0,
                name='v',
                value=['asd'],
            ))

        with self.assertRaises(InvalidSpec) as cm:
            l1.check_example(
                AstExampleField(
                    path='test.stone',
                    lineno=1,
                    lexpos=0,
                    name='v',
                    value=[],
                ))
        self.assertIn("has fewer than 1 item(s)", cm.exception.msg)

        #
        # Test list of lists
        #

        l1 = List(List(String(min_length=1), min_items=1))

        l1.check_example(
            AstExampleField(
                path='test.stone',
                lineno=1,
                lexpos=0,
                name='v',
                value=[['asd']],
            ))

        with self.assertRaises(InvalidSpec) as cm:
            l1.check_example(
                AstExampleField(
                    path='test.stone',
                    lineno=1,
                    lexpos=0,
                    name='v',
                    value=[[]],
                ))
        self.assertIn("has fewer than 1 item(s)", cm.exception.msg)

        #
        # Test Map type
        #

        m = Map(String(), String())
        # valid example
        m.check_example(
            AstExampleField(path='test.stone',
                            lineno=1,
                            lexpos=0,
                            name='v',
                            value={"foo": "bar"}))

        # does not conform to declared type
        with self.assertRaises(InvalidSpec):
            m.check_example(
                AstExampleField(path='test.stone',
                                lineno=1,
                                lexpos=0,
                                name='v',
                                value={1: "bar"}))

        with self.assertRaises(ParameterError):
            # errors because only string types can be used as keys
            Map(Int32(), String())

        s = Struct('S', None, None)
        s.set_attributes(
            "Docstring",
            [
                StructField('a', UInt64(), 'a field', None),
                StructField('b', List(String()), 'a field', None),
            ],
        )

        s._add_example(
            AstExample('test.stone',
                       lineno=1,
                       lexpos=0,
                       label='default',
                       text='Default example',
                       fields={
                           'a':
                           AstExampleField(
                               path='test.stone',
                               lineno=2,
                               lexpos=0,
                               name='a',
                               value=132,
                           ),
                           'b':
                           AstExampleField(
                               path='test.stone',
                               lineno=2,
                               lexpos=0,
                               name='b',
                               value=['a'],
                           ),
                       }))
예제 #21
0
    def test_struct(self):

        ns = ApiNamespace('test')

        quota_info = Struct(
            'QuotaInfo',
            None,
            ns,
        )
        quota_info.set_attributes(
            "Information about a user's space quota.",
            [
                StructField('quota', UInt64(), 'Total amount of space.', None),
            ],
        )

        # add an example that doesn't fit the definition of a struct
        with self.assertRaises(InvalidSpec) as cm:
            quota_info._add_example(
                AstExample(
                    path=None,
                    lineno=None,
                    lexpos=None,
                    label='default',
                    text=None,
                    fields={
                        'bad_field': AstExampleField(
                            None,
                            None,
                            None,
                            'bad_field',
                            'xyz123')}))
        self.assertIn('has unknown field', cm.exception.msg)

        quota_info._add_example(
            AstExample(
                path=None,
                lineno=None,
                lexpos=None,
                label='default',
                text=None,
                fields={
                    'quota': AstExampleField(
                        None,
                        None,
                        None,
                        'quota',
                        64000)}))

        # set null for a required field
        with self.assertRaises(InvalidSpec) as cm:
            quota_info._add_example(
                AstExample(
                    path=None,
                    lineno=None,
                    lexpos=None,
                    label='null',
                    text=None,
                    fields={
                        'quota': AstExampleField(
                            None,
                            None,
                            None,
                            'quota',
                            None)}))
        self.assertEqual(
            "Bad example for field 'quota': null is not a valid integer",
            cm.exception.msg)

        self.assertTrue(quota_info._has_example('default'))

        quota_info.nullable = True

        # test for structs within structs
        account_info = Struct(
            'AccountInfo',
            None,
            ns,
        )
        account_info.set_attributes(
            "Information about an account.",
            [
                StructField('account_id', String(), 'Unique identifier for account.', None),
                StructField('quota_info', quota_info, 'Quota', None)
            ],
        )

        account_info._add_example(
            AstExample(
                path=None,
                lineno=None,
                lexpos=None,
                label='default',
                text=None,
                fields={
                    'account_id': AstExampleField(
                        None,
                        None,
                        None,
                        'account_id',
                        'xyz123'),
                    'quota_info': AstExampleField(
                        None,
                        None,
                        None,
                        'quota_info',
                        AstExampleRef(
                            None,
                            None,
                            None,
                            'default'))})
        )

        account_info._compute_examples()

        # ensure that an example for quota_info is propagated up
        self.assertIn('quota_info', account_info.get_examples()['default'].value)
    def test_no_preserve_aliases_from_api(self):
        api = Api(version=None)
        # Ensure imports come after 'preserve_alias' lexiographicaly
        # to catch namespace ordering bugs
        api.ensure_namespace('preserve_alias')
        api.ensure_namespace('zzzz')

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Setup aliases
        namespace_id = Alias('NamespaceId', ns, None)
        namespace_id.data_type = String()
        shared_folder_id = Alias('SharedFolderId', ns, None)
        shared_folder_id.set_attributes(None, namespace_id)
        path_root_id = Alias('PathRootId', ns, None)
        path_root_id.set_attributes(None, shared_folder_id)
        nullable_alias = Alias('NullableAlias', ns, None)
        nullable_alias.set_attributes(None, Nullable(path_root_id))
        foo_alias = Alias('FooAlias', None, None)
        foo_alias.set_attributes(None, String())
        bar_alias = Alias('BarAlias', None, None)
        bar_alias.set_attributes(None, foo_alias)

        ns.add_alias(namespace_id)
        ns.add_alias(shared_folder_id)
        ns.add_alias(path_root_id)
        ns.add_alias(nullable_alias)
        imported.add_alias(foo_alias)
        imported.add_alias(bar_alias)

        # Setup composite types
        test_struct = Struct('TestStruct', ns, None)
        test_struct.set_attributes(None, [
            StructField('field_alias', path_root_id, None, None),
            StructField('field_nullable_alias', nullable_alias, None, None),
            StructField('field_list_of_alias', List(path_root_id), None, None)
        ])
        test_union = Union('TestUnion', ns, None, None)
        test_union.set_attributes(
            None, [UnionField('test', path_root_id, None, None)])
        dependent_struct = Struct('DependentStruct', ns, None)
        dependent_struct.set_attributes(None, [
            StructField('field_alias', imported.alias_by_name['BarAlias'],
                        None, None)
        ])

        ns.add_data_type(test_struct)
        ns.add_data_type(test_union)
        ns.add_data_type(dependent_struct)

        # Setup aliases on composite types
        struct_alias = Alias('StructAlias', ns, None)
        struct_alias.set_attributes(None, test_struct)

        ns.add_alias(struct_alias)

        api = remove_aliases_from_api(api)

        # Ensure namespace exists
        self.assertEqual(len(api.namespaces), 2)
        self.assertTrue('preserve_alias' in api.namespaces)
        self.assertTrue('zzzz' in api.namespaces)

        ns = api.namespaces['preserve_alias']
        imported = api.namespaces['zzzz']

        # Ensure aliases are gone
        self.assertEqual(len(ns.aliases), 0)
        self.assertEqual(len(imported.aliases), 0)

        data_types = {
            data_type._name: data_type
            for data_type in ns.data_types
        }

        # Ensure struct and union field aliases resolve to proper types
        test_struct = data_types.get('TestStruct')
        self.assertIsInstance(test_struct, Struct)

        self.assertEqual(len(test_struct.fields), 3)

        for field in test_struct.fields:
            if field.name == 'field_list_of_alias':
                self.assertIsInstance(field.data_type, List)
                list_type = field.data_type.data_type
                self.assertIsInstance(list_type, String)
            elif field.name == 'field_nullable_alias':
                field_type = field.data_type
                self.assertIsInstance(field_type, Nullable)
                self.assertIsInstance(field_type.data_type, String)
            else:
                self.assertIsInstance(field.data_type, String)

        test_union = data_types['TestUnion']

        self.assertTrue(len(test_union.fields), 1)
        field = test_union.fields[0]

        self.assertEqual(field.name, 'test')
        self.assertIsInstance(field.data_type, String)

        # Ensure struct using imported alias resolves properly
        dependent_struct = data_types.get('DependentStruct')
        self.assertIsInstance(dependent_struct, Struct)

        self.assertEqual(len(dependent_struct.fields), 1)

        field = dependent_struct.fields[0]
        self.assertIsInstance(field.data_type, String)
예제 #23
0
    def test_struct(self):

        ns = ApiNamespace('test')

        quota_info = Struct(
            'QuotaInfo',
            None,
            ns,
        )
        quota_info.set_attributes(
            "Information about a user's space quota.",
            [
                StructField('quota', UInt64(), 'Total amount of space.', None),
            ],
        )

        # add an example that doesn't fit the definition of a struct
        with self.assertRaises(InvalidSpec) as cm:
            quota_info._add_example(
                AstExample(path=None,
                           lineno=None,
                           lexpos=None,
                           label='default',
                           text=None,
                           fields={
                               'bad_field':
                               AstExampleField(None, None, None, 'bad_field',
                                               'xyz123')
                           }))
        self.assertIn('has unknown field', cm.exception.msg)

        quota_info._add_example(
            AstExample(path=None,
                       lineno=None,
                       lexpos=None,
                       label='default',
                       text=None,
                       fields={
                           'quota':
                           AstExampleField(None, None, None, 'quota', 64000)
                       }))

        # set null for a required field
        with self.assertRaises(InvalidSpec) as cm:
            quota_info._add_example(
                AstExample(path=None,
                           lineno=None,
                           lexpos=None,
                           label='null',
                           text=None,
                           fields={
                               'quota':
                               AstExampleField(None, None, None, 'quota', None)
                           }))
        self.assertEqual(
            "Bad example for field 'quota': null is not a valid integer",
            cm.exception.msg)

        self.assertTrue(quota_info._has_example('default'))

        quota_info.nullable = True

        # test for structs within structs
        account_info = Struct(
            'AccountInfo',
            None,
            ns,
        )
        account_info.set_attributes(
            "Information about an account.",
            [
                StructField('account_id', String(),
                            'Unique identifier for account.', None),
                StructField('quota_info', quota_info, 'Quota', None)
            ],
        )

        account_info._add_example(
            AstExample(path=None,
                       lineno=None,
                       lexpos=None,
                       label='default',
                       text=None,
                       fields={
                           'account_id':
                           AstExampleField(None, None, None, 'account_id',
                                           'xyz123'),
                           'quota_info':
                           AstExampleField(
                               None, None, None, 'quota_info',
                               AstExampleRef(None, None, None, 'default'))
                       }))

        account_info._compute_examples()

        # ensure that an example for quota_info is propagated up
        self.assertIn('quota_info',
                      account_info.get_examples()['default'].value)
예제 #24
0
    def test_union(self):

        ns = ApiNamespace('files')

        update_parent_rev = Struct(
            'UpdateParentRev',
            None,
            ns,
        )
        update_parent_rev.set_attributes(
            "Overwrite existing file if the parent rev matches.",
            [
                StructField('parent_rev', String(), 'The revision to be updated.', None)
            ],
        )
        update_parent_rev._add_example(
            AstExample(
                path=None,
                lineno=None,
                lexpos=None,
                label='default',
                text=None,
                fields={
                    'parent_rev': AstExampleField(
                        None,
                        None,
                        None,
                        'parent_rev',
                        'xyz123')}))

        # test variants with only tags, as well as those with structs.
        conflict = Union(
            'WriteConflictPolicy',
            None,
            ns,
            True,
        )
        conflict.set_attributes(
            'Policy for managing write conflicts.',
            [
                UnionField(
                    'reject', Void(),
                    'On a write conflict, reject the new file.', None),
                UnionField(
                    'overwrite', Void(),
                    'On a write conflict, overwrite the existing file.', None),
                UnionField(
                    'update_if_matching_parent_rev', update_parent_rev,
                    'On a write conflict, overwrite the existing file.', None),
            ],
        )

        conflict._add_example(
            AstExample(
                path=None,
                lineno=None,
                lexpos=None,
                label='default',
                text=None,
                fields={
                    'update_if_matching_parent_rev': AstExampleField(
                        None,
                        None,
                        None,
                        'update_if_matching_parent_rev',
                        AstExampleRef(None, None, None, 'default'))}))

        conflict._compute_examples()

        # test that only null value is returned for an example of a Void type
        self.assertEqual(conflict.get_examples()['reject'].value, {'.tag': 'reject'})

        # test that dict is returned for a tagged struct variant
        self.assertEqual(conflict.get_examples()['default'].value,
            {'.tag': 'update_if_matching_parent_rev', 'parent_rev': 'xyz123'})
예제 #25
0
    def test_union(self):

        ns = ApiNamespace('files')

        update_parent_rev = Struct(
            'UpdateParentRev',
            None,
            ns,
        )
        update_parent_rev.set_attributes(
            "Overwrite existing file if the parent rev matches.",
            [
                StructField('parent_rev', String(),
                            'The revision to be updated.', None)
            ],
        )
        update_parent_rev._add_example(
            AstExample(path=None,
                       lineno=None,
                       lexpos=None,
                       label='default',
                       text=None,
                       fields={
                           'parent_rev':
                           AstExampleField(None, None, None, 'parent_rev',
                                           'xyz123')
                       }))

        # test variants with only tags, as well as those with structs.
        conflict = Union(
            'WriteConflictPolicy',
            None,
            ns,
            True,
        )
        conflict.set_attributes(
            'Policy for managing write conflicts.',
            [
                UnionField('reject', Void(),
                           'On a write conflict, reject the new file.', None),
                UnionField(
                    'overwrite', Void(),
                    'On a write conflict, overwrite the existing file.', None),
                UnionField(
                    'update_if_matching_parent_rev', update_parent_rev,
                    'On a write conflict, overwrite the existing file.', None),
            ],
        )

        conflict._add_example(
            AstExample(path=None,
                       lineno=None,
                       lexpos=None,
                       label='default',
                       text=None,
                       fields={
                           'update_if_matching_parent_rev':
                           AstExampleField(
                               None, None, None,
                               'update_if_matching_parent_rev',
                               AstExampleRef(None, None, None, 'default'))
                       }))

        conflict._compute_examples()

        # test that only null value is returned for an example of a Void type
        self.assertEqual(conflict.get_examples()['reject'].value,
                         {'.tag': 'reject'})

        # test that dict is returned for a tagged struct variant
        self.assertEqual(conflict.get_examples()['default'].value, {
            '.tag': 'update_if_matching_parent_rev',
            'parent_rev': 'xyz123'
        })
예제 #26
0
    def test_no_preserve_aliases_from_api(self):
        api = Api(version=None)
        api.ensure_namespace('preserve_alias')

        ns = api.namespaces['preserve_alias']

        namespace_id = Alias('NamespaceId', ns, None)
        namespace_id.data_type = String()
        shared_folder_id = Alias('SharedFolderId', ns, None)
        shared_folder_id.set_attributes(None, namespace_id)
        path_root_id = Alias('PathRootId', ns, None)
        path_root_id.set_attributes(None, shared_folder_id)

        ns.add_alias(namespace_id)
        ns.add_alias(shared_folder_id)
        ns.add_alias(path_root_id)

        test_struct = Struct('TestStruct', ns, None)
        test_struct.set_attributes(
            None, [StructField('field1', path_root_id, None, None)])
        test_union = Union('TestUnion', ns, None, None)
        test_union.set_attributes(
            None, [UnionField('test', path_root_id, None, None)])

        ns.add_data_type(test_struct)
        ns.add_data_type(test_union)

        struct_alias = Alias('StructAlias', ns, None)
        struct_alias.set_attributes(None, test_struct)

        ns.add_alias(struct_alias)

        api = remove_aliases_from_api(api)

        # Ensure namespace exists
        self.assertEqual(len(api.namespaces), 1)
        self.assertTrue('preserve_alias' in api.namespaces)

        ns = api.namespaces['preserve_alias']

        # Ensure aliases are gone
        self.assertEqual(len(ns.aliases), 0)

        data_types = {
            data_type._name: data_type
            for data_type in ns.data_types
        }

        # Ensure struct and union field aliases resolve to proper types
        test_struct = data_types.get('TestStruct')
        self.assertIsInstance(test_struct, Struct)

        self.assertTrue(len(test_struct.fields), 1)

        field = test_struct.fields[0]
        self.assertEqual(field.name, 'field1')
        self.assertIsInstance(field.data_type, String)

        test_union = data_types['TestUnion']

        self.assertTrue(len(test_union.fields), 1)
        field = test_union.fields[0]

        self.assertEqual(field.name, 'test')
        self.assertIsInstance(field.data_type, String)