open source is social v-it.org
at main 112 lines 3.6 kB view raw
1// SPDX-License-Identifier: MIT 2// Copyright (c) 2026 sol pbc 3 4import { describe, test, expect } from 'bun:test'; 5import { 6 isValidSkillName, 7 isSkillRef, 8 isValidSkillRef, 9 skillRefFromName, 10 nameFromSkillRef, 11 SKILL_NAME_PATTERN, 12 SKILL_REF_PATTERN, 13 SKILL_NAME_MAX, 14} from '../src/lib/skill-ref.js'; 15 16describe('isValidSkillName', () => { 17 test('accepts simple lowercase names', () => { 18 expect(isValidSkillName('vit')).toBe(true); 19 expect(isValidSkillName('agent-test-patterns')).toBe(true); 20 expect(isValidSkillName('pdf-form-filler')).toBe(true); 21 }); 22 23 test('accepts names with numbers', () => { 24 expect(isValidSkillName('tool2')).toBe(true); 25 expect(isValidSkillName('agent-v2-helper')).toBe(true); 26 }); 27 28 test('rejects names starting with hyphen', () => { 29 expect(isValidSkillName('-bad')).toBe(false); 30 }); 31 32 test('rejects names with consecutive hyphens', () => { 33 expect(isValidSkillName('bad--name')).toBe(false); 34 }); 35 36 test('rejects names starting with number', () => { 37 expect(isValidSkillName('3bad')).toBe(false); 38 }); 39 40 test('rejects uppercase', () => { 41 expect(isValidSkillName('BadName')).toBe(false); 42 expect(isValidSkillName('ALLCAPS')).toBe(false); 43 }); 44 45 test('rejects empty and null', () => { 46 expect(isValidSkillName('')).toBe(false); 47 expect(isValidSkillName(null)).toBe(false); 48 expect(isValidSkillName(undefined)).toBe(false); 49 }); 50 51 test('rejects names over 64 chars', () => { 52 const long = 'a'.repeat(65); 53 expect(isValidSkillName(long)).toBe(false); 54 const justRight = 'a'.repeat(64); 55 expect(isValidSkillName(justRight)).toBe(true); 56 }); 57 58 test('rejects names with special chars', () => { 59 expect(isValidSkillName('has_underscore')).toBe(false); 60 expect(isValidSkillName('has.dot')).toBe(false); 61 expect(isValidSkillName('has space')).toBe(false); 62 expect(isValidSkillName('has@sign')).toBe(false); 63 }); 64 65 test('rejects trailing hyphen', () => { 66 expect(isValidSkillName('bad-')).toBe(false); 67 }); 68}); 69 70describe('isSkillRef', () => { 71 test('detects skill- prefix', () => { 72 expect(isSkillRef('skill-vit')).toBe(true); 73 expect(isSkillRef('skill-agent-test')).toBe(true); 74 }); 75 76 test('rejects non-skill refs', () => { 77 expect(isSkillRef('fast-cache-invalidation')).toBe(false); 78 expect(isSkillRef('vit')).toBe(false); 79 expect(isSkillRef('')).toBe(false); 80 expect(isSkillRef(null)).toBe(false); 81 }); 82}); 83 84describe('isValidSkillRef', () => { 85 test('validates well-formed skill refs', () => { 86 expect(isValidSkillRef('skill-vit')).toBe(true); 87 expect(isValidSkillRef('skill-agent-test-patterns')).toBe(true); 88 expect(isValidSkillRef('skill-pdf2')).toBe(true); 89 }); 90 91 test('rejects invalid skill refs', () => { 92 expect(isValidSkillRef('skill-')).toBe(false); 93 expect(isValidSkillRef('skill--bad')).toBe(false); 94 expect(isValidSkillRef('skill-Bad')).toBe(false); 95 expect(isValidSkillRef('not-a-skill-ref')).toBe(false); 96 expect(isValidSkillRef('')).toBe(false); 97 }); 98}); 99 100describe('skillRefFromName / nameFromSkillRef', () => { 101 test('round-trips correctly', () => { 102 expect(skillRefFromName('vit')).toBe('skill-vit'); 103 expect(nameFromSkillRef('skill-vit')).toBe('vit'); 104 expect(nameFromSkillRef(skillRefFromName('agent-test'))).toBe('agent-test'); 105 }); 106 107 test('nameFromSkillRef returns null for non-skill refs', () => { 108 expect(nameFromSkillRef('fast-cache-invalidation')).toBe(null); 109 expect(nameFromSkillRef('')).toBe(null); 110 expect(nameFromSkillRef(null)).toBe(null); 111 }); 112});