import { describe, expect, it } from 'vitest' import { validateMorfo, MorfoInvariantError } from '../schema' import type { Morfo } from '../types' import { toastMorfo } from './toast' function cloneMorfo(m: typeof toastMorfo): Morfo { return structuredClone(m as Morfo) as Morfo } describe('toastMorfo semantic contract', () => { it('passes shape + invariant validation', () => { expect(() => validateMorfo(toastMorfo)).not.toThrow() }) it('declares announce semantics and supported intents in morfo', () => { const announce = toastMorfo.events?.find((event) => event.name === 'announce') expect(announce).toBeDefined() expect(announce?.semantic).toMatchObject({ family: 'alert', intent: { fromProp: 'intent', default: 'neutral', supported: ['neutral', 'affirm', 'fulfill', 'risk', 'threat'] } }) }) it('declares intent-driven role and aria-live on the item contract', () => { const item = toastMorfo.parts.find((part) => part.kebab === 'item') const role = item?.aria.find((entry) => entry.attr === 'role') const live = item?.aria.find((entry) => entry.attr === 'aria-live') expect(role).toMatchObject({ attr: 'role', value: { kind: 'mapRef', source: { kind: 'propRef', prop: 'intent' }, map: { neutral: 'status', affirm: 'status', fulfill: 'status', risk: 'alert', threat: 'alert' } } }) expect(live).toMatchObject({ attr: 'aria-live', value: { kind: 'mapRef', source: { kind: 'propRef', prop: 'intent' }, map: { neutral: 'polite', affirm: 'polite', fulfill: 'polite', risk: 'assertive', threat: 'assertive' } } }) }) it('fails when the default intent is not in the supported list', () => { const broken = cloneMorfo(toastMorfo) const announce = broken.events?.find((event) => event.name === 'announce') if (!announce || !('intent' in announce.semantic) || typeof announce.semantic.intent === 'string') { throw new Error('announce semantic intent binding missing in fixture') } announce.semantic.intent.default = 'neutral' announce.semantic.intent.supported = ['affirm', 'risk'] expect(() => validateMorfo(broken)).toThrow(MorfoInvariantError) expect(() => validateMorfo(broken)).toThrow(/default intent "neutral" must be included/) }) it('fails when an intent map references an unknown local state', () => { const broken = cloneMorfo(toastMorfo) const item = broken.parts.find((part) => part.kebab === 'item') if (!item) throw new Error('item part missing in fixture') item.aria[0] = { attr: 'role', value: { kind: 'mapRef', source: { kind: 'stateRef', state: 'missing' }, map: { true: 'alert', false: 'status' } } } expect(() => validateMorfo(broken)).toThrow(MorfoInvariantError) expect(() => validateMorfo(broken)).toThrow(/stateRef "missing"/) }) })