84 lines
3.2 KiB
TypeScript
84 lines
3.2 KiB
TypeScript
|
|
import { describe, expect, test } from 'bun:test'
|
|||
|
|
|
|||
|
|
import {
|
|||
|
|
OPEN_PENCIL_PLUGIN_DATA,
|
|||
|
|
OPEN_PENCIL_PLUGIN_ID,
|
|||
|
|
readAllPluginData,
|
|||
|
|
readPluginData,
|
|||
|
|
SceneGraph,
|
|||
|
|
withPluginData,
|
|||
|
|
type PluginDataEntry
|
|||
|
|
} from '@open-pencil/scene-graph'
|
|||
|
|
import {
|
|||
|
|
clearNodeFillOkHCL,
|
|||
|
|
getNodeOkHCLPayloads,
|
|||
|
|
setNodeFillOkHCL,
|
|||
|
|
setNodeStrokeOkHCL
|
|||
|
|
} from '@open-pencil/scene-graph/color'
|
|||
|
|
|
|||
|
|
const { exportSettings, okhcl, textDirection } = OPEN_PENCIL_PLUGIN_DATA
|
|||
|
|
const OTHER_PLUGIN: PluginDataEntry = { pluginId: 'other-plugin', key: 'okhcl', value: 'theirs' }
|
|||
|
|
|
|||
|
|
function entry(key: string, value: string): PluginDataEntry {
|
|||
|
|
return { pluginId: OPEN_PENCIL_PLUGIN_ID, key, value }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
describe('OpenPencil plugin data', () => {
|
|||
|
|
test('gives every field its own key', () => {
|
|||
|
|
const keys = Object.values(OPEN_PENCIL_PLUGIN_DATA).map((field) => field.key)
|
|||
|
|
expect(new Set(keys).size).toBe(keys.length)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
test('reads a value that is not JSON or has the wrong shape as missing', () => {
|
|||
|
|
for (const value of ['{not json', '{"scale":2}', '[{"scale":2,"format":"gif"}]']) {
|
|||
|
|
expect(readPluginData([entry('exportSettings', value)], exportSettings)).toBeUndefined()
|
|||
|
|
}
|
|||
|
|
expect(readPluginData([entry('textDirection', 'SIDEWAYS')], textDirection)).toBeUndefined()
|
|||
|
|
expect(readPluginData([entry('textDirection', 'RTL')], textDirection)).toBe('RTL')
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
test('ignores the same key written by another plugin', () => {
|
|||
|
|
const entries = [{ ...entry('textDirection', 'RTL'), pluginId: 'other-plugin' }]
|
|||
|
|
expect(readPluginData(entries, textDirection)).toBeUndefined()
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
test('replaces its own entry and keeps everything else', () => {
|
|||
|
|
const settings = [{ scale: 2, format: 'png' as const }]
|
|||
|
|
const entries = withPluginData(
|
|||
|
|
[entry('exportSettings', '[]'), OTHER_PLUGIN, entry('textDirection', 'LTR')],
|
|||
|
|
exportSettings,
|
|||
|
|
settings
|
|||
|
|
)
|
|||
|
|
expect(entries).toEqual([
|
|||
|
|
OTHER_PLUGIN,
|
|||
|
|
entry('textDirection', 'LTR'),
|
|||
|
|
entry('exportSettings', JSON.stringify(settings))
|
|||
|
|
])
|
|||
|
|
expect(readPluginData(entries, exportSettings)).toEqual(settings)
|
|||
|
|
expect(withPluginData(entries, exportSettings, undefined)).toEqual(entries.slice(0, 2))
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
test('picking an OkHCL color keeps the node’s other plugin data', () => {
|
|||
|
|
const graph = new SceneGraph()
|
|||
|
|
const paint = { type: 'SOLID' as const, visible: true, opacity: 1, color: { r: 1, g: 0, b: 0, a: 1 } }
|
|||
|
|
const node = graph.createNode('FRAME', graph.getPages()[0].id, {
|
|||
|
|
fills: [paint],
|
|||
|
|
strokes: [{ ...paint, weight: 1, align: 'INSIDE' as const }],
|
|||
|
|
pluginData: [OTHER_PLUGIN, entry('exportSettings', '[{"scale":1,"format":"png"}]')]
|
|||
|
|
})
|
|||
|
|
const color = { h: 30, c: 0.1, l: 0.6, a: 1 }
|
|||
|
|
|
|||
|
|
graph.updateNode(node.id, setNodeFillOkHCL(node, 0, color))
|
|||
|
|
graph.updateNode(node.id, setNodeStrokeOkHCL(node, 0, color))
|
|||
|
|
graph.updateNode(node.id, clearNodeFillOkHCL(node, 0))
|
|||
|
|
|
|||
|
|
const pluginData = graph.getNode(node.id)?.pluginData ?? []
|
|||
|
|
expect(pluginData.slice(0, 2)).toEqual([
|
|||
|
|
OTHER_PLUGIN,
|
|||
|
|
entry('exportSettings', '[{"scale":1,"format":"png"}]')
|
|||
|
|
])
|
|||
|
|
expect(readAllPluginData(pluginData, okhcl).map(({ kind }) => kind)).toEqual(['stroke'])
|
|||
|
|
expect(getNodeOkHCLPayloads({ ...node, pluginData })).toHaveLength(1)
|
|||
|
|
})
|
|||
|
|
})
|