import { expect, test } from 'vitest'; import { WebComponent, disable, enable, number, string } from '../src/index.ts'; const SPEC = { props: { userId: number(), userName: string(), min: number({ default: 1 }), max: number({ default: 10 }), ready: enable({ attribute: 'is-ready' }), fetch: disable(), }, } as const; class ExampleElement extends WebComponent(SPEC) {} customElements.define('example-element', ExampleElement); function attributes(el: Element): Record { return Object.fromEntries([...el.attributes].map((a) => [a.name, a.value])); } test('observedAttributes', () => { expect(ExampleElement.observedAttributes).toEqual([ 'user-id', 'user-name', 'min', 'max', 'is-ready', 'disable-fetch', ]); }); test('defaults', () => { const el = new ExampleElement(); expect(el.max).toBe(10); expect(el.min).toBe(1); expect(el.fetch).toBe(true); expect(el.ready).toBe(false); expect(el.userId).toBeUndefined(); expect(el.userName).toBeUndefined(); expect(el.attributes).toHaveLength(0); }); test('props reflect to attributes and attributes back to props', () => { const el = new ExampleElement(); el.max = 9; el.min = 2; el.fetch = false; el.ready = true; el.userId = 123; expect(attributes(el)).toEqual({ max: '9', min: '2', 'disable-fetch': '', 'is-ready': '', 'user-id': '123', }); el.removeAttribute('disable-fetch'); el.removeAttribute('is-ready'); el.setAttribute('max', '100'); el.setAttribute('min', '10'); el.setAttribute('user-id', '300'); expect(el.fetch).toBe(true); expect(el.max).toBe(100); expect(el.min).toBe(10); expect(el.ready).toBe(false); expect(el.userId).toBe(300); expect(attributes(el)).toEqual({ max: '100', min: '10', 'user-id': '300' }); el.userId = undefined; expect(el.hasAttribute('user-id')).toBe(false); });