check / check (push) Successful in 54s
Remove the template's HTTP service, database and fx wiring. Add exact arithmetic on go/parser and go/constant, a client that runs simplex-chat as a child process and drives its WebSocket API, and the bot, which keeps an auto-accepting address and replies to each message. The image adds the checksum-pinned simplex-chat v7.0.2 on Ubuntu 22.04. Model: opus-5-5
97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
package config_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/spf13/viper"
|
|
"sneak.berlin/go/simplexcalc/internal/config"
|
|
)
|
|
|
|
// env builds a viper instance holding exactly the given keys, so a test
|
|
// describes one environment without touching the process's.
|
|
func env(kv map[string]string) *viper.Viper {
|
|
v := viper.New()
|
|
for k, val := range kv {
|
|
v.Set(k, val)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
// TestAbsentValuesTakeDefaults pins the other half of the iron rule: a
|
|
// value that is not set does get the default. Without this, a bug that
|
|
// rejected everything would pass every test below.
|
|
func TestAbsentValuesTakeDefaults(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for name, kv := range map[string]map[string]string{
|
|
"unset": nil,
|
|
"whitespace only": {config.EnvDataDir: " ", config.EnvDebug: " "},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c, err := config.Load(env(kv))
|
|
if err != nil {
|
|
t.Fatalf("absent values must be valid, got: %v", err)
|
|
}
|
|
|
|
if c.DataDir != config.DefaultDataDir {
|
|
t.Errorf("DataDir = %q, want %q", c.DataDir, config.DefaultDataDir)
|
|
}
|
|
|
|
if c.Debug {
|
|
t.Error("Debug must default off")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestSetButUnparseableAborts is the central contract of this package:
|
|
// a value an operator plausibly types, and that does not parse, fails
|
|
// startup rather than being replaced by the default.
|
|
func TestSetButUnparseableAborts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, raw := range []string{"yes", "on", "enabled", "2"} {
|
|
t.Run(raw, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c, err := config.Load(env(map[string]string{config.EnvDebug: raw}))
|
|
if err == nil {
|
|
t.Fatalf("wanted a startup failure, got a Config: %+v", c)
|
|
}
|
|
|
|
if !errors.Is(err, config.ErrInvalidConfig) {
|
|
t.Errorf("error does not wrap ErrInvalidConfig: %v", err)
|
|
}
|
|
|
|
if c != nil {
|
|
t.Error("a failed load must return no Config at all")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestValidValuesAreUsed proves the parsers accept what they document.
|
|
func TestValidValuesAreUsed(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c, err := config.Load(env(map[string]string{
|
|
config.EnvDataDir: "/var/lib/example",
|
|
config.EnvDebug: "true",
|
|
}))
|
|
if err != nil {
|
|
t.Fatalf("valid environment was rejected: %v", err)
|
|
}
|
|
|
|
if c.DataDir != "/var/lib/example" {
|
|
t.Errorf("DataDir = %q, want /var/lib/example", c.DataDir)
|
|
}
|
|
|
|
if !c.Debug {
|
|
t.Error("Debug = false, want true")
|
|
}
|
|
}
|