test(01-02): add failing test for optional plugin services
- Cover typed Publish/Lookup, duplicate providers and HasPlugin - Require missing/cycle errors to name plugin IDs before Boot - Assert greeter works with and without an optional extra
This commit is contained in:
@@ -7,11 +7,17 @@ import (
|
||||
"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"
|
||||
want := "name=hello-app posts_per_page=10 debug=false extra=hello-from-optional"
|
||||
if got != want {
|
||||
t.Fatalf("output = %q, want %q", got, want)
|
||||
}
|
||||
@@ -19,7 +25,7 @@ func TestGreeterHelloPrintsLayeredConfig(t *testing.T) {
|
||||
|
||||
func TestGreeterHelloSeesDevelopmentOverlay(t *testing.T) {
|
||||
got := runHello(t, map[string]string{"SUMMER_ENV": "development"})
|
||||
want := "name=hello-dev posts_per_page=10 debug=true"
|
||||
want := "name=hello-dev posts_per_page=10 debug=true extra=hello-from-optional"
|
||||
if got != want {
|
||||
t.Fatalf("output = %q, want %q", got, want)
|
||||
}
|
||||
@@ -29,7 +35,7 @@ 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"
|
||||
want := "name=hello-app posts_per_page=25 debug=false extra=hello-from-optional"
|
||||
if got != want {
|
||||
t.Fatalf("output = %q, want %q", got, want)
|
||||
}
|
||||
@@ -47,6 +53,43 @@ func runHello(t *testing.T, env map[string]string) string {
|
||||
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="
|
||||
if got != want {
|
||||
t.Fatalf("output = %q, want %q", 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 := bonfire.NewRoot("hello", commands, &buf)
|
||||
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)
|
||||
@@ -61,8 +104,8 @@ func TestBuiltBinaryGreeterHello(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("bin/hello greeter:hello: %v\n%s", err, out)
|
||||
}
|
||||
if got := strings.TrimSpace(string(out)); got != "name=hello-app posts_per_page=10 debug=false" {
|
||||
t.Fatalf("output = %q, want layered production config", got)
|
||||
if got := strings.TrimSpace(string(out)); got != "name=hello-app posts_per_page=10 debug=false extra=hello-from-optional" {
|
||||
t.Fatalf("output = %q, want layered production config with optional extra", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
75
examples/hello/plugins/greeter/plugin_test.go
Normal file
75
examples/hello/plugins/greeter/plugin_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package greeter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"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"
|
||||
)
|
||||
|
||||
type testOut struct{ bytes.Buffer }
|
||||
|
||||
func (o *testOut) Write(p []byte) (int, error) { return o.Buffer.Write(p) }
|
||||
func (o *testOut) Println(a ...any) { fmt.Fprintln(&o.Buffer, a...) }
|
||||
func (o *testOut) Printf(format string, a ...any) {
|
||||
fmt.Fprintf(&o.Buffer, format, a...)
|
||||
}
|
||||
|
||||
var _ bonfire.Output = (*testOut)(nil)
|
||||
var _ io.Writer = (*testOut)(nil)
|
||||
|
||||
type extraMsg struct{ msg string }
|
||||
|
||||
func (e extraMsg) Message() string { return e.msg }
|
||||
|
||||
func TestBootSkipsAbsentOptionalPlugin(t *testing.T) {
|
||||
app := backpack.New(&compass.Config{})
|
||||
app.SetPlugins([]string{"golem15.hello", "golem15.greeter"})
|
||||
p := &Plugin{}
|
||||
if err := p.Boot(app); err != nil {
|
||||
t.Fatalf("Boot: %v", err)
|
||||
}
|
||||
out := runHelloCmd(t, p)
|
||||
if strings.Contains(out, "hello-from-optional") {
|
||||
t.Fatalf("absent optional leaked into output: %q", out)
|
||||
}
|
||||
if !strings.Contains(out, "extra=") {
|
||||
t.Fatalf("output %q should include extra=", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootUsesPublishedOptionalService(t *testing.T) {
|
||||
app := backpack.New(&compass.Config{})
|
||||
app.SetPlugins([]string{"golem15.hello", "golem15.greeter", "golem15.optional"})
|
||||
if err := app.Publish[pact.OptionalMessage](extraMsg{msg: "hello-from-optional"}); err != nil {
|
||||
t.Fatalf("Publish: %v", err)
|
||||
}
|
||||
p := &Plugin{}
|
||||
if err := p.Boot(app); err != nil {
|
||||
t.Fatalf("Boot: %v", err)
|
||||
}
|
||||
out := runHelloCmd(t, p)
|
||||
if !strings.Contains(out, "extra=hello-from-optional") {
|
||||
t.Fatalf("output = %q, want extra=hello-from-optional", out)
|
||||
}
|
||||
}
|
||||
|
||||
func runHelloCmd(t *testing.T, p *Plugin) string {
|
||||
t.Helper()
|
||||
cmds := p.Commands()
|
||||
if len(cmds) == 0 {
|
||||
t.Fatal("no commands")
|
||||
}
|
||||
var out testOut
|
||||
if err := cmds[0].Run(context.Background(), nil, &out); err != nil {
|
||||
t.Fatalf("Run: %v", err)
|
||||
}
|
||||
return strings.TrimSpace(out.String())
|
||||
}
|
||||
Reference in New Issue
Block a user