package openrouter import ( "bytes" "errors" "fmt" "io" "io/fs" "path" "strings" "testing" "gopkg.in/yaml.v3" ) func TestCatalogLayoutAndContents(t *testing.T) { assets := FS() if assets == nil { t.Fatal("FS returned nil") } backendPath := Root + "/backend.yml" backendData, err := fs.ReadFile(assets, backendPath) if err != nil { t.Fatalf("read backend: %v", err) } assertBackend(t, backendData) profilesRoot := Root + "/profiles" ids := make(map[string]string) err = fs.WalkDir(assets, Root, func(assetPath string, entry fs.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } if assetPath == Root || assetPath == profilesRoot || entry.IsDir() { return nil } if assetPath == backendPath { if !entry.Type().IsRegular() { return fmt.Errorf("backend asset is not a regular file") } return nil } if !strings.HasPrefix(assetPath, profilesRoot+"/") { return fmt.Errorf("unexpected catalog entry %q", assetPath) } if !entry.Type().IsRegular() || !strings.HasSuffix(assetPath, ".yml") { return fmt.Errorf("profile asset %q is not a regular .yml file", assetPath) } data, err := fs.ReadFile(assets, assetPath) if err != nil { return err } id := assertProfile(t, assetPath, data) if previous, found := ids[id]; found { return fmt.Errorf("duplicate profile ID %q in %s and %s", id, previous, assetPath) } ids[id] = assetPath return nil }) if err != nil { t.Fatalf("validate catalog layout: %v", err) } if len(ids) != 36 { t.Fatalf("profile inventory changed: got %d, want 36", len(ids)) } } func assertBackend(t *testing.T, data []byte) { t.Helper() root := decodeMapping(t, "backend", data) backends := requireSingleMapping(t, "backend", root, "backends") if len(backends) != 1 || backends["openrouter"] == nil { t.Fatalf("backend asset must define only openrouter: %v", backends) } definition := mappingFields(t, "backend", backends["openrouter"]) for field, want := range map[string]string{ "endpoint": "https://openrouter.ai/api/v1", "api_key_env": "OPENROUTER_API_KEY", "concurrency_limit": "16", "queue_capacity": "1024", } { value := definition[field] if value == nil || value.Value != want { t.Fatalf("backend %s: got %v, want %q", field, value, want) } } if len(definition) != 4 { t.Fatalf("unexpected backend fields: %v", definition) } } func assertProfile(t *testing.T, assetPath string, data []byte) string { t.Helper() root := decodeMapping(t, assetPath, data) profiles := requireSingleMapping(t, assetPath, root, "profiles") if len(profiles) != 1 { t.Fatalf("profile asset %s must define exactly one ID", assetPath) } for id, entry := range profiles { if id == "" || id != strings.TrimSuffix(path.Base(assetPath), ".yml") { t.Fatalf("profile asset %s has unexpected ID %q", assetPath, id) } fields := mappingFields(t, assetPath, entry) if fields["backend"] == nil || fields["backend"].Value != "openrouter" { t.Fatalf("profile %s does not select openrouter", assetPath) } if fields["model"] == nil || strings.TrimSpace(fields["model"].Value) == "" { t.Fatalf("profile %s has no model", assetPath) } for _, obsolete := range []string{"id", "base_profile"} { if fields[obsolete] != nil { t.Fatalf("profile %s contains obsolete %s field", assetPath, obsolete) } } return id } panic("unreachable") } func decodeMapping(t *testing.T, name string, data []byte) *yaml.Node { t.Helper() decoder := yaml.NewDecoder(bytes.NewReader(data)) var document yaml.Node if err := decoder.Decode(&document); err != nil { t.Fatalf("decode %s: %v", name, err) } var trailing yaml.Node if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) { t.Fatalf("%s must contain exactly one YAML document: %v", name, err) } if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { t.Fatalf("%s must contain one mapping document", name) } return document.Content[0] } func requireSingleMapping(t *testing.T, name string, parent *yaml.Node, key string) map[string]*yaml.Node { t.Helper() fields := mappingFields(t, name, parent) if len(fields) != 1 || fields[key] == nil { t.Fatalf("%s must contain only %s", name, key) } return mappingFields(t, name, fields[key]) } func mappingFields(t *testing.T, name string, node *yaml.Node) map[string]*yaml.Node { t.Helper() if node.Kind != yaml.MappingNode { t.Fatalf("%s must contain a mapping", name) } fields := make(map[string]*yaml.Node, len(node.Content)/2) for index := 0; index+1 < len(node.Content); index += 2 { key := node.Content[index].Value if _, exists := fields[key]; exists { t.Fatalf("%s repeats key %q", name, key) } fields[key] = node.Content[index+1] } return fields }