import { describe, it, expect } from 'vitest'; import { h, render, mount, nextTick } from '@/index'; /** * In a file of its own: before the fix, a render that threw stopped every * later renew, which would have hidden the other tests' failures. */ const flush = async () => { for (let i = 0; i < 3; i++) await nextTick(); }; describe('redraw scheduling after an error', () => { it('flushes already queued siblings after an error without another renew', async () => { let fail = false; let bumpA = () => {}; let bumpB = () => {}; let count = 0; const A = mount(renew => { bumpA = renew; return () => { if (fail) throw new Error('render failed with a sibling queued'); return a; }; }); const B = mount(renew => { bumpB = () => { count++; renew(); }; return () => {count}; }); const el = document.createElement('div'); const destroy = render(
, el ); const errors: unknown[] = []; const onError = (error: unknown) => errors.push(error); process.on('uncaughtException', onError); try { fail = true; bumpA(); bumpB(); await new Promise(resolve => setTimeout(resolve)); expect(errors).toHaveLength(1); expect(errors[0]).toEqual( new Error('render failed with a sibling queued') ); expect(el.innerHTML).toBe('
a1
'); } finally { process.off('uncaughtException', onError); destroy(); } }); it('keeps redrawing after a render throws', async () => { let fail = false; let bumpA = () => {}; let bumpB = () => {}; let count = 0; const A = mount(renew => { bumpA = renew; return () => { if (fail) { fail = false; throw new Error('render failed'); } return a; }; }); const B = mount(renew => { bumpB = () => { count++; renew(); }; return () => {count}; }); const el = document.createElement('div'); render(
, el ); const errors: unknown[] = []; const onError = (error: unknown) => errors.push(error); process.on('uncaughtException', onError); try { fail = true; bumpA(); await new Promise(resolve => setTimeout(resolve)); } finally { process.off('uncaughtException', onError); } bumpB(); await flush(); expect(el.innerHTML).toBe('
a1
'); }); });