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