package globals_test import ( "runtime/debug" "testing" "sneak.berlin/go/vaultik/internal/globals" ) // TestGlobalsNew ensures the globals package initializes correctly func TestGlobalsNew(t *testing.T) { t.Parallel() g, err := globals.New() if err != nil { t.Fatalf("Failed to create Globals: %v", err) } if g == nil { t.Fatal("Globals instance is nil") } if g.Appname != "vaultik" { t.Errorf("Expected Appname to be 'vaultik', got '%s'", g.Appname) } // Version and Commit will be "dev" and "unknown" by default if g.Version == "" { t.Error("Version should not be empty") } if g.Commit == "" { t.Error("Commit should not be empty") } } // TestIsDevVersion covers the boundary that matters: everything // script/version, a plain docker build and goreleaser's snapshot // template can emit for an untagged build must be recognised as a // development build, and a real tag must not be. A plain equality check // against "dev" used to decide this, which classified every // commit-stamped dev build as a release. func TestIsDevVersion(t *testing.T) { t.Parallel() cases := []struct { version string want bool }{ // What an untagged build produces. {"dev", true}, {"dev-b6e4a218a39e", true}, {"dev-b6e4a218a39e-dirty", true}, // What `git describe --tags --always --dirty` produces with no // tag reachable, and on a commit after a tag. {"877eb2f", true}, {"877eb2f-dirty", true}, {"v1.0.0-3-g877eb2f", true}, {"v1.0.0-3-g877eb2f-dirty", true}, {"1.0.0-rc.1-12-g877eb2f", true}, // A tagged commit with uncommitted changes is not that tag. {"v1.0.0-dirty", true}, // What Go records for a build without linker flags: a // pseudo-version for an untagged commit, "+dirty" for a // modified checkout. {"v1.0.0-rc3.0.20261111001226-abcdefabcdef", true}, {"v0.0.0-20261111001226-abcdefabcdef", true}, {"v1.0.1-0.20261111001226-abcdefabcdef", true}, {"v1.0.0+dirty", true}, // What a tagged build produces (goreleaser's .Version strips // the leading "v"; script/version keeps it). {"1.0.0", false}, {"0.1.0", false}, {"1.0.0-rc.1", false}, {"v1.0.0", false}, {"v1.0.0-rc3", false}, // A release must not be mistaken for a dev build just because // the string happens to contain "dev". {"1.0.0-dev", false}, {"developer", false}, // A binary with no version string at all did not get stamped, // which is a build failure, not a release. It must never print // as one. The Makefile refuses to build when script/version // yields nothing; this covers a binary linked some other way. {"", true}, // What script/docker and script/cibuild stamp when the host // has no git checkout. {"unknown", true}, } for _, tc := range cases { if got := globals.IsDevVersion(tc.version); got != tc.want { t.Errorf("IsDevVersion(%q) = %v, want %v", tc.version, got, tc.want) } } } // TestDefaultVersionIsDev pins the default: a binary whose linker flags // and build info name no version must report itself as a development // build rather than as some default release number. func TestDefaultVersionIsDev(t *testing.T) { t.Parallel() if !globals.IsDevVersion(globals.DevVersion) { t.Errorf("DevVersion %q is not recognised as a dev version", globals.DevVersion) } } // buildInfo returns build info with the given main module version and, // when revision is not empty, the commit settings Go records for a // build from a git checkout. func buildInfo(version, revision string) *debug.BuildInfo { info := &debug.BuildInfo{ Main: debug.Module{Path: "sneak.berlin/go/vaultik", Version: version}, } if revision != "" { info.Settings = []debug.BuildSetting{ {Key: "vcs.revision", Value: revision}, {Key: "vcs.time", Value: "2026-11-10T23:12:26Z"}, } } return info } // TestFromBuildInfo covers a binary from `go install` of a tag, which // carries no linker flags: it must report the tag. Values the linker // flags set are kept. func TestFromBuildInfo(t *testing.T) { t.Parallel() const ( tag = "v1.0.0-rc3" rev = "0123456789abcdef0123456789abcdef01234567" ) cases := []struct { name string info *debug.BuildInfo version, commit, date string wantVersion, wantCommit string wantDate string }{ { name: "go install of a tag", info: buildInfo(tag, ""), version: globals.DevVersion, commit: globals.Unknown, date: globals.Unknown, wantVersion: tag, wantCommit: globals.Unknown, wantDate: globals.Unknown, }, { name: "empty version", info: buildInfo(tag, ""), version: "", commit: globals.Unknown, date: globals.Unknown, wantVersion: tag, wantCommit: globals.Unknown, wantDate: globals.Unknown, }, { name: "go build in a git checkout", info: buildInfo(tag, rev), version: globals.DevVersion, commit: globals.Unknown, date: globals.Unknown, wantVersion: tag, wantCommit: rev, wantDate: "2026-11-10", }, { name: "Go could not tell the version", info: buildInfo("(devel)", ""), version: globals.DevVersion, commit: globals.Unknown, date: globals.Unknown, wantVersion: globals.DevVersion, wantCommit: globals.Unknown, wantDate: globals.Unknown, }, { name: "linker flags set", info: buildInfo(tag, rev), version: "v1.0.0-rc2-4-gabcdef1", commit: "abcdef1", date: "2026-11-01", wantVersion: "v1.0.0-rc2-4-gabcdef1", wantCommit: "abcdef1", wantDate: "2026-11-01", }, } for _, tc := range cases { version, commit, date := globals.FromBuildInfo( tc.info, tc.version, tc.commit, tc.date) if version != tc.wantVersion || commit != tc.wantCommit || date != tc.wantDate { t.Errorf("%s: got %q, %q, %q; want %q, %q, %q", tc.name, version, commit, date, tc.wantVersion, tc.wantCommit, tc.wantDate) } } }