示例#1
0
    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
        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] + "'")
        params["internal_name"] = internal_name
        params["value"] = value

        # Magic usage is correct
        # pylint: disable=W0142
        return Model.EnumElement(**params)
    def test_gen_enum(self):
        """Test generation of the enum.

        Verifies correct generation of the enum.

        """
        generator = SmartFactoryBase.CodeGenerator()

        elements1 = collections.OrderedDict()
        elements1[u"name1"] = Model.EnumElement(
            name=u"name1",
            design_description=DESIGN_DESCRIPTION,
            todos=TODOS,
            value=u"1")
        elements1[u"name2"] = Model.EnumElement(
            name=u"name2",
            description=DESCRIPTION,
            issues=ISSUES,
            internal_name=u"internal_name2")

        enum1 = Model.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)
        self.assertEqual(generator._gen_enum(enum2),
                         EXPECTED_RESULT_ENUM2,
                         "Long enum is invalid")

        self.assertEqual(generator._gen_enums([enum1, enum2],
                                              collections.OrderedDict()),
                         u"{0}\n{1}".format(EXPECTED_RESULT_ENUM1,
                                            EXPECTED_RESULT_ENUM2),
                         "Generated enums are invalid")
示例#3
0
    def test_gen_pre_function_schemas(self):
        """Test code that goes before schema initialization.

        Verifies JSONPRC implementation of the _gen_pre_function_schemas
        function.

        """

        generator = SmartFactoryJSONRPC.CodeGenerator()

        self.assertEqual(u"", generator._gen_pre_function_schemas([]),
                         "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(
            name=u"response")
        message_type_elements[u"notification"] = Model.EnumElement(
            name=u"notification")

        message_type = Model.Enum(name=u"messageType",
                                  elements=message_type_elements)

        function1 = Model.Function(
            "func1",
            function_id=message_type.elements[u"request"],
            message_type=message_type.elements[u"request"])

        self.assertEqual(u"", generator._gen_pre_function_schemas([function1]),
                         "Invalid code for empty functions list")

        function2 = Model.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")
    def test_gen_enum_elements(self):
        """Test generation of the enum elements.

        Verifies correct generation of the enum elements.

        """
        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")]
        self.assertEqual(generator._gen_enum_elements(elements),
                         EXPECTED_RESULT_ENUM_ELEMENTS1,
                         "Simple enum elements are invalid")
示例#5
0
    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)
示例#6
0
    def test_preprocess_message_type(self):
        """Test preprocessing of the message_type enum.

        Verifies JSONPRC implementation of the _preprocess_message_type
        function.

        """

        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(
            name=u"response")
        message_type_elements[u"notification"] = Model.EnumElement(
            name=u"notification")

        message_type = Model.Enum(name=u"messageType",
                                  elements=message_type_elements)

        result_enum = generator._preprocess_message_type(message_type)

        self.assertIn("error_response", result_enum.elements)
        self.assertEqual("error_response",
                         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(
            name=u"notification")

        message_type = Model.Enum(name=u"messageType",
                                  elements=message_type_elements)

        result_enum = generator._preprocess_message_type(message_type)

        self.assertNotIn("error_response", result_enum.elements)
    def test_gen_enum_element(self):
        """Test generation of the single enum element.

        Verifies correct generation of the single enum element.

        """
        generator = SmartFactoryBase.CodeGenerator()

        enum_element1 = Model.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(
            name=u"NO_VALUE_ELEMENT",
            description=DESCRIPTION,
            design_description=DESIGN_DESCRIPTION)
        self.assertEqual(generator._gen_enum_element(enum_element2),
                         EXPECTED_RESULT_ENUM_ELEMENT2,
                         "Enum element with no value is invalid")
示例#8
0
    def _preprocess_message_type(self, message_type):
        """Preprocess message_type enum.

        JSON RPC generator needs to add new message_type "error_response" in
        case if at least one response available.

        Keyword arguments:
        message_type -- message_type enum to preprocess.

        Returns:
        Preprocessed message_type enum.

        """

        if "response" in message_type.elements:
            message_type.elements[u"error_response"] = Model.EnumElement(
                name=u"error_response")

        return message_type
示例#9
0
    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]
示例#10
0
    def test_full_generation(self):
        """Test full generation using JSONRPC SmartSchema generator.

        Creates output files which is captured by the mock and compare them
        with sample files with correct code. This test requires valid
        test_expected_jsonrpc.h and test_expected_jsonrpc.cc in the same
        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()

        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(
            name=u"response")
        message_type_elements[u"notification"] = Model.EnumElement(
            name=u"notification")

        message_type = Model.Enum(name=u"messageType",
                                  elements=message_type_elements)

        elements1 = collections.OrderedDict()
        elements1[u"name1"] = Model.EnumElement(
            name=u"name1",
            design_description=DESIGN_DESCRIPTION,
            todos=TODOS,
            value=u"1")
        elements1[u"name2"] = Model.EnumElement(
            name="name2",
            description=DESCRIPTION,
            issues=ISSUES,
            internal_name=u"internal_name2")

        enum1 = Model.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")

        enum2 = Model.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)

        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)

        enums = collections.OrderedDict()
        enums["Enum1"] = enum1
        enums["Enum2"] = enum2
        enums["Enum3"] = enum3
        enums["Enum4"] = enum4
        enums["messageType"] = message_type

        params1 = collections.OrderedDict()
        params1["1"] = Model.FunctionParam(
            name="param1",
            design_description=DESIGN_DESCRIPTION,
            description=DESCRIPTION,
            issues=ISSUES,
            todos=TODOS,
            param_type=enum4,
            default_value=elements4["name1"])
        params1["2"] = Model.FunctionParam(
            name="param2",
            param_type=Model.EnumSubset(
                name="sub1",
                enum=enum1,
                allowed_elements={"e1": elements1["name1"]}),
            default_value=elements1["name1"])

        functions = collections.OrderedDict()
        functions["Function1"] = Model.Function(
            name="Function1",
            function_id=elements1["name1"],
            message_type=message_type_elements["request"],
            params=params1)
        functions["Function2"] = Model.Function(
            name="Function2",
            function_id=elements2["xxx"],
            message_type=message_type_elements["response"])
        functions["Function3"] = Model.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(
            name="enumSubset1",
            param_type=Model.EnumSubset(
                name="sub",
                enum=enum1,
                allowed_elements={"e1": elements1["name1"]}),
            is_mandatory=False)
        members1["1"] = Model.Param(name="arrayOfInt",
                                    param_type=Model.Array(
                                        min_size=0,
                                        max_size=20,
                                        element_type=Model.Boolean()),
                                    is_mandatory=False)
        members1["2"] = Model.Param(name="arrayOfEnum1",
                                    param_type=Model.Array(min_size=0,
                                                           max_size=20,
                                                           element_type=enum1),
                                    is_mandatory=False)
        members1["3"] = Model.Param(name="arrayOfEnum3",
                                    param_type=Model.Array(min_size=10,
                                                           max_size=40,
                                                           element_type=enum3),
                                    is_mandatory=True)
        members1["4"] = Model.Param(
            name="arrayOfEnum4",
            param_type=Model.Array(
                min_size=10,
                max_size=41,
                element_type=Model.EnumSubset(
                    name="sub1",
                    enum=enum1,
                    allowed_elements={"e1": elements1["name1"]})))
        members1["5"] = Model.Param(
            name="arrayOfEnum5",
            param_type=Model.Array(
                min_size=10,
                max_size=42,
                element_type=Model.EnumSubset(
                    name="sub2",
                    enum=enum1,
                    allowed_elements={"e1": elements1["name2"]})))
        members1["6"] = Model.Param(
            name="arrayOfEnum6",
            param_type=Model.Array(
                min_size=10,
                max_size=43,
                element_type=Model.EnumSubset(
                    name="sub3",
                    enum=enum4,
                    allowed_elements={"e1": elements4["name2"]})))

        structs = collections.OrderedDict()
        structs["Struct1"] = Model.Struct(
            name="Struct1",
            design_description=DESIGN_DESCRIPTION,
            issues=ISSUES,
            members=members1)
        structs["Struct2"] = Model.Struct(name="Struct2", issues=ISSUES)

        interface = Model.Interface(enums=enums,
                                    structs=structs,
                                    functions=functions,
                                    params={
                                        "param1": "value1",
                                        "param2": "value2"
                                    })

        os.path.exists = MagicMock(return_value=True)
        uuid.uuid1 = MagicMock(
            return_value=uuid.UUID("12345678123456781234567812345678"))
        codecs.open = MagicMock()

        generator.generate(interface=interface,
                           filename="Test.xml",
                           namespace="XXX::YYY::ZZZ",
                           destination_dir="/some/test/dir")

        os.path.exists.assert_has_calls([call('/some/test/dir')])

        open_result = codecs.open
        mock_calls = open_result.mock_calls

        self.assertEqual(
            mock_calls[0],
            call('/some/test/dir/Test.h', mode='w', encoding='utf-8'),
            "Invalid header file creation")

        self.assertEqual(
            mock_calls[4],
            call('/some/test/dir/Test.cc', mode='w', encoding='utf-8'),
            "Invalid source file creation")

        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")
示例#11
0
    def generate(self, interface, filename, namespace, destination_dir):
        """ Generate SmartFactory source files.

        Generates source code files at destination directory in
        accordance with given model in specified namespace.

        Keyword arguments:
        interface -- model of the interface to generate source code for.
        filename -- name of initial XML file.
        namespace -- name of destination namespace.
        destination_dir -- directory to create source files.

        """

        if interface is None:
            raise GenerateError("Given interface is None.")

        params_set = set()
        for func in interface.functions.values():
            for param in func.params:
                params_set.add(param)
        parameter_enum = Model.Enum('Parameter')

        for item in params_set:
            parameter_enum.elements[item.upper()] = Model.EnumElement(item)

        required_enums_for_policy = [
            "HMILevel", "FunctionID", "HybridAppPreference", "AppHMIType",
            "RequestType", "ModuleType", "Common_AppPriority", "Parameter"
        ]

        self.required_empty_value = ["RequestType", "ModuleType", "Parameter"]

        self.enum_items_naming_conversion_ = {
            "HMILevel":
            lambda item_name: "HL_" + item_name.replace("HMI_", ""),
            "AppHMIType":
            lambda item_name: "AHT_" + item_name,
            "FunctionID":
            lambda item_name: item_name,
            "HybridAppPreference":
            lambda item_name: item_name,
            "RequestType":
            lambda item_name: "RT_" + item_name,
            "ModuleType":
            lambda item_name: "MT_" + item_name,
            "Common_AppPriority":
            lambda item_name: "P_" + item_name
            if not item_name == "VOICE_COMMUNICATION" else "P_VOICECOM",
            "Parameter":
            lambda item_name: "P_" + to_snake_case(item_name).upper()
        }

        self.enum_items_string_naming_conversion_ = {
            "HMILevel":
            lambda item_name: item_name,
            "AppHMIType":
            lambda item_name: item_name,
            "FunctionID":
            lambda item_name: item_name[:item_name.rfind("ID")],
            "HybridAppPreference":
            lambda item_name: item_name,
            "RequestType":
            lambda item_name: item_name,
            "ModuleType":
            lambda item_name: item_name,
            "Common_AppPriority":
            lambda item_name: item_name
            if not item_name == "VOICE_COMMUNICATION" else "VOICECOM",
            "Parameter":
            lambda item_name: item_name
        }

        self.enum_naming_conversion_ = {
            "HMILevel": "HmiLevel",
            "AppHMIType": "AppHMIType",
            "FunctionID": "FunctionID",
            "HybridAppPreference": "HybridAppPreference",
            "RequestType": "RequestType",
            "ModuleType": "ModuleType",
            "Common_AppPriority": "Priority",
            "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)
        ]

        if filename == "MOBILE_API":
            self._write_cc_with_enum_schema_factory(filename, namespace,
                                                    destination_dir,
                                                    interface.enums.values())

            # Params should be generated as enum for MOBILE_API to validate RPCSpec parameters
            required_enum_values.append(parameter_enum)

        self._write_header_with_enums(filename, namespace, destination_dir,
                                      required_enum_values)
        self._write_cc_with_enums(filename, namespace, destination_dir,
                                  required_enum_values)