13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2023-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_ciconst fs = require('fs');
173af6ab5fSopenharmony_ciconst path = require('path');
183af6ab5fSopenharmony_ciconst diff = require('diff');
193af6ab5fSopenharmony_ciconst { execSync } = require('child_process');
203af6ab5fSopenharmony_ciimport { Extension } from '../src/common/type';
213af6ab5fSopenharmony_ciimport { FileUtils } from '../src/utils/FileUtils';
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ciconst testDirectory = path.resolve('./test/local');
243af6ab5fSopenharmony_ciconst NonExecutableFile = ['name_as_export_api_1.ts', 'name_as_import_api_1.ts', 'ohmurl_test.ts', 'ohmurl_test_new.ts',
253af6ab5fSopenharmony_ci  'export_struct_transform_class.ts', 'nosymbolIdentifierTest.ts'];
263af6ab5fSopenharmony_ciconst PRINT_UNOBFUSCATION_SUFFIX = 'keptNames.unobf.json';
273af6ab5fSopenharmony_ciconst EXPECTED_UNOBFUSCATION_SUFFIX = '_expected_unobf.txt';
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_cifunction runTest(filePath) {
303af6ab5fSopenharmony_ci  try {
313af6ab5fSopenharmony_ci    const command = `node ./node_modules/ts-node/dist/bin.js ${filePath}`;
323af6ab5fSopenharmony_ci    execSync(command);
333af6ab5fSopenharmony_ci  } catch (error) {
343af6ab5fSopenharmony_ci    console.error(`Test case ${filePath} failed:`, error);
353af6ab5fSopenharmony_ci    return false;
363af6ab5fSopenharmony_ci  }
373af6ab5fSopenharmony_ci  return true;
383af6ab5fSopenharmony_ci}
393af6ab5fSopenharmony_cilet successCount = 0;
403af6ab5fSopenharmony_cilet failureCount = 0;
413af6ab5fSopenharmony_cilet contentcomparationSuccessCount = 0;
423af6ab5fSopenharmony_cilet contentcomparationFailureCount = 0;
433af6ab5fSopenharmony_ciconst failedFiles = [];
443af6ab5fSopenharmony_ciconst contentComparisionFailureFiles = [];
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_cifunction runTestsInDirectory(directoryPath) {
473af6ab5fSopenharmony_ci  const files = fs.readdirSync(directoryPath);
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_ci  for (const file of files) {
503af6ab5fSopenharmony_ci    const filePath = path.join(directoryPath, file);
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci    if (fs.statSync(filePath).isDirectory()) {
533af6ab5fSopenharmony_ci      runTestsInDirectory(filePath);
543af6ab5fSopenharmony_ci    } else if (filePath.includes('assert-expectation.ts')) {
553af6ab5fSopenharmony_ci      const isSuccess = runTest(filePath);
563af6ab5fSopenharmony_ci      if (isSuccess) {
573af6ab5fSopenharmony_ci        successCount++;
583af6ab5fSopenharmony_ci      } else {
593af6ab5fSopenharmony_ci        failureCount++;
603af6ab5fSopenharmony_ci        failedFiles.push(filePath);
613af6ab5fSopenharmony_ci      }
623af6ab5fSopenharmony_ci    } else if ((filePath.endsWith(Extension.TS) || filePath.endsWith(Extension.JS)) && !(filePath.endsWith(Extension.DETS) ||
633af6ab5fSopenharmony_ci      filePath.endsWith(Extension.DTS))) {
643af6ab5fSopenharmony_ci      executeRunTest(file, filePath);
653af6ab5fSopenharmony_ci      compareContent(filePath);
663af6ab5fSopenharmony_ci    } else if (filePath.endsWith(Extension.DETS) || filePath.endsWith(Extension.DTS)) {
673af6ab5fSopenharmony_ci      compareContent(filePath);
683af6ab5fSopenharmony_ci    }
693af6ab5fSopenharmony_ci  }
703af6ab5fSopenharmony_ci}
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_cifunction executeRunTest(fileName, filePath) {
733af6ab5fSopenharmony_ci  if (!NonExecutableFile.includes(fileName)) {
743af6ab5fSopenharmony_ci    const isSuccess = runTest(filePath);
753af6ab5fSopenharmony_ci    if (isSuccess) {
763af6ab5fSopenharmony_ci      successCount++;
773af6ab5fSopenharmony_ci    } else {
783af6ab5fSopenharmony_ci      failureCount++;
793af6ab5fSopenharmony_ci      failedFiles.push(filePath);
803af6ab5fSopenharmony_ci    }
813af6ab5fSopenharmony_ci  }
823af6ab5fSopenharmony_ci}
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_cifunction compareContent(filePath) {
853af6ab5fSopenharmony_ci  const sourcePath = filePath.replace('/test/local/', '/test/grammar/');
863af6ab5fSopenharmony_ci  const sourcePathAndExtension = FileUtils.getFileSuffix(sourcePath);
873af6ab5fSopenharmony_ci  const expectationPath = sourcePathAndExtension.path + '_expected.txt';
883af6ab5fSopenharmony_ci  const resultPathAndExtension = FileUtils.getFileSuffix(filePath);
893af6ab5fSopenharmony_ci  const resultCachePath = resultPathAndExtension.path + '.ts.cache.json';
903af6ab5fSopenharmony_ci  const expectationCachePath = sourcePathAndExtension.path + '_expected_cache.txt';
913af6ab5fSopenharmony_ci  const hasExpectationFile = fs.existsSync(expectationPath);
923af6ab5fSopenharmony_ci  const hasExpectationCache = fs.existsSync(expectationCachePath);
933af6ab5fSopenharmony_ci  const hasResultCache = fs.existsSync(resultCachePath);
943af6ab5fSopenharmony_ci  // compare print_unobfuscation
953af6ab5fSopenharmony_ci  const resultUnobfuscationPath = path.join(path.dirname(resultPathAndExtension.path), PRINT_UNOBFUSCATION_SUFFIX);
963af6ab5fSopenharmony_ci  const expectUnobfuscationPath = sourcePathAndExtension.path + EXPECTED_UNOBFUSCATION_SUFFIX;
973af6ab5fSopenharmony_ci  const hasExpectationUnobfuscation = fs.existsSync(expectUnobfuscationPath);
983af6ab5fSopenharmony_ci  const hasResultUnobfuscation = fs.existsSync(resultUnobfuscationPath);
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci  const compareExpected = function(filePath, actual, expectation) {
1013af6ab5fSopenharmony_ci    if (actual.replace(/(\n|\r\n)/g, '') === expectation.replace(/(\n|\r\n)/g, '')) {
1023af6ab5fSopenharmony_ci      contentcomparationSuccessCount++;
1033af6ab5fSopenharmony_ci    } else {
1043af6ab5fSopenharmony_ci      contentcomparationFailureCount++;
1053af6ab5fSopenharmony_ci      contentComparisionFailureFiles.push(filePath);
1063af6ab5fSopenharmony_ci      const differences = diff.diffLines(actual, expectation);
1073af6ab5fSopenharmony_ci      differences.forEach(part => {
1083af6ab5fSopenharmony_ci        const color = part.added ? '\x1b[32m' : part.removed ? '\x1b[31m' : '\x1b[0m';
1093af6ab5fSopenharmony_ci        console.log(color + part.value + '\x1b[0m');
1103af6ab5fSopenharmony_ci      });
1113af6ab5fSopenharmony_ci    }
1123af6ab5fSopenharmony_ci  };
1133af6ab5fSopenharmony_ci
1143af6ab5fSopenharmony_ci  if (hasExpectationFile) {
1153af6ab5fSopenharmony_ci    let actual = fs.readFileSync(filePath).toString();
1163af6ab5fSopenharmony_ci    let expectation = fs.readFileSync(expectationPath).toString();
1173af6ab5fSopenharmony_ci    compareExpected(filePath, actual, expectation);
1183af6ab5fSopenharmony_ci  }
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ci  if (hasExpectationCache && hasResultCache) {
1213af6ab5fSopenharmony_ci    let actual = fs.readFileSync(resultCachePath).toString();
1223af6ab5fSopenharmony_ci    let expectation = fs.readFileSync(expectationCachePath).toString();
1233af6ab5fSopenharmony_ci    compareExpected(filePath, actual, expectation);
1243af6ab5fSopenharmony_ci  }
1253af6ab5fSopenharmony_ci
1263af6ab5fSopenharmony_ci  if (hasExpectationUnobfuscation && hasResultUnobfuscation) {
1273af6ab5fSopenharmony_ci    let actual = fs.readFileSync(resultUnobfuscationPath).toString();
1283af6ab5fSopenharmony_ci    let expectation = fs.readFileSync(expectUnobfuscationPath).toString();
1293af6ab5fSopenharmony_ci    compareExpected(filePath, actual, expectation);
1303af6ab5fSopenharmony_ci  }
1313af6ab5fSopenharmony_ci}
1323af6ab5fSopenharmony_ci
1333af6ab5fSopenharmony_cirunTestsInDirectory(testDirectory);
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ciconsole.log('--- Grammar Test Results ---');
1363af6ab5fSopenharmony_ciconsole.log(`Success count: ${successCount}`);
1373af6ab5fSopenharmony_ciconsole.log(`Failure count: ${failureCount}`);
1383af6ab5fSopenharmony_ciif (failureCount > 0) {
1393af6ab5fSopenharmony_ci  console.log('Execution failed files:');
1403af6ab5fSopenharmony_ci  for (const failedFile of failedFiles) {
1413af6ab5fSopenharmony_ci    console.log(failedFile);
1423af6ab5fSopenharmony_ci  }
1433af6ab5fSopenharmony_ci}
1443af6ab5fSopenharmony_ci
1453af6ab5fSopenharmony_ciconsole.log(`Content comparison Success count: ${contentcomparationSuccessCount}`);
1463af6ab5fSopenharmony_ciconsole.log(`Content comparison Failure count: ${contentcomparationFailureCount}`);
1473af6ab5fSopenharmony_ciif (contentcomparationFailureCount > 0) {
1483af6ab5fSopenharmony_ci  console.log('Content comparision failed files:');
1493af6ab5fSopenharmony_ci  for (const failedFile of contentComparisionFailureFiles) {
1503af6ab5fSopenharmony_ci    console.log(failedFile);
1513af6ab5fSopenharmony_ci  }
1523af6ab5fSopenharmony_ci}