package version import ( "fmt" "testing" "time" "github.com/google/go-cmp/cmp" ) func Test_version_NewVersion(t *testing.T) { // custom options for comparer opts := cmp.Options{ cmp.Comparer(func(left, right *Version) bool { if left == nil && right == nil { return true } if left.major == right.major && left.minor == right.minor && left.patch == right.patch { return true } return false }), } type args struct { versionString string } tests := []struct { name string args args want *Version wantErr bool }{ { name: "default", args: args{}, want: &Version{ major: 0, minor: 0, patch: 0, BuildInformation: BuildInformation{}, }, wantErr: false, }, { name: "faulty version string", args: args{ versionString: "faulty.version.string", }, want: nil, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // This is not run in parallel since we change the versionString // and this would therefore result in a data race. // // versionString is and should only be touched through ldflags with // `go build`. if tt.name != "default" { versionString = tt.args.versionString } got, err := NewVersion() if (err != nil) != tt.wantErr { t.Errorf("NewVersion() error = %v, wantErr %v", err, tt.wantErr) return } if !cmp.Equal(got, tt.want, opts...) { t.Errorf("NewVersion() got = %v, want %v", got, tt.want) } }) } } func Test_version_Compare(t *testing.T) { timeNormal, err := time.Parse(time.RFC3339, "2022-08-19T11:11:02+00:00") if err != nil { t.Errorf("Compare() error = %v", err) } timeBefore, err := time.Parse(time.RFC3339, "2022-08-18T11:11:02+00:00") if err != nil { t.Errorf("Compare() error = %v", err) } timeAfter, err := time.Parse(time.RFC3339, "2022-08-22T11:11:02+00:00") if err != nil { t.Errorf("Compare() error = %v", err) } v := &Version{ major: 1, minor: 3, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, } type args struct { inputVersion *Version } tests := []struct { name string args args want int }{ { name: "input version is equal", args: args{ inputVersion: &Version{ major: 1, minor: 3, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: 0, }, { name: "input version is smaller based on major", args: args{ inputVersion: &Version{ major: 0, minor: 0, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: 1, }, { name: "input version is smaller based on minor", args: args{ inputVersion: &Version{ major: 1, minor: 0, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: 1, }, { name: "input version is smaller based on patch", args: args{ inputVersion: &Version{ major: 1, minor: 3, patch: 78, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: 1, }, { name: "input version is smaller based on commit", args: args{ inputVersion: &Version{ major: 1, minor: 3, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "14379478a8c56269dd59419d04c9080c1103174d", time: timeBefore, modified: false, }, }, }, want: 1, }, { name: "input version is larger based on major", args: args{ inputVersion: &Version{ major: 2, minor: 3, patch: 78, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: -1, }, { name: "input version is larger based on minor", args: args{ inputVersion: &Version{ major: 1, minor: 4, patch: 78, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: -1, }, { name: "input version is larger based on patch", args: args{ inputVersion: &Version{ major: 1, minor: 3, patch: 103, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNormal, modified: false, }, }, }, want: -1, }, { name: "input version is larger based on commit", args: args{ inputVersion: &Version{ major: 1, minor: 3, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "14379478a8c56269dd59419d04c9080c1103174d", time: timeAfter, modified: false, }, }, }, want: -1, }, { name: "one of the versions is modified", args: args{ inputVersion: &Version{ BuildInformation: BuildInformation{ modified: true, }, }, }, want: -2, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() got := v.Compare(tt.args.inputVersion) if !cmp.Equal(got, tt.want) { t.Errorf("Compare() got = %v, want %v", got, tt.want) } }) } } func Test_version_String(t *testing.T) { timeNow := time.Now() v := &Version{ major: 1, minor: 3, patch: 101, BuildInformation: BuildInformation{ goos: "linux", goarch: "amd64", revision: "34979478a8c56269dd59419d04d9080c1103174d", time: timeNow, modified: false, }, } tests := []struct { name string want string }{ { name: "default", want: fmt.Sprintf(`Version: 1.3.101 Build Information: - GOOS: linux - GOARCH: amd64 - Revision: 34979478a8c56269dd59419d04d9080c1103174d - Time: %s - Modified (dirty): false`, timeNow.String()), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := v.String() if !cmp.Equal(got, tt.want) { t.Errorf("String() got = %v, want %v", got, tt.want) } }) } } func Test_version_compareVersionSegment(t *testing.T) { type args struct { left, right int } tests := []struct { name string args args want int }{ { name: "left is smaller && right is larger", args: args{ left: 5, right: 8, }, want: -1, }, { name: "left is larger && right is smaller", args: args{ left: 9, right: 3, }, want: 1, }, { name: "left and right are equal", args: args{ left: 4, right: 4, }, want: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() got := compareVersionSegment(tt.args.left, tt.args.right) if !cmp.Equal(got, tt.want) { t.Errorf("compareVersionSegment() got = %v, want %v", got, tt.want) } }) } } func Test_version_parseVersionString(t *testing.T) { type args struct { input string } tests := []struct { name string args args want []int wantErr bool }{ { name: "default", args: args{ input: "1.0.4", }, want: []int{1, 0, 4}, wantErr: false, }, { name: "too many values in version string", args: args{ input: "1.0.4.259", }, want: nil, wantErr: true, }, { name: "faulty version string - no numbers", args: args{ input: "this is wrong", }, want: nil, wantErr: true, }, { name: "faulty version string - wrong delimiter", args: args{ input: "1-2-187", }, want: nil, wantErr: true, }, { name: "faulty version string - mixed", args: args{ input: "1.abc.283", }, want: nil, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := parseVersionString(tt.args.input) if (err != nil) != tt.wantErr { t.Errorf("parseVersionString() error = %v, wantErr %v", err, tt.wantErr) return } if !cmp.Equal(got, tt.want) { t.Errorf("parseVersionString() got = %v, want %v", got, tt.want) } }) } }