mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 22:37:32 +00:00
Fix ColorPicker, further test cleanup
This commit is contained in:
@@ -17,7 +17,7 @@ describe('WidgetColorPicker Value Binding', () => {
|
||||
callback?: (value: string) => void
|
||||
): SimplifiedWidget<string> => {
|
||||
const valueRef = ref(value)
|
||||
if (callback) watch(valueRef, callback)
|
||||
if (callback) watch(valueRef, (v) => callback(v))
|
||||
return {
|
||||
name: 'test_color_picker',
|
||||
type: 'color',
|
||||
@@ -53,80 +53,61 @@ describe('WidgetColorPicker Value Binding', () => {
|
||||
) => {
|
||||
const colorPicker = wrapper.findComponent({ name: 'ColorPicker' })
|
||||
await colorPicker.setValue(value)
|
||||
return wrapper.emitted('update:modelValue')
|
||||
}
|
||||
|
||||
describe('Vue Event Emission', () => {
|
||||
it('emits Vue event when color changes', async () => {
|
||||
const widget = createMockWidget('#ff0000')
|
||||
describe('Value Binding', () => {
|
||||
it('triggers callback when color changes', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('#ff0000', {}, callback)
|
||||
const wrapper = mountComponent(widget, '#ff0000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, '#00ff00')
|
||||
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#00ff00')
|
||||
await setColorPickerValue(wrapper, '#00ff00')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#00ff00')
|
||||
})
|
||||
|
||||
it('handles different color formats', async () => {
|
||||
const widget = createMockWidget('#ffffff')
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('#ffffff', {}, callback)
|
||||
const wrapper = mountComponent(widget, '#ffffff')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, '#123abc')
|
||||
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#123abc')
|
||||
await setColorPickerValue(wrapper, '#123abc')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#123abc')
|
||||
})
|
||||
|
||||
it('handles missing callback gracefully', async () => {
|
||||
const widget = createMockWidget('#000000', {}, undefined)
|
||||
const wrapper = mountComponent(widget, '#000000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, '#ff00ff')
|
||||
|
||||
// Should still emit Vue event
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#ff00ff')
|
||||
})
|
||||
|
||||
it('normalizes bare hex without # to #hex on emit', async () => {
|
||||
const widget = createMockWidget('ff0000')
|
||||
it('normalizes bare hex without # to #hex', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('ff0000', {}, callback)
|
||||
const wrapper = mountComponent(widget, 'ff0000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, '00ff00')
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#00ff00')
|
||||
await setColorPickerValue(wrapper, '00ff00')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#00ff00')
|
||||
})
|
||||
|
||||
it('normalizes rgb() strings to #hex on emit', async (context) => {
|
||||
context.skip('needs diagnosis')
|
||||
const widget = createMockWidget('#000000')
|
||||
it('normalizes rgb() strings to #hex', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('#000000', { format: 'rgb' }, callback)
|
||||
const wrapper = mountComponent(widget, '#000000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, 'rgb(255, 0, 0)')
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#ff0000')
|
||||
await setColorPickerValue(wrapper, 'rgb(255, 0, 0)')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#ff0000')
|
||||
})
|
||||
|
||||
it('normalizes hsb() strings to #hex on emit', async () => {
|
||||
const widget = createMockWidget('#000000', { format: 'hsb' })
|
||||
it('normalizes hsb() strings to #hex', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('#000000', { format: 'hsb' }, callback)
|
||||
const wrapper = mountComponent(widget, '#000000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, 'hsb(120, 100, 100)')
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#00ff00')
|
||||
await setColorPickerValue(wrapper, 'hsb(120, 100, 100)')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#00ff00')
|
||||
})
|
||||
|
||||
it('normalizes HSB object values to #hex on emit', async () => {
|
||||
const widget = createMockWidget('#000000', { format: 'hsb' })
|
||||
it('normalizes HSB object values to #hex', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('#000000', { format: 'hsb' }, callback)
|
||||
const wrapper = mountComponent(widget, '#000000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, {
|
||||
h: 240,
|
||||
s: 100,
|
||||
b: 100
|
||||
})
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#0000ff')
|
||||
await setColorPickerValue(wrapper, { h: 240, s: 100, b: 100 })
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#0000ff')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -269,15 +250,15 @@ describe('WidgetColorPicker Value Binding', () => {
|
||||
})
|
||||
|
||||
it('handles invalid color formats gracefully', async () => {
|
||||
const widget = createMockWidget('invalid-color')
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('invalid-color', {}, callback)
|
||||
const wrapper = mountComponent(widget, 'invalid-color')
|
||||
|
||||
const colorText = wrapper.find('[data-testid="widget-color-text"]')
|
||||
expect(colorText.text()).toBe('#000000')
|
||||
|
||||
const emitted = await setColorPickerValue(wrapper, 'invalid-color')
|
||||
expect(emitted).toBeDefined()
|
||||
expect(emitted![0]).toContain('#000000')
|
||||
await setColorPickerValue(wrapper, 'invalid-color')
|
||||
expect(callback).toHaveBeenCalledExactlyOnceWith('#000000')
|
||||
})
|
||||
|
||||
it('handles widget with no options', () => {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
:pt="{
|
||||
preview: '!w-full !h-full !border-none'
|
||||
}"
|
||||
@update:model-value="onPickerUpdate"
|
||||
/>
|
||||
<span
|
||||
class="text-xs truncate min-w-[4ch]"
|
||||
@@ -27,11 +26,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import ColorPicker from 'primevue/colorpicker'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { isColorFormat, toHexFromFormat } from '@/utils/colorUtil'
|
||||
import type { ColorFormat, HSB } from '@/utils/colorUtil'
|
||||
import type { ColorFormat } from '@/utils/colorUtil'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
import {
|
||||
PANEL_EXCLUDED_PROPS,
|
||||
@@ -45,39 +44,23 @@ type WidgetOptions = { format?: ColorFormat } & Record<string, unknown>
|
||||
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<string, WidgetOptions>
|
||||
modelValue: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string]
|
||||
}>()
|
||||
const modelValue = props.widget.value()
|
||||
|
||||
const format = computed<ColorFormat>(() => {
|
||||
const optionFormat = props.widget.options?.format
|
||||
return isColorFormat(optionFormat) ? optionFormat : 'hex'
|
||||
})
|
||||
|
||||
type PickerValue = string | HSB
|
||||
const localValue = ref<PickerValue>(
|
||||
toHexFromFormat(
|
||||
props.modelValue || '#000000',
|
||||
isColorFormat(props.widget.options?.format)
|
||||
? props.widget.options.format
|
||||
: 'hex'
|
||||
)
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
localValue.value = toHexFromFormat(newVal || '#000000', format.value)
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return toHexFromFormat(modelValue.value || '#000000', format.value)
|
||||
},
|
||||
set(v) {
|
||||
modelValue.value = toHexFromFormat(v, format.value)
|
||||
}
|
||||
)
|
||||
|
||||
function onPickerUpdate(val: unknown) {
|
||||
localValue.value = val as PickerValue
|
||||
emit('update:modelValue', toHexFromFormat(val, format.value))
|
||||
}
|
||||
})
|
||||
|
||||
// ColorPicker specific excluded props include panel/overlay classes
|
||||
const COLOR_PICKER_EXCLUDED_PROPS = [...PANEL_EXCLUDED_PROPS] as const
|
||||
|
||||
@@ -51,7 +51,7 @@ describe('WidgetInputNumberInput Value Binding', () => {
|
||||
expect(input.value).toBe('42')
|
||||
})
|
||||
|
||||
it('emits update:modelValue when value changes', async () => {
|
||||
it('triggers callback when value changes', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget(10, 'int', {}, callback)
|
||||
const wrapper = mountComponent(widget, 10)
|
||||
|
||||
@@ -212,7 +212,7 @@ describe('WidgetMarkdown Dual Mode Display', () => {
|
||||
})
|
||||
|
||||
describe('Value Updates', () => {
|
||||
it('emits update:modelValue when textarea content changes', async () => {
|
||||
it('triggers callback when textarea content changes', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('# Original', {}, callback)
|
||||
const wrapper = mountComponent(widget, '# Original')
|
||||
|
||||
@@ -61,7 +61,7 @@ async function setTextareaValueAndTrigger(
|
||||
|
||||
describe('WidgetTextarea Value Binding', () => {
|
||||
describe('Widget Value Callbacks', () => {
|
||||
it('emits Vue event when textarea value changes on input', async () => {
|
||||
it('triggers callback when textarea value changes on input', async () => {
|
||||
const callback = vi.fn()
|
||||
const widget = createMockWidget('initial', {}, callback)
|
||||
const wrapper = mountComponent(widget, 'initial')
|
||||
|
||||
Reference in New Issue
Block a user