Files
ComfyUI_frontend/tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts
Christian Byrne 316e05b8b9 [refactor] Reorganize Vue nodes to domain-driven design architecture (#5085)
* refactor: Reorganize Vue nodes system to domain-driven design architecture

Move Vue nodes code from scattered technical layers to domain-focused structure:

- Widget system → src/renderer/extensions/vueNodes/widgets/
- LOD optimization → src/renderer/extensions/vueNodes/lod/
- Layout logic → src/renderer/extensions/vueNodes/layout/
- Node components → src/renderer/extensions/vueNodes/components/
- Test structure mirrors source organization

Benefits:
- Clear domain boundaries instead of technical layers
- Everything Vue nodes related in renderer domain (not workbench)
- camelCase naming (vueNodes vs vue-nodes)
- Tests co-located with source domains
- All imports updated to new DDD structure

* fix: Skip spatial index performance test on CI to avoid flaky timing

Performance tests are inherently flaky on CI due to variable system
performance. This test should only run locally like the other
performance tests.
2025-08-18 16:58:45 -07:00

142 lines
5.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { useWidgetRenderer } from '@/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer'
import { WidgetType } from '@/renderer/extensions/vueNodes/widgets/registry/widgetRegistry'
describe('useWidgetRenderer', () => {
const { getWidgetComponent, shouldRenderAsVue } = useWidgetRenderer()
describe('getWidgetComponent', () => {
// Test number type mappings
describe('number types', () => {
it('should map number type to NUMBER widget', () => {
expect(getWidgetComponent('number')).toBe(WidgetType.NUMBER)
})
it('should map slider type to SLIDER widget', () => {
expect(getWidgetComponent('slider')).toBe(WidgetType.SLIDER)
})
it('should map INT type to INT widget', () => {
expect(getWidgetComponent('INT')).toBe(WidgetType.INT)
})
it('should map FLOAT type to FLOAT widget', () => {
expect(getWidgetComponent('FLOAT')).toBe(WidgetType.FLOAT)
})
})
// Test text type mappings
describe('text types', () => {
it('should map text variations to STRING widget', () => {
expect(getWidgetComponent('text')).toBe(WidgetType.STRING)
expect(getWidgetComponent('string')).toBe(WidgetType.STRING)
expect(getWidgetComponent('STRING')).toBe(WidgetType.STRING)
})
it('should map multiline text types to TEXTAREA widget', () => {
expect(getWidgetComponent('multiline')).toBe(WidgetType.TEXTAREA)
expect(getWidgetComponent('textarea')).toBe(WidgetType.TEXTAREA)
expect(getWidgetComponent('MARKDOWN')).toBe(WidgetType.MARKDOWN)
expect(getWidgetComponent('customtext')).toBe(WidgetType.TEXTAREA)
})
})
// Test selection type mappings
describe('selection types', () => {
it('should map combo types to COMBO widget', () => {
expect(getWidgetComponent('combo')).toBe(WidgetType.COMBO)
expect(getWidgetComponent('COMBO')).toBe(WidgetType.COMBO)
})
})
// Test boolean type mappings
describe('boolean types', () => {
it('should map boolean types to appropriate widgets', () => {
expect(getWidgetComponent('toggle')).toBe(WidgetType.TOGGLESWITCH)
expect(getWidgetComponent('boolean')).toBe(WidgetType.BOOLEAN)
expect(getWidgetComponent('BOOLEAN')).toBe(WidgetType.BOOLEAN)
})
})
// Test advanced widget mappings
describe('advanced widgets', () => {
it('should map color types to COLOR widget', () => {
expect(getWidgetComponent('color')).toBe(WidgetType.COLOR)
expect(getWidgetComponent('COLOR')).toBe(WidgetType.COLOR)
})
it('should map image types to IMAGE widget', () => {
expect(getWidgetComponent('image')).toBe(WidgetType.IMAGE)
expect(getWidgetComponent('IMAGE')).toBe(WidgetType.IMAGE)
})
it('should map file types to FILEUPLOAD widget', () => {
expect(getWidgetComponent('file')).toBe(WidgetType.FILEUPLOAD)
expect(getWidgetComponent('FILEUPLOAD')).toBe(WidgetType.FILEUPLOAD)
})
it('should map button types to BUTTON widget', () => {
expect(getWidgetComponent('button')).toBe(WidgetType.BUTTON)
expect(getWidgetComponent('BUTTON')).toBe(WidgetType.BUTTON)
})
})
// Test fallback behavior
describe('fallback behavior', () => {
it('should return STRING widget for unknown types', () => {
expect(getWidgetComponent('unknown')).toBe(WidgetType.STRING)
expect(getWidgetComponent('custom_widget')).toBe(WidgetType.STRING)
expect(getWidgetComponent('')).toBe(WidgetType.STRING)
})
it('should return STRING widget for unmapped but valid types', () => {
expect(getWidgetComponent('datetime')).toBe(WidgetType.STRING)
expect(getWidgetComponent('json')).toBe(WidgetType.STRING)
})
})
})
describe('shouldRenderAsVue', () => {
it('should return false for widgets marked as canvas-only', () => {
const widget = { type: 'text', options: { canvasOnly: true } }
expect(shouldRenderAsVue(widget)).toBe(false)
})
it('should return false for widgets without a type', () => {
const widget = { options: {} }
expect(shouldRenderAsVue(widget)).toBe(false)
})
it('should return true for widgets with mapped types', () => {
expect(shouldRenderAsVue({ type: 'text' })).toBe(true)
expect(shouldRenderAsVue({ type: 'number' })).toBe(true)
expect(shouldRenderAsVue({ type: 'combo' })).toBe(true)
})
it('should return true even for unknown types (fallback to STRING)', () => {
expect(shouldRenderAsVue({ type: 'unknown_type' })).toBe(true)
})
it('should respect options while checking type', () => {
const widget = { type: 'text', options: { someOption: 'value' } }
expect(shouldRenderAsVue(widget)).toBe(true)
})
})
describe('edge cases', () => {
it('should handle widgets with empty options', () => {
const widget = { type: 'text', options: {} }
expect(shouldRenderAsVue(widget)).toBe(true)
})
it('should handle case sensitivity correctly', () => {
// Test that both lowercase and uppercase work
expect(getWidgetComponent('string')).toBe(WidgetType.STRING)
expect(getWidgetComponent('STRING')).toBe(WidgetType.STRING)
expect(getWidgetComponent('combo')).toBe(WidgetType.COMBO)
expect(getWidgetComponent('COMBO')).toBe(WidgetType.COMBO)
})
})
})