package util_test import ( "testing" "galaxy/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewSemver(t *testing.T) { t.Parallel() tests := []struct { name string input []uint want util.SemVer wantErr string }{ { name: "major only", input: []uint{1}, want: util.SemVer{Major: 1}, }, { name: "major and minor", input: []uint{1, 2}, want: util.SemVer{Major: 1, Minor: 2}, }, { name: "major minor and patch", input: []uint{1, 2, 3}, want: util.SemVer{Major: 1, Minor: 2, Patch: 3}, }, { name: "all components", input: []uint{1, 2, 3, 4}, want: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, }, { name: "missing major", input: nil, wantErr: "incorrect args count: 0", }, { name: "too many components", input: []uint{1, 2, 3, 4, 5}, wantErr: "incorrect args count: 5", }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := util.NewSemver(tt.input...) if tt.wantErr != "" { require.Error(t, err) assert.Contains(t, err.Error(), tt.wantErr) assert.Equal(t, util.SemVer{}, got) return } require.NoError(t, err) assert.Equal(t, tt.want, got) }) } } func TestMustSemver(t *testing.T) { t.Parallel() t.Run("returns version", func(t *testing.T) { t.Parallel() assert.Equal(t, util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, util.MustSemver(1, 2, 3, 4)) }) t.Run("panics on invalid input", func(t *testing.T) { t.Parallel() var recovered any func() { defer func() { recovered = recover() }() util.MustSemver() }() require.NotNil(t, recovered) err, ok := recovered.(error) require.True(t, ok) assert.EqualError(t, err, "new semver: incorrect args count: 0") }) } func TestParseSemver(t *testing.T) { t.Parallel() tests := []struct { name string input string want util.SemVer wantErr string }{ { name: "major only", input: "1", want: util.SemVer{Major: 1}, }, { name: "major and minor", input: "1.2", want: util.SemVer{Major: 1, Minor: 2}, }, { name: "major minor and patch", input: "1.2.3", want: util.SemVer{Major: 1, Minor: 2, Patch: 3}, }, { name: "all components", input: "1.2.3.4", want: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, }, { name: "v prefix", input: "v2.3.4.5", want: util.SemVer{Major: 2, Minor: 3, Patch: 4, Build: 5}, }, { name: "v dot prefix", input: "v.6.7.8.9", want: util.SemVer{Major: 6, Minor: 7, Patch: 8, Build: 9}, }, { name: "leading zeros", input: "v.01.002.0003.0004", want: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, }, { name: "empty input", input: "", wantErr: "missing major version", }, { name: "prefix without version", input: "v", wantErr: "missing major version", }, { name: "prefix with dot without version", input: "v.", wantErr: "missing major version", }, { name: "leading dot", input: ".1", wantErr: "empty version part at position 1", }, { name: "trailing dot", input: "1.", wantErr: "empty version part at position 2", }, { name: "empty middle part", input: "1..2", wantErr: "empty version part at position 2", }, { name: "too many parts", input: "1.2.3.4.5", wantErr: "too many version parts: 5", }, { name: "non numeric part", input: "1.2.beta", wantErr: `parse part "beta"`, }, { name: "negative part", input: "1.-2", wantErr: `parse part "-2"`, }, { name: "spaces are not accepted", input: " 1.2 ", wantErr: `parse part " 1"`, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := util.ParseSemver(tt.input) if tt.wantErr != "" { require.Error(t, err) assert.Contains(t, err.Error(), tt.wantErr) assert.Equal(t, util.SemVer{}, got) return } require.NoError(t, err) assert.Equal(t, tt.want, got) }) } } func TestParserSemver(t *testing.T) { t.Parallel() got, err := util.ParserSemver("v1.2.3.4") require.NoError(t, err) assert.Equal(t, util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, got) } func TestCompareSemver(t *testing.T) { t.Parallel() tests := []struct { name string x util.SemVer y util.SemVer want int }{ { name: "equal versions", x: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, y: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, want: 0, }, { name: "x less by major", x: util.SemVer{Major: 1, Minor: 9, Patch: 9, Build: 9}, y: util.SemVer{Major: 2}, want: 1, }, { name: "x greater by major", x: util.SemVer{Major: 2}, y: util.SemVer{Major: 1, Minor: 9, Patch: 9, Build: 9}, want: -1, }, { name: "x less by minor", x: util.SemVer{Major: 1, Minor: 1, Patch: 9, Build: 9}, y: util.SemVer{Major: 1, Minor: 2}, want: 1, }, { name: "x less by patch", x: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 9}, y: util.SemVer{Major: 1, Minor: 2, Patch: 4}, want: 1, }, { name: "x less by build", x: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 4}, y: util.SemVer{Major: 1, Minor: 2, Patch: 3, Build: 5}, want: 1, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() assert.Equal(t, tt.want, util.CompareSemver(tt.x, tt.y)) }) } }