Split jest tests into fast and slow groups (#1401)

This commit is contained in:
Chenlei Hu
2024-11-01 22:39:42 -04:00
committed by GitHub
parent d719a4e0fb
commit 8baaf380dc
22 changed files with 80 additions and 36 deletions

View File

@@ -0,0 +1,99 @@
import { setActivePinia, createPinia } from 'pinia'
import { useModelStore } from '@/stores/modelStore'
import { api } from '@/scripts/api'
// Mock the api
jest.mock('@/scripts/api', () => ({
api: {
getModels: jest.fn(),
getModelFolders: jest.fn(),
viewMetadata: jest.fn()
}
}))
function enableMocks() {
;(api.getModels as jest.Mock).mockResolvedValue([
'sdxl.safetensors',
'sdv15.safetensors',
'noinfo.safetensors'
])
;(api.getModelFolders as jest.Mock).mockResolvedValue(['checkpoints', 'vae'])
;(api.viewMetadata as jest.Mock).mockImplementation((_, model) => {
if (model === 'noinfo.safetensors') {
return Promise.resolve({})
}
return Promise.resolve({
'modelspec.title': `Title of ${model}`,
display_name: 'Should not show',
'modelspec.architecture': 'stable-diffusion-xl-base-v1',
'modelspec.author': `Author of ${model}`,
'modelspec.description': `Description of ${model}`,
'modelspec.resolution': '1024x1024',
trigger_phrase: `Trigger phrase of ${model}`,
usage_hint: `Usage hint of ${model}`,
tags: `tags,for,${model}`
})
})
}
describe('useModelStore', () => {
let store: ReturnType<typeof useModelStore>
beforeEach(async () => {
setActivePinia(createPinia())
store = useModelStore()
})
it('should load models', async () => {
enableMocks()
await store.loadModelFolders()
const folderStore = await store.getLoadedModelFolder('checkpoints')
expect(folderStore).not.toBeNull()
if (!folderStore) return
expect(Object.keys(folderStore.models).length).toBe(3)
})
it('should load model metadata', async () => {
enableMocks()
await store.loadModelFolders()
const folderStore = await store.getLoadedModelFolder('checkpoints')
expect(folderStore).not.toBeNull()
if (!folderStore) return
const model = folderStore.models['sdxl.safetensors']
await model.load()
expect(model.title).toBe('Title of sdxl.safetensors')
expect(model.architecture_id).toBe('stable-diffusion-xl-base-v1')
expect(model.author).toBe('Author of sdxl.safetensors')
expect(model.description).toBe('Description of sdxl.safetensors')
expect(model.resolution).toBe('1024x1024')
expect(model.trigger_phrase).toBe('Trigger phrase of sdxl.safetensors')
expect(model.usage_hint).toBe('Usage hint of sdxl.safetensors')
expect(model.tags).toHaveLength(3)
})
it('should handle no metadata', async () => {
enableMocks()
await store.loadModelFolders()
const folderStore = await store.getLoadedModelFolder('checkpoints')
expect(folderStore).not.toBeNull()
if (!folderStore) return
const model = folderStore.models['noinfo.safetensors']
await model.load()
expect(model.file_name).toBe('noinfo.safetensors')
expect(model.title).toBe('noinfo')
expect(model.architecture_id).toBe('')
expect(model.author).toBe('')
expect(model.description).toBe('')
expect(model.resolution).toBe('')
})
it('should cache model information', async () => {
enableMocks()
await store.loadModelFolders()
expect(api.getModels).toHaveBeenCalledTimes(0)
await store.getLoadedModelFolder('checkpoints')
expect(api.getModels).toHaveBeenCalledTimes(1)
await store.getLoadedModelFolder('checkpoints')
expect(api.getModels).toHaveBeenCalledTimes(1)
})
})

View File

@@ -0,0 +1,207 @@
import { setActivePinia, createPinia } from 'pinia'
import {
TempUserFile,
UserFile,
useUserFileStore
} from '@/stores/userFileStore'
import { api } from '@/scripts/api'
// Mock the api
jest.mock('@/scripts/api', () => ({
api: {
listUserDataFullInfo: jest.fn(),
getUserData: jest.fn(),
storeUserData: jest.fn(),
deleteUserData: jest.fn(),
moveUserData: jest.fn()
}
}))
describe('useUserFileStore', () => {
let store: ReturnType<typeof useUserFileStore>
beforeEach(() => {
setActivePinia(createPinia())
store = useUserFileStore()
})
it('should initialize with empty files', () => {
expect(store.userFiles).toHaveLength(0)
expect(store.modifiedFiles).toHaveLength(0)
expect(store.openedFiles).toHaveLength(0)
})
describe('syncFiles', () => {
it('should add new files', async () => {
const mockFiles = [
{ path: 'dir/file1.txt', modified: 123, size: 100 },
{ path: 'dir/file2.txt', modified: 456, size: 200 }
]
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue(mockFiles)
await store.syncFiles('dir')
expect(store.userFiles).toHaveLength(2)
expect(store.userFiles[0].path).toBe('dir/file1.txt')
expect(store.userFiles[1].path).toBe('dir/file2.txt')
})
it('should update existing files', async () => {
const initialFile = { path: 'dir/file1.txt', modified: 123, size: 100 }
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue([initialFile])
await store.syncFiles('dir')
const updatedFile = { path: 'dir/file1.txt', modified: 456, size: 200 }
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue([updatedFile])
await store.syncFiles('dir')
expect(store.userFiles).toHaveLength(1)
expect(store.userFiles[0].lastModified).toBe(456)
expect(store.userFiles[0].size).toBe(200)
})
it('should remove non-existent files', async () => {
const initialFiles = [
{ path: 'dir/file1.txt', modified: 123, size: 100 },
{ path: 'dir/file2.txt', modified: 456, size: 200 }
]
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue(initialFiles)
await store.syncFiles('dir')
const updatedFiles = [{ path: 'dir/file1.txt', modified: 123, size: 100 }]
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue(updatedFiles)
await store.syncFiles('dir')
expect(store.userFiles).toHaveLength(1)
expect(store.userFiles[0].path).toBe('dir/file1.txt')
})
it('should sync root directory when no directory is specified', async () => {
const mockFiles = [{ path: 'file1.txt', modified: 123, size: 100 }]
;(api.listUserDataFullInfo as jest.Mock).mockResolvedValue(mockFiles)
await store.syncFiles()
expect(api.listUserDataFullInfo).toHaveBeenCalledWith('')
expect(store.userFiles).toHaveLength(1)
expect(store.userFiles[0].path).toBe('file1.txt')
})
})
describe('UserFile', () => {
describe('load', () => {
it('should load file content', async () => {
const file = new UserFile('file1.txt', 123, 100)
;(api.getUserData as jest.Mock).mockResolvedValue({
status: 200,
text: () => Promise.resolve('file content')
})
await file.load()
expect(file.content).toBe('file content')
expect(file.originalContent).toBe('file content')
expect(file.isLoading).toBe(false)
})
it('should throw error on failed load', async () => {
const file = new UserFile('file1.txt', 123, 100)
;(api.getUserData as jest.Mock).mockResolvedValue({
status: 404,
statusText: 'Not Found'
})
await expect(file.load()).rejects.toThrow(
"Failed to load file 'file1.txt': 404 Not Found"
)
})
})
describe('save', () => {
it('should save modified file', async () => {
const file = new UserFile('file1.txt', 123, 100)
file.content = 'modified content'
file.originalContent = 'original content'
;(api.storeUserData as jest.Mock).mockResolvedValue({
status: 200,
json: () => Promise.resolve({ modified: 456, size: 200 })
})
await file.save()
expect(api.storeUserData).toHaveBeenCalledWith(
'file1.txt',
'modified content',
{ throwOnError: true, full_info: true }
)
expect(file.lastModified).toBe(456)
expect(file.size).toBe(200)
})
it('should not save unmodified file', async () => {
const file = new UserFile('file1.txt', 123, 100)
file.content = 'content'
file.originalContent = 'content'
await file.save()
expect(api.storeUserData).not.toHaveBeenCalled()
})
})
describe('delete', () => {
it('should delete file', async () => {
const file = new UserFile('file1.txt', 123, 100)
;(api.deleteUserData as jest.Mock).mockResolvedValue({ status: 204 })
await file.delete()
expect(api.deleteUserData).toHaveBeenCalledWith('file1.txt')
})
})
describe('rename', () => {
it('should rename file', async () => {
const file = new UserFile('file1.txt', 123, 100)
;(api.moveUserData as jest.Mock).mockResolvedValue({
status: 200,
json: () => Promise.resolve({ modified: 456, size: 200 })
})
await file.rename('newfile.txt')
expect(api.moveUserData).toHaveBeenCalledWith(
'file1.txt',
'newfile.txt'
)
expect(file.path).toBe('newfile.txt')
expect(file.lastModified).toBe(456)
expect(file.size).toBe(200)
})
})
describe('saveAs', () => {
it('should save file with new path', async () => {
const file = new UserFile('file1.txt', 123, 100)
file.content = 'file content'
;(api.storeUserData as jest.Mock).mockResolvedValue({
status: 200,
json: () => Promise.resolve({ modified: 456, size: 200 })
})
const newFile = await file.saveAs('newfile.txt')
expect(api.storeUserData).toHaveBeenCalledWith(
'newfile.txt',
'file content',
{ throwOnError: true, full_info: true }
)
expect(newFile).toBeInstanceOf(TempUserFile)
expect(newFile.path).toBe('newfile.txt')
expect(newFile.lastModified).toBe(456)
expect(newFile.size).toBe(200)
expect(newFile.content).toBe('file content')
})
})
})
})