mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
224 lines
7.5 KiB
TypeScript
224 lines
7.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import type {
|
|
ComboInputSpec,
|
|
ComboInputSpecV2,
|
|
FloatInputSpec,
|
|
InputSpec,
|
|
IntInputSpec
|
|
} from '@/schemas/nodeDefSchema'
|
|
import { mergeInputSpec } from '@/utils/nodeDefUtil'
|
|
|
|
describe('nodeDefUtil', () => {
|
|
describe('mergeInputSpec', () => {
|
|
// Test numeric input specs (INT and FLOAT)
|
|
describe('numeric input specs', () => {
|
|
it('should merge INT specs with overlapping ranges', () => {
|
|
const spec1: IntInputSpec = ['INT', { min: 0, max: 10 }]
|
|
const spec2: IntInputSpec = ['INT', { min: 5, max: 15 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('INT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].min).toBe(5)
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].max).toBe(10)
|
|
})
|
|
|
|
it('should return null for INT specs with non-overlapping ranges', () => {
|
|
const spec1: IntInputSpec = ['INT', { min: 0, max: 5 }]
|
|
const spec2: IntInputSpec = ['INT', { min: 10, max: 15 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).toBeNull()
|
|
})
|
|
|
|
it('should merge FLOAT specs with overlapping ranges', () => {
|
|
const spec1: FloatInputSpec = ['FLOAT', { min: 0.5, max: 10.5 }]
|
|
const spec2: FloatInputSpec = ['FLOAT', { min: 5.5, max: 15.5 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('FLOAT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].min).toBe(5.5)
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].max).toBe(10.5)
|
|
})
|
|
|
|
it('should handle specs with undefined min/max values', () => {
|
|
const spec1: FloatInputSpec = ['FLOAT', { min: 0.5 }]
|
|
const spec2: FloatInputSpec = ['FLOAT', { max: 15.5 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('FLOAT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].min).toBe(0.5)
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].max).toBe(15.5)
|
|
})
|
|
|
|
it('should merge step values using least common multiple', () => {
|
|
const spec1: IntInputSpec = ['INT', { min: 0, max: 10, step: 2 }]
|
|
const spec2: IntInputSpec = ['INT', { min: 0, max: 10, step: 3 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('INT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].step).toBe(6) // LCM of 2 and 3 is 6
|
|
})
|
|
|
|
it('should use default step of 1 when step is not specified', () => {
|
|
const spec1: IntInputSpec = ['INT', { min: 0, max: 10 }]
|
|
const spec2: IntInputSpec = ['INT', { min: 0, max: 10, step: 4 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('INT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].step).toBe(4) // LCM of 1 and 4 is 4
|
|
})
|
|
|
|
it('should handle step values for FLOAT specs', () => {
|
|
const spec1: FloatInputSpec = ['FLOAT', { min: 0, max: 10, step: 0.5 }]
|
|
const spec2: FloatInputSpec = ['FLOAT', { min: 0, max: 10, step: 0.25 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('FLOAT')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].step).toBe(0.5)
|
|
})
|
|
})
|
|
|
|
// Test combo input specs
|
|
describe('combo input specs', () => {
|
|
it('should merge COMBO specs with overlapping options', () => {
|
|
const spec1: ComboInputSpecV2 = ['COMBO', { options: ['A', 'B', 'C'] }]
|
|
const spec2: ComboInputSpecV2 = ['COMBO', { options: ['B', 'C', 'D'] }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('COMBO')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].options).toEqual(['B', 'C'])
|
|
})
|
|
|
|
it('should return null for COMBO specs with no overlapping options', () => {
|
|
const spec1: ComboInputSpecV2 = ['COMBO', { options: ['A', 'B'] }]
|
|
const spec2: ComboInputSpecV2 = ['COMBO', { options: ['C', 'D'] }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).toBeNull()
|
|
})
|
|
|
|
it('should handle COMBO specs with additional properties', () => {
|
|
const spec1: ComboInputSpecV2 = [
|
|
'COMBO',
|
|
{
|
|
options: ['A', 'B', 'C'],
|
|
default: 'A',
|
|
tooltip: 'Select an option'
|
|
}
|
|
]
|
|
const spec2: ComboInputSpecV2 = [
|
|
'COMBO',
|
|
{
|
|
options: ['B', 'C', 'D'],
|
|
default: 'B',
|
|
multiline: true
|
|
}
|
|
]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('COMBO')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].options).toEqual(['B', 'C'])
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].default).toBe('B')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].tooltip).toBe('Select an option')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].multiline).toBe(true)
|
|
})
|
|
|
|
it('should handle v1 and v2 combo specs', () => {
|
|
const spec1: ComboInputSpec = [['A', 'B', 'C', 'D'], {}]
|
|
const spec2: ComboInputSpecV2 = ['COMBO', { options: ['C', 'D'] }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('COMBO')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].options).toEqual(['C', 'D'])
|
|
})
|
|
})
|
|
|
|
// Test common input spec behavior
|
|
describe('common input spec behavior', () => {
|
|
it('should return null for specs with different types', () => {
|
|
const spec1: IntInputSpec = ['INT', { min: 0, max: 10 }]
|
|
const spec2: ComboInputSpecV2 = ['COMBO', { options: ['A', 'B'] }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2 as unknown as IntInputSpec)
|
|
|
|
expect(result).toBeNull()
|
|
})
|
|
|
|
it('should ignore specified keys when comparing specs', () => {
|
|
const spec1: InputSpec = [
|
|
'STRING',
|
|
{
|
|
default: 'value1',
|
|
tooltip: 'Tooltip 1',
|
|
step: 1
|
|
}
|
|
]
|
|
const spec2: InputSpec = [
|
|
'STRING',
|
|
{
|
|
default: 'value2',
|
|
tooltip: 'Tooltip 2',
|
|
step: 1
|
|
}
|
|
]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).not.toBeNull()
|
|
expect(result?.[0]).toBe('STRING')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].default).toBe('value2')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].tooltip).toBe('Tooltip 2')
|
|
// @ts-expect-error fixme ts strict error
|
|
expect(result?.[1].step).toBe(1)
|
|
})
|
|
|
|
it('should return null if non-ignored properties differ', () => {
|
|
const spec1: InputSpec = ['STRING', { step: 1 }]
|
|
const spec2: InputSpec = ['STRING', { step: 2 }]
|
|
|
|
const result = mergeInputSpec(spec1, spec2)
|
|
|
|
expect(result).toBeNull()
|
|
})
|
|
})
|
|
})
|
|
})
|