зеркало из https://github.com/golang/pkgsite.git
259 строки
6.2 KiB
Go
259 строки
6.2 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package version
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
func TestForSorting(t *testing.T) {
|
|
for _, test := range []struct {
|
|
in, want string
|
|
}{
|
|
{"v1.2.3", "1,2,3~"},
|
|
{"v12.48.301", "a12,a48,b301~"},
|
|
{"v0.9.3-alpha.1", "0,9,3,~alpha,1"},
|
|
{"v1.2.3-rc.20150901.-", "1,2,3,~rc,g20150901,~-"},
|
|
{"v1.2.3-alpha.789+build", "1,2,3,~alpha,b789"},
|
|
} {
|
|
got := ForSorting(test.in)
|
|
if got != test.want {
|
|
t.Errorf("ForSorting(%s) = %s, want %s", test.in, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestForSortingOrder(t *testing.T) {
|
|
// A list of valid semantic versions, in order.
|
|
semvers := []string{
|
|
"v0.0.0-20180713131340-b395d2d6f5ee",
|
|
"v0.0.0-20190124233150-8f7fa2680c82",
|
|
"v0.0.0",
|
|
"v0.0.1",
|
|
"v0.1.0",
|
|
"v1.0.0-alpha",
|
|
"v1.0.0-alpha.1",
|
|
"v1.0.0-alpha.beta",
|
|
"v1.0.0-beta",
|
|
"v1.0.0-beta.2",
|
|
"v1.0.0-beta.11",
|
|
"v1.0.0-rc.1",
|
|
"v1.0.0",
|
|
"v1.2.0",
|
|
"v1.11.0",
|
|
"v1.12.0-alph.1",
|
|
"v1.12.0-alpha",
|
|
// These next two would order incorrectly if we used '.' as a separator, because
|
|
// '.' comes after '-'.
|
|
"v2.0.0-z.a",
|
|
"v2.0.0-z-",
|
|
// These next two would sort incorrectly if we did not prepend non-numeric components
|
|
// with a '~'.
|
|
"v2.1.0-a.1",
|
|
"v2.1.0-a.-",
|
|
}
|
|
|
|
// Check that the test has the ordering right according to the semver package.
|
|
for i := range semvers {
|
|
if !semver.IsValid(semvers[i]) {
|
|
t.Fatalf("test is broken: bad semver: %s", semvers[i])
|
|
}
|
|
if i > 0 {
|
|
if semver.Compare(semvers[i-1], semvers[i]) >= 0 {
|
|
t.Fatalf("test is broken: %s is not less than %s", semvers[i-1], semvers[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check that ForSorting produces the correct ordering.
|
|
var prev string
|
|
for _, v := range semvers {
|
|
got := ForSorting(v)
|
|
if prev != "" && prev >= got {
|
|
t.Errorf("%s: %s >= %s, want less than", v, prev, got)
|
|
}
|
|
prev = got
|
|
}
|
|
}
|
|
|
|
func TestAppendNumericPrefix(t *testing.T) {
|
|
for _, test := range []struct {
|
|
n int
|
|
want string
|
|
}{
|
|
{1, ""},
|
|
{2, "a"},
|
|
{3, "b"},
|
|
{26, "y"},
|
|
{53, "zz"}, // 53-1 = 26*2
|
|
{100, "zzzu"}, // 100-1 = 26*3 + 21
|
|
} {
|
|
got := string(appendNumericPrefix(nil, test.n))
|
|
if got != test.want {
|
|
t.Errorf("%d: got %s, want %s", test.n, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseVersionType(t *testing.T) {
|
|
testCases := []struct {
|
|
name, version string
|
|
wantVersionType Type
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "pseudo major version",
|
|
version: "v1.0.0-20190311183353-d8887717615a",
|
|
wantVersionType: TypePseudo,
|
|
},
|
|
{
|
|
name: "pseudo prerelease version",
|
|
version: "v1.2.3-pre.0.20190311183353-d8887717615a",
|
|
wantVersionType: TypePseudo,
|
|
},
|
|
{
|
|
name: "pseudo minor version",
|
|
version: "v1.2.4-0.20190311183353-d8887717615a",
|
|
wantVersionType: TypePseudo,
|
|
},
|
|
{
|
|
name: "pseudo version invalid",
|
|
version: "v1.2.3-20190311183353-d8887717615a",
|
|
wantVersionType: TypePrerelease,
|
|
},
|
|
{
|
|
name: "valid release",
|
|
version: "v1.0.0",
|
|
wantVersionType: TypeRelease,
|
|
},
|
|
{
|
|
name: "valid prerelease",
|
|
version: "v1.0.0-alpha.1",
|
|
wantVersionType: TypePrerelease,
|
|
},
|
|
{
|
|
name: "invalid version",
|
|
version: "not_a_version",
|
|
wantVersionType: "",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
if gotVt, err := ParseType(test.version); (test.wantErr == (err != nil)) && test.wantVersionType != gotVt {
|
|
t.Errorf("parseVersionType(%v) = %v, want %v", test.version, gotVt, test.wantVersionType)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLatestOf(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
versions []string
|
|
want string
|
|
}{
|
|
{
|
|
name: "highest release",
|
|
versions: []string{"v1.2.3", "v1.0.0", "v1.9.0-pre"},
|
|
want: "v1.2.3",
|
|
},
|
|
{
|
|
name: "highest pre-release if no release",
|
|
versions: []string{"v1.2.3-alpha", "v1.0.0-beta", "v1.9.0-pre"},
|
|
want: "v1.9.0-pre",
|
|
},
|
|
{
|
|
name: "prefer pre-release to pseudo",
|
|
versions: []string{"v1.0.0-20180713131340-b395d2d6f5ee", "v0.0.0-alpha"},
|
|
want: "v0.0.0-alpha",
|
|
},
|
|
|
|
{
|
|
name: "highest pseudo if no pre-release or release",
|
|
versions: []string{"v0.0.0-20180713131340-b395d2d6f5ee", "v0.0.0-20190124233150-8f7fa2680c82"},
|
|
want: "v0.0.0-20190124233150-8f7fa2680c82",
|
|
},
|
|
{
|
|
name: "use incompatible",
|
|
versions: []string{"v1.2.3", "v1.0.0", "v2.0.0+incompatible"},
|
|
want: "v2.0.0+incompatible",
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
got := LatestOf(test.versions)
|
|
if got != test.want {
|
|
t.Errorf("got %s, want %s", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLatest(t *testing.T) {
|
|
pseudo := "v0.0.0-20190124233150-8f7fa2680c82"
|
|
for _, test := range []struct {
|
|
name string
|
|
versions []string
|
|
hasGoMod func(string) (bool, error)
|
|
want string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
versions: nil,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "tagged release",
|
|
versions: []string{pseudo, "v0.1.0", "v1.2.3-pre"},
|
|
want: "v0.1.0",
|
|
},
|
|
{
|
|
name: "tagged pre-release",
|
|
versions: []string{pseudo, "v1.2.3-pre"},
|
|
want: "v1.2.3-pre",
|
|
},
|
|
{
|
|
name: "pseudo",
|
|
versions: []string{pseudo},
|
|
want: pseudo,
|
|
},
|
|
{
|
|
name: "incompatible with go.mod",
|
|
versions: []string{"v2.0.0+incompatible", "v1.2.3"},
|
|
want: "v1.2.3",
|
|
},
|
|
{
|
|
name: "incompatible without go.mod",
|
|
versions: []string{"v2.0.0+incompatible", "v1.2.3"},
|
|
hasGoMod: func(v string) (bool, error) { return false, nil },
|
|
want: "v2.0.0+incompatible",
|
|
},
|
|
{
|
|
name: "incompatible without tagged go.mod",
|
|
// Although the latest compatible version has a go.mod file,
|
|
// it is not a tagged version.
|
|
versions: []string{pseudo, "v2.0.0+incompatible"},
|
|
want: "v2.0.0+incompatible",
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
|
|
if test.hasGoMod == nil {
|
|
test.hasGoMod = func(v string) (bool, error) { return true, nil }
|
|
}
|
|
got, err := LatestVersion(test.versions, test.hasGoMod)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got != test.want {
|
|
t.Errorf("got %q, want %q", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|