feat(api): add iterator for spec registry
Adds RegisteredSpecGroupsIter so CLI consumers can range over a snapshot of the package-level spec registry without copying the slice manually. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
f2f262a4c2
commit
cb726000a9
2 changed files with 49 additions and 1 deletions
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
package api
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"iter"
|
||||
"sync"
|
||||
|
||||
"slices"
|
||||
)
|
||||
|
||||
// specRegistry stores RouteGroups that should be included in CLI-generated
|
||||
// OpenAPI documents. Packages can register their groups during init and the
|
||||
|
|
@ -49,6 +54,19 @@ func RegisteredSpecGroups() []RouteGroup {
|
|||
return out
|
||||
}
|
||||
|
||||
// RegisteredSpecGroupsIter returns an iterator over the route groups registered
|
||||
// for CLI-generated OpenAPI documents.
|
||||
//
|
||||
// The iterator snapshots the current registry contents so callers can range
|
||||
// over it without holding the registry lock.
|
||||
func RegisteredSpecGroupsIter() iter.Seq[RouteGroup] {
|
||||
specRegistry.mu.RLock()
|
||||
groups := slices.Clone(specRegistry.groups)
|
||||
specRegistry.mu.RUnlock()
|
||||
|
||||
return slices.Values(groups)
|
||||
}
|
||||
|
||||
// ResetSpecGroups clears the package-level spec registry.
|
||||
// It is primarily intended for tests that need to isolate global state.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -45,3 +45,33 @@ func TestRegisterSpecGroups_Good_DeduplicatesByIdentity(t *testing.T) {
|
|||
t.Fatalf("expected second group to be beta at /beta, got %s at %s", groups[1].Name(), groups[1].BasePath())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterSpecGroups_Good_IteratorReturnsSnapshot(t *testing.T) {
|
||||
snapshot := api.RegisteredSpecGroups()
|
||||
api.ResetSpecGroups()
|
||||
t.Cleanup(func() {
|
||||
api.ResetSpecGroups()
|
||||
api.RegisterSpecGroups(snapshot...)
|
||||
})
|
||||
|
||||
first := &specRegistryStubGroup{name: "alpha", basePath: "/alpha"}
|
||||
second := &specRegistryStubGroup{name: "beta", basePath: "/beta"}
|
||||
|
||||
api.RegisterSpecGroups(first)
|
||||
|
||||
iter := api.RegisteredSpecGroupsIter()
|
||||
|
||||
api.RegisterSpecGroups(second)
|
||||
|
||||
var groups []api.RouteGroup
|
||||
for group := range iter {
|
||||
groups = append(groups, group)
|
||||
}
|
||||
|
||||
if len(groups) != 1 {
|
||||
t.Fatalf("expected iterator snapshot to contain 1 group, got %d", len(groups))
|
||||
}
|
||||
if groups[0].Name() != "alpha" || groups[0].BasePath() != "/alpha" {
|
||||
t.Fatalf("expected iterator snapshot to preserve alpha at /alpha, got %s at %s", groups[0].Name(), groups[0].BasePath())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue