187 lines
4.7 KiB
Go
187 lines
4.7 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package generator
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadPersonaRegistry(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry, err := loadPersonaRegistry()
|
|
if err != nil {
|
|
t.Fatalf("loadPersonaRegistry() error = %v", err)
|
|
}
|
|
if len(registry.Personas) == 0 {
|
|
t.Fatal("loadPersonaRegistry() returned empty personas")
|
|
}
|
|
}
|
|
|
|
func TestLoadRecipeRegistry(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry, err := loadRecipeRegistry()
|
|
if err != nil {
|
|
t.Fatalf("loadRecipeRegistry() error = %v", err)
|
|
}
|
|
if len(registry.Recipes) == 0 {
|
|
t.Fatal("loadRecipeRegistry() returned empty recipes")
|
|
}
|
|
}
|
|
|
|
func TestValidateRegistryReferences(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
personas, err := loadPersonaRegistry()
|
|
if err != nil {
|
|
t.Fatalf("loadPersonaRegistry() error = %v", err)
|
|
}
|
|
recipes, err := loadRecipeRegistry()
|
|
if err != nil {
|
|
t.Fatalf("loadRecipeRegistry() error = %v", err)
|
|
}
|
|
if err := validateRegistryReferences(personas, recipes); err != nil {
|
|
t.Fatalf("validateRegistryReferences() error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateRegistryReferencesRejectsUnknownWorkflow(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
personas := PersonaRegistry{
|
|
Personas: []PersonaEntry{
|
|
{
|
|
Name: "pm",
|
|
Title: "PM",
|
|
Description: "project manager",
|
|
Services: []string{"doc"},
|
|
Workflows: []string{"unknown-workflow"},
|
|
Instructions: []string{"do work"},
|
|
},
|
|
},
|
|
}
|
|
recipes := RecipeRegistry{
|
|
Recipes: []RecipeEntry{
|
|
{
|
|
Name: "meeting-prep",
|
|
Title: "Meeting Prep",
|
|
Description: "prepare",
|
|
Category: "collaboration",
|
|
Services: []string{"doc"},
|
|
Steps: []string{"step"},
|
|
},
|
|
},
|
|
}
|
|
|
|
if err := validateRegistryReferences(personas, recipes); err == nil {
|
|
t.Fatal("validateRegistryReferences() should fail for unknown workflow")
|
|
}
|
|
}
|
|
|
|
func TestUniqueSkillProducts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := uniqueSkillProducts([]string{"doc", "drive", "doc", " DRIVE ", ""})
|
|
want := []string{"doc", "drive"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("uniqueSkillProducts() len = %d, want %d", len(got), len(want))
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("uniqueSkillProducts()[%d] = %q, want %q", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestServiceRefsSupportServicesAndProducts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
persona := PersonaEntry{
|
|
Services: []string{"doc", "drive"},
|
|
Products: []string{"doc", "chat"},
|
|
}
|
|
got := persona.serviceRefs()
|
|
want := []string{"chat", "doc", "drive"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("serviceRefs() len = %d, want %d", len(got), len(want))
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("serviceRefs()[%d] = %q, want %q", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeRegistryToken(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if got := normalizeRegistryToken(" Meeting_Prep "); got != "meeting-prep" {
|
|
t.Fatalf("normalizeRegistryToken() = %q, want %q", got, "meeting-prep")
|
|
}
|
|
}
|
|
|
|
func TestValidateRegistryReferencesUsesNormalizedWorkflowName(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
personas := PersonaRegistry{
|
|
Personas: []PersonaEntry{
|
|
{
|
|
Name: "pm",
|
|
Title: "PM",
|
|
Description: "project manager",
|
|
Services: []string{"doc"},
|
|
Workflows: []string{"meeting-prep"},
|
|
Instructions: []string{"do work"},
|
|
},
|
|
},
|
|
}
|
|
recipes := RecipeRegistry{
|
|
Recipes: []RecipeEntry{
|
|
{
|
|
Name: "meeting_prep",
|
|
Title: "Meeting Prep",
|
|
Description: "prepare",
|
|
Category: "collaboration",
|
|
Services: []string{"doc"},
|
|
Steps: []string{"step"},
|
|
},
|
|
},
|
|
}
|
|
|
|
if err := validateRegistryReferences(personas, recipes); err != nil {
|
|
t.Fatalf("validateRegistryReferences() error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestReadRegistryYAMLFromEnvOverride(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
path := filepath.Join(tmp, "personas.yaml")
|
|
want := []byte("personas: []\n")
|
|
if err := os.WriteFile(path, want, 0o644); err != nil {
|
|
t.Fatalf("WriteFile() error = %v", err)
|
|
}
|
|
t.Setenv(PersonaRegistryPathEnv, path)
|
|
|
|
got, err := readRegistryYAML(PersonaRegistryPathEnv, []byte("fallback"))
|
|
if err != nil {
|
|
t.Fatalf("readRegistryYAML() error = %v", err)
|
|
}
|
|
if string(got) != string(want) {
|
|
t.Fatalf("readRegistryYAML() = %q, want %q", string(got), string(want))
|
|
}
|
|
}
|