import type { Injector } from '@furystack/inject' import { createInjector } from '@furystack/inject' import { describe, expect, it, vi } from 'vitest' import './jsx.js' import { createComponent } from './shade-component.js' import { flushUpdates, Shade } from './shade.js' describe('Shades Component Factory', () => { describe('HTML Elements', () => { it('Should create a simple component', () => { const component =
test
expect(component).toBeInstanceOf(HTMLDivElement) expect(component.innerHTML).toBe('test') expect(component.outerHTML).toBe('
test
') }) it('Should apply styles', () => { const component =
a
expect(component).toBeInstanceOf(HTMLDivElement) expect(component.style.color).toBe('red') }) it('Should apply data attributes', () => { const component =
a
expect(component).toBeInstanceOf(HTMLDivElement) expect(component.getAttribute('data-testid')).toBe('asd-123') }) it('Should apply aria attributes', () => { const component = ( ) expect(component).toBeInstanceOf(HTMLDivElement) expect(component.getAttribute('aria-label')).toBe('My label') expect(component.getAttribute('aria-hidden')).toBe('true') }) it('Should create a nested component', () => { const component = (

Hi, I'm a header

paragraph... {['a', 'b', 'c']}

link
) expect(component).toBeInstanceOf(HTMLDivElement) expect(component.childElementCount).toBe(3) expect(component.innerHTML).toBe( `

Hi, I'm a header

paragraph... abc

link`, ) }) it('Should attach listeners', () => { const onclick = vi.fn() const component =
expect(component.onclick).toBe(onclick) }) }) describe('Shade components', () => { it('Should render a basic component', () => { const Example = Shade({ customElementName: 'example-basic', render: () =>
}) const component = (
) const shade = component.firstElementChild as JSX.Element expect(shade.props).toEqual({}) expect(shade.shadeChildren).toEqual([]) }) it('Should render a component with props', async () => { const Example = Shade<{ foo: string; injector: Injector }>({ customElementName: 'example-with-props', render: ({ props }) =>
{props.foo}
, }) const component = (
) const shade = component.firstElementChild as JSX.Element<{ foo: string }> shade.updateComponent() await flushUpdates() expect(shade.props.foo).toEqual('example') expect(shade.shadeChildren).toEqual([]) expect(shade.innerHTML).toBe('
example
') }) it('Should render a component with state', async () => { const Example = Shade({ customElementName: 'example-with-state', render: ({ useState }) => { useState('foo', 'example') return
}, }) const component = (
) const shade = component.firstElementChild as JSX.Element shade.updateComponent() await flushUpdates() expect(shade.resourceManager.stateObservers.get('foo')?.getValue()).toEqual('example') expect(shade.shadeChildren).toEqual([]) }) }) })