mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-12 00:20:15 +00:00
## Summary Simplify default scripts. Filtering is still available to users, we can revisit tagging or grouping later. This fixes the issue where we had tests that were in the codebase but never run because they weren't under `/src/components` Also deletes the duplicate litegraph tests and their associated vitest config file. ## Changes - **What**: Test cleanup ## Review Focus ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5888-Tests-Vitest-configuration-cleanup-2806d73d36508197b800f68f0b028279) by [Unito](https://www.unito.io)
181 lines
5.6 KiB
TypeScript
181 lines
5.6 KiB
TypeScript
import { mount } from '@vue/test-utils'
|
|
import PrimeVue from 'primevue/config'
|
|
import InputText from 'primevue/inputtext'
|
|
import type { InputTextProps } from 'primevue/inputtext'
|
|
import Textarea from 'primevue/textarea'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
|
|
|
import WidgetInputText from './WidgetInputText.vue'
|
|
|
|
describe('WidgetInputText Value Binding', () => {
|
|
const createMockWidget = (
|
|
value: string = 'default',
|
|
options: Partial<InputTextProps> = {},
|
|
callback?: (value: string) => void
|
|
): SimplifiedWidget<string> => ({
|
|
name: 'test_input',
|
|
type: 'string',
|
|
value,
|
|
options,
|
|
callback
|
|
})
|
|
|
|
const mountComponent = (
|
|
widget: SimplifiedWidget<string>,
|
|
modelValue: string,
|
|
readonly = false
|
|
) => {
|
|
return mount(WidgetInputText, {
|
|
global: {
|
|
plugins: [PrimeVue],
|
|
components: { InputText, Textarea }
|
|
},
|
|
props: {
|
|
widget,
|
|
modelValue,
|
|
readonly
|
|
}
|
|
})
|
|
}
|
|
|
|
const setInputValueAndTrigger = async (
|
|
wrapper: ReturnType<typeof mount>,
|
|
value: string,
|
|
trigger: 'blur' | 'keydown.enter' = 'blur'
|
|
) => {
|
|
const input = wrapper.find('input[type="text"]')
|
|
if (!(input.element instanceof HTMLInputElement)) {
|
|
throw new Error('Input element not found or is not an HTMLInputElement')
|
|
}
|
|
await input.setValue(value)
|
|
await input.trigger(trigger)
|
|
return input
|
|
}
|
|
|
|
describe('Vue Event Emission', () => {
|
|
it('emits Vue event when input value changes on blur', async () => {
|
|
const widget = createMockWidget('hello')
|
|
const wrapper = mountComponent(widget, 'hello')
|
|
|
|
await setInputValueAndTrigger(wrapper, 'world', 'blur')
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('world')
|
|
})
|
|
|
|
it('emits Vue event when enter key is pressed', async () => {
|
|
const widget = createMockWidget('initial')
|
|
const wrapper = mountComponent(widget, 'initial')
|
|
|
|
await setInputValueAndTrigger(wrapper, 'new value', 'keydown.enter')
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('new value')
|
|
})
|
|
|
|
it('handles empty string values', async () => {
|
|
const widget = createMockWidget('something')
|
|
const wrapper = mountComponent(widget, 'something')
|
|
|
|
await setInputValueAndTrigger(wrapper, '')
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('')
|
|
})
|
|
|
|
it('handles special characters correctly', async () => {
|
|
const widget = createMockWidget('normal')
|
|
const wrapper = mountComponent(widget, 'normal')
|
|
|
|
const specialText = 'special @#$%^&*()[]{}|\\:";\'<>?,./'
|
|
await setInputValueAndTrigger(wrapper, specialText)
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain(specialText)
|
|
})
|
|
|
|
it('handles missing callback gracefully', async () => {
|
|
const widget = createMockWidget('test', {}, undefined)
|
|
const wrapper = mountComponent(widget, 'test')
|
|
|
|
await setInputValueAndTrigger(wrapper, 'new value')
|
|
|
|
// Should still emit Vue event
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('new value')
|
|
})
|
|
})
|
|
|
|
describe('User Interactions', () => {
|
|
it('emits update:modelValue on blur', async () => {
|
|
const widget = createMockWidget('original')
|
|
const wrapper = mountComponent(widget, 'original')
|
|
|
|
await setInputValueAndTrigger(wrapper, 'updated')
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('updated')
|
|
})
|
|
|
|
it('emits update:modelValue on enter key', async () => {
|
|
const widget = createMockWidget('start')
|
|
const wrapper = mountComponent(widget, 'start')
|
|
|
|
await setInputValueAndTrigger(wrapper, 'finish', 'keydown.enter')
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain('finish')
|
|
})
|
|
})
|
|
|
|
describe('Component Rendering', () => {
|
|
it('always renders InputText component', () => {
|
|
const widget = createMockWidget('test value')
|
|
const wrapper = mountComponent(widget, 'test value')
|
|
|
|
// WidgetInputText always uses InputText, not Textarea
|
|
const input = wrapper.find('input[type="text"]')
|
|
expect(input.exists()).toBe(true)
|
|
|
|
// Should not render textarea (that's handled by WidgetTextarea component)
|
|
const textarea = wrapper.find('textarea')
|
|
expect(textarea.exists()).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('Edge Cases', () => {
|
|
it('handles very long strings', async () => {
|
|
const widget = createMockWidget('short')
|
|
const wrapper = mountComponent(widget, 'short')
|
|
|
|
const longString = 'a'.repeat(10000)
|
|
await setInputValueAndTrigger(wrapper, longString)
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain(longString)
|
|
})
|
|
|
|
it('handles unicode characters', async () => {
|
|
const widget = createMockWidget('ascii')
|
|
const wrapper = mountComponent(widget, 'ascii')
|
|
|
|
const unicodeText = '🎨 Unicode: αβγ 中文 العربية 🚀'
|
|
await setInputValueAndTrigger(wrapper, unicodeText)
|
|
|
|
const emitted = wrapper.emitted('update:modelValue')
|
|
expect(emitted).toBeDefined()
|
|
expect(emitted![0]).toContain(unicodeText)
|
|
})
|
|
})
|
|
})
|