package skills import ( "os" "path/filepath" "testing" ) func TestLoadSkill(t *testing.T) { // Create a temp skill dir := t.TempDir() skillDir := filepath.Join(dir, "test-skill") os.MkdirAll(skillDir, 0755) content := `--- name: test-skill description: A test skill for unit testing. Use when testing skill loading. --- # Test Skill This is test content. ` os.WriteFile(filepath.Join(skillDir, "SKILL.md"), []byte(content), 0644) skill, err := loadSkill(filepath.Join(skillDir, "SKILL.md")) if err != nil { t.Fatalf("loadSkill: %v", err) } if skill.Name != "test-skill" { t.Errorf("name = %q, want %q", skill.Name, "test-skill") } if skill.Description != "A test skill for unit testing. Use when testing skill loading." { t.Errorf("description = %q", skill.Description) } } func TestParseFrontmatter(t *testing.T) { tests := []struct { name string input string wantN string wantD string wantErr bool }{ { name: "valid", input: `--- name: my-skill description: My description --- content`, wantN: "my-skill", wantD: "My description", }, { name: "no frontmatter", input: "# Just content", wantErr: true, }, { name: "missing name", input: `--- description: test ---`, wantErr: true, }, { name: "missing description", input: `--- name: test ---`, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { n, d, err := parseFrontmatter([]byte(tt.input)) if tt.wantErr { if err == nil { t.Error("expected error") } return } if err != nil { t.Fatalf("unexpected error: %v", err) } if n != tt.wantN { t.Errorf("name = %q, want %q", n, tt.wantN) } if d != tt.wantD { t.Errorf("description = %q, want %q", d, tt.wantD) } }) } } func TestIndexMatch(t *testing.T) { // Find model directory home, _ := os.UserHomeDir() modelDir := "" candidates := []string{ "../data/models", filepath.Join(home, ".local/share/ollie/models"), } for _, c := range candidates { if _, err := os.Stat(filepath.Join(c, "model.onnx")); err == nil { modelDir = c break } } if modelDir == "" { t.Skip("model not found") } // Create temp skill directory dir := t.TempDir() skills := []struct { name string desc string }{ {"jira-cli", "Interact with Jira for issue tracking. Use for tickets, sprints, and project management."}, {"github-cli", "Interact with GitHub repositories, issues, and pull requests."}, {"bash-exec", "Execute bash commands locally or remotely."}, } for _, s := range skills { skillDir := filepath.Join(dir, s.name) os.MkdirAll(skillDir, 0755) content := "---\nname: " + s.name + "\ndescription: " + s.desc + "\n---\n# " + s.name os.WriteFile(filepath.Join(skillDir, "SKILL.md"), []byte(content), 0644) } idx, err := NewIndex(modelDir, []string{dir}) if err != nil { t.Fatalf("NewIndex: %v", err) } defer idx.Close() // Test matching results, err := idx.Match("create a jira ticket for the bug", 0.1, 3) if err != nil { t.Fatalf("Match: %v", err) } if len(results) == 0 { t.Fatal("expected results") } t.Logf("Query: 'create a jira ticket for the bug'") for _, r := range results { t.Logf(" %s: %.4f", r.Skill.Name, r.Score) } // Jira should be top result if results[0].Skill.Name != "jira-cli" { t.Errorf("expected jira-cli as top result, got %s", results[0].Skill.Name) } }