- Move scene graph behavior tests into focused files - Share basic scene graph helper builders from basic/helpers.ts - Remove scene graph basic from max-lines exceptions
252 lines
6.5 KiB
TypeScript
252 lines
6.5 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
|
|
import { SceneGraph } from '@open-pencil/core'
|
|
|
|
describe('Variables', () => {
|
|
function pageId(graph: SceneGraph): string {
|
|
return graph.getPages()[0]?.id ?? ''
|
|
}
|
|
|
|
test('add and resolve color variable', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Colors',
|
|
modes: [{ modeId: 'm1', name: 'Light' }],
|
|
defaultModeId: 'm1',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'Primary',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { r: 0, g: 0.5, b: 1, a: 1 } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
const color = graph.resolveColorVariable('v1')
|
|
expect(color).toEqual({ r: 0, g: 0.5, b: 1, a: 1 })
|
|
})
|
|
|
|
test('resolve number variable', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Spacing',
|
|
modes: [{ modeId: 'm1', name: 'Default' }],
|
|
defaultModeId: 'm1',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'spacing/md',
|
|
type: 'FLOAT',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: 16 },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
expect(graph.resolveNumberVariable('v1')).toBe(16)
|
|
})
|
|
|
|
test('resolve alias variable', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Tokens',
|
|
modes: [{ modeId: 'm1', name: 'Light' }],
|
|
defaultModeId: 'm1',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'Blue/500',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { r: 0, g: 0, b: 1, a: 1 } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
graph.addVariable({
|
|
id: 'v2',
|
|
name: 'Primary',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { aliasId: 'v1' } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
expect(graph.resolveColorVariable('v2')).toEqual({ r: 0, g: 0, b: 1, a: 1 })
|
|
})
|
|
|
|
test('mode switching changes resolved value', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Theme',
|
|
modes: [
|
|
{ modeId: 'light', name: 'Light' },
|
|
{ modeId: 'dark', name: 'Dark' }
|
|
],
|
|
defaultModeId: 'light',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'bg',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: {
|
|
light: { r: 1, g: 1, b: 1, a: 1 },
|
|
dark: { r: 0, g: 0, b: 0, a: 1 }
|
|
},
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
expect(graph.resolveColorVariable('v1')).toEqual({ r: 1, g: 1, b: 1, a: 1 })
|
|
graph.setActiveMode('col1', 'dark')
|
|
expect(graph.resolveColorVariable('v1')).toEqual({ r: 0, g: 0, b: 0, a: 1 })
|
|
})
|
|
|
|
test('missing active mode falls back to default value', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Theme',
|
|
modes: [
|
|
{ modeId: 'light', name: 'Light' },
|
|
{ modeId: 'dark', name: 'Dark' }
|
|
],
|
|
defaultModeId: 'light',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'bg',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { light: { r: 1, g: 1, b: 1, a: 1 } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
graph.setActiveMode('col1', 'dark')
|
|
expect(graph.resolveColorVariable('v1')).toEqual({ r: 1, g: 1, b: 1, a: 1 })
|
|
})
|
|
|
|
test('explicit alias resolution preserves source mode', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Theme',
|
|
modes: [
|
|
{ modeId: 'light', name: 'Light' },
|
|
{ modeId: 'dark', name: 'Dark' }
|
|
],
|
|
defaultModeId: 'light',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'base',
|
|
name: 'base',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: {
|
|
light: { r: 1, g: 1, b: 1, a: 1 },
|
|
dark: { r: 0, g: 0, b: 0, a: 1 }
|
|
},
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
graph.addVariable({
|
|
id: 'alias',
|
|
name: 'alias',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: {
|
|
light: { aliasId: 'base' },
|
|
dark: { aliasId: 'base' }
|
|
},
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
expect(graph.resolveVariable('alias', 'dark')).toEqual({ r: 0, g: 0, b: 0, a: 1 })
|
|
})
|
|
|
|
test('bind and unbind variable to node', () => {
|
|
const graph = new SceneGraph()
|
|
const node = graph.createNode('RECTANGLE', pageId(graph), { name: 'Rect' })
|
|
|
|
graph.bindVariable(node.id, 'fills/0/color', 'v1')
|
|
expect(node.boundVariables['fills/0/color']).toBe('v1')
|
|
|
|
graph.unbindVariable(node.id, 'fills/0/color')
|
|
expect(node.boundVariables['fills/0/color']).toBeUndefined()
|
|
})
|
|
|
|
test('removing variable cleans up bindings', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Colors',
|
|
modes: [{ modeId: 'm1', name: 'Default' }],
|
|
defaultModeId: 'm1',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'Red',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { r: 1, g: 0, b: 0, a: 1 } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
const node = graph.createNode('RECTANGLE', pageId(graph), { name: 'Rect' })
|
|
graph.bindVariable(node.id, 'fills/0/color', 'v1')
|
|
expect(node.boundVariables['fills/0/color']).toBe('v1')
|
|
|
|
graph.removeVariable('v1')
|
|
expect(node.boundVariables['fills/0/color']).toBeUndefined()
|
|
expect(graph.variables.size).toBe(0)
|
|
})
|
|
|
|
test('circular alias does not infinite loop', () => {
|
|
const graph = new SceneGraph()
|
|
graph.addCollection({
|
|
id: 'col1',
|
|
name: 'Test',
|
|
modes: [{ modeId: 'm1', name: 'Default' }],
|
|
defaultModeId: 'm1',
|
|
variableIds: []
|
|
})
|
|
graph.addVariable({
|
|
id: 'v1',
|
|
name: 'A',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { aliasId: 'v2' } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
graph.addVariable({
|
|
id: 'v2',
|
|
name: 'B',
|
|
type: 'COLOR',
|
|
collectionId: 'col1',
|
|
valuesByMode: { m1: { aliasId: 'v1' } },
|
|
description: '',
|
|
hiddenFromPublishing: false
|
|
})
|
|
|
|
expect(graph.resolveColorVariable('v1')).toBeUndefined()
|
|
})
|
|
})
|