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('9-1: test writeArkguardObfuscatedSourceCode when obfuscation is enabled', async function () { 507 this.rollup.build(RELEASE); 508 const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME); 509 const arkguardConfig = { 510 mCompact: false, 511 mDisableConsole: false, 512 mSimplify: false, 513 mRemoveComments: true, 514 mNameObfuscation: { 515 mEnable: true, 516 mNameGeneratorType: 1, 517 mReservedNames: [], 518 mRenameProperties: false, 519 mReservedProperties: [], 520 mKeepStringProperty: true, 521 mTopLevel: false, 522 mReservedToplevelNames: [], 523 mUniversalReservedProperties: [], 524 mUniversalReservedToplevelNames: [], 525 }, 526 mRemoveDeclarationComments: { 527 mEnable: true, 528 mReservedComments: [] 529 }, 530 mEnableSourceMap: true, 531 mEnableNameCache: true, 532 mRenameFileName: { 533 mEnable: false, 534 mNameGeneratorType: 1, 535 mReservedFileNames: [], 536 }, 537 mExportObfuscation: false, 538 mPerformancePrinter: { 539 mFilesPrinter: false, 540 mSingleFilePrinter: false, 541 mSumPrinter: false, 542 mOutputPath: "" 543 }, 544 mKeepFileSourceCode: { 545 mKeepSourceOfPaths: new Set(), 546 mkeepFilesAndDependencies: new Set(), 547 }, 548 }; 549 550 const sourceMapGenerator: SourceMapGenerator = SourceMapGenerator.initInstance(this.rollup); 551 sourceMapGenerator.setNewSoureMaps(false); 552 const arkObfuscator: ArkObfuscator = new ArkObfuscator(); 553 arkObfuscator.init(arkguardConfig); 554 555 const projectConfig = { 556 projectRootPath: PROJECT_ROOT, 557 arkObfuscator: arkObfuscator, 558 packageDir: 'oh_modules', 559 localPackageSet: new Set(), 560 useTsHar: false, 561 useNormalized: false 562 }; 563 564 const sourceFileName = 'sourceFile.ts'; 565 const originalSourceFilePath = path.join(__dirname, '../../test/ark_compiler_ut/testdata/har_obfuscation', sourceFileName); 566 const moduleInfo = { 567 content: fs.readFileSync(originalSourceFilePath, 'utf-8'), 568 buildFilePath: `${PROJECT_ROOT}/har_obfuscation/build/default/cache/${sourceFileName}`, 569 relativeSourceFilePath: `har_obfuscation/${sourceFileName}`, 570 originSourceFilePath: originalSourceFilePath, 571 rollupModuleId: originalSourceFilePath 572 }; 573 574 try { 575 await writeArkguardObfuscatedSourceCode(moduleInfo, logger, projectConfig, undefined); 576 } catch (e) { 577 } 578 const expectedResult = `export function add(d: number, e: number): number { 579 return d + e; 580} 581export function findElement<a>(b: a[], c: (item: a) => boolean): a | undefined { 582 return b.find(c); 583} 584`; 585 const result = fs.readFileSync(moduleInfo.buildFilePath, 'utf-8'); 586 expect(result === expectedResult).to.be.true; 587 588 const declFileName = 'sourceFile.d.ts'; 589 const originalDeclFilePath = path.join(__dirname, '../../test/ark_compiler_ut/testdata/har_obfuscation/', declFileName); 590 591 const declModuleInfo = { 592 content: fs.readFileSync(originalDeclFilePath, 'utf-8'), 593 buildFilePath: `${PROJECT_ROOT}/har_obfuscation/build/default/cache/${declFileName}`, 594 relativeSourceFilePath: `har_obfuscation/build/default/cache/${declFileName}`, 595 originSourceFilePath: originalSourceFilePath, 596 rollupModuleId: originalSourceFilePath 597 }; 598 599 try { 600 await writeArkguardObfuscatedSourceCode(declModuleInfo, logger, projectConfig, undefined); 601 } catch (e) { 602 } 603 604 const expectedDeclResult = `export declare function add(d: number, e: number): number; 605export declare function findElement<a>(b: a[], c: (item: a) => boolean): a | undefined; 606`; 607 const declResult = fs.readFileSync(declModuleInfo.buildFilePath, 'utf-8'); 608 expect(declResult === expectedDeclResult).to.be.true; 609 }); 610 611 mocha.describe('10: test getPreviousStageSourceMap', function() { 612 let sourceMapGeneratorStub; 613 mocha.beforeEach(function () { 614 sourceMapGeneratorStub = sinon.stub(SourceMapGenerator, 'getInstance'); 615 }); 616 617 mocha.afterEach(() => { 618 sinon.restore(); 619 }); 620 621 mocha.it('10-1: should return undefined if relativeSourceFilePath is empty', async function () { 622 const moduleInfo = { 623 buildFilePath: 'file.js', 624 relativeSourceFilePath: '', 625 rollupModuleId: 'moduleId' 626 }; 627 const result = getPreviousStageSourceMap(moduleInfo); 628 expect(result).to.be.undefined; 629 }); 630 631 mocha.it('10-2: should return undefined if the file is a declaration file', function() { 632 const moduleInfo = { 633 buildFilePath: 'file.d.ts', 634 relativeSourceFilePath: 'sourceFile.ts', 635 rollupModuleId: 'moduleId' 636 }; 637 const result = getPreviousStageSourceMap(moduleInfo); 638 expect(result).to.be.undefined; 639 }); 640 641 mocha.it('10-3: should call getSpecifySourceMap with rollupModuleId if isNewSourceMaps is true', function() { 642 const fakeSourceMap = {}; 643 const instanceStub = { 644 isNewSourceMaps: sinon.stub().returns(true), 645 getSpecifySourceMap: sinon.stub().returns(fakeSourceMap) 646 }; 647 sourceMapGeneratorStub.returns(instanceStub); 648 649 const moduleInfo = { 650 buildFilePath: 'file.js', 651 relativeSourceFilePath: 'sourceFile.ts', 652 rollupModuleId: 'moduleId' 653 }; 654 const result = getPreviousStageSourceMap(moduleInfo); 655 656 expect(instanceStub.getSpecifySourceMap.calledWith({}, 'moduleId')).to.be.true; 657 expect(result).to.equal(fakeSourceMap); 658 }); 659 660 mocha.it('10-4: should call getSpecifySourceMap with relativeSourceFilePath if isNewSourceMaps is false', function() { 661 const fakeSourceMap = {}; 662 const instanceStub = { 663 isNewSourceMaps: sinon.stub().returns(false), 664 getSpecifySourceMap: sinon.stub().returns(fakeSourceMap) 665 }; 666 sourceMapGeneratorStub.returns(instanceStub); 667 668 const moduleInfo = { 669 buildFilePath: 'file.js', 670 relativeSourceFilePath: 'sourceFile.ts', 671 rollupModuleId: 'moduleId' 672 }; 673 const result = getPreviousStageSourceMap(moduleInfo); 674 675 expect(instanceStub.getSpecifySourceMap.calledWith({}, 'sourceFile.ts')).to.be.true; 676 expect(result).to.equal(fakeSourceMap); 677 }); 678 }) 679 mocha.describe('11: test collectObfuscationFileContent', function () { 680 let fileContentManagerStub; 681 682 mocha.beforeEach(function () { 683 fileContentManagerStub = { 684 updateFileContent: sinon.stub(), 685 }; 686 }); 687 688 mocha.afterEach(function () { 689 sinon.restore(); 690 }); 691 692 mocha.it('11-1: should not call updateFileContent if filePathManager is not defined', function () { 693 const moduleInfo = { 694 buildFilePath: 'file.js', 695 originSourceFilePath: 'sourceFile.ts', 696 }; 697 const projectConfig = { 698 arkObfuscator: {}, 699 }; 700 const previousStageSourceMap = {}; 701 702 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 703 704 expect(fileContentManagerStub.updateFileContent.called).to.be.false; 705 }); 706 707 mocha.it('11-2: should not call updateFileContent if the file is a declaration file and not an original declaration file', function () { 708 const moduleInfo = { 709 buildFilePath: 'file.d.ts', 710 originSourceFilePath: 'sourceFile.ts', 711 }; 712 const projectConfig = { 713 arkObfuscator: { 714 filePathManager: {}, 715 fileContentManager: fileContentManagerStub, 716 }, 717 }; 718 const previousStageSourceMap = {}; 719 720 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 721 722 expect(fileContentManagerStub.updateFileContent.called).to.be.false; 723 }); 724 725 mocha.it('11-3: should call updateFileContent if the file is not a declaration file', function () { 726 const moduleInfo = { 727 buildFilePath: 'file.js', 728 originSourceFilePath: 'sourceFile.ts', 729 }; 730 const projectConfig = { 731 arkObfuscator: { 732 filePathManager: {}, 733 fileContentManager: fileContentManagerStub, 734 }, 735 }; 736 const previousStageSourceMap = {}; 737 738 collectObfuscationFileContent(moduleInfo, projectConfig, previousStageSourceMap); 739 740 expect(fileContentManagerStub.updateFileContent.calledOnce).to.be.true; 741 expect(fileContentManagerStub.updateFileContent.calledWith({ 742 moduleInfo: moduleInfo, 743 previousStageSourceMap: previousStageSourceMap, 744 })).to.be.true; 745 }); 746 747 mocha.it('11-4: should call updateFileContent if the file is an original declaration file', function () { 748 const moduleInfo = { 749 buildFilePath: 'file.d.ts', 750 originSourceFilePath: 'file.d.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});