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 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 16import { expect } from 'chai'; 17import path from 'path'; 18import fs from 'fs'; 19import { FileUtils } from '../../src/utils/FileUtils'; 20import { FilesMap, Parser } from '../../src/coreImpl/parser/parser'; 21import { StringConstant } from '../../src/utils/Constant'; 22import { DiffHelper } from '../../src/coreImpl/diff/diff'; 23import { BasicDiffInfo } from '../../src/typedef/diff/ApiInfoDiff'; 24import { ApiStatisticsHelper } from '../../src/coreImpl/statistics/Statistics'; 25import { ApiStatisticsInfo } from '../../src/typedef/statistics/ApiStatistics'; 26import { Check } from '../../src/coreImpl/checker/src/api_check_plugin'; 27import { apiCheckResult, cleanApiCheckResult, compositiveResult } from '../../src/utils/checkUtils'; 28import { LocalEntry } from '../../src/coreImpl/checker/local_entry'; 29import { ApiChangeCheck } from '../../src/coreImpl/checker/src/check_api_diff'; 30import { ApiResultMessage, checkEntryType } from '../../src/typedef/checker/result_type'; 31const utDir: string = 'test/ut'; 32const outputDir: string = 'test/output'; 33const expectDir: string = 'test/expect'; 34 35describe('testParserEachSince', function () { 36 before(() => { Parser.cleanParserParamSDK(); }); 37 const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'parserSince'); 38 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'parserSince'); 39 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'parserSince'); 40 const testFileNames: string[] = fs.readdirSync(testFileDir); 41 testFileNames.forEach((testFileName: string) => { 42 const baseName: string = path 43 .basename(testFileName) 44 .replace(/.d.ts/g, '') 45 .replace(/.d.ets/g, ''); 46 const testFilePath: string = path.join(testFileDir, testFileName); 47 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 48 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 49 it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 50 if (fs.existsSync(outputFilePath)) { 51 fs.rmdirSync(outputFilePath, { recursive: true }); 52 } 53 if (!fs.existsSync(outputFileDir)) { 54 fs.mkdirSync(outputFileDir); 55 } 56 const outputContent: string = Parser.getParseEachSince(Parser.parseFile(testFileDir, testFilePath)); 57 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 58 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 59 expect(outputContent).eql(expectFileContent); 60 }); 61 }); 62}); 63 64describe('testParser', function () { 65 before(() => { Parser.cleanParserParamSDK(); }); 66 const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'parser'); 67 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'parser'); 68 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'parser'); 69 const testFileNames: string[] = fs.readdirSync(testFileDir); 70 testFileNames.forEach((testFileName: string) => { 71 const baseName: string = path 72 .basename(testFileName) 73 .replace(/.d.ts/g, '') 74 .replace(/.d.ets/g, ''); 75 const testFilePath: string = path.join(testFileDir, testFileName); 76 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 77 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 78 it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 79 if (fs.existsSync(outputFilePath)) { 80 fs.rmdirSync(outputFilePath, { recursive: true }); 81 } 82 if (!fs.existsSync(outputFileDir)) { 83 fs.mkdirSync(outputFileDir); 84 } 85 const outputContent: string = Parser.getParseResults(Parser.parseFile(testFileDir, testFilePath)); 86 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 87 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 88 expect(outputContent).eql(expectFileContent); 89 }); 90 }); 91}); 92 93describe('testApiDiff', function () { 94 before(() => { Parser.cleanParserParamSDK(); }); 95 const testOldFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiDiff/old'); 96 const testNewFileDir: string = testOldFileDir.replace('old', 'new'); 97 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiDiff'); 98 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiDiff'); 99 const testOldFileNames: string[] = fs.readdirSync(testOldFileDir); 100 testOldFileNames.forEach((testOldFileName: string) => { 101 const baseName: string = path 102 .basename(testOldFileName) 103 .replace(/.d.ts/g, '') 104 .replace(/.d.ets/g, ''); 105 const testOldFilePath: string = path.join(testOldFileDir, testOldFileName); 106 const testNewFilePath: string = testOldFilePath.replace('old', 'new'); 107 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 108 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 109 it('\ntestFile#' + testOldFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 110 if (fs.existsSync(outputFilePath)) { 111 fs.rmdirSync(outputFilePath, { recursive: true }); 112 } 113 if (!fs.existsSync(outputFileDir)) { 114 fs.mkdirSync(outputFileDir); 115 } 116 Parser.cleanParserParamSDK(); 117 const oldSDKApiMap: FilesMap = Parser.parseFile(testOldFileDir, testOldFilePath); 118 Parser.cleanParserParamSDK(); 119 const newSDKApiMap: FilesMap = Parser.parseFile(testNewFileDir, testNewFilePath); 120 const diffInfos: BasicDiffInfo[] = DiffHelper.diffSDK(oldSDKApiMap, newSDKApiMap, true); 121 const outputContent: string = JSON.stringify(diffInfos, null, 2); 122 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 123 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 124 expect(outputContent).eql(expectFileContent); 125 }); 126 }); 127}); 128 129describe('testStatistics', function () { 130 before(() => { Parser.cleanParserParamSDK(); }); 131 const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiStatistics'); 132 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiStatistics'); 133 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiStatistics'); 134 const testFileNames: string[] = fs.readdirSync(testFileDir); 135 testFileNames.forEach((testFileName: string) => { 136 const baseName: string = path 137 .basename(testFileName) 138 .replace(/.d.ts/g, '') 139 .replace(/.d.ets/g, ''); 140 const testFilePath: string = path.join(testFileDir, testFileName); 141 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 142 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 143 it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 144 if (!fs.existsSync(outputFileDir)) { 145 fs.mkdirSync(outputFileDir); 146 } 147 const apiInfos: ApiStatisticsInfo[] = ApiStatisticsHelper.getApiStatisticsInfos( 148 Parser.parseFile(testFileDir, testFilePath) 149 ).apiStatisticsInfos; 150 const outputContent: string = JSON.stringify(apiInfos, null, 2); 151 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 152 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 153 expect(outputContent).eql(expectFileContent); 154 }); 155 }); 156}); 157 158describe('testApiCheck', function () { 159 before(() => { Parser.cleanParserParamSDK(); }); 160 const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiCheck'); 161 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiCheck'); 162 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiCheck'); 163 const testFileNames: string[] = fs.readdirSync(testFileDir); 164 testFileNames.forEach((testFileName: string) => { 165 const baseName: string = path 166 .basename(testFileName) 167 .replace(/.d.ts/g, '') 168 .replace(/.d.ets/g, ''); 169 const testFilePath: string = path.join(testFileDir, testFileName); 170 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 171 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 172 it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 173 if (!fs.existsSync(outputFileDir)) { 174 fs.mkdirSync(outputFileDir); 175 } 176 Check.scanEntry([testFilePath], ''); 177 let ruleName: string = testFileName.substring(0, testFileName.indexOf('.')); 178 ruleName = testFileName.indexOf('API_DEFINE_ANONYMOUS_FUNCTION') !== -1 ? 179 'API_DEFINE_ANONYMOUS_FUNCTION_01' : ruleName; 180 ruleName = testFileName.indexOf('API_DEFINE_HUMP_01_small') !== -1 ? 181 'API_DEFINE_HUMP_01' : ruleName; 182 ruleName = testFileName.indexOf('API_DEFINE_HUMP_02_LARGE') !== -1 ? 183 'API_DEFINE_HUMP_02' : ruleName; 184 ruleName = testFileName.indexOf('API_DEFINE_NAME_02_ability') !== -1 ? 185 'API_DEFINE_NAME_02' : ruleName; 186 187 LocalEntry.maskAlarm(compositiveResult, [ruleName]); 188 apiCheckResult.forEach((result: ApiResultMessage) => { 189 result.buggyFilePath = result.buggyFilePath.substring(result.buggyFilePath.indexOf('build-tools'), result.buggyFilePath.length); 190 }); 191 const outputContent: string = JSON.stringify(apiCheckResult, null, 2); 192 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 193 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 194 expect(outputContent).eql(expectFileContent); 195 }); 196 }); 197}); 198 199describe('testApiChangeCheck', function () { 200 before(() => { Parser.cleanParserParamSDK(); }); 201 const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiChange'); 202 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiChange'); 203 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiChange'); 204 const testOldFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiChange/old'); 205 const testOldFileNames: string[] = fs.readdirSync(testOldFileDir); 206 207 ApiChangeCheck.checkApiChange(testFileDir); 208 testOldFileNames.forEach((testOldFileName: string) => { 209 const baseName: string = path 210 .basename(testOldFileName) 211 .replace(/.d.ts/g, '') 212 .replace(/.d.ets/g, ''); 213 const testOldFilePath: string = path.join(testOldFileDir, testOldFileName); 214 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 215 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 216 it('\ntestFile#' + testOldFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 217 if (!fs.existsSync(outputFileDir)) { 218 fs.mkdirSync(outputFileDir); 219 } 220 cleanApiCheckResult(); 221 LocalEntry.maskAlarm(compositiveResult, [baseName]); 222 const keyString: string[] = []; 223 const finalResult: ApiResultMessage[] = []; 224 apiCheckResult.forEach(apiCheck => { 225 const key: string = apiCheck.description + apiCheck.mainBuggyCode + apiCheck.extendInfo.hierarchicalRelations; 226 if (!keyString.includes(key)) { 227 keyString.push(key); 228 finalResult.push(apiCheck); 229 } 230 }); 231 const outputContent: string = JSON.stringify(finalResult, null, 2); 232 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 233 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 234 expect(outputContent).eql(expectFileContent); 235 }); 236 }); 237 238 describe('testApiCheckIncrement', function testApiCheckIncrement() { 239 const testFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/ut/apiIncrement'); 240 const outputFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/output/apiIncrement'); 241 const expectFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/expect/apiIncrement'); 242 const testFileNames: string[] = fs.readdirSync(testFileDir); 243 244 testFileNames.forEach((testFileName: string) => { 245 const testFilePath: string = path.join(testFileDir, testFileName); 246 const testOldFileDir: string = path.join(testFilePath, '/old'); 247 const testNewFileDir: string = path.join(testFilePath, '/new'); 248 const baseName: string = path 249 .basename(testFileName) 250 .replace(/.d.ts/g, '') 251 .replace(/.d.ets/g, ''); 252 const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); 253 const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); 254 it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { 255 if (!fs.existsSync(outputFileDir)) { 256 fs.mkdirSync(outputFileDir); 257 } 258 cleanApiCheckResult(); 259 const files: Array<string> = FileUtils.readFilesInDir(testNewFileDir); 260 const checkParam: checkEntryType = { 261 filePathArr: files, 262 fileRuleArr: ['all'], 263 output: './result.json', 264 prId: testFilePath, 265 isOutExcel: 'true', 266 isIncrement: true, 267 }; 268 LocalEntry.checkEntryLocal(checkParam); 269 const outputContent: string = JSON.stringify(apiCheckResult, null, 2); 270 fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); 271 const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); 272 expect(outputContent).eql(expectFileContent); 273 }); 274 }); 275 }); 276 277