openpencil/packages/fig/tests/instance-overrides.test.ts
Danila Poyarkov 8b9be17a56 perf(fig): remove large fixture bottlenecks
- Index component property definitions and variable asset references once per export or override context\n- Skip converged instance fill and text propagation and use native binary hex encoding\n- Add a non-populating parse mode for raw fixture validation\n- Reduce the Material 3 round trip from minutes to about twenty seconds
2026-07-18 03:37:58 +03:00

68 lines
2.3 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { SceneGraph } from '@open-pencil/scene-graph'
import {
populateAndApplyOverrides,
protectField,
syncNodeProps,
type ProtectionMap
} from '../src/instance-overrides'
describe('@open-pencil/fig instance interpretation', () => {
test('populates an empty instance from its component tree', () => {
const graph = new SceneGraph()
const pageId = graph.getPages()[0].id
const component = graph.createNode('COMPONENT', pageId, { name: 'Button' })
graph.createNode('TEXT', component.id, { text: 'Label' })
const instance = graph.createNode('INSTANCE', pageId, {
componentId: component.id,
childIds: []
})
populateAndApplyOverrides(graph, new Map(), new Map())
const populated = graph.getNode(instance.id)
expect(populated?.childIds).toHaveLength(1)
expect(graph.getNode(populated?.childIds[0] ?? '')?.text).toBe('Label')
})
test('resolves text clone chains to their source values', () => {
const graph = new SceneGraph()
const pageId = graph.getPages()[0].id
const source = graph.createNode('TEXT', pageId, {
text: 'Label',
width: 80,
fills: [{ type: 'SOLID', color: { r: 1, g: 0, b: 0, a: 1 }, opacity: 1, visible: true }]
})
const middle = graph.createNode('TEXT', pageId, {
componentId: source.id,
text: 'Label',
width: 120
})
const leaf = graph.createNode('TEXT', pageId, {
componentId: middle.id,
text: 'Label',
width: 160
})
populateAndApplyOverrides(graph, new Map(), new Map())
expect(graph.getNode(middle.id)?.width).toBe(80)
expect(graph.getNode(leaf.id)).toMatchObject({ width: 80, fills: source.fills })
})
test('preserves protected text while synchronizing other fields', () => {
const graph = new SceneGraph()
const pageId = graph.getPages()[0].id
const source = graph.createNode('TEXT', pageId, { text: 'Source', visible: false })
const target = graph.createNode('TEXT', pageId, { text: 'Override', visible: true })
const protections: ProtectionMap = new Map()
protectField(protections, target.id, 'text')
syncNodeProps(graph, source, target, protections)
expect(graph.getNode(target.id)).toMatchObject({ text: 'Override', visible: false })
})
})