diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.test.ts b/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.test.ts new file mode 100644 index 0000000000..52121b8164 --- /dev/null +++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.test.ts @@ -0,0 +1,108 @@ +import { mount } from '@vue/test-utils' +import { nextTick } from 'vue' +import PrimeVue from 'primevue/config' +import { describe, expect, it } from 'vitest' + +import SelectPlus from '@/components/primevueOverride/SelectPlus.vue' +import type { SimplifiedWidget } from '@/types/simplifiedWidget' + +import WidgetSelectDefault from './WidgetSelectDefault.vue' + +describe('WidgetSelectDefault', () => { + const createWidget = ( + values: unknown + ): SimplifiedWidget => ({ + name: 'test_combo', + type: 'combo', + value: undefined, + options: { values } as SimplifiedWidget['options'] + }) + + const mountComponent = (widget: SimplifiedWidget) => + mount(WidgetSelectDefault, { + props: { widget }, + global: { + plugins: [PrimeVue], + components: { SelectPlus } + } + }) + + describe('array-valued options', () => { + it('resolves options from a plain array', () => { + const widget = createWidget(['a', 'b', 'c']) + const wrapper = mountComponent(widget) + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([ + 'a', + 'b', + 'c' + ]) + }) + + it('reactively updates when widget prop changes', async () => { + const widget = createWidget(['x', 'y']) + const wrapper = mountComponent(widget) + + await wrapper.setProps({ widget: createWidget(['x', 'y', 'z']) }) + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([ + 'x', + 'y', + 'z' + ]) + }) + }) + + describe('undefined/empty options', () => { + it('returns empty array when values is undefined', () => { + const widget = createWidget(undefined) + const wrapper = mountComponent(widget) + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([]) + }) + }) + + describe('function-valued options', () => { + it('resolves options from a function', () => { + const widget = createWidget(() => ['a', 'b', 'c']) + const wrapper = mountComponent(widget) + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([ + 'a', + 'b', + 'c' + ]) + }) + + it('re-evaluates function on show event', async () => { + let items = ['x', 'y'] + const widget = createWidget(() => items) + const wrapper = mountComponent(widget) + + items = ['x', 'y', 'z'] + wrapper.findComponent(SelectPlus).vm.$emit('show') + await nextTick() + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([ + 'x', + 'y', + 'z' + ]) + }) + + it('re-evaluates function on filter event', async () => { + let items = ['a'] + const widget = createWidget(() => items) + const wrapper = mountComponent(widget) + + items = ['a', 'b'] + wrapper.findComponent(SelectPlus).vm.$emit('filter') + await nextTick() + + expect(wrapper.findComponent(SelectPlus).props('options')).toEqual([ + 'a', + 'b' + ]) + }) + }) +}) diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue b/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue index 2803b57708..2fdf328cd2 100644 --- a/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue +++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue @@ -17,6 +17,8 @@ overlay: 'w-fit min-w-full' }" data-capture-wheel="true" + @show="refreshOptions" + @filter="refreshOptions" >