- Non-TTY widgets/prompts, flag parsing, secret non-leak and malicious IDs - Real hello workspace rebuild latency line, debounce and ignored bin/tmp - scripts/check-phase1.sh runs vet/test/race across root, hello, base, greeter, optional
157 lines
4.3 KiB
Go
157 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/backpack"
|
|
"git.golem15.com/golem15/summercms/bonfire"
|
|
"git.golem15.com/golem15/summercms/compass"
|
|
"git.golem15.com/golem15/summercms/pact"
|
|
"git.golem15.com/golem15/summercms/party"
|
|
)
|
|
|
|
func TestGreeterHelloPrintsLayeredConfig(t *testing.T) {
|
|
got := runHello(t, nil)
|
|
want := "name=hello-app posts_per_page=10 debug=false extra=hello-from-optional events=ok collected=greeter handled=true"
|
|
assertGreeting(t, got, want)
|
|
}
|
|
|
|
func TestGreeterHelloSeesDevelopmentOverlay(t *testing.T) {
|
|
got := runHello(t, map[string]string{"SUMMER_ENV": "development"})
|
|
want := "name=hello-dev posts_per_page=10 debug=true extra=hello-from-optional events=ok collected=greeter handled=true"
|
|
assertGreeting(t, got, want)
|
|
}
|
|
|
|
func TestGreeterHelloSeesEnvVarOverrideOfPluginDefault(t *testing.T) {
|
|
got := runHello(t, map[string]string{
|
|
"SUMMER_GOLEM15__HELLO__POSTS_PER_PAGE": "25",
|
|
})
|
|
want := "name=hello-app posts_per_page=25 debug=false extra=hello-from-optional events=ok collected=greeter handled=true"
|
|
assertGreeting(t, got, want)
|
|
}
|
|
|
|
func runHello(t *testing.T, env map[string]string) string {
|
|
t.Helper()
|
|
for k, v := range env {
|
|
t.Setenv(k, v)
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := run([]string{"greeter:hello"}, &buf); err != nil {
|
|
t.Fatalf("greeter:hello: %v", err)
|
|
}
|
|
return strings.TrimSpace(buf.String())
|
|
}
|
|
|
|
func TestGreeterRunsWithoutOptionalPlugin(t *testing.T) {
|
|
got := runHelloIDs(t, []string{"golem15.hello", "golem15.greeter"}, nil)
|
|
want := "name=hello-app posts_per_page=10 debug=false extra= events=ok collected=greeter handled=true"
|
|
assertGreeting(t, got, want)
|
|
}
|
|
|
|
func runHelloIDs(t *testing.T, ids []string, env map[string]string) string {
|
|
t.Helper()
|
|
for k, v := range env {
|
|
t.Setenv(k, v)
|
|
}
|
|
cfg, err := compass.Load("config")
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
app := backpack.New(cfg)
|
|
plugins, err := party.Activate(app, ids)
|
|
if err != nil {
|
|
t.Fatalf("Activate: %v", err)
|
|
}
|
|
var commands []bonfire.Command
|
|
for _, plugin := range plugins {
|
|
if hasCommands, ok := plugin.(pact.HasCommands); ok {
|
|
commands = append(commands, hasCommands.Commands()...)
|
|
}
|
|
}
|
|
var buf bytes.Buffer
|
|
root, err := bonfire.NewRoot("hello", commands, &buf)
|
|
if err != nil {
|
|
t.Fatalf("NewRoot: %v", err)
|
|
}
|
|
root.SetArgs([]string{"greeter:hello"})
|
|
if err := root.Execute(); err != nil {
|
|
t.Fatalf("execute: %v", err)
|
|
}
|
|
return strings.TrimSpace(buf.String())
|
|
}
|
|
|
|
func TestBuiltBinaryGreeterHello(t *testing.T) {
|
|
first := runSummerBuild(t)
|
|
h1 := generatedHash(t)
|
|
second := runSummerBuild(t)
|
|
h2 := generatedHash(t)
|
|
if h1 != h2 {
|
|
t.Fatalf("generated files changed on second build\nfirst:\n%s\nsecond:\n%s", first, second)
|
|
}
|
|
|
|
cmd := exec.Command("./bin/hello", "greeter:hello")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("bin/hello greeter:hello: %v\n%s", err, out)
|
|
}
|
|
got := strings.TrimSpace(string(out))
|
|
want := "name=hello-app posts_per_page=10 debug=false extra=hello-from-optional events=ok collected=greeter handled=true"
|
|
assertGreeting(t, got, want)
|
|
}
|
|
|
|
func TestBuiltBinaryUnknownCommandExitsNonZero(t *testing.T) {
|
|
runSummerBuild(t)
|
|
cmd := exec.Command("./bin/hello", "does:not-exist")
|
|
out, err := cmd.CombinedOutput()
|
|
if err == nil {
|
|
t.Fatalf("expected non-zero exit, output:\n%s", out)
|
|
}
|
|
}
|
|
|
|
func assertGreeting(t *testing.T, got, want string) {
|
|
t.Helper()
|
|
if !strings.Contains(got, "plugin\tstatus") || !strings.Contains(got, "golem15.greeter\tactive") {
|
|
t.Fatalf("missing non-tty table:\n%s", got)
|
|
}
|
|
if lastLine(got) != want {
|
|
t.Fatalf("greeting = %q, want %q\nfull:\n%s", lastLine(got), want, got)
|
|
}
|
|
}
|
|
|
|
func lastLine(s string) string {
|
|
s = strings.TrimSpace(s)
|
|
if i := strings.LastIndex(s, "\n"); i >= 0 {
|
|
return s[i+1:]
|
|
}
|
|
return s
|
|
}
|
|
|
|
func runSummerBuild(t *testing.T) string {
|
|
t.Helper()
|
|
cmd := exec.Command("go", "run", "../../cmd/summer", "build")
|
|
cmd.Dir = "."
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("summer build: %v\n%s", err, out)
|
|
}
|
|
return string(out)
|
|
}
|
|
|
|
func generatedHash(t *testing.T) [32]byte {
|
|
t.Helper()
|
|
var buf bytes.Buffer
|
|
for _, name := range []string{"main.go", "plugins.gen.go"} {
|
|
body, err := os.ReadFile(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
buf.Write(body)
|
|
}
|
|
return sha256.Sum256(buf.Bytes())
|
|
}
|