UNPKG

ripple

Version:

Ripple is an elegant TypeScript UI framework

85 lines (69 loc) 3.12 kB
import { describe, it, expect } from 'vitest'; import { flushSync } from 'ripple'; import { hydrateComponent, container } from '../setup-hydration.js'; import * as ServerComponents from './compiled/server/mixed-control-flow.js'; import * as ClientComponents from './compiled/client/mixed-control-flow.js'; describe('hydration > mixed control flow blocks', () => { it('hydrates static composition of if + for + switch + try', async () => { await hydrateComponent( ServerComponents.MixedControlFlowStatic, ClientComponents.MixedControlFlowStatic, ); // Allow the try+pending async transitions to settle (pending → resolved). await Promise.resolve(); const rows = Array.from(container.querySelectorAll('.row')).map((node) => node.textContent); expect(rows).toEqual(['A-1', 'B-2']); expect(container.querySelector('.row-3')).toBeNull(); expect(container.querySelector('.pending')).toBeNull(); }); it('hydrates reactive composition of if + for + switch + try and updates correctly', async () => { await hydrateComponent( ServerComponents.MixedControlFlowReactive, ClientComponents.MixedControlFlowReactive, ); expect(Array.from(container.querySelectorAll('.item')).map((node) => node.textContent)).toEqual( ['A:One', 'A:Two'], ); container.querySelector('.toggle-mode')?.click(); flushSync(); expect(Array.from(container.querySelectorAll('.item')).map((node) => node.textContent)).toEqual( ['B:One', 'B:Two'], ); container.querySelector('.add-item')?.click(); flushSync(); expect(Array.from(container.querySelectorAll('.item')).map((node) => node.textContent)).toEqual( ['B:One', 'B:Two', 'B:Three'], ); container.querySelector('.toggle-show')?.click(); flushSync(); expect(container.querySelectorAll('.item').length).toBe(0); container.querySelector('.toggle-show')?.click(); flushSync(); expect(Array.from(container.querySelectorAll('.item')).map((node) => node.textContent)).toEqual( ['B:One', 'B:Two', 'B:Three'], ); }); it('hydrates async try with resolved server content in mixed control flow', async () => { await hydrateComponent( ServerComponents.MixedControlFlowAsyncPending, ClientComponents.MixedControlFlowAsyncPending, ); // Server resolves trackAsync fully, so resolved content is in the SSR HTML expect(container.querySelector('.before')?.textContent).toBe('before'); expect(container.querySelector('.resolved-row')?.textContent).toBe('row-1'); expect(container.querySelector('.pending-row')).toBeNull(); }); }); describe.skip('streaming ssr > mixed control flow async pending', () => { it('hydrates async pending path in mixed control flow without losing leading structure', async () => { await hydrateComponent( ServerComponents.MixedControlFlowAsyncPending, ClientComponents.MixedControlFlowAsyncPending, ); await Promise.resolve(); flushSync(); expect(container.querySelector('.before')?.textContent).toBe('before'); expect(container.querySelector('.pending-row-1')?.textContent).toBe('pending 1'); expect(container.querySelector('.unexpected')).toBeNull(); }); });