Every publish added a version and nothing removed one. A Go bundle beside the TypeScript one keeps what a lockfile or a range on the forge names, what a dist-tag names and the newest five; a dry run unless asked with a why, and nothing deleted while any repository is unread.
118 lines
4.3 KiB
Go
118 lines
4.3 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
func TestVersionsAreOrderedAsSemverSays(t *testing.T) {
|
|
// Each is lower than the next (semver.org §11's own example, and the edges around it).
|
|
ordered := []string{"0.0.1", "0.1.0", "1.0.0-0", "1.0.0-alpha", "1.0.0-alpha.1", "1.0.0-alpha.beta", "1.0.0-beta",
|
|
"1.0.0-beta.2", "1.0.0-beta.11", "1.0.0-rc.1", "1.0.0", "1.0.1", "1.2.0", "1.10.0", "2.0.0"}
|
|
for i := 0; i+1 < len(ordered); i++ {
|
|
a, _ := ParseVersion(ordered[i])
|
|
b, _ := ParseVersion(ordered[i+1])
|
|
if Compare(a, b) >= 0 || Compare(b, a) <= 0 {
|
|
t.Errorf("%s should be lower than %s", ordered[i], ordered[i+1])
|
|
}
|
|
}
|
|
a, _ := ParseVersion("1.2.3+build.1")
|
|
b, _ := ParseVersion("1.2.3")
|
|
if Compare(a, b) != 0 {
|
|
t.Error("build metadata does not order")
|
|
}
|
|
for _, bad := range []string{"1.2", "x", "1.2.3.4", "latest", ""} {
|
|
if _, err := ParseVersion(bad); err == nil {
|
|
t.Errorf("%q read as a version", bad)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRangesAreReadAsNpmReadsThem(t *testing.T) {
|
|
cases := []struct {
|
|
r string
|
|
in []string
|
|
out []string
|
|
}{
|
|
{"1.2.3", []string{"1.2.3"}, []string{"1.2.4", "1.2.3-beta"}},
|
|
{"=1.2.3", []string{"1.2.3"}, []string{"1.2.2"}},
|
|
{"^1.2.3", []string{"1.2.3", "1.9.9"}, []string{"2.0.0", "1.2.2", "1.3.0-beta", "2.0.0-0"}},
|
|
{"^0.2.3", []string{"0.2.3", "0.2.9"}, []string{"0.3.0", "0.2.2"}},
|
|
{"^0.0.3", []string{"0.0.3"}, []string{"0.0.4"}},
|
|
{"^1.2", []string{"1.2.0", "1.9.0"}, []string{"2.0.0", "1.1.9"}},
|
|
{"^0.x", []string{"0.0.1", "0.9.9"}, []string{"1.0.0"}},
|
|
{"^0.0", []string{"0.0.9"}, []string{"0.1.0"}},
|
|
{"^1.2.3-beta.2", []string{"1.2.3-beta.2", "1.2.3-beta.4", "1.2.3", "1.5.0"}, []string{"1.2.3-beta.1", "1.2.4-beta.1", "2.0.0"}},
|
|
{"~1.2.3", []string{"1.2.3", "1.2.9"}, []string{"1.3.0", "1.2.2"}},
|
|
{"~1.2", []string{"1.2.0", "1.2.9"}, []string{"1.3.0"}},
|
|
{"~1", []string{"1.0.0", "1.9.9"}, []string{"2.0.0"}},
|
|
{"~0.2.3", []string{"0.2.5"}, []string{"0.3.0"}},
|
|
{"*", []string{"0.0.0", "9.9.9"}, []string{"1.0.0-beta"}},
|
|
{"", []string{"1.0.0"}, nil},
|
|
{"x", []string{"1.0.0"}, nil},
|
|
{"1.x", []string{"1.0.0", "1.9.9"}, []string{"2.0.0", "0.9.9"}},
|
|
{"1.2.*", []string{"1.2.0", "1.2.9"}, []string{"1.3.0"}},
|
|
{"1", []string{"1.5.0"}, []string{"2.0.0"}},
|
|
{">1.2.3", []string{"1.2.4"}, []string{"1.2.3"}},
|
|
{">1.2", []string{"1.3.0"}, []string{"1.2.9"}},
|
|
{">=1.2.3", []string{"1.2.3", "5.0.0"}, []string{"1.2.2"}},
|
|
{"<1.2.3", []string{"1.2.2"}, []string{"1.2.3", "1.2.3-beta"}},
|
|
{"<1.2", []string{"1.1.9"}, []string{"1.2.0"}},
|
|
{"<=1.2.3", []string{"1.2.3"}, []string{"1.2.4"}},
|
|
{"<=1.2", []string{"1.2.9"}, []string{"1.3.0"}},
|
|
{">= 1.2.3 < 2", []string{"1.2.3", "1.9.9"}, []string{"2.0.0", "1.2.2"}},
|
|
{">=1.2.3 <1.5.0", []string{"1.4.9"}, []string{"1.5.0"}},
|
|
{"1.2.3 - 2.3.4", []string{"1.2.3", "2.3.4"}, []string{"2.3.5", "1.2.2"}},
|
|
{"1.2 - 2.3", []string{"1.2.0", "2.3.9"}, []string{"2.4.0", "1.1.9"}},
|
|
{"1.2.3 - 2", []string{"2.9.9"}, []string{"3.0.0"}},
|
|
{"^1.0.0 || ^3.0.0", []string{"1.5.0", "3.1.0"}, []string{"2.0.0"}},
|
|
{"1.2.3 || >=2.5.0 <3", []string{"1.2.3", "2.6.0"}, []string{"2.0.0", "3.0.0"}},
|
|
{"v1.2.3", []string{"1.2.3"}, nil},
|
|
{"~>1.2.3", []string{"1.2.9"}, []string{"1.3.0"}},
|
|
{">=1.0.0-rc.1 <1.0.0", []string{"1.0.0-rc.2"}, []string{"0.9.0-rc.1"}},
|
|
}
|
|
for _, c := range cases {
|
|
r, err := ParseRange(c.r)
|
|
if err != nil {
|
|
t.Errorf("%q: %v", c.r, err)
|
|
continue
|
|
}
|
|
for _, s := range c.in {
|
|
v, err := ParseVersion(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !r.Satisfies(v) {
|
|
t.Errorf("%q should hold %s", c.r, s)
|
|
}
|
|
}
|
|
for _, s := range c.out {
|
|
v, _ := ParseVersion(s)
|
|
if r.Satisfies(v) {
|
|
t.Errorf("%q should not hold %s", c.r, s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestARangeThatIsNotOneIsRefused(t *testing.T) {
|
|
for _, bad := range []string{"latest", "^abc", "1.2.3.4", ">=x.y.z", "1.x-beta"} {
|
|
if _, err := ParseRange(bad); err == nil {
|
|
t.Errorf("%q read as a range", bad)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheHighestSatisfyingVersionIsTheOneARangeResolvesTo(t *testing.T) {
|
|
var vs []Version
|
|
for _, s := range []string{"0.1.0", "0.1.4", "0.2.0", "0.2.1-beta", "1.0.0"} {
|
|
v, _ := ParseVersion(s)
|
|
vs = append(vs, v)
|
|
}
|
|
r, _ := ParseRange("^0.1.0")
|
|
if best, ok := MaxSatisfying(r, vs); !ok || best.String() != "0.1.4" {
|
|
t.Fatalf("^0.1.0 resolved to %v", best)
|
|
}
|
|
r, _ = ParseRange("^2.0.0")
|
|
if _, ok := MaxSatisfying(r, vs); ok {
|
|
t.Fatal("^2.0.0 resolved to something")
|
|
}
|
|
}
|