• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 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
16
17import { expect } from 'chai';
18import fs from "fs";
19import mocha from 'mocha';
20import path from "path";
21
22import {
23  MergedConfig,
24  ObConfigResolver,
25  collectResevedFileNameInIDEConfig,
26  getRelativeSourcePath
27} from '../../../lib/fast_build/ark_compiler/common/ob_config_resolver';
28import {
29  OBFUSCATION_RULE_PATH,
30  OBFUSCATION_RULE_TEMPLATE_PATH
31} from '../mock/rollup_mock/path_config';
32import { OBFUSCATION_TOOL } from '../../../lib/fast_build/ark_compiler/common/ark_define';
33import { RELEASE } from '../../../lib/fast_build/ark_compiler/common/ark_define';
34import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock';
35
36const OBFUSCATE_TESTDATA_DIR = path.resolve(__dirname, '../../../test/ark_compiler_ut/testdata/obfuscation');
37
38mocha.describe('test obfuscate config resolver api', function () {
39  mocha.before(function () {
40    this.rollup = new RollUpPluginMock();
41    let obfuscationContent = undefined;
42    try {
43      obfuscationContent = fs.readFileSync(OBFUSCATION_RULE_TEMPLATE_PATH, 'utf-8');
44      obfuscationContent = obfuscationContent.replace('OBFUSCATE_TESTDATA_DIR', OBFUSCATE_TESTDATA_DIR);
45      fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, obfuscationContent);
46    } catch (err) {
47      throw err;
48    }
49  });
50
51  mocha.afterEach(() => {
52    if (fs.existsSync(`${OBFUSCATION_RULE_PATH}`)) {
53      fs.unlinkSync(`${OBFUSCATION_RULE_PATH}`);
54    }
55  });
56
57  mocha.after(() => {
58    delete this.rollup;
59  });
60
61  mocha.it('1-1: test resolveDts', function () {
62    this.rollup.build(RELEASE);
63    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
64    this.rollup.share.projectConfig.obfuscationOptions = {
65      'selfConfig': {
66        'ruleOptions': {
67          'enable': true,
68          'rules': [ OBFUSCATION_RULE_PATH ]
69        },
70        'consumerRules': [],
71      },
72      'dependencies': {
73        'libraries': [],
74        'hars': []
75      }
76    };
77    const obConfig: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
78    const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
79    expect(mergedObConfig.options.enableToplevelObfuscation).to.be.true;
80    expect(mergedObConfig.options.enablePropertyObfuscation).to.be.false;
81
82    const reservedNames = mergedObConfig.reservedNames;
83    expect(reservedNames.length == 4).to.be.true;
84    expect(reservedNames.includes('matrix44')).to.be.true;
85    expect(reservedNames.includes('TranslateOption2')).to.be.true;
86    expect(reservedNames.includes('TestAdd')).to.be.true;
87    expect(reservedNames.includes('TestProperty')).to.be.true;
88
89    const reservedPropertyNames = mergedObConfig.reservedPropertyNames;
90    expect(reservedPropertyNames.length == 4).to.be.true;
91    expect(reservedPropertyNames.includes('matrix44')).to.be.true;
92    expect(reservedPropertyNames.includes('TranslateOption2')).to.be.true;
93    expect(reservedPropertyNames.includes('TestAdd')).to.be.true;
94    expect(reservedPropertyNames.includes('TestProperty')).to.be.true;
95
96    const reservedGlobalNames = mergedObConfig.reservedGlobalNames;
97    expect(reservedGlobalNames.length == 4).to.be.true;
98    expect(reservedGlobalNames.includes('matrix44')).to.be.true;
99    expect(reservedGlobalNames.includes('TranslateOption2')).to.be.true;
100    expect(reservedGlobalNames.includes('TestAdd')).to.be.true;
101    expect(reservedGlobalNames.includes('TestProperty')).to.be.true;
102
103    this.rollup.clearCache();
104  });
105
106  mocha.it('1-2: test resolveObfuscationConfigs: -enable-property-obfuscation', function () {
107    this.rollup.build(RELEASE);
108    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
109    const optionContent: string = '-enable-property-obfuscation';
110    fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, optionContent);
111    this.rollup.share.projectConfig.obfuscationOptions = {
112      'selfConfig': {
113        'ruleOptions': {
114          'enable': true,
115          'rules': [OBFUSCATION_RULE_PATH]
116        },
117        'consumerRules': [],
118      },
119      'dependencies': {
120        'libraries': [],
121        'hars': []
122      }
123    };
124    const obConfigResolver: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
125    const mergedObConfig: MergedConfig = obConfigResolver.resolveObfuscationConfigs();
126    const obOptions: ObOptions = mergedObConfig.options;
127    for (const [optionName, optionValue] of Object.entries(obOptions)) {
128      if (optionName === 'enablePropertyObfuscation') {
129        expect(optionValue).to.be.true;
130      } else {
131        if (typeof optionValue === 'boolean') {
132          expect(optionValue).to.be.false;
133        } else if (typeof optionValue === 'string') {
134          expect(optionValue === '').to.be.true;
135        }
136      }
137    }
138  });
139
140  mocha.it('1-3: test resolveObfuscationConfigs: -enable-property-obfuscation -enable-export-obfuscation', function () {
141    this.rollup.build(RELEASE);
142    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
143    const optionContent: string = '-enable-property-obfuscation\n-enable-export-obfuscation';
144    fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, optionContent);
145    this.rollup.share.projectConfig.obfuscationOptions = {
146      'selfConfig': {
147        'ruleOptions': {
148          'enable': true,
149          'rules': [OBFUSCATION_RULE_PATH]
150        },
151        'consumerRules': [],
152      },
153      'dependencies': {
154        'libraries': [],
155        'hars': []
156      }
157    };
158    const obConfigResolver: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
159    const mergedObConfig: MergedConfig = obConfigResolver.resolveObfuscationConfigs();
160    const obOptions: ObOptions = mergedObConfig.options;
161    for (const [optionName, optionValue] of Object.entries(obOptions)) {
162      if (optionName === 'enablePropertyObfuscation' || optionName === 'enableExportObfuscation') {
163        expect(optionValue).to.be.true;
164      } else {
165        if (typeof optionValue === 'boolean') {
166          expect(optionValue).to.be.false;
167        } else if (typeof optionValue === 'string') {
168          expect(optionValue === '').to.be.true;
169        }
170      }
171    }
172  });
173
174  mocha.it('1-3: test resolveObfuscationConfigs: -enable-property-obfuscation -enable-string-property-obfuscation', function () {
175    this.rollup.build(RELEASE);
176    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
177    const optionContent: string = '-enable-property-obfuscation\n-enable-string-property-obfuscation';
178    fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, optionContent);
179    this.rollup.share.projectConfig.obfuscationOptions = {
180      'selfConfig': {
181        'ruleOptions': {
182          'enable': true,
183          'rules': [OBFUSCATION_RULE_PATH]
184        },
185        'consumerRules': [],
186      },
187      'dependencies': {
188        'libraries': [],
189        'hars': []
190      }
191    };
192    const obConfigResolver: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
193    const mergedObConfig: MergedConfig = obConfigResolver.resolveObfuscationConfigs();
194    const obOptions: ObOptions = mergedObConfig.options;
195    for (const [optionName, optionValue] of Object.entries(obOptions)) {
196      if (optionName === 'enablePropertyObfuscation' || optionName === 'enableStringPropertyObfuscation') {
197        expect(optionValue).to.be.true;
198      } else {
199        if (typeof optionValue === 'boolean') {
200          expect(optionValue).to.be.false;
201        } else if (typeof optionValue === 'string') {
202          expect(optionValue === '').to.be.true;
203        }
204      }
205    }
206  });
207
208  mocha.it('1-4: test resolveObfuscationConfigs: -enable-property-obfuscation -enable-toplevel-obfuscation', function () {
209    this.rollup.build(RELEASE);
210    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
211    const optionContent: string = '-enable-property-obfuscation\n-enable-toplevel-obfuscation';
212    fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, optionContent);
213    this.rollup.share.projectConfig.obfuscationOptions = {
214      'selfConfig': {
215        'ruleOptions': {
216          'enable': true,
217          'rules': [OBFUSCATION_RULE_PATH]
218        },
219        'consumerRules': [],
220      },
221      'dependencies': {
222        'libraries': [],
223        'hars': []
224      }
225    };
226    const obConfigResolver: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
227    const mergedObConfig: MergedConfig = obConfigResolver.resolveObfuscationConfigs();
228    const obOptions: ObOptions = mergedObConfig.options;
229    for (const [optionName, optionValue] of Object.entries(obOptions)) {
230      if (optionName === 'enablePropertyObfuscation' || optionName === 'enableToplevelObfuscation') {
231        expect(optionValue).to.be.true;
232      } else {
233        if (typeof optionValue === 'boolean') {
234          expect(optionValue).to.be.false;
235        } else if (typeof optionValue === 'string') {
236          expect(optionValue === '').to.be.true;
237        }
238      }
239    }
240  });
241
242  mocha.it('1-5: test resolveObfuscationConfigs: enable all', function () {
243    this.rollup.build(RELEASE);
244    const logger: object = this.rollup.share.getLogger(OBFUSCATION_TOOL);
245    const optionContent: string = '-enable-property-obfuscation\n-enable-export-obfuscation\n-enable-filename-obfuscation\n'
246                                + '-enable-string-property-obfuscation\n-enable-toplevel-obfuscation';
247    fs.writeFileSync(`${OBFUSCATION_RULE_PATH}`, optionContent);
248    this.rollup.share.projectConfig.obfuscationOptions = {
249      'selfConfig': {
250        'ruleOptions': {
251          'enable': true,
252          'rules': [OBFUSCATION_RULE_PATH]
253        },
254        'consumerRules': [],
255      },
256      'dependencies': {
257        'libraries': [],
258        'hars': []
259      }
260    };
261    const obConfigResolver: ObConfigResolver =  new ObConfigResolver(this.rollup.share.projectConfig, logger, true);
262    const mergedObConfig: MergedConfig = obConfigResolver.resolveObfuscationConfigs();
263    const obOptions: ObOptions = mergedObConfig.options;
264    expect(obOptions.disableObfuscation).to.be.false;
265    expect(obOptions.enablePropertyObfuscation).to.be.true;
266    expect(obOptions.enableStringPropertyObfuscation).to.be.true;
267    expect(obOptions.enableToplevelObfuscation).to.be.true;
268    expect(obOptions.enableFileNameObfuscation).to.be.true;
269    expect(obOptions.enableExportObfuscation).to.be.true;
270    expect(obOptions.removeComments).to.be.false;
271    expect(obOptions.compact).to.be.false;
272    expect(obOptions.removeLog).to.be.false;
273  });
274
275  describe('2: test collectResevedFileNameInIDEConfig', function() {
276    let aceModuleJsonPath = '';
277    let ohPackagePath = '';
278    let projectConfig = {};
279    let modulePathMap = {};
280    let entryArray = [];
281    mocha.before('init config', function () {
282      aceModuleJsonPath = path.join(OBFUSCATE_TESTDATA_DIR, 'filename_obf/module.json');
283      ohPackagePath = path.join(OBFUSCATE_TESTDATA_DIR, 'filename_obf/oh-package.json5');
284      projectConfig = {
285        aceModuleJsonPath: aceModuleJsonPath,
286        projectPath: '/mnt/application/entry/src/main/ets',
287        cachePath: '/mnt/application/entry/build/default/cache/default/default@HarCompileArkTs/esmodules/release',
288        aceModuleBuild: '/mnt/application/entry/build/default/intermediates/loader_out',
289        compileShared: false,
290        compileHar: false,
291        byteCodeHar: false,
292      };
293      modulePathMap = {
294        'entry': '/mnt/application/entry',
295        'harpackagename': '/mnt/application/harPackageName'
296      };
297      entryArray = [
298        'entryability/EntryAbility',
299        'pages/Index'
300      ];
301    });
302
303    mocha.it('2-1: test collectResevedFileNameInIDEConfig in hsp module', function () {
304      projectConfig.compileShared = true;
305      projectConfig.compileHar = false;
306      projectConfig.byteCodeHar = false;
307      const acutualReservedFileNames: string[] = collectResevedFileNameInIDEConfig(ohPackagePath, projectConfig, modulePathMap, entryArray);
308      const expectReservedFileNames = [
309        'entryability',
310        'EntryAbility',
311        'pages',
312        'Index',
313        '',
314        'mnt',
315        'application',
316        'entry',
317        '',
318        'mnt',
319        'application',
320        'harPackageName',
321        'entry',
322        'harpackagename',
323        '.',
324        'Index-oh-package.ets',
325        '.',
326        'Type-oh-package.ets',
327        '..',
328        '..',
329        'Index2.ets',
330        '',
331        'mnt',
332        'application',
333        'entry',
334        'build',
335        'default',
336        'intermediates',
337        'loader_out',
338        'etsFortgz',
339        '',
340        'mnt',
341        'application',
342        'entry',
343        'src',
344        'main',
345        'ets',
346        '',
347        'mnt',
348        'application',
349        'entry',
350        'build',
351        'default',
352        'cache',
353        'default',
354        'default@HarCompileArkTs',
355        'esmodules',
356        'release'
357      ];
358      expect(acutualReservedFileNames.toString() === expectReservedFileNames.toString()).to.be.true;
359    });
360
361    mocha.it('2-2: test collectResevedFileNameInIDEConfig in hap module', function () {
362      projectConfig.compileShared = false;
363      projectConfig.compileHar = false;
364      projectConfig.byteCodeHar = false;
365      const acutualReservedFileNames: string[] = collectResevedFileNameInIDEConfig(ohPackagePath, projectConfig, modulePathMap, entryArray);
366      const expectReservedFileNames = [
367        'entryability',
368        'EntryAbility',
369        'pages',
370        'Index',
371        '',
372        'mnt',
373        'application',
374        'entry',
375        '',
376        'mnt',
377        'application',
378        'harPackageName',
379        'entry',
380        'harpackagename',
381        '.',
382        'Index-oh-package.ets',
383        '.',
384        'Type-oh-package.ets',
385        '..',
386        '..',
387        'Index2.ets',
388        '',
389        'mnt',
390        'application',
391        'entry',
392        'src',
393        'main',
394        'ets',
395        '',
396        'mnt',
397        'application',
398        'entry',
399        'build',
400        'default',
401        'cache',
402        'default',
403        'default@HarCompileArkTs',
404        'esmodules',
405        'release'
406      ];
407      expect(acutualReservedFileNames.toString() === expectReservedFileNames.toString()).to.be.true;
408    });
409
410    mocha.it('2-3: test collectResevedFileNameInIDEConfig in source har module', function () {
411      projectConfig.compileShared = false;
412      projectConfig.compileHar = true;
413      projectConfig.byteCodeHar = false;
414      const acutualReservedFileNames: string[] = collectResevedFileNameInIDEConfig(ohPackagePath, projectConfig, modulePathMap, entryArray);
415      const expectReservedFileNames = [
416        'entryability',
417        'EntryAbility',
418        'pages',
419        'Index',
420        '',
421        'mnt',
422        'application',
423        'entry',
424        '',
425        'mnt',
426        'application',
427        'harPackageName',
428        'entry',
429        'harpackagename',
430        '.',
431        'Index-oh-package.ets',
432        '.',
433        'Type-oh-package.ets',
434        '..',
435        '..',
436        'Index2.ets',
437        '',
438        'mnt',
439        'application',
440        'entry',
441        'src',
442        'main',
443        'ets',
444        '',
445        'mnt',
446        'application',
447        'entry',
448        'build',
449        'default',
450        'cache',
451        'default',
452        'default@HarCompileArkTs',
453        'esmodules',
454        'release'
455      ];
456      expect(acutualReservedFileNames.toString() === expectReservedFileNames.toString()).to.be.true;
457    });
458
459    mocha.it('2-4: test collectResevedFileNameInIDEConfig in byte code har module', function () {
460      projectConfig.compileShared = false;
461      projectConfig.compileHar = true;
462      projectConfig.byteCodeHar = true;
463      const acutualReservedFileNames: string[] = collectResevedFileNameInIDEConfig(ohPackagePath, projectConfig, modulePathMap, entryArray);
464      const expectReservedFileNames = [
465        'entryability',
466        'EntryAbility',
467        'pages',
468        'Index',
469        '',
470        'mnt',
471        'application',
472        'entry',
473        '',
474        'mnt',
475        'application',
476        'harPackageName',
477        'entry',
478        'harpackagename',
479        '.',
480        'Index-oh-package.ets',
481        '.',
482        'Type-oh-package.ets',
483        '..',
484        '..',
485        'Index2.ets',
486        '',
487        'mnt',
488        'application',
489        'entry',
490        'build',
491        'default',
492        'intermediates',
493        'loader_out',
494        'etsFortgz',
495        '',
496        'mnt',
497        'application',
498        'entry',
499        'src',
500        'main',
501        'ets',
502        '',
503        'mnt',
504        'application',
505        'entry',
506        'build',
507        'default',
508        'cache',
509        'default',
510        'default@HarCompileArkTs',
511        'esmodules',
512        'release'
513      ];
514      expect(acutualReservedFileNames.toString() === expectReservedFileNames.toString()).to.be.true;
515    });
516  })
517
518  mocha.it('3-1: test resolveKeepConfig', function () {
519    this.rollup.build(RELEASE);
520    this.rollup.share.projectConfig.obfuscationOptions = {
521      'selfConfig': {
522        'ruleOptions': {
523          'enable': true,
524          'rules': [ OBFUSCATION_RULE_PATH ]
525        },
526        'consumerRules': [],
527      },
528      'dependencies': {
529        'libraries': [],
530        'hars': []
531      }
532    };
533    const keepConfigs = [
534      './bundle',
535      './testdata/**/filename_obf',
536      '!./testdata/obfuscation/filename_obf',
537      './testdata/obfuscation/filename_obf/..',
538      './testdata/obfuscation/keep?ts',
539      './testdata/obfuscation/*',
540      './^',
541      '$',
542      '!./testdata/expect/*',
543      './.ohpm/(*)'
544    ];
545    let configs = {
546      keepSourceOfPaths: [],
547      keepUniversalPaths: [],
548      excludeUniversalPaths: [],
549      excludePathSet: new Set<string>()
550    };
551    const currentFilePath = __filename;
552    const configPath = path.dirname(currentFilePath);
553    const obResolver = new ObConfigResolver(this.rollup.share.projectConfig, console, true);
554    obResolver.resolveKeepConfig(keepConfigs, configs, configPath);
555    let excludePathArray = Array.from(configs.excludePathSet);
556    expect(configs.keepSourceOfPaths[0].includes('bundle')).to.be.true;
557    expect(configs.keepSourceOfPaths[1].includes('obfuscation')).to.be.true;
558    expect(configs.keepUniversalPaths[0].toString().includes('filename_obf')).to.be.true;
559    expect(configs.keepUniversalPaths[1].toString().includes('keep[^/]ts')).to.be.true;
560    expect(configs.keepUniversalPaths[2].toString().includes('[^/]*')).to.be.true;
561    expect(configs.keepUniversalPaths[3].toString().includes('.ohpm')).to.be.true;
562    expect(configs.excludeUniversalPaths[0].toString().includes('[^/]*')).to.be.true;
563    expect(excludePathArray[0].includes('filename_obf')).to.be.true;
564  });
565
566  mocha.it('4-1: test getSystemApiCache: -enable-property-obfuscation', function () {
567    let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/property');
568    let obfuscationOptions = {
569      'selfConfig': {
570        'ruleOptions': {
571          'enable': true,
572          'rules': [
573            path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/property/property.txt')
574          ]
575        },
576        'consumerRules': [],
577      },
578      'dependencies': {
579        'libraries': [],
580        'hars': []
581      },
582      'obfuscationCacheDir': obfuscationCacheDir,
583      'sdkApis': [
584        path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/system_api.d.ts')
585      ]
586    };
587    let projectConfig = {
588      obfuscationOptions,
589      compileHar: false
590    }
591    const obConfig: ObConfigResolver =  new ObConfigResolver(projectConfig, undefined);
592
593    const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
594    expect(mergedObConfig.reservedPropertyNames.length == 8).to.be.true;
595    expect(mergedObConfig.reservedPropertyNames.includes('TestClass')).to.be.true;
596    expect(mergedObConfig.reservedPropertyNames.includes('para1')).to.be.true;
597    expect(mergedObConfig.reservedPropertyNames.includes('para2')).to.be.true;
598    expect(mergedObConfig.reservedPropertyNames.includes('foo')).to.be.true;
599    expect(mergedObConfig.reservedPropertyNames.includes('TestFunction')).to.be.true;
600    expect(mergedObConfig.reservedPropertyNames.includes('funcPara1')).to.be.true;
601    expect(mergedObConfig.reservedPropertyNames.includes('funcPara2')).to.be.true;
602    expect(mergedObConfig.reservedPropertyNames.includes('ns')).to.be.true;
603    expect(mergedObConfig.reservedGlobalNames.length == 0).to.be.true;
604
605    let systemApiPath = obfuscationCacheDir + '/systemApiCache.json';
606    const data = fs.readFileSync(systemApiPath, 'utf8');
607    const systemApiContent = JSON.parse(data);
608
609    expect(systemApiContent.ReservedPropertyNames.length == 8).to.be.true;
610    expect(systemApiContent.ReservedPropertyNames.includes('TestClass')).to.be.true;
611    expect(systemApiContent.ReservedPropertyNames.includes('para1')).to.be.true;
612    expect(systemApiContent.ReservedPropertyNames.includes('para2')).to.be.true;
613    expect(systemApiContent.ReservedPropertyNames.includes('foo')).to.be.true;
614    expect(systemApiContent.ReservedPropertyNames.includes('TestFunction')).to.be.true;
615    expect(systemApiContent.ReservedPropertyNames.includes('funcPara1')).to.be.true;
616    expect(systemApiContent.ReservedPropertyNames.includes('funcPara2')).to.be.true;
617    expect(systemApiContent.ReservedPropertyNames.includes('ns')).to.be.true;
618    expect(systemApiContent.ReservedGlobalNames == undefined).to.be.true;
619
620    fs.unlinkSync(systemApiPath);
621  });
622
623  mocha.it('4-2: test getSystemApiCache: -enable-export-obfuscation', function () {
624    let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/export');
625    let obfuscationOptions = {
626      'selfConfig': {
627        'ruleOptions': {
628          'enable': true,
629          'rules': [
630            path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/export/export.txt')
631          ]
632        },
633        'consumerRules': [],
634      },
635      'dependencies': {
636        'libraries': [],
637        'hars': []
638      },
639      'obfuscationCacheDir': obfuscationCacheDir,
640      'sdkApis': [
641        path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/system_api.d.ts')
642      ]
643    };
644    let projectConfig = {
645      obfuscationOptions,
646      compileHar: false
647    }
648    const obConfig: ObConfigResolver =  new ObConfigResolver(projectConfig, undefined);
649
650    const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
651    expect(mergedObConfig.reservedNames.length == 0).to.be.true;
652    expect(mergedObConfig.reservedGlobalNames.length == 0).to.be.true;
653    expect(mergedObConfig.reservedPropertyNames.length == 0).to.be.true;
654
655    let systemApiPath = obfuscationCacheDir + '/systemApiCache.json';
656    const noSystemApi = fs.existsSync(systemApiPath);
657
658    expect(noSystemApi).to.be.false;
659  });
660
661  mocha.it('4-3: test getSystemApiCache: -enable-export-obfuscation -enable-toplevel-obfuscation', function () {
662    let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/export_toplevel');
663    let obfuscationOptions = {
664      'selfConfig': {
665        'ruleOptions': {
666          'enable': true,
667          'rules': [
668            path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/export_toplevel/export_toplevel.txt')
669          ]
670        },
671        'consumerRules': [],
672      },
673      'dependencies': {
674        'libraries': [],
675        'hars': []
676      },
677      'obfuscationCacheDir': obfuscationCacheDir,
678      'sdkApis': [
679        path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_obfuscation/system_api.d.ts')
680      ]
681    };
682    let projectConfig = {
683      obfuscationOptions,
684      compileHar: false
685    }
686    const obConfig: ObConfigResolver =  new ObConfigResolver(projectConfig, undefined);
687
688    const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
689    expect(mergedObConfig.reservedNames.length == 0).to.be.true;
690    expect(mergedObConfig.reservedPropertyNames.length == 0).to.be.true;
691    expect(mergedObConfig.reservedGlobalNames.length == 3).to.be.true;
692    expect(mergedObConfig.reservedGlobalNames.includes('TestClass')).to.be.true;
693    expect(mergedObConfig.reservedGlobalNames.includes('TestFunction')).to.be.true;
694    expect(mergedObConfig.reservedGlobalNames.includes('ns')).to.be.true;
695
696    let systemApiPath = obfuscationCacheDir + '/systemApiCache.json';
697    const data = fs.readFileSync(systemApiPath, 'utf8');
698    const systemApiContent = JSON.parse(data);
699
700    expect(systemApiContent.ReservedNames == undefined).to.be.true;
701    expect(systemApiContent.ReservedPropertyNames == undefined).to.be.true;
702    expect(systemApiContent.ReservedGlobalNames.length == 3).to.be.true;
703    expect(systemApiContent.ReservedGlobalNames.includes('TestClass')).to.be.true;
704    expect(systemApiContent.ReservedGlobalNames.includes('TestFunction')).to.be.true;
705    expect(systemApiContent.ReservedGlobalNames.includes('ns')).to.be.true;
706
707    fs.unlinkSync(systemApiPath);
708  });
709
710  mocha.it('5-1: test getRelativeSourcePath: filePath starts with projectRootPath', function () {
711    const filePath = 'C:/projects/my-project/src/file.ts';
712    const projectRootPath = 'C:/projects/my-project';
713    const belongProjectPath = undefined;
714    const relativePath = getRelativeSourcePath(filePath, projectRootPath, belongProjectPath);
715    expect(relativePath).to.equal('src/file.ts');
716  });
717
718  mocha.it('5-2: test getRelativeSourcePath: filePath starts with belongProjectPath', function () {
719    const filePath = 'C:/projects/another-project/src/file.ts';
720    const projectRootPath = 'C:/projects/my-project';
721    const belongProjectPath = 'C:/projects/another-project';
722    const relativePath = getRelativeSourcePath(filePath, projectRootPath, belongProjectPath);
723    expect(relativePath).to.equal('src/file.ts');
724  });
725
726  mocha.it('5-3: test getRelativeSourcePath: undefined projectRootPath', function () {
727    const filePath = 'C:/projects/another-project/src/file.ts';
728    const projectRootPath = undefined;
729    const belongProjectPath = 'C:/projects/another-project';
730    const relativePath = getRelativeSourcePath(filePath, projectRootPath, belongProjectPath);
731    expect(relativePath).to.equal('src/file.ts');
732  });
733
734  mocha.it('5-4: test getRelativeSourcePath: undefined belongProjectPath ', function () {
735    const filePath = 'C:/projects/my-project/src/file.ts';
736    const projectRootPath = 'C:/projects/my-project';
737    const belongProjectPath = undefined;
738    const relativePath = getRelativeSourcePath(filePath, projectRootPath, belongProjectPath);
739    expect(relativePath).to.equal('src/file.ts');
740  });
741});