27 lines
1.6 KiB
TypeScript
27 lines
1.6 KiB
TypeScript
// "Open guide" on a finding: skill name -> the shipped SKILL.md; the known list matches the skills/ folder.
|
|
import { expect, test } from 'bun:test';
|
|
import { existsSync, readdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { KNOWN_SKILLS, SKILLS_BASE, skillGuideUrl } from '../cli/lib/skill-guide';
|
|
|
|
const dir = join(import.meta.dir, '..', 'skills');
|
|
|
|
test('KNOWN_SKILLS is exactly the skills/ folder', () => {
|
|
const real = readdirSync(dir).filter(n => existsSync(join(dir, n, 'SKILL.md'))).sort();
|
|
expect([...KNOWN_SKILLS].sort()).toEqual(real);
|
|
});
|
|
test('a skill name, a skills/ path or a SKILL.md path resolve to the guide', () => {
|
|
expect(skillGuideUrl('store-api')).toBe(`${SKILLS_BASE}/store-api/SKILL.md`);
|
|
expect(skillGuideUrl('skills/store-api')).toBe(`${SKILLS_BASE}/store-api/SKILL.md`);
|
|
expect(skillGuideUrl(' skills/game-services/SKILL.md ')).toBe(`${SKILLS_BASE}/game-services/SKILL.md`);
|
|
});
|
|
test('unknown or empty: no link', () => {
|
|
for (const s of ['', null, undefined, 'not-a-skill', '../etc', 'store-api/../x']) expect(skillGuideUrl(s)).toBeNull();
|
|
});
|
|
test('every skill a scan rule names is a known skill', async () => {
|
|
const { readFileSync } = await import('node:fs');
|
|
const src = readdirSync(join(import.meta.dir, '..', 'cli', 'lib', 'scan')).filter(f => f.endsWith('.ts')).map(f => readFileSync(join(import.meta.dir, '..', 'cli', 'lib', 'scan', f), 'utf8')).join('\n');
|
|
const named = [...src.matchAll(/skill: '([a-z0-9-]+)'/g)].map(m => m[1]!);
|
|
expect(named.length).toBeGreaterThan(0);
|
|
for (const s of new Set(named)) expect(skillGuideUrl(s)).not.toBeNull();
|
|
});
|