Move setting impl from ComfySettingsDialog to settingStore (#2085)

This commit is contained in:
Chenlei Hu
2024-12-28 21:31:09 -05:00
committed by GitHub
parent 5152985656
commit a48ad1cb41
10 changed files with 299 additions and 188 deletions

View File

@@ -0,0 +1,141 @@
import { setActivePinia, createPinia } from 'pinia'
import { useSettingStore } from '@/stores/settingStore'
import { api } from '@/scripts/api'
import type { SettingParams } from '@/types/settingTypes'
// Mock the api
jest.mock('@/scripts/api', () => ({
api: {
getSettings: jest.fn(),
storeSetting: jest.fn()
}
}))
// Mock the app
jest.mock('@/scripts/app', () => ({
app: {
ui: {
settings: {
dispatchChange: jest.fn()
}
}
}
}))
describe('useSettingStore', () => {
let store: ReturnType<typeof useSettingStore>
beforeEach(() => {
setActivePinia(createPinia())
store = useSettingStore()
jest.clearAllMocks()
})
it('should initialize with empty settings', () => {
expect(store.settingValues).toEqual({})
expect(store.settingsById).toEqual({})
expect(store.settingTree.children).toEqual([])
})
describe('loadSettingValues', () => {
it('should load settings from API', async () => {
const mockSettings = { 'test.setting': 'value' }
;(api.getSettings as jest.Mock).mockResolvedValue(mockSettings)
await store.loadSettingValues()
expect(store.settingValues).toEqual(mockSettings)
expect(api.getSettings).toHaveBeenCalled()
})
it('should throw error if settings are loaded after registration', async () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default'
}
store.addSetting(setting)
await expect(store.loadSettingValues()).rejects.toThrow(
'Setting values must be loaded before any setting is registered.'
)
})
})
describe('addSetting', () => {
it('should register a new setting', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default'
}
store.addSetting(setting)
expect(store.settingsById['test.setting']).toEqual(setting)
})
it('should throw error for duplicate setting ID', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default'
}
store.addSetting(setting)
expect(() => store.addSetting(setting)).toThrow(
'Setting test.setting must have a unique ID.'
)
})
it('should migrate deprecated values', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default',
migrateDeprecatedValue: (value: string) => value.toUpperCase()
}
store.settingValues['test.setting'] = 'oldvalue'
store.addSetting(setting)
expect(store.settingValues['test.setting']).toBe('OLDVALUE')
})
})
describe('get and set', () => {
it('should get default value when setting not exists', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default'
}
store.addSetting(setting)
expect(store.get('test.setting')).toBe('default')
})
it('should set value and trigger onChange', async () => {
const onChangeMock = jest.fn()
const setting: SettingParams = {
id: 'test.setting',
name: 'test.setting',
type: 'text',
defaultValue: 'default',
onChange: onChangeMock
}
store.addSetting(setting)
await store.set('test.setting', 'newvalue')
expect(store.get('test.setting')).toBe('newvalue')
expect(onChangeMock).toHaveBeenCalledWith('newvalue')
expect(api.storeSetting).toHaveBeenCalledWith('test.setting', 'newvalue')
})
})
})

View File

@@ -1,5 +1,5 @@
// @ts-strict-ignore
import { APIConfig, mockApi, mockSettingStore, mockNodeDefStore } from './setup'
import { APIConfig, mockApi, mockNodeDefStore } from './setup'
import { Ez, EzGraph, EzNameSpace } from './ezgraph'
import lg from './litegraph'
import fs from 'fs'
@@ -41,10 +41,7 @@ export async function start(config: StartConfig = {}): Promise<StartResult> {
document.body.innerHTML = html.toString()
mockApi(config)
mockSettingStore()
const { app } = await import('../../src/scripts/app')
const { useSettingStore } = await import('../../src/stores/settingStore')
useSettingStore().addSettings(app.ui.settings)
mockNodeDefStore()
const { LiteGraph, LGraphCanvas } = await import('@comfyorg/litegraph')

View File

@@ -1,6 +1,4 @@
// @ts-strict-ignore
import type { ComfySettingsDialog } from '@/scripts/ui/settings'
import type { ComfyApp } from '@/scripts/app'
import '../../src/scripts/api'
import { ComfyNodeDef } from '@/types/apiTypes'
@@ -98,31 +96,6 @@ export function mockApi(config: APIConfig = {}) {
}))
}
export const mockSettingStore = () => {
let app: ComfyApp | null = null
const mockedSettingStore = {
addSettings(settings: ComfySettingsDialog) {
app = settings.app
},
set(key: string, value: any) {
app?.ui.settings.setSettingValue(key, value)
},
get(key: string) {
return (
app?.ui.settings.getSettingValue(key) ??
app?.ui.settings.getSettingDefaultValue(key)
)
}
}
jest.mock('@/stores/settingStore', () => ({
useSettingStore: jest.fn(() => mockedSettingStore)
}))
}
export const mockNodeDefStore = () => {
const mockedNodeDefStore = {
addNodeDef: jest.fn((nodeDef: ComfyNodeDef) => {})