import { describe, it, expect } from 'vitest' import { createRangeRoot } from './vdom.ts' import type { Remix } from './component.ts' describe('createRangeRoot', () => { it('renders', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = 'Hello, world!' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) root.render(
Hello, world!
) expect(container.innerHTML).toBe('
Hello, world!
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) }) it('updates', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = 'Hello, world!' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) root.render(
Hello, world!
) expect(container.innerHTML).toBe('
Hello, world!
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) root.render(
Goodbye, world!
) expect(container.innerHTML).toBe('
Goodbye, world!
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) }) it('adds grows fragments', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = 'one' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) root.render( <>
one
, ) expect(container.innerHTML).toBe('
one
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) root.render( <>
one
two
, ) expect(container.innerHTML).toBe('
one
two
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) }) it('updates components', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = '1' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) let capturedUpdate = () => {} function App(this: Remix.Handle) { let count = 1 capturedUpdate = () => { count++ this.render() } return () => ( <> {Array.from({ length: count }).map((_, i) => (
{i}
))} ) } root.render() expect(container.innerHTML).toBe('
0
') expect(container.querySelector('div')).toBe(div) capturedUpdate() root.flush() expect(container.innerHTML).toBe('
0
1
') }) it('replaces nodes at the end', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = 'one' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) root.render( <>
one
two
, ) expect(container.innerHTML).toBe('
one
two
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) root.render( <>
one
main
, ) expect(container.innerHTML).toBe('
one
main
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) expect(container.querySelector('div')).toBe(div) }) it('updates nested children', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') let div = document.createElement('div') div.innerHTML = '0' container.appendChild(start) container.appendChild(div) container.appendChild(end) let root = createRangeRoot([start, end]) let capturedUpdate = () => {} function Nested(this: Remix.Handle) { let count = 0 capturedUpdate = () => { count++ this.render() } return () => {count} } function App(this: Remix.Handle) { return () => (
) } root.render() expect(container.innerHTML).toBe('
0
') expect(container.querySelector('div')).toBe(div) capturedUpdate() root.flush() expect(container.innerHTML).toBe('
1
') }) it('works w/o hydration', () => { let container = document.createElement('div') let start = document.createComment('range') let end = document.createComment('/range') container.appendChild(start) container.appendChild(end) let root = createRangeRoot([start, end]) root.render(
Hello, world!
) expect(container.innerHTML).toBe('
Hello, world!
') expect(container.firstChild).toBe(start) expect(container.lastChild).toBe(end) }) })