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 { computeAllLayouts } from '@open-pencil/core/layout'
|
||||||
|
|
||||||
import { getNodeOrThrow } from '#tests/helpers/assert'
|
import { getNodeOrThrow } from '#tests/helpers/assert'
|
||||||
import { autoFrame, rect } from '#tests/helpers/layout'
|
import { 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)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
describe('structure state actions', () => {
|
||||||
test('toggleNodeVisibility reflows HUG auto-layout instance slots', () => {
|
test('toggleNodeVisibility reflows HUG auto-layout instance slots', () => {
|
||||||
const editor = createEditor()
|
const editor = createEditor()
|
||||||
const page = editor.state.currentPageId
|
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(innerNode.height).toBe(50)
|
||||||
expect(children[1].x).toBe(0)
|
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 { 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'
|
import { autoFrame, pageId, rect } from '#tests/helpers/layout'
|
||||||
|
|
||||||
describe('vertical basic', () => {
|
describe('vertical basic', () => {
|
||||||
|
|
@ -43,4 +44,30 @@ describe('vertical basic', () => {
|
||||||
expect(children[1].y).toBe(56)
|
expect(children[1].y).toBe(56)
|
||||||
expect(children[2].y).toBe(112)
|
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