refactor: extract shared createMockWidget factory for widget component tests (#9423)

## Summary

Extract a shared `createMockWidget` test factory to eliminate duplicated
`SimplifiedWidget` object construction across 13 widget component test
files.

## Changes

- **What**: Add `widgetTestUtils.ts` with a generic
`createMockWidget<T>` factory providing sensible defaults (`name`,
`type`, `options`). Refactor 13 test files to delegate to it via thin
local wrappers that supply component-specific defaults (combo values,
slider ranges, etc.).

## Review Focus

- The shared factory only covers `SimplifiedWidget`-based tests. Three
files using different base types (`NodeWidgets.test.ts`,
`useRemoteWidget.test.ts`, `useComboWidget.test.ts`) are intentionally
excluded.
- `mountComponent` helpers remain per-file since plugin/component setups
vary too much to share.

Fixes #5554

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9423-refactor-extract-shared-createMockWidget-factory-for-widget-component-tests-31a6d73d36508159b65ee0e7b49212c3)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Christian Byrne
2026-03-05 15:39:41 -08:00
committed by GitHub
parent df69d6b5d4
commit b2915ed42a
14 changed files with 396 additions and 333 deletions

View File

@@ -13,6 +13,7 @@ import type { ComboInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import WidgetSelectDropdown from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelectDropdown.vue'
import { createMockWidget } from './widgetTestUtils'
const mockAssetsData = vi.hoisted(() => ({ items: [] as AssetItem[] }))
vi.mock(
@@ -42,23 +43,24 @@ interface WidgetSelectDropdownInstance extends ComponentPublicInstance {
}
describe('WidgetSelectDropdown custom label mapping', () => {
const createMockWidget = (
const createSelectDropdownWidget = (
value: string = 'img_001.png',
options: {
values?: string[]
getOptionLabel?: (value?: string | null) => string
} = {},
spec?: ComboInputSpec
): SimplifiedWidget<string | undefined> => ({
name: 'test_image_select',
type: 'combo',
value,
options: {
values: ['img_001.png', 'photo_abc.jpg', 'hash789.png'],
...options
},
spec
})
) =>
createMockWidget<string | undefined>({
value,
name: 'test_image_select',
type: 'combo',
options: {
values: ['img_001.png', 'photo_abc.jpg', 'hash789.png'],
...options
},
spec
})
const mountComponent = (
widget: SimplifiedWidget<string | undefined>,
@@ -81,7 +83,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
describe('when custom labels are not provided', () => {
it('uses values as labels when no mapping provided', () => {
const widget = createMockWidget('img_001.png')
const widget = createSelectDropdownWidget('img_001.png')
const wrapper = mountComponent(widget, 'img_001.png')
const inputItems = wrapper.vm.inputItems
@@ -107,7 +109,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
return mapping[value] || value
})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -132,7 +134,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
return `Custom: ${value}`
})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -160,7 +162,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
.spyOn(console, 'error')
.mockImplementation(() => {})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -185,7 +187,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
return `Labeled: ${value}`
})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -207,7 +209,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
return `Labeled: ${value}`
})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -229,7 +231,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
return `Output: ${value}`
})
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
getOptionLabel
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -242,7 +244,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
describe('missing value handling for template-loaded nodes', () => {
it('creates a fallback item in "all" filter when modelValue is not in available items', () => {
const widget = createMockWidget('template_image.png', {
const widget = createSelectDropdownWidget('template_image.png', {
values: ['img_001.png', 'photo_abc.jpg']
})
const wrapper = mountComponent(widget, 'template_image.png')
@@ -263,7 +265,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
it('does not include fallback item when filter is "inputs"', async () => {
const widget = createMockWidget('template_image.png', {
const widget = createSelectDropdownWidget('template_image.png', {
values: ['img_001.png', 'photo_abc.jpg']
})
const wrapper = mountComponent(widget, 'template_image.png')
@@ -279,7 +281,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
it('does not include fallback item when filter is "outputs"', async () => {
const widget = createMockWidget('template_image.png', {
const widget = createSelectDropdownWidget('template_image.png', {
values: ['img_001.png', 'photo_abc.jpg']
})
const wrapper = mountComponent(widget, 'template_image.png')
@@ -295,7 +297,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
it('does not create a fallback item when modelValue exists in available items', () => {
const widget = createMockWidget('img_001.png', {
const widget = createSelectDropdownWidget('img_001.png', {
values: ['img_001.png', 'photo_abc.jpg']
})
const wrapper = mountComponent(widget, 'img_001.png')
@@ -308,9 +310,12 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
it('does not create a fallback item when modelValue is undefined', () => {
const widget = createMockWidget(undefined as unknown as string, {
values: ['img_001.png', 'photo_abc.jpg']
})
const widget = createSelectDropdownWidget(
undefined as unknown as string,
{
values: ['img_001.png', 'photo_abc.jpg']
}
)
const wrapper = mountComponent(widget, undefined)
const dropdownItems = wrapper.vm.dropdownItems