From d7f8ff9fb422029355850cb2c7080a0e50b82c01 Mon Sep 17 00:00:00 2001 From: John Liu Date: Wed, 22 Mar 2023 12:17:20 -0400 Subject: [PATCH] Add test for union of empty type --- .../test/resources/types/example-types.yml | 5 ++-- .../types/expected/package_name/_impl.py | 25 +++++++++++++++++-- .../python/test/client/test_code_gen.py | 13 ++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/conjure-python-core/src/test/resources/types/example-types.yml b/conjure-python-core/src/test/resources/types/example-types.yml index aa4814fe4..1a2bbaae3 100644 --- a/conjure-python-core/src/test/resources/types/example-types.yml +++ b/conjure-python-core/src/test/resources/types/example-types.yml @@ -121,6 +121,8 @@ types: alias: type: StringAliasExample docs: docs for alias field + EmptyObjectExample: + fields: {} UnionTypeExample: docs: A type which can either be a StringExample, a set of strings, or an integer. union: @@ -134,8 +136,7 @@ types: new: integer interface: integer property: integer - EmptyObjectExample: - fields: {} + empty: EmptyObjectExample AliasAsMapKeyExample: fields: strings: map diff --git a/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py b/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py index 6aa8bfeaa..e6c4d1f07 100644 --- a/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py +++ b/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py @@ -1397,6 +1397,7 @@ class product_UnionTypeExample(ConjureUnionType): _new: Optional[int] = None _interface: Optional[int] = None _property: Optional[int] = None + _empty: Optional["product_EmptyObjectExample"] = None @builtins.classmethod def _options(cls) -> Dict[str, ConjureFieldDefinition]: @@ -1408,7 +1409,8 @@ def _options(cls) -> Dict[str, ConjureFieldDefinition]: 'if_': ConjureFieldDefinition('if', int), 'new': ConjureFieldDefinition('new', int), 'interface': ConjureFieldDefinition('interface', int), - 'property': ConjureFieldDefinition('property', int) + 'property': ConjureFieldDefinition('property', int), + 'empty': ConjureFieldDefinition('empty', product_EmptyObjectExample) } def __init__( @@ -1421,10 +1423,11 @@ def __init__( new: Optional[int] = None, interface: Optional[int] = None, property: Optional[int] = None, + empty: Optional["product_EmptyObjectExample"] = None, type_of_union: Optional[str] = None ) -> None: if type_of_union is None: - if (string_example is not None) + (set is not None) + (this_field_is_an_integer is not None) + (also_an_integer is not None) + (if_ is not None) + (new is not None) + (interface is not None) + (property is not None) != 1: + if (string_example is not None) + (set is not None) + (this_field_is_an_integer is not None) + (also_an_integer is not None) + (if_ is not None) + (new is not None) + (interface is not None) + (property is not None) + (empty is not None) != 1: raise ValueError('a union must contain a single member') if string_example is not None: @@ -1451,6 +1454,9 @@ def __init__( if property is not None: self._property = property self._type = 'property' + if empty is not None: + self._empty = empty + self._type = 'empty' elif type_of_union == 'string_example': if string_example is None: @@ -1492,6 +1498,11 @@ def __init__( raise ValueError('a union value must not be None') self._property = property self._type = 'property' + elif type_of_union == 'empty': + if empty is None: + raise ValueError('a union value must not be None') + self._empty = empty + self._type = 'empty' @builtins.property def string_example(self) -> Optional["product_StringExample"]: @@ -1528,6 +1539,10 @@ def interface(self) -> Optional[int]: def property(self) -> Optional[int]: return self._property + @builtins.property + def empty(self) -> Optional["product_EmptyObjectExample"]: + return self._empty + def accept(self, visitor) -> Any: if not isinstance(visitor, product_UnionTypeExampleVisitor): raise ValueError('{} is not an instance of product_UnionTypeExampleVisitor'.format(visitor.__class__.__name__)) @@ -1547,6 +1562,8 @@ def accept(self, visitor) -> Any: return visitor._interface(self.interface) if self._type == 'property' and self.property is not None: return visitor._property(self.property) + if self._type == 'empty' and self.empty is not None: + return visitor._empty(self.empty) product_UnionTypeExample.__name__ = "UnionTypeExample" @@ -1588,6 +1605,10 @@ def _interface(self, interface: int) -> Any: def _property(self, property: int) -> Any: pass + @abstractmethod + def _empty(self, empty: "product_EmptyObjectExample") -> Any: + pass + product_UnionTypeExampleVisitor.__name__ = "UnionTypeExampleVisitor" product_UnionTypeExampleVisitor.__qualname__ = "UnionTypeExampleVisitor" diff --git a/conjure-python-verifier/python/test/client/test_code_gen.py b/conjure-python-verifier/python/test/client/test_code_gen.py index ae9bea99c..bc0a75775 100644 --- a/conjure-python-verifier/python/test/client/test_code_gen.py +++ b/conjure-python-verifier/python/test/client/test_code_gen.py @@ -51,3 +51,16 @@ def _options(self, value): # test for backwards compatibility assert OptionsUnion(options="options").accept(TestOptionsUnionVisitor()) == "options" assert OptionsUnion(options="options", type_of_union="options").accept(TestOptionsUnionVisitor()) == "options" + + +def test_union_visitor_for_empty_type(): + from generated_integration.product import UnionTypeExample, UnionTypeExampleVisitor, EmptyObjectExample + + class TestUnionTypeExampleVisitor(UnionTypeExampleVisitor): + def _empty(self, value): + return value + + # test for backwards compatibility + emptyExample = EmptyObjectExample() + assert UnionTypeExample(empty=emptyExample).accept(TestUnionTypeExampleVisitor()) == emptyExample + assert UnionTypeExample(empty=emptyExample, type_of_union="empty").accept(TestUnionTypeExampleVisitor()) == emptyExample