internal/app/skill_file_requirement_test.go
Rama main · réplica de lectura del repositorio original.
package app
import (
"bytes"
"log/slog"
"os"
"path/filepath"
"strings"
"testing"
"github.com/yeomyeonggeori/blueclaw/internal/skill"
)
func skillsRootDeclaringAFont(t *testing.T, fontPaths []string) string {
t.Helper()
skillsRoot := filepath.Join(t.TempDir(), "skills")
skillPath := filepath.Join(skillsRoot, "pdf")
if errorValue := os.MkdirAll(skillPath, 0o755); errorValue != nil {
t.Fatal(errorValue)
}
document := `---
name: pdf
description: Writes a PDF from a source.
metadata:
kim.intern.requires-any-file: "` + strings.Join(fontPaths, " ") + `"
---
Write the PDF.
`
if errorValue := os.WriteFile(filepath.Join(skillPath, "SKILL.md"), []byte(document), 0o644); errorValue != nil {
t.Fatal(errorValue)
}
return skillsRoot
}
func TestASkillWhoseDeclaredFileIsAbsentIsLeftOutOfThePrompt(t *testing.T) {
absentFontPath := filepath.Join(t.TempDir(), "NanumGothic.ttf")
discovered := readSkillInstructions(t.TempDir(), skillsRootDeclaringAFont(t, []string{absentFontPath}), []string{})
if len(discovered.Selectable) != 0 {
t.Fatalf("a skill that would write the wrong file must not be offered, got %+v", discovered.Selectable)
}
if len(discovered.Unavailable) != 1 || discovered.Unavailable[0].Name != "pdf" {
t.Fatalf("expected pdf listed as unavailable, got %+v", discovered.Unavailable)
}
missingPaths := discovered.Unavailable[0].MissingAnyFilePaths
if len(missingPaths) != 1 || missingPaths[0] != absentFontPath {
t.Fatalf("expected the path that would have done, got %v", missingPaths)
}
}
func TestASkillWhoseDeclaredFileIsThereStaysSelectable(t *testing.T) {
fontDirectory := t.TempDir()
presentFontPath := filepath.Join(fontDirectory, "NotoSansCJK-Regular.ttc")
if errorValue := os.WriteFile(presentFontPath, []byte("font"), 0o644); errorValue != nil {
t.Fatal(errorValue)
}
absentFontPath := filepath.Join(fontDirectory, "NanumGothic.ttf")
discovered := readSkillInstructions(t.TempDir(), skillsRootDeclaringAFont(t, []string{absentFontPath, presentFontPath}), []string{})
if len(discovered.Unavailable) != 0 {
t.Fatalf("one of the alternatives being there is enough, got %+v", discovered.Unavailable)
}
if len(discovered.Selectable) != 1 || discovered.Selectable[0].Name != "pdf" {
t.Fatalf("expected pdf offered, got %+v", discovered.Selectable)
}
}
// A skill left out for a missing tool used to be the only one said out loud.
// Every other reason reached the inventory and nothing else, so a host that had
// quietly dropped a skill looked the same as one that never shipped it.
func TestStartupSaysEveryReasonASkillWasLeftOut(t *testing.T) {
logDocument := bytes.Buffer{}
logger := slog.New(slog.NewTextHandler(&logDocument, nil))
logSkillsThisHostCannotSatisfy(logger, []skill.UnavailableSkill{
{Name: "internkim-api", Path: "/skills/internkim-api/SKILL.md", MissingEnvironmentVariables: []string{"INTERNKIM_TOKEN"}},
{Name: "pdf", Path: "/skills/pdf/SKILL.md", MissingAnyFilePaths: []string{"/usr/share/fonts/truetype/nanum/NanumGothic.ttf"}},
{Name: "calendar", Path: "/skills/calendar/SKILL.md", MissingToolNames: []string{"event_add"}},
})
for _, expectedText := range []string{
`skill.environment.missing`, `missingEnvironment=INTERNKIM_TOKEN`,
`skill.file.missing`, `anyOfTheseWouldHaveDone=/usr/share/fonts/truetype/nanum/NanumGothic.ttf`,
`skill.tools.missing`, `missingTools=event_add`,
} {
if !strings.Contains(logDocument.String(), expectedText) {
t.Fatalf("startup must say %q; it said:\n%s", expectedText, logDocument.String())
}
}
}