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 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()) }