Replace fmt/errors/strings/encoding/json/os/os/exec/path/filepath with
core primitives; rename abbreviated variables; add Ugly test variants to
all test files; rename integration tests to TestFilename_Function_{Good,Bad,Ugly}.
Co-Authored-By: Virgil <virgil@lethean.io>
212 lines
5.9 KiB
Go
212 lines
5.9 KiB
Go
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
package api_test
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
|
|
api "dappco.re/go/core/api"
|
|
)
|
|
|
|
type streamGroupStub struct {
|
|
healthGroup
|
|
channels []string
|
|
}
|
|
|
|
func (s *streamGroupStub) Channels() []string { return s.channels }
|
|
|
|
// ── GroupsIter ────────────────────────────────────────────────────────
|
|
|
|
func TestModernization_GroupsIter_Good(t *testing.T) {
|
|
engine, _ := api.New()
|
|
engine.Register(&healthGroup{})
|
|
|
|
var groups []api.RouteGroup
|
|
for group := range engine.GroupsIter() {
|
|
groups = append(groups, group)
|
|
}
|
|
|
|
if len(groups) != 1 {
|
|
t.Fatalf("expected 1 group, got %d", len(groups))
|
|
}
|
|
if groups[0].Name() != "health-extra" {
|
|
t.Errorf("expected group name 'health-extra', got %q", groups[0].Name())
|
|
}
|
|
}
|
|
|
|
func TestModernization_GroupsIter_Bad(t *testing.T) {
|
|
engine, _ := api.New()
|
|
// No groups registered — iterator should yield nothing.
|
|
var groups []api.RouteGroup
|
|
for group := range engine.GroupsIter() {
|
|
groups = append(groups, group)
|
|
}
|
|
if len(groups) != 0 {
|
|
t.Fatalf("expected 0 groups with no registration, got %d", len(groups))
|
|
}
|
|
}
|
|
|
|
func TestModernization_GroupsIter_Ugly(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Fatalf("GroupsIter on nil groups panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
engine, _ := api.New()
|
|
// Iterating immediately without any Register call must not panic.
|
|
for range engine.GroupsIter() {
|
|
t.Fatal("expected no iterations")
|
|
}
|
|
}
|
|
|
|
// ── ChannelsIter ──────────────────────────────────────────────────────
|
|
|
|
func TestModernization_ChannelsIter_Good(t *testing.T) {
|
|
engine, _ := api.New()
|
|
engine.Register(&streamGroupStub{channels: []string{"ch1", "ch2"}})
|
|
engine.Register(&streamGroupStub{channels: []string{"ch3"}})
|
|
|
|
var channels []string
|
|
for channelName := range engine.ChannelsIter() {
|
|
channels = append(channels, channelName)
|
|
}
|
|
|
|
expected := []string{"ch1", "ch2", "ch3"}
|
|
if !slices.Equal(channels, expected) {
|
|
t.Fatalf("expected channels %v, got %v", expected, channels)
|
|
}
|
|
}
|
|
|
|
func TestModernization_ChannelsIter_Bad(t *testing.T) {
|
|
engine, _ := api.New()
|
|
// Register a group that has no Channels() — ChannelsIter must skip it.
|
|
engine.Register(&healthGroup{})
|
|
|
|
var channels []string
|
|
for channelName := range engine.ChannelsIter() {
|
|
channels = append(channels, channelName)
|
|
}
|
|
|
|
if len(channels) != 0 {
|
|
t.Fatalf("expected 0 channels for non-StreamGroup, got %v", channels)
|
|
}
|
|
}
|
|
|
|
func TestModernization_ChannelsIter_Ugly(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Fatalf("ChannelsIter panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
engine, _ := api.New()
|
|
// Group with empty channel list must not panic during iteration.
|
|
engine.Register(&streamGroupStub{channels: []string{}})
|
|
for range engine.ChannelsIter() {
|
|
t.Fatal("expected no iterations for empty channel list")
|
|
}
|
|
}
|
|
|
|
// ── ToolBridge iterators ──────────────────────────────────────────────
|
|
|
|
func TestModernization_ToolBridgeIterators_Good(t *testing.T) {
|
|
bridge := api.NewToolBridge("/tools")
|
|
bridge.Add(api.ToolDescriptor{Name: "test", Group: "g1"}, nil)
|
|
|
|
var tools []api.ToolDescriptor
|
|
for tool := range bridge.ToolsIter() {
|
|
tools = append(tools, tool)
|
|
}
|
|
if len(tools) != 1 || tools[0].Name != "test" {
|
|
t.Errorf("ToolsIter failed, got %v", tools)
|
|
}
|
|
|
|
var descs []api.RouteDescription
|
|
for desc := range bridge.DescribeIter() {
|
|
descs = append(descs, desc)
|
|
}
|
|
if len(descs) != 1 || descs[0].Path != "/test" {
|
|
t.Errorf("DescribeIter failed, got %v", descs)
|
|
}
|
|
}
|
|
|
|
func TestModernization_ToolBridgeIterators_Bad(t *testing.T) {
|
|
bridge := api.NewToolBridge("/tools")
|
|
// Empty bridge — iterators must yield nothing.
|
|
for range bridge.ToolsIter() {
|
|
t.Fatal("expected no iterations on empty bridge (ToolsIter)")
|
|
}
|
|
for range bridge.DescribeIter() {
|
|
t.Fatal("expected no iterations on empty bridge (DescribeIter)")
|
|
}
|
|
}
|
|
|
|
func TestModernization_ToolBridgeIterators_Ugly(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Fatalf("ToolBridge iterator with nil handler panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
bridge := api.NewToolBridge("/tools")
|
|
bridge.Add(api.ToolDescriptor{Name: "noop"}, nil)
|
|
|
|
var toolCount int
|
|
for range bridge.ToolsIter() {
|
|
toolCount++
|
|
}
|
|
if toolCount != 1 {
|
|
t.Fatalf("expected 1 tool, got %d", toolCount)
|
|
}
|
|
}
|
|
|
|
// ── SupportedLanguagesIter ────────────────────────────────────────────
|
|
|
|
func TestModernization_SupportedLanguagesIter_Good(t *testing.T) {
|
|
var langs []string
|
|
for language := range api.SupportedLanguagesIter() {
|
|
langs = append(langs, language)
|
|
}
|
|
|
|
if !slices.Contains(langs, "go") {
|
|
t.Errorf("SupportedLanguagesIter missing 'go'")
|
|
}
|
|
if !slices.IsSorted(langs) {
|
|
t.Errorf("SupportedLanguagesIter should be sorted, got %v", langs)
|
|
}
|
|
}
|
|
|
|
func TestModernization_SupportedLanguagesIter_Bad(t *testing.T) {
|
|
// Iterator and slice function must agree on count.
|
|
iterCount := 0
|
|
for range api.SupportedLanguagesIter() {
|
|
iterCount++
|
|
}
|
|
sliceCount := len(api.SupportedLanguages())
|
|
if iterCount != sliceCount {
|
|
t.Fatalf("SupportedLanguagesIter count %d != SupportedLanguages count %d", iterCount, sliceCount)
|
|
}
|
|
}
|
|
|
|
func TestModernization_SupportedLanguagesIter_Ugly(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Fatalf("SupportedLanguagesIter panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
// Calling multiple times concurrently should not panic.
|
|
done := make(chan struct{}, 5)
|
|
for goroutineIndex := 0; goroutineIndex < 5; goroutineIndex++ {
|
|
go func() {
|
|
for range api.SupportedLanguagesIter() {
|
|
}
|
|
done <- struct{}{}
|
|
}()
|
|
}
|
|
for goroutineIndex := 0; goroutineIndex < 5; goroutineIndex++ {
|
|
<-done
|
|
}
|
|
}
|