예제 #1
0
    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"))])
예제 #2
0
    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
        for attribute in attributes:
            if attribute == "internal_scope":
                internal_scope = attributes[attribute]
            elif attribute == "scope":
                scope = attributes[attribute]
            else:
                raise ParseError("Unexpected attribute '" + attribute +
                                 "' in enum '" + params["name"] + "'")
        params["internal_scope"] = internal_scope
        params["scope"] = scope

        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 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")
예제 #4
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_comment(self):
        """Test generation of the source code comments.

        Verifies correct generation of the code comments.

        """
        generator = SmartFactoryBase.CodeGenerator()

        enum = Model.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")
예제 #6
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")
예제 #7
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")
예제 #8
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)