94 lines
4 KiB
TypeScript
94 lines
4 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
|
|
import { TRANSPARENT } from '@open-pencil/core/constants'
|
|
import { createEditor } from '@open-pencil/core/editor'
|
|
|
|
describe('booleanOperationSelected', () => {
|
|
test('wraps selected nodes in a boolean operation container', () => {
|
|
const editor = createEditor()
|
|
const pageId = editor.state.currentPageId
|
|
const first = editor.graph.createNode('RECTANGLE', pageId, { x: 10, y: 20, width: 30, height: 40 })
|
|
const second = editor.graph.createNode('ELLIPSE', pageId, { x: 80, y: 90, width: 20, height: 10 })
|
|
|
|
editor.select([first.id, second.id])
|
|
editor.booleanOperationSelected('UNION')
|
|
|
|
const [booleanId] = [...editor.state.selectedIds]
|
|
const booleanNode = editor.graph.getNode(booleanId)
|
|
expect(booleanNode?.type).toBe('BOOLEAN_OPERATION')
|
|
expect(booleanNode?.booleanOperation).toBe('UNION')
|
|
expect(booleanNode?.fills).toEqual(first.fills)
|
|
expect(booleanNode?.childIds).toEqual([first.id, second.id])
|
|
expect(editor.graph.getNode(first.id)?.parentId).toBe(booleanId)
|
|
expect(editor.graph.getNode(second.id)?.parentId).toBe(booleanId)
|
|
})
|
|
|
|
test('does not wrap unsupported text nodes', () => {
|
|
const editor = createEditor()
|
|
const pageId = editor.state.currentPageId
|
|
const first = editor.graph.createNode('TEXT', pageId, { text: 'Nope', fontFamily: 'Definitely Missing Font' })
|
|
const second = editor.graph.createNode('RECTANGLE', pageId)
|
|
|
|
editor.select([first.id, second.id])
|
|
const result = editor.booleanOperationSelected('UNION')
|
|
|
|
expect(result).toBeNull()
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([first.id, second.id])
|
|
expect(editor.state.selectedIds).toEqual(new Set([first.id, second.id]))
|
|
})
|
|
|
|
test('does not wrap complex script text without shaping support', () => {
|
|
const editor = createEditor()
|
|
const pageId = editor.state.currentPageId
|
|
const first = editor.graph.createNode('TEXT', pageId, {
|
|
text: 'مرحبا',
|
|
fontFamily: 'Inter'
|
|
})
|
|
const second = editor.graph.createNode('RECTANGLE', pageId)
|
|
|
|
editor.select([first.id, second.id])
|
|
const result = editor.booleanOperationSelected('UNION')
|
|
|
|
expect(result).toBeNull()
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([first.id, second.id])
|
|
})
|
|
|
|
test('does not wrap visible image fills', () => {
|
|
const editor = createEditor()
|
|
const pageId = editor.state.currentPageId
|
|
const first = editor.graph.createNode('RECTANGLE', pageId, {
|
|
fills: [{ type: 'IMAGE', imageHash: 'image', imageScaleMode: 'FILL', color: TRANSPARENT, opacity: 1, visible: true }]
|
|
})
|
|
const second = editor.graph.createNode('RECTANGLE', pageId)
|
|
|
|
editor.select([first.id, second.id])
|
|
const result = editor.booleanOperationSelected('UNION')
|
|
|
|
expect(result).toBeNull()
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([first.id, second.id])
|
|
})
|
|
|
|
test('undo and redo preserve parent order and selection', () => {
|
|
const editor = createEditor()
|
|
const pageId = editor.state.currentPageId
|
|
const before = editor.graph.createNode('RECTANGLE', pageId, { name: 'Before' })
|
|
const first = editor.graph.createNode('RECTANGLE', pageId, { name: 'First' })
|
|
const second = editor.graph.createNode('ELLIPSE', pageId, { name: 'Second' })
|
|
const after = editor.graph.createNode('RECTANGLE', pageId, { name: 'After' })
|
|
|
|
editor.select([first.id, second.id])
|
|
editor.booleanOperationSelected('EXCLUDE')
|
|
const [booleanId] = [...editor.state.selectedIds]
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([before.id, booleanId, after.id])
|
|
|
|
editor.undo.undo()
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([before.id, first.id, second.id, after.id])
|
|
expect(editor.state.selectedIds).toEqual(new Set([first.id, second.id]))
|
|
|
|
editor.undo.redo()
|
|
expect(editor.graph.getNode(pageId)?.childIds).toEqual([before.id, booleanId, after.id])
|
|
expect(editor.graph.getNode(booleanId)?.booleanOperation).toBe('EXCLUDE')
|
|
expect(editor.state.selectedIds).toEqual(new Set([booleanId]))
|
|
})
|
|
})
|