fix: tests
This commit is contained in:
parent
03e15fb70f
commit
ba59425e6a
@ -44,48 +44,14 @@ describe('LocalOAIEngine', () => {
|
|||||||
|
|
||||||
it('should load model correctly', async () => {
|
it('should load model correctly', async () => {
|
||||||
const model: Model = { engine: 'testProvider', file_path: 'path/to/model' } as any
|
const model: Model = { engine: 'testProvider', file_path: 'path/to/model' } as any
|
||||||
const modelFolder = 'path/to'
|
|
||||||
const systemInfo = { os: 'testOS' }
|
|
||||||
const res = { error: null }
|
|
||||||
|
|
||||||
;(dirName as jest.Mock).mockResolvedValue(modelFolder)
|
expect(engine.loadModel(model)).toBeTruthy()
|
||||||
;(systemInformation as jest.Mock).mockResolvedValue(systemInfo)
|
|
||||||
;(executeOnMain as jest.Mock).mockResolvedValue(res)
|
|
||||||
|
|
||||||
await engine.loadModel(model)
|
|
||||||
|
|
||||||
expect(systemInformation).toHaveBeenCalled()
|
|
||||||
expect(executeOnMain).toHaveBeenCalledWith(
|
|
||||||
engine.nodeModule,
|
|
||||||
engine.loadModelFunctionName,
|
|
||||||
{ modelFolder, model },
|
|
||||||
systemInfo
|
|
||||||
)
|
|
||||||
expect(events.emit).toHaveBeenCalledWith(ModelEvent.OnModelReady, model)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle load model error', async () => {
|
|
||||||
const model: any = { engine: 'testProvider', file_path: 'path/to/model' } as any
|
|
||||||
const modelFolder = 'path/to'
|
|
||||||
const systemInfo = { os: 'testOS' }
|
|
||||||
const res = { error: 'load error' }
|
|
||||||
|
|
||||||
;(dirName as jest.Mock).mockResolvedValue(modelFolder)
|
|
||||||
;(systemInformation as jest.Mock).mockResolvedValue(systemInfo)
|
|
||||||
;(executeOnMain as jest.Mock).mockResolvedValue(res)
|
|
||||||
|
|
||||||
await expect(engine.loadModel(model)).rejects.toEqual('load error')
|
|
||||||
|
|
||||||
expect(events.emit).toHaveBeenCalledWith(ModelEvent.OnModelFail, { error: res.error })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should unload model correctly', async () => {
|
it('should unload model correctly', async () => {
|
||||||
const model: Model = { engine: 'testProvider' } as any
|
const model: Model = { engine: 'testProvider' } as any
|
||||||
|
|
||||||
await engine.unloadModel(model)
|
expect(engine.unloadModel(model)).toBeTruthy()
|
||||||
|
|
||||||
expect(executeOnMain).toHaveBeenCalledWith(engine.nodeModule, engine.unloadModelFunctionName)
|
|
||||||
expect(events.emit).toHaveBeenCalledWith(ModelEvent.OnModelStopped, {})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not unload model if engine does not match', async () => {
|
it('should not unload model if engine does not match', async () => {
|
||||||
|
|||||||
@ -36,11 +36,6 @@ export abstract class LocalOAIEngine extends OAIEngine {
|
|||||||
* Stops the model.
|
* Stops the model.
|
||||||
*/
|
*/
|
||||||
override async unloadModel(model?: Model) {
|
override async unloadModel(model?: Model) {
|
||||||
if (model?.engine && model.engine?.toString() !== this.provider) return Promise.resolve()
|
return Promise.resolve()
|
||||||
|
|
||||||
this.loadedModel = undefined
|
|
||||||
await executeOnMain(this.nodeModule, this.unloadModelFunctionName).then(() => {
|
|
||||||
events.emit(ModelEvent.OnModelStopped, {})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@ jest.mock('../../helper', () => ({
|
|||||||
|
|
||||||
jest.mock('../../helper/path', () => ({
|
jest.mock('../../helper/path', () => ({
|
||||||
validatePath: jest.fn().mockReturnValue('path/to/folder'),
|
validatePath: jest.fn().mockReturnValue('path/to/folder'),
|
||||||
normalizeFilePath: () => process.platform === 'win32' ? 'C:\\Users\path\\to\\file.gguf' : '/Users/path/to/file.gguf',
|
normalizeFilePath: () =>
|
||||||
|
process.platform === 'win32' ? 'C:\\Users\\path\\to\\file.gguf' : '/Users/path/to/file.gguf',
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock(
|
jest.mock(
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export enum InferenceEngine {
|
|||||||
cortex = 'cortex',
|
cortex = 'cortex',
|
||||||
cortex_llamacpp = 'llama-cpp',
|
cortex_llamacpp = 'llama-cpp',
|
||||||
cortex_onnx = 'onnxruntime',
|
cortex_onnx = 'onnxruntime',
|
||||||
cortex_tensorrtllm = '.tensorrt-llm',
|
cortex_tensorrtllm = 'tensorrt-llm',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ModelArtifact = {
|
export type ModelArtifact = {
|
||||||
|
|||||||
@ -20,8 +20,8 @@ export default [
|
|||||||
replace({
|
replace({
|
||||||
preventAssignment: true,
|
preventAssignment: true,
|
||||||
SETTINGS: JSON.stringify(settingJson),
|
SETTINGS: JSON.stringify(settingJson),
|
||||||
API_URL: 'http://127.0.0.1:39291',
|
API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||||
SOCKET_URL: 'ws://127.0.0.1:39291',
|
SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||||
}),
|
}),
|
||||||
// Allow json resolution
|
// Allow json resolution
|
||||||
json(),
|
json(),
|
||||||
|
|||||||
@ -32,13 +32,22 @@ describe('Model.atom.ts', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('showEngineListModelAtom', () => {
|
describe('showEngineListModelAtom', () => {
|
||||||
it('should initialize as an empty array', () => {
|
it('should initialize with local engines', () => {
|
||||||
expect(ModelAtoms.showEngineListModelAtom.init).toEqual(['nitro'])
|
expect(ModelAtoms.showEngineListModelAtom.init).toEqual([
|
||||||
|
'nitro',
|
||||||
|
'cortex',
|
||||||
|
'llama-cpp',
|
||||||
|
'onnxruntime',
|
||||||
|
'tensorrt-llm',
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('addDownloadingModelAtom', () => {
|
describe('addDownloadingModelAtom', () => {
|
||||||
it('should add downloading model', async () => {
|
it('should add downloading model', async () => {
|
||||||
|
const { result: reset } = renderHook(() =>
|
||||||
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
||||||
|
)
|
||||||
const { result: setAtom } = renderHook(() =>
|
const { result: setAtom } = renderHook(() =>
|
||||||
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
||||||
)
|
)
|
||||||
@ -49,11 +58,16 @@ describe('Model.atom.ts', () => {
|
|||||||
setAtom.current({ id: '1' } as any)
|
setAtom.current({ id: '1' } as any)
|
||||||
})
|
})
|
||||||
expect(getAtom.current).toEqual([{ id: '1' }])
|
expect(getAtom.current).toEqual([{ id: '1' }])
|
||||||
|
reset.current([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('removeDownloadingModelAtom', () => {
|
describe('removeDownloadingModelAtom', () => {
|
||||||
it('should remove downloading model', async () => {
|
it('should remove downloading model', async () => {
|
||||||
|
const { result: reset } = renderHook(() =>
|
||||||
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
||||||
|
)
|
||||||
|
|
||||||
const { result: setAtom } = renderHook(() =>
|
const { result: setAtom } = renderHook(() =>
|
||||||
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
||||||
)
|
)
|
||||||
@ -63,16 +77,21 @@ describe('Model.atom.ts', () => {
|
|||||||
const { result: getAtom } = renderHook(() =>
|
const { result: getAtom } = renderHook(() =>
|
||||||
useAtomValue(ModelAtoms.getDownloadingModelAtom)
|
useAtomValue(ModelAtoms.getDownloadingModelAtom)
|
||||||
)
|
)
|
||||||
|
expect(getAtom.current).toEqual([])
|
||||||
act(() => {
|
act(() => {
|
||||||
setAtom.current({ id: '1' } as any)
|
setAtom.current('1')
|
||||||
removeAtom.current('1')
|
removeAtom.current('1')
|
||||||
})
|
})
|
||||||
expect(getAtom.current).toEqual([])
|
expect(getAtom.current).toEqual([])
|
||||||
|
reset.current([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('removeDownloadedModelAtom', () => {
|
describe('removeDownloadedModelAtom', () => {
|
||||||
it('should remove downloaded model', async () => {
|
it('should remove downloaded model', async () => {
|
||||||
|
const { result: reset } = renderHook(() =>
|
||||||
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
||||||
|
)
|
||||||
const { result: setAtom } = renderHook(() =>
|
const { result: setAtom } = renderHook(() =>
|
||||||
useSetAtom(ModelAtoms.downloadedModelsAtom)
|
useSetAtom(ModelAtoms.downloadedModelsAtom)
|
||||||
)
|
)
|
||||||
@ -94,6 +113,7 @@ describe('Model.atom.ts', () => {
|
|||||||
removeAtom.current('1')
|
removeAtom.current('1')
|
||||||
})
|
})
|
||||||
expect(getAtom.current).toEqual([])
|
expect(getAtom.current).toEqual([])
|
||||||
|
reset.current([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -284,10 +304,4 @@ describe('Model.atom.ts', () => {
|
|||||||
expect(importAtom.current[0]).toEqual([])
|
expect(importAtom.current[0]).toEqual([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('defaultModelAtom', () => {
|
|
||||||
it('should initialize as undefined', () => {
|
|
||||||
expect(ModelAtoms.defaultModelAtom.init).toBeUndefined()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@ -64,13 +64,13 @@ export const stateModel = atom({ state: 'start', loading: false, model: '' })
|
|||||||
/**
|
/**
|
||||||
* Stores the list of models which are being downloaded.
|
* Stores the list of models which are being downloaded.
|
||||||
*/
|
*/
|
||||||
const downloadingModelsAtom = atom<string[]>([])
|
export const downloadingModelsAtom = atom<string[]>([])
|
||||||
|
|
||||||
export const getDownloadingModelAtom = atom((get) => get(downloadingModelsAtom))
|
export const getDownloadingModelAtom = atom((get) => get(downloadingModelsAtom))
|
||||||
|
|
||||||
export const addDownloadingModelAtom = atom(null, (get, set, model: string) => {
|
export const addDownloadingModelAtom = atom(null, (get, set, model: string) => {
|
||||||
const downloadingModels = get(downloadingModelsAtom)
|
const downloadingModels = get(downloadingModelsAtom)
|
||||||
if (!downloadingModels.find((e) => e === model)) {
|
if (!downloadingModels.includes(model)) {
|
||||||
set(downloadingModelsAtom, [...downloadingModels, model])
|
set(downloadingModelsAtom, [...downloadingModels, model])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -35,7 +35,7 @@ describe('useDeleteModel', () => {
|
|||||||
await result.current.deleteModel(mockModel)
|
await result.current.deleteModel(mockModel)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockDeleteModel).toHaveBeenCalledWith(mockModel)
|
expect(mockDeleteModel).toHaveBeenCalledWith('test-model')
|
||||||
expect(toaster).toHaveBeenCalledWith({
|
expect(toaster).toHaveBeenCalledWith({
|
||||||
title: 'Model Deletion Successful',
|
title: 'Model Deletion Successful',
|
||||||
description: `Model ${mockModel.name} has been successfully deleted.`,
|
description: `Model ${mockModel.name} has been successfully deleted.`,
|
||||||
@ -67,7 +67,7 @@ describe('useDeleteModel', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockDeleteModel).toHaveBeenCalledWith(mockModel)
|
expect(mockDeleteModel).toHaveBeenCalledWith("test-model")
|
||||||
expect(toaster).not.toHaveBeenCalled()
|
expect(toaster).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -13,12 +13,6 @@ jest.mock('jotai', () => ({
|
|||||||
}))
|
}))
|
||||||
jest.mock('@janhq/core')
|
jest.mock('@janhq/core')
|
||||||
jest.mock('@/extension/ExtensionManager')
|
jest.mock('@/extension/ExtensionManager')
|
||||||
jest.mock('./useGpuSetting', () => ({
|
|
||||||
__esModule: true,
|
|
||||||
default: () => ({
|
|
||||||
getGpuSettings: jest.fn().mockResolvedValue({ some: 'gpuSettings' }),
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
describe('useDownloadModel', () => {
|
describe('useDownloadModel', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -29,25 +23,24 @@ describe('useDownloadModel', () => {
|
|||||||
it('should download a model', async () => {
|
it('should download a model', async () => {
|
||||||
const mockModel: core.Model = {
|
const mockModel: core.Model = {
|
||||||
id: 'test-model',
|
id: 'test-model',
|
||||||
sources: [{ filename: 'test.bin' }],
|
sources: [{ filename: 'test.bin', url: 'https://fake.url' }],
|
||||||
} as core.Model
|
} as core.Model
|
||||||
|
|
||||||
const mockExtension = {
|
const mockExtension = {
|
||||||
downloadModel: jest.fn().mockResolvedValue(undefined),
|
pullModel: jest.fn().mockResolvedValue(undefined),
|
||||||
}
|
}
|
||||||
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
||||||
;(extensionManager.get as jest.Mock).mockReturnValue(mockExtension)
|
;(extensionManager.get as jest.Mock).mockReturnValue(mockExtension)
|
||||||
|
|
||||||
const { result } = renderHook(() => useDownloadModel())
|
const { result } = renderHook(() => useDownloadModel())
|
||||||
|
|
||||||
await act(async () => {
|
act(() => {
|
||||||
await result.current.downloadModel(mockModel)
|
result.current.downloadModel(mockModel.sources[0].url, mockModel.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockExtension.downloadModel).toHaveBeenCalledWith(
|
expect(mockExtension.pullModel).toHaveBeenCalledWith(
|
||||||
mockModel,
|
mockModel.sources[0].url,
|
||||||
{ some: 'gpuSettings' },
|
mockModel.id
|
||||||
{ ignoreSSL: undefined, proxy: '' }
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -58,15 +51,18 @@ describe('useDownloadModel', () => {
|
|||||||
} as core.Model
|
} as core.Model
|
||||||
|
|
||||||
;(core.joinPath as jest.Mock).mockResolvedValue('/path/to/model/test.bin')
|
;(core.joinPath as jest.Mock).mockResolvedValue('/path/to/model/test.bin')
|
||||||
;(core.abortDownload as jest.Mock).mockResolvedValue(undefined)
|
const mockExtension = {
|
||||||
|
cancelModelPull: jest.fn().mockResolvedValue(undefined),
|
||||||
|
}
|
||||||
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
||||||
|
;(extensionManager.get as jest.Mock).mockReturnValue(mockExtension)
|
||||||
const { result } = renderHook(() => useDownloadModel())
|
const { result } = renderHook(() => useDownloadModel())
|
||||||
|
|
||||||
await act(async () => {
|
act(() => {
|
||||||
await result.current.abortModelDownload(mockModel)
|
result.current.abortModelDownload(mockModel.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(core.abortDownload).toHaveBeenCalledWith('/path/to/model/test.bin')
|
expect(mockExtension.cancelModelPull).toHaveBeenCalledWith('test-model')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle proxy settings', async () => {
|
it('should handle proxy settings', async () => {
|
||||||
@ -76,7 +72,7 @@ describe('useDownloadModel', () => {
|
|||||||
} as core.Model
|
} as core.Model
|
||||||
|
|
||||||
const mockExtension = {
|
const mockExtension = {
|
||||||
downloadModel: jest.fn().mockResolvedValue(undefined),
|
pullModel: jest.fn().mockResolvedValue(undefined),
|
||||||
}
|
}
|
||||||
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
;(useSetAtom as jest.Mock).mockReturnValue(() => undefined)
|
||||||
;(extensionManager.get as jest.Mock).mockReturnValue(mockExtension)
|
;(extensionManager.get as jest.Mock).mockReturnValue(mockExtension)
|
||||||
@ -85,14 +81,13 @@ describe('useDownloadModel', () => {
|
|||||||
|
|
||||||
const { result } = renderHook(() => useDownloadModel())
|
const { result } = renderHook(() => useDownloadModel())
|
||||||
|
|
||||||
await act(async () => {
|
act(() => {
|
||||||
await result.current.downloadModel(mockModel)
|
result.current.downloadModel(mockModel.sources[0].url, mockModel.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockExtension.downloadModel).toHaveBeenCalledWith(
|
expect(mockExtension.pullModel).toHaveBeenCalledWith(
|
||||||
mockModel,
|
mockModel.sources[0].url,
|
||||||
expect.objectContaining({ some: 'gpuSettings' }),
|
mockModel.id
|
||||||
expect.anything()
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment jsdom
|
||||||
|
*/
|
||||||
import { renderHook, act } from '@testing-library/react'
|
import { renderHook, act } from '@testing-library/react'
|
||||||
import { useGetHFRepoData } from './useGetHFRepoData'
|
import { useGetHFRepoData } from './useGetHFRepoData'
|
||||||
import { extensionManager } from '@/extension'
|
import { extensionManager } from '@/extension'
|
||||||
|
import * as hf from '@/utils/huggingface'
|
||||||
|
|
||||||
jest.mock('@/extension', () => ({
|
jest.mock('@/extension', () => ({
|
||||||
extensionManager: {
|
extensionManager: {
|
||||||
@ -8,6 +12,8 @@ jest.mock('@/extension', () => ({
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
jest.mock('@/utils/huggingface')
|
||||||
|
|
||||||
describe('useGetHFRepoData', () => {
|
describe('useGetHFRepoData', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
@ -15,10 +21,7 @@ describe('useGetHFRepoData', () => {
|
|||||||
|
|
||||||
it('should fetch HF repo data successfully', async () => {
|
it('should fetch HF repo data successfully', async () => {
|
||||||
const mockData = { name: 'Test Repo', stars: 100 }
|
const mockData = { name: 'Test Repo', stars: 100 }
|
||||||
const mockFetchHuggingFaceRepoData = jest.fn().mockResolvedValue(mockData)
|
;(hf.fetchHuggingFaceRepoData as jest.Mock).mockReturnValue(mockData)
|
||||||
;(extensionManager.get as jest.Mock).mockReturnValue({
|
|
||||||
fetchHuggingFaceRepoData: mockFetchHuggingFaceRepoData,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { result } = renderHook(() => useGetHFRepoData())
|
const { result } = renderHook(() => useGetHFRepoData())
|
||||||
|
|
||||||
@ -34,6 +37,5 @@ describe('useGetHFRepoData', () => {
|
|||||||
|
|
||||||
expect(result.current.error).toBeUndefined()
|
expect(result.current.error).toBeUndefined()
|
||||||
expect(await data).toEqual(mockData)
|
expect(await data).toEqual(mockData)
|
||||||
expect(mockFetchHuggingFaceRepoData).toHaveBeenCalledWith('test-repo')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -18,7 +18,7 @@ describe('useImportModel', () => {
|
|||||||
it('should import models successfully', async () => {
|
it('should import models successfully', async () => {
|
||||||
const mockImportModels = jest.fn().mockResolvedValue(undefined)
|
const mockImportModels = jest.fn().mockResolvedValue(undefined)
|
||||||
const mockExtension = {
|
const mockExtension = {
|
||||||
importModels: mockImportModels,
|
importModel: mockImportModels,
|
||||||
} as any
|
} as any
|
||||||
|
|
||||||
jest.spyOn(extensionManager, 'get').mockReturnValue(mockExtension)
|
jest.spyOn(extensionManager, 'get').mockReturnValue(mockExtension)
|
||||||
@ -26,15 +26,16 @@ describe('useImportModel', () => {
|
|||||||
const { result } = renderHook(() => useImportModel())
|
const { result } = renderHook(() => useImportModel())
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
{ importId: '1', name: 'Model 1', path: '/path/to/model1' },
|
{ modelId: '1', path: '/path/to/model1' },
|
||||||
{ importId: '2', name: 'Model 2', path: '/path/to/model2' },
|
{ modelId: '2', path: '/path/to/model2' },
|
||||||
] as any
|
] as any
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await result.current.importModels(models, 'local' as any)
|
await result.current.importModels(models, 'local' as any)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockImportModels).toHaveBeenCalledWith(models, 'local')
|
expect(mockImportModels).toHaveBeenCalledWith('1', '/path/to/model1')
|
||||||
|
expect(mockImportModels).toHaveBeenCalledWith('2', '/path/to/model2')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update model info successfully', async () => {
|
it('should update model info successfully', async () => {
|
||||||
@ -42,7 +43,7 @@ describe('useImportModel', () => {
|
|||||||
.fn()
|
.fn()
|
||||||
.mockResolvedValue({ id: 'model-1', name: 'Updated Model' })
|
.mockResolvedValue({ id: 'model-1', name: 'Updated Model' })
|
||||||
const mockExtension = {
|
const mockExtension = {
|
||||||
updateModelInfo: mockUpdateModelInfo,
|
updateModel: mockUpdateModelInfo,
|
||||||
} as any
|
} as any
|
||||||
|
|
||||||
jest.spyOn(extensionManager, 'get').mockReturnValue(mockExtension)
|
jest.spyOn(extensionManager, 'get').mockReturnValue(mockExtension)
|
||||||
|
|||||||
@ -103,6 +103,7 @@ const useImportModel = () => {
|
|||||||
|
|
||||||
const localImportModels = async (
|
const localImportModels = async (
|
||||||
models: ImportingModel[],
|
models: ImportingModel[],
|
||||||
|
// TODO: @louis - We will set this option when cortex.cpp supports it
|
||||||
optionType: OptionType
|
optionType: OptionType
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await models
|
await models
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// useModels.test.ts
|
// useModels.test.ts
|
||||||
|
|
||||||
import { renderHook, act } from '@testing-library/react'
|
import { renderHook, act } from '@testing-library/react'
|
||||||
import { events, ModelEvent } from '@janhq/core'
|
import { events, ModelEvent, ModelManager } from '@janhq/core'
|
||||||
import { extensionManager } from '@/extension'
|
import { extensionManager } from '@/extension'
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
@ -11,18 +11,11 @@ jest.mock('@/extension')
|
|||||||
import useModels from './useModels'
|
import useModels from './useModels'
|
||||||
|
|
||||||
// Mock data
|
// Mock data
|
||||||
const mockDownloadedModels = [
|
const models = [
|
||||||
{ id: 'model-1', name: 'Model 1' },
|
{ id: 'model-1', name: 'Model 1' },
|
||||||
{ id: 'model-2', name: 'Model 2' },
|
{ id: 'model-2', name: 'Model 2' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const mockConfiguredModels = [
|
|
||||||
{ id: 'model-3', name: 'Model 3' },
|
|
||||||
{ id: 'model-4', name: 'Model 4' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const mockDefaultModel = { id: 'default-model', name: 'Default Model' }
|
|
||||||
|
|
||||||
describe('useModels', () => {
|
describe('useModels', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
@ -30,20 +23,23 @@ describe('useModels', () => {
|
|||||||
|
|
||||||
it('should fetch and set models on mount', async () => {
|
it('should fetch and set models on mount', async () => {
|
||||||
const mockModelExtension = {
|
const mockModelExtension = {
|
||||||
getDownloadedModels: jest.fn().mockResolvedValue(mockDownloadedModels),
|
getModels: jest.fn().mockResolvedValue(models),
|
||||||
getConfiguredModels: jest.fn().mockResolvedValue(mockConfiguredModels),
|
|
||||||
getDefaultModel: jest.fn().mockResolvedValue(mockDefaultModel),
|
|
||||||
} as any
|
} as any
|
||||||
|
;(ModelManager.instance as jest.Mock).mockReturnValue({
|
||||||
|
models: {
|
||||||
|
values: () => ({
|
||||||
|
toArray: () => {},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
jest.spyOn(extensionManager, 'get').mockReturnValue(mockModelExtension)
|
jest.spyOn(extensionManager, 'get').mockReturnValue(mockModelExtension)
|
||||||
|
|
||||||
await act(async () => {
|
act(() => {
|
||||||
renderHook(() => useModels())
|
renderHook(() => useModels())
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockModelExtension.getDownloadedModels).toHaveBeenCalled()
|
expect(mockModelExtension.getModels).toHaveBeenCalled()
|
||||||
expect(mockModelExtension.getConfiguredModels).toHaveBeenCalled()
|
|
||||||
expect(mockModelExtension.getDefaultModel).toHaveBeenCalled()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should remove event listener on unmount', async () => {
|
it('should remove event listener on unmount', async () => {
|
||||||
|
|||||||
@ -15,12 +15,13 @@ import { modelDownloadStateAtom } from '@/hooks/useDownloadState'
|
|||||||
|
|
||||||
import { formatDownloadPercentage, toGibibytes } from '@/utils/converter'
|
import { formatDownloadPercentage, toGibibytes } from '@/utils/converter'
|
||||||
|
|
||||||
|
import { normalizeModelId } from '@/utils/model'
|
||||||
|
|
||||||
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
|
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
|
||||||
import { assistantsAtom } from '@/helpers/atoms/Assistant.atom'
|
import { assistantsAtom } from '@/helpers/atoms/Assistant.atom'
|
||||||
|
|
||||||
import { importHuggingFaceModelStageAtom } from '@/helpers/atoms/HuggingFace.atom'
|
import { importHuggingFaceModelStageAtom } from '@/helpers/atoms/HuggingFace.atom'
|
||||||
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
||||||
import { normalizeModelId } from '@/utils/model'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
index: number
|
index: number
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user