- delegateCommands() builds every delegate from one table of name, description and common-flags hint; toolCommands appends it - route:list, key:generate, admin:create and admin:reset-password are new delegates; the child keeps summer's stdin, so the password prompts work - migrate:rollback, queue:work and schedule:run lose their hand-written flag copies: --plugin, --queue and --once now pass through verbatim - the command list marks delegates with "(flags pass to the app binary)" and the help command prints a Long text with the common flags - console introduction, setup-and-maintenance and the root README describe the passthrough behaviour and the new delegates
116 lines
3.1 KiB
Go
116 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/bonfire"
|
|
)
|
|
|
|
// captureAppRunner replaces appRunner for the test and returns a pointer to
|
|
// the argv of the last call.
|
|
func captureAppRunner(t *testing.T) *[]string {
|
|
t.Helper()
|
|
got := new([]string)
|
|
prev := appRunner
|
|
appRunner = func(ctx context.Context, argv []string, out bonfire.Output) error {
|
|
*got = append([]string(nil), argv...)
|
|
return nil
|
|
}
|
|
t.Cleanup(func() { appRunner = prev })
|
|
return got
|
|
}
|
|
|
|
func TestDelegatedServePassesFlags(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
args []string
|
|
want []string
|
|
}{
|
|
{[]string{"serve", "--addr", ":8123"}, []string{"serve", "--addr", ":8123"}},
|
|
{[]string{"serve", "--help"}, []string{"serve", "--help"}},
|
|
{[]string{"serve", "-h"}, []string{"serve", "-h"}},
|
|
{[]string{"serve", "--addr=:8123"}, []string{"serve", "--addr=:8123"}},
|
|
{[]string{"serve", "--", "--addr", ":8123"}, []string{"serve", "--addr", ":8123"}},
|
|
} {
|
|
got := captureAppRunner(t)
|
|
if out, err := runSummer(t, tc.args...); err != nil {
|
|
t.Fatalf("%q: %v\n%s", tc.args, err, out)
|
|
}
|
|
if !slices.Equal(*got, tc.want) {
|
|
t.Fatalf("%q: argv = %q, want %q", tc.args, *got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDelegateCommandsPassArgs(t *testing.T) {
|
|
for _, args := range [][]string{
|
|
{"migrate:rollback", "--plugin", "acme.blog"},
|
|
{"queue:work", "--queue", "a", "--queue", "b"},
|
|
{"schedule:run", "--once"},
|
|
{"queue:clear", "emails"},
|
|
{"migrate"},
|
|
{"migrate:status", "--help"},
|
|
{"route:list"},
|
|
{"key:generate"},
|
|
{"admin:create", "--email", "you@example.com", "--superuser"},
|
|
{"admin:reset-password", "admin@example.com"},
|
|
} {
|
|
got := captureAppRunner(t)
|
|
if out, err := runSummer(t, args...); err != nil {
|
|
t.Fatalf("%q: %v\n%s", args, err, out)
|
|
}
|
|
if !slices.Equal(*got, args) {
|
|
t.Fatalf("%q: argv = %q, want %q", args, *got, args)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDelegateCommandsHelp(t *testing.T) {
|
|
hints := map[string][]string{
|
|
"migrate:rollback": {"--plugin"},
|
|
"queue:work": {"--queue"},
|
|
"schedule:run": {"--once"},
|
|
"serve": {"--addr"},
|
|
"admin:create": {"--email", "--superuser"},
|
|
}
|
|
cmds := delegateCommands()
|
|
if len(cmds) != 11 {
|
|
t.Fatalf("delegateCommands() has %d commands, want 11", len(cmds))
|
|
}
|
|
got := captureAppRunner(t)
|
|
for _, c := range cmds {
|
|
out, err := runSummer(t, "help", c.Name)
|
|
if err != nil {
|
|
t.Fatalf("help %s: %v", c.Name, err)
|
|
}
|
|
for _, want := range append([]string{"passed to the app binary"}, hints[c.Name]...) {
|
|
if !strings.Contains(out, want) {
|
|
t.Fatalf("help %s missing %q:\n%s", c.Name, want, out)
|
|
}
|
|
}
|
|
}
|
|
if *got != nil {
|
|
t.Fatalf("help ran the app binary with %q", *got)
|
|
}
|
|
|
|
out, err := runSummer(t, "--help")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, c := range cmds {
|
|
found := false
|
|
for _, line := range strings.Split(out, "\n") {
|
|
fields := strings.Fields(line)
|
|
if len(fields) > 0 && fields[0] == c.Name && strings.Contains(line, "(flags pass to the app binary)") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatalf("summer --help does not mark %s:\n%s", c.Name, out)
|
|
}
|
|
}
|
|
}
|