/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { expect } from 'chai'; import path from 'path'; import fs from 'fs'; import { FileUtils } from '../../src/utils/FileUtils'; import { FilesMap, Parser } from '../../src/coreImpl/parser/parser'; import { StringConstant } from '../../src/utils/Constant'; import { DiffHelper } from '../../src/coreImpl/diff/diff'; import { BasicDiffInfo } from '../../src/typedef/diff/ApiInfoDiff'; import { ApiStatisticsHelper } from '../../src/coreImpl/statistics/Statistics'; import { ApiStatisticsInfo } from '../../src/typedef/statistics/ApiStatistics'; import { Check } from '../../src/coreImpl/checker/src/api_check_plugin'; import { apiCheckResult, cleanApiCheckResult, compositiveResult } from '../../src/utils/checkUtils'; import { LocalEntry } from '../../src/coreImpl/checker/local_entry'; import { ApiChangeCheck } from '../../src/coreImpl/checker/src/check_api_diff'; import { ApiResultMessage, checkEntryType } from '../../src/typedef/checker/result_type'; const utDir: string = 'test/ut'; const outputDir: string = 'test/output'; const expectDir: string = 'test/expect'; describe('testParserEachSince', function () { before(() => { Parser.cleanParserParamSDK(); }); const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'parserSince'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'parserSince'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'parserSince'); const testFileNames: string[] = fs.readdirSync(testFileDir); testFileNames.forEach((testFileName: string) => { const baseName: string = path .basename(testFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testFilePath: string = path.join(testFileDir, testFileName); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (fs.existsSync(outputFilePath)) { fs.rmdirSync(outputFilePath, { recursive: true }); } if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } const outputContent: string = Parser.getParseEachSince(Parser.parseFile(testFileDir, testFilePath)); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); }); describe('testParser', function () { before(() => { Parser.cleanParserParamSDK(); }); const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'parser'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'parser'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'parser'); const testFileNames: string[] = fs.readdirSync(testFileDir); testFileNames.forEach((testFileName: string) => { const baseName: string = path .basename(testFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testFilePath: string = path.join(testFileDir, testFileName); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (fs.existsSync(outputFilePath)) { fs.rmdirSync(outputFilePath, { recursive: true }); } if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } const outputContent: string = Parser.getParseResults(Parser.parseFile(testFileDir, testFilePath)); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); }); describe('testApiDiff', function () { before(() => { Parser.cleanParserParamSDK(); }); const testOldFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiDiff/old'); const testNewFileDir: string = testOldFileDir.replace('old', 'new'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiDiff'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiDiff'); const testOldFileNames: string[] = fs.readdirSync(testOldFileDir); testOldFileNames.forEach((testOldFileName: string) => { const baseName: string = path .basename(testOldFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testOldFilePath: string = path.join(testOldFileDir, testOldFileName); const testNewFilePath: string = testOldFilePath.replace('old', 'new'); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testOldFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (fs.existsSync(outputFilePath)) { fs.rmdirSync(outputFilePath, { recursive: true }); } if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } Parser.cleanParserParamSDK(); const oldSDKApiMap: FilesMap = Parser.parseFile(testOldFileDir, testOldFilePath); Parser.cleanParserParamSDK(); const newSDKApiMap: FilesMap = Parser.parseFile(testNewFileDir, testNewFilePath); const diffInfos: BasicDiffInfo[] = DiffHelper.diffSDK(oldSDKApiMap, newSDKApiMap, true); const outputContent: string = JSON.stringify(diffInfos, null, 2); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); }); describe('testStatistics', function () { before(() => { Parser.cleanParserParamSDK(); }); const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiStatistics'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiStatistics'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiStatistics'); const testFileNames: string[] = fs.readdirSync(testFileDir); testFileNames.forEach((testFileName: string) => { const baseName: string = path .basename(testFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testFilePath: string = path.join(testFileDir, testFileName); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } const apiInfos: ApiStatisticsInfo[] = ApiStatisticsHelper.getApiStatisticsInfos( Parser.parseFile(testFileDir, testFilePath) ).apiStatisticsInfos; const outputContent: string = JSON.stringify(apiInfos, null, 2); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); }); describe('testApiCheck', function () { before(() => { Parser.cleanParserParamSDK(); }); const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiCheck'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiCheck'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiCheck'); const testFileNames: string[] = fs.readdirSync(testFileDir); testFileNames.forEach((testFileName: string) => { const baseName: string = path .basename(testFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testFilePath: string = path.join(testFileDir, testFileName); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } Check.scanEntry([testFilePath], ''); let ruleName: string = testFileName.substring(0, testFileName.indexOf('.')); ruleName = testFileName.indexOf('API_DEFINE_ANONYMOUS_FUNCTION') !== -1 ? 'API_DEFINE_ANONYMOUS_FUNCTION_01' : ruleName; ruleName = testFileName.indexOf('API_DEFINE_HUMP_01_small') !== -1 ? 'API_DEFINE_HUMP_01' : ruleName; ruleName = testFileName.indexOf('API_DEFINE_HUMP_02_LARGE') !== -1 ? 'API_DEFINE_HUMP_02' : ruleName; ruleName = testFileName.indexOf('API_DEFINE_NAME_02_ability') !== -1 ? 'API_DEFINE_NAME_02' : ruleName; LocalEntry.maskAlarm(compositiveResult, [ruleName]); apiCheckResult.forEach((result: ApiResultMessage) => { result.buggyFilePath = result.buggyFilePath.substring(result.buggyFilePath.indexOf('build-tools'), result.buggyFilePath.length); }); const outputContent: string = JSON.stringify(apiCheckResult, null, 2); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); }); describe('testApiChangeCheck', function () { before(() => { Parser.cleanParserParamSDK(); }); const testFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiChange'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), outputDir, 'apiChange'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), expectDir, 'apiChange'); const testOldFileDir: string = path.join(FileUtils.getBaseDirName(), utDir, 'apiChange/old'); const testOldFileNames: string[] = fs.readdirSync(testOldFileDir); ApiChangeCheck.checkApiChange(testFileDir); testOldFileNames.forEach((testOldFileName: string) => { const baseName: string = path .basename(testOldFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const testOldFilePath: string = path.join(testOldFileDir, testOldFileName); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testOldFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } cleanApiCheckResult(); LocalEntry.maskAlarm(compositiveResult, [baseName]); const keyString: string[] = []; const finalResult: ApiResultMessage[] = []; apiCheckResult.forEach(apiCheck => { const key: string = apiCheck.description + apiCheck.mainBuggyCode + apiCheck.extendInfo.hierarchicalRelations; if (!keyString.includes(key)) { keyString.push(key); finalResult.push(apiCheck); } }); const outputContent: string = JSON.stringify(finalResult, null, 2); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); describe('testApiCheckIncrement', function testApiCheckIncrement() { const testFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/ut/apiIncrement'); const outputFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/output/apiIncrement'); const expectFileDir: string = path.join(FileUtils.getBaseDirName(), '/test/expect/apiIncrement'); const testFileNames: string[] = fs.readdirSync(testFileDir); testFileNames.forEach((testFileName: string) => { const testFilePath: string = path.join(testFileDir, testFileName); const testOldFileDir: string = path.join(testFilePath, '/old'); const testNewFileDir: string = path.join(testFilePath, '/new'); const baseName: string = path .basename(testFileName) .replace(/.d.ts/g, '') .replace(/.d.ets/g, ''); const outputFilePath: string = path.join(outputFileDir, `${baseName}.json`); const expectFilePath: string = path.join(expectFileDir, `${baseName}.json`); it('\ntestFile#' + testFilePath + '\noutput:' + outputFilePath + '\nexpect:' + expectFilePath, function () { if (!fs.existsSync(outputFileDir)) { fs.mkdirSync(outputFileDir); } cleanApiCheckResult(); const files: Array = FileUtils.readFilesInDir(testNewFileDir); const checkParam: checkEntryType = { filePathArr: files, fileRuleArr: ['all'], output: './result.json', prId: testFilePath, isOutExcel: 'true', isIncrement: true, }; LocalEntry.checkEntryLocal(checkParam); const outputContent: string = JSON.stringify(apiCheckResult, null, 2); fs.writeFileSync(outputFilePath, outputContent, StringConstant.UTF8); const expectFileContent: string = fs.readFileSync(expectFilePath, 'utf-8').replace(/\r\n/g, '\n'); expect(outputContent).eql(expectFileContent); }); }); });