(
template: string,
registry: Record<string, import('../scripts/resolvers/types').ResolverValue>,
ctx: TemplateContext,
)
| 106 | */ |
| 107 | describe('gen-skill-docs substitution loop respects the appliesTo gate', () => { |
| 108 | function simulateGenSubstitution( |
| 109 | template: string, |
| 110 | registry: Record<string, import('../scripts/resolvers/types').ResolverValue>, |
| 111 | ctx: TemplateContext, |
| 112 | ): string { |
| 113 | // Mirrors scripts/gen-skill-docs.ts:457-467 (the {{NAME}} substitution |
| 114 | // loop). Keep this in sync with the real loop. Drift here is what the |
| 115 | // test is designed to catch. |
| 116 | return template.replace(/\{\{(\w+(?::[^}]+)?)\}\}/g, (_match, fullKey) => { |
| 117 | const parts = fullKey.split(':'); |
| 118 | const resolverName = parts[0]; |
| 119 | const args = parts.slice(1); |
| 120 | const entry = registry[resolverName]; |
| 121 | if (!entry) throw new Error(`Unknown placeholder {{${resolverName}}}`); |
| 122 | const { resolve, appliesTo } = unwrapResolver(entry); |
| 123 | if (appliesTo && !appliesTo(ctx)) return ''; |
| 124 | return args.length > 0 ? resolve(ctx, args) : resolve(ctx); |
| 125 | }); |
| 126 | } |
| 127 | |
| 128 | test('plain-function resolver fires unconditionally', () => { |
| 129 | const tpl = '{{ALWAYS}}'; |
no test coverage detected