test(01-04): cover config, lifecycle, services, events and context
- Table-driven compass precedence, malformed YAML, snake_case env and concurrent reads - Party duplicate/missing/cycle, reordered manifest, HasConfig/HasCommands discovery - Isolated backpack services, festival panic payload omission, towel nested isolation
This commit is contained in:
@@ -9,7 +9,9 @@ import (
|
||||
"testing/fstest"
|
||||
|
||||
"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 tracePlugin struct {
|
||||
@@ -225,3 +227,170 @@ func TestActivateRunsAllRegisterBeforeAnyBoot(t *testing.T) {
|
||||
t.Fatalf("lifecycle = %v, want %v", log, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActivateReorderedManifestStillTopoSorts(t *testing.T) {
|
||||
var log []string
|
||||
hello := &tracePlugin{id: "golem15.hello", log: &log}
|
||||
greeter := &tracePlugin{id: "golem15.greeter", req: []string{"golem15.hello"}, log: &log}
|
||||
extra := &tracePlugin{id: "golem15.extra", req: []string{"golem15.greeter"}, log: &log}
|
||||
app := backpack.New(&compass.Config{})
|
||||
got, err := activate(
|
||||
[]Plugin{extra, greeter, hello},
|
||||
app,
|
||||
[]string{"golem15.extra", "golem15.hello", "golem15.greeter"},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("activate: %v", err)
|
||||
}
|
||||
if len(got) != 3 || got[0].ID() != "golem15.hello" || got[1].ID() != "golem15.greeter" || got[2].ID() != "golem15.extra" {
|
||||
t.Fatalf("order = %v, want hello, greeter, extra", idsOf(got))
|
||||
}
|
||||
want := []string{
|
||||
"golem15.hello:register",
|
||||
"golem15.greeter:register",
|
||||
"golem15.extra:register",
|
||||
"golem15.hello:boot",
|
||||
"golem15.greeter:boot",
|
||||
"golem15.extra:boot",
|
||||
}
|
||||
if strings.Join(log, ",") != strings.Join(want, ",") {
|
||||
t.Fatalf("lifecycle = %v, want %v", log, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActivateDuplicateManifestIDRejected(t *testing.T) {
|
||||
var log []string
|
||||
p := &tracePlugin{id: "golem15.hello", log: &log}
|
||||
app := backpack.New(&compass.Config{})
|
||||
_, err := activate([]Plugin{p}, app, []string{"golem15.hello", "golem15.hello"})
|
||||
if err == nil {
|
||||
t.Fatal("expected duplicate manifest id error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "golem15.hello") {
|
||||
t.Fatalf("error %q should name the duplicate id", err)
|
||||
}
|
||||
if len(log) != 0 {
|
||||
t.Fatalf("lifecycle ran despite duplicate manifest: %v", log)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActivateUnregisteredPluginNamesID(t *testing.T) {
|
||||
app := backpack.New(&compass.Config{})
|
||||
_, err := activate(nil, app, []string{"golem15.missing"})
|
||||
if err == nil {
|
||||
t.Fatal("expected missing registered plugin error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "golem15.missing") {
|
||||
t.Fatalf("error %q should name the missing id", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActivateEmptyManifestIDRejected(t *testing.T) {
|
||||
var log []string
|
||||
p := &tracePlugin{id: "golem15.hello", log: &log}
|
||||
app := backpack.New(&compass.Config{})
|
||||
_, err := activate([]Plugin{p}, app, []string{""})
|
||||
if err == nil {
|
||||
t.Fatal("expected empty plugin id error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestActivateNilAppRejected(t *testing.T) {
|
||||
_, err := Activate(nil, []string{"golem15.hello"})
|
||||
if err == nil {
|
||||
t.Fatal("expected nil app error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterNilIsNoop(t *testing.T) {
|
||||
Register(nil)
|
||||
}
|
||||
|
||||
func TestActivateHasPluginFalseForUnselected(t *testing.T) {
|
||||
var log []string
|
||||
hello := &tracePlugin{id: "golem15.hello", log: &log}
|
||||
opt := &tracePlugin{id: "golem15.optional", log: &log}
|
||||
app := backpack.New(&compass.Config{})
|
||||
if _, err := activate([]Plugin{hello, opt}, app, []string{"golem15.hello"}); err != nil {
|
||||
t.Fatalf("activate: %v", err)
|
||||
}
|
||||
if !app.HasPlugin("golem15.hello") {
|
||||
t.Fatal("selected plugin must be present")
|
||||
}
|
||||
if app.HasPlugin("golem15.optional") {
|
||||
t.Fatal("unselected registered plugin must not appear in HasPlugin")
|
||||
}
|
||||
}
|
||||
|
||||
type commandsPlugin struct {
|
||||
tracePlugin
|
||||
}
|
||||
|
||||
func (p *commandsPlugin) Commands() []bonfire.Command {
|
||||
return []bonfire.Command{{
|
||||
Name: "demo:run",
|
||||
Description: "demo command",
|
||||
}}
|
||||
}
|
||||
|
||||
func TestActivateDiscoversHasConfigAndHasCommands(t *testing.T) {
|
||||
var log []string
|
||||
var got int
|
||||
cfgPlugin := &configPlugin{
|
||||
id: "golem15.hello",
|
||||
got: &got,
|
||||
fsys: fstest.MapFS{
|
||||
"config/config.yaml": {Data: []byte("posts_per_page: 4\n")},
|
||||
},
|
||||
}
|
||||
cmdPlugin := &commandsPlugin{tracePlugin: tracePlugin{id: "golem15.demo", log: &log}}
|
||||
plain := &tracePlugin{id: "golem15.plain", log: &log}
|
||||
|
||||
dir := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: app\n"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg, err := compass.Load(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
app := backpack.New(cfg)
|
||||
gotPlugins, err := activate([]Plugin{cfgPlugin, cmdPlugin, plain}, app, []string{"golem15.hello", "golem15.demo", "golem15.plain"})
|
||||
if err != nil {
|
||||
t.Fatalf("activate: %v", err)
|
||||
}
|
||||
if got != 4 {
|
||||
t.Fatalf("HasConfig value during Register = %d, want 4", got)
|
||||
}
|
||||
|
||||
var sawConfig, sawCommands, sawPlainCommands bool
|
||||
for _, p := range gotPlugins {
|
||||
if _, ok := p.(pact.HasConfig); ok && p.ID() == "golem15.hello" {
|
||||
sawConfig = true
|
||||
}
|
||||
if hc, ok := p.(pact.HasCommands); ok {
|
||||
if p.ID() == "golem15.demo" {
|
||||
cmds := hc.Commands()
|
||||
if len(cmds) != 1 || cmds[0].Name != "demo:run" {
|
||||
t.Fatalf("HasCommands commands = %+v", cmds)
|
||||
}
|
||||
sawCommands = true
|
||||
}
|
||||
if p.ID() == "golem15.plain" {
|
||||
sawPlainCommands = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !sawConfig {
|
||||
t.Fatal("golem15.hello should satisfy HasConfig")
|
||||
}
|
||||
if !sawCommands {
|
||||
t.Fatal("golem15.demo should satisfy HasCommands")
|
||||
}
|
||||
if sawPlainCommands {
|
||||
t.Fatal("plain plugin must not satisfy HasCommands")
|
||||
}
|
||||
if _, ok := any(plain).(pact.HasConfig); ok {
|
||||
t.Fatal("plain plugin must not satisfy HasConfig")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user