import { describe, expect, it } from 'vitest'; import { TriggerRegistry, triggerMatches, type Trigger } from './trigger.js'; const tap: Trigger = { type: 'tap', id: 'draw', match: { part: 'carcassonne:tile#a', trigger: 'draw' }, emit: [{ type: 'move', data: { part: 'carcassonne:tile#a', to: '/grid/5/5' } }], }; describe('triggerMatches', () => { it('matches on type and every match param', () => { expect( triggerMatches(tap, { type: 'tap', data: { part: 'carcassonne:tile#a', trigger: 'draw' } }), ).toBe(true); }); it('rejects a different type', () => { expect(triggerMatches(tap, { type: 'focus' })).toBe(false); }); it('rejects a mismatched param', () => { expect( triggerMatches(tap, { type: 'tap', data: { part: 'carcassonne:tile#b', trigger: 'draw' } }), ).toBe(false); }); it('matches any message of the type when there is no match block', () => { const any = { type: 'focus', emit: [] }; expect(triggerMatches(any, { type: 'focus', data: { path: '/deck' } })).toBe(true); }); }); describe('TriggerRegistry', () => { it('registers and matches enabled triggers', () => { const reg = new TriggerRegistry(); reg.register(tap); expect(reg.match({ type: 'tap', data: { part: 'carcassonne:tile#a', trigger: 'draw' } })).toEqual([ tap, ]); }); it('collision-checks duplicate type#id', () => { const reg = new TriggerRegistry(); reg.register(tap); expect(() => reg.register({ ...tap })).toThrow(/Duplicate trigger: tap#draw/); }); it('disable/enable toggles a trigger at runtime', () => { const reg = new TriggerRegistry(); reg.register(tap); reg.disable('tap', 'draw'); expect(reg.match({ type: 'tap', data: { part: 'carcassonne:tile#a', trigger: 'draw' } })).toEqual([]); reg.enable('tap', 'draw'); expect(reg.match({ type: 'tap', data: { part: 'carcassonne:tile#a', trigger: 'draw' } })).toEqual([ tap, ]); }); });