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")
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