package pact import ( "io/fs" "testing" "testing/fstest" "git.golem15.com/golem15/summercms/bonfire" "github.com/go-gormigrate/gormigrate/v2" ) type configOnly struct{} func (configOnly) ConfigFS() fs.FS { return fstest.MapFS{"config/config.yaml": {Data: []byte("k: 1\n")}} } type commandsOnly struct{} func (commandsOnly) Commands() []bonfire.Command { return []bonfire.Command{{Name: "demo:run"}} } type bothCaps struct { configOnly commandsOnly } type neither struct{} type migrationsOnly struct{} func (migrationsOnly) Migrations() []*gormigrate.Migration { return []*gormigrate.Migration{{ID: "202609170001_create_users"}} } func TestOptionalCapabilitiesDiscoveredByTypeAssertion(t *testing.T) { plugins := []any{configOnly{}, commandsOnly{}, bothCaps{}, neither{}, extraMessage{}, migrationsOnly{}} var configs, commands, messages, migrations, none int for _, p := range plugins { _, hasCfg := p.(HasConfig) _, hasCmd := p.(HasCommands) _, hasMsg := p.(OptionalMessage) _, hasMig := p.(HasMigrations) if hasCfg { configs++ } if hasCmd { commands++ } if hasMsg { messages++ } if hasMig { migrations++ } if !hasCfg && !hasCmd && !hasMsg && !hasMig { none++ } } if configs != 2 { t.Fatalf("HasConfig count = %d, want 2", configs) } if commands != 2 { t.Fatalf("HasCommands count = %d, want 2", commands) } if messages != 1 { t.Fatalf("OptionalMessage count = %d, want 1", messages) } if migrations != 1 { t.Fatalf("HasMigrations count = %d, want 1", migrations) } if none != 1 { t.Fatalf("neither count = %d, want 1", none) } } func TestHasMigrationsReturnsOrderedSet(t *testing.T) { var p HasMigrations = migrationsOnly{} set := p.Migrations() if len(set) != 1 || set[0].ID != "202609170001_create_users" { t.Fatalf("Migrations = %+v", set) } } func TestHasConfigReturnsFilesystem(t *testing.T) { var p HasConfig = configOnly{} fsys := p.ConfigFS() if fsys == nil { t.Fatal("ConfigFS returned nil") } raw, err := fs.ReadFile(fsys, "config/config.yaml") if err != nil { t.Fatal(err) } if string(raw) != "k: 1\n" { t.Fatalf("ConfigFS body = %q", raw) } } func TestHasCommandsReturnsNamespacedCommand(t *testing.T) { var p HasCommands = commandsOnly{} cmds := p.Commands() if len(cmds) != 1 || cmds[0].Name != "demo:run" { t.Fatalf("Commands = %+v", cmds) } } func TestOptionalMessageContract(t *testing.T) { var msg OptionalMessage = extraMessage{s: "hello-from-optional"} if msg.Message() != "hello-from-optional" { t.Fatalf("Message = %q", msg.Message()) } } type extraMessage struct{ s string } func (e extraMessage) Message() string { return e.s } type routesOnly struct{} func (routesOnly) Routes(Router) error { return nil } type middlewareOnly struct{} func (middlewareOnly) Middlewares() map[string]Middleware { return map[string]Middleware{"jwt.auth": nil} } type modelsOnly struct{} func (modelsOnly) Models() []any { return []any{struct{}{}} } func TestHTTPCapabilitiesDiscoveredByTypeAssertion(t *testing.T) { var r HasRoutes = routesOnly{} if err := r.Routes(nil); err != nil { t.Fatal(err) } var m HasMiddleware = middlewareOnly{} if _, ok := m.Middlewares()["jwt.auth"]; !ok { t.Fatal("missing jwt.auth") } var models HasModels = modelsOnly{} if len(models.Models()) != 1 { t.Fatalf("Models = %+v", models.Models()) } }