From e26f56dbf90b827c3ec88ca3b84097bc6d7eabb5 Mon Sep 17 00:00:00 2001 From: liujia178 Date: Tue, 16 Sep 2025 09:43:11 +0800 Subject: [PATCH] add toochain mock function Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICWWAA Signed-off-by: liujia178 --- .../generate_mockconfig.test.ts | 803 ++++++++++++++++++ 1 file changed, 803 insertions(+) create mode 100644 ets2panda/driver/build_system/test/ut/generate_mockconfigTest/generate_mockconfig.test.ts diff --git a/ets2panda/driver/build_system/test/ut/generate_mockconfigTest/generate_mockconfig.test.ts b/ets2panda/driver/build_system/test/ut/generate_mockconfigTest/generate_mockconfig.test.ts new file mode 100644 index 0000000000..311ae75450 --- /dev/null +++ b/ets2panda/driver/build_system/test/ut/generate_mockconfigTest/generate_mockconfig.test.ts @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2025 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 { MockConfigGenerator } from '../../../src/build/generate_mockconfig'; +import { ArkTSConfigGenerator } from '../../../src/build/generate_arktsconfig'; +import { Logger } from '../../../src/logger'; +import { BUILD_MODE } from '../../../src/types'; +import path from 'path'; + +const mockConfigPath = path.resolve(__dirname, 'mock-config.json5'); +const buildConfig = { + mockParams: { + mockConfigPath, + }, + projectRootPath: __dirname, + aceModuleJsonPath: __dirname, + cachePath: path.resolve(__dirname, 'cache'), + compileFiles: [path.resolve(__dirname, 'test.ets')], + projectConfig: { + getHvigorConsoleLogger: () => ({ + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + log: jest.fn() + }) + }, + pandaSdkPath: '/mock/sdk', + buildSdkPath: '/mock/sdk', + buildMode: BUILD_MODE.DEBUG, + interopSDKPaths: [] +}; + +const mockModuleInfos = new Map(); + +jest.mock('fs'); +jest.mock('path'); +jest.mock('json5', () => ({ + parse: jest.fn().mockReturnValue({ + 'moduleA': { source: 'mockA.ets' } + }) +})); +jest.mock('os', () => ({ + platform: jest.fn() +})); + +const fs = require('fs'); + +fs.readdirSync = jest.fn().mockReturnValue([]); +fs.statSync = jest.fn().mockReturnValue({ isDirectory: () => false }); + +const mockExit = jest.fn(); +process.exit = mockExit as any; + +describe('MockConfigGenerator', () => { + let mockConfigGenerate: MockConfigGenerator; + + beforeEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + Logger.getInstance(buildConfig as any); + ArkTSConfigGenerator.getInstance(buildConfig as any, mockModuleInfos); + mockConfigGenerate = MockConfigGenerator.getInstance(buildConfig as any); + }); + + afterEach(() => { + MockConfigGenerator.destroyInstance(); + ArkTSConfigGenerator.destroyInstance(); + Logger.destroyInstance(); + }); + + test('test collectMockConfigInfo_invalid_first_line', () => { + test_collectMockConfigInfo_invalid_first_line(mockConfigGenerate); + }); + + test('test collectMockConfigInfo_with_nonexistent_source', () => { + test_collectMockConfigInfo_with_nonexistent_source(mockConfigGenerate); + }); + + test('test collectMockConfigInfo_valid_use_static_coverage', () => { + test_collectMockConfigInfo_valid_use_static_coverage(mockConfigGenerate); + }); + + test('test generateSimpleMockInfo', () => { + test_generateSimpleMockInfo(mockConfigGenerate); + }); + + test('test generateSimpleMockInfo_no_mockRules', () => { + test_generateSimpleMockInfo_no_mockRules(mockConfigGenerate); + }); + + test('test generateSimpleMockInfo_no_mockFileFullPath', () => { + test_generateSimpleMockInfo_no_mockFileFullPath(mockConfigGenerate); + }); + + test('test generateSimpleMockInfo_with_throw_err', () => { + test_generateSimpleMockInfo_with_throw_err(mockConfigGenerate); + }); + + test('test generateSimpleMockInfo_with_isOriginMocked', () => { + test_generateSimpleMockInfo_with_isOriginMocked(mockConfigGenerate); + }); + + test('test generateMockConfigFile_cache_not_exist', () => { + test_generateMockConfigFile_cache_not_exist(mockConfigGenerate); + }); + + test('test generateMockConfigFile_config_changed', () => { + test_generateMockConfigFile_config_changed(mockConfigGenerate); + }); + + test('test resolveAndVerifyPath_file_no_ext', () => { + test_resolveAndVerifyPath_file_no_ext(mockConfigGenerate); + }); + + test('test removePotentialMockConfigCache', () => { + test_removePotentialMockConfigCache(mockConfigGenerate); + }); + + test('test removePotentialMockConfigCache_both_files_not_exist', () => { + test_removePotentialMockConfigCache_both_files_not_exist(mockConfigGenerate); + }); + + test('test convertFullPathToOhmUrl', () => { + test_convertFullPathToOhmUrl(mockConfigGenerate); + }); + + test('test convertFullPathToOhmUrl_not_ets_file', () => { + test_convertFullPathToOhmUrl_not_ets_file(mockConfigGenerate); + }); + + test('test toUnixPath_on_Windows', () => { + test_toUnixPath_on_Windows(mockConfigGenerate); + }); + + test('test toUnixPath_on_non-Windows', () => { + test_toUnixPath_on_non_Windows(mockConfigGenerate); + }); + + test('test findUsageContext_normal_import', () => { + test_findUsageContext_normal_import(mockConfigGenerate); + }); + + test('test findUsageContext_kitMappingMatch_branch', () => { + test_findUsageContext_kitMappingMatch_branch(mockConfigGenerate); + }); + + test('test findUsageContext_external_module_branch', () => { + test_findUsageContext_external_module_branch(mockConfigGenerate); + }); + + test('test findUsageContext_no_match_found', () => { + test_findUsageContext_no_match_found(mockConfigGenerate); + }); + + test('test kitMappingMatch_missing_deps', () => { + test_kitMappingMatch_missing_deps(mockConfigGenerate); + }); + + test('test kitMappingMatch_no_content', () => { + test_kitMappingMatch_no_content(mockConfigGenerate); + }); + + test('test kitMappingMatch_no_match', () => { + test_kitMappingMatch_no_match(mockConfigGenerate); + }); + + test('test tryGenerateOriginMock_imported_and_used', () => { + test_tryGenerateOriginMock_imported_and_used(mockConfigGenerate); + }); + + test('test tryGenerateOriginMock_kitMappingMatch', () => { + test_tryGenerateOriginMock_kitMappingMatch(mockConfigGenerate); + }); + + test('test tryGenerateOriginMock_local_file_match', () => { + test_tryGenerateOriginMock_local_file_match(mockConfigGenerate); + }); + + test('test isExternalOrSystemModule_system_prefix', () => { + test_isExternalOrSystemModule_system_prefix(mockConfigGenerate); + }); + + test('test isExternalOrSystemModule_so_file', () => { + test_isExternalOrSystemModule_so_file(mockConfigGenerate); + }); + + test('test isExternalOrSystemModule_external_pkg_map', () => { + test_isExternalOrSystemModule_external_pkg_map(mockConfigGenerate); + }); + + test('test isExternalOrSystemModule_normal_module', () => { + test_isExternalOrSystemModule_normal_module(mockConfigGenerate); + }); + + test('test getSystemLibraryContent_no_system_path_section', () => { + test_getSystemLibraryContent_no_system_path_section(mockConfigGenerate); + }); + + test('test getSystemLibraryContent_found_ets_file', () => { + test_getSystemLibraryContent_found_ets_file(mockConfigGenerate); + }); + + test('test getSystemLibraryContent_found_ts_file', () => { + test_getSystemLibraryContent_found_ts_file(mockConfigGenerate); + }); + + test('test getSystemLibraryContent_no_files_found', () => { + test_getSystemLibraryContent_no_files_found(mockConfigGenerate); + }); + + test('test parseImportBindings_namespace_import', () => { + test_parseImportBindings_namespace_import(mockConfigGenerate); + }); + +}); + +function test_collectMockConfigInfo_with_nonexistent_source(mockConfigGenerate: MockConfigGenerator) { + (fs.readFileSync as any).mockReturnValue('{ "modA": { "source": "notExist.ets" } }'); + + const json5 = require('json5'); + (json5.parse as any).mockReturnValue({ + modA: { source: 'notExist.ets' } + }); + + const mockResolveAndVerifyPath = jest.spyOn(mockConfigGenerate as any, 'resolveAndVerifyPath'); + mockResolveAndVerifyPath.mockReturnValue(null); + + mockConfigGenerate.collectMockConfigInfo(); + + expect(mockConfigGenerate['mockRules'].size).toBe(0); + expect(mockConfigGenerate['mockRules'].has('modA')).toBe(false); +} + +function test_generateSimpleMockInfo(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['mockRules'].set('../mockModule', '/fake/path/mockModule.ets'); + (fs.existsSync as any).mockReturnValue(true); + + const mockUsageContext = jest.spyOn(mockConfigGenerate as any, 'findUsageContext'); + mockUsageContext.mockReturnValue({ + newKey: 'ohm://someModule' + }); + const mockConvertFullPathToOhmUrl = jest.spyOn(mockConfigGenerate as any, 'convertFullPathToOhmUrl'); + mockConvertFullPathToOhmUrl.mockImplementation((...args: any[]) => { + const fullPath = args[0] as string; + return fullPath.replace('.ets', '').replace('/fake/path/', ''); + }); + + mockConfigGenerate.generateSimpleMockInfo(); + expect(mockConfigGenerate['newMockConfigInfo']).toEqual({ + "ohm://someModule": { source: 'mockModule' } + }); + expect(fs.readFileSync).toHaveBeenCalled(); + expect(mockConvertFullPathToOhmUrl).toHaveBeenCalledTimes(1); +} + +function test_generateSimpleMockInfo_no_mockRules(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate.generateSimpleMockInfo(); + expect(fs.readFileSync).not.toHaveBeenCalled(); +} + +function test_generateSimpleMockInfo_no_mockFileFullPath(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['mockRules'].set('../mockModule', '/fake/path/mockModule.ets'); + (fs.existsSync as any).mockReturnValue(false); + mockConfigGenerate.generateSimpleMockInfo(); + expect(mockConfigGenerate['newMockConfigInfo']).toEqual({}); +} + +function test_generateSimpleMockInfo_with_throw_err(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['mockRules'].set('../mockModule', '/fake/path/mockModule.ets'); + (fs.existsSync as jest.Mock).mockReturnValue(true); + + const mockFindUsageContext = jest.spyOn(mockConfigGenerate as any, 'findUsageContext'); + mockFindUsageContext.mockReturnValue(null); + + const mockPrintError = jest.fn(); + (MockConfigGenerator as any).logger = { printError: mockPrintError }; + + mockConfigGenerate.generateSimpleMockInfo(); + + expect(mockPrintError).toHaveBeenCalledTimes(1); + expect(mockPrintError).toHaveBeenCalledWith( + expect.objectContaining({ + cause: expect.stringContaining( + 'Failed to convert the key in mock-config to ohmurl, ' + + 'because the key "../mockModule" is not used in the project or no valid path was found.' + ) + }) + ); +} + +function test_generateSimpleMockInfo_with_isOriginMocked(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['mockRules'].set('../mockModule', '/fake/path/mockModule.ets'); + (fs.existsSync as jest.Mock).mockReturnValue(true); + + const mockFindUsageContext = jest.spyOn(mockConfigGenerate as any, 'findUsageContext'); + mockFindUsageContext.mockReturnValue({ + newKey: 'ohm://someModule' + }); + const mockConvertFullPathToOhmUrl = jest.spyOn(mockConfigGenerate as any, 'convertFullPathToOhmUrl'); + mockConvertFullPathToOhmUrl.mockImplementation((...args: any[]) => { + const fullPath = args[0] as string; + return fullPath.replace('.ets', '').replace('/fake/path/', ''); + }); + const mockTryGenerateOriginMock = jest.spyOn(mockConfigGenerate as any, 'tryGenerateOriginMock'); + mockTryGenerateOriginMock.mockReturnValue(true); + + mockConfigGenerate.generateSimpleMockInfo(); + expect(mockTryGenerateOriginMock).toHaveBeenCalled(); + expect(mockConfigGenerate['newMockConfigInfo']).toEqual({}); +} + +function test_generateMockConfigFile_cache_not_exist(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['newMockConfigInfo'] = { 'test': { source: 'mock' } }; + + (fs.writeFileSync as any).mockImplementation(() => {}); + (fs.copyFileSync as any).mockImplementation(() => {}); + (fs.existsSync as any).mockReturnValue(false); + (fs.readFileSync as any).mockReturnValue('{}'); + + mockConfigGenerate.generateMockConfigFile(); + + expect(fs.copyFileSync).toHaveBeenCalledTimes(2); + expect(fs.readFileSync).not.toHaveBeenCalled(); +} + +function test_generateMockConfigFile_config_changed(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['mockConfigInfo'] = { 'new': { source: 'newMock' } }; + mockConfigGenerate['newMockConfigInfo'] = { 'test': { source: 'mock' } }; + + (fs.writeFileSync as any).mockImplementation(() => {}); + (fs.copyFileSync as any).mockImplementation(() => {}); + (fs.existsSync as any).mockReturnValue(true); + (fs.readFileSync as any).mockReturnValue('{"old": {"source": "oldMock"}}'); + + const json5 = require('json5'); + (json5.parse as any).mockReturnValue({ 'old': { source: 'oldMock' } }); + + mockConfigGenerate.generateMockConfigFile(); + + expect(fs.copyFileSync).toHaveBeenCalledTimes(2); + expect(json5.parse).toHaveBeenCalledWith('{"old": {"source": "oldMock"}}'); +} + +function test_resolveAndVerifyPath_file_no_ext(mockConfigGenerate: MockConfigGenerator) { + (fs.existsSync as any) + .mockReturnValueOnce(false) + .mockReturnValueOnce(true); + const mockToUnixPath = jest.spyOn(mockConfigGenerate as any, 'toUnixPath'); + mockToUnixPath.mockReturnValue('/fake/path/file'); + + const result = mockConfigGenerate['resolveAndVerifyPath']('/fake/path', 'file'); + + expect(result).toBe('/fake/path/file.ets'); +} + +function test_removePotentialMockConfigCache(mockConfigGenerate: MockConfigGenerator) { + (fs.existsSync as any).mockReturnValue(true); + mockConfigGenerate.removePotentialMockConfigCache(); + expect(fs.rmSync).toHaveBeenCalledTimes(2); +} + +function test_removePotentialMockConfigCache_both_files_not_exist(mockConfigGenerate: MockConfigGenerator) { + (fs.existsSync as any).mockReturnValue(false); + mockConfigGenerate.removePotentialMockConfigCache(); + expect(fs.rmSync).not.toHaveBeenCalled(); +} + +function test_convertFullPathToOhmUrl(mockConfigGenerate: MockConfigGenerator) { + const mockToUnixPath = jest.spyOn(mockConfigGenerate as any, 'toUnixPath'); + mockToUnixPath.mockReturnValue('relative/path/file.ets'); + const result = mockConfigGenerate['convertFullPathToOhmUrl']('/project/root/relative/path/file.ets'); + expect(result).toBe('relative/path/file'); +} + +function test_convertFullPathToOhmUrl_not_ets_file(mockConfigGenerate: MockConfigGenerator) { + const mockToUnixPath = jest.spyOn(mockConfigGenerate as any, 'toUnixPath'); + mockToUnixPath.mockReturnValue('relative/path/file'); + const result = mockConfigGenerate['convertFullPathToOhmUrl']('/project/root/relative/path/file.ets'); + expect(result).toBe('relative/path/file'); +} + +function test_toUnixPath_on_Windows(mockConfigGenerate: MockConfigGenerator) { + const os = require('os'); + (os.platform as any).mockReturnValue('win32'); + (path.sep as any) = '\\'; + (path.posix.join as any) = jest.fn().mockReturnValue('C/Users/Admin/file.txt'); + const input = "C:\\Users\\Admin\\file.txt"; + const result = mockConfigGenerate['toUnixPath'](input); + expect(os.platform()).toBe('win32'); + expect(result).toBe('C/Users/Admin/file.txt'); + expect(path.posix.join).toHaveBeenCalledWith('C:', 'Users', 'Admin', 'file.txt'); +} + +function test_toUnixPath_on_non_Windows(mockConfigGenerate: MockConfigGenerator) { + const os = require('os'); + (os.platform as any).mockReturnValue('linux'); + const input = "test"; + const result = mockConfigGenerate['toUnixPath'](input); + expect(os.platform()).toBe('linux'); + expect(result).toBe(input); +} + +function test_findUsageContext_normal_import(mockConfigGenerate: MockConfigGenerator) { + const fileContent = ` +import MyModule from '../mockModule'; +const instance = new MyModule(); + `; + (fs.readFileSync as jest.Mock).mockReturnValue(fileContent); + + const mockResolveAndVerifyPath = jest.spyOn(mockConfigGenerate as any, 'resolveAndVerifyPath'); + mockResolveAndVerifyPath.mockReturnValue('/fake/path/mockModule.ets'); + + const mockConvertFullPathToOhmUrl = jest.spyOn(mockConfigGenerate as any, 'convertFullPathToOhmUrl'); + mockConvertFullPathToOhmUrl.mockReturnValue('mockModule'); + + const result = mockConfigGenerate['findUsageContext']('../mockModule', ['/fake/source/file.ets']); + + expect(result).toEqual({ newKey: 'mockModule', resolvedKeyPath: '/fake/path/mockModule.ets' }); + expect(mockResolveAndVerifyPath).toHaveBeenCalledWith(undefined, '../mockModule'); + expect(mockConvertFullPathToOhmUrl).toHaveBeenCalledWith('/fake/path/mockModule.ets'); +} + +function test_kitMappingMatch_missing_deps(mockConfigGenerate: MockConfigGenerator) { + const result = mockConfigGenerate['kitMappingMatch']('@kit.PerformanceAnalysisKit', '@kit.DifferentKit'); + + expect(result).toBe(false); +} + +function test_tryGenerateOriginMock_imported_and_used(mockConfigGenerate: MockConfigGenerator) { + const mockFileContent = ` +import hilog from '@kit.PerformanceAnalysisKit'; +export class MyMock { + log() { + hilog.info('mock log message'); + } +} + `; + (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); + + const mockIsThirdPartyKey = jest.spyOn(mockConfigGenerate as any, 'isExternalOrSystemModule'); + mockIsThirdPartyKey.mockReturnValue(true); + + const newConfig = {}; + + const result = mockConfigGenerate['tryGenerateOriginMock']( + '@kit.PerformanceAnalysisKit', + '/fake/path/mock.ets', + 'mockSource', + newConfig, + 'newKey' + ); + + expect(result).toBe(true); + expect(newConfig).toEqual({ + 'newKey': { source: 'mockSource' }, + 'newKey.origin': { source: 'newKey' } + }); +} + +function test_tryGenerateOriginMock_kitMappingMatch(mockConfigGenerate: MockConfigGenerator) { + const mockFileContent = ` +import { hilog } from '@ohos.PerformanceAnalysisKit'; +export class MyMock { + log() { + hilog.info('mock log message'); + } +} + `; + (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); + + const mockIsThirdPartyKey = jest.spyOn(mockConfigGenerate as any, 'isExternalOrSystemModule'); + mockIsThirdPartyKey.mockReturnValue(true); + + const mockKitMappingMatch = jest.spyOn(mockConfigGenerate as any, 'kitMappingMatch'); + mockKitMappingMatch.mockReturnValue(true); + + const newConfig = {}; + + const result = mockConfigGenerate['tryGenerateOriginMock']( + '@kit.PerformanceAnalysisKit', + '/fake/path/mock.ets', + 'mockSource', + newConfig, + 'newKey' + ); + + expect(result).toBe(true); + expect(newConfig).toEqual({ + 'newKey': { source: 'mockSource' }, + 'newKey.origin': { source: 'newKey' } + }); + expect(mockKitMappingMatch).toHaveBeenCalledWith('@kit.PerformanceAnalysisKit', '@ohos.PerformanceAnalysisKit'); +} + +function test_tryGenerateOriginMock_local_file_match(mockConfigGenerate: MockConfigGenerator) { + const mockFileContent = ` +import { LocalClass } from './localModule'; +export class MyMock { + createLocal() { + return new LocalClass(); + } +} + `; + (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); + + (path.dirname as jest.Mock).mockReturnValue('/fake/path'); + + const mockIsThirdPartyKey = jest.spyOn(mockConfigGenerate as any, 'isExternalOrSystemModule'); + mockIsThirdPartyKey.mockReturnValue(false); + + const mockResolveAndVerifyPath = jest.spyOn(mockConfigGenerate as any, 'resolveAndVerifyPath'); + mockResolveAndVerifyPath.mockReturnValue('/fake/path/localModule.ets'); + + const newConfig = {}; + + const result = mockConfigGenerate['tryGenerateOriginMock']( + '/fake/path/localModule.ets', + '/fake/path/mock.ets', + 'mockSource', + newConfig, + 'newKey' + ); + + expect(result).toBe(true); + expect(newConfig).toEqual({ + 'newKey': { source: 'mockSource' }, + 'newKey.origin': { source: 'newKey' } + }); + expect(mockResolveAndVerifyPath).toHaveBeenCalledWith('/fake/path', './localModule'); +} + +function test_collectMockConfigInfo_invalid_first_line(mockConfigGenerate: MockConfigGenerator) { + const mockConfig = { + 'testKey': { source: 'test/mock.ets' } + }; + + mockConfigGenerate['buildConfig'].userMockConfigPath = '/fake/mock-config.json5'; + + const json5Mock = require('json5'); + json5Mock.parse.mockReturnValue(mockConfig); + + const mockFileContent = `export class TestMock {}\n// invalid first line`; + + (fs.readFileSync as jest.Mock) + .mockReturnValueOnce(JSON.stringify(mockConfig)) + .mockReturnValueOnce(mockFileContent); + + const mockResolveAndVerifyPath = jest.spyOn(mockConfigGenerate as any, 'resolveAndVerifyPath'); + mockResolveAndVerifyPath.mockReturnValue('/fake/path/test/mock.ets'); + + const mockRules = new Map(); + mockConfigGenerate['mockRules'] = mockRules; + + mockConfigGenerate.collectMockConfigInfo(); + + expect(mockExit).toHaveBeenCalledWith(1); +} + +function test_collectMockConfigInfo_valid_use_static_coverage(mockConfigGenerate: MockConfigGenerator) { + const mockConfig = { + 'validKey': { source: 'valid/mock.ets' } + }; + + mockConfigGenerate['buildConfig'].userMockConfigPath = '/fake/mock-config.json5'; + mockConfigGenerate['buildConfig'].projectRootPath = '/fake/project'; + + const json5 = require('json5'); + (json5.parse as any).mockReturnValue(mockConfig); + + const validMockFileContent = `'use static'\nexport class ValidMock {}`; + + (fs.readFileSync as jest.Mock) + .mockReturnValueOnce(JSON.stringify(mockConfig)) + .mockReturnValueOnce(validMockFileContent); + const mockResolveAndVerifyPath = jest.spyOn(mockConfigGenerate as any, 'resolveAndVerifyPath'); + mockResolveAndVerifyPath.mockReturnValue('/fake/project/entry/valid/mock.ets'); + + const mockRules = new Map(); + mockConfigGenerate['mockRules'] = mockRules; + + mockConfigGenerate['mockConfigInfo'] = {}; + + mockConfigGenerate.collectMockConfigInfo(); + + const actualMockRules = mockConfigGenerate['mockRules']; + + expect(actualMockRules.get('validKey')).toBe('/fake/project/entry/valid/mock.ets'); + expect(actualMockRules.size).toBe(1); +} + +function test_isExternalOrSystemModule_system_prefix(mockConfigGenerate: MockConfigGenerator) { + expect(mockConfigGenerate['isExternalOrSystemModule']('@kit.AbilityKit')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('@ohos.hilog')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('@arkts.collections')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('@system.app')).toBe(true); +} + +function test_isExternalOrSystemModule_so_file(mockConfigGenerate: MockConfigGenerator) { + expect(mockConfigGenerate['isExternalOrSystemModule']('libnative.so')).toBe(true); + expect(mockConfigGenerate['isExternalOrSystemModule']('libtest.so')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('normalModule')).toBe(false); + expect(mockConfigGenerate['isExternalOrSystemModule']('file.js')).toBe(false); +} + +function test_isExternalOrSystemModule_external_pkg_map(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['buildConfig'].hspNameOhmMap = { + 'hspPackage': '@ohos/hspPackage' + }; + mockConfigGenerate['buildConfig'].harNameOhmMap = { + 'harPackage': '@ohos/harPackage' + }; + + expect(mockConfigGenerate['isExternalOrSystemModule']('hspPackage')).toBe(true); + expect(mockConfigGenerate['isExternalOrSystemModule']('harPackage')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('hspPackage/submodule')).toBe(true); + expect(mockConfigGenerate['isExternalOrSystemModule']('harPackage/utils')).toBe(true); + + expect(mockConfigGenerate['isExternalOrSystemModule']('unknownPackage')).toBe(false); +} + +function test_isExternalOrSystemModule_normal_module(mockConfigGenerate: MockConfigGenerator) { + mockConfigGenerate['buildConfig'].hspNameOhmMap = {}; + mockConfigGenerate['buildConfig'].harNameOhmMap = {}; + + expect(mockConfigGenerate['isExternalOrSystemModule']('normalModule')).toBe(false); + expect(mockConfigGenerate['isExternalOrSystemModule']('./localFile')).toBe(false); + expect(mockConfigGenerate['isExternalOrSystemModule']('../parentFile')).toBe(false); + expect(mockConfigGenerate['isExternalOrSystemModule']('thirdParty')).toBe(false); + + expect(mockConfigGenerate['isExternalOrSystemModule']('@kit')).toBe(false); + expect(mockConfigGenerate['isExternalOrSystemModule']('@ohos')).toBe(false); +} + +function test_kitMappingMatch_no_content(mockConfigGenerate: MockConfigGenerator) { + const mockGetSystemLibraryContent = jest.spyOn(mockConfigGenerate as any, 'getSystemLibraryContent'); + mockGetSystemLibraryContent.mockReturnValue(null); + + const result = mockConfigGenerate['kitMappingMatch']('@ohos.hilog', '@kit.AbilityKit'); + + expect(result).toBe(false); + expect(mockGetSystemLibraryContent).toHaveBeenCalledWith('@kit.AbilityKit'); +} + +function test_kitMappingMatch_no_match(mockConfigGenerate: MockConfigGenerator) { + const mockGetSystemLibraryContent = jest.spyOn(mockConfigGenerate as any, 'getSystemLibraryContent'); + const kitFileContent = ` +declare module '@kit.AbilityKit' { + import { Context } from '@ohos.app.ability.UIAbility'; + import { router } from '@ohos.router'; + export { Context, router }; +} + `; + mockGetSystemLibraryContent.mockReturnValue(kitFileContent); + + const result = mockConfigGenerate['kitMappingMatch']('@ohos.hilog', '@kit.AbilityKit'); + + expect(result).toBe(false); + expect(mockGetSystemLibraryContent).toHaveBeenCalledWith('@kit.AbilityKit'); +} + +function test_findUsageContext_kitMappingMatch_branch(mockConfigGenerate: MockConfigGenerator) { + const fileContent = ` +import { hilog } from '@kit.PerformanceAnalysisKit'; +hilog.info('test message'); + `; + (fs.readFileSync as jest.Mock).mockReturnValue(fileContent); + + const mockKitMappingMatch = jest.spyOn(mockConfigGenerate as any, 'kitMappingMatch'); + mockKitMappingMatch.mockReturnValue(true); + + const mockIsExternalOrSystemModule = jest.spyOn(mockConfigGenerate as any, 'isExternalOrSystemModule'); + mockIsExternalOrSystemModule.mockReturnValue(true); + + const result = mockConfigGenerate['findUsageContext']('@ohos.hilog', ['/fake/source/file.ets']); + + expect(result).toEqual({ newKey: '@ohos.hilog', resolvedKeyPath: '@ohos.hilog' }); + expect(mockKitMappingMatch).toHaveBeenCalledWith('@ohos.hilog', '@kit.PerformanceAnalysisKit'); + expect(mockIsExternalOrSystemModule).toHaveBeenCalledWith('@ohos.hilog'); +} + +function test_findUsageContext_external_module_branch(mockConfigGenerate: MockConfigGenerator) { + const fileContent = ` +import { Context } from '@ohos.app.ability.UIAbility'; +const context = new Context(); + `; + (fs.readFileSync as jest.Mock).mockReturnValue(fileContent); + + const mockIsExternalOrSystemModule = jest.spyOn(mockConfigGenerate as any, 'isExternalOrSystemModule'); + mockIsExternalOrSystemModule.mockReturnValue(true); + + const result = mockConfigGenerate['findUsageContext']('@ohos.app.ability.UIAbility', ['/fake/source/file.ets']); + + expect(result).toEqual({ + newKey: '@ohos.app.ability.UIAbility', + resolvedKeyPath: '@ohos.app.ability.UIAbility' + }); + expect(mockIsExternalOrSystemModule).toHaveBeenCalledWith('@ohos.app.ability.UIAbility'); +} + +function test_findUsageContext_no_match_found(mockConfigGenerate: MockConfigGenerator) { + const fileContent = ` +import { OtherModule } from './otherModule'; +import { DifferentKit } from '@kit.DifferentKit'; +const instance = new OtherModule(); + `; + (fs.readFileSync as jest.Mock).mockReturnValue(fileContent); + + const result = mockConfigGenerate['findUsageContext']('@kit.NonExistentKit', ['/fake/source/file.ets']); + + expect(result).toBeNull(); +} + +function test_getSystemLibraryContent_no_system_path_section(mockConfigGenerate: MockConfigGenerator) { + const mockArktsconfigGenerator = mockConfigGenerate['arktsconfigGenerator']; + (mockArktsconfigGenerator as any).systemPathSection = undefined; + + const result = mockConfigGenerate['getSystemLibraryContent']('@kit.AbilityKit'); + + expect(result).toBeNull(); +} + +function test_getSystemLibraryContent_found_ets_file(mockConfigGenerate: MockConfigGenerator) { + const mockArktsconfigGenerator = mockConfigGenerate['arktsconfigGenerator']; + (mockArktsconfigGenerator as any).systemPathSection = { + '@kit.AbilityKit': ['/fake/sdk/path/AbilityKit'] + }; + + const mockFileContent = 'declare module "@kit.AbilityKit" { export interface Context {} }'; + + (fs.existsSync as jest.Mock).mockReturnValueOnce(true); + + (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); + + const result = mockConfigGenerate['getSystemLibraryContent']('@kit.AbilityKit'); + + expect(result).toBe(mockFileContent); + expect(fs.existsSync).toHaveBeenCalledWith('/fake/sdk/path/AbilityKit.d.ets'); + expect(fs.readFileSync).toHaveBeenCalledWith('/fake/sdk/path/AbilityKit.d.ets', 'utf-8'); +} + +function test_getSystemLibraryContent_found_ts_file(mockConfigGenerate: MockConfigGenerator) { + const mockArktsconfigGenerator = mockConfigGenerate['arktsconfigGenerator']; + (mockArktsconfigGenerator as any).systemPathSection = { + '@kit.PerformanceAnalysisKit': ['/fake/sdk/path/PerformanceAnalysisKit'] + }; + + const mockFileContent = 'declare module "@kit.PerformanceAnalysisKit" { export namespace hilog {} }'; + + (fs.existsSync as jest.Mock) + .mockReturnValueOnce(false) + .mockReturnValueOnce(true); + + (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); + + const result = mockConfigGenerate['getSystemLibraryContent']('@kit.PerformanceAnalysisKit'); + + expect(result).toBe(mockFileContent); + expect(fs.existsSync).toHaveBeenCalledWith('/fake/sdk/path/PerformanceAnalysisKit.d.ets'); + expect(fs.existsSync).toHaveBeenCalledWith('/fake/sdk/path/PerformanceAnalysisKit.d.ts'); + expect(fs.readFileSync).toHaveBeenCalledWith('/fake/sdk/path/PerformanceAnalysisKit.d.ts', 'utf-8'); +} + +function test_getSystemLibraryContent_no_files_found(mockConfigGenerate: MockConfigGenerator) { + const mockArktsconfigGenerator = mockConfigGenerate['arktsconfigGenerator']; + (mockArktsconfigGenerator as any).systemPathSection = { + '@kit.TestKit': ['/fake/sdk/path/TestKit'] + }; + + (fs.existsSync as jest.Mock) + .mockReturnValueOnce(false) + .mockReturnValueOnce(false); + + const result = mockConfigGenerate['getSystemLibraryContent']('@kit.TestKit'); + + expect(result).toBeNull(); + expect(fs.existsSync).toHaveBeenCalledWith('/fake/sdk/path/TestKit.d.ets'); + expect(fs.existsSync).toHaveBeenCalledWith('/fake/sdk/path/TestKit.d.ts'); + expect(fs.readFileSync).not.toHaveBeenCalled(); +} + +function test_parseImportBindings_namespace_import(mockConfigGenerate: MockConfigGenerator) { + const result = mockConfigGenerate['parseImportBindings']('* as TestModule'); + + expect(result).toEqual(['TestModule']); +} -- Gitee