1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use rollupObject file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// Execute this file first to avoid circular dependency problems 17 18import { expect } from 'chai'; 19import mocha from 'mocha'; 20import fs, { unwatchFile } from "fs"; 21import path from "path"; 22import MagicString from 'magic-string'; 23import sinon from 'sinon'; 24 25import { 26 getBuildModeInLowerCase, 27 getPackageInfo, 28 genSourceMapFileName, 29 isOhModules, 30 isEs2Abc, 31 writeArkguardObfuscatedSourceCode, 32 writeMinimizedSourceCode, 33 tryMangleFileName, 34 getPreviousStageSourceMap, 35 collectObfuscationFileContent 36} from '../../lib/ark_utils'; 37import { 38 DEBUG, 39 RELEASE, 40 OH_MODULES, 41 EXTNAME_TS, 42 EXTNAME_JS, 43 EXTNAME_ETS, 44 OBFUSCATION_TOOL 45} from '../../lib/fast_build/ark_compiler/common/ark_define'; 46import RollUpPluginMock from './mock/rollup_mock/rollup_plugin_mock'; 47import { 48 BUNDLE_NAME_DEFAULT, 49 ENTRY_MODULE_NAME_DEFAULT, 50 EXTNAME_MAP, 51 ENTRYABILITY_JS 52} from './mock/rollup_mock/common'; 53import projectConfig from './utils/processProjectConfig'; 54import { 55 ES2ABC, 56 TS2ABC 57} from '../../lib/pre_define'; 58import { changeFileExtension } from '../../lib/fast_build/ark_compiler/utils'; 59import ModuleSourceFileMock from './mock/class_mock/module_source_files_mock'; 60import { 61 genTemporaryPath, 62 toUnixPath 63} from '../../lib/utils'; 64import { 65 ObConfigResolver, 66 MergedConfig, 67 obfLogger 68} from '../../lib/fast_build/ark_compiler/common/ob_config_resolver'; 69import { 70 utProcessArkConfig 71} from '../../lib/fast_build/ark_compiler/common/process_ark_config'; 72import { ModuleSourceFile } from '../../lib/fast_build/ark_compiler/module/module_source_file'; 73import { PROJECT_ROOT, TERSER_PROCESSED_EXPECTED_CODE } from './mock/rollup_mock/path_config'; 74import { GEN_ABC_PLUGIN_NAME } from '../../lib/fast_build/ark_compiler/common/ark_define'; 75import { SourceMapGenerator } from '../../lib/fast_build/ark_compiler/generate_sourcemap'; 76import { ArkObfuscator } from 'arkguard'; 77import { 78 ArkTSInternalErrorDescription, 79 ErrorCode 80} from '../../lib/fast_build/ark_compiler/error_code'; 81import { 82 CommonLogger, 83 LogData, 84 LogDataFactory 85} from '../../lib/fast_build/ark_compiler/logger'; 86import { initObfLogger, printObfLogger } from '../../lib/fast_build/ark_compiler/common/ob_config_resolver'; 87import { getLogger } from 'log4js'; 88import { createErrInfo } from './utils/utils'; 89 90mocha.describe('test ark_utils file api', function () { 91 mocha.before(function () { 92 this.rollup = new RollUpPluginMock(); 93 }); 94 95 mocha.after(() => { 96 delete this.rollup; 97 }); 98 99 mocha.it('1-1: test getBuildModeInLowerCase under build debug', function () { 100 this.rollup.build(); 101 const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig); 102 expect(buildMode === DEBUG).to.be.true; 103 }); 104 105 mocha.it('1-2: test getBuildModeInLowerCase under build release', function () { 106 this.rollup.build(RELEASE); 107 const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig); 108 expect(buildMode === RELEASE).to.be.true; 109 }); 110 111 mocha.it('1-3: test getBuildModeInLowerCase under preview debug', function () { 112 this.rollup.preview(); 113 const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig); 114 expect(buildMode === DEBUG).to.be.true; 115 }); 116 117 mocha.it('1-4: test getBuildModeInLowerCase under hot reload debug', function () { 118 this.rollup.hotReload(); 119 const buildMode = getBuildModeInLowerCase(this.rollup.share.projectConfig); 120 expect(buildMode === DEBUG).to.be.true; 121 }); 122 123 mocha.it('2-1: test getPackageInfo under build debug', function () { 124 this.rollup.build(); 125 const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath); 126 expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true; 127 expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true; 128 }); 129 130 mocha.it('2-2: test getPackageInfo under build release', function () { 131 this.rollup.build(RELEASE); 132 const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath); 133 expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true; 134 expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true; 135 }); 136 137 mocha.it('2-3: test getPackageInfo under preview debug', function () { 138 this.rollup.preview(); 139 const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath); 140 expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true; 141 expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true; 142 }); 143 144 mocha.it('2-4: test getPackageInfo under hot reload debug', function () { 145 this.rollup.hotReload(); 146 const returnInfo = getPackageInfo(this.rollup.share.projectConfig.aceModuleJsonPath); 147 expect(returnInfo[0] === BUNDLE_NAME_DEFAULT).to.be.true; 148 expect(returnInfo[1] === ENTRY_MODULE_NAME_DEFAULT).to.be.true; 149 }); 150 151 mocha.it('3-1: test genSourceMapFileName under build debug', function () { 152 this.rollup.build(); 153 for (const filePath of this.rollup.share.allFiles) { 154 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) { 155 const originPath = genSourceMapFileName(filePath); 156 const expectedPath = `${filePath}${EXTNAME_MAP}`; 157 expect(originPath === expectedPath).to.be.true; 158 } else if (filePath.endsWith(EXTNAME_ETS)) { 159 const originPath = genSourceMapFileName(filePath); 160 expect(originPath === filePath).to.be.true; 161 } 162 } 163 }); 164 165 mocha.it('3-2: test genSourceMapFileName under build release', function () { 166 this.rollup.build(RELEASE); 167 for (const filePath of this.rollup.share.allFiles) { 168 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) { 169 const originPath = genSourceMapFileName(filePath); 170 const expectedPath = `${filePath}${EXTNAME_MAP}`; 171 expect(originPath === expectedPath).to.be.true; 172 } 173 } 174 }); 175 176 mocha.it('3-3: test genSourceMapFileName under preview debug', function () { 177 this.rollup.preview(); 178 for (const filePath of this.rollup.share.allFiles) { 179 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) { 180 const originPath = genSourceMapFileName(filePath); 181 const expectedPath = `${filePath}${EXTNAME_MAP}`; 182 expect(originPath === expectedPath).to.be.true; 183 } 184 } 185 }); 186 187 mocha.it('3-4: test genSourceMapFileName under hot reload debug', function () { 188 this.rollup.hotReload(); 189 for (const filePath of this.rollup.share.allFiles) { 190 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_JS)) { 191 const originPath = genSourceMapFileName(filePath); 192 const expectedPath = `${filePath}${EXTNAME_MAP}`; 193 expect(originPath === expectedPath).to.be.true; 194 } 195 } 196 }); 197 198 mocha.it('4-1: test isOhModules under build debug', function () { 199 this.rollup.build(); 200 const returnInfo = isOhModules(this.rollup.share.projectConfig); 201 expect(returnInfo === false).to.be.true; 202 this.rollup.share.projectConfig.packageDir = OH_MODULES; 203 const returnInfoOh = isOhModules(this.rollup.share.projectConfig); 204 expect(returnInfoOh).to.be.true; 205 }); 206 207 mocha.it('4-2: test isOhModules under build release', function () { 208 this.rollup.build(RELEASE); 209 const returnInfo = isOhModules(this.rollup.share.projectConfig); 210 expect(returnInfo === false).to.be.true; 211 this.rollup.share.projectConfig.packageDir = OH_MODULES; 212 const returnInfoOh = isOhModules(this.rollup.share.projectConfig); 213 expect(returnInfoOh).to.be.true; 214 }); 215 216 mocha.it('4-3: test isOhModules under preview debug', function () { 217 this.rollup.preview(); 218 const returnInfo = isOhModules(this.rollup.share.projectConfig); 219 expect(returnInfo === false).to.be.true; 220 this.rollup.share.projectConfig.packageDir = OH_MODULES; 221 const returnInfoOh = isOhModules(this.rollup.share.projectConfig); 222 expect(returnInfoOh).to.be.true; 223 }); 224 225 mocha.it('4-4: test isOhModules under hot reload debug', function () { 226 this.rollup.hotReload(); 227 const returnInfo = isOhModules(this.rollup.share.projectConfig); 228 expect(returnInfo === false).to.be.true; 229 this.rollup.share.projectConfig.packageDir = OH_MODULES; 230 const returnInfoOh = isOhModules(this.rollup.share.projectConfig); 231 expect(returnInfoOh).to.be.true; 232 }); 233 234 mocha.it('4-5: test isOhModules under hot fix debug', function () { 235 projectConfig.buildMode = DEBUG; 236 const returnInfo = isOhModules(projectConfig); 237 expect(returnInfo).to.be.true; 238 }); 239 240 mocha.it('4-6: test isOhModules under hot fix release', function () { 241 projectConfig.buildMode = RELEASE; 242 const returnInfo = isOhModules(projectConfig); 243 expect(returnInfo).to.be.true; 244 }); 245 246 mocha.it('5-1: test isEs2Abc under build debug', function () { 247 this.rollup.build(); 248 this.rollup.share.projectConfig.pandaMode = ES2ABC; 249 const returnInfo = isEs2Abc(this.rollup.share.projectConfig); 250 expect(returnInfo).to.be.true; 251 252 this.rollup.share.projectConfig.pandaMode = TS2ABC; 253 const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig); 254 expect(returnInfoTS2ABC === false).to.be.true; 255 256 this.rollup.share.projectConfig.pandaMode = "undefined"; 257 const returnInfoUndef = isEs2Abc(this.rollup.share.projectConfig); 258 expect(returnInfoUndef).to.be.true; 259 260 this.rollup.share.projectConfig.pandaMode = undefined; 261 const returnInfoUndefined = isEs2Abc(this.rollup.share.projectConfig); 262 expect(returnInfoUndefined).to.be.true; 263 }); 264 265 mocha.it('5-2: test isEs2Abc under build release', function () { 266 this.rollup.build(RELEASE); 267 this.rollup.share.projectConfig.pandaMode = ES2ABC; 268 const returnInfo = isEs2Abc(this.rollup.share.projectConfig); 269 expect(returnInfo).to.be.true; 270 271 this.rollup.share.projectConfig.pandaMode = TS2ABC; 272 const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig); 273 expect(returnInfoTS2ABC).to.be.false; 274 }); 275 276 mocha.it('5-3: test isEs2Abc under preview debug', function () { 277 this.rollup.preview(); 278 this.rollup.share.projectConfig.pandaMode = ES2ABC; 279 const returnInfo = isEs2Abc(this.rollup.share.projectConfig); 280 expect(returnInfo).to.be.true; 281 282 this.rollup.share.projectConfig.pandaMode = TS2ABC; 283 const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig); 284 expect(returnInfoTS2ABC).to.be.false; 285 }); 286 287 mocha.it('5-4: test isEs2Abc under hot reload debug', function () { 288 this.rollup.hotReload(); 289 this.rollup.share.projectConfig.pandaMode = ES2ABC; 290 const returnInfo = isEs2Abc(this.rollup.share.projectConfig); 291 expect(returnInfo).to.be.true; 292 293 this.rollup.share.projectConfig.pandaMode = TS2ABC; 294 const returnInfoTS2ABC = isEs2Abc(this.rollup.share.projectConfig); 295 expect(returnInfoTS2ABC).to.be.false; 296 }); 297 298 mocha.it('5-5: test isEs2Abc under hot fix debug', function () { 299 projectConfig.buildMode = DEBUG; 300 projectConfig.pandaMode = ES2ABC; 301 const returnInfo = isEs2Abc(projectConfig); 302 expect(returnInfo).to.be.true; 303 304 projectConfig.pandaMode = TS2ABC; 305 const returnInfoTS2ABC = isEs2Abc(projectConfig); 306 expect(returnInfoTS2ABC).to.be.false; 307 }); 308 309 mocha.it('5-6: test isEs2Abc under hot fix release', function () { 310 projectConfig.buildMode = RELEASE; 311 projectConfig.pandaMode = ES2ABC; 312 const returnInfo = isEs2Abc(projectConfig); 313 expect(returnInfo).to.be.true; 314 315 projectConfig.pandaMode = TS2ABC; 316 const returnInfoTS2ABC = isEs2Abc(projectConfig); 317 expect(returnInfoTS2ABC).to.be.false; 318 }); 319 320 mocha.it('6-1: test the error message of writeArkguardObfuscatedSourceCode', async function () { 321 this.rollup.build(RELEASE); 322 SourceMapGenerator.initInstance(this.rollup); 323 this.rollup.share.getHvigorConsoleLogger = undefined; 324 initObfLogger(this.rollup.share); 325 const stub = sinon.stub(obfLogger, 'error'); 326 const red: string = '\x1B[31m'; 327 try { 328 await writeArkguardObfuscatedSourceCode( 329 {content: undefined, buildFilePath: '', relativeSourceFilePath: '', originSourceFilePath: ''}, 330 printObfLogger, this.rollup.share.projectConfig, {}); 331 } catch (e) { 332 } 333 expect(stub.calledWith(red, 334 `ArkTS:INTERNAL ERROR: Failed to obfuscate file '' with arkguard. TypeError: Cannot read properties of undefined (reading 'obfuscate')` 335 )).to.be.true; 336 stub.restore(); 337 SourceMapGenerator.cleanSourceMapObject(); 338 }); 339 340 mocha.it('6-2: test the error message of writeArkguardObfuscatedSourceCode' + 341 'with getHvigorConsoleLogger', async function () { 342 this.rollup.build(RELEASE); 343 SourceMapGenerator.initInstance(this.rollup); 344 class customShare { 345 public getHvigorConsoleLogger(prefix: string) { 346 const logger = hvigorLogger.getLogger(prefix); 347 return logger; 348 } 349 } 350 class hvigorLogger { 351 mSubSystem: string = ''; 352 constructor(subSystem: string) { 353 this.mSubSystem = subSystem; 354 } 355 356 public printError(errInfo: Object) { 357 } 358 359 public static getLogger(subSystem): hvigorLogger { 360 return new hvigorLogger(subSystem); 361 } 362 } 363 initObfLogger(new customShare()); 364 const stub = sinon.stub(obfLogger, 'printError'); 365 try { 366 await writeArkguardObfuscatedSourceCode( 367 {content: undefined, buildFilePath: '', relativeSourceFilePath: '', originSourceFilePath: ''}, 368 printObfLogger, this.rollup.share.projectConfig, {}); 369 } catch (e) { 370 } 371 const info = { 372 code: '10810001', 373 description: 'ArkTS compiler Error', 374 cause: "ArkTS:INTERNAL ERROR: Failed to obfuscate file '' with arkguard. TypeError: Cannot read properties of undefined (reading 'obfuscate')", 375 position: '', 376 solutions: [ 'Please modify the code based on the error information.' ] 377 }; 378 expect(stub.calledWith(info)).to.be.true; 379 stub.restore(); 380 SourceMapGenerator.cleanSourceMapObject(); 381 }); 382 383 mocha.it('7-1: test the error message of writeMinimizedSourceCode', async function () { 384 this.rollup.build(RELEASE); 385 const errInfo: LogData = LogDataFactory.newInstance( 386 ErrorCode.ETS2BUNDLE_INTERNAL_SOURCE_CODE_OBFUSCATION_FAILED, 387 ArkTSInternalErrorDescription, 388 'Failed to obfuscate source code for filePath' 389 ); 390 const logger = CommonLogger.getInstance(this.rollup); 391 const stub = sinon.stub(logger.getLoggerFromErrorCode(errInfo.code), 'printError'); 392 try { 393 await writeMinimizedSourceCode(undefined, 'filePath', logger); 394 } catch (e) { 395 } 396 expect(stub.calledWith(errInfo)).to.be.true; 397 stub.restore(); 398 }); 399 400 mocha.it('7-2: test the error message of writeMinimizedSourceCode without getHvigorConsoleLogger', async function () { 401 this.rollup.build(RELEASE); 402 const errInfo: LogData = LogDataFactory.newInstance( 403 ErrorCode.ETS2BUNDLE_INTERNAL_SOURCE_CODE_OBFUSCATION_FAILED, 404 ArkTSInternalErrorDescription, 405 'Failed to obfuscate source code for filePath' 406 ); 407 CommonLogger.destroyInstance(); 408 const getHvigorConsoleLogger = this.rollup.share.getHvigorConsoleLogger; 409 this.rollup.share.getHvigorConsoleLogger = undefined; 410 const logger = CommonLogger.getInstance(this.rollup); 411 const stub = sinon.stub(logger.logger, 'error'); 412 try { 413 await writeMinimizedSourceCode(undefined, 'filePath', logger); 414 } catch (e) { 415 } 416 expect(stub.calledWith(errInfo.toString())).to.be.true; 417 CommonLogger.destroyInstance(); 418 this.rollup.share.getHvigorConsoleLogger = getHvigorConsoleLogger; 419 stub.restore(); 420 }); 421 422 mocha.it('8-1: test tryMangleFileName when obfuscation is disabled', async function () { 423 const filePath = '/mnt/application/entry/build/default/cache/default/default@CompileArkTS/esmodule/release/src/main/ets/entryability/EntryAbility.ts'; 424 const originalFilePath = '/mnt/application/entry/src/main/ets/entryability/EntryAbility.ets'; 425 const projectConfig = { 426 projectRootPath: '/mnt/application', 427 packageDir: 'oh_modules', 428 modulePathMap: { 429 entry: '/mnt/application/entry' 430 }, 431 obfuscationMergedObConfig: { 432 options: { 433 enableFileNameObfuscation: false 434 } 435 } 436 } 437 const result = tryMangleFileName(filePath, projectConfig, originalFilePath); 438 expect(result === filePath).to.be.true; 439 }); 440 441 mocha.it('8-2: test tryMangleFileName when obfuscation is enabled', async function () { 442 const filePath = '/mnt/application/entry/build/default/cache/default/default@CompileArkTS/esmodule/release/src/main/ets/entryability/EntryAbility.ts'; 443 const originalFilePath = '/mnt/application/entry/src/main/ets/entryability/EntryAbility.ets'; 444 const newFilePath = '/mnt/application/entry/build/default/cache/default/default@CompileArkTS/esmodule/release/src/main/ets/a/b.ts'; 445 const projectConfig = { 446 projectRootPath: '/mnt/application', 447 packageDir: 'oh_modules', 448 modulePathMap: { 449 entry: '/mnt/application/entry' 450 }, 451 obfuscationMergedObConfig: { 452 options: { 453 enableFileNameObfuscation: true 454 } 455 } 456 } 457 458 const printerConfig = { 459 //Print obfuscation time&memory usage of all files and obfuscation processes 460 mFilesPrinter: false, 461 //Print time&memory usage of a single file obfuscation in transform processes 462 mSingleFilePrinter: false, 463 //Print sum up time of transform processes during obfuscation 464 mSumPrinter: false, 465 //Output path of printer 466 mOutputPath: "" 467 } 468 469 const arkguardConfig = { 470 mRenameFileName: { 471 mEnable: true, 472 mNameGeneratorType: 1, 473 mReservedFileNames: [ 474 'entry', 475 'mnt', 476 'application', 477 'entry', 478 'src', 479 'main', 480 'ets', 481 'build', 482 'default', 483 'cache', 484 'default', 485 'default@CompileArkTS', 486 'esmodule', 487 'release' 488 ], 489 }, 490 mPerformancePrinter: printerConfig 491 } 492 493 let arkObfuscator: ArkObfuscator = new ArkObfuscator(); 494 arkObfuscator.init(arkguardConfig); 495 const content = `function foo() {}` 496 const obfuscateResult = arkObfuscator.obfuscate(content, filePath, undefined); 497 obfuscateResult.then(result => { 498 const afterObfuscateFilePath = result.filePath; 499 expect(afterObfuscateFilePath === newFilePath).to.be.true; 500 }) 501 502 const result = tryMangleFileName(filePath, projectConfig, originalFilePath); 503 expect(result === newFilePath).to.be.true; 504 }); 505 506 mocha.it('8-3: test tryMangleFileName when bytecode obfuscation is enabled', async function () { 507 const filePath = '/mnt/application/entry/build/default/cache/default/default@CompileArkTS/esmodule/release/src/main/ets/entryability/EntryAbility.ts'; 508 const originalFilePath = '/mnt/application/entry/src/main/ets/entryability/EntryAbility.ets'; 509 const projectConfig = { 510 projectRootPath: '/mnt/application', 511 packageDir: 'oh_modules', 512 modulePathMap: { 513 entry: '/mnt/application/entry' 514 }, 515 obfuscationMergedObConfig: { 516 options: { 517 enableFileNameObfuscation: true 518 } 519 }, 520 isArkguardEnabled: false, 521 isBytecodeObfEnabled: true 522 } 523 const result = tryMangleFileName(filePath, projectConfig, originalFilePath, projectConfig.isBytecodeObfEnabled); 524 expect(result === filePath).to.be.true; 525 projectConfig.isBytecodeObfEnabled = false 526 }); 527 528 mocha.it('9-1: test writeArkguardObfuscatedSourceCode when obfuscation is enabled', async function () { 529 this.rollup.build(RELEASE); 530 const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME); 531 const arkguardConfig = { 532 mCompact: false, 533 mDisableConsole: false, 534 mSimplify: false, 535 mRemoveComments: true, 536 mNameObfuscation: { 537 mEnable: true, 538 mNameGeneratorType: 1, 539 mReservedNames: [], 540 mRenameProperties: false, 541 mReservedProperties: [], 542 mKeepStringProperty: true, 543 mTopLevel: false, 544 mReservedToplevelNames: [], 545 mUniversalReservedProperties: [], 546 mUniversalReservedToplevelNames: [], 547 }, 548 mRemoveDeclarationComments: { 549 mEnable: true, 550 mReservedComments: [] 551 }, 552 mEnableSourceMap: true, 553 mEnableNameCache: true, 554 mRenameFileName: { 555 mEnable: false, 556 mNameGeneratorType: 1, 557 mReservedFileNames: [], 558 }, 559 mExportObfuscation: false, 560 mPerformancePrinter: { 561 mFilesPrinter: false, 562 mSingleFilePrinter: false, 563 mSumPrinter: false, 564 mOutputPath: "" 565 }, 566 mKeepFileSourceCode: { 567 mKeepSourceOfPaths: new Set(), 568 mkeepFilesAndDependencies: new Set(), 569 }, 570 }; 571 572 const sourceMapGenerator: SourceMapGenerator = SourceMapGenerator.initInstance(this.rollup); 573 sourceMapGenerator.setNewSoureMaps(false); 574 const arkObfuscator: ArkObfuscator = new ArkObfuscator(); 575 arkObfuscator.init(arkguardConfig); 576 577 const projectConfig = { 578 projectRootPath: PROJECT_ROOT, 579 arkObfuscator: arkObfuscator, 580 packageDir: 'oh_modules', 581 localPackageSet: new Set(), 582 useTsHar: false, 583 useNormalized: false 584 }; 585 586 const sourceFileName = 'sourceFile.ts'; 587 const originalSourceFilePath = path.join(__dirname, '../../test/ark_compiler_ut/testdata/har_obfuscation', sourceFileName); 588 const moduleInfo = { 589 content: fs.readFileSync(originalSourceFilePath, 'utf-8'), 590 buildFilePath: `${PROJECT_ROOT}/har_obfuscation/build/default/cache/${sourceFileName}`, 591 relativeSourceFilePath: `har_obfuscation/${sourceFileName}`, 592 originSourceFilePath: originalSourceFilePath, 593 rollupModuleId: originalSourceFilePath 594 }; 595 596 try { 597 await writeArkguardObfuscatedSourceCode(moduleInfo, logger, projectConfig, undefined); 598 } catch (e) { 599 } 600 const expectedResult = `export function add(d: number, e: number): number { 601 return d + e; 602} 603export function findElement<a>(b: a[], c: (item: a) => boolean): a | undefined { 604 return b.find(c); 605} 606`; 607 const result = fs.readFileSync(moduleInfo.buildFilePath, 'utf-8'); 608 expect(result === expectedResult).to.be.true; 609 610 const declFileName = 'sourceFile.d.ts'; 611 const originalDeclFilePath = path.join(__dirname, '../../test/ark_compiler_ut/testdata/har_obfuscation/', declFileName); 612 613 const declModuleInfo = { 614 content: fs.readFileSync(originalDeclFilePath, 'utf-8'), 615 buildFilePath: `${PROJECT_ROOT}/har_obfuscation/build/default/cache/${declFileName}`, 616 relativeSourceFilePath: `har_obfuscation/build/default/cache/${declFileName}`, 617 originSourceFilePath: originalSourceFilePath, 618 rollupModuleId: originalSourceFilePath 619 }; 620 621 try { 622 await writeArkguardObfuscatedSourceCode(declModuleInfo, logger, projectConfig, undefined); 623 } catch (e) { 624 } 625 626 const expectedDeclResult = `export declare function add(d: number, e: number): number; 627export declare function findElement<a>(b: a[], c: (item: a) => boolean): a | undefined; 628`; 629 const declResult = fs.readFileSync(declModuleInfo.buildFilePath, 'utf-8'); 630 expect(declResult === expectedDeclResult).to.be.true; 631 }); 632 633 mocha.describe('10: test getPreviousStageSourceMap', function() { 634 let sourceMapGeneratorStub; 635 mocha.beforeEach(function () { 636 sourceMapGeneratorStub = sinon.stub(SourceMapGenerator, 'getInstance'); 637 }); 638 639 mocha.afterEach(() => { 640 sinon.restore(); 641 }); 642 643 mocha.it('10-1: should return undefined if relativeSourceFilePath is empty', async function () { 644 const moduleInfo = { 645 buildFilePath: 'file.js', 646 relativeSourceFilePath: '', 647 rollupModuleId: 'moduleId' 648 }; 649 const result = getPreviousStageSourceMap(moduleInfo); 650 expect(result).to.be.undefined; 651 }); 652 653 mocha.it('10-2: should return undefined if the file is a declaration file', function() { 654 const moduleInfo = { 655 buildFilePath: 'file.d.ts', 656 relativeSourceFilePath: 'sourceFile.ts', 657 rollupModuleId: 'moduleId' 658 }; 659 const result = getPreviousStageSourceMap(moduleInfo); 660 expect(result).to.be.undefined; 661 }); 662 663 mocha.it('10-3: should call getSpecifySourceMap with rollupModuleId if isNewSourceMaps is true', function() { 664 const fakeSourceMap = {}; 665 const instanceStub = { 666 isNewSourceMaps: sinon.stub().returns(true), 667 getSpecifySourceMap: sinon.stub().returns(fakeSourceMap) 668 }; 669 sourceMapGeneratorStub.returns(instanceStub); 670 671 const moduleInfo = { 672 buildFilePath: 'file.js', 673 relativeSourceFilePath: 'sourceFile.ts', 674 rollupModuleId: 'moduleId' 675 }; 676 const result = getPreviousStageSourceMap(moduleInfo); 677 678 expect(instanceStub.getSpecifySourceMap.calledWith({}, 'moduleId')).to.be.true; 679 expect(result).to.equal(fakeSourceMap); 680 }); 681 682 mocha.it('10-4: should call getSpecifySourceMap with relativeSourceFilePath if isNewSourceMaps is false', function() { 683 const fakeSourceMap = {}; 684 const instanceStub = { 685 isNewSourceMaps: sinon.stub().returns(false), 686 getSpecifySourceMap: sinon.stub().returns(fakeSourceMap) 687 }; 688 sourceMapGeneratorStub.returns(instanceStub); 689 690 const moduleInfo = { 691 buildFilePath: 'file.js', 692 relativeSourceFilePath: 'sourceFile.ts', 693 rollupModuleId: 'moduleId' 694 }; 695 const result = getPreviousStageSourceMap(moduleInfo); 696 697 expect(instanceStub.getSpecifySourceMap.calledWith({}, 'sourceFile.ts')).to.be.true; 698 expect(result).to.equal(fakeSourceMap); 699 }); 700 }) 701 mocha.describe('11: test collectObfuscationFileContent', function () { 702 let fileContentManagerStub; 703 704 mocha.beforeEach(function () { 705 fileContentManagerStub = { 706 updateFileContent: sinon.stub(), 707 }; 708 }); 709 710 mocha.afterEach(function () { 711 sinon.restore(); 712 }); 713 714 mocha.it('11-1: should not call updateFileContent if filePathManager is not defined', function () { 715 const moduleInfo = { 716 buildFilePath: 'file.js', 717 originSourceFilePath: 'sourceFile.ts', 718 }; 719 const projectConfig = { 720 arkObfuscator: {}, 721 }; 722 const previousStageSourceMap = {}; 723 724 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 725 726 expect(fileContentManagerStub.updateFileContent.called).to.be.false; 727 }); 728 729 mocha.it('11-2: should not call updateFileContent if the file is a declaration file and not an original declaration file', function () { 730 const moduleInfo = { 731 buildFilePath: 'file.d.ts', 732 originSourceFilePath: 'sourceFile.ts', 733 }; 734 const projectConfig = { 735 arkObfuscator: { 736 filePathManager: {}, 737 fileContentManager: fileContentManagerStub, 738 }, 739 }; 740 const previousStageSourceMap = {}; 741 742 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 743 744 expect(fileContentManagerStub.updateFileContent.called).to.be.false; 745 }); 746 747 mocha.it('11-3: should call updateFileContent if the file is not a declaration file', function () { 748 const moduleInfo = { 749 buildFilePath: 'file.js', 750 originSourceFilePath: 'sourceFile.ts', 751 }; 752 const projectConfig = { 753 arkObfuscator: { 754 filePathManager: {}, 755 fileContentManager: fileContentManagerStub, 756 }, 757 }; 758 const previousStageSourceMap = {}; 759 760 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 761 762 expect(fileContentManagerStub.updateFileContent.calledOnce).to.be.true; 763 expect(fileContentManagerStub.updateFileContent.calledWith({ 764 moduleInfo: moduleInfo, 765 previousStageSourceMap: previousStageSourceMap, 766 })).to.be.true; 767 }); 768 769 mocha.it('11-4: should call updateFileContent if the file is an original declaration file', function () { 770 const moduleInfo = { 771 buildFilePath: 'file.d.ts', 772 originSourceFilePath: 'file.d.ts', 773 }; 774 const projectConfig = { 775 arkObfuscator: { 776 filePathManager: {}, 777 fileContentManager: fileContentManagerStub, 778 }, 779 }; 780 const previousStageSourceMap = {}; 781 782 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 783 784 expect(fileContentManagerStub.updateFileContent.calledOnce).to.be.true; 785 expect(fileContentManagerStub.updateFileContent.calledWith({ 786 moduleInfo: moduleInfo, 787 previousStageSourceMap: previousStageSourceMap, 788 })).to.be.true; 789 }); 790 }); 791});