diff options
author | Vladyslav Mustafin <v.mustafin@gmail.com> | 2020-02-06 21:23:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-06 14:23:23 -0500 |
commit | 88c73e25c957cf5eae521688d74064ae8429fb8c (patch) | |
tree | 383d380f15e94848f1385ff9f51f49fc6614d7a2 /tools/InterfaceGenerator | |
parent | fcdacd760c6182e73f3517b3baa0dd10660ff0e8 (diff) | |
download | sdl_core-88c73e25c957cf5eae521688d74064ae8429fb8c.tar.gz |
#3211 [SDL 0234] Proxy Library RPC Generation (#3213)
* #3211 [SDL 0234] Proxy Library RPC Generation
* Split existing `InterfaceGenerator` into `InterfaceParser` and `InterfaceGenerator`
* Moved InterfaceParser into `smartdevicelink/rpc_spec`
* Rejoined `InterfaceParser` as `tools/rpc_spec` Git submodule from `smartdevicelink/rpc_spec`
* Refactored `InterfaceGenerator` to use Parser from `tools/rpc_spec` Git submodule and be compatible with Python 3.5
* Replaced url SSH to HTTPS in submodule
* refactoring according to comments in pull/202
* move common parsers to rpc_spec repo
* change cmake argument
* fix cmake argument list
* fix cmake argument list
* fix cmake argument list
* small refactoring as requested in code review
* adding *.xsd
* adding *.xsd
* xmlschema dependency added for python interface generator
* align changes from parser rpc_spec
* align changes from parser rpc_spec
* align with rpc_spec
* moved xmlschema python dependency installation to build script
* installing all python requirements
* Corrected requirements file
* Additional dependencies for requirements
* Correcting requirements
* adding jsoncpp submodule
* fixing unit tests
* fixing unit tests
* rename CodeFormatAndQuality
* updated rpc_spec reference
Co-authored-by: Aleksandr Mishchenko <amishchenko@luxoft.com>
Co-authored-by: Kostiantyn Sologubov <ksologubov@luxoft.com>
Diffstat (limited to 'tools/InterfaceGenerator')
24 files changed, 724 insertions, 2482 deletions
diff --git a/tools/InterfaceGenerator/Generator.py b/tools/InterfaceGenerator/Generator.py index 905b0754b3..6f90f62e71 100755 --- a/tools/InterfaceGenerator/Generator.py +++ b/tools/InterfaceGenerator/Generator.py @@ -16,113 +16,161 @@ optional arguments: --parser-type {sdlrpcv2} """ -import os.path -import argparse -import errno +import os +import re import sys - -import generator.parsers.SDLRPCV1 -import generator.parsers.SDLRPCV2 -import generator.parsers.JSONRPC -import generator.generators.SmartFactorySDLRPC -import generator.generators.SmartFactoryJSONRPC -import generator.generators.PolicyTypes -import MsgVersionGenerate - -from generator.parsers.RPCBase import ParseError -from generator.generators.SmartFactoryBase import GenerateError - -SUPPORTED_FORMATS = { - "sdlrpcv1": (generator.parsers.SDLRPCV1.Parser, - generator.generators.SmartFactorySDLRPC.CodeGenerator), - "sdlrpcv2": (generator.parsers.SDLRPCV2.Parser, - generator.generators.SmartFactorySDLRPC.CodeGenerator), - "jsonrpc": (generator.parsers.JSONRPC.Parser, - generator.generators.SmartFactoryJSONRPC.CodeGenerator), - "mobile-policy-types": (generator.parsers.SDLRPCV2.Parser, - generator.generators.PolicyTypes.CodeGenerator), - "hmi-policy-types": (generator.parsers.JSONRPC.Parser, - generator.generators.PolicyTypes.CodeGenerator) -} - - -def _create_parser(): - """Create parser for parsing command-line arguments. - - Returns an instance of argparse.ArgumentParser - - """ - - parser = argparse.ArgumentParser( - description="SmartSchema interface generator" - ) - parser.add_argument("source-xml") - parser.add_argument("namespace") - parser.add_argument("output-dir") - parser.add_argument("--parser-type", - choices=SUPPORTED_FORMATS.keys(), - required=True) - return parser - - -def _handle_fatal_error(error): - """Handle fatal error during parsing or code generation. - - Keyword arguments: - error -- base exception to handle. +from argparse import ArgumentParser +from pathlib import Path + +ROOT = Path(__file__).absolute().parents[1] +sys.path.append(ROOT.joinpath('rpc_spec/InterfaceParser').as_posix()) + +try: + from model.interface import Interface + from parsers import sdl_rpc_v2 + from parsers.parse_error import ParseError + from MsgVersionGenerate import generate_msg_version + from generator.generators import SmartFactorySDLRPC, SmartFactoryJSONRPC, PolicyTypes + from generator.generators.SmartFactoryBase import GenerateError + from generator.parsers import SDLRPCV1, JSONRPC +except ModuleNotFoundError as error: + print(str(error) + '\nPlease make sure the RPC Spec Generator Submodule is initialized.\n' + 'Check the sdl_core source directory in `tools/rpc_spec`.\n' + 'Try running in the source directory:\n' + '$ git submodule init\n' + '$ git submodule update') + sys.exit(1) + + +class Generator: + """Generator application that generates c++ interfaces code from xml description """ - print(error.message) - print - sys.exit(errno.EINVAL) - -def main(): - """Main function of the generator that does actual work.""" - - args = vars(_create_parser().parse_args()) - - src_xml = args["source-xml"] - src_xml_name = os.path.splitext(os.path.basename(src_xml))[0] - namespace = args["namespace"] - output_dir = args["output-dir"] - parser_type = args["parser_type"] - - print(""" + def __init__(self): + self._supported_formats = { + 'sdlrpcv1': (SDLRPCV1.Parser, SmartFactorySDLRPC.CodeGenerator), + 'sdlrpcv2': (sdl_rpc_v2.Parser, SmartFactorySDLRPC.CodeGenerator), + 'jsonrpc': (JSONRPC.Parser, SmartFactoryJSONRPC.CodeGenerator), + 'mobile-policy-types': (sdl_rpc_v2.Parser, PolicyTypes.CodeGenerator), + 'hmi-policy-types': (JSONRPC.Parser, PolicyTypes.CodeGenerator) + } + + @property + def supported_formats(self): + """ + :return: dictionary with supported_formats + """ + return self._supported_formats + + def _create_parser(self): + """ + Parsing command-line arguments, or evaluating required Paths interactively. + :return: an instance of argparse.ArgumentParser + """ + if len(sys.argv) == 2 and sys.argv[1] in ('-v', '--version'): + print('1.0.0') + sys.exit(0) + + parser = ArgumentParser(description='Proxy Library RPC Generator') + parser.add_argument('-xml', '--source-xml', '--input-file', required=True, + help='should point to MOBILE_API.xml') + parser.add_argument('-ns', '--namespace', required=True) + parser.add_argument('-d', '-o', '--output-dir', required=True, + help='define the place where the generated output should be placed') + parser.add_argument('-t', '--parser-type', required=True, choices=self.supported_formats.keys()) + parser.add_argument('-v', '--version', action='store_true', help='print the version and exit') + parser.add_argument('-r', '--regex-pattern', required=False, + help='only elements matched with defined regex pattern will be parsed and generated') + parser.add_argument('--verbose', action='store_true', help='display additional details like logs etc') + parser.add_argument('-e', '--enums', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-s', '--structs', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-m', '-f', '--functions', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-y', '--overwrite', action='store_true', + help='force overwriting of existing files in output directory, ignore confirmation message') + parser.add_argument('-n', '--skip', action='store_true', + help='skip overwriting of existing files in output directory, ignore confirmation message') + + args, unknown = parser.parse_known_args() + + if unknown: + print('found unknown arguments: ' + ' '.join(unknown)) + parser.print_help(sys.stderr) + sys.exit(1) + + if args.skip and args.overwrite or not args.skip and not args.overwrite: + print('please select one option skip or overwrite') + sys.exit(1) + + if not args.enums and not args.structs and not args.functions: + args.enums = args.structs = args.functions = True + + return args + + @staticmethod + def filter_pattern(interface, pattern): + """ + Filtring model according to regex pattern + :param interface: Interface model + :param pattern: regex pattern + :return: + """ + match = {i: {} for i in vars(interface).keys()} + match['params'] = interface.params + if pattern: + for key, value in vars(interface).items(): + if key == 'params': + continue + for name, item in value.items(): + if re.match(pattern, item.name): + if key in match: + match[key].update({name: item}) + else: + return interface + + return Interface(**match) + + def main(self): + """Main function of the generator that does actual work.""" + + args = self._create_parser() + + print(""" Generating interface source code with following parameters: Source xml : {0} Namespace : {1} Output directory: {2} Parser type : {3} -""".format(src_xml, namespace, output_dir, parser_type)) + overwrite : {4} +""".format(args.source_xml, args.namespace, args.output_dir, args.parser_type, args.overwrite)) - # Select required parser and code generator - parser = SUPPORTED_FORMATS[parser_type][0]() - code_generator = SUPPORTED_FORMATS[parser_type][1]() + # Select required parser and code generator + parser = self.supported_formats[args.parser_type][0]() + code_generator = self.supported_formats[args.parser_type][1]() - # Convert incoming xml to internal model - try: - interface = parser.parse(args["source-xml"]) - except ParseError as error: - _handle_fatal_error(error) - - # Parse sdl version from MOBILE_API.xml and create source file with this version - if src_xml_name == "MOBILE_API": + # Convert incoming xml to internal model try: - MsgVersionGenerate.generate_msg_version(src_xml, output_dir) - except ParseError as error: - _handle_fatal_error(error) + interface = parser.parse(args.source_xml) + filtered = self.filter_pattern(interface, args.regex_pattern) + src_xml_name = os.path.splitext(os.path.basename(args.source_xml))[0] + # Parse sdl version from MOBILE_API.xml and create source file with this version + if src_xml_name == "MOBILE_API": + generate_msg_version(args.source_xml, args.output_dir) + + # Generate SmartFactory source code from internal model + code_generator.generate(filtered, + src_xml_name, + args.namespace, + args.output_dir) + except (ParseError, GenerateError) as error1: + print(error1) + sys.exit(1) - # Generate SmartFactory source code from internal model - try: - code_generator.generate(interface, - src_xml_name, - namespace, - output_dir) - except GenerateError as error: - _handle_fatal_error(error) + print('Done.') - print("Done.") if __name__ == '__main__': - main() + Generator().main() diff --git a/tools/InterfaceGenerator/MsgVersionGenerate.py b/tools/InterfaceGenerator/MsgVersionGenerate.py index d1e5d7d968..85b3cfd38f 100644 --- a/tools/InterfaceGenerator/MsgVersionGenerate.py +++ b/tools/InterfaceGenerator/MsgVersionGenerate.py @@ -4,8 +4,10 @@ Generate file with major and minor msg_version. import xml.etree.ElementTree from string import Template import re -from generator.parsers import RPCBase - + +from parsers.parse_error import ParseError + + def generate_msg_version(file_name, path_to_storage): """Parses MOBILE_API.xml in order to receive major_version, minor_version, and patch_version @@ -33,9 +35,9 @@ def generate_msg_version(file_name, path_to_storage): minimum_major_version, minimum_minor_version, minimum_patch_version) store_data_to_file(path_to_storage, data_for_storage) else: - raise RPCBase.ParseError("Attribute version has incorect value in MOBILE_API.xml") + raise ParseError("Attribute version has incorect value in MOBILE_API.xml") else: - raise RPCBase.ParseError("Check MOBILE_API.xml file, parser can not find first element " + raise ParseError("Check MOBILE_API.xml file, parser can not find first element " " with tag interface or atribute version") def store_data_to_file(path_to_storage, data_for_storage): @@ -53,7 +55,7 @@ def check_version_format(version): p = re.compile('\d+\\.\d+\\.\d+') result = p.match(version) if result == None or (result.end() != len(version)): - raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. " + raise ParseError("Incorrect format of version please check MOBILE_API.xml. " "Need format of version major_version.minor_version.patch_version") @@ -63,7 +65,7 @@ def check_minimum_version_format(version): p = re.compile('\d+\\.\d+\\.\d+|\d+\\.\d+') result = p.match(version) if result == None or (result.end() != len(version)): - raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. " + raise ParseError("Incorrect format of version please check MOBILE_API.xml. " "Need format of minVersion major_version.minor_version or major_version.minor_version.patch_version") def prepare_data_for_storage(major_version, minor_version, patch_version, minimum_major_version, minimum_minor_version, minimum_patch_version): """Prepares data to store to file. diff --git a/tools/InterfaceGenerator/generator/Model.py b/tools/InterfaceGenerator/generator/Model.py deleted file mode 100755 index e7cce732ed..0000000000 --- a/tools/InterfaceGenerator/generator/Model.py +++ /dev/null @@ -1,354 +0,0 @@ -"""Interface model. - -Interface model is represented by Interface class. -Parser must provide an instance of this model as a result of parsing -interface definition file. -Generator must take an instance of this model as input for generating -output files. -""" - -# In this module there are classes that are used as data container -# pylint: disable=R0903 - -import collections - - -class Boolean(object): - - """Boolean type. - - default_value -- default value - - """ - - def __init__(self, default_value=None): - self.default_value = default_value - - -class Integer(object): - - """Integer type. - - Instance variables: - min_value -- minimum allowed value - max_value -- maximum allowed value - default_value -- default value - - """ - - def __init__(self, min_value=None, max_value=None, default_value=None): - self.min_value = min_value - self.max_value = max_value - self.default_value = default_value - - -class Double(object): - - """Floating-point type. - - Instance variables: - min_value -- minimum allowed value - max_value -- maximum allowed value - default_value -- default value - - """ - - def __init__(self, min_value=None, max_value=None, default_value=None): - self.min_value = min_value - self.max_value = max_value - self.default_value = default_value - -class String(object): - - """String type. - - Instance variables: - min_length -- minimum string length - max_length -- maximum string length - default_value -- default value - - """ - - def __init__(self, min_length=None, max_length=None, default_value=None): - self.min_length = min_length - self.max_length = max_length - self.default_value = default_value - - -class Array(object): - - """Array type. - - Instance variables: - min_size -- minimum array size - max_size -- maximum array size - element_type -- type of array element - - """ - - def __init__(self, min_size=None, max_size=None, element_type=None): - self.min_size = min_size - self.max_size = max_size - self.element_type = element_type - - -class Issue(object): - - """Issue. - - Instance variables: - creator -- issue creator - value -- issue text - - """ - - def __init__(self, creator=None, value=None): - self.creator = creator - self.value = value - - -class InterfaceItemBase(object): - - """Base class for interface item. - - Instance variables: - name -- item name - description -- list of string description elements - design_description -- list of string design description elements - issues -- list of issues - todos -- list of string todo elements - platform -- optional platform (string or None) - default_value -- default value - scope -- optional scope: internal, partner or none (none by defaul, means public) - - """ - - def __init__(self, name, description=None, design_description=None, - issues=None, todos=None, platform=None, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None, history=None): - self.name = name - self.description = description if description is not None else [] - self.design_description = \ - design_description if design_description is not None else [] - self.issues = issues if issues is not None else [] - self.todos = todos if todos is not None else [] - self.platform = platform - self.default_value = default_value - self.scope = scope - self.since = since - self.until = until - self.deprecated = deprecated - self.removed = removed - self.history = history - - -class EnumElement(InterfaceItemBase): - - """Element of enumeration. - - Instance variables: - internal_name -- internal name of an element must be used by a - generator if it is provided (not None) - value -- optional element value - - """ - - def __init__(self, name, description=None, design_description=None, - issues=None, todos=None, platform=None, internal_name=None, - value=None, since=None, until=None, deprecated=None, removed=None, history=None): - super(EnumElement, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, history=history) - self.internal_name = internal_name - self.value = value - self.since = since - self.until = until - self.deprecated = deprecated - self.removed = removed - - - @property - def primary_name(self): - """Primary name of the EnumElement. - - Return the 'internal_name' property if presented or 'name' property - otherwise. - - """ - return self.name if self.internal_name is None else self.internal_name - - -class Enum(InterfaceItemBase): - - """Enumeration. - - Instance variables: - internal_scope -- optional internal scope - elements -- enumeration elements - - """ - - def __init__(self, name, description=None, design_description=None, - issues=None, todos=None, platform=None, internal_scope=None, - elements=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None): - super(Enum, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, scope=scope, history=history) - - self.internal_scope = internal_scope - self.elements = \ - elements if elements is not None else collections.OrderedDict() - self.since = since - self.until = until - self.deprecated = deprecated - self.removed = removed - - -class EnumSubset(InterfaceItemBase): - - """Enumeration subset. - - Instance variables: - enum -- enumeration - allowed_elements -- dictionary of elements of enumeration - which are allowed in this subset - - """ - - def __init__(self, name, enum, description=None, design_description=None, - issues=None, todos=None, platform=None, - allowed_elements=None, since=None, until=None, deprecated=None, removed=None, history=None): - super(EnumSubset, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, history=history) - - self.enum = enum - self.allowed_elements = \ - allowed_elements if allowed_elements is not None else {} - self.since = since - self.until = until - self.deprecated = deprecated - self.removed = removed - - -class Param(InterfaceItemBase): - - """Parameter. - - Instance variables: - is_mandatory -- boolean value indicating whether - this parameter is mandatory - param_type -- parameter type - default_value -- default value - - """ - - def __init__(self, name, param_type, description=None, - design_description=None, issues=None, todos=None, - platform=None, is_mandatory=True, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None, history=None): - super(Param, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, default_value=default_value, scope=scope, history=history) - - self.is_mandatory = is_mandatory - self.param_type = param_type - self.default_value = default_value - self.since = since - self.until = until - self.deprecated = deprecated - self.removed=removed - - -class FunctionParam(Param): - - """Function parameter. - - Instance variables: - default_value -- optional default value of this parameter - - """ - - def __init__(self, name, param_type, description=None, - design_description=None, issues=None, todos=None, - platform=None, is_mandatory=True, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None, history=None): - super(FunctionParam, self).__init__( - name, param_type=param_type, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, is_mandatory=is_mandatory, default_value=default_value, - scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history) - - self.default_value = default_value - - -class Struct(InterfaceItemBase): - - """Structure. - - Instance variables: - members -- dictionary of structure members (instances of Param class) - - """ - - def __init__(self, name, description=None, design_description=None, - issues=None, todos=None, platform=None, members=None, scope=None, - since=None, until=None, deprecated=None, removed=None, history=None): - super(Struct, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, scope=scope, since=since, until=until, - deprecated=deprecated, removed=removed, history=history) - - self.members = \ - members if members is not None else collections.OrderedDict() - - -class Function(InterfaceItemBase): - - """Function. - - Instance variables: - function_id -- function identifier (EnumElement from Enum "FunctionID") - message_type -- message type (EnumElement from Enum "messageType") - params -- function parameters - - """ - - def __init__(self, name, function_id, message_type, description=None, - design_description=None, issues=None, todos=None, - platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None): - super(Function, self).__init__( - name, description=description, - design_description=design_description, issues=issues, todos=todos, - platform=platform, scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history) - - self.function_id = function_id - self.message_type = message_type - self.params = \ - params if params is not None else collections.OrderedDict() - - -class Interface(object): - - """Interface. - - Instance variables: - enums -- dictionary of enumerations - structs -- dictionary of structures - functions -- dictionary of functions - params -- dictionary of interface parameters (name, version, etc.) - - """ - - def __init__(self, enums=None, structs=None, functions=None, params=None): - self.enums = enums if enums is not None else collections.OrderedDict() - self.structs = \ - structs if structs is not None else collections.OrderedDict() - self.functions = \ - functions if functions is not None else collections.OrderedDict() - self.params = params if params is not None else {} diff --git a/tools/InterfaceGenerator/generator/generators/PolicyTypes.py b/tools/InterfaceGenerator/generator/generators/PolicyTypes.py index 2621950e7a..53c3062f30 100644 --- a/tools/InterfaceGenerator/generator/generators/PolicyTypes.py +++ b/tools/InterfaceGenerator/generator/generators/PolicyTypes.py @@ -7,13 +7,14 @@ accordance with given internal model. # pylint: disable=W0402 # pylint: disable=C0302 import codecs -import collections import os import string import uuid import re -from generator import Model +from model.enum import Enum +from model.enum_element import EnumElement +from model.function import Function class GenerateError(Exception): @@ -106,10 +107,10 @@ class CodeGenerator(object): for func in interface.functions.values(): for param in func.params: params_set.add(param) - parameter_enum = Model.Enum('Parameter') + parameter_enum = Enum('Parameter') for item in params_set: - parameter_enum.elements[item.upper()] = Model.EnumElement(item) + parameter_enum.elements[item.upper()] = EnumElement(item) required_enums_for_policy = [ @@ -162,13 +163,11 @@ class CodeGenerator(object): "Parameter" : "Parameter" } - get_first_enum_value_name = lambda enum : enum.elements.values()[0].name - enum_required_for_policy = lambda enum : enum.name in required_enums_for_policy and "." not in get_first_enum_value_name(enum) # In case if "." is in FunctionID name this is HMI_API function ID and should not be included in Policy enums - required_enum_values = [val for val in interface.enums.values() - if enum_required_for_policy(val)] + required_enum_values = list(filter(lambda e: e.name in required_enums_for_policy + and "." not in list(e.elements.values())[0].name, list(interface.enums.values()))) if filename == "MOBILE_API": self._write_cc_with_enum_schema_factory(filename, namespace, destination_dir, interface.enums.values()) @@ -190,7 +189,7 @@ class CodeGenerator(object): encoding="utf-8", mode="w") as f_cc: guard = u"_{0}_{1}_CC__".format( class_name.upper(), - unicode(uuid.uuid1().hex.capitalize())) + uuid.uuid1().hex.capitalize()) namespace_open, namespace_close = self._namespaces_strings(namespace) includes = '''#include <set>\n'''\ '''#include "interfaces/MOBILE_API.h"\n'''\ @@ -212,7 +211,7 @@ class CodeGenerator(object): encoding="utf-8", mode="w") as f_h: guard = u"_{0}_{1}_H__".format( class_name.upper(), - unicode(uuid.uuid1().hex.capitalize())) + uuid.uuid1().hex.capitalize()) namespace_open, namespace_close = self._namespaces_strings(namespace) f_h.write(self._h_file_template.substitute( class_name=class_name, @@ -233,7 +232,7 @@ class CodeGenerator(object): encoding="utf-8", mode="w") as f_cc: guard = u"_{0}_{1}_CC__".format( class_name.upper(), - unicode(uuid.uuid1().hex.capitalize())) + uuid.uuid1().hex.capitalize()) namespace_open, namespace_close = self._namespaces_strings(namespace) f_cc.write(self._cc_file_template.substitute( class_name=class_name, @@ -257,7 +256,6 @@ class CodeGenerator(object): Tuple with namespace open string and namespace close string """ - namespace = unicode(namespace) namespace_open = u"" namespace_close = u"" if namespace: @@ -432,7 +430,7 @@ class CodeGenerator(object): interface_item_base_classname) name = interface_item_base.primary_name if \ - type(interface_item_base) is Model.EnumElement else \ + type(interface_item_base) is EnumElement else \ interface_item_base.name brief_description = (u" * @brief {0}{1}.\n" if use_doxygen is True else u"// {0}{1}.\n").format( @@ -475,7 +473,7 @@ class CodeGenerator(object): True else u"//\n", todos]) returns = u"" - if type(interface_item_base) is Model.Function: + if type(interface_item_base) is Function: returns = u"".join([u" *\n", self._function_return_comment]) template = self._comment_doxygen_template if use_doxygen is \ diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py index 6cd60a7dfc..de0067bba8 100755 --- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py +++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py @@ -12,7 +12,17 @@ import os import string import uuid -from generator import Model +from model.array import Array +from model.boolean import Boolean +from model.float import Float +from model.enum import Enum +from model.enum_element import EnumElement +from model.enum_subset import EnumSubset +from model.function import Function +from model.integer import Integer +from model.param import Param +from model.string import String +from model.struct import Struct class GenerateError(Exception): @@ -56,8 +66,6 @@ class CodeGenerator(object): """ - namespace = unicode(namespace) - if interface is None: raise GenerateError("Given interface is None.") @@ -84,10 +92,10 @@ class CodeGenerator(object): [namespace_close, "}} // {0}\n".format(part)]) - class_name = unicode(os.path.splitext(filename)[0]) + class_name = os.path.splitext(filename)[0] guard = u"__CSMARTFACTORY_{0}_{1}_H__".format( class_name.upper(), - unicode(uuid.uuid1().hex.capitalize())) + uuid.uuid1().hex.capitalize()) header_file_name = u"".join("{0}.h".format(class_name)) with codecs.open(os.path.join(destination_dir, header_file_name), @@ -127,14 +135,14 @@ class CodeGenerator(object): header_file_name = "".join("{0}_schema.h".format(class_name)) guard = u"__CSMARTFACTORY_{0}_{1}_HPP__".format( class_name.upper(), - unicode(uuid.uuid1().hex.capitalize())) + uuid.uuid1().hex.capitalize()) with codecs.open(os.path.join(destination_dir, header_file_name), encoding="utf-8", mode="w") as f_h: f_h.write(self._hpp_schema_file_template.substitute( class_name=class_name, guard=guard, - header_file_name=unicode("".join("{0}.h".format(class_name))), + header_file_name="".join("{0}.h".format(class_name)), namespace_open=namespace_open, class_content=self._gen_h_class( class_name, @@ -147,7 +155,7 @@ class CodeGenerator(object): u"".join("{0}_schema.cc".format(class_name))), encoding="utf-8", mode="w") as f_s: f_s.write(self._cc_file_template.substitute( - header_file_name=unicode(header_file_name), + header_file_name=header_file_name, namespace=namespace, class_name=class_name, function_id_items=self._indent_code(function_id_items, 1), @@ -382,7 +390,7 @@ class CodeGenerator(object): """ - if type(member.param_type) is Model.Struct: + if type(member.param_type) is Struct: self._ensure_struct_generated(member.param_type) def _ensure_struct_generated(self, struct): @@ -618,7 +626,7 @@ class CodeGenerator(object): result = u"" for member in members: - if type(member.param_type) is Model.Enum and \ + if type(member.param_type) is Enum and \ member.param_type.name not in processed_enums: has_history = self._enum_has_history_present(member) local_var = self._gen_schema_loc_emum_var_name( @@ -678,7 +686,7 @@ class CodeGenerator(object): processed_enums.append(member.param_type.name) result = u"".join([result, u"\n\n"]) if result else u"" - elif type(member.param_type) is Model.EnumSubset: + elif type(member.param_type) is EnumSubset: local_var = self._gen_schema_loc_emum_s_var_name(member.name) result = u"\n".join( [u"".join( @@ -695,12 +703,12 @@ class CodeGenerator(object): for x in member.param_type. allowed_elements.values()])]) result = u"".join([result, u"\n\n"]) if result else u"" - elif type(member.param_type) is Model.Array: + elif type(member.param_type) is Array: result = u"".join( [result, self._gen_schema_loc_decls( - [Model.Param(name=member.param_type.element_type.name + [Param(name=member.param_type.element_type.name if type(member.param_type.element_type) is - Model.EnumSubset else "", + EnumSubset else "", param_type=member.param_type.element_type)], processed_enums)]) @@ -793,13 +801,13 @@ class CodeGenerator(object): """ code = u"" - if type(param) is Model.Boolean: + if type(param) is Boolean: code = self._impl_code_bool_item_template.substitute( params=self._gen_schema_item_param_values( [[u"bool", None if param.default_value is None else u"true" if param.default_value is True else u"false"]])) - elif type(param) is Model.Integer: - if param.max_value < 2 ** 31: + elif type(param) is Integer: + if not param.max_value or param.max_value and param.max_value < 2 ** 31: code = self._impl_code_integer_item_template.substitute( type=u"int32_t", params=self._gen_schema_item_param_values( @@ -815,14 +823,14 @@ class CodeGenerator(object): [u"int64_t", param.default_value]])) else: raise GenerateError("Parameter value too large: " + str(param.max_value)) - elif type(param) is Model.Double: + elif type(param) is Float: code = self._impl_code_integer_item_template.substitute( type=u"double", params=self._gen_schema_item_param_values( [[u"double", param.min_value], [u"double", param.max_value], [u"double", param.default_value]])) - elif type(param) is Model.String: + elif type(param) is String: code = self._impl_code_string_item_template.substitute( params=self._gen_schema_item_param_values( [[u"size_t", param.min_length], @@ -830,23 +838,23 @@ class CodeGenerator(object): [u"std::string", u"".join( [u'"', param.default_value, u'"']) if param.default_value is not None else u""]])) - elif type(param) is Model.Array: + elif type(param) is Array: code = self._impl_code_array_item_template.substitute( params=u"".join( [u"".join( [self._gen_schema_item_decl_code( param.element_type, param.element_type.name if type(param.element_type) - is Model.EnumSubset else u"", + is EnumSubset else u"", None), u", "]), self._gen_schema_item_param_values( [[u"size_t", param.min_size], [u"size_t", param.max_size]])])) - elif type(param) is Model.Struct: + elif type(param) is Struct: code = self._impl_code_struct_item_template.substitute( name=param.name) - elif type(param) is Model.Enum: + elif type(param) is Enum: if self._enum_param_type_has_history_present(param): code = self._impl_code_enum_item_with_history_template.substitute( type=param.name, @@ -871,7 +879,7 @@ class CodeGenerator(object): u"".join([param.name, u"::", default_value.primary_name]) if default_value is not None else None]])])) - elif type(param) is Model.EnumSubset: + elif type(param) is EnumSubset: code = self._impl_code_enum_item_template.substitute( type=param.enum.name, params=u"".join( @@ -1046,7 +1054,7 @@ class CodeGenerator(object): deprecated=member.deprecated if member.deprecated is not None else u"false", removed=member.removed if member.removed is not None else u"false") else: - print "Warning! History item does not have any version history. Omitting %s" % member.name + print("Warning! History item does not have any version history. Omitting " + member.name) @staticmethod def _gen_schema_item_var_name(member): @@ -1175,11 +1183,11 @@ class CodeGenerator(object): if structs: struct_id_enum_elements = collections.OrderedDict() for struct in structs: - struct_id_enum_elements[struct.name] = Model.EnumElement( + struct_id_enum_elements[struct.name] = EnumElement( name=struct.name) return u"\n".join( [self._gen_enum( - Model.Enum(name="StructIdentifiers", + Enum(name="StructIdentifiers", elements=struct_id_enum_elements)), u"\n".join([self._gen_enum(x) for x in enums])]) @@ -1198,8 +1206,8 @@ class CodeGenerator(object): """ - enum_elements = enum.elements.values() - enum_elements.insert(0, Model.EnumElement( + enum_elements = list(enum.elements.values()) + enum_elements.insert(0, EnumElement( name=u"INVALID_ENUM", description=None, design_description=None, @@ -1300,7 +1308,7 @@ class CodeGenerator(object): interface_item_base_classname) name = interface_item_base.primary_name if \ - type(interface_item_base) is Model.EnumElement else \ + type(interface_item_base) is EnumElement else \ interface_item_base.name brief_description = (u" * @brief {0}{1}.\n" if use_doxygen is True else u"// {0}{1}.\n").format( @@ -1343,7 +1351,7 @@ class CodeGenerator(object): True else u"//\n", todos]) returns = u"" - if type(interface_item_base) is Model.Function: + if type(interface_item_base) is Function: returns = u"".join([u" *\n", self._function_return_comment]) template = self._comment_doxygen_template if use_doxygen is \ diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryJSONRPC.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryJSONRPC.py index 07b55382a6..f7241af30c 100755 --- a/tools/InterfaceGenerator/generator/generators/SmartFactoryJSONRPC.py +++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryJSONRPC.py @@ -6,7 +6,7 @@ Defines JSONRPC format specific code generation rules. import string from generator.generators import SmartFactoryBase -from generator import Model +from model.enum_element import EnumElement class CodeGenerator(SmartFactoryBase.CodeGenerator): @@ -40,7 +40,7 @@ class CodeGenerator(SmartFactoryBase.CodeGenerator): code = u"" for function in functions: - if unicode(function.message_type.primary_name) == u"response": + if function.message_type.primary_name == u"response": code = u"".join( [code, self._error_response_insert_template.substitute( function_id=function.function_id.primary_name)]) @@ -66,7 +66,7 @@ class CodeGenerator(SmartFactoryBase.CodeGenerator): """ if "response" in message_type.elements: - message_type.elements[u"error_response"] = Model.EnumElement( + message_type.elements[u"error_response"] = EnumElement( name=u"error_response") return message_type @@ -88,9 +88,9 @@ class CodeGenerator(SmartFactoryBase.CodeGenerator): return u"".join( [self._base_params, self._correlation_id_param - if unicode(message_type_name) != u"notification" else u"", + if message_type_name != u"notification" else u"", self._additional_response_params - if unicode(message_type_name) == u"response" else u""]) + if message_type_name == u"response" else u""]) _error_response_insert_template = string.Template( u'''functions_schemes_.insert(std::make_pair(''' diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactorySDLRPC.py b/tools/InterfaceGenerator/generator/generators/SmartFactorySDLRPC.py index f82c7bb808..ef5cf9286b 100755 --- a/tools/InterfaceGenerator/generator/generators/SmartFactorySDLRPC.py +++ b/tools/InterfaceGenerator/generator/generators/SmartFactorySDLRPC.py @@ -83,5 +83,5 @@ class CodeGenerator(SmartFactoryBase.CodeGenerator): u'''strings::S_CORRELATION_ID] = SMember(TNumberSchemaItem<int>::create(), true);\n''' return u"".join([base_params, correlation_id_param - if unicode(message_type_name) != + if message_type_name != u"notification" else u""]) diff --git a/tools/InterfaceGenerator/generator/parsers/JSONRPC.py b/tools/InterfaceGenerator/generator/parsers/JSONRPC.py index 52aa5a1048..e63bcc38aa 100755 --- a/tools/InterfaceGenerator/generator/parsers/JSONRPC.py +++ b/tools/InterfaceGenerator/generator/parsers/JSONRPC.py @@ -4,14 +4,17 @@ Contains parser for JSON RPC XML format. """ -from generator import Model -from generator.parsers import RPCBase -import xml.etree.ElementTree as ET +from parsers.parse_error import ParseError +from parsers.rpc_base import RPCBase -class Parser(RPCBase.Parser): +class Parser(RPCBase): """JSON RPC parser.""" + @property + def get_version(self): + return '1.0.0' + def __init__(self): """Constructor.""" super(Parser, self).__init__() @@ -33,11 +36,11 @@ class Parser(RPCBase.Parser): for element in root: if element.tag != "interface": - raise RPCBase.ParseError("Subelement '" + element.tag + - "' is unexpected in interfaces") + raise ParseError("Subelement '" + element.tag + + "' is unexpected in interfaces") if "name" not in element.attrib: - raise RPCBase.ParseError( + raise ParseError( "Name is not specified for interface") self._interface_name = element.attrib["name"] @@ -72,7 +75,7 @@ class Parser(RPCBase.Parser): if "FunctionID" == enum_name: prefix_length = len(self._interface_name) + 1 if element_name[:prefix_length] != self._interface_name + '_': - raise RPCBase.ParseError( + raise ParseError( "Unexpected prefix for function id '" + element_name + "'") name = self._interface_name + "." + element_name[prefix_length:] @@ -95,7 +98,7 @@ class Parser(RPCBase.Parser): """ if function_param_name in ['method', 'code']: - raise RPCBase.ParseError( + raise ParseError( "'" + function_param_name + "' is a predefined name and can't be used" + " as a function parameter name") diff --git a/tools/InterfaceGenerator/generator/parsers/RPCBase.py b/tools/InterfaceGenerator/generator/parsers/RPCBase.py deleted file mode 100755 index ac5bb4c858..0000000000 --- a/tools/InterfaceGenerator/generator/parsers/RPCBase.py +++ /dev/null @@ -1,913 +0,0 @@ -"""RPC XML base parser. - -Contains base parser for SDLRPC v1/v2 and JSON RPC XML format. - -""" - -import collections -import xml.etree.ElementTree -import re -from generator import Model - - -class ParseError(Exception): - - """Parse error. - - This exception is raised when XML contains errors and can't be parsed. - - """ - - pass - - -class Parser(object): - - """RPC XML Parser base. - - This class must not be used directly. One of its subclasses must be used - instead. - - """ - - def __init__(self): - """Constructor.""" - self._types = {} - self._enums = collections.OrderedDict() - self._structs = collections.OrderedDict() - self._functions = collections.OrderedDict() - self._params = {} - - def parse(self, filename): - """Parse XML. - - Returns an instance of generator.Model.Interface containing parsed - interface or raises ParseError if input XML contains errors - and can't be parsed. - - Keyword arguments: - filename -- name of input XML file. - - """ - - tree = xml.etree.ElementTree.parse(filename) - root = tree.getroot() - - self._enums = self._initialize_enums() - self._structs = collections.OrderedDict() - self._functions = collections.OrderedDict() - self._params = {} - - self._types = dict(self._enums.items()) - - self._parse_root(root) - - return Model.Interface(enums=self._enums, structs=self._structs, - functions=self._functions, params=self._params) - - def _initialize_enums(self): - """Initialize enums. - - The default implementation returns an OrderedDict with two empty - enums: "FunctionID" and "messageType". Required for formats where - these enums must be generated automatically according to the declared - in the XML functions. - - These enums are filled during the parsing of the functions. - - """ - return collections.OrderedDict( - [("FunctionID", Model.Enum(name="FunctionID")), - ("messageType", Model.Enum(name="messageType"))]) - - def _check_enum_name(self, enum): - """Check enum name. - - This method is called to check whether the newly parsed enum's name - conflicts with some predefined enum. - - This implementation raises an error if enum name is one of the - predefined enums "FunctionID" or "messageType" which must not be - declared explicitly in the XML. - - """ - if enum.name in ["FunctionID", "messageType"]: - raise ParseError( - "Enum '" + enum.name + - "' is generated automatically in SDLRPCV1 and" - " must not be declared in xml file") - - def _check_function_param_name(self, function_param_name): - """Check function param name. - - This method is called to check whether the newly parsed function - parameter name conflicts with some predefined name. - - This implementation doesn't check anything because there is no - predefined names in base RPC XML. - """ - - pass - - def _parse_root(self, root): - """Parse root XML element. - - Default implementation parses root as interface element without a - prefix. - - Keyword arguments: - root -- root element. - - """ - - self._parse_interface(root, "") - - def _parse_interface(self, interface, prefix): - """Parse interface element. - - Keyword arguments: - interface -- interface element. - prefix -- string prefix for all types of the interface. - - """ - if interface.tag != "interface": - raise ParseError("Invalid interface tag: " + interface.tag) - - params, subelements, attrib = self._parse_base_item(interface, "") - - for param in ["description", "design_description", "todos"]: - if 0 != len(params[param]): - attrib[param] = "\n".join(params[param]) - - if 0 != len(params["issues"]): - attrib["issues"] = "\n".join(i.value for i in params["issues"]) - - self._params = dict( - self._params.items() + - [(prefix + p[0], p[1]) for p in attrib.items()]) - - for element in subelements: - if element.tag == "enum": - enum = self._parse_enum(element, prefix) - self._check_enum_name(enum) - self._add_item(self._enums, enum) - self._add_type(enum) - elif element.tag == "struct": - struct = self._parse_struct(element, prefix) - self._add_item(self._structs, struct) - self._add_type(struct) - elif element.tag == "function": - function = self._parse_function(element, prefix) - self._add_item(self._functions, function, - (function.function_id, function.message_type)) - else: - raise ParseError("Unexpected element: " + element.tag) - - @staticmethod - def _add_item(items, item, key=None): - """Add new item in the items dictionary with given key. - - Performs additional check for presence in the dictionary and throws - ParseError exception if key already exist. - - """ - if key is None: - key = item.name - - if key in items: - raise ParseError(type(item).__name__ + " '" + str(key) + - "' is declared more than once") - items[key] = item - - def _add_type(self, _type): - """Add new type in the internal types dictionary. - - Performs additional check for presence type with same name in the - dictionary and throws ParseError exception if key already exist. - - """ - if _type.name in self._types: - raise ParseError("Type '" + _type.name + - "' is declared as both struct and enum") - - self._types[_type.name] = _type - - def _parse_enum(self, element, prefix): - """Parse element as enumeration. - - Returns an instance of generator.Model.Enum - - """ - params, subelements, attributes = \ - self._parse_base_item(element, prefix) - - internal_scope = None - scope = None - since = None - until = None - deprecated = None - removed = None - result = None - for attribute in attributes: - if attribute == "internal_scope": - internal_scope = attributes[attribute] - elif attribute == "scope": - scope = attributes[attribute] - elif attribute == "since": - result = self._parse_version(attributes[attribute]) - since = result - elif attribute == "until": - result = self._parse_version(attributes[attribute]) - until = result - elif attribute == "deprecated": - deprecated = attributes[attribute] - elif attribute == "removed": - removed = attributes[attribute] - else: - raise ParseError("Unexpected attribute '" + attribute + - "' in enum '" + params["name"] + "'") - params["internal_scope"] = internal_scope - params["scope"] = scope - params["since"] = since - params["until"] = until - params["deprecated"] = deprecated - params["removed"] = removed - - elements = collections.OrderedDict() - for subelement in subelements: - if subelement.tag == "element": - self._add_item(elements, self._parse_enum_element(subelement)) - else: - raise ParseError("Unexpected element '" + subelement.tag + - "' in enum '" + params["name"] + "'") - params["elements"] = elements - - # Magic usage is correct - # pylint: disable=W0142 - return Model.Enum(**params) - - def _parse_struct(self, element, prefix): - """Parse element as structure. - - Returns an instance of generator.Model.Struct - - """ - params, subelements, attrib = self._parse_base_item(element, prefix) - - scope = None - since = None - until = None - deprecated = None - removed = None - result = None - for attribute in attrib: - if attribute == "scope": - scope = attrib[attribute] - elif attribute == "since": - result = self._parse_version(attrib[attribute]) - since = result - elif attribute == "until": - result = self._parse_version(attrib[attribute]) - until = result - elif attribute == "deprecated": - deprecated = attrib[attribute] - elif attribute == "removed": - removed = attrib[attribute] - else: - raise ParseError("Unexpected attribute '" + attribute + - "' in struct '" + params["name"] + "'") - params["scope"] = scope - params["since"] = since - params["until"] = until - params["deprecated"] = deprecated - params["removed"] = removed - - members = collections.OrderedDict() - for subelement in subelements: - if subelement.tag == "param": - self._add_item(members, self._parse_param(subelement, prefix)) - else: - raise ParseError("Unexpected subelement '" + subelement.name + - "' in struct '" + params["name"] + "'") - params["members"] = members - - # Magic usage is correct - # pylint: disable=W0142 - return Model.Struct(**params) - - def _parse_function(self, element, prefix): - """Parse element as function. - - Returns an instance of generator.Model.Function - - """ - params, subelements, attributes = \ - self._parse_base_item(element, prefix) - - function_id, message_type = self._parse_function_id_type( - params["name"], - attributes) - - scope = None - since = None - until = None - deprecated = None - removed = None - result = None - for attribute in attributes: - if attribute == "scope": - scope = attributes[attribute] - elif attribute == "since": - result = self._parse_version(attributes[attribute]) - since = result - elif attribute == "until": - result = self._parse_version(attributes[attribute]) - until = result - elif attribute == "deprecated": - deprecated = attributes[attribute] - elif attribute == "removed": - removed = attributes[attribute] - - params["function_id"] = function_id - params["message_type"] = message_type - params["scope"] = scope - params["since"] = since - params["until"] = until - params["deprecated"] = deprecated - params["removed"] = removed - - function_params = collections.OrderedDict() - for subelement in subelements: - if subelement.tag == "param": - function_param = self._parse_function_param(subelement, - prefix) - self._check_function_param_name(function_param.name) - if function_param.name in function_params: - raise ParseError("Parameter '" + function_param.name + - "' is specified more than once" + - " for function '" + params["name"] + "'") - function_params[function_param.name] = function_param - else: - raise ParseError("Unexpected subelement '" + subelement.tag + - "' in function '" + params["name"] + "'") - params["params"] = function_params - - # Magic usage is correct - # pylint: disable=W0142 - return Model.Function(**params) - - def _parse_function_id_type(self, function_name, attrib): - """Parse function id and message type according to XML format. - - This implementation takes function name as function id and extracts - attribute "messagetype" as message type and searches them in enums - "FunctionID" and "messageType" adding the missing elements if - necessary. - - Returns function id and message type as an instances of EnumElement. - - """ - if "messagetype" not in attrib: - raise ParseError("No messagetype specified for function '" + - function_name + "'") - - function_id = self._provide_enum_element_for_function( - "FunctionID", - function_name) - - message_type = self._provide_enum_element_for_function( - "messageType", - self._extract_attrib(attrib, "messagetype")) - - return function_id, message_type - - def _provide_enum_element_for_function(self, enum_name, element_name): - """Provide enum element for functions. - - Search an element in an enum and add it if it is missing. - - Returns EnumElement. - - """ - if enum_name not in self._types: - raise ParseError("Enum '" + enum_name + - "' is not initialized") - - enum = self._types[enum_name] - - if not isinstance(enum, Model.Enum): - raise ParseError("'" + enum_name + "' is not an enum") - - if element_name not in enum.elements: - enum.elements[element_name] = Model.EnumElement(name=element_name) - - return enum.elements[element_name] - - def _parse_base_item(self, element, prefix): - """Parse element as base item. - - Returns an params, sub-elements and attributes of the element - - """ - params = {} - - description = [] - design_description = [] - issues = [] - todos = [] - subelements = [] - history = None - warnings = [] - - if "name" not in element.attrib: - raise ParseError("Name is not specified for " + element.tag) - - params["name"] = prefix + element.attrib["name"] - attrib = dict(element.attrib.items()) - del attrib["name"] - - params["platform"] = self._extract_attrib(attrib, "platform") - - for subelement in element: - if subelement.tag == "description": - description.append(self._parse_simple_element(subelement)) - elif subelement.tag == "designdescription": - design_description.append( - self._parse_simple_element(subelement)) - elif subelement.tag == "todo": - todos.append(self._parse_simple_element(subelement)) - elif subelement.tag == "issue": - issues.append(self._parse_issue(subelement)) - elif subelement.tag == "history": - if history is not None: - raise ParseError("Elements can only have one history tag: " + element.tag) - history = self._parse_history(subelement, prefix, element) - elif subelement.tag == "warning": - warnings.append(self._parse_simple_element(subelement)) - else: - subelements.append(subelement) - - params["description"] = description - params["design_description"] = design_description - params["issues"] = issues - params["todos"] = todos - params["history"] = history - - return params, subelements, attrib - - @staticmethod - def _parse_simple_element(element): - """Parse element as simple element and returns it's text. - - Element is simple when it contains no subelements and attributes. - - Returns element text if present or empty string if not - - """ - if len(element) != 0: - raise ParseError("Unexpected subelements in '" + - element.tag + "'") - if len(element.attrib) != 0: - raise ParseError("Unexpected attributes in '" + - element.tag + "'") - return element.text if element.text is not None else "" - - @staticmethod - def _parse_issue(element): - """Parse element as issue. - - Issue must not contain subelements and attributes. - - Returns an instance of generator.Model.Issue - - """ - if len(element) != 0: - raise ParseError("Unexpected subelements in issue") - if "creator" not in element.attrib: - raise ParseError("No creator in issue") - if len(element.attrib) != 1: - raise ParseError("Unexpected attributes in issue") - - return Model.Issue( - creator=element.attrib["creator"], - value=element.text if element.text is not None else "") - - def _parse_enum_element(self, element): - """Parse element as element of enumeration. - - Returns an instance of generator.Model.EnumElement - - """ - params, subelements, attributes = self._parse_base_item(element, "") - - if len(subelements) != 0: - raise ParseError("Unexpected subelements in enum element") - - self._ignore_attribute(attributes, "hexvalue") - self._ignore_attribute(attributes, "scope") - self._ignore_attribute(attributes, "rootscreen") - - internal_name = None - value = None - since = None - until = None - deprecated = None - removed = None - result = None - for attribute in attributes: - if attribute == "internal_name": - internal_name = attributes[attribute] - elif attribute == "value": - try: - value = int(attributes[attribute]) - except: - raise ParseError("Invalid value for enum element: '" + - attributes[attribute] + "'") - elif attribute == "since": - result = self._parse_version(attributes[attribute]) - since = result - elif attribute == "until": - result = self._parse_version(attributes[attribute]) - until = result - elif attribute == "deprecated": - deprecated = attributes[attribute] - elif attribute == "removed": - removed = attributes[attribute] - params["internal_name"] = internal_name - params["value"] = value - params["since"] = since - params["until"] = until - params["deprecated"] = deprecated - params["removed"] = removed - # Magic usage is correct - # pylint: disable=W0142 - return Model.EnumElement(**params) - - def _parse_param(self, element, prefix): - """Parse element as structure parameter. - - Returns an instance of generator.Model.Param - - """ - params, subelements, attrib = \ - self._parse_param_base_item(element, prefix) - - if len(attrib) != 0: - raise ParseError("""Unknown attribute(s) {0} in param {1} - """.format(attrib, params["name"])) - - if len(subelements) != 0: - raise ParseError("Unknown subelements in param '" + - params["name"] + "'") - - # Magic usage is correct - # pylint: disable=W0142 - return Model.Param(**params) - - def _parse_function_param(self, element, prefix): - """Parse element as function parameter. - - Returns an instance of generator.Model.FunctionParam - - """ - params, subelements, attrib = \ - self._parse_param_base_item(element, prefix) - - default_value = None - default_value_string = self._extract_attrib(attrib, "defvalue") - if default_value_string is not None: - param_type = params["param_type"] - if type(param_type) is Model.Boolean: - default_value = \ - self._get_bool_from_string(default_value_string) - elif type(param_type) is Model.Integer: - try: - default_value = int(default_value_string) - except: - raise ParseError("Invalid value for integer: '" + - default_value_string + "'") - elif type(param_type) is Model.Double: - try: - default_value = float(default_value_string) - except: - raise ParseError("Invalid value for float: '" + - default_value_string + "'") - elif type(param_type) is Model.String: - default_value = default_value_string - elif type(param_type) is Model.Enum or \ - type(param_type) is Model.EnumSubset: - if type(param_type) is Model.EnumSubset: - allowed_elements = param_type.allowed_elements - else: - allowed_elements = param_type.elements - if default_value_string not in allowed_elements: - raise ParseError("Default value '" + default_value_string + - "' for parameter '" + params["name"] + - "' is not a member of " + - type(param_type).__name__ + - "'" + params["name"] + "'") - default_value = allowed_elements[default_value_string] - else: - raise ParseError("Default value specified for " + - type(param_type).__name__) - params["default_value"] = default_value - - if len(attrib) != 0: - raise ParseError("Unexpected attributes in parameter '" + - params["name"] + "'") - - if len(subelements) != 0: - raise ParseError("Unexpected subelements in parameter '" + - params["name"] + "'") - - # Magic usage is correct - # pylint: disable=W0142 - return Model.FunctionParam(**params) - - def _parse_param_base_item(self, element, prefix): - """Parse base param items. - - Returns params, other subelements and attributes. - - """ - params, subelements, attrib = self._parse_base_item(element, "") - - since_version = self._extract_attrib(attrib, "since") - if since_version is not None: - result = self._parse_version(since_version) - params["since"] = result - - until_version = self._extract_attrib(attrib, "until") - if until_version is not None: - result = self._parse_version(until_version) - params["until"] = result - - deprecated = self._extract_attrib(attrib, "deprecated") - if deprecated is not None: - params["deprecated"] = deprecated - - removed = self._extract_attrib(attrib, "removed") - if removed is not None: - params["removed"] = removed - - - is_mandatory = self._extract_attrib(attrib, "mandatory") - if is_mandatory is None: - raise ParseError("'mandatory' is not specified for parameter '" + - params["name"] + "'") - - params["is_mandatory"] = self._get_bool_from_string(is_mandatory) - - scope = self._extract_attrib(attrib, "scope") - if scope is not None: - params["scope"] = scope - - default_value = None; - param_type = None - type_name = self._extract_attrib(attrib, "type") - if type_name is None: - raise ParseError("Type is not specified for parameter '" + - params["name"] + "'") - if type_name == "Boolean": - default_value = self._extract_attrib( - attrib, "defvalue") - if default_value != None: - default_value = self._get_bool_from_string(default_value); - param_type = Model.Boolean(default_value=default_value) - elif type_name == "Integer" or \ - type_name == "Float" or \ - type_name == "Double" : - min_value = self._extract_optional_number_attrib( - attrib, "minvalue", int if type_name == "Integer" else float) - max_value = self._extract_optional_number_attrib( - attrib, "maxvalue", int if type_name == "Integer" else float) - default_value = self._extract_optional_number_attrib( - attrib, "defvalue", int if type_name == "Integer" else float) - - param_type = \ - (Model.Integer if type_name == "Integer" else Model.Double)( - min_value=min_value, - max_value=max_value, - default_value=default_value) - elif type_name == "String": - min_length = self._extract_optional_number_attrib( - attrib, "minlength") - # if minlength is not defined default value is 1 - if min_length is None: - min_length = 1 - max_length = self._extract_optional_number_attrib( - attrib, "maxlength") - default_value = self._extract_attrib(attrib, "defvalue") - param_type = Model.String(min_length=min_length, max_length=max_length, default_value=default_value) - else: - if 1 == type_name.count("."): - custom_type_name = type_name.replace(".", "_") - else: - custom_type_name = prefix + type_name - - if custom_type_name in self._types: - param_type = self._types[custom_type_name] - default_value = self._extract_attrib(attrib, "defvalue") - if default_value != None: - if default_value not in param_type.elements: - raise ParseError("Default value '" + default_value + - "' for parameter '" + params["name"] + - "' is not a member of " + - type(param_type).__name__ + - "'" + params["name"] + "'") - default_value = param_type.elements[default_value] - else: - raise ParseError("Unknown type '" + type_name + "'") - - if self._extract_optional_bool_attrib(attrib, "array", False): - min_size = self._extract_optional_number_attrib(attrib, - "minsize") - max_size = self._extract_optional_number_attrib(attrib, - "maxsize") - param_type = Model.Array(element_type=param_type, - min_size=min_size, - max_size=max_size) - - base_type = \ - param_type.element_type if isinstance(param_type, Model.Array) \ - else param_type - - other_subelements = [] - for subelement in subelements: - if subelement.tag == "element": - if type(base_type) is not Model.Enum and \ - type(base_type) is not Model.EnumSubset: - raise ParseError("Elements specified for parameter '" + - params["name"] + "' of type " + - type(base_type).__name__) - if type(base_type) is Model.Enum: - base_type = Model.EnumSubset( - name=params["name"], - enum=base_type, - description=params["description"], - design_description=params["design_description"], - issues=params["issues"], - todos=params["todos"], - allowed_elements={}) - if "name" not in subelement.attrib: - raise ParseError( - "Element name is not specified for parameter '" + - params["name"] + "'") - element_name = subelement.attrib["name"] - if len(subelement.attrib) != 1: - raise ParseError("Unexpected attributes for element '" + - element_name + "' of parameter '" + - params["name"]) - children = subelement.getchildren() - for child in children: - if child.tag == "description": - children.remove(child) - if len(children) != 0: - raise ParseError("Unexpected subelements for element '" + - element_name + "' of parameter '" + - params["name"]) - if element_name in base_type.allowed_elements: - raise ParseError("Element '" + element_name + - "' is specified more than once for" + - " parameter '" + params["name"] + "'") - if element_name not in base_type.enum.elements: - raise ParseError("Element '" + element_name + - "' is not a member of enum '" + - base_type.enum.name + "'") - base_type.allowed_elements[element_name] = \ - base_type.enum.elements[element_name] - else: - other_subelements.append(subelement) - - if isinstance(param_type, Model.Array): - param_type.element_type = base_type - else: - param_type = base_type - - params["param_type"] = param_type - if default_value is not None: - params["default_value"] = default_value - - return params, other_subelements, attrib - - def _extract_optional_bool_attrib(self, attrib, name, default): - """Extract boolean attribute with given name. - - Returns value of the attribute. - - """ - value = self._extract_attrib(attrib, name) - - if value is None: - value = default - else: - value = self._get_bool_from_string(value) - - return value - - def _extract_optional_number_attrib(self, attrib, name, _type=int): - """Extract number attribute with given name. - - Returns value of the attribute. - - """ - value = self._extract_attrib(attrib, name) - - if value is not None: - try: - value = _type(value) - except: - raise ParseError("Invlaid value for " + _type.__name__ + - ": '" + value + "'") - - return value - - @staticmethod - def _extract_attrib(attrib, name): - """Extract attribute with given name. - - Returns value of the attribute. - - """ - value = None - - if name in attrib: - value = attrib[name] - del attrib[name] - - return value - - @staticmethod - def _get_bool_from_string(bool_string): - """Convert string representation of boolean to real bool value. - - Returns converted value. - - """ - value = None - - if bool_string in ['0', 'false']: - value = False - elif bool_string in ['1', 'true']: - value = True - else: - raise ParseError("Invalid value for bool: '" + - bool_string + "'") - - return value - - def _ignore_attribute(self, attrib, name): - """To be called when attribute is meaningless in terms - of code generation but it's presence is not issue. - - Removes this attribute from attribute list. - - """ - if name in attrib: - del attrib[name] - return True - - def _parse_version(self, version): - """ - Validates if a version supplied is in the correct - format of Major.Minor.Patch. If Major.Minor format - is supplied, a patch version of 0 will be added to - the end. - """ - p = re.compile('\d+\\.\d+\\.\d+|\d+\\.\d+') - result = p.match(version) - if result == None or (result.end() != len(version)): - raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. " - "Need format of major_version.minor_version or major_version.minor_version.patch_version") - - version_array = version.split(".") - if (len(version_array) == 2): - version_array.append("0") - dot_str = "." - return dot_str.join(version_array) - - def _parse_history(self, history, prefix, parent): - if history.tag != "history": - raise ParseError("Invalid history tag: " + interface.tag) - - items = [] - - for subelement in history: - if subelement.tag == "enum" and parent.tag == "enum": - items.append(self._parse_enum(subelement, prefix)) - elif subelement.tag == "element" and parent.tag == "element": - items.append(self._parse_enum_element(subelement)) - elif subelement.tag == "description" and parent.tag == "description": - items.append(self._parse_simple_element(subelement)) - elif subelement.tag == "struct" and parent.tag == "struct": - items.append(self._parse_struct(subelement, prefix)) - elif subelement.tag == "param" and parent.tag == "param": - items.append(self._parse_function_param(subelement, prefix)) - elif subelement.tag == "function" and parent.tag == "function": - items.append(self._parse_function(subelement, prefix)) - else: - raise ParseError("A history tag must be nested within the element it notes the history for. Fix item: '" + - parent.attrib["name"] + "'") - - return items - diff --git a/tools/InterfaceGenerator/generator/parsers/SDLRPCV1.py b/tools/InterfaceGenerator/generator/parsers/SDLRPCV1.py index 52158ee93b..eacf9d9f09 100755 --- a/tools/InterfaceGenerator/generator/parsers/SDLRPCV1.py +++ b/tools/InterfaceGenerator/generator/parsers/SDLRPCV1.py @@ -3,12 +3,12 @@ Contains parser for SDLRPCV1 XML format. """ +from parsers.rpc_base import RPCBase -from generator.parsers import RPCBase - - -class Parser(RPCBase.Parser): +class Parser(RPCBase): """SDLRPCV1 parser.""" - pass + @property + def get_version(self): + return '1.0.0' diff --git a/tools/InterfaceGenerator/generator/parsers/SDLRPCV2.py b/tools/InterfaceGenerator/generator/parsers/SDLRPCV2.py deleted file mode 100755 index 24974a5527..0000000000 --- a/tools/InterfaceGenerator/generator/parsers/SDLRPCV2.py +++ /dev/null @@ -1,90 +0,0 @@ -"""SDLRPCV2 parser. - -Contains parser for SDLRPCV2 XML format. - -""" - -import collections - -from generator import Model -from generator.parsers import RPCBase -import xml.etree.ElementTree as ET - - -class Parser(RPCBase.Parser): - - """SDLRPCV2 parser.""" - - def _initialize_enums(self): - """Initialize enums. - - This implementation returns empty OrderedDict because in SDLRPCV2 - all enums must be declared explicitly in the XML file. - - """ - return collections.OrderedDict() - - def _check_enum_name(self, enum): - """Check enum name. - - This method is called to check whether the newly parsed enum's name - conflicts with some predefined enum. - As SDLRPCV2 has no predefined enums this implementation does nothing. - - """ - - pass - - def _parse_function_id_type(self, function_name, attrib): - """Parse function id and message type according to XML format. - - This implementation extracts attribute "FunctionID" as function id - and messagetype as message type and searches them in enums - "FunctionID" and "messageType". If at least one of them (or the entire - enum) is missing it raises an error. - - Returns function id and message type as an instances of EnumElement. - - """ - if "functionID" not in attrib: - raise RPCBase.ParseError( - "No functionID specified for function '" + - function_name + "'") - - if "messagetype" not in attrib: - raise RPCBase.ParseError( - "No messagetype specified for function '" + - function_name + "'") - - function_id = self._get_enum_element_for_function( - "FunctionID", - self._extract_attrib(attrib, "functionID")) - message_type = self._get_enum_element_for_function( - "messageType", - self._extract_attrib(attrib, "messagetype")) - - return function_id, message_type - - def _get_enum_element_for_function(self, enum_name, element_name): - """Get enum element with given name from given enumeration. - - Returns an instance of generator.Model.EnumElement. - - """ - if enum_name not in self._types: - raise RPCBase.ParseError( - "Enumeration '" + enum_name + - "' must be declared before any function") - - enum = self._types[enum_name] - - if type(enum) is not Model.Enum: - raise RPCBase.ParseError("'" + enum_name + - "' is not an enumeration") - - if element_name not in enum.elements: - raise RPCBase.ParseError( - "'" + element_name + - "' is not a member of enum '" + enum_name + "'") - - return enum.elements[element_name] diff --git a/tools/InterfaceGenerator/requirements.txt b/tools/InterfaceGenerator/requirements.txt index af21f6cb96..a76759eea6 100644 --- a/tools/InterfaceGenerator/requirements.txt +++ b/tools/InterfaceGenerator/requirements.txt @@ -1,6 +1,3 @@ -flake8 -pep8-naming -pep257 -mccabe +xmlschema pylint -mock
\ No newline at end of file +coverage diff --git a/tools/InterfaceGenerator/test/CodeFormatAndQuality.py b/tools/InterfaceGenerator/test/CodeFormatAndQuality.py new file mode 100755 index 0000000000..d403c821ab --- /dev/null +++ b/tools/InterfaceGenerator/test/CodeFormatAndQuality.py @@ -0,0 +1,39 @@ +# pylint: disable=C0103, C0301, C0115, C0116 +"""Interface model unit test + +""" + +import unittest +from os import walk +from os.path import join +from pathlib import Path + +from pylint.lint import Run + + +class TestCodeFormatAndQuality(unittest.TestCase): + MINIMUM_SCORE = 3.7 + + def setUp(self): + """Searching for all python files to be checked + + """ + self.list_of_files = [] + root = Path(__file__).absolute().parents[1] + for (directory, _, filenames) in walk(root.as_posix()): + self.list_of_files += [join(directory, file) for file in filenames + if file.endswith('.py') and not file.startswith('test')] + self.list_of_files.append('--max-line-length=130') + # self.list_of_files.append('--rcfile=../pylint.ini') + + def test_pylint_conformance(self): + """Performing checks by PyLint + + """ + results = Run(self.list_of_files, do_exit=False) + score = results.linter.stats['global_note'] + self.assertGreaterEqual(score, self.MINIMUM_SCORE) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryBase.py b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryBase.py index aea91f4a45..08f231abe6 100755 --- a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryBase.py +++ b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryBase.py @@ -5,10 +5,21 @@ Verifies common helper functions and produced source code. """ import collections import unittest - -from generator.generators import SmartFactoryBase -from generator import Model - +from pathlib import Path + +import sys + +sys.path.append(Path(__file__).absolute().parents[3].as_posix()) +sys.path.append(Path(__file__).absolute().parents[4].joinpath('rpc_spec/InterfaceParser').as_posix()) +try: + from generator.generators import SmartFactoryBase + from model.enum import Enum + from model.enum_element import EnumElement + from model.issue import Issue + from generator.generators import SmartFactoryBase +except ModuleNotFoundError as error: + print('{}.\nProbably you did not initialize submodule'.format(error)) + sys.exit(1) EXPECTED_RESULT_FULL_COMMENT = u"""/** * @brief Enumeration Test Name. @@ -133,15 +144,14 @@ DESCRIPTION = [u"Description Line1", u"Description Line2"] DESIGN_DESCRIPTION = [u"Design Line1"] -ISSUES = [Model.Issue(value=u"Issue1"), - Model.Issue(value=u"Issue2"), - Model.Issue(value=u"Issue3")] +ISSUES = [Issue(value=u"Issue1"), + Issue(value=u"Issue2"), + Issue(value=u"Issue3")] TODOS = [u"Do1", u"Do2"] class Test(unittest.TestCase): - """Test for SmartFactory base generator. This class holds set of test cases for the SmartFactory base generator. @@ -156,11 +166,11 @@ class Test(unittest.TestCase): """ generator = SmartFactoryBase.CodeGenerator() - enum = Model.Enum(name=u"Test Name", - description=DESCRIPTION, - design_description=DESIGN_DESCRIPTION, - issues=ISSUES, - todos=TODOS) + enum = Enum(name=u"Test Name", + description=DESCRIPTION, + design_description=DESIGN_DESCRIPTION, + issues=ISSUES, + todos=TODOS) self.assertEqual(generator._gen_comment(enum), EXPECTED_RESULT_FULL_COMMENT, "Full comment for enum is invalid") @@ -173,16 +183,16 @@ class Test(unittest.TestCase): """ generator = SmartFactoryBase.CodeGenerator() - enum_element1 = Model.EnumElement(name=u"Element1", - internal_name=u"InternalName", - value=u"10") + enum_element1 = EnumElement(name=u"Element1", + internal_name=u"InternalName", + value=u"10") self.assertEqual( generator._gen_enum_element(enum_element1), EXPECTED_RESULT_ENUM_ELEMENT1, "Short commented enum element with internal name is invalid") - enum_element2 = Model.EnumElement( + enum_element2 = EnumElement( name=u"NO_VALUE_ELEMENT", description=DESCRIPTION, design_description=DESIGN_DESCRIPTION) @@ -198,14 +208,14 @@ class Test(unittest.TestCase): """ generator = SmartFactoryBase.CodeGenerator() - elements = [Model.EnumElement(name=u"name1", - design_description=DESIGN_DESCRIPTION, - todos=TODOS, - value=u"1"), - Model.EnumElement(name=u"name2", - description=DESCRIPTION, - issues=ISSUES, - internal_name=u"internal_name2")] + elements = [EnumElement(name=u"name1", + design_description=DESIGN_DESCRIPTION, + todos=TODOS, + value=u"1"), + EnumElement(name=u"name2", + description=DESCRIPTION, + issues=ISSUES, + internal_name=u"internal_name2")] self.assertEqual(generator._gen_enum_elements(elements), EXPECTED_RESULT_ENUM_ELEMENTS1, "Simple enum elements are invalid") @@ -219,35 +229,35 @@ class Test(unittest.TestCase): generator = SmartFactoryBase.CodeGenerator() elements1 = collections.OrderedDict() - elements1[u"name1"] = Model.EnumElement( + elements1[u"name1"] = EnumElement( name=u"name1", design_description=DESIGN_DESCRIPTION, todos=TODOS, value=u"1") - elements1[u"name2"] = Model.EnumElement( + elements1[u"name2"] = EnumElement( name=u"name2", description=DESCRIPTION, issues=ISSUES, internal_name=u"internal_name2") - enum1 = Model.Enum(name=u"Enum1", - todos=TODOS, - elements=elements1) + enum1 = Enum(name=u"Enum1", + todos=TODOS, + elements=elements1) self.assertEqual(generator._gen_enum(enum1), EXPECTED_RESULT_ENUM1, "Simple enum is invalid") elements2 = collections.OrderedDict() - elements2[u"xxx"] = Model.EnumElement(name=u"xxx", - internal_name=u"val_1") - elements2[u"yyy"] = Model.EnumElement(name=u"yyy", - internal_name=u"val_2", - value=u"100") - elements2[u"zzz"] = Model.EnumElement(name=u"val_3") - - enum2 = Model.Enum(name=u"E2", - elements=elements2) + elements2[u"xxx"] = EnumElement(name=u"xxx", + internal_name=u"val_1") + elements2[u"yyy"] = EnumElement(name=u"yyy", + internal_name=u"val_2", + value=u"100") + elements2[u"zzz"] = EnumElement(name=u"val_3") + + enum2 = Enum(name=u"E2", + elements=elements2) self.assertEqual(generator._gen_enum(enum2), EXPECTED_RESULT_ENUM2, "Long enum is invalid") @@ -279,5 +289,6 @@ class Test(unittest.TestCase): "aaa aaa"]), ["aaa", "1", "bbb", "2", "ccc", "3", "aaa aaa"]) + if __name__ == '__main__': unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryJSONRPC.py b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryJSONRPC.py index 533fe92eb5..d3262c8da2 100755 --- a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryJSONRPC.py +++ b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactoryJSONRPC.py @@ -3,18 +3,36 @@ Verifies format specific functions and produced source code. """ -import collections import codecs +import collections import os import unittest import uuid - -from mock import MagicMock -from mock import call - -from generator.generators import SmartFactoryJSONRPC -from generator import Model - +from pathlib import Path +from unittest.mock import MagicMock +from unittest.mock import call + +import sys + +sys.path.append(Path(__file__).absolute().parents[3].as_posix()) +sys.path.append(Path(__file__).absolute().parents[4].joinpath('rpc_spec/InterfaceParser').as_posix()) +try: + from generator.generators import SmartFactoryJSONRPC + from model.array import Array + from model.boolean import Boolean + from model.float import Float + from model.enum import Enum + from model.enum_element import EnumElement + from model.enum_subset import EnumSubset + from model.function import Function + from model.integer import Integer + from model.interface import Interface + from model.issue import Issue + from model.param import Param + from model.struct import Struct +except ModuleNotFoundError as error: + print('{}.\nProbably you did not initialize submodule'.format(error)) + sys.exit(1) EXPECTED_RESULT_REQUEST = ( u"""params_members[ns_smart_device_link::ns_json_handler::""" @@ -124,15 +142,14 @@ DESCRIPTION = [u"Description Line1", u"Description Line2"] DESIGN_DESCRIPTION = [u"Design Line1"] -ISSUES = [Model.Issue(value=u"Issue1"), - Model.Issue(value=u"Issue2"), - Model.Issue(value=u"Issue3")] +ISSUES = [Issue(value=u"Issue1"), + Issue(value=u"Issue2"), + Issue(value=u"Issue3")] TODOS = [u"Do1", u"Do2"] class Test(unittest.TestCase): - """Test for JSONRPC SmartFactory generator. This class holds set of test cases for the JSONRPC SmartFactory generator. @@ -183,14 +200,14 @@ class Test(unittest.TestCase): generator = SmartFactoryJSONRPC.CodeGenerator() message_type_elements = collections.OrderedDict() - message_type_elements[u"request"] = Model.EnumElement(name=u"request") - message_type_elements[u"response"] = Model.EnumElement( + message_type_elements[u"request"] = EnumElement(name=u"request") + message_type_elements[u"response"] = EnumElement( name=u"response") - message_type_elements[u"notification"] = Model.EnumElement( + message_type_elements[u"notification"] = EnumElement( name=u"notification") - message_type = Model.Enum(name=u"messageType", - elements=message_type_elements) + message_type = Enum(name=u"messageType", + elements=message_type_elements) result_enum = generator._preprocess_message_type(message_type) @@ -199,12 +216,12 @@ class Test(unittest.TestCase): result_enum.elements["error_response"].primary_name) message_type_elements = collections.OrderedDict() - message_type_elements[u"request"] = Model.EnumElement(name=u"request") - message_type_elements[u"notification"] = Model.EnumElement( + message_type_elements[u"request"] = EnumElement(name=u"request") + message_type_elements[u"notification"] = EnumElement( name=u"notification") - message_type = Model.Enum(name=u"messageType", - elements=message_type_elements) + message_type = Enum(name=u"messageType", + elements=message_type_elements) result_enum = generator._preprocess_message_type(message_type) @@ -217,6 +234,7 @@ class Test(unittest.TestCase): function. """ + self.maxDiff = None generator = SmartFactoryJSONRPC.CodeGenerator() @@ -225,16 +243,16 @@ class Test(unittest.TestCase): "Invalid code for empty functions list") message_type_elements = collections.OrderedDict() - message_type_elements[u"request"] = Model.EnumElement(name=u"request") - message_type_elements[u"response"] = Model.EnumElement( + message_type_elements[u"request"] = EnumElement(name=u"request") + message_type_elements[u"response"] = EnumElement( name=u"response") - message_type_elements[u"notification"] = Model.EnumElement( + message_type_elements[u"notification"] = EnumElement( name=u"notification") - message_type = Model.Enum(name=u"messageType", - elements=message_type_elements) + message_type = Enum(name=u"messageType", + elements=message_type_elements) - function1 = Model.Function( + function1 = Function( "func1", function_id=message_type.elements[u"request"], message_type=message_type.elements[u"request"]) @@ -242,18 +260,20 @@ class Test(unittest.TestCase): generator._gen_pre_function_schemas([function1]), "Invalid code for empty functions list") - function2 = Model.Function( + function2 = Function( "func2", function_id=message_type.elements[u"request"], message_type=message_type.elements[u"response"]) - - self.assertEqual(EXPECTED_PRE_FUNCTION_CODE, - generator._gen_pre_function_schemas([function2]), - "Invalid code for single response function") - - self.assertEqual(EXPECTED_PRE_FUNCTION_CODE, - generator._gen_pre_function_schemas([function1, - function2]), - "Invalid code for mixed function list") + try: + self.assertEqual(EXPECTED_PRE_FUNCTION_CODE, + generator._gen_pre_function_schemas([function2]), + "Invalid code for single response function") + + self.assertEqual(EXPECTED_PRE_FUNCTION_CODE, + generator._gen_pre_function_schemas([function1, + function2]), + "Invalid code for mixed function list") + except AssertionError as message: + print(message) def test_full_generation(self): """Test full generation using JSONRPC SmartSchema generator. @@ -264,66 +284,66 @@ class Test(unittest.TestCase): directory as this module. """ - - expected_h_file_content = open("test_expected_jsonrpc.h", "r").read() - expected_cc_file_content = open("test_expected_jsonrpc.cc", "r").read() + self.maxDiff = None + expected_h_file_content = Path(__file__).parents[0].joinpath("test_expected_jsonrpc.h").read_text() + expected_cc_file_content = Path(__file__).parents[0].joinpath("test_expected_jsonrpc.cc").read_text() generator = SmartFactoryJSONRPC.CodeGenerator() message_type_elements = collections.OrderedDict() - message_type_elements[u"request"] = Model.EnumElement(name=u"request") - message_type_elements[u"response"] = Model.EnumElement( + message_type_elements[u"request"] = EnumElement(name=u"request") + message_type_elements[u"response"] = EnumElement( name=u"response") - message_type_elements[u"notification"] = Model.EnumElement( + message_type_elements[u"notification"] = EnumElement( name=u"notification") - message_type = Model.Enum(name=u"messageType", - elements=message_type_elements) + message_type = Enum(name=u"messageType", + elements=message_type_elements) elements1 = collections.OrderedDict() - elements1[u"name1"] = Model.EnumElement( + elements1[u"name1"] = EnumElement( name=u"name1", design_description=DESIGN_DESCRIPTION, todos=TODOS, value=u"1") - elements1[u"name2"] = Model.EnumElement( + elements1[u"name2"] = EnumElement( name="name2", description=DESCRIPTION, issues=ISSUES, internal_name=u"internal_name2") - enum1 = Model.Enum(name=u"Enum1", - todos=TODOS, - elements=elements1) + enum1 = Enum(name=u"Enum1", + todos=TODOS, + elements=elements1) elements2 = collections.OrderedDict() - elements2[u"xxx"] = Model.EnumElement(name=u"xxx", - internal_name=u"val_1") - elements2[u"yyy"] = Model.EnumElement(name=u"yyy", - internal_name=u"val_2", - value=u"100") - elements2[u"zzz"] = Model.EnumElement(name=u"val_3") + elements2[u"xxx"] = EnumElement(name=u"xxx", + internal_name=u"val_1") + elements2[u"yyy"] = EnumElement(name=u"yyy", + internal_name=u"val_2", + value=u"100") + elements2[u"zzz"] = EnumElement(name=u"val_3") - enum2 = Model.Enum(name=u"E2", - elements=elements2) + enum2 = Enum(name=u"E2", + elements=elements2) elements3 = collections.OrderedDict() - elements3["1"] = Model.EnumElement(name="xxx", - internal_name="_1") - elements3["2"] = Model.EnumElement(name="xxx", - internal_name="_2") - elements3["3"] = Model.EnumElement(name="xxx", - internal_name="_3") - enum3 = Model.Enum(name="Enum_new2", - elements=elements3) + elements3["1"] = EnumElement(name="xxx", + internal_name="_1") + elements3["2"] = EnumElement(name="xxx", + internal_name="_2") + elements3["3"] = EnumElement(name="xxx", + internal_name="_3") + enum3 = Enum(name="Enum_new2", + elements=elements3) elements4 = collections.OrderedDict() - elements4["name1"] = Model.EnumElement(name="xxx", - internal_name="_11") - elements4["name2"] = Model.EnumElement(name="xxx", - internal_name="_22") - enum4 = Model.Enum(name="Enum_new4", - elements=elements4) + elements4["name1"] = EnumElement(name="xxx", + internal_name="_11") + elements4["name2"] = EnumElement(name="xxx", + internal_name="_22") + enum4 = Enum(name="Enum_new4", + elements=elements4) enums = collections.OrderedDict() enums["Enum1"] = enum1 @@ -333,7 +353,7 @@ class Test(unittest.TestCase): enums["messageType"] = message_type params1 = collections.OrderedDict() - params1["1"] = Model.FunctionParam( + params1["1"] = Param( name="param1", design_description=DESIGN_DESCRIPTION, description=DESCRIPTION, @@ -341,110 +361,110 @@ class Test(unittest.TestCase): todos=TODOS, param_type=enum4, default_value=elements4["name1"]) - params1["2"] = Model.FunctionParam( + params1["2"] = Param( name="param2", - param_type=Model.EnumSubset( + param_type=EnumSubset( name="sub1", enum=enum1, allowed_elements={"e1": elements1["name1"]}), default_value=elements1["name1"]) functions = collections.OrderedDict() - functions["Function1"] = Model.Function( + functions["Function1"] = Function( name="Function1", function_id=elements1["name1"], message_type=message_type_elements["request"], params=params1) - functions["Function2"] = Model.Function( + functions["Function2"] = Function( name="Function2", function_id=elements2["xxx"], message_type=message_type_elements["response"]) - functions["Function3"] = Model.Function( + functions["Function3"] = Function( name="Function2", function_id=elements2["yyy"], message_type=message_type_elements["notification"]) members1 = collections.OrderedDict() - members1["m1"] = Model.Param(name="intParam", - param_type=Model.Integer(max_value=2)) - members1["m11"] = Model.Param(name="doubleParam", - param_type=Model.Double(min_value=0.333), - is_mandatory=False) - members1["m222"] = Model.Param(name="boolParam", - param_type=Model.Boolean()) - members1["m2"] = Model.Param(name="structParam", - param_type=Model.Struct(name="Struct2")) - members1["aaa"] = Model.Param(name="enumParam", - param_type=enum1) - members1["bbb"] = Model.Param(name="enumParam1", - param_type=enum1) - members1["xxx"] = Model.Param( + members1["m1"] = Param(name="intParam", + param_type=Integer(max_value=2)) + members1["m11"] = Param(name="doubleParam", + param_type=Float(min_value=0.333), + is_mandatory=False) + members1["m222"] = Param(name="boolParam", + param_type=Boolean()) + members1["m2"] = Param(name="structParam", + param_type=Struct(name="Struct2")) + members1["aaa"] = Param(name="enumParam", + param_type=enum1) + members1["bbb"] = Param(name="enumParam1", + param_type=enum1) + members1["xxx"] = Param( name="enumSubset1", - param_type=Model.EnumSubset( + param_type=EnumSubset( name="sub", enum=enum1, allowed_elements={"e1": elements1["name1"]}), is_mandatory=False) - members1["1"] = Model.Param( + members1["1"] = Param( name="arrayOfInt", - param_type=Model.Array(min_size=0, - max_size=20, - element_type=Model.Boolean()), + param_type=Array(min_size=0, + max_size=20, + element_type=Boolean()), is_mandatory=False) - members1["2"] = Model.Param( + members1["2"] = Param( name="arrayOfEnum1", - param_type=Model.Array(min_size=0, - max_size=20, - element_type=enum1), + param_type=Array(min_size=0, + max_size=20, + element_type=enum1), is_mandatory=False) - members1["3"] = Model.Param( + members1["3"] = Param( name="arrayOfEnum3", - param_type=Model.Array(min_size=10, - max_size=40, - element_type=enum3), + param_type=Array(min_size=10, + max_size=40, + element_type=enum3), is_mandatory=True) - members1["4"] = Model.Param( + members1["4"] = Param( name="arrayOfEnum4", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=41, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub1", enum=enum1, allowed_elements={"e1": elements1["name1"]}))) - members1["5"] = Model.Param( + members1["5"] = Param( name="arrayOfEnum5", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=42, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub2", enum=enum1, allowed_elements={"e1": elements1["name2"]}))) - members1["6"] = Model.Param( + members1["6"] = Param( name="arrayOfEnum6", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=43, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub3", enum=enum4, allowed_elements={"e1": elements4["name2"]}))) structs = collections.OrderedDict() - structs["Struct1"] = Model.Struct( + structs["Struct1"] = Struct( name="Struct1", design_description=DESIGN_DESCRIPTION, issues=ISSUES, members=members1) - structs["Struct2"] = Model.Struct(name="Struct2", - issues=ISSUES) + structs["Struct2"] = Struct(name="Struct2", + issues=ISSUES) - interface = Model.Interface(enums=enums, - structs=structs, - functions=functions, - params={"param1": "value1", - "param2": "value2"}) + interface = Interface(enums=enums, + structs=structs, + functions=functions, + params={"param1": "value1", + "param2": "value2"}) os.path.exists = MagicMock(return_value=True) uuid.uuid1 = MagicMock( @@ -468,15 +488,21 @@ class Test(unittest.TestCase): "Invalid header file creation") self.assertEqual(mock_calls[4], - call('/some/test/dir/Test.cc', + call('/some/test/dir/Test_schema.h', mode='w', encoding='utf-8'), "Invalid source file creation") + try: + self.assertSequenceEqual(str(mock_calls[2])[27:-2].replace("\\n", "\n"), + expected_h_file_content, + "Invalid header file content") + + self.assertSequenceEqual(str(mock_calls[6])[27:-2].replace("\\n", "\n"), + expected_cc_file_content, + "Invalid source file content") + except AssertionError as message: + print(message) - self.assertEqual(str(mock_calls[2])[27:-2].replace("\\n", "\n"), - expected_h_file_content, - "Invalid header file content") - self.assertEqual(str(mock_calls[6])[27:-2].replace("\\n", "\n"), - expected_cc_file_content, - "Invalid source file content") +if __name__ == '__main__': + unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactorySDLRPC.py b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactorySDLRPC.py index 3c354cd34b..4b21a64ec1 100755 --- a/tools/InterfaceGenerator/test/generator/generators/test_SmartFactorySDLRPC.py +++ b/tools/InterfaceGenerator/test/generator/generators/test_SmartFactorySDLRPC.py @@ -3,18 +3,36 @@ Verifies format specific functions and produced source code. """ -import collections import codecs +import collections import os import unittest import uuid - -from mock import MagicMock -from mock import call - -from generator.generators import SmartFactorySDLRPC -from generator import Model - +from pathlib import Path +from unittest.mock import MagicMock +from unittest.mock import call + +import sys + +sys.path.append(Path(__file__).absolute().parents[3].as_posix()) +sys.path.append(Path(__file__).absolute().parents[4].joinpath('rpc_spec/InterfaceParser').as_posix()) +try: + from generator.generators import SmartFactorySDLRPC + from model.array import Array + from model.boolean import Boolean + from model.float import Float + from model.enum import Enum + from model.enum_element import EnumElement + from model.enum_subset import EnumSubset + from model.function import Function + from model.integer import Integer + from model.interface import Interface + from model.issue import Issue + from model.param import Param + from model.struct import Struct +except ModuleNotFoundError as error: + print('{}.\nProbably you did not initialize submodule'.format(error)) + sys.exit(1) EXPECTED_NOTIFICATION_RESULT = ( u"""params_members[ns_smart_device_link::ns_json_handler::""" @@ -41,15 +59,14 @@ DESCRIPTION = [u"Description Line1", u"Description Line2"] DESIGN_DESCRIPTION = [u"Design Line1"] -ISSUES = [Model.Issue(value=u"Issue1"), - Model.Issue(value=u"Issue2"), - Model.Issue(value=u"Issue3")] +ISSUES = [Issue(value=u"Issue1"), + Issue(value=u"Issue2"), + Issue(value=u"Issue3")] TODOS = [u"Do1", u"Do2"] class Test(unittest.TestCase): - """Test for SLDRPC SmartFactory generator. This class holds set of test cases for the SDLRPC SmartFactory generator. @@ -107,66 +124,66 @@ class Test(unittest.TestCase): this module. """ - - expected_h_file_content = open("test_expected_sdlrpc.h", "r").read() - expected_cc_file_content = open("test_expected_sdlrpc.cc", "r").read() + self.maxDiff = None + expected_h_file_content = Path(__file__).parents[0].joinpath('test_expected_sdlrpc.h').read_text() + expected_cc_file_content = Path(__file__).parents[0].joinpath('test_expected_sdlrpc.cc').read_text() generator = SmartFactorySDLRPC.CodeGenerator() message_type_elements = collections.OrderedDict() - message_type_elements[u"request"] = Model.EnumElement(name=u"request") - message_type_elements[u"response"] = Model.EnumElement( + message_type_elements[u"request"] = EnumElement(name=u"request") + message_type_elements[u"response"] = EnumElement( name=u"response") - message_type_elements[u"notification"] = Model.EnumElement( + message_type_elements[u"notification"] = EnumElement( name=u"notification") - message_type = Model.Enum(name=u"messageType", - elements=message_type_elements) + message_type = Enum(name=u"messageType", + elements=message_type_elements) elements1 = collections.OrderedDict() - elements1[u"name1"] = Model.EnumElement( + elements1[u"name1"] = EnumElement( name=u"name1", design_description=DESIGN_DESCRIPTION, todos=TODOS, value=u"1") - elements1[u"name2"] = Model.EnumElement( + elements1[u"name2"] = EnumElement( name="name2", description=DESCRIPTION, issues=ISSUES, internal_name=u"internal_name2") - enum1 = Model.Enum(name=u"Enum1", - todos=TODOS, - elements=elements1) + enum1 = Enum(name=u"Enum1", + todos=TODOS, + elements=elements1) elements2 = collections.OrderedDict() - elements2[u"xxx"] = Model.EnumElement(name=u"xxx", - internal_name=u"val_1") - elements2[u"yyy"] = Model.EnumElement(name=u"yyy", - internal_name=u"val_2", - value=u"100") - elements2[u"zzz"] = Model.EnumElement(name=u"val_3") + elements2[u"xxx"] = EnumElement(name=u"xxx", + internal_name=u"val_1") + elements2[u"yyy"] = EnumElement(name=u"yyy", + internal_name=u"val_2", + value=u"100") + elements2[u"zzz"] = EnumElement(name=u"val_3") - enum2 = Model.Enum(name=u"E2", - elements=elements2) + enum2 = Enum(name=u"E2", + elements=elements2) elements3 = collections.OrderedDict() - elements3["1"] = Model.EnumElement(name="xxx", - internal_name="_1") - elements3["2"] = Model.EnumElement(name="xxx", - internal_name="_2") - elements3["3"] = Model.EnumElement(name="xxx", - internal_name="_3") - enum3 = Model.Enum(name="Enum_new2", - elements=elements3) + elements3["1"] = EnumElement(name="xxx", + internal_name="_1") + elements3["2"] = EnumElement(name="xxx", + internal_name="_2") + elements3["3"] = EnumElement(name="xxx", + internal_name="_3") + enum3 = Enum(name="Enum_new2", + elements=elements3) elements4 = collections.OrderedDict() - elements4["name1"] = Model.EnumElement(name="xxx", - internal_name="_11") - elements4["name2"] = Model.EnumElement(name="xxx", - internal_name="_22") - enum4 = Model.Enum(name="Enum_new4", - elements=elements4) + elements4["name1"] = EnumElement(name="xxx", + internal_name="_11") + elements4["name2"] = EnumElement(name="xxx", + internal_name="_22") + enum4 = Enum(name="Enum_new4", + elements=elements4) enums = collections.OrderedDict() enums["Enum1"] = enum1 @@ -176,7 +193,7 @@ class Test(unittest.TestCase): enums["messageType"] = message_type params1 = collections.OrderedDict() - params1["1"] = Model.FunctionParam( + params1["1"] = Param( name="param1", design_description=DESIGN_DESCRIPTION, description=DESCRIPTION, @@ -184,110 +201,110 @@ class Test(unittest.TestCase): todos=TODOS, param_type=enum4, default_value=elements4["name1"]) - params1["2"] = Model.FunctionParam( + params1["2"] = Param( name="param2", - param_type=Model.EnumSubset( + param_type=EnumSubset( name="sub1", enum=enum1, allowed_elements={"e1": elements1["name1"]}), default_value=elements1["name1"]) functions = collections.OrderedDict() - functions["Function1"] = Model.Function( + functions["Function1"] = Function( name="Function1", function_id=elements1["name1"], message_type=message_type_elements["request"], params=params1) - functions["Function2"] = Model.Function( + functions["Function2"] = Function( name="Function2", function_id=elements2["xxx"], message_type=message_type_elements["response"]) - functions["Function3"] = Model.Function( + functions["Function3"] = Function( name="Function2", function_id=elements2["yyy"], message_type=message_type_elements["notification"]) members1 = collections.OrderedDict() - members1["m1"] = Model.Param(name="intParam", - param_type=Model.Integer(max_value=2)) - members1["m11"] = Model.Param(name="doubleParam", - param_type=Model.Double(min_value=0.333), - is_mandatory=False) - members1["m222"] = Model.Param(name="boolParam", - param_type=Model.Boolean()) - members1["m2"] = Model.Param(name="structParam", - param_type=Model.Struct(name="Struct2")) - members1["aaa"] = Model.Param(name="enumParam", - param_type=enum1) - members1["bbb"] = Model.Param(name="enumParam1", - param_type=enum1) - members1["xxx"] = Model.Param( + members1["m1"] = Param(name="intParam", + param_type=Integer(max_value=2)) + members1["m11"] = Param(name="doubleParam", + param_type=Float(min_value=0.333), + is_mandatory=False) + members1["m222"] = Param(name="boolParam", + param_type=Boolean()) + members1["m2"] = Param(name="structParam", + param_type=Struct(name="Struct2")) + members1["aaa"] = Param(name="enumParam", + param_type=enum1) + members1["bbb"] = Param(name="enumParam1", + param_type=enum1) + members1["xxx"] = Param( name="enumSubset1", - param_type=Model.EnumSubset( + param_type=EnumSubset( name="sub", enum=enum1, allowed_elements={"e1": elements1["name1"]}), is_mandatory=False) - members1["1"] = Model.Param( + members1["1"] = Param( name="arrayOfInt", - param_type=Model.Array(min_size=0, - max_size=20, - element_type=Model.Boolean()), + param_type=Array(min_size=0, + max_size=20, + element_type=Boolean()), is_mandatory=False) - members1["2"] = Model.Param( + members1["2"] = Param( name="arrayOfEnum1", - param_type=Model.Array(min_size=0, - max_size=20, - element_type=enum1), + param_type=Array(min_size=0, + max_size=20, + element_type=enum1), is_mandatory=False) - members1["3"] = Model.Param( + members1["3"] = Param( name="arrayOfEnum3", - param_type=Model.Array(min_size=10, - max_size=40, - element_type=enum3), + param_type=Array(min_size=10, + max_size=40, + element_type=enum3), is_mandatory=True) - members1["4"] = Model.Param( + members1["4"] = Param( name="arrayOfEnum4", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=41, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub1", enum=enum1, allowed_elements={"e1": elements1["name1"]}))) - members1["5"] = Model.Param( + members1["5"] = Param( name="arrayOfEnum5", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=42, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub2", enum=enum1, allowed_elements={"e1": elements1["name2"]}))) - members1["6"] = Model.Param( + members1["6"] = Param( name="arrayOfEnum6", - param_type=Model.Array( + param_type=Array( min_size=10, max_size=43, - element_type=Model.EnumSubset( + element_type=EnumSubset( name="sub3", enum=enum4, allowed_elements={"e1": elements4["name2"]}))) structs = collections.OrderedDict() - structs["Struct1"] = Model.Struct( + structs["Struct1"] = Struct( name="Struct1", design_description=DESIGN_DESCRIPTION, issues=ISSUES, members=members1) - structs["Struct2"] = Model.Struct(name="Struct2", - issues=ISSUES) + structs["Struct2"] = Struct(name="Struct2", + issues=ISSUES) - interface = Model.Interface(enums=enums, - structs=structs, - functions=functions, - params={"param1": "value1", - "param2": "value2"}) + interface = Interface(enums=enums, + structs=structs, + functions=functions, + params={"param1": "value1", + "param2": "value2"}) os.path.exists = MagicMock(return_value=True) uuid.uuid1 = MagicMock( @@ -311,15 +328,21 @@ class Test(unittest.TestCase): "Invalid header file creation") self.assertEqual(mock_calls[4], - call('/some/test/dir/Test.cc', + call('/some/test/dir/Test_schema.h', mode='w', encoding='utf-8'), "Invalid source file creation") + try: + self.assertSequenceEqual(str(mock_calls[2])[27:-2].replace("\\n", "\n"), + expected_h_file_content, + "Invalid header file content") + + self.assertSequenceEqual(str(mock_calls[6])[27:-2].replace("\\n", "\n"), + expected_cc_file_content, + "Invalid source file content") + except AssertionError as message: + print(message) - self.assertEqual(str(mock_calls[2])[27:-2].replace("\\n", "\n"), - expected_h_file_content, - "Invalid header file content") - self.assertEqual(str(mock_calls[6])[27:-2].replace("\\n", "\n"), - expected_cc_file_content, - "Invalid source file content") +if __name__ == '__main__': + unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/parsers/test_JSONRPC.py b/tools/InterfaceGenerator/test/generator/parsers/test_JSONRPC.py index f2fecdb901..90700fdbb9 100755 --- a/tools/InterfaceGenerator/test/generator/parsers/test_JSONRPC.py +++ b/tools/InterfaceGenerator/test/generator/parsers/test_JSONRPC.py @@ -1,13 +1,25 @@ """JSONRPC XML parser unit test.""" import os +import sys import unittest - -import generator.Model -import generator.parsers.JSONRPC +from pathlib import Path + +sys.path.append(Path(__file__).absolute().parents[3].as_posix()) +sys.path.append(Path(__file__).absolute().parents[4].joinpath('rpc_spec/InterfaceParser').as_posix()) +try: + import generator.parsers.JSONRPC + from model.array import Array + from model.boolean import Boolean + from model.enum_subset import EnumSubset + from model.integer import Integer + from model.float import Float + from model.string import String +except ModuleNotFoundError as error: + print('{}.\nJSONRPC\tProbably you did not initialize submodule'.format(error)) + sys.exit(1) class TestJSONRPCVParser(unittest.TestCase): - """Test for JSONRPC xml parser.""" class _Issue: @@ -21,7 +33,7 @@ class TestJSONRPCVParser(unittest.TestCase): def setUp(self): """Test initialization.""" self.valid_xml_name = os.path.dirname(os.path.realpath(__file__)) + \ - "/valid_JSONRPC.xml" + "/valid_JSONRPC.xml" self.parser = generator.parsers.JSONRPC.Parser() def test_valid_xml(self): @@ -37,7 +49,7 @@ class TestJSONRPCVParser(unittest.TestCase): "interface1_design_description": "dd", "interface2_attribute": "value", "interface2_description": - "Description of interface2", + "Description of interface2", "interface2_todos": "i2 todo"}, interface.params) @@ -217,7 +229,7 @@ class TestJSONRPCVParser(unittest.TestCase): name="member1", description=["Param1 description"]) self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Integer) + self.assertIsInstance(member.param_type, Integer) self.assertIsNone(member.param_type.min_value) self.assertIsNone(member.param_type.max_value) @@ -226,13 +238,13 @@ class TestJSONRPCVParser(unittest.TestCase): self.verify_base_item(item=member, name="member2", platform="member2 platform") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Boolean) + self.assertIsInstance(member.param_type, Boolean) self.assertIn("member3", struct.members) member = struct.members["member3"] self.verify_base_item(item=member, name="member3") self.assertEqual(False, member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Double) + self.assertIsInstance(member.param_type, Float) self.assertIsNone(member.param_type.min_value) self.assertAlmostEqual(20.5, member.param_type.max_value) @@ -240,11 +252,11 @@ class TestJSONRPCVParser(unittest.TestCase): member = struct.members["member4"] self.verify_base_item(item=member, name="member4") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertIsNone(member.param_type.min_size) self.assertIsNone(member.param_type.max_size) self.assertIsInstance(member.param_type.element_type, - generator.Model.Integer) + Integer) self.assertEqual(11, member.param_type.element_type.min_value) self.assertEqual(100, member.param_type.element_type.max_value) @@ -263,18 +275,18 @@ class TestJSONRPCVParser(unittest.TestCase): member = struct.members["m1"] self.verify_base_item(item=member, name="m1") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.String) + self.assertIsInstance(member.param_type, String) self.assertIsNone(member.param_type.max_length) self.assertIn("m2", struct.members) member = struct.members["m2"] self.verify_base_item(item=member, name="m2") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertEqual(1, member.param_type.min_size) self.assertEqual(50, member.param_type.max_size) self.assertIsInstance(member.param_type.element_type, - generator.Model.String) + String) self.assertEqual(100, member.param_type.element_type.max_length) self.assertIn("m3", struct.members) @@ -287,7 +299,7 @@ class TestJSONRPCVParser(unittest.TestCase): member = struct.members["m4"] self.verify_base_item(item=member, name="m4") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertIsNone(member.param_type.min_size) self.assertEqual(10, member.param_type.max_size) self.assertIs(member.param_type.element_type, @@ -305,7 +317,7 @@ class TestJSONRPCVParser(unittest.TestCase): member = struct.members["m_1"] self.verify_base_item(item=member, name="m_1") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertEqual(1, member.param_type.min_size) self.assertEqual(10, member.param_type.max_size) self.assertIs(member.param_type.element_type, @@ -321,7 +333,7 @@ class TestJSONRPCVParser(unittest.TestCase): member = struct.members["m_3"] self.verify_base_item(item=member, name="m_3") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.String) + self.assertIsInstance(member.param_type, String) self.assertEqual(20, member.param_type.max_length) # Functions @@ -357,9 +369,10 @@ class TestJSONRPCVParser(unittest.TestCase): name="param1", issues=[TestJSONRPCVParser._Issue(creator="", value="")]) self.assertEqual(False, param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.String) + self.assertIsInstance(param.param_type, String) self.assertIsNone(param.param_type.max_length) - self.assertEqual("String default value", param.default_value) + self.assertIsNone(param.default_value) + self.assertEqual("String default value", param.param_type.default_value) self.assertIn("param2", function.params) param = function.params["param2"] @@ -370,7 +383,7 @@ class TestJSONRPCVParser(unittest.TestCase): todos=["Param2 todo"], platform="param2 platform") self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Integer) + self.assertIsInstance(param.param_type, Integer) self.assertIsNone(param.param_type.min_value) self.assertIsNone(param.param_type.max_value) self.assertIsNone(param.default_value) @@ -418,16 +431,18 @@ class TestJSONRPCVParser(unittest.TestCase): self.verify_base_item(item=param, name="p2") self.assertTrue(param.is_mandatory) self.assertIs(param.param_type, interface.enums["interface1_enum1"]) - self.assertIs( - param.default_value, - interface.enums["interface1_enum1"].elements["element2"]) + self.assertIsNone(param.default_value) + self.assertIsNone(param.param_type.default_value) + self.assertIs(param.param_type.elements["element2"], + interface.enums["interface1_enum1"].elements["element2"]) self.assertIn("p3", function.params) param = function.params["p3"] self.verify_base_item(item=param, name="p3", design_description=[""]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Boolean) - self.assertEqual(False, param.default_value) + self.assertIsInstance(param.param_type, Boolean) + self.assertIsNone(param.default_value) + self.assertFalse(param.param_type.default_value) # Function notification "interface1_Function2" @@ -454,14 +469,14 @@ class TestJSONRPCVParser(unittest.TestCase): param = function.params["n1"] self.verify_base_item(item=param, name="n1", todos=["n1 todo"]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.EnumSubset) + self.assertIsInstance(param.param_type, EnumSubset) self.assertIs(param.param_type.enum, interface.enums["interface1_enum1"]) self.assertDictEqual( {"element2": - interface.enums["interface1_enum1"].elements["element2"], + interface.enums["interface1_enum1"].elements["element2"], "element3": - interface.enums["interface1_enum1"].elements["element3"]}, + interface.enums["interface1_enum1"].elements["element3"]}, param.param_type.allowed_elements) self.assertIsNone(param.default_value) @@ -469,18 +484,18 @@ class TestJSONRPCVParser(unittest.TestCase): param = function.params["n2"] self.verify_base_item(item=param, name="n2", todos=["n2 todo"]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Array) + self.assertIsInstance(param.param_type, Array) self.assertEqual(1, param.param_type.min_size) self.assertEqual(100, param.param_type.max_size) self.assertIsInstance(param.param_type.element_type, - generator.Model.EnumSubset) + EnumSubset) self.assertIs(param.param_type.element_type.enum, interface.enums["interface1_enum1"]) self.assertDictEqual( {"element1": - interface.enums["interface1_enum1"].elements["element1"], + interface.enums["interface1_enum1"].elements["element1"], "element3": - interface.enums["interface1_enum1"].elements["element3"]}, + interface.enums["interface1_enum1"].elements["element3"]}, param.param_type.element_type.allowed_elements) self.assertIsNone(param.default_value) @@ -521,7 +536,7 @@ class TestJSONRPCVParser(unittest.TestCase): param = function.params["param2"] self.verify_base_item(item=param, name="param2") self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Array) + self.assertIsInstance(param.param_type, Array) self.assertEqual(5, param.param_type.min_size) self.assertEqual(25, param.param_type.max_size) self.assertIs(param.param_type.element_type, @@ -555,14 +570,14 @@ class TestJSONRPCVParser(unittest.TestCase): param = function.params["param"] self.verify_base_item(item=param, name="param") self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.EnumSubset) + self.assertIsInstance(param.param_type, EnumSubset) self.assertIs(param.param_type.enum, interface.enums["interface2_enum2"]) self.assertDictEqual( {"element2": - interface.enums["interface2_enum2"].elements["element2"], + interface.enums["interface2_enum2"].elements["element2"], "element3": - interface.enums["interface2_enum2"].elements["element3"]}, + interface.enums["interface2_enum2"].elements["element3"]}, param.param_type.allowed_elements) self.assertIsNone(param.default_value) @@ -591,5 +606,6 @@ class TestJSONRPCVParser(unittest.TestCase): """Return provided list or empty list if None is provided.""" return list if list is not None else [] + if __name__ == "__main__": unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV1.py b/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV1.py index 1464658ff4..b039473c24 100755 --- a/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV1.py +++ b/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV1.py @@ -1,13 +1,25 @@ """SDLRPCV1 XML parser unit test.""" import os +import sys import unittest - -import generator.Model -import generator.parsers.SDLRPCV1 +from pathlib import Path + +sys.path.append(Path(__file__).absolute().parents[3].as_posix()) +sys.path.append(Path(__file__).absolute().parents[4].joinpath('rpc_spec/InterfaceParser').as_posix()) +try: + import generator.parsers.SDLRPCV1 + from model.array import Array + from model.boolean import Boolean + from model.enum_subset import EnumSubset + from model.float import Float + from model.integer import Integer + from model.string import String +except ModuleNotFoundError as error: + print('{}.\nProbably you did not initialize submodule'.format(error)) + sys.exit(1) class TestSDLRPCV1Parser(unittest.TestCase): - """Test for SDLRPCV1 xml parser.""" class _Issue: @@ -21,7 +33,7 @@ class TestSDLRPCV1Parser(unittest.TestCase): def setUp(self): """Test initialization.""" self.valid_xml_name = os.path.dirname(os.path.realpath(__file__)) + \ - "/valid_SDLRPCV1.xml" + "/valid_SDLRPCV1.xml" self.parser = generator.parsers.SDLRPCV1.Parser() def test_valid_xml(self): @@ -150,7 +162,7 @@ class TestSDLRPCV1Parser(unittest.TestCase): name="member1", description=["Param1 description"]) self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Integer) + self.assertIsInstance(member.param_type, Integer) self.assertIsNone(member.param_type.min_value) self.assertIsNone(member.param_type.max_value) @@ -159,13 +171,13 @@ class TestSDLRPCV1Parser(unittest.TestCase): self.verify_base_item(item=member, name="member2", platform="member2 platform") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Boolean) + self.assertIsInstance(member.param_type, Boolean) self.assertIn("member3", struct.members) member = struct.members["member3"] self.verify_base_item(item=member, name="member3") self.assertEqual(False, member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Double) + self.assertIsInstance(member.param_type, Float) self.assertIsNone(member.param_type.min_value) self.assertAlmostEqual(20.5, member.param_type.max_value) @@ -173,11 +185,11 @@ class TestSDLRPCV1Parser(unittest.TestCase): member = struct.members["member4"] self.verify_base_item(item=member, name="member4") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertIsNone(member.param_type.min_size) self.assertIsNone(member.param_type.max_size) self.assertIsInstance(member.param_type.element_type, - generator.Model.Integer) + Integer) self.assertEqual(11, member.param_type.element_type.min_value) self.assertEqual(100, member.param_type.element_type.max_value) @@ -196,18 +208,18 @@ class TestSDLRPCV1Parser(unittest.TestCase): member = struct.members["m1"] self.verify_base_item(item=member, name="m1") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.String) + self.assertIsInstance(member.param_type, String) self.assertIsNone(member.param_type.max_length) self.assertIn("m2", struct.members) member = struct.members["m2"] self.verify_base_item(item=member, name="m2") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertEqual(1, member.param_type.min_size) self.assertEqual(50, member.param_type.max_size) self.assertIsInstance(member.param_type.element_type, - generator.Model.String) + String) self.assertEqual(100, member.param_type.element_type.max_length) self.assertIn("m3", struct.members) @@ -220,7 +232,7 @@ class TestSDLRPCV1Parser(unittest.TestCase): member = struct.members["m4"] self.verify_base_item(item=member, name="m4") self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) + self.assertIsInstance(member.param_type, Array) self.assertIsNone(member.param_type.min_size) self.assertEqual(10, member.param_type.max_size) self.assertIs(member.param_type.element_type, @@ -258,9 +270,10 @@ class TestSDLRPCV1Parser(unittest.TestCase): name="param1", issues=[TestSDLRPCV1Parser._Issue(creator="", value="")]) self.assertEqual(False, param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.String) + self.assertIsInstance(param.param_type, String) self.assertIsNone(param.param_type.max_length) - self.assertEqual("String default value", param.default_value) + self.assertIsNone(param.default_value) + self.assertEqual("String default value", param.param_type.default_value) self.assertIn("param2", function.params) param = function.params["param2"] @@ -271,7 +284,7 @@ class TestSDLRPCV1Parser(unittest.TestCase): todos=["Param2 todo"], platform="param2 platform") self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Integer) + self.assertIsInstance(param.param_type, Integer) self.assertIsNone(param.param_type.min_value) self.assertIsNone(param.param_type.max_value) self.assertIsNone(param.default_value) @@ -317,15 +330,17 @@ class TestSDLRPCV1Parser(unittest.TestCase): self.verify_base_item(item=param, name="p2") self.assertTrue(param.is_mandatory) self.assertIs(param.param_type, interface.enums["enum1"]) - self.assertIs(param.default_value, - interface.enums["enum1"].elements["element2"]) + self.assertIsNone(param.default_value) + self.assertIsNone(param.param_type.default_value) + self.assertIs(param.param_type.elements["element2"], interface.enums["enum1"].elements["element2"]) self.assertIn("p3", function.params) param = function.params["p3"] self.verify_base_item(item=param, name="p3", design_description=[""]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Boolean) - self.assertEqual(False, param.default_value) + self.assertIsInstance(param.param_type, Boolean) + self.assertIsNone(param.default_value) + self.assertFalse(param.param_type.default_value) # Function notification "Function2" @@ -351,7 +366,7 @@ class TestSDLRPCV1Parser(unittest.TestCase): param = function.params["n1"] self.verify_base_item(item=param, name="n1", todos=["n1 todo"]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.EnumSubset) + self.assertIsInstance(param.param_type, EnumSubset) self.assertIs(param.param_type.enum, interface.enums["enum1"]) self.assertDictEqual( {"element2": interface.enums["enum1"].elements["element2"], @@ -363,11 +378,11 @@ class TestSDLRPCV1Parser(unittest.TestCase): param = function.params["n2"] self.verify_base_item(item=param, name="n2", todos=["n2 todo"]) self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Array) + self.assertIsInstance(param.param_type, Array) self.assertEqual(1, param.param_type.min_size) self.assertEqual(100, param.param_type.max_size) self.assertIsInstance(param.param_type.element_type, - generator.Model.EnumSubset) + EnumSubset) self.assertIs(param.param_type.element_type.enum, interface.enums["enum1"]) self.assertDictEqual( @@ -400,5 +415,6 @@ class TestSDLRPCV1Parser(unittest.TestCase): """Return provided list or empty list if None is provided.""" return list if list is not None else [] + if __name__ == "__main__": unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV2.py b/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV2.py deleted file mode 100755 index c37962cfe6..0000000000 --- a/tools/InterfaceGenerator/test/generator/parsers/test_SDLRPCV2.py +++ /dev/null @@ -1,417 +0,0 @@ -"""SDLRPCV2 XML parser unit test.""" -import os -import unittest - -import generator.Model -import generator.parsers.SDLRPCV2 - - -class TestSDLRPCV2Parser(unittest.TestCase): - - """Test for SDLRPCV2 xml parser.""" - - class _Issue: - def __init__(self, creator, value): - self.creator = creator - self.value = value - - def __eq__(self, other): - return self.creator == other.creator and self.value == other.value - - def setUp(self): - """Test initialization.""" - self.valid_xml_name = os.path.dirname(os.path.realpath(__file__)) + \ - "/valid_SDLRPCV2.xml" - self.parser = generator.parsers.SDLRPCV2.Parser() - - def test_valid_xml(self): - """Test parsing of valid xml.""" - interface = self.parser.parse(self.valid_xml_name) - - self.assertEqual(2, len(interface.params)) - self.assertDictEqual({"attribute1": "value1", "attribute2": "value2"}, - interface.params) - - # Enumerations - - self.assertEqual(3, len(interface.enums)) - - # Enumeration "FunctionID" - - self.assertIn("FunctionID", interface.enums) - enum = interface.enums["FunctionID"] - self.verify_base_item(item=enum, - name="FunctionID", - description=["Description string 1", - "Description string 2"], - todos=['Function id todo']) - self.assertIsNone(enum.internal_scope) - - self.assertEqual(2, len(enum.elements)) - - self.assertIn("Function1_id", enum.elements) - element = enum.elements["Function1_id"] - self.verify_base_item( - item=element, - name="Function1_id", - design_description=["Function1 element design description"]) - self.assertIsNone(element.internal_name) - self.assertEqual(10, element.value) - - self.assertIn("Function2_id", enum.elements) - element = enum.elements["Function2_id"] - self.verify_base_item( - item=element, - name="Function2_id") - self.assertEqual("Function2_internal", element.internal_name) - self.assertIsNone(element.value) - - # Enumeration "messageType" - - self.assertIn("messageType", interface.enums) - enum = interface.enums["messageType"] - self.verify_base_item( - item=enum, - name="messageType", - design_description=["messageType design description", - "messageType design description 2"], - issues=[TestSDLRPCV2Parser._Issue( - creator="messageType issue creator", - value="Issue text")]) - self.assertIsNone(enum.internal_scope) - - self.assertEqual(3, len(enum.elements)) - - self.assertIn("request", enum.elements) - element = enum.elements["request"] - self.verify_base_item(item=element, - name="request", - todos=["request todo 1", "request todo 2"], - issues=[TestSDLRPCV2Parser._Issue( - creator="issue creator", - value="request issue")]) - self.assertIsNone(element.internal_name) - self.assertEqual(0, element.value) - - self.assertIn("response", enum.elements) - element = enum.elements["response"] - self.verify_base_item(item=element, name="response") - self.assertIsNone(element.internal_name) - self.assertEqual(1, element.value) - - self.assertIn("notification", enum.elements) - element = enum.elements["notification"] - self.verify_base_item(item=element, name="notification") - self.assertIsNone(element.internal_name) - self.assertEqual(2, element.value) - - # Enumeration "enum1" - - self.assertIn("enum1", interface.enums) - enum = interface.enums["enum1"] - self.verify_base_item(item=enum, name="enum1", - platform="enum1 platform") - self.assertEqual("scope", enum.internal_scope) - - self.assertEqual(3, len(enum.elements)) - - self.assertIn("element1", enum.elements) - element = enum.elements["element1"] - self.verify_base_item(item=element, name="element1") - self.assertIsNone(element.internal_name) - self.assertEqual(10, element.value) - - self.assertIn("element2", enum.elements) - element = enum.elements["element2"] - self.verify_base_item(item=element, name="element2") - self.assertEqual("element2_internal", element.internal_name) - self.assertEqual(11, element.value) - - self.assertIn("element3", enum.elements) - element = enum.elements["element3"] - self.verify_base_item( - item=element, - name="element3", - design_description=["Element design description"], - platform="element3 platform") - self.assertIsNone(element.internal_name) - self.assertIsNone(element.value) - - # Structures - - self.assertEqual(2, len(interface.structs)) - - # Structure "struct1" - - self.assertIn("struct1", interface.structs) - struct = interface.structs["struct1"] - self.verify_base_item( - item=struct, - name="struct1", - description=["Struct description"], - issues=[TestSDLRPCV2Parser._Issue(creator="creator1", - value="Issue1"), - TestSDLRPCV2Parser._Issue(creator="creator2", - value="Issue2")]) - - self.assertEqual(4, len(struct.members)) - - self.assertIn("member1", struct.members) - member = struct.members["member1"] - self.verify_base_item( - item=member, - name="member1", - description=["Param1 description"]) - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Integer) - self.assertIsNone(member.param_type.min_value) - self.assertIsNone(member.param_type.max_value) - - self.assertIn("member2", struct.members) - member = struct.members["member2"] - self.verify_base_item(item=member, name="member2", - platform="member2 platform") - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Boolean) - - self.assertIn("member3", struct.members) - member = struct.members["member3"] - self.verify_base_item(item=member, name="member3") - self.assertEqual(False, member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Double) - self.assertIsNone(member.param_type.min_value) - self.assertAlmostEqual(20.5, member.param_type.max_value) - - self.assertIn("member4", struct.members) - member = struct.members["member4"] - self.verify_base_item(item=member, name="member4") - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) - self.assertIsNone(member.param_type.min_size) - self.assertIsNone(member.param_type.max_size) - self.assertIsInstance(member.param_type.element_type, - generator.Model.Integer) - self.assertEqual(11, member.param_type.element_type.min_value) - self.assertEqual(100, member.param_type.element_type.max_value) - - # Structure "struct2" - - self.assertIn("struct2", interface.structs) - struct = interface.structs["struct2"] - self.verify_base_item(item=struct, - name="struct2", - description=["Description of struct2"], - platform="struct2 platform") - - self.assertEqual(4, len(struct.members)) - - self.assertIn("m1", struct.members) - member = struct.members["m1"] - self.verify_base_item(item=member, name="m1") - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.String) - self.assertIsNone(member.param_type.max_length) - - self.assertIn("m2", struct.members) - member = struct.members["m2"] - self.verify_base_item(item=member, name="m2") - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) - self.assertEqual(1, member.param_type.min_size) - self.assertEqual(50, member.param_type.max_size) - self.assertIsInstance(member.param_type.element_type, - generator.Model.String) - self.assertEqual(100, member.param_type.element_type.max_length) - - self.assertIn("m3", struct.members) - member = struct.members["m3"] - self.verify_base_item(item=member, name="m3") - self.assertTrue(member.is_mandatory) - self.assertIs(member.param_type, interface.enums["enum1"]) - - self.assertIn("m4", struct.members) - member = struct.members["m4"] - self.verify_base_item(item=member, name="m4") - self.assertTrue(member.is_mandatory) - self.assertIsInstance(member.param_type, generator.Model.Array) - self.assertIsNone(member.param_type.min_size) - self.assertEqual(10, member.param_type.max_size) - self.assertIs(member.param_type.element_type, - interface.structs["struct1"]) - - # Functions - - self.assertEqual(3, len(interface.functions)) - - # Function request "Function1" - - self.assertIn( - (interface.enums["FunctionID"].elements["Function1_id"], - interface.enums["messageType"].elements["request"]), - interface.functions) - function = interface.functions[ - (interface.enums["FunctionID"].elements["Function1_id"], - interface.enums["messageType"].elements["request"])] - self.verify_base_item( - item=function, - name="Function1", - description=["Description of request Function1"], - todos=["Function1 request todo"]) - self.assertIs(function.function_id, - interface.enums["FunctionID"].elements["Function1_id"]) - self.assertIs(function.message_type, - interface.enums["messageType"].elements["request"]) - - self.assertEqual(3, len(function.params)) - - self.assertIn("param1", function.params) - param = function.params["param1"] - self.verify_base_item( - item=param, - name="param1", - issues=[TestSDLRPCV2Parser._Issue(creator="", value="")]) - self.assertEqual(False, param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.String) - self.assertIsNone(param.param_type.max_length) - self.assertEqual("String default value", param.default_value) - - self.assertIn("param2", function.params) - param = function.params["param2"] - self.verify_base_item( - item=param, - name="param2", - description=["Param2 description", ""], - todos=["Param2 todo"], - platform="param2 platform") - self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Integer) - self.assertIsNone(param.param_type.min_value) - self.assertIsNone(param.param_type.max_value) - self.assertIsNone(param.default_value) - - self.assertIn("param3", function.params) - param = function.params["param3"] - self.verify_base_item(item=param, name="param3") - self.assertEqual(False, param.is_mandatory) - self.assertIs(param.param_type, interface.structs["struct1"]) - self.assertIsNone(param.default_value) - - # Function response "Function1" - - self.assertIn( - (interface.enums["FunctionID"].elements["Function1_id"], - interface.enums["messageType"].elements["response"]), - interface.functions) - function = interface.functions[ - (interface.enums["FunctionID"].elements["Function1_id"], - interface.enums["messageType"].elements["response"])] - self.verify_base_item( - item=function, - name="Function1", - issues=[TestSDLRPCV2Parser._Issue(creator="c1", value=""), - TestSDLRPCV2Parser._Issue(creator="c2", value="")], - platform="") - self.assertIs(function.function_id, - interface.enums["FunctionID"].elements["Function1_id"]) - self.assertIs(function.message_type, - interface.enums["messageType"].elements["response"]) - - self.assertEqual(3, len(function.params)) - - self.assertIn("p1", function.params) - param = function.params["p1"] - self.verify_base_item(item=param, name="p1") - self.assertTrue(param.is_mandatory) - self.assertIs(param.param_type, interface.enums["enum1"]) - self.assertIsNone(param.default_value) - - self.assertIn("p2", function.params) - param = function.params["p2"] - self.verify_base_item(item=param, name="p2") - self.assertTrue(param.is_mandatory) - self.assertIs(param.param_type, interface.enums["enum1"]) - self.assertIs(param.default_value, - interface.enums["enum1"].elements["element2"]) - - self.assertIn("p3", function.params) - param = function.params["p3"] - self.verify_base_item(item=param, name="p3", design_description=[""]) - self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Boolean) - self.assertEqual(False, param.default_value) - - # Function notification "Function2" - - self.assertIn( - (interface.enums["FunctionID"].elements["Function2_id"], - interface.enums["messageType"].elements["notification"]), - interface.functions) - function = interface.functions[ - (interface.enums["FunctionID"].elements["Function2_id"], - interface.enums["messageType"].elements["notification"])] - self.verify_base_item(item=function, - name="Function2", - description=["Function2 description"], - platform="function2 platform") - self.assertIs(function.function_id, - interface.enums["FunctionID"].elements["Function2_id"]) - self.assertIs(function.message_type, - interface.enums["messageType"].elements["notification"]) - - self.assertEqual(3, len(function.params)) - - self.assertIn("n1", function.params) - param = function.params["n1"] - self.verify_base_item(item=param, name="n1", todos=["n1 todo"]) - self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.EnumSubset) - self.assertIs(param.param_type.enum, interface.enums["enum1"]) - self.assertDictEqual( - {"element2": interface.enums["enum1"].elements["element2"], - "element3": interface.enums["enum1"].elements["element3"]}, - param.param_type.allowed_elements) - self.assertIsNone(param.default_value) - - self.assertIn("n2", function.params) - param = function.params["n2"] - self.verify_base_item(item=param, name="n2", todos=["n2 todo"]) - self.assertTrue(param.is_mandatory) - self.assertIsInstance(param.param_type, generator.Model.Array) - self.assertEqual(1, param.param_type.min_size) - self.assertEqual(100, param.param_type.max_size) - self.assertIsInstance(param.param_type.element_type, - generator.Model.EnumSubset) - self.assertIs(param.param_type.element_type.enum, - interface.enums["enum1"]) - self.assertDictEqual( - {"element1": interface.enums["enum1"].elements["element1"], - "element3": interface.enums["enum1"].elements["element3"]}, - param.param_type.element_type.allowed_elements) - self.assertIsNone(param.default_value) - - self.assertIn("n3", function.params) - param = function.params["n3"] - self.verify_base_item(item=param, name="n3") - self.assertEqual(False, param.is_mandatory) - self.assertIs(param.param_type, interface.structs["struct2"]) - self.assertIsNone(param.default_value) - - def verify_base_item(self, item, name, description=None, - design_description=None, issues=None, todos=None, - platform=None): - """Verify base interface item variables.""" - self.assertEqual(name, item.name) - self.assertSequenceEqual(self.get_list(description), item.description) - self.assertSequenceEqual(self.get_list(design_description), - item.design_description) - self.assertSequenceEqual(self.get_list(issues), item.issues) - self.assertSequenceEqual(self.get_list(todos), item.todos) - self.assertEqual(platform, item.platform) - - @staticmethod - def get_list(list=None): - """Return provided list or empty list if None is provided.""" - return list if list is not None else [] - -if __name__ == "__main__": - unittest.main() diff --git a/tools/InterfaceGenerator/test/generator/parsers/valid_JSONRPC.xml b/tools/InterfaceGenerator/test/generator/parsers/valid_JSONRPC.xml index a754e5714e..a964ce6e92 100644 --- a/tools/InterfaceGenerator/test/generator/parsers/valid_JSONRPC.xml +++ b/tools/InterfaceGenerator/test/generator/parsers/valid_JSONRPC.xml @@ -2,7 +2,7 @@ <interfaces attr1="v1" attr2="v2"> <interface name="interface1" attribute1="value1" attribute2="value2"> <struct name="struct1"> - <param name="member1" type="Integer"> + <param name="member1" type="Integer" mandatory="true"> <description>Param1 description</description> </param> <issue creator="creator1">Issue1</issue> @@ -10,7 +10,7 @@ <param name="member3" type="Float" maxvalue="20.5" mandatory="false"/> <description>Struct description</description> <issue creator="creator2">Issue2</issue> - <param name="member4" type="Integer" minvalue="11" maxvalue="100" array="true"/> + <param name="member4" type="Integer" minvalue="11" maxvalue="100" array="true" mandatory="true"/> </struct> <issue creator="c">Issue1</issue> <function name="Function1" messagetype="request"> @@ -18,7 +18,7 @@ <param name="param1" type="String" mandatory="false" defvalue="String default value"> <issue creator=""/> </param> - <param name="param2" type="Integer" platform="param2 platform"> + <param name="param2" type="Integer" platform="param2 platform" mandatory="true"> <description>Param2 description</description> <todo>Param2 todo</todo> <description/> @@ -36,29 +36,29 @@ <designdescription>dd</designdescription> <issue creator="c">Issue2</issue> <function name="Function1" messagetype="response" platform=""> - <param name="p1" type="enum1"/> + <param name="p1" type="enum1" mandatory="true"/> <issue creator="c1"/> - <issue creator="c2"></issue> - <param name="p2" type="enum1" defvalue="element2"/> - <param name="p3" type="Boolean" defvalue="false"> + <issue creator="c2"/> + <param name="p2" type="enum1" defvalue="element2" mandatory="true"/> + <param name="p3" type="Boolean" defvalue="false" mandatory="true"> <designdescription/> </param> </function> <struct name="struct2" platform="struct2 platform"> <description>Description of struct2</description> - <param name="m1" type="String"/> - <param name="m2" type="String" maxlength="100" array="true" minsize="1" maxsize="50"/> - <param name="m3" type="enum1"/> - <param name="m4" type="struct1" array="true" maxsize="10"/> + <param name="m1" type="String" mandatory="true"/> + <param name="m2" type="String" maxlength="100" array="true" minsize="1" maxsize="50" mandatory="true"/> + <param name="m3" type="enum1" mandatory="true"/> + <param name="m4" type="struct1" array="true" maxsize="10" mandatory="true"/> </struct> <function name="Function2" messagetype="notification" platform="function2 platform"> <description>Function2 description</description> - <param name="n1" type="enum1"> + <param name="n1" type="enum1" mandatory="true"> <element name="element2"/> <element name="element3"/> <todo>n1 todo</todo> </param> - <param name="n2" type="enum1" array="true" minsize="1" maxsize="100"> + <param name="n2" type="enum1" array="true" minsize="1" maxsize="100" mandatory="true"> <element name="element3"/> <todo>n2 todo</todo> <element name="element1"/> @@ -79,22 +79,22 @@ <element name="element3"/> </enum> <struct name="struct1"> - <param name="m_1" type="enum1" minsize="1" maxsize="10" array="true"/> - <param name="m_2" type="enum2"/> - <param name="m_3" type="String" maxlength="20"/> + <param name="m_1" type="enum1" minsize="1" maxsize="10" array="true" mandatory="true"/> + <param name="m_2" type="enum2" mandatory="true"/> + <param name="m_3" type="String" maxlength="20" mandatory="true"/> </struct> <function name="Function1" messagetype="request"> <param name="param1" type="enum1" mandatory="false"/> - <param name="param2" type="struct1" array="true" minsize="5" maxsize="25"/> + <param name="param2" type="struct1" array="true" minsize="5" maxsize="25" mandatory="true"/> </function> <todo>i2 todo</todo> <function name="Function1" messagetype="notification" platform="platform"> <issue creator="c">Issue text</issue> - <param name="param" type="enum2"> + <param name="param" type="enum2" mandatory="true"> <element name="element2"/> <element name="element3"/> </param> - <param name="i1" type="interface1.struct2"/> + <param name="i1" type="interface1.struct2" mandatory="true"/> </function> </interface> </interfaces>
\ No newline at end of file diff --git a/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV1.xml b/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV1.xml index 37ebf39d3a..05a83c5834 100644 --- a/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV1.xml +++ b/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV1.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <interface name="test_interface" attribute1="value1" attribute2="value2"> <struct name="struct1"> - <param name="member1" type="Integer"> + <param name="member1" type="Integer" mandatory="true"> <description>Param1 description</description> </param> <issue creator="creator1">Issue1</issue> @@ -9,14 +9,14 @@ <param name="member3" type="Float" maxvalue="20.5" mandatory="false"/> <description>Struct description</description> <issue creator="creator2">Issue2</issue> - <param name="member4" type="Integer" minvalue="11" maxvalue="100" array="true"/> + <param name="member4" type="Integer" minvalue="11" maxvalue="100" array="true" mandatory="true"/> </struct> - <function name="Function1" messagetype="request"> + <function name="Function1" functionID="Function1_id" messagetype="request"> <description>Description of request Function1</description> <param name="param1" type="String" mandatory="false" defvalue="String default value"> <issue creator=""/> </param> - <param name="param2" type="Integer" platform="param2 platform"> + <param name="param2" type="Integer" platform="param2 platform" mandatory="true"> <description>Param2 description</description> <todo>Param2 todo</todo> <description/> @@ -31,30 +31,30 @@ <designdescription>Element design description</designdescription> </element> </enum> - <function name="Function1" messagetype="response" platform=""> - <param name="p1" type="enum1"/> + <function name="Function1" functionID="Function1_id" messagetype="response" platform=""> + <param name="p1" type="enum1" mandatory="true"/> <issue creator="c1"/> - <issue creator="c2"></issue> - <param name="p2" type="enum1" defvalue="element2"/> - <param name="p3" type="Boolean" defvalue="false"> + <issue creator="c2"/> + <param name="p2" type="enum1" defvalue="element2" mandatory="true"/> + <param name="p3" type="Boolean" defvalue="false" mandatory="true"> <designdescription/> </param> </function> <struct name="struct2" platform="struct2 platform"> <description>Description of struct2</description> - <param name="m1" type="String"/> - <param name="m2" type="String" maxlength="100" array="true" minsize="1" maxsize="50"/> - <param name="m3" type="enum1"/> - <param name="m4" type="struct1" array="true" maxsize="10"/> + <param name="m1" type="String" mandatory="true"/> + <param name="m2" type="String" maxlength="100" array="true" minsize="1" maxsize="50" mandatory="true"/> + <param name="m3" type="enum1" mandatory="true"/> + <param name="m4" type="struct1" array="true" maxsize="10" mandatory="true"/> </struct> - <function name="Function2" messagetype="notification" platform="function2 platform"> + <function name="Function2" functionID="Function2_id" messagetype="notification" platform="function2 platform"> <description>Function2 description</description> - <param name="n1" type="enum1"> + <param name="n1" type="enum1" mandatory="true"> <element name="element2"/> <element name="element3"/> <todo>n1 todo</todo> </param> - <param name="n2" type="enum1" array="true" minsize="1" maxsize="100"> + <param name="n2" type="enum1" array="true" minsize="1" maxsize="100" mandatory="true"> <element name="element3"/> <todo>n2 todo</todo> <element name="element1"/> diff --git a/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV2.xml b/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV2.xml deleted file mode 100644 index cdc5f1ae85..0000000000 --- a/tools/InterfaceGenerator/test/generator/parsers/valid_SDLRPCV2.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0"?> -<interface name="test_interface" attribute1="value1" attribute2="value2"> - <enum name="FunctionID"> - <description>Description string 1</description> - <element name="Function1_id" value="10"> - <designdescription>Function1 element design description</designdescription> - </element> - <description>Description string 2</description> - <todo>Function id todo</todo> - <element name="Function2_id" internal_name="Function2_internal"/> - </enum> - <enum name="messageType"> - <element name="request" value="0"> - <todo>request todo 1</todo> - <issue creator="issue creator">request issue</issue> - <todo>request todo 2</todo> - </element> - <designdescription>messageType design description</designdescription> - <issue creator="messageType issue creator">Issue text</issue> - <element name="response" value="1"/> - <element name="notification" value="2"/> - <designdescription>messageType design description 2</designdescription> - </enum> - <struct name="struct1"> - <param name="member1" type="Integer"> - <description>Param1 description</description> - </param> - <issue creator="creator1">Issue1</issue> - <param name="member2" type="Boolean" mandatory="true" platform="member2 platform"/> - <param name="member3" type="Float" maxvalue="20.5" mandatory="false"/> - <description>Struct description</description> - <issue creator="creator2">Issue2</issue> - <param name="member4" type="Integer" minvalue="11" maxvalue="100" array="true"/> - </struct> - <function name="Function1" functionID="Function1_id" messagetype="request"> - <description>Description of request Function1</description> - <param name="param1" type="String" mandatory="false" defvalue="String default value"> - <issue creator=""/> - </param> - <param name="param2" type="Integer" platform="param2 platform"> - <description>Param2 description</description> - <todo>Param2 todo</todo> - <description/> - </param> - <todo>Function1 request todo</todo> - <param name="param3" type="struct1" mandatory="false"/> - </function> - <enum name="enum1" internal_scope="scope" platform="enum1 platform"> - <element name="element1" value="10"/> - <element name="element2" internal_name="element2_internal" value="11"/> - <element name="element3" platform="element3 platform"> - <designdescription>Element design description</designdescription> - </element> - </enum> - <function name="Function1" functionID="Function1_id" messagetype="response" platform=""> - <param name="p1" type="enum1"/> - <issue creator="c1"/> - <issue creator="c2"></issue> - <param name="p2" type="enum1" defvalue="element2"/> - <param name="p3" type="Boolean" defvalue="false"> - <designdescription/> - </param> - </function> - <struct name="struct2" platform="struct2 platform"> - <description>Description of struct2</description> - <param name="m1" type="String"/> - <param name="m2" type="String" maxlength="100" array="true" minsize="1" maxsize="50"/> - <param name="m3" type="enum1"/> - <param name="m4" type="struct1" array="true" maxsize="10"/> - </struct> - <function name="Function2" functionID="Function2_id" messagetype="notification" platform="function2 platform"> - <description>Function2 description</description> - <param name="n1" type="enum1"> - <element name="element2"/> - <element name="element3"/> - <todo>n1 todo</todo> - </param> - <param name="n2" type="enum1" array="true" minsize="1" maxsize="100"> - <element name="element3"/> - <todo>n2 todo</todo> - <element name="element1"/> - </param> - <param name="n3" type="struct2" mandatory="false"/> - </function> -</interface> diff --git a/tools/InterfaceGenerator/test/generator/test_Model.py b/tools/InterfaceGenerator/test/generator/test_Model.py deleted file mode 100755 index 55f6a54705..0000000000 --- a/tools/InterfaceGenerator/test/generator/test_Model.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Interface model unit test""" -import unittest - -import generator.Model - - -class TestInterfaceModel(unittest.TestCase): - - """Test for interface model.""" - - def test_enum_element_primary_name(self): - """Test property primary_name of EnumElement.""" - element = generator.Model.EnumElement(name="name1") - self.assertEqual("name1", element.primary_name) - - element = generator.Model.EnumElement(name="name2", - internal_name="internal_name1") - self.assertEqual("internal_name1", element.primary_name) - - element.internal_name = None - self.assertEqual("name2", element.primary_name) - - element.internal_name = "internal_name2" - self.assertEqual("internal_name2", element.primary_name) - -if __name__ == "__main__": - unittest.main() diff --git a/tools/InterfaceGenerator/test/test_CodeFormatAndQuality.py b/tools/InterfaceGenerator/test/test_CodeFormatAndQuality.py deleted file mode 100755 index 3ce56e0fae..0000000000 --- a/tools/InterfaceGenerator/test/test_CodeFormatAndQuality.py +++ /dev/null @@ -1,59 +0,0 @@ -import subprocess -import unittest -import flake8.main -import pep257 -import os.path -import fnmatch -import os -import pylint.lint -import sys - -class TestCodeFormatAndQuality(unittest.TestCase): - - def setUp(self): - self.projectRootDir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - projectTestsDir = os.path.join(self.projectRootDir, "test") - self.filesToAnalyze = [] - for root, dirnames, filenames in os.walk(self.projectRootDir): - if root.startswith(projectTestsDir): - continue # Currently we skipping test files - for filename in fnmatch.filter(filenames, '*.py'): - fullFileName = os.path.join(root, filename) - relativeFileName = os.path.relpath(fullFileName, self.projectRootDir) - self.filesToAnalyze.append(relativeFileName) - - def test_pep8_conformance(self): - maxCyclomaticComplexity = 10 - errors = 0 - for file in self.filesToAnalyze: - errors = errors + flake8.main.check_file(file, None, maxCyclomaticComplexity) - - self.assertEqual(errors, 0, "Found code style errors or warnings.") - - def test_pep257_conformance(self): - errors = [] - - for filePath in self.filesToAnalyze: - print("Processing file: {0}".format(filePath)) - result = pep257.check_files([filePath]) - if result: - errors.extend(result) - for error in result: - print(error) - print - self.assertEqual(len(errors), 0, "Found Docstring Conventions violations.") - - def test_pylint_conformance(self): - print - self.assertEqual(0, - subprocess.call( - ["pylint", - '--rcfile=pylint.cfg', - 'generator', - 'Generator.py'] - ), "Found Pylint violations") - return - -if __name__ == '__main__': - unittest.main() - |