openpencil/tests/engine/io/fig/export/stroke-geometry.test.ts
Danila Poyarkov 2f8d799a5f feat(editor): add stroke geometry controls
- Add mixed-selection cap, join, and miter-limit controls with one-step undo
- Apply node miter limits across CanvasKit stroke paths and vector outline caches
- Preserve imported and edited stroke geometry through Plugin API and .fig roundtrips
2026-07-17 19:01:42 +03:00

59 lines
1.8 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { SceneGraph } from '@open-pencil/scene-graph'
import { sceneNodeToKiwi } from '#core/kiwi/fig/node-change/serialize'
function serializeMiterLimit(strokeMiterLimit: number, importedMiterLimit?: number) {
const graph = new SceneGraph()
const page = graph.getPages()[0]
const node = graph.createNode('VECTOR', page.id, { strokeMiterLimit })
if (importedMiterLimit !== undefined) {
graph.updateNode(node.id, {
source: {
...node.source,
id: '1:2',
fig: {
...node.source.fig,
rawNodeFields: { ...node.source.fig.rawNodeFields, miterLimit: importedMiterLimit }
}
}
})
}
const current = graph.getNode(node.id)
if (!current) throw new Error('Expected vector node')
return sceneNodeToKiwi(current, { sessionID: 1, localID: 1 }, 0, { value: 2 }, graph, [])[0]
.miterLimit
}
function serializeImportedDefaultJoin() {
const graph = new SceneGraph()
const page = graph.getPages()[0]
const node = graph.createNode('VECTOR', page.id, { strokeJoin: 'MITER' })
graph.updateNode(node.id, {
source: {
...node.source,
id: '1:2',
fig: {
...node.source.fig,
rawNodeFields: { ...node.source.fig.rawNodeFields, strokeJoin: 'BEVEL' }
}
}
})
const current = graph.getNode(node.id)
if (!current) throw new Error('Expected vector node')
return sceneNodeToKiwi(current, { sessionID: 1, localID: 1 }, 0, { value: 2 }, graph, [])[0]
.strokeJoin
}
describe('Figma stroke geometry export', () => {
test('exports non-default miter limits', () => {
expect(serializeMiterLimit(12)).toBe(12)
})
test('overrides stale imported raw values when edited back to the default', () => {
expect(serializeMiterLimit(4, 9)).toBe(4)
expect(serializeImportedDefaultJoin()).toBe('MITER')
})
})