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 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 16import { describe, it } from 'mocha'; 17import { assert, expect } from 'chai'; 18import { 19 ObOptionsForTest, 20 ObConfigResolver, 21 MergedConfig, 22 collectResevedFileNameInIDEConfig, 23 readNameCache, 24 handleUniversalPathInObf, 25 getArkguardNameCache, 26 fillNameCache, 27 writeObfuscationNameCache, 28 generateConsumerObConfigFile, 29 mangleFilePath, 30 enableObfuscatedFilePathConfig, 31 handleObfuscatedFilePath, 32 enableObfuscateFileName, 33 getRelativeSourcePath, 34 OptionTypeForTest, 35 SourceObConfig, 36 Obfuscation, 37 printUnobfuscationReasons, 38 clearNameCache 39} from '../../../src/initialization/ConfigResolver'; 40import { HvigorErrorInfo, PropCollections, renameFileNameModule } from '../../../src/ArkObfuscator'; 41import { 42 clearUnobfuscationNamesObj, 43 nameCacheMap, 44 unobfuscationNamesObj 45} from '../../../src/initialization/CommonObject'; 46import path from 'path'; 47import fs from 'fs'; 48import { FileUtils } from '../../../src/utils/FileUtils'; 49import sinon from 'sinon'; 50import { AtKeepCollections, UnobfuscationCollections } from '../../../src/utils/CommonCollections'; 51import { 52 clearHistoryUnobfuscatedMap, 53 historyAllUnobfuscatedNamesMap, 54 historyUnobfuscatedPropMap 55} from '../../../src/initialization/Initializer'; 56 57const OBFUSCATE_TESTDATA_DIR = path.resolve(__dirname, '../../testData/obfuscation/system_api_obfuscation'); 58const projectConfig = { 59 obfuscationOptions: { option1: 'value1' }, 60 compileHar: true 61}; 62 63function printObfLogger(errorInfo: string, errorCodeInfo: HvigorErrorInfo | string, level: string): void { 64 switch (level) { 65 case 'warn': 66 console.warn(errorInfo); 67 break; 68 case 'error': 69 console.error(errorInfo); 70 break; 71 default: 72 break; 73 } 74} 75 76function printObfHvigorLogger(errorInfo: string, errorCodeInfo: HvigorErrorInfo | string, level: string): void { 77 switch (level) { 78 case 'warn': 79 console.warn(errorCodeInfo); 80 break; 81 case 'error': 82 console.error(errorCodeInfo); 83 break; 84 default: 85 break; 86 } 87} 88 89const logger = console; 90const isTerser = false; 91let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 92 93describe('test for ConfigResolve', function() { 94 describe('ObOptions', () => { 95 it('should merge options correctly', () => { 96 const ob1 = new ObOptionsForTest(); 97 ob1.disableObfuscation = true; 98 ob1.enablePropertyObfuscation = true; 99 100 const ob2 = new ObOptionsForTest(); 101 ob2.enableToplevelObfuscation = true; 102 ob2.printNameCache = 'test'; 103 ob2.printKeptNamesPath = './test/ut/initialization/printKeptNamesPath.txt'; 104 ob2.applyNameCache = 'test case'; 105 106 ob1.mergeObOptions(ob2); 107 108 expect(ob1.disableObfuscation).to.be.true; 109 expect(ob1.enablePropertyObfuscation).to.be.true; 110 expect(ob1.enableToplevelObfuscation).to.be.true; 111 expect(ob1.printNameCache).to.equal('test'); 112 expect(ob1.printKeptNamesPath).to.equal('./test/ut/initialization/printKeptNamesPath.txt'); 113 expect(ob1.applyNameCache).to.equal('test case'); 114 }); 115 }); 116 117 describe('MergedConfig', () => { 118 describe('should merge two MergedConfig instances correctly', () => { 119 it('merge arrays and sets in MergeConfig', () => { 120 const config1 = new MergedConfig(); 121 config1.reservedPropertyNames = ['prop1']; 122 config1.reservedGlobalNames = ['global1']; 123 config1.keepComments = ['comment1']; 124 config1.excludePathSet.add('path1'); 125 126 const config2 = new MergedConfig(); 127 config2.reservedPropertyNames = ['prop2']; 128 config2.reservedGlobalNames = ['global2']; 129 config2.keepComments = ['comment2']; 130 config2.excludePathSet.add('path2'); 131 132 config1.mergeAllRules(config2); 133 134 expect(config1.reservedPropertyNames).to.deep.equal(['prop1', 'prop2']); 135 expect(config1.reservedGlobalNames).to.deep.equal(['global1', 'global2']); 136 expect(config1.keepComments).to.deep.equal(['comment1', 'comment2']); 137 expect(config1.excludePathSet).to.deep.equal(new Set(['path1', 'path2'])); 138 }); 139 140 it('merge options in MergeConfig', () => { 141 const config1 = new MergedConfig(); 142 config1.options.enableExportObfuscation = false; 143 config1.options.stripLanguageDefault = true; 144 config1.options.stripSystemApiArgs = true; 145 146 const config2 = new MergedConfig(); 147 config2.options.enableExportObfuscation = true; 148 config2.options.stripLanguageDefault = false; 149 config2.options.stripSystemApiArgs = true; 150 config1.mergeAllRules(config2); 151 152 expect(config1.options.disableObfuscation).to.be.false; 153 expect(config1.options.enablePropertyObfuscation).to.be.false; 154 expect(config1.options.enableToplevelObfuscation).to.be.false; 155 expect(config1.options.enableStringPropertyObfuscation).to.be.false; 156 expect(config1.options.removeLog).to.be.false; 157 expect(config1.options.compact).to.be.false; 158 expect(config1.options.removeComments).to.be.false; 159 expect(config1.options.enableFileNameObfuscation).to.be.false; 160 expect(config1.options.enableExportObfuscation).to.be.true; 161 expect(config1.options.stripLanguageDefault).to.be.true; 162 expect(config1.options.stripSystemApiArgs).to.be.true; 163 }); 164 }); 165 166 it('should sort and deduplicate arrays correctly', () => { 167 const config = new MergedConfig(); 168 config.reservedPropertyNames = ['prop2', 'prop1', 'prop1']; 169 config.reservedGlobalNames = ['global2', 'global1', 'global1']; 170 config.keepComments = ['comment2', 'comment1', 'comment1']; 171 172 config.sortAndDeduplicate(); 173 174 expect(config.reservedPropertyNames).to.deep.equal(['prop1', 'prop2']); 175 expect(config.reservedGlobalNames).to.deep.equal(['global1', 'global2']); 176 expect(config.keepComments).to.deep.equal(['comment1', 'comment2']); 177 }); 178 179 it('should serialize merged config correctly', () => { 180 let resultStr: string = ''; 181 const config = new MergedConfig(); 182 config.options = new ObOptionsForTest(); 183 config.options['option1'] = true; 184 config.options['option2'] = false; 185 config.options['disableObfuscation'] = true; 186 config.options['enableStringPropertyObfuscation'] = true; 187 config.reservedGlobalNames = ['global1']; 188 config.reservedPropertyNames = ['prop1']; 189 190 const serialized = config.serializeMergedConfig(); 191 const serializedExportSwitchMap = new Map([ 192 ['disableObfuscation', ObConfigResolver.KEEP_DTS], 193 ['enablePropertyObfuscation', ObConfigResolver.ENABLE_PROPERTY_OBFUSCATION], 194 ['enableStringPropertyObfuscation', ObConfigResolver.ENABLE_STRING_PROPERTY_OBFUSCATION], 195 ['enableToplevelObfuscation', ObConfigResolver.ENABLE_TOPLEVEL_OBFUSCATION], 196 ['compact', ObConfigResolver.COMPACT], 197 ['removeLog', ObConfigResolver.REMOVE_LOG], 198 ]); 199 200 expect(serialized).to.include(ObConfigResolver.KEEP_GLOBAL_NAME); 201 expect(serialized).to.include('global1'); 202 expect(serialized).to.include(ObConfigResolver.KEEP_PROPERTY_NAME); 203 expect(serialized).to.include('prop1'); 204 expect(serialized).to.not.include('option2'); 205 206 expect(ObConfigResolver.exportedSwitchMap.has(String('disableObfuscation'))).to.be.false; 207 expect(ObConfigResolver.exportedSwitchMap.has(String('enableStringPropertyObfuscation'))).to.be.true; 208 expect(resultStr).to.equal(''); 209 }); 210 }); 211 212 describe('ObConfigResolver', () => { 213 describe('constructor', () => { 214 it('should create an instance with the correct properties', () => { 215 const projectConfig = { 216 obfuscationOptions: { option1: 'value1' }, 217 compileHar: true 218 }; 219 const isTerser = false; 220 const myInstance = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 221 222 expect(myInstance).to.be.an('object'); 223 expect(myInstance.sourceObConfig).to.deep.equal({ option1: 'value1' }); 224 expect(myInstance.isHarCompiled).to.be.true; 225 expect(myInstance.isTerser).to.be.false; 226 }); 227 228 it('should create an instance with Terser enabled', () => { 229 const projectConfig = { 230 obfuscationOptions: { option1: 'value1' }, 231 compileHar: true 232 }; 233 const myInstance = new ObConfigResolver(projectConfig, printObfLogger, true); 234 235 expect(myInstance).to.be.an('object'); 236 expect(myInstance.sourceObConfig).to.deep.equal({ option1: 'value1' }); 237 expect(myInstance.isHarCompiled).to.be.true; 238 expect(myInstance.isTerser).to.be.true; 239 }); 240 }); 241 242 describe('resolveObfuscationConfigs', () => { 243 const projectConfig = { 244 obfuscationOptions: { option1: 'value1' }, 245 compileHar: true 246 }; 247 const logger = console; 248 const isTerser = false; 249 let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 250 let testClass: ObConfigResolver & { 251 performancePrinter?: any; 252 }; 253 testClass = newObConfigResolver; 254 255 it('should return a MergedConfig object when sourceObConfig is undefined', () => { 256 testClass.sourceObConfig = undefined; 257 testClass.isHarCompiled = true; 258 testClass.performancePrinter = {}; 259 const result = testClass.resolveObfuscationConfigs(); 260 generateConsumerObConfigFile(testClass.sourceObConfig, undefined); 261 262 expect(testClass.sourceObConfig).to.be.an.undefined; 263 expect(result).to.deep.equal(new MergedConfig()); 264 expect(result).to.be.an('object'); 265 expect(result).to.have.property('options'); 266 }); 267 268 it('should return a MergedConfig object when sourceObConfig is null', () => { 269 testClass.sourceObConfig = null; 270 testClass.isHarCompiled = true; 271 testClass.performancePrinter = {}; 272 const result = testClass.resolveObfuscationConfigs(); 273 generateConsumerObConfigFile(null, undefined); 274 275 expect(testClass.sourceObConfig).to.be.a.null; 276 expect(result).to.deep.equal(new MergedConfig()); 277 expect(result).to.be.an('object'); 278 expect(result).to.have.property('options'); 279 }); 280 281 it('should handle the case when sourceObConfig.selfConfig.ruleOptions.enable is false', function () { 282 testClass.sourceObConfig = { 283 selfConfig: { 284 ruleOptions: { enable: false }, 285 }, 286 dependencies: { libraries: [], hars: [] }, 287 }; 288 generateConsumerObConfigFile(testClass.sourceObConfig, undefined); 289 const result = testClass.resolveObfuscationConfigs(); 290 291 expect(result).to.be.an('object'); 292 expect(result).to.have.property('options'); 293 expect(result.options.disableObfuscation).to.be.true; 294 }); 295 296 it('should handle the case when sourceObConfig.selfConfig.ruleOptions.enable is true', function () { 297 testClass.sourceObConfig = { 298 selfConfig: { 299 ruleOptions: { enable: true }, 300 }, 301 dependencies: { libraries: [], hars: [] }, 302 }; 303 generateConsumerObConfigFile(testClass.sourceObConfig, undefined); 304 const result = testClass.resolveObfuscationConfigs(); 305 306 expect(result).to.be.an('object'); 307 expect(result).to.have.property('options'); 308 expect(result.options.disableObfuscation).to.be.false; 309 }); 310 311 it('should handle the case when enableObfuscation is false', () => { 312 const sourceObConfig = { 313 selfConfig: { 314 ruleOptions: { enable: false }, 315 consumerRules: ['./test/testData/obfuscation/keepDts/obfuscation-template.txt'], 316 }, 317 dependencies: { libraries: [], hars: [] }, 318 obfuscationCacheDir: './test/testData/cache', 319 options: { 320 disableObfuscation: true 321 }, 322 exportRulePath: '', 323 sdkApis: [] 324 }; 325 const isHarCompiled = true; 326 let enableObfuscation = sourceObConfig.selfConfig.ruleOptions.enable; 327 let selfConfig = new MergedConfig(); 328 enableObfuscation = !selfConfig.options.disableObfuscation; 329 let needConsumerConfigs = isHarCompiled && sourceObConfig.selfConfig.consumerRules && 330 sourceObConfig.selfConfig.consumerRules.length > 0; 331 let needDependencyConfigs = enableObfuscation || needConsumerConfigs; 332 let dependencyConfigs = new MergedConfig(); 333 const dependencyMaxLength = Math.max( 334 sourceObConfig.dependencies.libraries.length, 335 sourceObConfig.dependencies.hars.length, 336 ); 337 newObConfigResolver.getDependencyConfigsForTest(sourceObConfig, dependencyConfigs); 338 339 expect(needConsumerConfigs).to.be.true; 340 expect(!dependencyMaxLength).to.be.true; 341 expect(needDependencyConfigs).to.be.true; 342 expect(dependencyConfigs).to.deep.equal(new MergedConfig()); 343 expect(enableObfuscation).to.be.true; 344 }); 345 346 it('should handle the case when enableObfuscation is false', () => { 347 const localHarConfig = { 348 selfConfig: { 349 ruleOptions: { 350 enable: true, 351 rules: ['./test/testData/obfuscation/Configs/localHar/obfuscation-rules.txt'] 352 }, 353 consumerRules: [], 354 libDir: "", 355 consumerFiles: "" 356 }, 357 dependencies: { libraries: [], hars: [] }, 358 sdkApis: [], 359 obfuscationCacheDir: '', 360 exportRulePath: '' 361 }; 362 363 const sourceObConfig = { 364 selfConfig: { 365 options: { 366 disableObfuscation: false, 367 enablePropertyObfuscation: true, 368 enableExportObfuscation: true, 369 enableToplevelObfuscation: true 370 }, 371 ruleOptions: { enable: true }, 372 consumerRules: ['./test/testData/obfuscation/keepDts/obfuscation-template.txt'], 373 libDir: '' 374 }, 375 dependencies: { libraries: [localHarConfig.selfConfig], hars: [] }, 376 obfuscationCacheDir: './test/testData/cache', 377 sdkApis: [], 378 exportRulePath: '' 379 }; 380 const isHarCompiled = true; 381 let enableObfuscation = sourceObConfig.selfConfig.ruleOptions.enable; 382 let selfConfig = new MergedConfig(); 383 enableObfuscation = !selfConfig.options.disableObfuscation; 384 let needConsumerConfigs = isHarCompiled && sourceObConfig.selfConfig.consumerRules && 385 sourceObConfig.selfConfig.consumerRules.length > 0; 386 let needDependencyConfigs = enableObfuscation || needConsumerConfigs; 387 let dependencyConfigs = new MergedConfig(); 388 const dependencyMaxLength = Math.max( 389 sourceObConfig.dependencies.libraries.length, 390 sourceObConfig.dependencies.hars.length, 391 ); 392 const mergedConfigs = newObConfigResolver.getMergedConfigsForTest(selfConfig, dependencyConfigs); 393 newObConfigResolver.handleReservedArrayForTest(mergedConfigs); 394 let needKeepSystemApi = enableObfuscation && 395 (mergedConfigs.options.enablePropertyObfuscation || 396 (mergedConfigs.options.enableExportObfuscation && mergedConfigs.options.enableToplevelObfuscation)); 397 398 newObConfigResolver.getDependencyConfigsForTest(sourceObConfig, dependencyConfigs); 399 400 expect(needConsumerConfigs).to.be.true; 401 expect(!dependencyMaxLength).to.be.false; 402 expect(needDependencyConfigs).to.be.true; 403 expect(dependencyConfigs).to.deep.equal(new MergedConfig()); 404 expect(enableObfuscation).to.be.true; 405 expect(needKeepSystemApi).to.be.false; 406 expect(needConsumerConfigs).to.be.true; 407 }); 408 409 it('should handle the case when enableObfuscation is true', () => { 410 testClass.sourceObConfig = { 411 selfConfig: { 412 ruleOptions: { enable: true }, 413 consumerRules: ['./test/testData/obfuscation/keepDts/obfuscation-template.txt'], 414 }, 415 dependencies: { libraries: [], hars: [] }, 416 obfuscationCacheDir: './test/testData/cache', 417 options: { 418 disableObfuscation: true 419 } 420 }; 421 testClass.isHarCompiled = true; 422 testClass.performancePrinter = {}; 423 let enableObfuscation = testClass.sourceObConfig.selfConfig.ruleOptions.enable; 424 let selfConfig = new MergedConfig(); 425 newObConfigResolver.getSelfConfigsForTest(selfConfig); 426 enableObfuscation = !selfConfig.options.disableObfuscation; 427 enableObfuscation = false; 428 let needConsumerConfigs = testClass.isHarCompiled && testClass.sourceObConfig.selfConfig.consumerRules && 429 testClass.sourceObConfig.selfConfig.consumerRules.length > 0; 430 let needDependencyConfigs = enableObfuscation || needConsumerConfigs; 431 let dependencyConfigs = new MergedConfig(); 432 const dependencyMaxLength = Math.max( 433 testClass.sourceObConfig.dependencies.libraries.length, 434 testClass.sourceObConfig.dependencies.hars.length, 435 testClass.sourceObConfig.dependencies.hsps?.length ?? 0, 436 testClass.sourceObConfig.dependencies.hspLibraries?.length ?? 0 437 ); 438 newObConfigResolver.getDependencyConfigsForTest(testClass.sourceObConfig, dependencyConfigs); 439 440 expect(needConsumerConfigs).to.be.true; 441 expect(!dependencyMaxLength).to.be.true; 442 expect(needDependencyConfigs).to.be.true; 443 expect(dependencyConfigs).to.deep.equal(new MergedConfig()); 444 expect(enableObfuscation).to.be.false; 445 }); 446 }); 447 448 describe('getSelfConfigs', () => { 449 it('should create an instance with the correct properties', () => { 450 const projectConfig = { 451 obfuscationOptions: { 452 selfConfig: { 453 ruleOptions: { 454 rules: [] 455 } 456 } 457 }, 458 compileHar: true 459 }; 460 const isTerser = false; 461 const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 462 463 expect(resolver).to.be.an('object'); 464 expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); 465 expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); 466 expect(resolver.isTerser).to.equal(isTerser); 467 }); 468 469 it('should create an instance with the correct properties', () => { 470 const projectConfig = { 471 obfuscationOptions: { 472 selfConfig: { 473 ruleOptions: { 474 rules: ['./test/ut/initialization/tempNameCache.json'] 475 } 476 } 477 }, 478 compileHar: true 479 }; 480 const isTerser = false; 481 const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 482 483 expect(resolver).to.be.an('object'); 484 expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); 485 expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); 486 expect(resolver.isTerser).to.equal(isTerser); 487 }); 488 489 it('should get self configs correctly', () => { 490 const projectConfig = { 491 obfuscationOptions: { 492 selfConfig: { 493 ruleOptions: { 494 rules: ['./test/ut/initialization/tempNameCache.json'] 495 } 496 } 497 }, 498 compileHar: true 499 }; 500 const isTerser = false; 501 const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 502 const selfConfigs = new MergedConfig(); 503 504 resolver.getSelfConfigsForTest(selfConfigs); 505 506 expect(resolver).to.be.an('object'); 507 expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); 508 expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); 509 expect(resolver.isTerser).to.equal(isTerser); 510 }); 511 }); 512 513 describe('getConfigByPath', () => { 514 const projectConfig = { 515 obfuscationOptions: { 516 selfConfig: { 517 ruleOptions: { 518 rules: ['./test/testData/obfuscation/filename_obf/getConfigByPath.json'] 519 } 520 } 521 }, 522 compileHar: true 523 }; 524 let sandbox; 525 let instance; 526 527 beforeEach(() => { 528 sandbox = sinon.createSandbox(); 529 instance = new ObConfigResolver(projectConfig, printObfLogger, true); 530 instance.logger = { error: sandbox.stub() }; 531 }); 532 533 afterEach(() => { 534 sandbox.restore(); 535 }); 536 537 it('should read file content and handle config content', () => { 538 const path = './test/testData/obfuscation/filename_obf/getConfigByPath.json'; 539 let fileContent; 540 const expectedContent = '{"key": "value"}'; 541 const configs = new MergedConfig(); 542 543 fileContent = fs.readFileSync(path, 'utf-8'); 544 instance.getConfigByPathForTest(path, configs); 545 instance.handleConfigContent(fileContent, configs, path); 546 547 expect(fileContent).to.equal(expectedContent); 548 expect(configs).to.be.an.instanceOf(MergedConfig); 549 }); 550 551 it('should log error and throw when failed to open file', () => { 552 const path = './test/testData/obfuscation/filename_obf/non-existent-file.json'; 553 const configs = new MergedConfig(); 554 const stub = sinon.stub(console, 'error'); 555 const errorMessage = `Failed to open ${path}. Error message: Error: ENOENT: no such file or directory, open ${path}`; 556 sandbox.stub(fs, 'readFileSync').throws(new Error(`ENOENT: no such file or directory, open ${path}`)); 557 try { 558 instance.getConfigByPath(path, configs); 559 } catch (err) { 560 } 561 expect(stub.calledWith(errorMessage)).to.be.true; 562 stub.restore(); 563 }); 564 565 it('should log error and throw when failed to open file with hvigor errorCode', () => { 566 const path = './test/testData/obfuscation/filename_obf/non-existent-file.json'; 567 const configs = new MergedConfig(); 568 const stub = sinon.stub(console, 'error'); 569 const errorMessage = { 570 code: '10804001', 571 description: 'ArkTS compiler Error', 572 cause: `Failed to open obfuscation config file from ${path}. Error message: Error: ENOENT: no such file or directory, open ${path}`, 573 position: path, 574 solutions: [`Please check whether ${path} exists.`], 575 }; 576 instance = new ObConfigResolver(projectConfig, printObfHvigorLogger, true); 577 sandbox.stub(fs, 'readFileSync').throws(new Error(`ENOENT: no such file or directory, open ${path}`)); 578 try { 579 instance.getConfigByPath(path, configs); 580 } catch (err) { 581 } 582 expect(stub.calledWith(errorMessage)).to.be.true; 583 stub.restore(); 584 }); 585 }); 586 587 it('should return a new MergedConfig instance when sourceObConfig is not defined', function() { 588 const projectConfig = { 589 sourceObConfig: null, 590 getMergedConfig: function() { 591 let sourceObConfig = this.sourceObConfig; 592 if (!sourceObConfig) { 593 return new MergedConfig(); 594 } 595 } 596 }; 597 598 const result = projectConfig.getMergedConfig(); 599 expect(result).to.be.an.instanceOf(MergedConfig); 600 }); 601 602 describe('resolveKeepConfig', () => { 603 it('should resolve keep config correctly, starts with "!" and contains "*", not starts with "!"', () => { 604 const keepConfigs = ['!test/*/exclude.js', 'test/include.js']; 605 const configs = new MergedConfig(); 606 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 607 608 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 609 610 expect(configs.excludeUniversalPaths).to.have.lengthOf(1); 611 expect(configs.keepUniversalPaths).to.have.lengthOf(0); 612 expect(configs.excludePathSet).to.have.lengthOf(0); 613 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 614 }); 615 616 it('should resolve keep config correctly, starts with "!" and contains "*", not starts with "!" and "?"', () => { 617 const keepConfigs = ['!test/*/exclude.js', 'test/?/include.js']; 618 const configs = new MergedConfig(); 619 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 620 621 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 622 623 expect(configs.excludeUniversalPaths).to.have.lengthOf(1); 624 expect(configs.keepUniversalPaths).to.have.lengthOf(1); 625 expect(configs.excludePathSet).to.have.lengthOf(0); 626 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 627 }); 628 629 it('should resolve keep config correctly, both start with "!", contains "*" and "?"', () => { 630 const keepConfigs = ['!test/*/exclude.js', '!test/?/include.js']; 631 const configs = new MergedConfig(); 632 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 633 634 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 635 636 expect(configs.excludeUniversalPaths).to.have.lengthOf(2); 637 expect(configs.keepUniversalPaths).to.have.lengthOf(0); 638 expect(configs.excludePathSet).to.have.lengthOf(0); 639 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 640 }); 641 642 it('should resolve keep config correctly, not starts with "!" and contains "*" and "?"', () => { 643 const keepConfigs = ['test/*/exclude.js', 'test/?/include.js']; 644 const configs = new MergedConfig(); 645 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 646 647 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 648 649 expect(configs.excludeUniversalPaths).to.have.lengthOf(0); 650 expect(configs.keepUniversalPaths).to.have.lengthOf(2); 651 expect(configs.excludePathSet).to.have.lengthOf(0); 652 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 653 }); 654 655 it('should resolve keep config correctly, starts with "!", not starts with "!" and contains "*"', () => { 656 const keepConfigs = ['!test/exclude.js', 'test/*/include.js']; 657 const configs = new MergedConfig(); 658 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 659 660 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 661 662 expect(configs.excludeUniversalPaths).to.have.lengthOf(0); 663 expect(configs.keepUniversalPaths).to.have.lengthOf(1); 664 expect(configs.excludePathSet).to.have.lengthOf(1); 665 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 666 }); 667 668 it('should resolve keep config correctly, starts with "!" and not starts with "!"', () => { 669 const keepConfigs = ['!test/exclude.js', 'test/include.js']; 670 const configs = new MergedConfig(); 671 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 672 673 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 674 675 expect(configs.excludeUniversalPaths).to.have.lengthOf(0); 676 expect(configs.keepUniversalPaths).to.have.lengthOf(0); 677 expect(configs.excludePathSet).to.have.lengthOf(1); 678 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 679 }); 680 681 it('should resolve keep config correctly, both start with "!"', () => { 682 const keepConfigs = ['!test/exclude.js', '!test/include.js']; 683 const configs = new MergedConfig(); 684 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 685 686 newObConfigResolver.resolveKeepConfig(keepConfigs, configs, configPath); 687 688 expect(configs.excludeUniversalPaths).to.have.lengthOf(0); 689 expect(configs.keepUniversalPaths).to.have.lengthOf(0); 690 expect(configs.excludePathSet).to.have.lengthOf(2); 691 expect(configs.keepSourceOfPaths).to.have.lengthOf(0); 692 }); 693 }); 694 695 describe('resolvePath', () => { 696 it('should return the absolute path if token is already an absolute path', () => { 697 const configPath = '/home/user/config.json'; 698 const token = '/home/user/data.txt'; 699 const result = newObConfigResolver.resolvePathForTest(configPath, token); 700 expect(result).to.equal(token); 701 }); 702 703 it('should resolve the relative path based on the config file directory', () => { 704 const configPath = '/home/user/config.json'; 705 const token = 'data.txt'; 706 const expectedResult = '/home/user/data.txt'; 707 const result = newObConfigResolver.resolvePathForTest(configPath, token); 708 expect(result).to.equal(expectedResult); 709 }); 710 }); 711 712 describe('getTokenType', () => { 713 it('should return the correct OptionType for each token', () => { 714 const tokens = [ 715 ObConfigResolver.KEEP_DTS, 716 ObConfigResolver.KEEP_GLOBAL_NAME, 717 ObConfigResolver.KEEP_PROPERTY_NAME, 718 ObConfigResolver.KEEP_FILE_NAME, 719 ObConfigResolver.KEEP_COMMENTS, 720 ObConfigResolver.DISABLE_OBFUSCATION, 721 ObConfigResolver.ENABLE_PROPERTY_OBFUSCATION, 722 ObConfigResolver.ENABLE_STRING_PROPERTY_OBFUSCATION, 723 ObConfigResolver.ENABLE_TOPLEVEL_OBFUSCATION, 724 ObConfigResolver.ENABLE_FILENAME_OBFUSCATION, 725 ObConfigResolver.ENABLE_EXPORT_OBFUSCATION, 726 ObConfigResolver.ENABLE_LIB_OBFUSCATION_OPTIONS, 727 ObConfigResolver.REMOVE_COMMENTS, 728 ObConfigResolver.COMPACT, 729 ObConfigResolver.REMOVE_LOG, 730 ObConfigResolver.PRINT_NAMECACHE, 731 ObConfigResolver.PRINT_KEPT_NAMES, 732 ObConfigResolver.APPLY_NAMECACHE, 733 ObConfigResolver.KEEP, 734 ObConfigResolver.EXTRA_OPTIONS, 735 ObConfigResolver.STRIP_LANGUAGE_DEFAULT, 736 ObConfigResolver.STRIP_SYSTEM_API_ARGS, 737 'unknown_token' 738 ]; 739 740 const expectedResults = [ 741 OptionTypeForTest.KEEP_DTS, 742 OptionTypeForTest.KEEP_GLOBAL_NAME, 743 OptionTypeForTest.KEEP_PROPERTY_NAME, 744 OptionTypeForTest.KEEP_FILE_NAME, 745 OptionTypeForTest.KEEP_COMMENTS, 746 OptionTypeForTest.DISABLE_OBFUSCATION, 747 OptionTypeForTest.ENABLE_PROPERTY_OBFUSCATION, 748 OptionTypeForTest.ENABLE_STRING_PROPERTY_OBFUSCATION, 749 OptionTypeForTest.ENABLE_TOPLEVEL_OBFUSCATION, 750 OptionTypeForTest.ENABLE_FILENAME_OBFUSCATION, 751 OptionTypeForTest.ENABLE_EXPORT_OBFUSCATION, 752 OptionTypeForTest.ENABLE_LIB_OBFUSCATION_OPTIONS, 753 OptionTypeForTest.REMOVE_COMMENTS, 754 OptionTypeForTest.COMPACT, 755 OptionTypeForTest.REMOVE_LOG, 756 OptionTypeForTest.PRINT_NAMECACHE, 757 OptionTypeForTest.PRINT_KEPT_NAMES, 758 OptionTypeForTest.APPLY_NAMECACHE, 759 OptionTypeForTest.KEEP, 760 OptionTypeForTest.EXTRA_OPTIONS, 761 OptionTypeForTest.STRIP_LANGUAGE_DEFAULT, 762 OptionTypeForTest.STRIP_SYSTEM_API_ARGS, 763 OptionTypeForTest.NONE 764 ]; 765 766 for (let i = 0; i < tokens.length; i++) { 767 const result = newObConfigResolver.getTokenTypeForTest(tokens[i]); 768 expect(result).to.equal(expectedResults[i]); 769 } 770 }); 771 }); 772 773 describe('handleConfigContent', () => { 774 it('should handle config content correctly', () => { 775 const configs: MergedConfig = new MergedConfig(); 776 configs.options = new ObOptionsForTest(); 777 778 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 779 const data = ` 780 #This is a comment 781 -none, 782 -keep obfuscation-template.txt, 783 -keep-dts, 784 -keep-global-name, 785 -keep-property-name, 786 -keep-file-name, 787 -keep-comments, 788 -disable-obfuscation, 789 -enable-property-obfuscation, 790 -enable-string-property-obfuscation, 791 -enable-toplevel-obfuscation, 792 -enable-filename-obfuscation, 793 -enable-export-obfuscation, 794 -enable-lib-obfuscation-options, 795 -use-keep-in-source, 796 -extra-options strip-language-default, 797 -extra-options strip-system-api-args, 798 -keep-parameter-names 799 -remove-comments, 800 -compact, 801 -remove-log, 802 -print-namecache obfuscation-template.txt, 803 -print-kept-names, 804 -apply-namecache obfuscation-template.txt 805 `; 806 807 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 808 809 expect(configs.options.disableObfuscation).to.be.true; 810 expect(configs.options.enablePropertyObfuscation).to.be.true; 811 expect(configs.options.enableStringPropertyObfuscation).to.be.true; 812 expect(configs.options.enableToplevelObfuscation).to.be.true; 813 expect(configs.options.removeComments).to.be.true; 814 expect(configs.options.enableFileNameObfuscation).to.be.true; 815 expect(configs.options.enableExportObfuscation).to.be.true; 816 expect(configs.options.enableLibObfuscationOptions).to.be.true; 817 expect(configs.options.enableAtKeep).to.be.true; 818 expect(configs.options.compact).to.be.true; 819 expect(configs.options.removeLog).to.be.true; 820 expect(configs.options.stripLanguageDefault).to.be.true; 821 expect(configs.options.stripSystemApiArgs).to.be.true; 822 expect(configs.options.keepParameterNames).to.be.true; 823 }); 824 825 it('should handle config content correctly when diffenent combinations use line break splitting', () => { 826 const configs: MergedConfig = new MergedConfig(); 827 configs.options = new ObOptionsForTest(); 828 829 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 830 const data = ` 831 #This is a comment 832 -extra-options 833 strip-language-default 834 -extra-options 835 strip-system-api-args 836 `; 837 838 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 839 840 expect(configs.options.stripLanguageDefault).to.be.true; 841 expect(configs.options.stripSystemApiArgs).to.be.true; 842 }); 843 844 it('should handle config content correctly when diffenent combinations use line break splitting', () => { 845 const configs: MergedConfig = new MergedConfig(); 846 configs.options = new ObOptionsForTest(); 847 848 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 849 const data = ` 850 #This is a comment 851 -extra-options strip-language-default 852 -extra-options strip-system-api-args 853 `; 854 855 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 856 857 expect(configs.options.stripLanguageDefault).to.be.true; 858 expect(configs.options.stripSystemApiArgs).to.be.true; 859 }); 860 861 it('should handle config content correctly when diffenent combinations use space separation', () => { 862 const configs: MergedConfig = new MergedConfig(); 863 configs.options = new ObOptionsForTest(); 864 865 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 866 const data = ` 867 #This is a comment 868 -extra-options strip-language-default -extra-options strip-system-api-args 869 `; 870 871 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 872 873 expect(configs.options.stripLanguageDefault).to.be.true; 874 expect(configs.options.stripSystemApiArgs).to.be.true; 875 }); 876 877 it('should handle config content correctly when diffenent combinations only use one "-extra-options"', () => { 878 const configs: MergedConfig = new MergedConfig(); 879 configs.options = new ObOptionsForTest(); 880 881 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 882 const data = ` 883 #This is a comment 884 -extra-options strip-language-default, strip-system-api-args 885 `; 886 887 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 888 889 expect(configs.options.stripLanguageDefault).to.be.true; 890 expect(configs.options.stripSystemApiArgs).to.be.true; 891 }); 892 893 it('should handle config content correctly when no "-extra-options"', () => { 894 const configs: MergedConfig = new MergedConfig(); 895 configs.options = new ObOptionsForTest(); 896 897 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 898 const data = ` 899 #This is a comment 900 strip-language-default, strip-system-api-args 901 `; 902 903 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 904 905 expect(configs.options.stripLanguageDefault).to.be.false; 906 expect(configs.options.stripSystemApiArgs).to.be.false; 907 }); 908 909 it('should handle config content correctly when have invalid token between "-extra-options" and "strip-language-default"', () => { 910 const configs: MergedConfig = new MergedConfig(); 911 configs.options = new ObOptionsForTest(); 912 913 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 914 const data = ` 915 #This is a comment 916 -extra-options 917 invalid-token 918 strip-system-api-args 919 strip-language-default 920 `; 921 922 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 923 924 expect(configs.options.stripLanguageDefault).to.be.false; 925 expect(configs.options.stripSystemApiArgs).to.be.false; 926 }); 927 928 it('should handle config content correctly when have valid token between "-extra-options" and "strip-language-default"', () => { 929 const configs: MergedConfig = new MergedConfig(); 930 configs.options = new ObOptionsForTest(); 931 932 const configPath = './test/testData/obfuscation/keepDts/obfuscation-template.txt'; 933 const data = ` 934 #This is a comment 935 -extra-options 936 -enable-property-obfuscation 937 strip-language-default 938 strip-system-api-args 939 `; 940 941 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 942 943 expect(configs.options.enablePropertyObfuscation).to.be.true; 944 expect(configs.options.stripLanguageDefault).to.be.false; 945 expect(configs.options.stripSystemApiArgs).to.be.false; 946 }); 947 948 it('should handle config content correctly when enable lib obfuscation options', () => { 949 const configs: MergedConfig = new MergedConfig(); 950 configs.options = new ObOptionsForTest(); 951 952 const configPath = './test/testData/obfuscation/enable_lib_obfuscation_options/obfuscation-rule.txt'; 953 const data = fs.readFileSync(configPath, 'utf-8'); 954 955 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 956 957 expect(configs.options.enableLibObfuscationOptions).to.be.true; 958 }); 959 960 it('should handle config correctly when enable bytecode obfuscation options', () => { 961 const configs: MergedConfig = new MergedConfig(); 962 configs.options = new ObOptionsForTest(); 963 964 const configPath = './test/testData/obfuscation/enable_lib_obfuscation_options/obfuscation-rule.txt'; 965 const data = ` 966 -enable-bytecode-obfuscation 967 -enable-bytecode-obfuscation-debugging 968 -enable-bytecode-obfuscation-enhanced 969 -enable-bytecode-obfuscation-arkui 970 `; 971 newObConfigResolver.handleConfigContentForTest(data, configs, configPath); 972 expect(configs.options.bytecodeObf.enable).to.be.true; 973 expect(configs.options.bytecodeObf.debugging).to.be.true; 974 expect(configs.options.bytecodeObf.enhanced).to.be.true; 975 expect(configs.options.bytecodeObf.obfArkUI).to.be.true; 976 }); 977 }); 978 979 describe('1: test Api collectSystemApiWhitelist', function() { 980 it('1-1: test collectSystemApiWhitelist: -enable-property-obfuscation', function () { 981 let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'property'); 982 let obfuscationOptions = { 983 'selfConfig': { 984 'ruleOptions': { 985 'enable': true, 986 'rules': [ 987 path.join(OBFUSCATE_TESTDATA_DIR, 'property/property.txt') 988 ] 989 }, 990 'consumerRules': [], 991 }, 992 'dependencies': { 993 'libraries': [], 994 'hars': [] 995 }, 996 'obfuscationCacheDir': obfuscationCacheDir, 997 'sdkApis': [ 998 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api.d.ts') 999 ] 1000 }; 1001 let projectConfig = { 1002 obfuscationOptions, 1003 compileHar: false 1004 }; 1005 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, undefined); 1006 obConfig.resolveObfuscationConfigs(); 1007 const reservedSdkApiForProp = UnobfuscationCollections.reservedSdkApiForProp; 1008 const reservedSdkApiForGlobal = UnobfuscationCollections.reservedSdkApiForGlobal; 1009 const reservedSdkApiForLocal = UnobfuscationCollections.reservedSdkApiForLocal; 1010 1011 expect(reservedSdkApiForProp.size == 12).to.be.true; 1012 expect(reservedSdkApiForProp.has('TestClass')).to.be.true; 1013 expect(reservedSdkApiForProp.has('para1')).to.be.true; 1014 expect(reservedSdkApiForProp.has('para2')).to.be.true; 1015 expect(reservedSdkApiForProp.has('foo')).to.be.true; 1016 expect(reservedSdkApiForProp.has('TestFunction')).to.be.true; 1017 expect(reservedSdkApiForProp.has('funcPara1')).to.be.true; 1018 expect(reservedSdkApiForProp.has('funcPara2')).to.be.true; 1019 expect(reservedSdkApiForProp.has('ns')).to.be.true; 1020 expect(reservedSdkApiForProp.has('NavigationBuilderRegister')).to.be.true; 1021 expect(reservedSdkApiForProp.has('ViewV2')).to.be.true; 1022 expect(reservedSdkApiForProp.has('initParam')).to.be.true; 1023 expect(reservedSdkApiForProp.has('updateParam')).to.be.true; 1024 expect(reservedSdkApiForProp.has('NavigationBuilderRegister')).to.be.true; 1025 expect(reservedSdkApiForProp.has('__Recycle__')).to.be.false; 1026 expect(reservedSdkApiForGlobal.size === 0).to.be.true; 1027 expect(reservedSdkApiForLocal.size === 8).to.be.true; 1028 UnobfuscationCollections.clear(); 1029 1030 let systemApiPath = obfuscationCacheDir + '/systemApiCache.json'; 1031 const data = fs.readFileSync(systemApiPath, 'utf8'); 1032 const systemApiContent = JSON.parse(data); 1033 1034 expect(systemApiContent.ReservedPropertyNames.length == 12).to.be.true; 1035 expect(systemApiContent.ReservedPropertyNames.includes('TestClass')).to.be.true; 1036 expect(systemApiContent.ReservedPropertyNames.includes('para1')).to.be.true; 1037 expect(systemApiContent.ReservedPropertyNames.includes('para2')).to.be.true; 1038 expect(systemApiContent.ReservedPropertyNames.includes('foo')).to.be.true; 1039 expect(systemApiContent.ReservedPropertyNames.includes('TestFunction')).to.be.true; 1040 expect(systemApiContent.ReservedPropertyNames.includes('funcPara1')).to.be.true; 1041 expect(systemApiContent.ReservedPropertyNames.includes('funcPara2')).to.be.true; 1042 expect(systemApiContent.ReservedPropertyNames.includes('ns')).to.be.true; 1043 expect(systemApiContent.ReservedPropertyNames.includes('NavigationBuilderRegister')).to.be.true; 1044 expect(systemApiContent.ReservedPropertyNames.includes('ViewV2')).to.be.true; 1045 expect(systemApiContent.ReservedPropertyNames.includes('initParam')).to.be.true; 1046 expect(systemApiContent.ReservedPropertyNames.includes('updateParam')).to.be.true; 1047 expect(systemApiContent.ReservedPropertyNames.includes('NavigationBuilderRegister')).to.be.true; 1048 expect(systemApiContent.ReservedPropertyNames.includes('__Recycle__')).to.be.false; 1049 expect(systemApiContent.ReservedGlobalNames === undefined).to.be.true; 1050 expect(systemApiContent.ReservedLocalNames.size === 8).to.be.false; 1051 1052 fs.unlinkSync(systemApiPath); 1053 }); 1054 1055 it('1-2: test collectSystemApiWhitelist: -enable-export-obfuscation', function () { 1056 let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'export'); 1057 let obfuscationOptions = { 1058 'selfConfig': { 1059 'ruleOptions': { 1060 'enable': true, 1061 'rules': [ 1062 path.join(OBFUSCATE_TESTDATA_DIR, 'export/export.txt') 1063 ] 1064 }, 1065 'consumerRules': [], 1066 }, 1067 'dependencies': { 1068 'libraries': [], 1069 'hars': [] 1070 }, 1071 'obfuscationCacheDir': obfuscationCacheDir, 1072 'sdkApis': [ 1073 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api.d.ts') 1074 ] 1075 }; 1076 let projectConfig = { 1077 obfuscationOptions, 1078 compileHar: false 1079 }; 1080 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, undefined); 1081 obConfig.resolveObfuscationConfigs(); 1082 const reservedSdkApiForProp = UnobfuscationCollections.reservedSdkApiForProp; 1083 const reservedSdkApiForGlobal = UnobfuscationCollections.reservedSdkApiForGlobal; 1084 1085 expect(reservedSdkApiForProp.size == 0).to.be.true; 1086 expect(reservedSdkApiForGlobal.size == 0).to.be.true; 1087 UnobfuscationCollections.clear(); 1088 1089 let systemApiPath = obfuscationCacheDir + '/systemApiCache.json'; 1090 const noSystemApi = fs.existsSync(systemApiPath); 1091 1092 expect(noSystemApi).to.be.false; 1093 }); 1094 1095 it('1-3: test collectSystemApiWhitelist: -enable-export-obfuscation -enable-toplevel-obfuscation', function () { 1096 let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'export_toplevel'); 1097 let obfuscationOptions = { 1098 'selfConfig': { 1099 'ruleOptions': { 1100 'enable': true, 1101 'rules': [ 1102 path.join(OBFUSCATE_TESTDATA_DIR, 'export_toplevel/export_toplevel.txt') 1103 ] 1104 }, 1105 'consumerRules': [], 1106 }, 1107 'dependencies': { 1108 'libraries': [], 1109 'hars': [] 1110 }, 1111 'obfuscationCacheDir': obfuscationCacheDir, 1112 'sdkApis': [ 1113 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api.d.ts') 1114 ] 1115 }; 1116 let projectConfig = { 1117 obfuscationOptions, 1118 compileHar: false 1119 }; 1120 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, undefined); 1121 obConfig.resolveObfuscationConfigs(); 1122 const reservedSdkApiForProp = UnobfuscationCollections.reservedSdkApiForProp; 1123 const reservedSdkApiForGlobal = UnobfuscationCollections.reservedSdkApiForGlobal; 1124 1125 expect(reservedSdkApiForProp.size == 0).to.be.true; 1126 expect(reservedSdkApiForGlobal.size == 3).to.be.true; 1127 expect(reservedSdkApiForGlobal.has('TestClass')).to.be.true; 1128 expect(reservedSdkApiForGlobal.has('TestFunction')).to.be.true; 1129 expect(reservedSdkApiForGlobal.has('ns')).to.be.true; 1130 UnobfuscationCollections.clear(); 1131 1132 let systemApiPath = obfuscationCacheDir + '/systemApiCache.json'; 1133 const data = fs.readFileSync(systemApiPath, 'utf8'); 1134 const systemApiContent = JSON.parse(data); 1135 1136 expect(systemApiContent.ReservedPropertyNames == undefined).to.be.true; 1137 expect(systemApiContent.ReservedGlobalNames.length == 3).to.be.true; 1138 expect(systemApiContent.ReservedGlobalNames.includes('TestClass')).to.be.true; 1139 expect(systemApiContent.ReservedGlobalNames.includes('TestFunction')).to.be.true; 1140 expect(systemApiContent.ReservedGlobalNames.includes('ns')).to.be.true; 1141 1142 fs.unlinkSync(systemApiPath); 1143 }); 1144 1145 it('1-4: test collectSystemApiWhitelist: system api when -enable-property-obfuscation and -extra-options strip-system-api-args', function () { 1146 let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_optimize'); 1147 let obfuscationOptions = { 1148 'selfConfig': { 1149 'ruleOptions': { 1150 'enable': true, 1151 'rules': [ 1152 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api_optimize/system_api_optimize.txt') 1153 ] 1154 }, 1155 'consumerRules': [], 1156 }, 1157 'dependencies': { 1158 'libraries': [], 1159 'hars': [] 1160 }, 1161 'obfuscationCacheDir': obfuscationCacheDir, 1162 'sdkApis': [ 1163 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api.d.ts') 1164 ] 1165 }; 1166 let projectConfig = { 1167 obfuscationOptions, 1168 compileHar: false 1169 }; 1170 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, undefined); 1171 obConfig.resolveObfuscationConfigs(); 1172 const reservedSdkApiForProp = UnobfuscationCollections.reservedSdkApiForProp; 1173 const reservedSdkApiForGlobal = UnobfuscationCollections.reservedSdkApiForGlobal; 1174 const reservedSdkApiForLocal = UnobfuscationCollections.reservedSdkApiForLocal; 1175 1176 expect(reservedSdkApiForProp.has('TestClass')).to.be.true; 1177 expect(reservedSdkApiForProp.has('para1')).to.be.true; 1178 expect(reservedSdkApiForProp.has('para2')).to.be.true; 1179 expect(reservedSdkApiForProp.has('foo')).to.be.true; 1180 expect(reservedSdkApiForProp.has('TestFunction')).to.be.true; 1181 expect(reservedSdkApiForProp.has('funcPara1')).to.be.false; 1182 expect(reservedSdkApiForProp.has('funcPara2')).to.be.false; 1183 expect(reservedSdkApiForProp.has('ns')).to.be.true; 1184 expect(reservedSdkApiForProp.has('NavigationBuilderRegister')).to.be.true; 1185 expect(reservedSdkApiForProp.has('__Recycle__')).to.be.true; 1186 expect(reservedSdkApiForGlobal.size == 0).to.be.true; 1187 expect(reservedSdkApiForLocal.size == 0).to.be.true; 1188 UnobfuscationCollections.clear(); 1189 1190 let systemApiPath = obfuscationCacheDir + '/systemApiCache.json'; 1191 const data = fs.readFileSync(systemApiPath, 'utf8'); 1192 const systemApiContent = JSON.parse(data); 1193 1194 expect(systemApiContent.ReservedPropertyNames.includes('TestClass')).to.be.true; 1195 expect(systemApiContent.ReservedPropertyNames.includes('para1')).to.be.true; 1196 expect(systemApiContent.ReservedPropertyNames.includes('para2')).to.be.true; 1197 expect(systemApiContent.ReservedPropertyNames.includes('foo')).to.be.true; 1198 expect(systemApiContent.ReservedPropertyNames.includes('TestFunction')).to.be.true; 1199 expect(systemApiContent.ReservedPropertyNames.includes('funcPara1')).to.be.false; 1200 expect(systemApiContent.ReservedPropertyNames.includes('funcPara2')).to.be.false; 1201 expect(systemApiContent.ReservedPropertyNames.includes('ns')).to.be.true; 1202 expect(systemApiContent.ReservedPropertyNames.includes('NavigationBuilderRegister')).to.be.true; 1203 expect(systemApiContent.ReservedPropertyNames.includes('__Recycle__')).to.be.true; 1204 expect(systemApiContent.ReservedGlobalNames === undefined).to.be.true; 1205 expect(systemApiContent.ReservedLocalNames === undefined).to.be.true; 1206 1207 fs.unlinkSync(systemApiPath); 1208 }); 1209 1210 it('1-5: test collectSystemApiWhitelist: -enable-bytecode-obfuscation', function () { 1211 let obfuscationCacheDir = path.join(OBFUSCATE_TESTDATA_DIR, 'bytecode_obfuscation'); 1212 let obfuscationOptions = { 1213 'selfConfig': { 1214 'ruleOptions': { 1215 'enable': true, 1216 'rules': [ 1217 path.join(OBFUSCATE_TESTDATA_DIR, 'bytecode_obfuscation/bytecode_obfuscation.txt') 1218 ] 1219 }, 1220 'consumerRules': [], 1221 }, 1222 'dependencies': { 1223 'libraries': [], 1224 'hars': [] 1225 }, 1226 'obfuscationCacheDir': obfuscationCacheDir, 1227 'sdkApis': [ 1228 path.join(OBFUSCATE_TESTDATA_DIR, 'system_api.d.ts') 1229 ] 1230 }; 1231 let projectConfig = { 1232 obfuscationOptions, 1233 compileHar: false 1234 }; 1235 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, undefined); 1236 obConfig.resolveObfuscationConfigs(); 1237 const reservedSdkApiForProp = UnobfuscationCollections.reservedSdkApiForProp; 1238 const reservedSdkApiForGlobal = UnobfuscationCollections.reservedSdkApiForGlobal; 1239 const reservedSdkApiForLocal = UnobfuscationCollections.reservedSdkApiForLocal; 1240 1241 expect(reservedSdkApiForProp.size == 12).to.be.true; 1242 expect(reservedSdkApiForGlobal.size == 3).to.be.true; 1243 expect(reservedSdkApiForLocal.size == 8).to.be.true; 1244 UnobfuscationCollections.clear(); 1245 1246 let systemApiPath = obfuscationCacheDir + '/systemApiCache.json'; 1247 const data = fs.readFileSync(systemApiPath, 'utf8'); 1248 const systemApiContent = JSON.parse(data); 1249 1250 expect(systemApiContent.ReservedLocalNames.length == 8).to.be.true; 1251 expect(systemApiContent.ReservedPropertyNames.length == 12).to.be.true; 1252 expect(systemApiContent.ReservedGlobalNames.length == 3).to.be.true; 1253 fs.unlinkSync(systemApiPath); 1254 }); 1255 }); 1256 }); 1257 1258 describe('getMergedConfigs', function() { 1259 it('should merge all configs', () => { 1260 const config1 = new MergedConfig(); 1261 config1.options.enableLibObfuscationOptions = true; 1262 1263 const config2 = new MergedConfig(); 1264 config2.options.enablePropertyObfuscation = true; 1265 config2.options.enableStringPropertyObfuscation = true; 1266 config2.options.enableToplevelObfuscation = true; 1267 config2.options.compact = true; 1268 config2.options.removeLog = true; 1269 config2.reservedPropertyNames = ['prop2']; 1270 config2.reservedGlobalNames = ['global2']; 1271 config2.keepComments = ['comment2']; 1272 config2.excludePathSet.add('path2'); 1273 1274 const projectConfig = { 1275 obfuscationOptions: { option1: 'value1' }, 1276 compileHar: false 1277 }; 1278 const logger = console; 1279 const isTerser = false; 1280 let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 1281 const res: MergedConfig = newObConfigResolver.getMergedConfigsForTest(config1, config2); 1282 1283 expect(res.options.enablePropertyObfuscation).to.be.true; 1284 expect(res.options.enableStringPropertyObfuscation).to.be.true; 1285 expect(res.options.enableToplevelObfuscation).to.be.true; 1286 expect(res.options.compact).to.be.true; 1287 expect(res.options.removeLog).to.be.true; 1288 expect(res.reservedPropertyNames).to.deep.equal(['prop2']); 1289 expect(res.reservedGlobalNames).to.deep.equal(['global2']); 1290 expect(res.keepComments).to.deep.equal(['comment2']); 1291 expect(res.excludePathSet).to.deep.equal(new Set(['path2'])); 1292 }); 1293 1294 it('should merge only keep configs', () => { 1295 const config1 = new MergedConfig(); 1296 config1.options.enableLibObfuscationOptions = false; 1297 1298 const config2 = new MergedConfig(); 1299 config2.options.enablePropertyObfuscation = true; 1300 config2.options.enableStringPropertyObfuscation = true; 1301 config2.options.enableToplevelObfuscation = true; 1302 config2.options.compact = true; 1303 config2.options.removeLog = true; 1304 config2.reservedPropertyNames = ['prop2']; 1305 config2.reservedGlobalNames = ['global2']; 1306 config2.keepComments = ['comment2']; 1307 config2.excludePathSet.add('path2'); 1308 1309 const projectConfig = { 1310 obfuscationOptions: { option1: 'value1' }, 1311 compileHar: false 1312 }; 1313 const logger = console; 1314 const isTerser = false; 1315 let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 1316 const res: MergedConfig = newObConfigResolver.getMergedConfigsForTest(config1, config2); 1317 1318 expect(res.options.enablePropertyObfuscation).to.be.false; 1319 expect(res.options.enableStringPropertyObfuscation).to.be.false; 1320 expect(res.options.enableToplevelObfuscation).to.be.false; 1321 expect(res.options.compact).to.be.false; 1322 expect(res.options.removeLog).to.be.false; 1323 expect(res.reservedPropertyNames).to.deep.equal(['prop2']); 1324 expect(res.reservedGlobalNames).to.deep.equal(['global2']); 1325 expect(res.keepComments).to.deep.equal(['comment2']); 1326 expect(res.excludePathSet).to.deep.equal(new Set(['path2'])); 1327 }); 1328 }); 1329 1330 describe('genConsumerConfigFilesForTest', function (){ 1331 it('should merge all configs: compileHar is true', () => { 1332 const config1 = new MergedConfig(); 1333 config1.options.enableLibObfuscationOptions = true; 1334 1335 const config2 = new MergedConfig(); 1336 config2.options.enablePropertyObfuscation = true; 1337 config2.options.enableStringPropertyObfuscation = true; 1338 config2.options.enableToplevelObfuscation = true; 1339 config2.options.compact = true; 1340 config2.options.removeLog = true; 1341 config2.reservedPropertyNames = ['prop2']; 1342 config2.reservedGlobalNames = ['global2']; 1343 config2.keepComments = ['comment2']; 1344 config2.excludePathSet.add('path2'); 1345 1346 const projectConfig = { 1347 obfuscationOptions: { option1: 'value1' }, 1348 compileHar: true 1349 }; 1350 const logger = console; 1351 const isTerser = false; 1352 let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 1353 const sourceObConfig: SourceObConfig = { 1354 selfConfig: {} as Obfuscation, 1355 sdkApis: [], 1356 obfuscationCacheDir: '', 1357 exportRulePath: './test/ut/initialization/obfuscation.txt', 1358 dependencies: { 1359 libraries: [], 1360 hars: [], 1361 hsps: [], 1362 hspLibraries: [], 1363 }, 1364 }; 1365 newObConfigResolver.genConsumerConfigFilesForTest(sourceObConfig, config1, config2); 1366 1367 let res: string = fs.readFileSync(sourceObConfig.exportRulePath, 'utf-8'); 1368 expect(res.indexOf('-enable-lib-obfuscation-options') === -1).to.be.true; 1369 expect(res.indexOf('-enable-property-obfuscation') !== -1).to.be.true; 1370 expect(res.indexOf('-enable-string-property-obfuscation') !== -1).to.be.true; 1371 expect(res.indexOf('-enable-toplevel-obfuscation') !== -1).to.be.true; 1372 expect(res.indexOf('-compact') !== -1).to.be.true; 1373 expect(res.indexOf('-remove-log') !== -1).to.be.true; 1374 expect(res.indexOf('-keep-global-name') !== -1).to.be.true; 1375 expect(res.indexOf('global2') !== -1).to.be.true; 1376 expect(res.indexOf('-keep-property-name') !== -1).to.be.true; 1377 expect(res.indexOf('prop2') !== -1).to.be.true; 1378 1379 fs.unlinkSync(sourceObConfig.exportRulePath); 1380 }); 1381 1382 it('should merge all configs: compileHar is false', () => { 1383 const config1 = new MergedConfig(); 1384 config1.options.enableLibObfuscationOptions = false; 1385 1386 const config2 = new MergedConfig(); 1387 config2.options.enablePropertyObfuscation = true; 1388 config2.options.enableStringPropertyObfuscation = true; 1389 config2.options.enableToplevelObfuscation = true; 1390 config2.options.compact = true; 1391 config2.options.removeLog = true; 1392 config2.reservedPropertyNames = ['prop2']; 1393 config2.reservedGlobalNames = ['global2']; 1394 config2.keepComments = ['comment2']; 1395 config2.excludePathSet.add('path2'); 1396 1397 const projectConfig = { 1398 obfuscationOptions: { option1: 'value1' }, 1399 compileHar: false 1400 }; 1401 const logger = console; 1402 const isTerser = false; 1403 let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); 1404 const sourceObConfig: SourceObConfig = { 1405 selfConfig: {} as Obfuscation, 1406 sdkApis: [], 1407 obfuscationCacheDir: '', 1408 exportRulePath: './test/ut/initialization/obfuscation.txt', 1409 dependencies: { 1410 libraries: [], 1411 hars: [], 1412 hsps: [], 1413 hspLibraries: [], 1414 }, 1415 }; 1416 newObConfigResolver.genConsumerConfigFilesForTest(sourceObConfig, config1, config2); 1417 1418 let res: string = fs.readFileSync(sourceObConfig.exportRulePath, 'utf-8'); 1419 1420 expect(res.indexOf('-enable-lib-obfuscation-options') === -1).to.be.true; 1421 expect(res.indexOf('-enable-property-obfuscation') === -1).to.be.true; 1422 expect(res.indexOf('-enable-string-property-obfuscation') === -1).to.be.true; 1423 expect(res.indexOf('-enable-toplevel-obfuscation') === -1).to.be.true; 1424 expect(res.indexOf('-compact') === -1).to.be.true; 1425 expect(res.indexOf('-remove-log') === -1).to.be.true; 1426 expect(res.indexOf('-keep-global-name') === -1).to.be.true; 1427 expect(res.indexOf('global2') === -1).to.be.true; 1428 expect(res.indexOf('-keep-property-name') === -1).to.be.true; 1429 expect(res.indexOf('prop2') === -1).to.be.true; 1430 1431 fs.unlinkSync(sourceObConfig.exportRulePath); 1432 }); 1433 }); 1434 1435 describe('collectResevedFileNameInIDEConfig', () => { 1436 let collectPathReservedStringStub; 1437 1438 beforeEach(function() { 1439 collectPathReservedStringStub = sinon.stub(FileUtils, 'collectPathReservedString'); 1440 collectPathReservedStringStub.callsFake((filePath, reservedArray) => reservedArray.push(filePath)); 1441 }); 1442 1443 afterEach(function() { 1444 collectPathReservedStringStub.restore(); 1445 projectConfig.compileShared = false; 1446 projectConfig.byteCodeHar = false; 1447 projectConfig.aceModuleJsonPath = ''; 1448 }); 1449 1450 const ohPackagePath = './test/ut/initialization/testOhPackagePath.json'; 1451 let projectConfig = { 1452 aceModuleJsonPath: '', 1453 projectPath: 'path/to/project', 1454 cachePath: 'path/to/cache', 1455 compileShared: false, 1456 byteCodeHar: false, 1457 aceModuleBuild: 'path/to/build', 1458 } 1459 const entryArray = ['path/to/entry1', 'path/to/entry2']; 1460 const modulePathMap = { 1461 module1: 'path/to/module1', 1462 module2: 'path/to/module2', 1463 }; 1464 1465 it('should collect reserved file names from entryArray and projectConfig', () => { 1466 const result = collectResevedFileNameInIDEConfig('', projectConfig, undefined, entryArray); 1467 expect(result).to.deep.equal(['path/to/entry1', 'path/to/entry2','path/to/project','path/to/cache']); 1468 }); 1469 it('should collect reserved file names from modulePathMap and projectConfig', () => { 1470 projectConfig.compileShared = true; 1471 const result = collectResevedFileNameInIDEConfig('', projectConfig, modulePathMap, []); 1472 expect(result).to.deep.equal(['path/to/module1', 'path/to/module2','module1','module2','path/to/build','etsFortgz','path/to/project','path/to/cache']); 1473 }); 1474 it('should collect reserved file names from ohPackagePath and projectConfig', () => { 1475 projectConfig.byteCodeHar = true; 1476 const result = collectResevedFileNameInIDEConfig(ohPackagePath, projectConfig, undefined, []); 1477 expect(result).to.deep.equal(['path/to/main', 'path/to/types','path/to/build','etsFortgz','path/to/project','path/to/cache']); 1478 }); 1479 it('should collect reserved file names from moduleJsonPath and projectConfig', () => { 1480 projectConfig.aceModuleJsonPath = "./test/ut/initialization/testModuleJsonPath_0.json"; 1481 const hasSrcEntry = collectResevedFileNameInIDEConfig('', projectConfig, undefined, []); 1482 expect(hasSrcEntry).to.deep.equal(['path/to/srcEntry','path/to/project','path/to/cache']); 1483 1484 projectConfig.aceModuleJsonPath = "./test/ut/initialization/testModuleJsonPath_1.json"; 1485 const noSrcEntry = collectResevedFileNameInIDEConfig('', projectConfig, undefined, []); 1486 expect(noSrcEntry).to.deep.equal(['path/to/project','path/to/cache']); 1487 }); 1488 }); 1489 1490 describe('readNameCache', () => { 1491 let tempFilePath; 1492 let testData; 1493 let fsWriteFileSyncStub; 1494 let fsUnlinkSyncStub; 1495 let PropCollections; 1496 let renameFileNameModule; 1497 1498 beforeEach(() => { 1499 PropCollections = { 1500 historyMangledTable: {}, 1501 }; 1502 renameFileNameModule = { 1503 historyFileNameMangledTable: {}, 1504 }; 1505 1506 tempFilePath = './test/ut/initialization/tempNameCache.json'; 1507 testData = { 1508 compileSdkVersion: '1.0.0', 1509 PropertyCache: { key1: 'value1', key2: 'value2' }, 1510 FileNameCache: { key3: 'value3', key4: 'value4' }, 1511 extraKey: '', 1512 }; 1513 1514 fsWriteFileSyncStub = sinon.stub(fs, 'writeFileSync').callsFake((path, data) => {}); 1515 fsUnlinkSyncStub = sinon.stub(fs, 'unlinkSync').callsFake((path) => {}); 1516 }); 1517 1518 afterEach(() => { 1519 fsWriteFileSyncStub.restore(); 1520 fsUnlinkSyncStub.restore(); 1521 }); 1522 1523 it('should read and parse the name cache file correctly', () => { 1524 readNameCache(tempFilePath, printObfLogger); 1525 1526 expect(nameCacheMap.get('extraKey')).to.equal(''); 1527 }); 1528 }); 1529 1530 describe('readNameCache', () => { 1531 let fsReadFileSyncStub; 1532 let logger; 1533 const testPath = './test/ut/initialization/tempNameCache.json'; 1534 1535 beforeEach(() => { 1536 fsReadFileSyncStub = sinon.stub(fs, 'readFileSync').returns('{"compileSdkVersion":"1.0","PropertyCache":{},"FileNameCache":{}}'); 1537 logger = { error: sinon.spy(), printError: (msg)=>{}}; 1538 }); 1539 1540 afterEach(() => { 1541 fsReadFileSyncStub.restore(); 1542 }); 1543 1544 it('should read the name cache file and parse its content', () => { 1545 readNameCache(testPath, printObfLogger); 1546 expect(PropCollections.historyMangledTable).to.deep.equal(new Map()); 1547 expect(renameFileNameModule.historyFileNameMangledTable).to.deep.equal(new Map()); 1548 expect(nameCacheMap.get('compileSdkVersion')).to.be.undefined; 1549 expect(logger.error.called).to.be.false; 1550 }); 1551 1552 it('should handle errors when reading the file', () => { 1553 const mockLogger = { 1554 error: (message: string) => console.error(message), 1555 }; 1556 1557 const nonExistentFilePath = './test/ut/initialization/nonExistentFile.json'; 1558 try { 1559 readNameCache(nonExistentFilePath, printObfLogger); 1560 } catch (err) { 1561 } 1562 expect(logger.error.calledWith(`Failed to open ${nonExistentFilePath}. Error message: Test error`)).to.be.false; 1563 }); 1564 1565 it('should handle errors when reading the file with hvigor errorCode', () => { 1566 const mockLogger = { 1567 error: (message: string) => console.error(message), 1568 }; 1569 1570 const nonExistentFilePath = './test/ut/initialization/nonExistentFile.json'; 1571 try { 1572 readNameCache(nonExistentFilePath, printObfHvigorLogger); 1573 } catch (err) { 1574 } 1575 const errorMessage = { 1576 code: '10804002', 1577 description: 'ArkTS compiler Error', 1578 cause: `Failed to open namecache file from ${nonExistentFilePath}, Error message: Test error`, 1579 position: nonExistentFilePath, 1580 solutions: [`Please check ${nonExistentFilePath} as error message suggested.`], 1581 }; 1582 expect(logger.error.calledWith(errorMessage)).to.be.false; 1583 }); 1584 }); 1585 1586 describe('handleUniversalPathInObf', () => { 1587 it('should handle universal paths correctly', () => { 1588 const mergedObConfig: MergedConfig = { 1589 options: new ObOptionsForTest(), 1590 reservedPropertyNames: [], 1591 reservedGlobalNames: [], 1592 reservedNames: [], 1593 reservedFileNames: [], 1594 keepComments: [], 1595 keepSourceOfPaths: [], 1596 universalReservedPropertyNames: [], 1597 universalReservedGlobalNames: [], 1598 keepUniversalPaths: [/test\.js$/], 1599 excludeUniversalPaths: [/exclude\.js$/], 1600 excludePathSet: new Set(), 1601 mergeKeepOptions: () => {}, 1602 mergeAllRules: () => {}, 1603 sortAndDeduplicate: () => {}, 1604 serializeMergedConfig: () => { 1605 return JSON.stringify(this); 1606 } 1607 }; 1608 const allSourceFilePaths = new Set([ 1609 'test.js', 1610 'exclude.js', 1611 'other.js', 1612 ]); 1613 1614 handleUniversalPathInObf(mergedObConfig, allSourceFilePaths); 1615 expect(mergedObConfig.keepSourceOfPaths).to.deep.equal(['test.js']); 1616 expect(mergedObConfig.excludePathSet).to.deep.equal(new Set(['exclude.js'])); 1617 }); 1618 1619 it('should return early if mergedObConfig is not provided or both keepUniversalPaths and excludeUniversalPaths are empty', () => { 1620 const mergedObConfig: MergedConfig = { 1621 options: new ObOptionsForTest(), 1622 reservedPropertyNames: [], 1623 reservedGlobalNames: [], 1624 reservedNames: [], 1625 reservedFileNames: [], 1626 keepComments: [], 1627 keepSourceOfPaths: [], 1628 universalReservedPropertyNames: [], 1629 universalReservedGlobalNames: [], 1630 keepUniversalPaths: [], 1631 excludeUniversalPaths: [], 1632 excludePathSet: new Set(), 1633 mergeKeepOptions: () => {}, 1634 mergeAllRules: () => {}, 1635 sortAndDeduplicate: () => {}, 1636 serializeMergedConfig: () => { 1637 return JSON.stringify(this); 1638 } 1639 }; 1640 const allSourceFilePaths = new Set([]); 1641 const result = handleUniversalPathInObf(mergedObConfig, allSourceFilePaths); 1642 1643 expect(result).to.be.undefined; 1644 }); 1645 }); 1646 1647 describe('getArkguardNameCache', () => { 1648 it('should return a JSON string with the correct structure', () => { 1649 const enablePropertyObfuscation = true; 1650 const enableFileNameObfuscation = true; 1651 const sdkVersion = '1.0.0'; 1652 const entryPackageInfo = 'packageInfo'; 1653 1654 const result = getArkguardNameCache(enablePropertyObfuscation, enableFileNameObfuscation, false, sdkVersion, entryPackageInfo); 1655 1656 try { 1657 JSON.parse(result); 1658 // If no error is thrown, the result is a valid JSON string 1659 console.log('Test passed: getArkguardNameCache returns a valid JSON string'); 1660 } catch (error) { 1661 console.error('Test failed: getArkguardNameCache does not return a valid JSON string'); 1662 } 1663 }); 1664 1665 it('should include the correct compileSdkVersion and entryPackageInfo', () => { 1666 const enablePropertyObfuscation = false; 1667 const enableFileNameObfuscation = false; 1668 const sdkVersion = '2.0.0'; 1669 const entryPackageInfo = 'anotherPackageInfo'; 1670 1671 const result = getArkguardNameCache(enablePropertyObfuscation, enableFileNameObfuscation, false, sdkVersion, entryPackageInfo); 1672 const parsedResult = JSON.parse(result); 1673 1674 expect(parsedResult.compileSdkVersion).to.equal(sdkVersion); 1675 expect(parsedResult.entryPackageInfo).to.equal(entryPackageInfo); 1676 }); 1677 1678 it('PropertyCache exists when enable export obfuscation', () => { 1679 const enablePropertyObfuscation = false; 1680 const enableFileNameObfuscation = false; 1681 const enableExportObfuscation = true; 1682 const sdkVersion = '2.0.0'; 1683 const entryPackageInfo = 'anotherPackageInfo'; 1684 1685 PropCollections.historyMangledTable.set("key1", "value1"); 1686 PropCollections.historyMangledTable.set("key2", "value2"); 1687 PropCollections.globalMangledTable.set("key3", "value3"); 1688 PropCollections.globalMangledTable.set("key4", "value4"); 1689 const result = getArkguardNameCache(enablePropertyObfuscation, enableFileNameObfuscation, enableExportObfuscation, sdkVersion, entryPackageInfo); 1690 const parsedResult = JSON.parse(result); 1691 PropCollections.historyMangledTable.clear(); 1692 PropCollections.globalMangledTable.clear(); 1693 expect('PropertyCache' in parsedResult).to.be.true; 1694 expect(parsedResult.PropertyCache.key1 === "value1").to.be.true; 1695 expect(parsedResult.PropertyCache.key2 === "value2").to.be.true; 1696 expect(parsedResult.PropertyCache.key3 === "value3").to.be.true; 1697 expect(parsedResult.PropertyCache.key4 === "value4").to.be.true; 1698 }); 1699 }); 1700 1701 describe('fillNameCache', function() { 1702 it('should correctly fill the name cache with the given table entries', function() { 1703 const table = new Map([ 1704 ['key1', 'value1'], 1705 ['key2', 'value2'], 1706 ['key3', 'value3'] 1707 ]); 1708 const nameCache = new Map(); 1709 1710 fillNameCache(table, nameCache); 1711 1712 assert.deepEqual(nameCache, table); 1713 }); 1714 1715 it('should handle empty tables gracefully', function() { 1716 const table = new Map(); 1717 const nameCache = new Map(); 1718 1719 fillNameCache(table, nameCache); 1720 1721 assert.deepEqual(nameCache, table); 1722 }); 1723 }); 1724 1725 describe('writeObfuscationNameCache', () => { 1726 let existsSyncSpy; 1727 let mkdirSyncSpy; 1728 let writeFileSyncSpy; 1729 1730 beforeEach(function() { 1731 existsSyncSpy = sinon.spy(fs, 'existsSync'); 1732 mkdirSyncSpy = sinon.spy(fs, 'mkdirSync'); 1733 writeFileSyncSpy = sinon.spy(fs, 'writeFileSync'); 1734 }); 1735 1736 afterEach(function() { 1737 existsSyncSpy.restore(); 1738 mkdirSyncSpy.restore(); 1739 writeFileSyncSpy.restore(); 1740 }); 1741 1742 it('should not write cache if projectConfig.arkObfuscator is false', () => { 1743 const projectConfig = { 1744 arkObfuscator: false, 1745 obfuscationMergedObConfig: { 1746 options: { 1747 enablePropertyObfuscation: true, 1748 enableFileNameObfuscation: true, 1749 }, 1750 }, 1751 etsLoaderVersion: '1.0.0', 1752 }; 1753 const entryPackageInfo = 'testEntryPackageInfo'; 1754 const obfuscationCacheDir = 'testCacheDir'; 1755 const printNameCache = 'testPrintNameCache'; 1756 1757 writeObfuscationNameCache(projectConfig, entryPackageInfo, obfuscationCacheDir, printNameCache); 1758 1759 expect(existsSyncSpy.called).to.be.false; 1760 expect(mkdirSyncSpy.called).to.be.false; 1761 expect(writeFileSyncSpy.called).to.be.false; 1762 }); 1763 it('should write cache to obfuscationCacheDir if provided', () => { 1764 const projectConfig = { 1765 arkObfuscator: true, 1766 obfuscationMergedObConfig: { 1767 options: { 1768 enablePropertyObfuscation: true, 1769 enableFileNameObfuscation: true, 1770 enableExportObfusaction: true 1771 }, 1772 }, 1773 etsLoaderVersion: '1.0.0', 1774 }; 1775 const entryPackageInfo = 'testEntryPackageInfo'; 1776 const obfuscationCacheDir = './test/ut/initialization/testObfuscationCacheDir'; 1777 const printNameCache = ''; 1778 writeObfuscationNameCache(projectConfig, entryPackageInfo, obfuscationCacheDir, printNameCache); 1779 const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json'); 1780 const expectedContent = { 1781 "extraKey": "", 1782 "compileSdkVersion": "1.0.0", 1783 "entryPackageInfo": "testEntryPackageInfo", 1784 "PropertyCache": {}, 1785 "FileNameCache": {} 1786 } 1787 const jsonData = fs.readFileSync(defaultNameCachePath,'utf-8'); 1788 const result = JSON.parse(jsonData); 1789 expect(result).to.deep.equal(expectedContent); 1790 fs.unlinkSync(defaultNameCachePath); 1791 fs.rmdirSync(path.dirname(defaultNameCachePath)); 1792 }); 1793 it('should write cache to printNameCache if provided', () => { 1794 const projectConfig = { 1795 arkObfuscator: true, 1796 obfuscationMergedObConfig: { 1797 options: { 1798 enablePropertyObfuscation: true, 1799 enableFileNameObfuscation: true, 1800 }, 1801 }, 1802 etsLoaderVersion: '1.0.0', 1803 }; 1804 const entryPackageInfo = 'testEntryPackageInfo'; 1805 const obfuscationCacheDir = ''; 1806 const printNameCache = './test/ut/initialization/printNameCache.json'; 1807 writeObfuscationNameCache(projectConfig, entryPackageInfo, obfuscationCacheDir, printNameCache); 1808 const expectedContent = { 1809 "extraKey": "", 1810 "compileSdkVersion": "1.0.0", 1811 "entryPackageInfo": "testEntryPackageInfo", 1812 "PropertyCache": {}, 1813 "FileNameCache": {} 1814 } 1815 const jsonData = fs.readFileSync(printNameCache,'utf-8'); 1816 const result = JSON.parse(jsonData); 1817 expect(result).to.deep.equal(expectedContent); 1818 expect(existsSyncSpy.called).to.be.false; 1819 expect(mkdirSyncSpy.called).to.be.false; 1820 fs.unlinkSync(printNameCache); 1821 }); 1822 }); 1823 1824 describe('enableObfuscatedFilePathConfig', () => { 1825 it('should return false if in debug mode or no obfuscation config', () => { 1826 const projectConfig = { 1827 obfuscationMergedObConfig: null, 1828 buildMode: 'debug' 1829 }; 1830 const result = enableObfuscatedFilePathConfig(true, projectConfig); 1831 expect(result).to.be.false; 1832 }); 1833 1834 it('should return false if obfuscation is disabled or file name obfuscation is not enabled', () => { 1835 const projectConfig = { 1836 obfuscationMergedObConfig: { 1837 options: { 1838 disableObfuscation: true, 1839 enableFileNameObfuscation: false, 1840 }, 1841 }, 1842 buildMode: 'debug' 1843 }; 1844 const result = enableObfuscatedFilePathConfig(false, projectConfig); 1845 expect(result).to.be.false; 1846 }); 1847 1848 it('should return true if all conditions are met', () => { 1849 const projectConfig = { 1850 obfuscationMergedObConfig: { 1851 options: { 1852 disableObfuscation: false, 1853 enableFileNameObfuscation: true, 1854 }, 1855 }, 1856 buildMode: 'not debug' 1857 }; 1858 const result = enableObfuscatedFilePathConfig(false, projectConfig); 1859 expect(result).to.be.true; 1860 }); 1861 }); 1862 1863 describe('handleObfuscatedFilePath', () => { 1864 it('should return the original file path if obfuscation is not enabled', () => { 1865 const filePath = '/path/to/file.js'; 1866 const isPackageModules = false; 1867 const projectConfig = { 1868 enableFileNameObfuscation: false, 1869 buildMode: 'debug' 1870 }; 1871 1872 const result = handleObfuscatedFilePath(filePath, isPackageModules, projectConfig); 1873 1874 expect(result).to.equal(filePath); 1875 }); 1876 1877 it('should return the original file path if obfuscation is not enabled', () => { 1878 const filePath = '/path/to/file.txt'; 1879 const isPackageModules = false; 1880 const projectConfig = { 1881 obfuscationMergedObConfig: null, 1882 buildMode: 'debug' 1883 }; 1884 const result = handleObfuscatedFilePath(filePath, isPackageModules, projectConfig); 1885 expect(result).to.equal(filePath); 1886 }); 1887 1888 it('should return the original file path if obfuscation is not enabled', () => { 1889 const filePath = '/path/to/file.txt'; 1890 const isPackageModules = false; 1891 const projectConfig = { 1892 obfuscationMergedObConfig: null, 1893 buildMode: 'not debug' 1894 }; 1895 const result = handleObfuscatedFilePath(filePath, isPackageModules, projectConfig); 1896 expect(result).to.equal(filePath); 1897 }); 1898 1899 it('should return the unix formatted file path if obfuscation is enabled and is a package module', () => { 1900 const filePath = '/path/to/file.js'; 1901 const isPackageModules = true; 1902 const projectConfig = { 1903 obfuscationMergedObConfig: { 1904 options: { 1905 disableObfuscation: false, 1906 enableFileNameObfuscation: true, 1907 }, 1908 }, 1909 buildMode: "not Debug" 1910 }; 1911 1912 const result = handleObfuscatedFilePath(filePath, isPackageModules, projectConfig); 1913 1914 expect(result).to.equal(FileUtils.toUnixPath(filePath)); 1915 }); 1916 1917 it('should return the unix formatted file path if obfuscation is enabled and is a package module', () => { 1918 const filePath = '/path/to/file.js'; 1919 const isPackageModules = true; 1920 const projectConfig = { 1921 obfuscationMergedObConfig: { 1922 options: { 1923 disableObfuscation: false, 1924 enableFileNameObfuscation: true, 1925 }, 1926 }, 1927 buildMode: "" 1928 }; 1929 1930 const result = handleObfuscatedFilePath(filePath, isPackageModules, projectConfig); 1931 1932 expect(result).to.equal(FileUtils.toUnixPath(filePath)); 1933 }); 1934 }); 1935 1936 describe('enableObfuscateFileName', () => { 1937 it('should return false if obfuscation is not enabled', () => { 1938 const isPackageModules = false; 1939 const projectConfig = { 1940 obfuscationMergedObConfig: null, 1941 buildMode: "not Debug" 1942 }; 1943 const result = enableObfuscateFileName(isPackageModules, projectConfig); 1944 expect(result).to.be.false; 1945 }); 1946 1947 it('should return true if obfuscation is enabled and not a package module', () => { 1948 const isPackageModules = false; 1949 const projectConfig = { 1950 obfuscationMergedObConfig: { 1951 options: { 1952 disableObfuscation: false, 1953 enableFileNameObfuscation: true, 1954 }, 1955 }, 1956 buildMode: "not Debug" 1957 }; 1958 const result = enableObfuscateFileName(isPackageModules, projectConfig); 1959 1960 expect(result).to.be.true; 1961 }); 1962 1963 it('should return false if obfuscation is enabled and is a package module', () => { 1964 const isPackageModules = true; 1965 const projectConfig = { 1966 obfuscationMergedObConfig: { 1967 options: { 1968 disableObfuscation: false, 1969 enableFileNameObfuscation: true, 1970 }, 1971 }, 1972 buildMode: "Debug" 1973 }; 1974 const result = enableObfuscateFileName(isPackageModules, projectConfig); 1975 expect(result).to.be.false; 1976 }); 1977 1978 it('should return false if obfuscation is enabled and is a package module', () => { 1979 const isPackageModules = true; 1980 const projectConfig = { 1981 obfuscationMergedObConfig: { 1982 options: { 1983 disableObfuscation: false, 1984 enableFileNameObfuscation: false, 1985 }, 1986 }, 1987 buildMode: "Debug" 1988 }; 1989 const result = enableObfuscateFileName(isPackageModules, projectConfig); 1990 expect(result).to.be.false; 1991 }); 1992 1993 it('should return false if obfuscation is enabled and is a package module', () => { 1994 const isPackageModules = true; 1995 const projectConfig = { 1996 obfuscationMergedObConfig: {}, 1997 buildMode: "Debug" 1998 }; 1999 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2000 expect(result).to.be.false; 2001 }); 2002 2003 it('should return false if obfuscation is enabled and is a package module', () => { 2004 const isPackageModules = true; 2005 const projectConfig = { 2006 obfuscationMergedObConfig: null, 2007 buildMode: "Debug" 2008 }; 2009 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2010 expect(result).to.be.false; 2011 }); 2012 2013 it('should return false if obfuscation is enabled and is a package module', () => { 2014 const isPackageModules = true; 2015 const projectConfig = { 2016 obfuscationMergedObConfig: undefined, 2017 buildMode: "Debug" 2018 }; 2019 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2020 expect(result).to.be.false; 2021 }); 2022 2023 it('should return false if obfuscation is enabled and is a package module', () => { 2024 const isPackageModules = true; 2025 const projectConfig = { 2026 obfuscationMergedObConfig: { 2027 options: { 2028 disableObfuscation: false, 2029 enableFileNameObfuscation: true, 2030 }, 2031 }, 2032 buildMode: "not Debug" 2033 }; 2034 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2035 expect(result).to.be.false; 2036 }); 2037 2038 it('should return false if obfuscation is enabled and is a package module', () => { 2039 const isPackageModules = true; 2040 const projectConfig = { 2041 obfuscationMergedObConfig: { 2042 options: { 2043 disableObfuscation: false, 2044 enableFileNameObfuscation: false, 2045 }, 2046 }, 2047 buildMode: "not Debug" 2048 }; 2049 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2050 expect(result).to.be.false; 2051 }); 2052 2053 it('should return false if obfuscation is enabled and is a package module', () => { 2054 const isPackageModules = true; 2055 const projectConfig = { 2056 obfuscationMergedObConfig: { 2057 options: { 2058 disableObfuscation: false, 2059 enableFileNameObfuscation: false, 2060 }, 2061 }, 2062 buildMode: "not Debug" 2063 }; 2064 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2065 expect(result).to.be.false; 2066 }); 2067 2068 it('should return false if obfuscation is enabled and is a package module', () => { 2069 const isPackageModules = true; 2070 const projectConfig = { 2071 obfuscationMergedObConfig: { 2072 options: { 2073 disableObfuscation: false, 2074 enableFileNameObfuscation: true, 2075 }, 2076 }, 2077 buildMode: "not Debug" 2078 }; 2079 const result = enableObfuscateFileName(isPackageModules, projectConfig); 2080 expect(result).to.be.false; 2081 }); 2082 2083 it('should return false if obfuscation is enabled and bytecodeObf is enable', () => { 2084 const isPackageModules = false; 2085 const projectConfig = { 2086 obfuscationMergedObConfig: { 2087 options: { 2088 disableObfuscation: false, 2089 enableFileNameObfuscation: true, 2090 bytecodeObf: { 2091 enable: true 2092 }, 2093 }, 2094 }, 2095 buildMode: "not Debug" 2096 }; 2097 const result = enableObfuscatedFilePathConfig(isPackageModules, projectConfig); 2098 expect(result).to.be.false; 2099 }); 2100 }); 2101 2102 describe('getRelativeSourcePath', () => { 2103 it('should return the relative path of a file within the project root', () => { 2104 const filePath = '/Users/user/project/src/components/Button.js'; 2105 const projectRootPath = '/Users/user/project'; 2106 const expectedRelativePath = 'src/components/Button.js'; 2107 2108 const result = getRelativeSourcePath(filePath, projectRootPath, ''); 2109 expect(result).to.equal(expectedRelativePath); 2110 }); 2111 2112 it('should return the relative path of a file within a specified project path', () => { 2113 const filePath = '/Users/user/project/src/components/Button.js'; 2114 const belongProjectPath = '/Users/user/project/src'; 2115 const expectedRelativePath = 'components/Button.js'; 2116 2117 const result = getRelativeSourcePath(filePath, '', belongProjectPath); 2118 expect(result).to.equal(expectedRelativePath); 2119 }); 2120 2121 it('should return the original path if no project root or belong project path is provided', () => { 2122 const filePath = '/Users/user/project/src/components/Button.js'; 2123 const expectedRelativePath = filePath; 2124 2125 const result = getRelativeSourcePath(filePath, '', ''); 2126 expect(result).to.equal(expectedRelativePath); 2127 }); 2128 }); 2129 2130 describe('printUnobfuscationReasons', () => { 2131 it('historyAllUnobfuscatedNamesMap is empty', () => { 2132 unobfuscationNamesObj['Index.ets'] = { 'abc': ['sdk'] }; 2133 unobfuscationNamesObj['Test.ets'] = { 'abc_test': ['conf'] }; 2134 printUnobfuscationReasons('', './keptNames.json'); 2135 let keptNamesObj = { 2136 keptReasons: {}, 2137 keptNames: {} 2138 }; 2139 let keptNameString = fs.readFileSync('./keptNames.json', 'utf-8'); 2140 const parsedObj = JSON.parse(keptNameString); 2141 keptNamesObj.keptReasons = parsedObj.keptReasons; 2142 keptNamesObj.keptNames = parsedObj.keptNames; 2143 expect(keptNamesObj.keptNames['Index.ets']['abc'][0]).to.equal('sdk'); 2144 expect(keptNamesObj.keptNames['Test.ets']['abc_test'][0]).to.equal('conf'); 2145 clearHistoryUnobfuscatedMap(); 2146 clearUnobfuscationNamesObj(); 2147 }); 2148 2149 it('historyAllUnobfuscatedNamesMap is not empty', () => { 2150 historyAllUnobfuscatedNamesMap.set('Index.ets', { 'abc': ['sdk'] }); 2151 historyAllUnobfuscatedNamesMap.set('Test.ets', { 'abc_test': ['conf'] }); 2152 unobfuscationNamesObj['Index.ets'] = { 'abc': ['conf'] }; 2153 unobfuscationNamesObj['Test2.ets'] = { 'abc_test2': ['lang'] }; 2154 printUnobfuscationReasons('', './keptNames.json'); 2155 let keptNamesObj = { 2156 keptReasons: {}, 2157 keptNames: {} 2158 }; 2159 let keptNameString = fs.readFileSync('./keptNames.json', 'utf-8'); 2160 const parsedObj = JSON.parse(keptNameString); 2161 keptNamesObj.keptReasons = parsedObj.keptReasons; 2162 keptNamesObj.keptNames = parsedObj.keptNames; 2163 expect(keptNamesObj.keptNames['Index.ets']['abc'][0]).to.equal('conf'); 2164 expect(keptNamesObj.keptNames['Test.ets']['abc_test'][0]).to.equal('conf'); 2165 expect(keptNamesObj.keptNames['Test2.ets']['abc_test2'][0]).to.equal('lang'); 2166 clearHistoryUnobfuscatedMap(); 2167 clearUnobfuscationNamesObj(); 2168 }); 2169 }); 2170 2171 describe('clearNameCache', () => { 2172 it('should clear historyMangledTable and nameCacheMap', () => { 2173 PropCollections.historyMangledTable.set('name1','name2'); 2174 nameCacheMap.set('name1','name2'); 2175 historyAllUnobfuscatedNamesMap.set('key', {'prop1': 'aaa'}); 2176 historyUnobfuscatedPropMap.set('key', ['value']); 2177 clearNameCache(); 2178 expect(PropCollections.historyMangledTable.size).to.be.equal(0); 2179 expect(nameCacheMap.size).to.be.equal(0); 2180 expect(historyAllUnobfuscatedNamesMap.size).to.equal(0); 2181 expect(historyUnobfuscatedPropMap.size).to.equal(0); 2182 }); 2183 }); 2184 2185 describe('emitConsumerConfigFiles', () => { 2186 it('should also collect atKeepNames when atKeep is enabled', () => { 2187 const atKeepExportedPath = path.join(__dirname, '../../testData/output/atKeep_obfuscation01.txt'); 2188 const sourceObConfig = { 2189 selfConfig: { 2190 ruleOptions: { 2191 enable: true, 2192 rules: ['./test/testData/obfuscation/testAtKeep/obfuscation-rules-atKeep.txt'] 2193 }, 2194 consumerRules: ['./test/testData/obfuscation/testAtKeep/consumer-rules.txt'], 2195 }, 2196 dependencies: { libraries: [], hars: [] }, 2197 obfuscationCacheDir: './test/testData/cache', 2198 options: { 2199 disableObfuscation: false 2200 }, 2201 exportRulePath: atKeepExportedPath, 2202 sdkApis: [] 2203 }; 2204 const projectConfig = { 2205 obfuscationOptions: sourceObConfig, 2206 compileHar: false, 2207 compileShared: true 2208 } 2209 const obConfigResolver = new ObConfigResolver(projectConfig, printObfLogger); 2210 obConfigResolver.resolveObfuscationConfigs(); 2211 AtKeepCollections.clear(); 2212 AtKeepCollections.keepAsConsumer.globalNames.add('globalName1'); 2213 AtKeepCollections.keepAsConsumer.propertyNames.add('propertyName1'); 2214 AtKeepCollections.keepSymbol.globalNames.add('globalName2'); 2215 AtKeepCollections.keepSymbol.propertyNames.add('propertyName2'); 2216 obConfigResolver.emitConsumerConfigFiles(); 2217 const atKeepContent = fs.readFileSync(sourceObConfig.exportRulePath, 'utf-8'); 2218 expect(atKeepContent).to.include('-enable-property-obfuscation'); 2219 expect(atKeepContent).to.include('-keep-global-name'); 2220 expect(atKeepContent).to.include('globalName00'); 2221 expect(atKeepContent).to.include('globalName1'); 2222 expect(atKeepContent).to.include('-keep-property-name'); 2223 expect(atKeepContent).to.include('propertyName00'); 2224 expect(atKeepContent).to.include('propertyName1'); 2225 expect(atKeepContent).not.to.include('globalName2'); 2226 expect(atKeepContent).not.to.include('propertyName2'); 2227 FileUtils.deleteFile(atKeepExportedPath); 2228 }); 2229 2230 it('should not collect atKeepNames when atKeep is not enabled', () => { 2231 const atKeepExportedPath = path.join(__dirname, '../../testData/output/atKeep_obfuscation02.txt'); 2232 const sourceObConfig = { 2233 selfConfig: { 2234 ruleOptions: { 2235 enable: true, 2236 rules: ['./test/testData/obfuscation/testAtKeep/obfuscation-rules.txt'] 2237 }, 2238 consumerRules: ['./test/testData/obfuscation/testAtKeep/consumer-rules.txt'], 2239 }, 2240 dependencies: { libraries: [], hars: [] }, 2241 obfuscationCacheDir: './test/testData/cache', 2242 options: { 2243 disableObfuscation: false 2244 }, 2245 exportRulePath: atKeepExportedPath, 2246 sdkApis: [] 2247 }; 2248 const projectConfig = { 2249 obfuscationOptions: sourceObConfig, 2250 compileHar: false, 2251 compileShared: true 2252 } 2253 AtKeepCollections.clear(); 2254 const obConfigResolver = new ObConfigResolver(projectConfig, printObfLogger); 2255 obConfigResolver.resolveObfuscationConfigs(); 2256 obConfigResolver.emitConsumerConfigFiles(); 2257 const atKeepContent = fs.readFileSync(sourceObConfig.exportRulePath, 'utf-8'); 2258 expect(atKeepContent).to.include('-enable-property-obfuscation'); 2259 expect(atKeepContent).to.include('-keep-global-name'); 2260 expect(atKeepContent).to.include('globalName00'); 2261 expect(atKeepContent).not.to.include('globalName1'); 2262 expect(atKeepContent).to.include('-keep-property-name'); 2263 expect(atKeepContent).to.include('propertyName00'); 2264 expect(atKeepContent).not.to.include('propertyName1'); 2265 expect(atKeepContent).not.to.include('globalName2'); 2266 expect(atKeepContent).not.to.include('propertyName2'); 2267 FileUtils.deleteFile(atKeepExportedPath); 2268 }); 2269 }); 2270}); 2271