148 lines
5.3 KiB
Go
148 lines
5.3 KiB
Go
package semver
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestTryParseSemver(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
in string
|
|
out Version
|
|
}{
|
|
{"1.2.3-pre.4+build.5", Version{major: 1, minor: 2, patch: 3, prerelease: []string{"pre", "4"}, build: []string{"build", "5"}}},
|
|
{"1.2.3-pre.4", Version{major: 1, minor: 2, patch: 3, prerelease: []string{"pre", "4"}}},
|
|
{"1.2.3+build.4", Version{major: 1, minor: 2, patch: 3, build: []string{"build", "4"}}},
|
|
{"1.2.3", Version{major: 1, minor: 2, patch: 3}},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.in, func(t *testing.T) {
|
|
t.Parallel()
|
|
v, err := TryParseVersion(test.in)
|
|
assert.NilError(t, err)
|
|
assertVersion(t, v, test.out)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestVersionString(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
in Version
|
|
out string
|
|
}{
|
|
{Version{major: 1, minor: 2, patch: 3, prerelease: []string{"pre", "4"}, build: []string{"build", "5"}}, "1.2.3-pre.4+build.5"},
|
|
{Version{major: 1, minor: 2, patch: 3, prerelease: []string{"pre", "4"}, build: []string{"build"}}, "1.2.3-pre.4+build"},
|
|
{Version{major: 1, minor: 2, patch: 3, build: []string{"build"}}, "1.2.3+build"},
|
|
{Version{major: 1, minor: 2, patch: 3, prerelease: []string{"pre", "4"}}, "1.2.3-pre.4"},
|
|
{Version{major: 1, minor: 2, patch: 3, build: []string{"build", "4"}}, "1.2.3+build.4"},
|
|
{Version{major: 1, minor: 2, patch: 3}, "1.2.3"},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.out, func(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, test.in.String(), test.out)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestVersionCompare(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
v1, v2 string
|
|
want int
|
|
}{
|
|
// https://semver.org/#spec-item-11
|
|
// > Precedence is determined by the first difference when comparing each of these
|
|
// > identifiers from left to right as follows: Major, minor, and patch versions are
|
|
// > always compared numerically.
|
|
{"1.0.0", "2.0.0", comparisonLessThan},
|
|
{"1.0.0", "1.1.0", comparisonLessThan},
|
|
{"1.0.0", "1.0.1", comparisonLessThan},
|
|
{"2.0.0", "1.0.0", comparisonGreaterThan},
|
|
{"1.1.0", "1.0.0", comparisonGreaterThan},
|
|
{"1.0.1", "1.0.0", comparisonGreaterThan},
|
|
{"1.0.0", "1.0.0", comparisonEqualTo},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > When major, minor, and patch are equal, a pre-release version has lower
|
|
// > precedence than a normal version.
|
|
{"1.0.0", "1.0.0-pre", comparisonGreaterThan},
|
|
{"1.0.1-pre", "1.0.0", comparisonGreaterThan},
|
|
{"1.0.0-pre", "1.0.0", comparisonLessThan},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > identifiers consisting of only digits are compared numerically
|
|
{"1.0.0-0", "1.0.0-1", comparisonLessThan},
|
|
{"1.0.0-1", "1.0.0-0", comparisonGreaterThan},
|
|
{"1.0.0-2", "1.0.0-10", comparisonLessThan},
|
|
{"1.0.0-10", "1.0.0-2", comparisonGreaterThan},
|
|
{"1.0.0-0", "1.0.0-0", comparisonEqualTo},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
|
|
{"1.0.0-a", "1.0.0-b", comparisonLessThan},
|
|
{"1.0.0-a-2", "1.0.0-a-10", comparisonGreaterThan},
|
|
{"1.0.0-b", "1.0.0-a", comparisonGreaterThan},
|
|
{"1.0.0-a", "1.0.0-a", comparisonEqualTo},
|
|
{"1.0.0-A", "1.0.0-a", comparisonLessThan},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
|
|
{"1.0.0-0", "1.0.0-alpha", comparisonLessThan},
|
|
{"1.0.0-alpha", "1.0.0-0", comparisonGreaterThan},
|
|
{"1.0.0-0", "1.0.0-0", comparisonEqualTo},
|
|
{"1.0.0-alpha", "1.0.0-alpha", comparisonEqualTo},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
|
|
// > of the preceding identifiers are equal.
|
|
{"1.0.0-alpha", "1.0.0-alpha.0", comparisonLessThan},
|
|
{"1.0.0-alpha.0", "1.0.0-alpha", comparisonGreaterThan},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
|
// > MUST be determined by comparing each dot separated identifier from left to right until
|
|
// > a difference is found [...]
|
|
{"1.0.0-a.0.b.1", "1.0.0-a.0.b.2", comparisonLessThan},
|
|
{"1.0.0-a.0.b.1", "1.0.0-b.0.a.1", comparisonLessThan},
|
|
{"1.0.0-a.0.b.2", "1.0.0-a.0.b.1", comparisonGreaterThan},
|
|
{"1.0.0-b.0.a.1", "1.0.0-a.0.b.1", comparisonGreaterThan},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// > Build metadata does not figure into precedence
|
|
{"1.0.0+build", "1.0.0", comparisonEqualTo},
|
|
{"1.0.0+build.stuff", "1.0.0", comparisonEqualTo},
|
|
{"1.0.0", "1.0.0+build", comparisonEqualTo},
|
|
{"1.0.0+build", "1.0.0+stuff", comparisonEqualTo},
|
|
|
|
// https://semver.org/#spec-item-11
|
|
// Edge cases for numeric and lexical comparison of prerelease identifiers.
|
|
{"1.0.0-alpha.99999", "1.0.0-alpha.100000", comparisonLessThan},
|
|
{"1.0.0-alpha.beta", "1.0.0-alpha.alpha", comparisonGreaterThan},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.v1+" <=> "+test.v2, func(t *testing.T) {
|
|
t.Parallel()
|
|
v1, err1 := TryParseVersion(test.v1)
|
|
assert.NilError(t, err1, test.v1)
|
|
v2, err2 := TryParseVersion(test.v2)
|
|
assert.NilError(t, err2, test.v2)
|
|
assert.Equal(t, v1.Compare(&v2), test.want)
|
|
})
|
|
}
|
|
}
|
|
|
|
func assertVersion(t *testing.T, a, b Version) {
|
|
assert.Equal(t, a.major, b.major)
|
|
assert.Equal(t, a.minor, b.minor)
|
|
assert.Equal(t, a.patch, b.patch)
|
|
assert.DeepEqual(t, a.prerelease, b.prerelease)
|
|
assert.DeepEqual(t, a.build, b.build)
|
|
}
|