• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use rollupObject 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
16import { expect } from 'chai';
17import mocha from 'mocha';
18import fs from "fs";
19import path from "path";
20import MagicString from 'magic-string';
21
22import {
23  getBuildModeInLowerCase,
24  getPackageInfo,
25  genSourceMapFileName,
26  isOhModules,
27  isEs2Abc,
28  writeTerserObfuscatedSourceCode
29} from '../../../lib/ark_utils';
30import {
31  DEBUG,
32  RELEASE,
33  OH_MODULES,
34  EXTNAME_TS,
35  EXTNAME_JS,
36  EXTNAME_ETS,
37  OBFUSCATION_TOOL
38} from '../../../lib/fast_build/ark_compiler/common/ark_define';
39import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock';
40import {
41  BUNDLE_NAME_DEFAULT,
42  ENTRY_MODULE_NAME_DEFAULT,
43  EXTNAME_MAP,
44  ENTRYABILITY_JS
45} from '../mock/rollup_mock/common';
46import projectConfig from '../utils/processProjectConfig';
47import {
48  ES2ABC,
49  TS2ABC
50} from '../../../lib/pre_define';
51import { changeFileExtension } from '../../../lib/fast_build/ark_compiler/utils';
52import ModuleSourceFileMock from '../mock/class_mock/module_source_files_mock';
53import {
54  genTemporaryPath,
55  toUnixPath
56} from '../../../lib/utils';
57import {
58  ObConfigResolver,
59  MergedConfig
60} from '../../../lib/fast_build/ark_compiler/common/ob_config_resolver';
61import {
62  utProcessArkConfig
63} from '../../../lib/fast_build/ark_compiler/common/process_ark_config';
64import { ModuleSourceFile } from '../../../lib/fast_build/ark_compiler/module/module_source_file';
65import { newSourceMaps } from '../../../lib/fast_build/ark_compiler/transform';
66import { TERSER_PROCESSED_EXPECTED_CODE } from '../mock/rollup_mock/path_config';
67
68mocha.describe('test ark_utils file api', function () {
69  mocha.before(function () {
70    this.rollup = new RollUpPluginMock();
71  });
72
73  mocha.after(() => {
74    delete this.rollup;
75  });
76
77  mocha.it('1-1: test getBuildModeInLowerCase under build debug', function () {
78    this.rollup.build();
79    const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig);
80    expect(buildMode === DEBUG).to.be.true;
81  });
82
83  mocha.it('1-2: test getBuildModeInLowerCase under build release', function () {
84    this.rollup.build(RELEASE);
85    const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig);
86    expect(buildMode === RELEASE).to.be.true;
87  });
88
89  mocha.it('1-3: test getBuildModeInLowerCase under preview debug', function () {
90    this.rollup.preview();
91    const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig);
92    expect(buildMode === DEBUG).to.be.true;
93  });
94
95  mocha.it('1-4: test getBuildModeInLowerCase under hot reload debug', function () {
96    this.rollup.hotReload();
97    const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig);
98    expect(buildMode === DEBUG).to.be.true;
99  });
100
101  mocha.it('2-1: test getPackageInfo under build debug', function () {
102    this.rollup.build();
103    const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath);
104    expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true;
105    expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true;
106  });
107
108  mocha.it('2-2: test getPackageInfo under build release', function () {
109    this.rollup.build(RELEASE);
110    const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath);
111    expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true;
112    expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true;
113  });
114
115  mocha.it('2-3: test getPackageInfo under preview debug', function () {
116    this.rollup.preview();
117    const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath);
118    expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true;
119    expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true;
120  });
121
122  mocha.it('2-4: test getPackageInfo under hot reload debug', function () {
123    this.rollup.hotReload();
124    const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath);
125    expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true;
126    expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true;
127  });
128
129  mocha.it('3-1: test genSourceMapFileName under build debug', function () {
130    this.rollup.build();
131    for (const filePath of this.rollup.share.allFiles) {
132      if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) {
133        const originPath = genSourceMapFileName(filePath);
134        const expectedPath = `${filePath}${EXTNAME_MAP}`;
135        expect(originPath === expectedPath).to.be.true;
136      } else if (filePath.endsWith(EXTNAME_ETS)) {
137        const originPath = genSourceMapFileName(filePath);
138        expect(originPath === filePath).to.be.true;
139      }
140    }
141  });
142
143  mocha.it('3-2: test genSourceMapFileName under build release', function () {
144    this.rollup.build(RELEASE);
145    for (const filePath of this.rollup.share.allFiles) {
146      if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) {
147        const originPath = genSourceMapFileName(filePath);
148        const expectedPath = `${filePath}${EXTNAME_MAP}`;
149        expect(originPath === expectedPath).to.be.true;
150      }
151    }
152  });
153
154  mocha.it('3-3: test genSourceMapFileName under preview debug', function () {
155    this.rollup.preview();
156    for (const filePath of this.rollup.share.allFiles) {
157      if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) {
158        const originPath = genSourceMapFileName(filePath);
159        const expectedPath = `${filePath}${EXTNAME_MAP}`;
160        expect(originPath === expectedPath).to.be.true;
161      }
162    }
163  });
164
165  mocha.it('3-4: test genSourceMapFileName under hot reload debug', function () {
166    this.rollup.hotReload();
167    for (const filePath of this.rollup.share.allFiles) {
168      if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) {
169        const originPath = genSourceMapFileName(filePath);
170        const expectedPath = `${filePath}${EXTNAME_MAP}`;
171        expect(originPath === expectedPath).to.be.true;
172      }
173    }
174  });
175
176  mocha.it('4-1: test isOhModules under build debug', function () {
177    this.rollup.build();
178    const returnInfo = isOhModules(this.rollup.share.projectConfig);
179    expect(returnInfo === false).to.be.true;
180    this.rollup.share.projectConfig.packageDir = OH_MODULES;
181    const returnInfoOh = isOhModules(this.rollup.share.projectConfig);
182    expect(returnInfoOh).to.be.true;
183  });
184
185  mocha.it('4-2: test isOhModules under build release', function () {
186    this.rollup.build(RELEASE);
187    const returnInfo = isOhModules(this.rollup.share.projectConfig);
188    expect(returnInfo === false).to.be.true;
189    this.rollup.share.projectConfig.packageDir = OH_MODULES;
190    const returnInfoOh = isOhModules(this.rollup.share.projectConfig);
191    expect(returnInfoOh).to.be.true;
192  });
193
194  mocha.it('4-3: test isOhModules under preview debug', function () {
195    this.rollup.preview();
196    const returnInfo = isOhModules(this.rollup.share.projectConfig);
197    expect(returnInfo === false).to.be.true;
198    this.rollup.share.projectConfig.packageDir = OH_MODULES;
199    const returnInfoOh = isOhModules(this.rollup.share.projectConfig);
200    expect(returnInfoOh).to.be.true;
201  });
202
203  mocha.it('4-4: test isOhModules under hot reload debug', function () {
204    this.rollup.hotReload();
205    const returnInfo = isOhModules(this.rollup.share.projectConfig);
206    expect(returnInfo === false).to.be.true;
207    this.rollup.share.projectConfig.packageDir = OH_MODULES;
208    const returnInfoOh = isOhModules(this.rollup.share.projectConfig);
209    expect(returnInfoOh).to.be.true;
210  });
211
212  mocha.it('4-5: test isOhModules under hot fix debug', function () {
213    projectConfig.buildMode = DEBUG;
214    const returnInfo = isOhModules(projectConfig);
215    expect(returnInfo).to.be.true;
216  });
217
218  mocha.it('4-6: test isOhModules under hot fix release', function () {
219    projectConfig.buildMode = RELEASE;
220    const returnInfo = isOhModules(projectConfig);
221    expect(returnInfo).to.be.true;
222  });
223
224  mocha.it('5-1: test isEs2Abc under build debug', function () {
225    this.rollup.build();
226    this.rollup.share.projectConfig.pandaMode = ES2ABC;
227    const returnInfo = isEs2Abc(this.rollup.share.projectConfig);
228    expect(returnInfo).to.be.true;
229
230    this.rollup.share.projectConfig.pandaMode = TS2ABC;
231    const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig);
232    expect(returnInfoTS2ABC === false).to.be.true;
233
234    this.rollup.share.projectConfig.pandaMode = "undefined";
235    const returnInfoUndef = isEs2Abc(this.rollup.share.projectConfig);
236    expect(returnInfoUndef).to.be.true;
237
238    this.rollup.share.projectConfig.pandaMode = undefined;
239    const returnInfoUndefined = isEs2Abc(this.rollup.share.projectConfig);
240    expect(returnInfoUndefined).to.be.true;
241  });
242
243  mocha.it('5-2: test isEs2Abc under build release', function () {
244    this.rollup.build(RELEASE);
245    this.rollup.share.projectConfig.pandaMode = ES2ABC;
246    const returnInfo = isEs2Abc(this.rollup.share.projectConfig);
247    expect(returnInfo).to.be.true;
248
249    this.rollup.share.projectConfig.pandaMode = TS2ABC;
250    const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig);
251    expect(returnInfoTS2ABC).to.be.false;
252  });
253
254  mocha.it('5-3: test isEs2Abc under preview debug', function () {
255    this.rollup.preview();
256    this.rollup.share.projectConfig.pandaMode = ES2ABC;
257    const returnInfo = isEs2Abc(this.rollup.share.projectConfig);
258    expect(returnInfo).to.be.true;
259
260    this.rollup.share.projectConfig.pandaMode = TS2ABC;
261    const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig);
262    expect(returnInfoTS2ABC).to.be.false;
263  });
264
265  mocha.it('5-4: test isEs2Abc under hot reload debug', function () {
266    this.rollup.hotReload();
267    this.rollup.share.projectConfig.pandaMode = ES2ABC;
268    const returnInfo = isEs2Abc(this.rollup.share.projectConfig);
269    expect(returnInfo).to.be.true;
270
271    this.rollup.share.projectConfig.pandaMode = TS2ABC;
272    const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig);
273    expect(returnInfoTS2ABC).to.be.false;
274  });
275
276  mocha.it('5-5: test isEs2Abc under hot fix debug', function () {
277    projectConfig.buildMode = DEBUG;
278    projectConfig.pandaMode = ES2ABC;
279    const returnInfo = isEs2Abc(projectConfig);
280    expect(returnInfo).to.be.true;
281
282    projectConfig.pandaMode = TS2ABC;
283    const returnInfoTS2ABC = isEs2Abc(projectConfig);
284    expect(returnInfoTS2ABC).to.be.false;
285  });
286
287  mocha.it('5-6: test isEs2Abc under hot fix release', function () {
288    projectConfig.buildMode = RELEASE;
289    projectConfig.pandaMode = ES2ABC;
290    const returnInfo = isEs2Abc(projectConfig);
291    expect(returnInfo).to.be.true;
292
293    projectConfig.pandaMode = TS2ABC;
294    const returnInfoTS2ABC = isEs2Abc(projectConfig);
295    expect(returnInfoTS2ABC).to.be.false;
296  });
297
298  mocha.it('6-1: test writeTerserObfuscatedSourceCode under build release', async function () {
299    this.rollup.build(RELEASE);
300    const mockFileList: object = this.rollup.getModuleIds();
301    for (const moduleId of mockFileList) {
302      if (moduleId.endsWith(EXTNAME_TS)) {
303        const code: string =
304          fs.readFileSync(`${this.rollup.share.projectConfig.projectTopDir}/${ENTRYABILITY_JS}`, 'utf-8');
305        const moduleSource = new ModuleSourceFileMock(moduleId, code);
306        moduleSource.initPluginEnvMock(this.rollup);
307        const filePath =
308          genTemporaryPath(moduleSource.moduleId, moduleSource.projectConfig.projectPath,
309            moduleSource.projectConfig.cachePath, moduleSource.projectConfig);
310        const newFilePath = changeFileExtension(filePath, EXTNAME_JS);
311        const relativeSourceFilePath: string =
312          toUnixPath(moduleSource.moduleId).replace(toUnixPath(moduleSource.projectConfig.projectRootPath) + '/', '');
313        const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
314        const obConfig: ObConfigResolver = new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
315        const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
316        const isHarCompiled: boolean = this.rollup.share.projectConfig.compileHar;
317        moduleSource.projectConfig.terserConfig =
318          utProcessArkConfig.initTerserConfig(this.rollup.share.projectConfig, logger, mergedObConfig, isHarCompiled);
319        const Code: string = fs.readFileSync(moduleId, 'utf-8');
320        const ModuleSource = new ModuleSourceFile(relativeSourceFilePath, Code);
321        const codeString: MagicString = new MagicString(<string>ModuleSource.source);
322        const sourceMap: object = codeString.generateMap({
323          source: relativeSourceFilePath,
324          file: `${path.basename(ModuleSource.moduleId)}`,
325          includeContent: false,
326          hires: true
327        });
328        newSourceMaps[relativeSourceFilePath] = sourceMap;
329        delete newSourceMaps[relativeSourceFilePath].sourcesContent;
330
331        await writeTerserObfuscatedSourceCode(moduleSource.source, newFilePath, moduleSource.logger,
332          moduleSource.projectConfig.terserConfig, relativeSourceFilePath, newSourceMaps);
333        const readFilecontent = fs.readFileSync(newFilePath, 'utf-8');
334        const expectResult = fs.readFileSync(TERSER_PROCESSED_EXPECTED_CODE, 'utf-8');
335        expect(readFilecontent === expectResult).to.be.true;
336      }
337    }
338
339    for (const key of Object.keys(newSourceMaps)) {
340      delete newSourceMaps[key];
341    }
342  });
343});