1/* 2* Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15const { NapiLog } = require('../tools/NapiLog'); 16const util = require('util'); 17const { InterfaceList, TypeList } = require('../tools/common'); 18const path = require('path'); 19const fs = require('fs'); 20const INTVALUE = 5; 21const FLOATVALUE = 2.5; 22 23function generateFuncTestCase(params, funcIndex, tsFuncName, abilityTestTemplete, hFileName) { 24 let funcInfo = { 25 'name': '', 26 'params': [], 27 'retType': '', 28 }; 29 funcInfo.name = params.functions[funcIndex].name; 30 let parseParams = params.functions[funcIndex].parameters; 31 for (let i = 0; i < parseParams.length; ++i) { 32 let param = createParam(parseParams[i]); 33 funcInfo.params.push(param); 34 } 35 funcInfo.retType = params.functions[funcIndex].rtnType; 36 let { funcParamUse, funcParamDefine, funcInfoParams } = genInitTestfunc(funcInfo); 37 // 去除调用参数的最后一个',' 38 let index = funcParamUse.lastIndexOf(', '); 39 funcParamUse = funcParamUse.substring(0, index); 40 let callFunc = ''; 41 let hilogContent = ''; 42 // 调用函数 43 if (getJsType(funcInfo.retType) !== 'void') { 44 callFunc = util.format('let result: %s = testNapi.%s(%s)\n ', getJsType(funcInfo.retType), tsFuncName, funcParamUse); 45 // 加 hilog 打印 46 hilogContent = util.format('hilog.info(0x0000, "testTag", "Test NAPI %s: ", JSON.stringify(result));\n ', tsFuncName); 47 hilogContent += util.format('console.info("testTag", "Test NAPI %s: ", JSON.stringify(result));\n ', tsFuncName); 48 } else { 49 callFunc = util.format('testNapi.%s(%s)\n ', tsFuncName, funcParamUse); 50 } 51 let funcTestReplace = funcParamDefine + callFunc + hilogContent; 52 // 替换test_case_name 53 let funcTestContent = replaceAll(abilityTestTemplete, '[func_direct_testCase]', funcTestReplace); 54 funcTestContent = replaceAll(funcTestContent, '[test_case_name]', tsFuncName); 55 funcTestContent = replaceAll(funcTestContent, '[file_introduce_replace]', hFileName); 56 funcTestContent = replaceAll(funcTestContent, '[func_introduce_replace]', funcInfo.name); 57 funcTestContent = replaceAll(funcTestContent, '[input_introduce_replace]', funcInfoParams === '' ? 'void' : funcInfoParams); 58 funcTestContent = replaceAll(funcTestContent, '[output_introduce_replace]', funcInfo.retType); 59 60 return funcTestContent; 61} 62 63function genInitTestfunc(funcInfo) { 64 let funcParamDefine = ''; 65 let funcParamUse = ''; 66 let funcInfoParams = ''; 67 let funcInfoParamTemp = '[paramName]: [paramType]; '; 68 // 判断函数有几个参数,依次给参数赋值 69 for (let i = 0; i < funcInfo.params.length; i++) { 70 let funcInfoParamReplace = replaceAll(funcInfoParamTemp, '[paramName]', funcInfo.params[i].name); 71 funcInfoParamReplace = replaceAll(funcInfoParamReplace, '[paramType]', funcInfo.params[i].type); 72 funcInfoParams += funcInfoParamReplace; 73 let testType = getTestType(funcInfo.params[i].type); 74 if (testType === 'int') { 75 funcParamDefine += util.format('let %s = %s\n ', funcInfo.params[i].name, INTVALUE); 76 funcParamUse += funcInfo.params[i].name + ', '; 77 } else if (testType === 'float') { 78 funcParamDefine += util.format('let %s = %s\n ', funcInfo.params[i].name, FLOATVALUE); 79 funcParamUse += funcInfo.params[i].name + ', '; 80 } else if (testType === 'bool') { 81 funcParamDefine += util.format('let %s = %s\n ', funcInfo.params[i].name, true); 82 funcParamUse += funcInfo.params[i].name + ', '; 83 } else if (testType === 'string') { 84 funcParamDefine += util.format('let %s = "%s"\n ', funcInfo.params[i].name, 'hello'); 85 funcParamUse += funcInfo.params[i].name + ', '; 86 } else if (TypeList.getValue(testType)) { 87 let typeDefineRes = getTypeDefine(testType, funcParamDefine, funcInfo, i, funcParamUse); 88 funcParamDefine = typeDefineRes[0]; 89 funcParamUse = typeDefineRes[1]; 90 } else if (InterfaceList.getBody(testType)) { 91 let interfaceDefineRes = getInterfaceDefine(testType, funcParamDefine, funcInfo, i, funcParamUse); 92 funcParamDefine = interfaceDefineRes[0]; 93 funcParamUse = interfaceDefineRes[1]; 94 } 95 } 96 return { funcParamUse, funcParamDefine, funcInfoParams }; 97} 98 99function getTypeDefine(testType, funcParamDefine, funcInfo, i, funcParamUse) { 100 let typeDefType = TypeList.getValue(testType); 101 // genType 102 if (typeDefType === 'number') { 103 funcParamDefine += util.format('let %s = %s\n ', funcInfo.params[i].name, INTVALUE); 104 funcParamUse += funcInfo.params[i].name + ', '; 105 } else if (typeDefType === 'string') { 106 funcParamDefine += util.format('let %s = "%s"\n ', funcInfo.params[i].name, 'hello'); 107 funcParamUse += funcInfo.params[i].name + ', '; 108 } else if (typeDefType === 'boolean') { 109 funcParamDefine += util.format('let %s = %s\n ', funcInfo.params[i].name, false); 110 funcParamUse += funcInfo.params[i].name + ', '; 111 } 112 return [funcParamDefine, funcParamUse]; 113} 114 115function getInterfaceDefine(testType, funcParamDefine, funcInfo, i, funcParamUse) { 116 let objValue = InterfaceList.getBody(testType); 117 let objTestData = 'let %s:testNapi.%s = { '; 118 for (let j = 0; j < objValue.length; j++) { 119 if (objValue[j].type === 'number') { 120 objTestData += util.format('%s: %s, ', objValue[j].name, INTVALUE); 121 } else if (objValue[j].type === 'string') { 122 objTestData += util.format('%s: "%s", ', objValue[j].name, 'hello'); 123 } else if (objValue[j].type === 'boolean') { 124 objTestData += util.format('%s: %s, ', objValue[j].name, true); 125 } else if (InterfaceList.getBody(objValue[j].type)) { 126 objTestData += util.format('%s: null, ', objValue[j].name); 127 } else if (objValue[j].type.indexOf('=>') >= 0) { // 成员方法 128 let interfaceFunc = objValue[j].type; 129 let indexFunc = interfaceFunc.indexOf('=>'); 130 let interfaceFuncRet = interfaceFunc.substring(indexFunc + 2, interfaceFunc.length); 131 if (interfaceFuncRet.trim() === 'void') { 132 let interfaceFuncRetDefine = interfaceFunc.substring(0, indexFunc + 2) + '{}'; 133 objTestData += util.format('%s, ', interfaceFuncRetDefine); 134 } else if (interfaceFuncRet.trim() === 'string') { 135 let interfaceFuncRetDefine = interfaceFunc.substring(0, indexFunc + 2) + '{return ""}'; 136 objTestData += util.format('%s, ', interfaceFuncRetDefine); 137 } else if (interfaceFuncRet.trim() === 'boolean') { 138 let interfaceFuncRetDefine = interfaceFunc.substring(0, indexFunc + 2) + '{ return true }'; 139 objTestData += util.format('%s, ', interfaceFuncRetDefine); 140 } else if (interfaceFuncRet.trim() === 'number') { 141 let interfaceFuncRetDefine = interfaceFunc.substring(0, indexFunc + 2) + '{ return 0 }'; 142 objTestData += util.format('%s, ', interfaceFuncRetDefine); 143 } 144 } 145 } 146 147 // 去除调用参数的最后一个',' 148 let index = objTestData.lastIndexOf(', '); 149 if (index !== -1) { 150 objTestData = objTestData.substring(0, index) + ' }\n '; 151 } else { 152 objTestData = 'let %s:testNapi.%s = null;\n '; 153 } 154 funcParamDefine += util.format(objTestData, funcInfo.params[i].name, testType); 155 funcParamUse += funcInfo.params[i].name + ', '; 156 return [funcParamDefine, funcParamUse]; 157} 158 159function replaceAll(s, sfrom, sto) { 160 while (s.indexOf(sfrom) >= 0) { 161 s = s.replace(sfrom, sto); 162 } 163 return s; 164} 165 166function getTestType(type) { 167 // 去掉const 和 * 168 type = type.replaceAll('const', '').replaceAll('*', '').trim(); 169 if (type === 'uint32_t' || type === 'int32_t' || type === 'int16_t' || 170 type === 'int64_t' || type === 'int' || type === 'size_t') { 171 return 'int'; 172 } else if (type === 'double_t' || type === 'double' || type === 'float') { 173 return 'float'; 174 } else if (type === 'bool') { 175 return 'bool'; 176 } else if (type === 'std::string' || type.indexOf('char') >= 0) { 177 return 'string'; 178 } 179 return type; 180} 181 182function getJsType(type) { 183 // 去掉const 和 * 184 type = type.replaceAll('const', '').replaceAll('*', '').trim(); 185 if (type === 'uint32_t' || type === 'int32_t' || type === 'int16_t' || type === 'int64_t' || 186 type === 'int' || type === 'double_t' || type === 'double' || type === 'float' || type === 'size_t') { 187 return 'number'; 188 } else if (type.indexOf('char') >= 0 || type === 'std::string') { 189 return 'string'; 190 } else if (type === 'bool') { 191 return 'boolean'; 192 } else if (type === 'void') { 193 return type; 194 } else { 195 // 对象,在ts中定义为interface 196 return 'testNapi.' + type.replace('*', '').trim(); 197 } 198} 199 200function createParam(parseParamInfo) { 201 let param = { 202 'name': '', 203 'type': '' 204 }; 205 param.name = parseParamInfo.name; 206 param.type = parseParamInfo.type; 207 return param; 208} 209 210module.exports = { 211 generateFuncTestCase 212};