1/* 2 * Copyright (c) 2023-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 16const fs = require('fs'); 17const path = require('path'); 18const diff = require('diff'); 19const { execSync } = require('child_process'); 20import { Extension } from '../src/common/type'; 21import { FileUtils } from '../src/utils/FileUtils'; 22 23const testDirectory = path.resolve('./test/local'); 24const NonExecutableFile = ['name_as_export_api_1.ts', 'name_as_import_api_1.ts', 'ohmurl_test.ts', 'ohmurl_test_new.ts', 25 'export_struct_transform_class.ts', 'nosymbolIdentifierTest.ts']; 26const PRINT_UNOBFUSCATION_SUFFIX = 'keptNames.unobf.json'; 27const EXPECTED_UNOBFUSCATION_SUFFIX = '_expected_unobf.txt'; 28 29function runTest(filePath) { 30 try { 31 const command = `node ./node_modules/ts-node/dist/bin.js ${filePath}`; 32 execSync(command); 33 } catch (error) { 34 console.error(`Test case ${filePath} failed:`, error); 35 return false; 36 } 37 return true; 38} 39let successCount = 0; 40let failureCount = 0; 41let contentcomparationSuccessCount = 0; 42let contentcomparationFailureCount = 0; 43const failedFiles = []; 44const contentComparisionFailureFiles = []; 45 46function runTestsInDirectory(directoryPath) { 47 const files = fs.readdirSync(directoryPath); 48 49 for (const file of files) { 50 const filePath = path.join(directoryPath, file); 51 52 if (fs.statSync(filePath).isDirectory()) { 53 runTestsInDirectory(filePath); 54 } else if (filePath.includes('assert-expectation.ts')) { 55 const isSuccess = runTest(filePath); 56 if (isSuccess) { 57 successCount++; 58 } else { 59 failureCount++; 60 failedFiles.push(filePath); 61 } 62 } else if ((filePath.endsWith(Extension.TS) || filePath.endsWith(Extension.JS)) && !(filePath.endsWith(Extension.DETS) || 63 filePath.endsWith(Extension.DTS))) { 64 executeRunTest(file, filePath); 65 compareContent(filePath); 66 } else if (filePath.endsWith(Extension.DETS) || filePath.endsWith(Extension.DTS)) { 67 compareContent(filePath); 68 } 69 } 70} 71 72function executeRunTest(fileName, filePath) { 73 if (!NonExecutableFile.includes(fileName)) { 74 const isSuccess = runTest(filePath); 75 if (isSuccess) { 76 successCount++; 77 } else { 78 failureCount++; 79 failedFiles.push(filePath); 80 } 81 } 82} 83 84function compareContent(filePath) { 85 const sourcePath = filePath.replace('/test/local/', '/test/grammar/'); 86 const sourcePathAndExtension = FileUtils.getFileSuffix(sourcePath); 87 const expectationPath = sourcePathAndExtension.path + '_expected.txt'; 88 const resultPathAndExtension = FileUtils.getFileSuffix(filePath); 89 const resultCachePath = resultPathAndExtension.path + '.ts.cache.json'; 90 const expectationCachePath = sourcePathAndExtension.path + '_expected_cache.txt'; 91 const hasExpectationFile = fs.existsSync(expectationPath); 92 const hasExpectationCache = fs.existsSync(expectationCachePath); 93 const hasResultCache = fs.existsSync(resultCachePath); 94 // compare print_unobfuscation 95 const resultUnobfuscationPath = path.join(path.dirname(resultPathAndExtension.path), PRINT_UNOBFUSCATION_SUFFIX); 96 const expectUnobfuscationPath = sourcePathAndExtension.path + EXPECTED_UNOBFUSCATION_SUFFIX; 97 const hasExpectationUnobfuscation = fs.existsSync(expectUnobfuscationPath); 98 const hasResultUnobfuscation = fs.existsSync(resultUnobfuscationPath); 99 100 const compareExpected = function(filePath, actual, expectation) { 101 if (actual.replace(/(\n|\r\n)/g, '') === expectation.replace(/(\n|\r\n)/g, '')) { 102 contentcomparationSuccessCount++; 103 } else { 104 contentcomparationFailureCount++; 105 contentComparisionFailureFiles.push(filePath); 106 const differences = diff.diffLines(actual, expectation); 107 differences.forEach(part => { 108 const color = part.added ? '\x1b[32m' : part.removed ? '\x1b[31m' : '\x1b[0m'; 109 console.log(color + part.value + '\x1b[0m'); 110 }); 111 } 112 }; 113 114 if (hasExpectationFile) { 115 let actual = fs.readFileSync(filePath).toString(); 116 let expectation = fs.readFileSync(expectationPath).toString(); 117 compareExpected(filePath, actual, expectation); 118 } 119 120 if (hasExpectationCache && hasResultCache) { 121 let actual = fs.readFileSync(resultCachePath).toString(); 122 let expectation = fs.readFileSync(expectationCachePath).toString(); 123 compareExpected(filePath, actual, expectation); 124 } 125 126 if (hasExpectationUnobfuscation && hasResultUnobfuscation) { 127 let actual = fs.readFileSync(resultUnobfuscationPath).toString(); 128 let expectation = fs.readFileSync(expectUnobfuscationPath).toString(); 129 compareExpected(filePath, actual, expectation); 130 } 131} 132 133runTestsInDirectory(testDirectory); 134 135console.log('--- Grammar Test Results ---'); 136console.log(`Success count: ${successCount}`); 137console.log(`Failure count: ${failureCount}`); 138if (failureCount > 0) { 139 console.log('Execution failed files:'); 140 for (const failedFile of failedFiles) { 141 console.log(failedFile); 142 } 143} 144 145console.log(`Content comparison Success count: ${contentcomparationSuccessCount}`); 146console.log(`Content comparison Failure count: ${contentcomparationFailureCount}`); 147if (contentcomparationFailureCount > 0) { 148 console.log('Content comparision failed files:'); 149 for (const failedFile of contentComparisionFailureFiles) { 150 console.log(failedFile); 151 } 152}