import { describe, expect, it } from 'vitest'; import { root } from '../../../../src/element-template/index.js'; import { ElementTemplateUpdateOps } from '../../../../src/element-template/protocol/opcodes.js'; import type { ElementTemplateUpdateCommandStream } from '../../../../src/element-template/protocol/types.js'; import { formatUpdateStream, runElementTemplateUpdate } from './updateRunner.js'; describe('element-template update runner', () => { it('formats update stream entries', () => { const stream: ElementTemplateUpdateCommandStream = [ ElementTemplateUpdateOps.createTemplate, 1, '_et_builtin_raw_text', null, ['hello'], [], ElementTemplateUpdateOps.setAttribute, 2, 3, 'next', ElementTemplateUpdateOps.setMainThreadEvent, 2, 4, { type: 'worklet' }, ElementTemplateUpdateOps.setMainThreadRef, 2, 5, { type: 'main-thread-ref' }, ElementTemplateUpdateOps.createTypedElement, 8, 'list', { id: 'typed-list' }, [[1]], { listChildren: [{ __etHandleRef: 1 }] }, ElementTemplateUpdateOps.setAttribute, 8, 0, { insertAction: [] }, ElementTemplateUpdateOps.insertTypedListItem, 8, { __etHandleRef: 2, type: '_et_item', platformInfo: { 'item-key': 'b' } }, 1, ElementTemplateUpdateOps.removeTypedListItem, 8, 1, [1], ElementTemplateUpdateOps.updateTypedListItem, 8, { __etHandleRef: 2, type: '_et_item', platformInfo: { 'item-key': 'c' } }, ElementTemplateUpdateOps.removeNode, 4, 5, 6, [6, 7], ]; expect(formatUpdateStream(stream)).toEqual([ { type: 'create', id: 1, template: '_et_builtin_raw_text', attributeSlots: ['hello'], childSlots: [], }, { type: 'setAttribute', id: 2, attrSlotIndex: 3, value: 'next', }, { type: 'setMainThreadEvent', id: 2, attrSlotIndex: 4, value: { type: 'worklet' }, }, { type: 'setMainThreadRef', id: 2, attrSlotIndex: 5, value: { type: 'main-thread-ref' }, }, { type: 'createTypedElement', id: 8, elementType: 'list', attributes: { id: 'typed-list' }, childSlots: [[1]], options: { listChildren: [{ __etHandleRef: 1 }] }, }, { type: 'setAttribute', id: 8, attrSlotIndex: 0, value: { insertAction: [] }, }, { type: 'insertTypedListItem', id: 8, item: { __etHandleRef: 2, type: '_et_item', platformInfo: { 'item-key': 'b' } }, before: 1, }, { type: 'removeTypedListItem', id: 8, item: 1, removedSubtreeHandleIds: [1], }, { type: 'updateTypedListItem', id: 8, item: { __etHandleRef: 2, type: '_et_item', platformInfo: { 'item-key': 'c' } }, }, { type: 'removeNode', id: 4, childSlotIndex: 5, child: 6, removedSubtreeHandleIds: [6, 7], }, ]); }); it('collects update output and patch formatting state', () => { let label = 'before'; function App() { return ; } const result = runElementTemplateUpdate({ render: () => , update: () => { label = 'after'; root.render(); }, }); expect(result.beforePageJsx).toContain('"before"'); expect(result.afterPageJsx).toContain('"after"'); expect(result.formattedOps).toHaveLength(1); expect(result.formattedOps[0]).toMatchObject({ type: 'setAttribute', attrSlotIndex: 0, value: { 0: { id: 'after' } }, }); }); });