Пример #1
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")
Пример #2
0
    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, "")

        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"])
                if len(subelement.getchildren()) != 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