import { describe, it, expect } from 'vitest' import { createRoot } from '../lib/vdom.ts' import { invariant } from '../lib/invariant.ts' import { css } from '../index.ts' describe('vnode rendering', () => { describe('special attributes', () => { it.todo('className') it.todo('htmlFor') it.todo('acceptCharset') it.todo('httpEquiv') it.todo('xlinkHref') it.todo('xmlLang') it.todo('xmlSpace') it.todo('data-*') it.todo('aria-*') }) describe('special props', () => { it.todo('style') it.todo('value') it.todo('defaultValue') it.todo('checked') it.todo('defaultChecked') it.todo('disabled') }) describe('framework props', () => { it.todo('does not render key') it.todo('does not render on') it.todo('does not render mix') it.todo('does not render children') it.todo('does not render tabIndex') it.todo('does not render acceptCharset') }) describe('innerHTML prop', () => { it('sets innerHTML on element', () => { let container = document.createElement('div') let root = createRoot(container) root.render(
) expect(container.innerHTML).toBe('
Hello
') }) it('ignores children when innerHTML is set', () => { let container = document.createElement('div') let root = createRoot(container) root.render(

Ignored child

, ) expect(container.innerHTML).toBe('
From innerHTML
') }) it('updates innerHTML on re-render', () => { let container = document.createElement('div') let root = createRoot(container) root.render(
) expect(container.innerHTML).toBe('
First
') let div = container.querySelector('div') invariant(div) root.render(
) expect(container.innerHTML).toBe('
Second
') expect(container.querySelector('div')).toBe(div) }) it('clears innerHTML when removed', () => { let container = document.createElement('div') let root = createRoot(container) root.render(
) expect(container.innerHTML).toBe('
Hello
') root.render(
) expect(container.innerHTML).toBe('
') }) it('switches from innerHTML to children', () => { let container = document.createElement('div') let root = createRoot(container) root.render(
) expect(container.innerHTML).toBe('
From innerHTML
') root.render(

From children

, ) expect(container.innerHTML).toBe('

From children

') }) it('switches from children to innerHTML', () => { let container = document.createElement('div') let root = createRoot(container) root.render(

From children

, ) expect(container.innerHTML).toBe('

From children

') root.render(
) expect(container.innerHTML).toBe('
From innerHTML
') }) it('switches from text children to innerHTML without throwing', () => { let container = document.createElement('div') let root = createRoot(container) let renderError: unknown root.addEventListener('error', (event) => { renderError = (event as ErrorEvent).error }) root.render(
From text child
) expect(container.innerHTML).toBe('
From text child
') root.render(
) expect(container.innerHTML).toBe('
From innerHTML
') expect(renderError).toBeUndefined() }) }) describe('css mixin', () => { it('adds className-based styles', async () => { let container = document.createElement('div') let root = createRoot(container) root.render(
Hello
) let div = container.querySelector('div') invariant(div instanceof HTMLDivElement) expect(div.className).toMatch(/rmxc-/) document.body.appendChild(container) expect(getComputedStyle(div).color).toBe('rgb(255, 0, 0)') }) it('composes with className without overriding it', async () => { let container = document.createElement('div') let root = createRoot(container) root.render(
Hello
, ) let div = container.querySelector('div') invariant(div instanceof HTMLDivElement) expect(div.className).toContain('custom-class') expect(div.className).toMatch(/rmxc-/) }) it('ignores class when composing css mixin className', async () => { let container = document.createElement('div') let root = createRoot(container) root.render(
Hello
, ) let div = container.querySelector('div') invariant(div instanceof HTMLDivElement) expect(div.className).toMatch(/rmxc-/) }) it('className updates independently of css mixin output', async () => { let container = document.createElement('div') let root = createRoot(container) root.render(
Hello
, ) let div = container.querySelector('div') invariant(div instanceof HTMLDivElement) expect(div.className).toContain('first') let generated = div.className.split(/\s+/).find((token) => token.startsWith('rmxc-')) invariant(generated) root.render(
Hello
, ) expect(div.className).toContain('second') expect(div.className).toContain(generated) }) it('removes nested selector rules when they become undefined', async () => { let container = document.createElement('div') document.body.appendChild(container) let root = createRoot(container) root.render(
Test
, ) let child = container.querySelector('span') invariant(child) // More-specific nested selector should win. expect(getComputedStyle(child).color).toBe('rgb(255, 0, 0)') root.render(
Test
, ) // Once the more-specific selector becomes undefined, the child should fall back to the base rule. expect(getComputedStyle(child).color).toBe('rgb(0, 0, 255)') }) }) })