| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import { describe, expect, it } from 'bun:test'
- import type { Ability, Triggers } from '../src/types/index.js'
- function matchesTrigger(text: string, triggers: Triggers | undefined): boolean {
- if (!triggers) return false
- const lowerText = text.toLowerCase()
- if (triggers.keywords) {
- for (const keyword of triggers.keywords) {
- if (lowerText.includes(keyword.toLowerCase())) {
- return true
- }
- }
- }
- if (triggers.patterns) {
- for (const pattern of triggers.patterns) {
- try {
- if (new RegExp(pattern, 'i').test(text)) {
- return true
- }
- } catch {
- continue
- }
- }
- }
- return false
- }
- describe('Trigger Detection', () => {
- describe('keyword matching', () => {
- it('should match exact keyword', () => {
- const triggers: Triggers = { keywords: ['deploy'] }
- expect(matchesTrigger('deploy to production', triggers)).toBe(true)
- })
- it('should match keyword case-insensitively', () => {
- const triggers: Triggers = { keywords: ['Deploy'] }
- expect(matchesTrigger('DEPLOY now', triggers)).toBe(true)
- })
- it('should match keyword as substring', () => {
- const triggers: Triggers = { keywords: ['ship'] }
- expect(matchesTrigger('ship it!', triggers)).toBe(true)
- })
- it('should not match when keyword not present', () => {
- const triggers: Triggers = { keywords: ['deploy'] }
- expect(matchesTrigger('release the code', triggers)).toBe(false)
- })
- it('should match any of multiple keywords', () => {
- const triggers: Triggers = { keywords: ['deploy', 'release', 'ship'] }
- expect(matchesTrigger('release v1.0', triggers)).toBe(true)
- expect(matchesTrigger('ship it', triggers)).toBe(true)
- })
- })
- describe('pattern matching', () => {
- it('should match regex pattern', () => {
- const triggers: Triggers = { patterns: ['deploy.*prod'] }
- expect(matchesTrigger('deploy to production', triggers)).toBe(true)
- })
- it('should match version pattern', () => {
- const triggers: Triggers = { patterns: ['v\\d+\\.\\d+\\.\\d+'] }
- expect(matchesTrigger('release v1.2.3', triggers)).toBe(true)
- })
- it('should not match invalid pattern gracefully', () => {
- const triggers: Triggers = { patterns: ['[invalid(regex'] }
- expect(matchesTrigger('some text', triggers)).toBe(false)
- })
- it('should match case-insensitively', () => {
- const triggers: Triggers = { patterns: ['DEPLOY'] }
- expect(matchesTrigger('deploy now', triggers)).toBe(true)
- })
- })
- describe('combined triggers', () => {
- it('should match keyword OR pattern', () => {
- const triggers: Triggers = {
- keywords: ['ship it'],
- patterns: ['deploy.*prod']
- }
- expect(matchesTrigger('ship it now', triggers)).toBe(true)
- expect(matchesTrigger('deploy to prod', triggers)).toBe(true)
- })
- it('should return false when no triggers defined', () => {
- expect(matchesTrigger('anything', undefined)).toBe(false)
- expect(matchesTrigger('anything', {})).toBe(false)
- })
- })
- describe('ability trigger detection', () => {
- it('should detect ability from user message', () => {
- const abilities: Ability[] = [
- {
- name: 'deploy',
- description: 'Deploy to production',
- triggers: { keywords: ['deploy', 'ship it'] },
- steps: [{ id: 'test', type: 'script', run: 'echo test' }]
- },
- {
- name: 'test',
- description: 'Run tests',
- triggers: { keywords: ['run tests', 'test suite'] },
- steps: [{ id: 'test', type: 'script', run: 'npm test' }]
- }
- ]
- const detectAbility = (text: string): Ability | null => {
- for (const ability of abilities) {
- if (matchesTrigger(text, ability.triggers)) {
- return ability
- }
- }
- return null
- }
- expect(detectAbility('please deploy to staging')?.name).toBe('deploy')
- expect(detectAbility('ship it!')?.name).toBe('deploy')
- expect(detectAbility('run tests please')?.name).toBe('test')
- expect(detectAbility('check the code')).toBe(null)
- })
- })
- })
|