fix(scene-graph): validate reorder destinations

This commit is contained in:
Danila Poyarkov 2026-09-02 09:32:28 +03:00
parent 0027e24465
commit 418dc4f61c
2 changed files with 27 additions and 4 deletions

View file

@ -523,16 +523,16 @@ export class SceneGraph {
insertChildAt(childId: string, parentId: string, index: number): void {
const node = this.getNode(childId)
const previousParentId = node?.parentId ?? null
const newParent = this.getNode(parentId)
if (!node || !newParent) return
const previousParentId = node.parentId
const oldParent = previousParentId ? this.getNode(previousParentId) : undefined
if (oldParent) {
oldParent.childIds = oldParent.childIds.filter((id) => id !== childId)
}
const newParent = this.getNode(parentId)
if (!newParent) return
newParent.childIds = newParent.childIds.filter((id) => id !== childId)
newParent.childIds.splice(index, 0, childId)
if (node) node.parentId = parentId
node.parentId = parentId
this.clearAbsPosCache()
this.emitter.emit('node:reordered', childId, parentId, index, previousParentId)
}

View file

@ -54,6 +54,29 @@ describe('scene mutation impact', () => {
expect(impact.currentParentIds).toContain(right.id)
})
test('retains old and new parents when reorderChild transfers a node', async () => {
const { graph, left, right, child } = transferSetup()
const { impact } = await collectSceneMutation(graph, () =>
graph.reorderChild(child.id, right.id, 0)
)
expect(child.parentId).toBe(right.id)
expect(left.childIds).not.toContain(child.id)
expect(right.childIds).toContain(child.id)
expect(impact.previousParentIds).toContain(left.id)
expect(impact.currentParentIds).toContain(right.id)
})
test('does not detach insertChildAt targets when the destination is missing', () => {
const { graph, left, child } = transferSetup()
graph.insertChildAt(child.id, 'missing', 0)
expect(child.parentId).toBe(left.id)
expect(left.childIds).toContain(child.id)
})
test('retains old and new parents when insertChildAt transfers a node', async () => {
const { graph, left, right, child } = transferSetup()