openpencil/tests/engine/vue/controls/component-properties.test.ts
Danila Poyarkov 23645d5a2d feat(editor): add component property controls
- Model typed component definitions, references, assignments, and preferred swap values

- Add SDK-owned variant, text, boolean, and nested instance-swap controls with mixed-selection undo

- Preserve assignments across variant changes and component synchronization

- Round-trip component property metadata through .fig import and export
2026-07-17 21:59:49 +03:00

58 lines
1.8 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { SceneGraph } from '@open-pencil/scene-graph'
import {
MIXED,
compatibleComponentPropertyDefinitions,
instanceSwapOptions,
mergedComponentPropertyValue
} from '@open-pencil/vue'
describe('component property control model', () => {
test('requires identical ordered property IDs and types', () => {
const definitions = [
{ id: '1:1', name: 'Label', type: 'TEXT' as const, defaultValue: 'Default' },
{ id: '1:2', name: 'Visible', type: 'BOOLEAN' as const, defaultValue: 'true' }
]
expect(
compatibleComponentPropertyDefinitions([definitions, structuredClone(definitions)])
).toBe(definitions)
expect(
compatibleComponentPropertyDefinitions([
definitions,
[{ ...definitions[0], type: 'BOOLEAN' as const }]
])
).toEqual([])
})
test('models mixed values and preferred instance swap options', () => {
expect(mergedComponentPropertyValue(['A', 'A'])).toBe('A')
expect(mergedComponentPropertyValue(['A', 'B'])).toBe(MIXED)
const graph = new SceneGraph()
const pageId = graph.getPages()[0].id
const secondary = graph.createNode('COMPONENT', pageId, { name: 'Secondary' })
const preferred = graph.createNode('COMPONENT', pageId, {
name: 'Preferred',
componentKey: 'preferred-key'
})
expect(
instanceSwapOptions(
[secondary, preferred],
{
id: '1:3',
name: 'Icon',
type: 'INSTANCE_SWAP',
defaultValue: secondary.id,
preferredValues: ['preferred-key']
},
'missing-id'
)
).toEqual([
{ value: preferred.id, label: 'Preferred' },
{ value: secondary.id, label: 'Secondary' },
{ value: 'missing-id', label: 'missing-id', missing: true }
])
})
})