Git Repository
Stackyard
Stackyard scannt lokale Entwicklungsordner und bündelt Projekte, Git-Status, TODOs, Toolchains, Docker-Compose-Setups, Datei- und Launcher-Funktionen sowie Operations-Informationen in einer lokalen WebUI.
HTTPS
https://zanvex.de/git/stackyard.gitinternal/operations/operations_test.go
Zum Verzeichnispackage operations
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
"stackyard/internal/project"
)
func TestLoadManifestAndActionWhitelist(t *testing.T) {
root := t.TempDir()
if err := os.MkdirAll(filepath.Join(root, ".stackyard"), 0o755); err != nil {
t.Fatal(err)
}
data := []byte("provider: go\nactions:\n - name: Tests\n kind: go-test\n")
if err := os.WriteFile(filepath.Join(root, ".stackyard", "project.yaml"), data, 0o644); err != nil {
t.Fatal(err)
}
manifest := LoadManifest(root)
if manifest.Provider != "go" || len(manifest.Actions) != 1 {
t.Fatalf("unexpected manifest: %+v", manifest)
}
if ValidateAction("go-test") != nil || ValidateAction("shell") == nil {
t.Fatal("unexpected action whitelist result")
}
}
func TestCollectTodos(t *testing.T) {
root := t.TempDir()
if err := os.WriteFile(filepath.Join(root, "TODO.md"), []byte("- [ ] offen\n- [x] fertig\ntext"), 0o644); err != nil {
t.Fatal(err)
}
items := CollectTodos([]project.Project{{ID: "p", Name: "Demo", Path: root}})
if len(items) != 2 || items[0].Text != "offen" || !items[1].Done {
t.Fatalf("unexpected todo items: %+v", items)
}
}
func TestLoopbackURLValidation(t *testing.T) {
if !isLoopbackURL("http://127.0.0.1:8080/health") || !isLoopbackURL("http://localhost:3000") {
t.Fatal("expected loopback URLs to be accepted")
}
if isLoopbackURL("https://example.com/collect") || isLoopbackURL("file:///tmp/test") {
t.Fatal("expected non-loopback URLs to be rejected")
}
}
func TestBoundedLogKeepsNewestOutput(t *testing.T) {
log := &boundedLog{max: 5}
if _, err := log.Write([]byte("1234")); err != nil {
t.Fatal(err)
}
if _, err := log.Write([]byte("567")); err != nil {
t.Fatal(err)
}
if got := log.String(); got != "34567" {
t.Fatalf("unexpected bounded log: %q", got)
}
}
func TestProcessManagerRejectsOneShotAction(t *testing.T) {
manager := NewProcessManager()
if err := manager.Start("project", t.TempDir(), "go-test"); err == nil {
t.Fatal("expected one-shot action to be rejected as a service")
}
}
func TestProcessManagerCapturesServiceOutput(t *testing.T) {
root := t.TempDir()
if err := os.WriteFile(filepath.Join(root, "go.mod"), []byte("module process-test\n\ngo 1.24\n"), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(root, "main.go"), []byte("package main\nimport \"fmt\"\nfunc main() { fmt.Print(\"service-ready\") }\n"), 0o644); err != nil {
t.Fatal(err)
}
manager := NewProcessManager()
if err := manager.Start("project", root, "go-run"); err != nil {
t.Fatalf("start service: %v", err)
}
deadline := time.Now().Add(10 * time.Second)
for time.Now().Before(deadline) {
status := manager.Status("project", "go-run")
if !status.Running {
if status.Error != "" || !strings.Contains(status.Log, "service-ready") {
t.Fatalf("unexpected final status: %+v", status)
}
return
}
time.Sleep(25 * time.Millisecond)
}
manager.StopAll()
t.Fatal("service did not finish")
}