• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device 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 */
15
16const ts = require('typescript');
17const path = require('path');
18const chai = require('chai');
19const mocha = require('mocha');
20const expect = chai.expect;
21const {
22  processUISyntax,
23  transformLog
24} = require('../lib/process_ui_syntax');
25const {
26  validateUISyntax,
27  preprocessExtend,
28  resetComponentCollection,
29  componentCollection
30} = require('../lib/validate_ui_syntax');
31const {
32  componentInfo,
33  readFile,
34  storedFileInfo
35} = require('../lib/utils');
36const {
37  BUILD_ON,
38  OHOS_PLUGIN,
39  NATIVE_MODULE,
40  SYSTEM_PLUGIN
41} = require('../lib/pre_define');
42const {
43  partialUpdateConfig,
44  projectConfig,
45  resources
46} = require('../main');
47
48projectConfig.projectPath = path.resolve(process.cwd());
49
50function expectActual(name, filePath, checkError = false) {
51  transformLog.errors = [];
52  resources.app["media"] = {icon:16777222};
53  resources.app["font"] = {song:16777223};
54  process.env.rawFileResource = './';
55  process.env.compileMode = 'moduleJson';
56  const content = require(filePath);
57  const source = content.source;
58  process.env.compiler = BUILD_ON;
59  componentInfo.id = 0;
60  componentCollection.customComponents.clear();
61  resetComponentCollection();
62  storedFileInfo.setCurrentArkTsFile();
63  const afterProcess = sourceReplace(source);
64  if (checkError) {
65    transformLog.errors.push(...validateUISyntax(source, afterProcess.content, `${name}.ets`, "?entry"));
66  } else {
67    validateUISyntax(source, afterProcess.content, `${name}.ets`);
68  }
69  const compilerOptions = ts.readConfigFile(
70    path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
71  Object.assign(compilerOptions, {
72    'sourceMap': false
73  });
74  const result = ts.transpileModule(afterProcess.content, {
75    compilerOptions: compilerOptions,
76    fileName: `${name}.ets`,
77    transformers: { before: [processUISyntax(null, true)] }
78  });
79  if (checkError) {
80    assertError(name);
81  } else {
82    expect(result.outputText).eql(content.expectResult);
83  }
84}
85
86mocha.describe('compiler', () => {
87  let utPath = path.resolve(__dirname, './ut');
88  if (process.argv.includes('--partialUpdate')) {
89    partialUpdateConfig.partialUpdateMode = true;
90    utPath = path.resolve(__dirname, './utForPartialUpdate');
91  } else if (process.argv.includes('--assertError')) {
92    partialUpdateConfig.partialUpdateMode = true;
93    utPath = path.resolve(__dirname, './utForValidate');
94  }
95  const utFiles = [];
96  readFile(utPath, utFiles);
97  utFiles.forEach((item) => {
98    const fileName = path.basename(item, '.ts');
99    mocha.it(fileName, () => {
100      if (process.argv.includes('--assertError')) {
101        expectActual(fileName, item, true);
102      } else {
103        expectActual(fileName, item);
104      }
105    });
106  });
107});
108
109function sourceReplace(source) {
110  let content = source;
111  const log = [];
112  content = preprocessExtend(content);
113  content = processSystemApi(content);
114  return {
115    content: content,
116    log: log
117  };
118}
119
120function processSystemApi(content) {
121  const REG_SYSTEM =
122    /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)/g;
123  const REG_LIB_SO =
124    /import\s+(.+)\s+from\s+['"]lib(\S+)\.so['"]|import\s+(.+)\s*=\s*require\(\s*['"]lib(\S+)\.so['"]\s*\)/g;
125  const newContent = content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => {
126    const libSoValue = item1 || item3;
127    const libSoKey = item2 || item4;
128    return `var ${libSoValue} = globalThis.requireNapi("${libSoKey}", true);`;
129  }).replace(REG_SYSTEM, (item, item1, item2, item3, item4, item5, item6, item7) => {
130    let moduleType = item2 || item5;
131    let systemKey = item3 || item6;
132    let systemValue = item1 || item4;
133    if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
134      item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
135    } else if (moduleType === SYSTEM_PLUGIN) {
136      item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` +
137        `globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`;
138    } else if (moduleType === OHOS_PLUGIN) {
139      item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
140        `(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
141        `globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
142        `? globalThis.systemplugin.${systemKey} : undefined)`;
143    }
144    return item;
145  });
146  return newContent;
147}
148
149function replaceFunctions(message) {
150  const regex = /\${(.*?)}/g;
151  return message.replace(regex, (match, p1) => {
152    return eval(p1);
153  });
154}
155
156function validateError(logmsg, logtype, message, type) {
157  expect(logmsg).to.be.equal(message);
158  expect(logtype).to.be.equal(type);
159}
160
161function assertError(fileName) {
162  const errorJson = require('./error.json');
163  const errorInfo = errorJson[fileName];
164  if (errorInfo) {
165    if (Array.isArray(errorInfo)) {
166      errorInfo.forEach((item, index) => {
167        validateError(transformLog.errors[index].message, transformLog.errors[index].type, replaceFunctions(item.message), item.type);
168      });
169    } else {
170      validateError(transformLog.errors[0].message, transformLog.errors[0].type, replaceFunctions(errorInfo.message), errorInfo.type);
171    }
172  }
173}
174