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