test(layout): place auto-layout reflow cases by domain
This commit is contained in:
parent
d522dc0529
commit
ddb46af32f
31
tests/engine/editor/clipboard/delete.test.ts
Normal file
31
tests/engine/editor/clipboard/delete.test.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { createEditor } from '@open-pencil/core/editor'
|
||||
import { computeAllLayouts } from '@open-pencil/core/layout'
|
||||
|
||||
import { getNodeOrThrow } from '#tests/helpers/assert'
|
||||
import { autoFrame, rect } from '#tests/helpers/layout'
|
||||
|
||||
describe('deleteSelected', () => {
|
||||
test('reflows fixed vertical auto-layout siblings', () => {
|
||||
const editor = createEditor()
|
||||
const page = editor.state.currentPageId
|
||||
const frame = autoFrame(editor.graph, page, {
|
||||
layoutMode: 'VERTICAL',
|
||||
width: 300,
|
||||
height: 300,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(editor.graph, frame.id, 300, 40)
|
||||
const body = rect(editor.graph, frame.id, 300, 100, { layoutGrow: 1 })
|
||||
const footerA = rect(editor.graph, frame.id, 300, 40)
|
||||
const footerB = rect(editor.graph, frame.id, 300, 40)
|
||||
computeAllLayouts(editor.graph, page)
|
||||
|
||||
editor.select([footerB.id])
|
||||
editor.deleteSelected()
|
||||
|
||||
expect(getNodeOrThrow(editor.graph, body.id).height).toBe(220)
|
||||
expect(getNodeOrThrow(editor.graph, footerA.id).y).toBe(260)
|
||||
})
|
||||
})
|
||||
|
|
@ -4,31 +4,9 @@ import { createEditor } from '@open-pencil/core/editor'
|
|||
import { computeAllLayouts } from '@open-pencil/core/layout'
|
||||
|
||||
import { getNodeOrThrow } from '#tests/helpers/assert'
|
||||
import { autoFrame, rect } from '#tests/helpers/layout'
|
||||
|
||||
describe('editor auto-layout reflow', () => {
|
||||
test('deleteSelected reflows fixed vertical auto-layout siblings', () => {
|
||||
const editor = createEditor()
|
||||
const page = editor.state.currentPageId
|
||||
const frame = autoFrame(editor.graph, page, {
|
||||
layoutMode: 'VERTICAL',
|
||||
width: 300,
|
||||
height: 300,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(editor.graph, frame.id, 300, 40)
|
||||
const body = rect(editor.graph, frame.id, 300, 100, { layoutGrow: 1 })
|
||||
const footerA = rect(editor.graph, frame.id, 300, 40)
|
||||
const footerB = rect(editor.graph, frame.id, 300, 40)
|
||||
computeAllLayouts(editor.graph, page)
|
||||
|
||||
editor.select([footerB.id])
|
||||
editor.deleteSelected()
|
||||
|
||||
expect(getNodeOrThrow(editor.graph, body.id).height).toBe(220)
|
||||
expect(getNodeOrThrow(editor.graph, footerA.id).y).toBe(260)
|
||||
})
|
||||
import { rect } from '#tests/helpers/layout'
|
||||
|
||||
describe('structure state actions', () => {
|
||||
test('toggleNodeVisibility reflows HUG auto-layout instance slots', () => {
|
||||
const editor = createEditor()
|
||||
const page = editor.state.currentPageId
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { computeAllLayouts, SceneGraph } from '@open-pencil/core'
|
||||
|
||||
import { getNodeOrThrow } from '#tests/helpers/assert'
|
||||
import { autoFrame, pageId, rect } from '#tests/helpers/layout'
|
||||
|
||||
describe('Figma auto-layout oracle regressions', () => {
|
||||
test('deleting a trailing child reflows fill siblings in fixed vertical auto-layout', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = pageId(graph)
|
||||
const frame = autoFrame(graph, page, {
|
||||
layoutMode: 'VERTICAL',
|
||||
width: 300,
|
||||
height: 300,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(graph, frame.id, 300, 40, { name: 'header h40' })
|
||||
const body = rect(graph, frame.id, 300, 100, { name: 'body fill', layoutGrow: 1 })
|
||||
const footerA = rect(graph, frame.id, 300, 40, { name: 'footerA h40' })
|
||||
const footerB = rect(graph, frame.id, 300, 40, { name: 'footerB h40' })
|
||||
|
||||
computeAllLayouts(graph, page)
|
||||
expect(getNodeOrThrow(graph, body.id).height).toBe(180)
|
||||
expect(getNodeOrThrow(graph, footerA.id).y).toBe(220)
|
||||
|
||||
graph.deleteNode(footerB.id)
|
||||
computeAllLayouts(graph, page)
|
||||
|
||||
expect(getNodeOrThrow(graph, body.id).height).toBe(220)
|
||||
expect(getNodeOrThrow(graph, footerA.id).y).toBe(260)
|
||||
expect(getNodeOrThrow(graph, frame.id).height).toBe(300)
|
||||
})
|
||||
|
||||
test('hidden child in HUG auto-layout instance is excluded from layout', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = pageId(graph)
|
||||
const component = graph.createNode('COMPONENT', page, {
|
||||
name: 'Optional slot component',
|
||||
layoutMode: 'VERTICAL',
|
||||
primaryAxisSizing: 'HUG',
|
||||
counterAxisSizing: 'FIXED',
|
||||
width: 300,
|
||||
height: 1,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(graph, component.id, 300, 40, { name: 'Slot / Pinned at Top' })
|
||||
rect(graph, component.id, 300, 74, { name: 'Slot / Content' })
|
||||
rect(graph, component.id, 300, 40, { name: 'Slot / Pinned at Bottom' })
|
||||
const instance = graph.createInstance(component.id, page, { x: 360, y: 0 })
|
||||
if (!instance) throw new Error('Expected instance to be created')
|
||||
|
||||
computeAllLayouts(graph, page)
|
||||
expect(getNodeOrThrow(graph, instance.id).height).toBe(154)
|
||||
const content = graph.getChildren(instance.id).find((child) => child.name === 'Slot / Content')
|
||||
const bottom = graph
|
||||
.getChildren(instance.id)
|
||||
.find((child) => child.name === 'Slot / Pinned at Bottom')
|
||||
if (!content || !bottom) throw new Error('Expected instance slot children')
|
||||
expect(getNodeOrThrow(graph, bottom.id).y).toBe(114)
|
||||
|
||||
graph.updateNode(content.id, { visible: false })
|
||||
computeAllLayouts(graph, page)
|
||||
|
||||
expect(getNodeOrThrow(graph, instance.id).height).toBe(80)
|
||||
expect(getNodeOrThrow(graph, bottom.id).y).toBe(40)
|
||||
expect(getNodeOrThrow(graph, content.id).height).toBe(74)
|
||||
})
|
||||
})
|
||||
|
|
@ -87,4 +87,39 @@ describe('hidden children', () => {
|
|||
expect(innerNode.height).toBe(50)
|
||||
expect(children[1].x).toBe(0)
|
||||
})
|
||||
|
||||
test('hidden children in HUG auto-layout instances collapse layout', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = pageId(graph)
|
||||
const component = graph.createNode('COMPONENT', page, {
|
||||
name: 'Optional slot component',
|
||||
layoutMode: 'VERTICAL',
|
||||
primaryAxisSizing: 'HUG',
|
||||
counterAxisSizing: 'FIXED',
|
||||
width: 300,
|
||||
height: 1,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(graph, component.id, 300, 40, { name: 'Slot / Pinned at Top' })
|
||||
rect(graph, component.id, 300, 74, { name: 'Slot / Content' })
|
||||
rect(graph, component.id, 300, 40, { name: 'Slot / Pinned at Bottom' })
|
||||
const instance = graph.createInstance(component.id, page, { x: 360, y: 0 })
|
||||
if (!instance) throw new Error('Expected instance to be created')
|
||||
|
||||
computeLayout(graph, instance.id)
|
||||
expect(getNodeOrThrow(graph, instance.id).height).toBe(154)
|
||||
const content = graph.getChildren(instance.id).find((child) => child.name === 'Slot / Content')
|
||||
const bottom = graph
|
||||
.getChildren(instance.id)
|
||||
.find((child) => child.name === 'Slot / Pinned at Bottom')
|
||||
if (!content || !bottom) throw new Error('Expected instance slot children')
|
||||
expect(getNodeOrThrow(graph, bottom.id).y).toBe(114)
|
||||
|
||||
graph.updateNode(content.id, { visible: false })
|
||||
computeLayout(graph, instance.id)
|
||||
|
||||
expect(getNodeOrThrow(graph, instance.id).height).toBe(80)
|
||||
expect(getNodeOrThrow(graph, bottom.id).y).toBe(40)
|
||||
expect(getNodeOrThrow(graph, content.id).height).toBe(74)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { computeLayout, SceneGraph } from '@open-pencil/core'
|
||||
import { computeAllLayouts, computeLayout, SceneGraph } from '@open-pencil/core'
|
||||
|
||||
import { getNodeOrThrow } from '#tests/helpers/assert'
|
||||
import { autoFrame, pageId, rect } from '#tests/helpers/layout'
|
||||
|
||||
describe('vertical basic', () => {
|
||||
|
|
@ -43,4 +44,30 @@ describe('vertical basic', () => {
|
|||
expect(children[1].y).toBe(56)
|
||||
expect(children[2].y).toBe(112)
|
||||
})
|
||||
|
||||
test('deleting a trailing child reflows fill siblings in fixed vertical auto-layout', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = pageId(graph)
|
||||
const frame = autoFrame(graph, page, {
|
||||
layoutMode: 'VERTICAL',
|
||||
width: 300,
|
||||
height: 300,
|
||||
itemSpacing: 0
|
||||
})
|
||||
rect(graph, frame.id, 300, 40, { name: 'header h40' })
|
||||
const body = rect(graph, frame.id, 300, 100, { name: 'body fill', layoutGrow: 1 })
|
||||
const footerA = rect(graph, frame.id, 300, 40, { name: 'footerA h40' })
|
||||
const footerB = rect(graph, frame.id, 300, 40, { name: 'footerB h40' })
|
||||
|
||||
computeAllLayouts(graph, page)
|
||||
expect(getNodeOrThrow(graph, body.id).height).toBe(180)
|
||||
expect(getNodeOrThrow(graph, footerA.id).y).toBe(220)
|
||||
|
||||
graph.deleteNode(footerB.id)
|
||||
computeAllLayouts(graph, page)
|
||||
|
||||
expect(getNodeOrThrow(graph, body.id).height).toBe(220)
|
||||
expect(getNodeOrThrow(graph, footerA.id).y).toBe(260)
|
||||
expect(getNodeOrThrow(graph, frame.id).height).toBe(300)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue