13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciimport { describe, it } from 'mocha';
173af6ab5fSopenharmony_ciimport { assert } from 'chai';
183af6ab5fSopenharmony_ciimport { ArkObfuscator, FileUtils, wildcardTransformer } from '../../../src/ArkObfuscator';
193af6ab5fSopenharmony_ciimport { ArkObfuscatorForTest } from '../../../src/ArkObfuscatorForTest'
203af6ab5fSopenharmony_ciimport path from 'path';
213af6ab5fSopenharmony_ciimport { TransformerFactory, Node, SourceFile, createSourceFile, ScriptTarget, Printer, createTextWriter, RawSourceMap } from 'typescript';
223af6ab5fSopenharmony_ciimport { IOptions } from '../../../src/configs/IOptions';
233af6ab5fSopenharmony_ciimport { getSourceMapGenerator } from '../../../src/utils/SourceMapUtil';
243af6ab5fSopenharmony_ciimport fs from 'fs';
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_cidescribe('Tester Cases for <ArkObfuscatorForTest>.', function () {
273af6ab5fSopenharmony_ci  describe('Tester Cases for <ArkObfuscatorForTest>.', function () {
283af6ab5fSopenharmony_ci    let etsSourceFile: SourceFile;
293af6ab5fSopenharmony_ci    let dEtsSourceFile: SourceFile;
303af6ab5fSopenharmony_ci    let tsSourceFile: SourceFile;
313af6ab5fSopenharmony_ci    let etsSourceFilePath: string = 'demo.ets';
323af6ab5fSopenharmony_ci    let dEtsSourceFilePath: string = 'demo.d.ets';
333af6ab5fSopenharmony_ci    let tsSourceFilePath: string = 'demo.ts';
343af6ab5fSopenharmony_ci
353af6ab5fSopenharmony_ci    before('init sourceFile', function () {
363af6ab5fSopenharmony_ci      const etsfileContent = `//This is a comment
373af6ab5fSopenharmony_ci//This is a comment
383af6ab5fSopenharmony_ci//This is a comment
393af6ab5fSopenharmony_ci//This is a comment
403af6ab5fSopenharmony_ciclass Demo{
413af6ab5fSopenharmony_ci  constructor(public  title: string, public  content: string, public  mark: number) {
423af6ab5fSopenharmony_ci      this.title = title
433af6ab5fSopenharmony_ci      this.content = content
443af6ab5fSopenharmony_ci      this.mark = mark
453af6ab5fSopenharmony_ci  }
463af6ab5fSopenharmony_ci}
473af6ab5fSopenharmony_ci`;
483af6ab5fSopenharmony_ci      const dEtsFileContent = `
493af6ab5fSopenharmony_ci      /**
503af6ab5fSopenharmony_ci       * This is a comment
513af6ab5fSopenharmony_ci       */
523af6ab5fSopenharmony_ci      
533af6ab5fSopenharmony_ci      class Demo{
543af6ab5fSopenharmony_ci          constructor(public  title: string, public  content: string, public  mark: number) {
553af6ab5fSopenharmony_ci              this.title = title
563af6ab5fSopenharmony_ci              this.content = content
573af6ab5fSopenharmony_ci              this.mark = mark
583af6ab5fSopenharmony_ci          }
593af6ab5fSopenharmony_ci      }
603af6ab5fSopenharmony_ci      `;
613af6ab5fSopenharmony_ci
623af6ab5fSopenharmony_ci      const tsFileContent = `
633af6ab5fSopenharmony_ci      //This is a comment
643af6ab5fSopenharmony_ci      class Demo{
653af6ab5fSopenharmony_ci          constructor(public  title: string, public  content: string, public  mark: number) {
663af6ab5fSopenharmony_ci              this.title = title
673af6ab5fSopenharmony_ci              this.content = content
683af6ab5fSopenharmony_ci              this.mark = mark
693af6ab5fSopenharmony_ci          }
703af6ab5fSopenharmony_ci      }
713af6ab5fSopenharmony_ci      `;
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci      etsSourceFile = createSourceFile('demo.ts', etsfileContent, ScriptTarget.ES2015, true);
743af6ab5fSopenharmony_ci      dEtsSourceFile = createSourceFile(dEtsSourceFilePath, dEtsFileContent, ScriptTarget.ES2015, true);
753af6ab5fSopenharmony_ci      tsSourceFile = createSourceFile(tsSourceFilePath, tsFileContent, ScriptTarget.ES2015, true);
763af6ab5fSopenharmony_ci    });
773af6ab5fSopenharmony_ci
783af6ab5fSopenharmony_ci    it('Tester: test case for handleTsHarComments for ets file', function () {
793af6ab5fSopenharmony_ci      let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json"));
803af6ab5fSopenharmony_ci      let arkobfuscator = new ArkObfuscatorForTest();
813af6ab5fSopenharmony_ci      arkobfuscator.init(mCustomProfiles);
823af6ab5fSopenharmony_ci      let originalFilePath = 'demo.ets';
833af6ab5fSopenharmony_ci      ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true };
843af6ab5fSopenharmony_ci      arkobfuscator.handleTsHarComments(etsSourceFile, originalFilePath);
853af6ab5fSopenharmony_ci      let sourceMapGenerator = getSourceMapGenerator(originalFilePath);
863af6ab5fSopenharmony_ci      const textWriter = createTextWriter('\n');
873af6ab5fSopenharmony_ci      arkobfuscator.createObfsPrinter(etsSourceFile.isDeclarationFile).writeFile(etsSourceFile, textWriter, sourceMapGenerator);
883af6ab5fSopenharmony_ci      const actualContent = textWriter.getText();
893af6ab5fSopenharmony_ci      const expectContent = `
903af6ab5fSopenharmony_ci      // @keepTs
913af6ab5fSopenharmony_ci      // @ts-nocheck
923af6ab5fSopenharmony_ci      class Demo {
933af6ab5fSopenharmony_ci          constructor(public title: string, public content: string, public mark: number) {
943af6ab5fSopenharmony_ci              this.title = title;
953af6ab5fSopenharmony_ci              this.content = content;
963af6ab5fSopenharmony_ci              this.mark = mark;
973af6ab5fSopenharmony_ci          }
983af6ab5fSopenharmony_ci      }`;
993af6ab5fSopenharmony_ci      
1003af6ab5fSopenharmony_ci      let actualSourceMap: RawSourceMap = sourceMapGenerator.toJSON();
1013af6ab5fSopenharmony_ci      actualSourceMap.sourceRoot = "";
1023af6ab5fSopenharmony_ci      let expectSourceMap = {
1033af6ab5fSopenharmony_ci          "version": 3,
1043af6ab5fSopenharmony_ci          "file": "demo.ets",
1053af6ab5fSopenharmony_ci          "sourceRoot": "",
1063af6ab5fSopenharmony_ci          "sources": [
1073af6ab5fSopenharmony_ci            "demo.ts"
1083af6ab5fSopenharmony_ci          ],
1093af6ab5fSopenharmony_ci          "names": [],
1103af6ab5fSopenharmony_ci          "mappings": ";;AAIA,MAAM,IAAI;IACR,YAAY,MAAM,CAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAE,IAAI,EAAE,MAAM;QAC5E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IACpB,CAAC;CACF"
1113af6ab5fSopenharmony_ci        }
1123af6ab5fSopenharmony_ci      console.log(JSON.stringify(actualSourceMap, null, 2))
1133af6ab5fSopenharmony_ci      assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true);
1143af6ab5fSopenharmony_ci      assert.strictEqual(compareStringsIgnoreNewlines(JSON.stringify(actualSourceMap, null, 2), JSON.stringify(expectSourceMap, null, 2)), true);
1153af6ab5fSopenharmony_ci    });
1163af6ab5fSopenharmony_ci
1173af6ab5fSopenharmony_ci    it('Tester: test case for handleTsHarComments for d.ets file', function () {
1183af6ab5fSopenharmony_ci      let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json"));
1193af6ab5fSopenharmony_ci      let arkobfuscator = new ArkObfuscatorForTest();
1203af6ab5fSopenharmony_ci      arkobfuscator.init(mCustomProfiles);
1213af6ab5fSopenharmony_ci      ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true };
1223af6ab5fSopenharmony_ci      arkobfuscator.handleTsHarComments(dEtsSourceFile, dEtsSourceFilePath);
1233af6ab5fSopenharmony_ci      let sourceMapGenerator = getSourceMapGenerator(dEtsSourceFilePath);
1243af6ab5fSopenharmony_ci      const textWriter = createTextWriter('\n');
1253af6ab5fSopenharmony_ci      arkobfuscator.createObfsPrinter(dEtsSourceFile.isDeclarationFile).writeFile(dEtsSourceFile, textWriter, sourceMapGenerator);
1263af6ab5fSopenharmony_ci      const actualContent = textWriter.getText();
1273af6ab5fSopenharmony_ci      const expectContent = `
1283af6ab5fSopenharmony_ci      /**
1293af6ab5fSopenharmony_ci       * This is a comment
1303af6ab5fSopenharmony_ci       */
1313af6ab5fSopenharmony_ci      class Demo {
1323af6ab5fSopenharmony_ci          constructor(public title: string, public content: string, public mark: number) {
1333af6ab5fSopenharmony_ci              this.title = title;
1343af6ab5fSopenharmony_ci              this.content = content;
1353af6ab5fSopenharmony_ci              this.mark = mark;
1363af6ab5fSopenharmony_ci          }
1373af6ab5fSopenharmony_ci      }`;
1383af6ab5fSopenharmony_ci      assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true);
1393af6ab5fSopenharmony_ci    });
1403af6ab5fSopenharmony_ci
1413af6ab5fSopenharmony_ci    it('Tester: test case for handleTsHarComments for ts file', function () {
1423af6ab5fSopenharmony_ci      let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json"));
1433af6ab5fSopenharmony_ci      let arkobfuscator = new ArkObfuscatorForTest();
1443af6ab5fSopenharmony_ci      arkobfuscator.init(mCustomProfiles);
1453af6ab5fSopenharmony_ci      ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true };
1463af6ab5fSopenharmony_ci      arkobfuscator.handleTsHarComments(tsSourceFile, tsSourceFilePath);
1473af6ab5fSopenharmony_ci      let sourceMapGenerator = getSourceMapGenerator(tsSourceFilePath);
1483af6ab5fSopenharmony_ci      const textWriter = createTextWriter('\n');
1493af6ab5fSopenharmony_ci      arkobfuscator.createObfsPrinter(tsSourceFile.isDeclarationFile).writeFile(tsSourceFile, textWriter, sourceMapGenerator);
1503af6ab5fSopenharmony_ci      const actualContent = textWriter.getText();
1513af6ab5fSopenharmony_ci      const expectContent = `
1523af6ab5fSopenharmony_ci        class Demo {
1533af6ab5fSopenharmony_ci          constructor(public title: string, public content: string, public mark: number) {
1543af6ab5fSopenharmony_ci            this.title = title;
1553af6ab5fSopenharmony_ci            this.content = content;
1563af6ab5fSopenharmony_ci            this.mark = mark;
1573af6ab5fSopenharmony_ci          }
1583af6ab5fSopenharmony_ci        }`;
1593af6ab5fSopenharmony_ci      console.log(actualContent)
1603af6ab5fSopenharmony_ci      assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true);
1613af6ab5fSopenharmony_ci      console.log(actualContent);
1623af6ab5fSopenharmony_ci    });
1633af6ab5fSopenharmony_ci  });
1643af6ab5fSopenharmony_ci
1653af6ab5fSopenharmony_ci  describe('Tester Cases for <ArkObfuscatorForTest>.', function () {
1663af6ab5fSopenharmony_ci    it('Tester: test case for ArkObfuscatorForTest.ini', function (){
1673af6ab5fSopenharmony_ci      let configPath = "test/ut/arkobfuscator/iniTestObfConfig.json"
1683af6ab5fSopenharmony_ci      let obfuscator: ArkObfuscatorForTest = new ArkObfuscatorForTest();
1693af6ab5fSopenharmony_ci      const originalConfig: IOptions | undefined = FileUtils.readFileAsJson(configPath);
1703af6ab5fSopenharmony_ci      obfuscator.init(originalConfig);
1713af6ab5fSopenharmony_ci      let config = obfuscator.customProfiles;
1723af6ab5fSopenharmony_ci      let reservedTopelevelNames = config.mNameObfuscation?.mReservedToplevelNames;
1733af6ab5fSopenharmony_ci      let reservedProperty = config.mNameObfuscation?.mReservedProperties;
1743af6ab5fSopenharmony_ci      let universalReservedToplevelNames = config.mNameObfuscation?.mUniversalReservedToplevelNames as RegExp[];
1753af6ab5fSopenharmony_ci      let universalReservedProperties = config.mNameObfuscation?.mUniversalReservedProperties as RegExp[];
1763af6ab5fSopenharmony_ci      assert.isTrue(reservedTopelevelNames?.includes("func2"));
1773af6ab5fSopenharmony_ci      assert.isTrue(reservedProperty?.includes("prop"));
1783af6ab5fSopenharmony_ci      assert.equal(universalReservedToplevelNames[0].toString(), new RegExp(`^${wildcardTransformer("a*")}$`).toString());
1793af6ab5fSopenharmony_ci      assert.equal(universalReservedToplevelNames[1].toString(), new RegExp(`^${wildcardTransformer("*shoul?keep*")}$`).toString());
1803af6ab5fSopenharmony_ci      assert.equal(universalReservedProperties[0].toString(), new RegExp(`^${wildcardTransformer("prop?")}$`).toString());
1813af6ab5fSopenharmony_ci      assert.equal(universalReservedProperties[2].toString(), new RegExp(`^${wildcardTransformer("*pro?")}$`).toString());
1823af6ab5fSopenharmony_ci      assert.equal(universalReservedProperties[1].toString(), new RegExp(`^${wildcardTransformer("function*")}$`).toString());
1833af6ab5fSopenharmony_ci    });
1843af6ab5fSopenharmony_ci  });
1853af6ab5fSopenharmony_ci
1863af6ab5fSopenharmony_ci  describe('Tester Cases for <ArkObfuscator>.', function () {
1873af6ab5fSopenharmony_ci    it('Tester: test case for ArkObfuscator.ini', function (){
1883af6ab5fSopenharmony_ci      let configPath = "test/ut/arkobfuscator/iniTestObfConfig.json"
1893af6ab5fSopenharmony_ci      let obfuscator: ArkObfuscator = new ArkObfuscator();
1903af6ab5fSopenharmony_ci      let config = FileUtils.readFileAsJson(configPath) as IOptions;
1913af6ab5fSopenharmony_ci      obfuscator.init(config);
1923af6ab5fSopenharmony_ci      let reservedTopelevelNames = config.mNameObfuscation?.mReservedToplevelNames;
1933af6ab5fSopenharmony_ci      let reservedProperty = config.mNameObfuscation?.mReservedProperties;
1943af6ab5fSopenharmony_ci      let universalReservedToplevelNames = config.mNameObfuscation?.mUniversalReservedToplevelNames;
1953af6ab5fSopenharmony_ci      let universalReservedProperties = config.mNameObfuscation?.mUniversalReservedProperties;
1963af6ab5fSopenharmony_ci      assert.isTrue(reservedTopelevelNames?.includes("func2"));
1973af6ab5fSopenharmony_ci      assert.isTrue(reservedTopelevelNames?.includes("a*"));
1983af6ab5fSopenharmony_ci      assert.isTrue(reservedTopelevelNames?.includes("*shoul?keep*"));
1993af6ab5fSopenharmony_ci      assert.isTrue(reservedProperty?.includes("prop"));
2003af6ab5fSopenharmony_ci      assert.isTrue(reservedProperty?.includes("prop?"));
2013af6ab5fSopenharmony_ci      assert.isTrue(reservedProperty?.includes("*pro?"));
2023af6ab5fSopenharmony_ci      assert.isTrue(reservedProperty?.includes("function*"));
2033af6ab5fSopenharmony_ci      assert.equal(universalReservedToplevelNames, undefined);
2043af6ab5fSopenharmony_ci      assert.equal(universalReservedProperties, undefined);
2053af6ab5fSopenharmony_ci    });
2063af6ab5fSopenharmony_ci  });
2073af6ab5fSopenharmony_ci});
2083af6ab5fSopenharmony_ci
2093af6ab5fSopenharmony_cifunction compareStringsIgnoreNewlines(str1: string, str2: string): boolean {
2103af6ab5fSopenharmony_ci  const normalize = (str: string) => str.replace(/[\n\r\s]+/g, '');
2113af6ab5fSopenharmony_ci  return normalize(str1) === normalize(str2);
2123af6ab5fSopenharmony_ci}