From 9db299937cbaf4cc9cc5993c6af7f0b34cc45a7c Mon Sep 17 00:00:00 2001 From: "Hanna Shalamitskaya (EPAM)" Date: Tue, 26 Nov 2024 17:17:06 +0500 Subject: [PATCH] Add human-readable object representation --- .../base/base.py | 4 + .../base/data_types/data_type.py | 3 + .../base/data_types/scalar.py | 3 + .../impl/base_impl.py | 60 +++++++++++++++ .../collection/default_collection.py | 2 + .../characteristics/default_characteristic.py | 2 + .../characteristics/default_enumeration.py | 2 + .../impl/characteristics/default_state.py | 2 + .../default_structured_value.py | 3 + .../impl/characteristics/default_trait.py | 3 + .../quantifiable/default_quantifiable.py | 2 + .../default_encoding_constraint.py | 2 + .../default_fixed_point_constraint.py | 2 + .../default_language_constraint.py | 2 + .../constraints/default_length_constraint.py | 2 + .../constraints/default_locale_constraint.py | 2 + .../constraints/default_range_constraint.py | 7 ++ .../default_regular_expression_constraint.py | 2 + .../data_types/default_abstract_entity.py | 2 + .../impl/data_types/default_complex_type.py | 2 + .../impl/data_types/default_data_type.py | 7 ++ .../impl/data_types/default_scalar.py | 7 ++ .../impl/default_aspect.py | 2 + .../impl/default_either.py | 2 + .../impl/default_event.py | 2 + .../impl/default_operation.py | 3 + .../impl/default_property.py | 9 +++ .../impl/default_unit.py | 3 + .../loader/instantiator_base.py | 5 ++ .../pyproject.toml | 1 + .../tests/unit/base/__init__.py | 0 .../tests/unit/base/data_types/__init__.py | 0 .../base/data_types/test_abstract_entity.py | 53 +++++++++++++ .../unit/base/data_types/test_complex_type.py | 50 +++++++++++++ .../unit/base/data_types/test_data_type.py | 33 ++++++++ .../tests/unit/base/data_types/test_scalar.py | 27 +++++++ .../tests/unit/base/test_base.py | 50 +++++++++++++ .../unit/impl/data_types/test_datatype.py | 6 ++ .../tests/unit/impl/data_types/test_scalar.py | 6 ++ .../tests/unit/impl/test_base.py | 75 +++++++++++++++++++ 40 files changed, 450 insertions(+) create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/__init__.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/data_types/__init__.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_abstract_entity.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_complex_type.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_data_type.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_scalar.py create mode 100644 core/esmf-aspect-meta-model-python/tests/unit/base/test_base.py diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/base.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/base.py index 304ac59..ed7ded8 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/base.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/base.py @@ -34,3 +34,7 @@ def parent_elements(self, elements: list["Base"]) -> None: @abstractmethod def append_parent_element(self, element: "Base") -> None: """Add parent element.""" + + def __repr__(self): + """Object representation.""" + return f"{self.__class__.__name__}({self.name})" diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/data_type.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/data_type.py index 95ca359..4fdcea4 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/data_type.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/data_type.py @@ -30,3 +30,6 @@ def is_scalar(self) -> bool: def is_complex(self) -> bool: """Is complex flag.""" return not self.is_scalar + + def __repr__(self): + return f"{self.__class__.__name__}({self.urn})" diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/scalar.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/scalar.py index 1f8ec5b..e45cb85 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/scalar.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/data_types/scalar.py @@ -25,3 +25,6 @@ class Scalar(DataType, ABC): def is_scalar(self) -> bool: """Is scalar flag.""" return True + + def __repr__(self): + return f"{self.__class__.__name__}({self.urn})" diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/base_impl.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/base_impl.py index e55ce6b..a5fd057 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/base_impl.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/base_impl.py @@ -20,6 +20,9 @@ class BaseImpl(Base, metaclass=abc.ABCMeta): """Base Implemented class.""" + SCALAR_ATTR_NAMES = ["meta_model_version", "urn", "preferred_names", "descriptions"] + LIST_ATTR_NAMES = ["see"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes): self._meta_model_version = meta_model_base_attributes.meta_model_version self._urn = meta_model_base_attributes.urn @@ -75,3 +78,60 @@ def urn(self) -> Optional[str]: def name(self) -> str: """Name.""" return self._name + + def _get_base_message(self): + """Get base string message.""" + message = self.__class__.__name__ + message = message.replace("Default", "") + message = f"({message}){self.name}" + + return message + + @staticmethod + def _prepare_attr_message(name, value): + """Prepare a message with scalar attribute value.""" + message = f"{name}: " + if isinstance(value, dict): + for k, v in value.items(): + message += f"\n\t\t{k.upper()}: {v}" + else: + message += repr(value) if isinstance(value, BaseImpl) else str(value) + + return message + + def _get_scalar_attr_info(self): + """Get info about all scalar attributes.""" + message = "" + for attr_name in self.SCALAR_ATTR_NAMES: + attr_value = getattr(self, attr_name, None) + if attr_value: + message += f"\n\t{self._prepare_attr_message(attr_name, attr_value)}" + + return message + + @staticmethod + def _prepare_list_attr_message(name, value): + """Prepare a message for the list data type attribute value.""" + message = f"{name}:" + for elem in value: + message += f"\n\t\t{elem.name}" + + return message + + def _get_list_attr_info(self): + """Get info about all list data type attributes.""" + message = "" + for attr_name in self.LIST_ATTR_NAMES: + attr_value = getattr(self, attr_name, []) + if attr_value: + message += f"\n\t{self._prepare_list_attr_message(attr_name, attr_value)}" + + return message + + def __str__(self): + """String representation.""" + message = self._get_base_message() + message += self._get_scalar_attr_info() + message += self._get_list_attr_info() + + return message diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/collection/default_collection.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/collection/default_collection.py index c86c3d8..3b6e296 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/collection/default_collection.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/collection/default_collection.py @@ -21,6 +21,8 @@ class DefaultCollection(DefaultCharacteristic, Collection): """Default Collection class.""" + SCALAR_ATTR_NAMES = DefaultCharacteristic.SCALAR_ATTR_NAMES + ["element_characteristic"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_characteristic.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_characteristic.py index 3411a1a..7f7ee2d 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_characteristic.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_characteristic.py @@ -19,6 +19,8 @@ class DefaultCharacteristic(BaseImpl, Characteristic): """Default Characteristic class.""" + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + ["data_type"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes, data_type: DataType): super().__init__(meta_model_base_attributes) self._data_type = data_type diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_enumeration.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_enumeration.py index 30ab6ac..02d73b3 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_enumeration.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_enumeration.py @@ -20,6 +20,8 @@ class DefaultEnumeration(DefaultCharacteristic, Enumeration): """Default Enumeration class.""" + LIST_ATTR_NAMES = DefaultCharacteristic.LIST_ATTR_NAMES + ["values"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_state.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_state.py index 8b573b6..f99e01b 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_state.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_state.py @@ -20,6 +20,8 @@ class DefaultState(DefaultEnumeration, State): """Default State class.""" + SCALAR_ATTR_NAMES = DefaultEnumeration.SCALAR_ATTR_NAMES + ["default_value"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_structured_value.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_structured_value.py index 979c37a..91e98e3 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_structured_value.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_structured_value.py @@ -20,6 +20,9 @@ class DefaultStructuredValue(DefaultCharacteristic, StructuredValue): """Default Structured Value class""" + SCALAR_ATTR_NAMES = DefaultCharacteristic.SCALAR_ATTR_NAMES + ["deconstruction_rule"] + LIST_ATTR_NAMES = DefaultCharacteristic.LIST_ATTR_NAMES + ["elements"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_trait.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_trait.py index af3d7eb..e3764a4 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_trait.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/default_trait.py @@ -21,6 +21,9 @@ class DefaultTrait(DefaultCharacteristic, Trait): """Default Trait class.""" + SCALAR_ATTR_NAMES = DefaultCharacteristic.SCALAR_ATTR_NAMES + ["base_characteristic"] + LIST_ATTR_NAMES = DefaultCharacteristic.LIST_ATTR_NAMES + ["constraints"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/quantifiable/default_quantifiable.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/quantifiable/default_quantifiable.py index 555f289..8ae11f6 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/quantifiable/default_quantifiable.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/characteristics/quantifiable/default_quantifiable.py @@ -21,6 +21,8 @@ class DefaultQuantifiable(DefaultCharacteristic, Quantifiable): """Default Quantifiable class.""" + LIST_ATTR_NAMES = DefaultCharacteristic.LIST_ATTR_NAMES + ["unit"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_encoding_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_encoding_constraint.py index 04a980e..1d62009 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_encoding_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_encoding_constraint.py @@ -17,6 +17,8 @@ class DefaultEncodingConstraint(DefaultConstraint, EncodingConstraint): """Default Encoding Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["value"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes, value: str): super().__init__(meta_model_base_attributes) self._value = value diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_fixed_point_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_fixed_point_constraint.py index 492c633..819152c 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_fixed_point_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_fixed_point_constraint.py @@ -17,6 +17,8 @@ class DefaultFixedPointConstraint(DefaultConstraint, FixedPointConstraint): """Default Fixed Point Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["scale", "integer"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_language_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_language_constraint.py index 1cc9fb6..c5da1a2 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_language_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_language_constraint.py @@ -17,6 +17,8 @@ class DefaultLanguageConstraint(DefaultConstraint, LanguageConstraint): """Default Language Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["language_code"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes, language_code: str): super().__init__(meta_model_base_attributes) self._language_code = language_code diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_length_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_length_constraint.py index 12e0592..488b62b 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_length_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_length_constraint.py @@ -19,6 +19,8 @@ class DefaultLengthConstraint(DefaultConstraint, LengthConstraint): """Default Length Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["min_value", "max_value"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_locale_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_locale_constraint.py index fea94c0..a725a36 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_locale_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_locale_constraint.py @@ -17,6 +17,8 @@ class DefaultLocaleConstraint(DefaultConstraint, LocaleConstraint): """Default Locale Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["locale_code"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes, locale_code: str): super().__init__(meta_model_base_attributes) self._locale_code = locale_code diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_range_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_range_constraint.py index d26151f..11226b8 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_range_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_range_constraint.py @@ -20,6 +20,13 @@ class DefaultRangeConstraint(DefaultConstraint, RangeConstraint): """Default Range Constraint class.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + [ + "min_value", + "max_value", + "lower_bound_definition", + "upper_bound_definition", + ] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_regular_expression_constraint.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_regular_expression_constraint.py index 68dfb90..2169acd 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_regular_expression_constraint.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/constraints/default_regular_expression_constraint.py @@ -17,6 +17,8 @@ class DefaultRegularExpressionConstraint(DefaultConstraint, RegularExpressionConstraint): """Default Regular Expression Constraint.""" + SCALAR_ATTR_NAMES = DefaultConstraint.SCALAR_ATTR_NAMES + ["value"] + def __init__(self, meta_model_base_attributes: MetaModelBaseAttributes, value: str): super().__init__(meta_model_base_attributes) self._value = value diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_abstract_entity.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_abstract_entity.py index 8c99932..f7b54a1 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_abstract_entity.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_abstract_entity.py @@ -21,6 +21,8 @@ class DefaultAbstractEntity(DefaultComplexType, AbstractEntity): """Default Abstract Entity class.""" + LIST_ATTR_NAMES = DefaultComplexType.LIST_ATTR_NAMES + ["extending_elements"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_complex_type.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_complex_type.py index 960c521..5982106 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_complex_type.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_complex_type.py @@ -25,6 +25,8 @@ class DefaultComplexType(BaseImpl, ComplexType): """ _instances: Dict[str, ComplexType] = {} + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + ["extends"] + LIST_ATTR_NAMES = BaseImpl.LIST_ATTR_NAMES + ["properties"] def __init__( self, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_data_type.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_data_type.py index 8582a47..9e06aa2 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_data_type.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_data_type.py @@ -28,3 +28,10 @@ def urn(self) -> str: def meta_model_version(self) -> str: """Meta model version.""" return self._meta_model_version + + def __str__(self): + message = self.__class__.__name__ + message = message.replace("Default", "") + message += f":\n\tmeta_model_version: {self.meta_model_version}\n\turn: {self.urn}" + + return message diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_scalar.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_scalar.py index 7c3f23d..0c4edb4 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_scalar.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/data_types/default_scalar.py @@ -28,3 +28,10 @@ def urn(self) -> str: def meta_model_version(self) -> str: """Meta model version.""" return self._meta_model_version + + def __str__(self): + message = self.__class__.__name__ + message = message.replace("Default", "") + message += f":\n\tmeta_model_version: {self.meta_model_version}\n\turn: {self.urn}" + + return message diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_aspect.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_aspect.py index 0c44f41..c026fff 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_aspect.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_aspect.py @@ -22,6 +22,8 @@ class DefaultAspect(Aspect, BaseImpl): """Default Aspect class.""" + LIST_ATTR_NAMES = BaseImpl.LIST_ATTR_NAMES + ["properties", "operations", "events"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_either.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_either.py index 5c519f4..a2d0f50 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_either.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_either.py @@ -18,6 +18,8 @@ class DefaultEither(BaseImpl, Either): """Default Either class.""" + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + ["left", "right"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_event.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_event.py index 4d39b9a..95777d8 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_event.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_event.py @@ -20,6 +20,8 @@ class DefaultEvent(BaseImpl, Event): """Default Event class.""" + LIST_ATTR_NAMES = BaseImpl.LIST_ATTR_NAMES + ["parameters"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_operation.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_operation.py index 2fb8656..5704c8f 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_operation.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_operation.py @@ -20,6 +20,9 @@ class DefaultOperation(BaseImpl, Operation): """Default Operation class.""" + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + ["output_property"] + LIST_ATTR_NAMES = BaseImpl.LIST_ATTR_NAMES + ["input_properties"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_property.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_property.py index 4f57879..de64166 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_property.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_property.py @@ -20,6 +20,15 @@ class DefaultProperty(BaseImpl, Property): """Default Property class.""" + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + [ + "characteristic", + "example_value", + "extends", + "optional", + "not_in_payload", + "payload_name", + ] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_unit.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_unit.py index 38fa9bc..b0b445f 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_unit.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/impl/default_unit.py @@ -20,6 +20,9 @@ class DefaultUnit(BaseImpl, Unit): """Default Unit class.""" + SCALAR_ATTR_NAMES = BaseImpl.SCALAR_ATTR_NAMES + ["symbol", "code", "reference_unit", "conversion_factor"] + LIST_ATTR_NAMES = BaseImpl.LIST_ATTR_NAMES + ["quantity_kinds"] + def __init__( self, meta_model_base_attributes: MetaModelBaseAttributes, diff --git a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator_base.py b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator_base.py index 62c49dd..a8136e2 100644 --- a/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator_base.py +++ b/core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator_base.py @@ -178,6 +178,11 @@ def _get_data_type(self, element_node: Node) -> Optional[DataType]: subject=element_characteristic_node, predicate=self._samm.get_urn(SAMM.data_type), ) + if not data_type_node: + data_type_node = self._aspect_graph.value( + subject=element_characteristic_node, + predicate=rdflib.RDF.type, + ) else: data_type_node = self._aspect_graph.value( subject=element_node, diff --git a/core/esmf-aspect-meta-model-python/pyproject.toml b/core/esmf-aspect-meta-model-python/pyproject.toml index e56bdf8..740f6ea 100644 --- a/core/esmf-aspect-meta-model-python/pyproject.toml +++ b/core/esmf-aspect-meta-model-python/pyproject.toml @@ -26,6 +26,7 @@ documentation = "https://eclipse-esmf.github.io/python-sdk-guide/index.html" [tool.poetry.dependencies] python = "^3.10" +keyboard = "^0.13" rdflib = "^6.2.0" requests = "^2.28.1" tox = "^4.5.2" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/__init__.py b/core/esmf-aspect-meta-model-python/tests/unit/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/__init__.py b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_abstract_entity.py b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_abstract_entity.py new file mode 100644 index 0000000..5bdde39 --- /dev/null +++ b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_abstract_entity.py @@ -0,0 +1,53 @@ +"""Abstract Entity interface test suite.""" + +from esmf_aspect_meta_model_python.base.data_types.abstract_entity import AbstractEntity + + +class AbstractEntityInterface(AbstractEntity): + """AbstractEntity interface class for testing.""" + + def name(self): + pass + + def preferred_names(self): + pass + + def descriptions(self): + pass + + def see(self): + pass + + def meta_model_version(self): + pass + + def urn(self): + pass + + def properties(self): + pass + + def parent_elements(self): + pass + + def append_parent_element(self, element): + pass + + def all_properties(self): + pass + + def extends(self): + pass + + def extending_elements(self): + pass + + +class TestAbstractEntity: + """Scalar interface test suite.""" + + def test_is_abstract_entity(self): + abstract_entity = AbstractEntityInterface() + result = abstract_entity.is_abstract_entity + + assert result is True diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_complex_type.py b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_complex_type.py new file mode 100644 index 0000000..c58e058 --- /dev/null +++ b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_complex_type.py @@ -0,0 +1,50 @@ +"""Complex Type interface test suite.""" + +from esmf_aspect_meta_model_python.base.data_types.complex_type import ComplexType + + +class ComplexTypeInterface(ComplexType): + """ComplexType interface class for testing.""" + + def name(self): + pass + + def preferred_names(self): + pass + + def descriptions(self): + pass + + def see(self): + pass + + def meta_model_version(self): + pass + + def urn(self): + pass + + def properties(self): + pass + + def parent_elements(self): + pass + + def append_parent_element(self, element): + pass + + def all_properties(self): + pass + + def extends(self): + pass + + +class TestComplexType: + """ComplexType interface test suite.""" + + def test_is_abstract_entity(self): + abstract_entity = ComplexTypeInterface() + result = abstract_entity.is_abstract_entity + + assert result is False diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_data_type.py b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_data_type.py new file mode 100644 index 0000000..8829610 --- /dev/null +++ b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_data_type.py @@ -0,0 +1,33 @@ +"""Data type interface test suite.""" + +from esmf_aspect_meta_model_python.base.data_types.data_type import DataType + + +class DataTypeInterface(DataType): + """DataType interface class for testing.""" + + def __init__(self, urn): + self._urn = urn + + @property + def urn(self): + return self._urn + + def meta_model_version(self): + pass + + +class TestDataType: + """DataType interface test suite.""" + + def test_is_scalar(self): + data_type = DataTypeInterface("urn") + result = data_type.is_scalar + + assert result is False + + def test_resp(self): + data_type = DataTypeInterface("urn") + result = repr(data_type) + + assert result == "DataTypeInterface(urn)" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_scalar.py b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_scalar.py new file mode 100644 index 0000000..a2ad6ff --- /dev/null +++ b/core/esmf-aspect-meta-model-python/tests/unit/base/data_types/test_scalar.py @@ -0,0 +1,27 @@ +"""Scalar interface test suite.""" + +from esmf_aspect_meta_model_python.base.data_types.scalar import Scalar + + +class ScalarInterface(Scalar): + """Scalar interface class for testing.""" + + def __init__(self, urn): + self._urn = urn + + @property + def urn(self): + return self._urn + + def meta_model_version(self): + pass + + +class TestScalar: + """Scalar interface test suite.""" + + def test_resp(self): + scalar = ScalarInterface("urn") + result = repr(scalar) + + assert result == "ScalarInterface(urn)" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/base/test_base.py b/core/esmf-aspect-meta-model-python/tests/unit/base/test_base.py new file mode 100644 index 0000000..7e88dc6 --- /dev/null +++ b/core/esmf-aspect-meta-model-python/tests/unit/base/test_base.py @@ -0,0 +1,50 @@ +"""Base interface test suite.""" + +from esmf_aspect_meta_model_python.base.base import Base + + +class BaseInterface(Base): + """Base interface class for testing.""" + + def __init__(self, name): + self._name = name + + def urn(self): + pass + + def meta_model_version(self): + pass + + @property + def name(self): + return self._name + + def preferred_names(self): + pass + + def descriptions(self): + pass + + def see(self): + pass + + @property + def parent_elements(self): + return None + + @parent_elements.setter + def parent_elements(self, elements): + pass + + def append_parent_element(self, element): + pass + + +class TestBase: + """Base interface test suite.""" + + def test_resp(self): + base = BaseInterface("name") + result = repr(base) + + assert result == "BaseInterface(name)" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_datatype.py b/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_datatype.py index ffdffb8..d4aefe4 100644 --- a/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_datatype.py +++ b/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_datatype.py @@ -27,3 +27,9 @@ def test_meta_model_version(self): result = scalar.meta_model_version assert result == self.meta_model_mock + + def test_str(self): + scalar = DefaultDataType("urn", "meta_model_version") + result = str(scalar) + + assert result == "DataType:\n\tmeta_model_version: meta_model_version\n\turn: urn" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_scalar.py b/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_scalar.py index 31bf913..e19f9bc 100644 --- a/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_scalar.py +++ b/core/esmf-aspect-meta-model-python/tests/unit/impl/data_types/test_scalar.py @@ -27,3 +27,9 @@ def test_meta_model_version(self): result = scalar.meta_model_version assert result == self.meta_model_mock + + def test_str(self): + scalar = DefaultScalar("urn", "meta_model_version") + result = str(scalar) + + assert result == "Scalar:\n\tmeta_model_version: meta_model_version\n\turn: urn" diff --git a/core/esmf-aspect-meta-model-python/tests/unit/impl/test_base.py b/core/esmf-aspect-meta-model-python/tests/unit/impl/test_base.py index 2c7fbd8..6de470b 100644 --- a/core/esmf-aspect-meta-model-python/tests/unit/impl/test_base.py +++ b/core/esmf-aspect-meta-model-python/tests/unit/impl/test_base.py @@ -118,3 +118,78 @@ def test_name(self): result = base.name assert result == "name" + + def test_get_base_message(self): + base = BaseImpl(self.meta_model_mock) + result = base._get_base_message() + + assert result == "(BaseImpl)name" + + def test_prepare_attr_message_dict_value(self): + value = {"attr_name": "attr_value"} + result = BaseImpl._prepare_attr_message("name", value) + + assert result == "name: \n\t\tATTR_NAME: attr_value" + + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.repr") + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.isinstance") + def test_prepare_attr_message_node_value(self, isinstance_mock, repr_mock): + isinstance_mock.side_effect = (False, True) + repr_mock.return_value = "value_repr" + result = BaseImpl._prepare_attr_message("name", "value") + + assert result == "name: value_repr" + isinstance_mock.assert_has_calls( + [ + mock.call("value", dict), + mock.call("value", BaseImpl), + ] + ) + repr_mock.assert_called_once_with("value") + + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.isinstance") + def test_prepare_attr_message(self, isinstance_mock): + isinstance_mock.side_effect = (False, False) + result = BaseImpl._prepare_attr_message("name", 1) + + assert result == "name: 1" + isinstance_mock.assert_has_calls([mock.call(1, dict), mock.call(1, BaseImpl)]) + + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.BaseImpl._prepare_attr_message") + def test_get_scalar_attr_info(self, prepare_attr_message_mock): + prepare_attr_message_mock.return_value = "attr_message" + base = BaseImpl(self.meta_model_mock) + base.SCALAR_ATTR_NAMES = ["attr_name"] + base.attr_name = "attr_value" + result = base._get_scalar_attr_info() + + assert result == "\n\tattr_message" + + def test_prepare_list_attr_message(self): + value_mock = mock.MagicMock(name="element") + value_mock.name = "value_name" + result = BaseImpl._prepare_list_attr_message("name", [value_mock]) + + assert result == "name:\n\t\tvalue_name" + + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.BaseImpl._prepare_list_attr_message") + def test_get_list_attr_info(self, prepare_list_attr_message_mock): + prepare_list_attr_message_mock.return_value = "attr_message" + base = BaseImpl(self.meta_model_mock) + base.LIST_ATTR_NAMES = ["attr_name"] + base.attr_name = "attr_value" + result = base._get_list_attr_info() + + assert result == "\n\tattr_message" + + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.BaseImpl._get_list_attr_info") + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.BaseImpl._get_scalar_attr_info") + @mock.patch("esmf_aspect_meta_model_python.impl.base_impl.BaseImpl._get_base_message") + def test_str(self, get_base_message_mock, get_scalar_attr_info_mock, get_list_attr_info_mock): + get_base_message_mock.return_value = "base message" + get_scalar_attr_info_mock.return_value = "\ncalar attributes info" + get_list_attr_info_mock.return_value = "\nlist attributes info" + base = BaseImpl(self.meta_model_mock) + result = str(base) + + assert result == "base message\ncalar attributes info\nlist attributes info"