107ac75b1Sopenharmony_ci/* 207ac75b1Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 307ac75b1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 407ac75b1Sopenharmony_ci * you may not use this file except in compliance with the License. 507ac75b1Sopenharmony_ci * You may obtain a copy of the License at 607ac75b1Sopenharmony_ci * 707ac75b1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 807ac75b1Sopenharmony_ci * 907ac75b1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1007ac75b1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1107ac75b1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1207ac75b1Sopenharmony_ci * See the License for the specific language governing permissions and 1307ac75b1Sopenharmony_ci * limitations under the License. 1407ac75b1Sopenharmony_ci */ 1507ac75b1Sopenharmony_ci 1607ac75b1Sopenharmony_ciconst ts = require('typescript'); 1707ac75b1Sopenharmony_ciconst path = require('path'); 1807ac75b1Sopenharmony_ciconst chai = require('chai'); 1907ac75b1Sopenharmony_ciconst mocha = require('mocha'); 2007ac75b1Sopenharmony_ciconst expect = chai.expect; 2107ac75b1Sopenharmony_ciconst { 2207ac75b1Sopenharmony_ci processUISyntax, 2307ac75b1Sopenharmony_ci transformLog 2407ac75b1Sopenharmony_ci} = require('../lib/process_ui_syntax'); 2507ac75b1Sopenharmony_ciconst { 2607ac75b1Sopenharmony_ci validateUISyntax, 2707ac75b1Sopenharmony_ci preprocessExtend, 2807ac75b1Sopenharmony_ci resetComponentCollection, 2907ac75b1Sopenharmony_ci componentCollection 3007ac75b1Sopenharmony_ci} = require('../lib/validate_ui_syntax'); 3107ac75b1Sopenharmony_ciconst { 3207ac75b1Sopenharmony_ci componentInfo, 3307ac75b1Sopenharmony_ci readFile, 3407ac75b1Sopenharmony_ci storedFileInfo 3507ac75b1Sopenharmony_ci} = require('../lib/utils'); 3607ac75b1Sopenharmony_ciconst { 3707ac75b1Sopenharmony_ci BUILD_ON, 3807ac75b1Sopenharmony_ci OHOS_PLUGIN, 3907ac75b1Sopenharmony_ci NATIVE_MODULE, 4007ac75b1Sopenharmony_ci SYSTEM_PLUGIN 4107ac75b1Sopenharmony_ci} = require('../lib/pre_define'); 4207ac75b1Sopenharmony_ciconst { 4307ac75b1Sopenharmony_ci partialUpdateConfig, 4407ac75b1Sopenharmony_ci projectConfig, 4507ac75b1Sopenharmony_ci resources 4607ac75b1Sopenharmony_ci} = require('../main'); 4707ac75b1Sopenharmony_ciconst processStructComponentV2 = require('../lib/process_struct_componentV2'); 4807ac75b1Sopenharmony_ci 4907ac75b1Sopenharmony_ciprojectConfig.projectPath = path.resolve(process.cwd()); 5007ac75b1Sopenharmony_ci 5107ac75b1Sopenharmony_cifunction expectActual(name, filePath, checkError = false) { 5207ac75b1Sopenharmony_ci transformLog.errors = []; 5307ac75b1Sopenharmony_ci resources.app["media"] = {icon:16777222}; 5407ac75b1Sopenharmony_ci resources.app["font"] = {song:16777223}; 5507ac75b1Sopenharmony_ci process.env.rawFileResource = './'; 5607ac75b1Sopenharmony_ci process.env.compileMode = 'moduleJson'; 5707ac75b1Sopenharmony_ci const content = require(filePath); 5807ac75b1Sopenharmony_ci const source = content.source; 5907ac75b1Sopenharmony_ci process.env.compiler = BUILD_ON; 6007ac75b1Sopenharmony_ci componentInfo.id = 0; 6107ac75b1Sopenharmony_ci componentCollection.customComponents.clear(); 6207ac75b1Sopenharmony_ci resetComponentCollection(); 6307ac75b1Sopenharmony_ci storedFileInfo.setCurrentArkTsFile(); 6407ac75b1Sopenharmony_ci const afterProcess = sourceReplace(source); 6507ac75b1Sopenharmony_ci if (checkError) { 6607ac75b1Sopenharmony_ci transformLog.errors.push(...validateUISyntax(source, afterProcess.content, `${name}.ets`, "?entry")); 6707ac75b1Sopenharmony_ci } else { 6807ac75b1Sopenharmony_ci validateUISyntax(source, afterProcess.content, `${name}.ets`); 6907ac75b1Sopenharmony_ci } 7007ac75b1Sopenharmony_ci const compilerOptions = ts.readConfigFile( 7107ac75b1Sopenharmony_ci path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions; 7207ac75b1Sopenharmony_ci Object.assign(compilerOptions, { 7307ac75b1Sopenharmony_ci 'sourceMap': false 7407ac75b1Sopenharmony_ci }); 7507ac75b1Sopenharmony_ci const result = ts.transpileModule(afterProcess.content, { 7607ac75b1Sopenharmony_ci compilerOptions: compilerOptions, 7707ac75b1Sopenharmony_ci fileName: `${name}.ets`, 7807ac75b1Sopenharmony_ci transformers: { before: [processUISyntax(null, true)] } 7907ac75b1Sopenharmony_ci }); 8007ac75b1Sopenharmony_ci processStructComponentV2.default.resetStructMapInEts(); 8107ac75b1Sopenharmony_ci if (checkError) { 8207ac75b1Sopenharmony_ci assertError(name); 8307ac75b1Sopenharmony_ci } else { 8407ac75b1Sopenharmony_ci expect(result.outputText).eql(content.expectResult); 8507ac75b1Sopenharmony_ci } 8607ac75b1Sopenharmony_ci} 8707ac75b1Sopenharmony_ci 8807ac75b1Sopenharmony_cimocha.describe('compiler', () => { 8907ac75b1Sopenharmony_ci let utPath = path.resolve(__dirname, './ut'); 9007ac75b1Sopenharmony_ci if (process.argv.includes('--partialUpdate')) { 9107ac75b1Sopenharmony_ci partialUpdateConfig.partialUpdateMode = true; 9207ac75b1Sopenharmony_ci utPath = path.resolve(__dirname, './utForPartialUpdate'); 9307ac75b1Sopenharmony_ci } else if (process.argv.includes('--assertError')) { 9407ac75b1Sopenharmony_ci partialUpdateConfig.partialUpdateMode = true; 9507ac75b1Sopenharmony_ci utPath = path.resolve(__dirname, './utForValidate'); 9607ac75b1Sopenharmony_ci } 9707ac75b1Sopenharmony_ci const utFiles = []; 9807ac75b1Sopenharmony_ci readFile(utPath, utFiles); 9907ac75b1Sopenharmony_ci utFiles.forEach((item) => { 10007ac75b1Sopenharmony_ci const fileName = path.basename(item, '.ts'); 10107ac75b1Sopenharmony_ci mocha.it(fileName, () => { 10207ac75b1Sopenharmony_ci if (process.argv.includes('--assertError')) { 10307ac75b1Sopenharmony_ci expectActual(fileName, item, true); 10407ac75b1Sopenharmony_ci } else { 10507ac75b1Sopenharmony_ci expectActual(fileName, item); 10607ac75b1Sopenharmony_ci } 10707ac75b1Sopenharmony_ci }); 10807ac75b1Sopenharmony_ci }); 10907ac75b1Sopenharmony_ci}); 11007ac75b1Sopenharmony_ci 11107ac75b1Sopenharmony_cifunction sourceReplace(source) { 11207ac75b1Sopenharmony_ci let content = source; 11307ac75b1Sopenharmony_ci const log = []; 11407ac75b1Sopenharmony_ci content = preprocessExtend(content); 11507ac75b1Sopenharmony_ci content = processSystemApi(content); 11607ac75b1Sopenharmony_ci return { 11707ac75b1Sopenharmony_ci content: content, 11807ac75b1Sopenharmony_ci log: log 11907ac75b1Sopenharmony_ci }; 12007ac75b1Sopenharmony_ci} 12107ac75b1Sopenharmony_ci 12207ac75b1Sopenharmony_cifunction processSystemApi(content) { 12307ac75b1Sopenharmony_ci const REG_SYSTEM = 12407ac75b1Sopenharmony_ci /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)/g; 12507ac75b1Sopenharmony_ci const REG_LIB_SO = 12607ac75b1Sopenharmony_ci /import\s+(.+)\s+from\s+['"]lib(\S+)\.so['"]|import\s+(.+)\s*=\s*require\(\s*['"]lib(\S+)\.so['"]\s*\)/g; 12707ac75b1Sopenharmony_ci const newContent = content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => { 12807ac75b1Sopenharmony_ci const libSoValue = item1 || item3; 12907ac75b1Sopenharmony_ci const libSoKey = item2 || item4; 13007ac75b1Sopenharmony_ci return `var ${libSoValue} = globalThis.requireNapi("${libSoKey}", true);`; 13107ac75b1Sopenharmony_ci }).replace(REG_SYSTEM, (item, item1, item2, item3, item4, item5, item6, item7) => { 13207ac75b1Sopenharmony_ci let moduleType = item2 || item5; 13307ac75b1Sopenharmony_ci let systemKey = item3 || item6; 13407ac75b1Sopenharmony_ci let systemValue = item1 || item4; 13507ac75b1Sopenharmony_ci if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) { 13607ac75b1Sopenharmony_ci item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`; 13707ac75b1Sopenharmony_ci } else if (moduleType === SYSTEM_PLUGIN) { 13807ac75b1Sopenharmony_ci item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` + 13907ac75b1Sopenharmony_ci `globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`; 14007ac75b1Sopenharmony_ci } else if (moduleType === OHOS_PLUGIN) { 14107ac75b1Sopenharmony_ci item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` + 14207ac75b1Sopenharmony_ci `(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` + 14307ac75b1Sopenharmony_ci `globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` + 14407ac75b1Sopenharmony_ci `? globalThis.systemplugin.${systemKey} : undefined)`; 14507ac75b1Sopenharmony_ci } 14607ac75b1Sopenharmony_ci return item; 14707ac75b1Sopenharmony_ci }); 14807ac75b1Sopenharmony_ci return newContent; 14907ac75b1Sopenharmony_ci} 15007ac75b1Sopenharmony_ci 15107ac75b1Sopenharmony_cifunction replaceFunctions(message) { 15207ac75b1Sopenharmony_ci const regex = /\${(.*?)}/g; 15307ac75b1Sopenharmony_ci return message.replace(regex, (match, p1) => { 15407ac75b1Sopenharmony_ci return eval(p1); 15507ac75b1Sopenharmony_ci }); 15607ac75b1Sopenharmony_ci} 15707ac75b1Sopenharmony_ci 15807ac75b1Sopenharmony_cifunction validateError(logmsg, logtype, message, type) { 15907ac75b1Sopenharmony_ci expect(logmsg).to.be.equal(message); 16007ac75b1Sopenharmony_ci expect(logtype).to.be.equal(type); 16107ac75b1Sopenharmony_ci} 16207ac75b1Sopenharmony_ci 16307ac75b1Sopenharmony_cifunction assertError(fileName) { 16407ac75b1Sopenharmony_ci const errorJson = require('./error.json'); 16507ac75b1Sopenharmony_ci const errorInfo = errorJson[fileName]; 16607ac75b1Sopenharmony_ci if (errorInfo) { 16707ac75b1Sopenharmony_ci if (Array.isArray(errorInfo)) { 16807ac75b1Sopenharmony_ci errorInfo.forEach((item, index) => { 16907ac75b1Sopenharmony_ci validateError(transformLog.errors[index].message, transformLog.errors[index].type, replaceFunctions(item.message), item.type); 17007ac75b1Sopenharmony_ci }); 17107ac75b1Sopenharmony_ci } else { 17207ac75b1Sopenharmony_ci validateError(transformLog.errors[0].message, transformLog.errors[0].type, replaceFunctions(errorInfo.message), errorInfo.type); 17307ac75b1Sopenharmony_ci } 17407ac75b1Sopenharmony_ci } 17507ac75b1Sopenharmony_ci} 176