import { describe, expect, it } from 'vitest';
import { h, mount, mountCallback, nextTick, render } from '@/index';
describe('subtrees added during an update', () => {
it('resolves new keyed components and preserves slots, renew and lifecycle after moves', async () => {
let rows: number[] = [];
let renewList = () => {};
const mounted: number[] = [];
const unmounted: number[] = [];
const Child = mount<{ id: number; key: number }>(
(renew, props, children) => {
let clicks = 0;
mountCallback(() => {
mounted.push(props.id);
return () => unmounted.push(props.id);
});
return () => (
{
clicks++;
renew();
}}
>
{`${props.id}:${clicks}`}
{children}
);
}
);
const List = mount(renew => {
renewList = renew;
return () => (
{rows.map(id => (
{`slot-${id}`}
))}
);
});
const host = document.createElement('div');
const dispose = render(
, host);
const update = async (next: number[]) => {
rows = next;
renewList();
await nextTick();
};
await update([1]);
const first = host.querySelector('section') as HTMLElement;
expect(first.textContent).toBe('1:0slot-1');
expect(mounted).toEqual([1]);
await update([1, 2]);
const second = host.querySelector('[data-id="2"]') as HTMLElement;
expect(second.textContent).toBe('2:0slot-2');
expect(mounted).toEqual([1, 2]);
await update([2, 1]);
expect([...host.querySelectorAll('section')]).toEqual([second, first]);
first.click();
await nextTick();
const updatedFirst = host.querySelector('[data-id="1"]');
expect(updatedFirst).toBe(first);
expect(first.textContent).toBe('1:1slot-1');
expect([...host.querySelectorAll('section')]).toEqual([second, first]);
expect(unmounted).toEqual([]);
await update([2]);
expect(unmounted).toEqual([1]);
expect(host.querySelector('section')).toBe(second);
dispose();
expect(unmounted).toEqual([1, 2]);
});
});