version_test.go #2

  • //
  • p4lf/
  • dev/
  • internal/
  • version/
  • version_test.go
  • View
  • Commits
  • Open Download .zip Download (3 KB)
package version_test

import (
	"regexp"
	"strings"
	"testing"

	"workshop.perforce.com/p4lf/internal/version"
)

func TestGet_ReturnsNonEmptySemVer(t *testing.T) {
	info := version.Get()
	if info.SemVer == "" {
		t.Error("SemVer should not be empty")
	}
}

func TestString_ContainsSemVer(t *testing.T) {
	s := version.String()
	if !strings.Contains(s, "p4lf") {
		t.Errorf("version string should contain 'p4lf': %q", s)
	}
	if !strings.Contains(s, version.SemVer) {
		t.Errorf("version string should contain SemVer %q: %q", version.SemVer, s)
	}
}

// TestStreamParsing validates the depot-path → stream extraction logic used
// inside Get(), by replicating the same regex against representative inputs.
func TestStreamParsing(t *testing.T) {
	idRe := regexp.MustCompile(`\$Id:\s*(//[^\s#]+)(#\d+)\s*\$`)

	cases := []struct {
		input        string
		wantStream   string
		wantRevision string
	}{
		{
			input:        "$Id: //p4lf/dev/internal/version/version.go#3 $",
			wantStream:   "//p4lf/dev",
			wantRevision: "#3",
		},
		{
			input:        "$Id: //p4lf/main/internal/version/version.go#12 $",
			wantStream:   "//p4lf/main",
			wantRevision: "#12",
		},
		{
			input:        "$Id: //p4lf/r26.1/internal/version/version.go#1 $",
			wantStream:   "//p4lf/r26.1",
			wantRevision: "#1",
		},
	}

	for _, tc := range cases {
		m := idRe.FindStringSubmatch(tc.input)
		if m == nil {
			t.Errorf("regex did not match %q", tc.input)
			continue
		}
		depotPath, revision := m[1], m[2]
		if revision != tc.wantRevision {
			t.Errorf("input %q: revision got %q, want %q", tc.input, revision, tc.wantRevision)
		}
		parts := strings.SplitN(strings.TrimPrefix(depotPath, "//"), "/", 3)
		stream := ""
		if len(parts) >= 2 {
			stream = "//" + parts[0] + "/" + parts[1]
		}
		if stream != tc.wantStream {
			t.Errorf("input %q: stream got %q, want %q", tc.input, stream, tc.wantStream)
		}
	}
}

func TestChangeParsing(t *testing.T) {
	changeRe := regexp.MustCompile(`\$Change:\s*(\d+)\s*\$`)
	cases := []struct{ input, want string }{
		{"$Change: 32819 $", "32819"},
		{"$Change: 1 $", "1"},
		{"$Change: 999999 $", "999999"},
	}
	for _, tc := range cases {
		m := changeRe.FindStringSubmatch(tc.input)
		if m == nil {
			t.Errorf("no match for %q", tc.input)
			continue
		}
		if m[1] != tc.want {
			t.Errorf("input %q: got %q, want %q", tc.input, m[1], tc.want)
		}
	}
}

func TestDateTimeParsing(t *testing.T) {
	dateRe := regexp.MustCompile(`\$DateTime:\s*(\d{4}/\d{2}/\d{2})`)
	cases := []struct{ input, want string }{
		{"$DateTime: 2026/06/25 15:00:00 $", "2026/06/25"},
		{"$DateTime: 2099/12/31 23:59:59 $", "2099/12/31"},
	}
	for _, tc := range cases {
		m := dateRe.FindStringSubmatch(tc.input)
		if m == nil {
			t.Errorf("no match for %q", tc.input)
			continue
		}
		if m[1] != tc.want {
			t.Errorf("input %q: got %q, want %q", tc.input, m[1], tc.want)
		}
	}
}
# Change User Description Committed
#2 32824 C. Thomas Tyler Rename Go module path from github.com/rcowham/p4lf to workshop.perforce.com/p4lf.

The rcowham prefix was a carryover from early research into go-libtail
(which is hosted at github.com/rcowham/go-libtail). p4lf is hosted on
the Perforce Public Depot / Workshop, not GitHub, so workshop.perforce.com
is the correct canonical module path.

Updated: go.mod, all *.go files with internal imports, Makefile (MODULE
and LDFLAGS). Session logs retain the old path as accurate historical
record.
#1 32819 C. Thomas Tyler Add version stamping via Perforce keyword expansion.

internal/version/version.go (type text+k):
- SemVer var: hand-maintained Major.Minor.Patch, injectable via -ldflags
- P4ID/P4Change/P4DateTime constants: expanded by Perforce on each submit/sync
- Get() parses expanded keywords into an Info struct (stream, CL, date, revision)
- String() produces: 'p4lf 0.1.0 (CL 32819, //p4lf/dev#3, 2026/06/25)'
- Gracefully handles unexpanded state (pre-first-submit, non-P4 builds)

internal/version/version_test.go:
- Tests stream/revision parsing for dev, main, release streams
- Tests Change and DateTime regex parsing

cmd/p4lf/main.go:
- Uses version.String() and version.SemVer instead of hardcoded const

Makefile:
- VERSION now read from internal/version/version.go
- LDFLAGS target github.com/rcowham/p4lf/internal/version.SemVer