This commit is contained in:
Sam Boyer 2016-03-17 12:53:32 -04:00
Родитель bdd3e88655
Коммит 3479717240
14 изменённых файлов: 1736 добавлений и 1 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -1 +0,0 @@
vendor

13
.travis.yml Normal file
Просмотреть файл

@ -0,0 +1,13 @@
language: go
go:
- 1.5
- 1.6
- tip
sudo: false
# Just test local dir, and make sure vendor flag is on
script:
- GO15VENDOREXPERIMENT=1 go test -v

16
vendor/github.com/Masterminds/semver/.travis.yml сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,16 @@
language: go
go:
- 1.3
- 1.4
- 1.5
- tip
# Setting sudo access to false will let Travis CI use containers rather than
# VMs to run the tests. For more details see:
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
sudo: false
notifications:
irc: "irc.freenode.net#masterminds"

12
vendor/github.com/Masterminds/semver/CHANGELOG.md сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
# Release 1.1.0 (2015-03-11)
- Issue #2: Implemented validation to provide reasons a versions failed a
constraint.
# Release 1.0.1 (2015-12-31)
- Fixed #1: * constraint failing on valid versions.
# Release 1.0.0 (2015-10-20)
- Initial release

20
vendor/github.com/Masterminds/semver/LICENSE.txt сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,20 @@
The Masterminds
Copyright (C) 2014-2015, Matt Butcher and Matt Farina
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

146
vendor/github.com/Masterminds/semver/README.md сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,146 @@
# SemVer
The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
* Parse semantic versions
* Sort semantic versions
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix
[![Build Status](https://travis-ci.org/Masterminds/semver.svg)](https://travis-ci.org/Masterminds/semver) [![Build status](https://ci.appveyor.com/api/projects/status/jfk66lib7hb985k8/branch/master?svg=true&passingText=windows%20build%20passing&failingText=windows%20build%20failing)](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [![GoDoc](https://godoc.org/github.com/Masterminds/semver?status.png)](https://godoc.org/github.com/Masterminds/semver) [![Go Report Card](http://goreportcard.com/badge/Masterminds/semver)](http://goreportcard.com/report/Masterminds/semver)
## Parsing Semantic Versions
To parse a semantic version use the `NewVersion` function. For example,
v, err := semver.NewVersion("1.2.3-beta.1+build345")
If there is an error the version wasn't parseable. The version object has methods
to get the parts of the version, compare it to other versions, convert the
version back into a string, and get the original string. For more details
please see the [documentation](https://godoc.org/github.com/Masterminds/semver).
## Sorting Semantic Versions
A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
package from the standard library. For example,
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
v, err := semver.NewVersion(r)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
vs[i] = v
}
sort.Sort(semver.Collection(vs))
## Checking Version Constraints
Checking a version against version constraints is one of the most featureful
parts of the package.
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Check if the version meets the constraints. The a variable will be true.
a := c.Check(v)
## Basic Comparisons
There are two elements to the comparisons. First, a comparison string is a list
of comma separated and comparisons. These are then separated by || separated or
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
greater than or equal to 4.2.3.
The basic comparisons are:
* `=`: equal (aliased to no operator)
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to
## Hyphen Range Comparisons
There are multiple methods to handle ranges and the first is hyphens ranges.
These look like:
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
## Wildcards In Comparisons
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
for all comparison operators. When used on the `=` operator it falls
back to the pack level comparison (see tilde below). For example,
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
* `<= 2.x` is equivalent to `<= 3`
* `*` is equivalent to `>= 0.0.0`
## Tilde Range Comparisons (Patch)
The tilde (`~`) comparison operator is for patch level ranges when a minor
version is specified and major level changes when the minor number is missing.
For example,
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
* `~1` is equivalent to `>= 1, < 2`
* `~2.3` is equivalent to `>= 2.3, < 2.4`
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `~1.x` is equivalent to `>= 1, < 2`
## Caret Range Comparisons (Major)
The caret (`^`) comparison operator is for major level changes. This is useful
when comparisons of API versions as a major change is API breaking. For example,
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
* `^2.3` is equivalent to `>= 2.3, < 3`
* `^2.x` is equivalent to `>= 2.0.0, < 3`
# Validation
In addition to testing a version against a constraint, a version can be validated
against a constraint. When validation fails a slice of errors containing why a
version didn't meet the constraint is returned. For example,
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Validate a version against a constraint.
a, msgs := c.Validate(v)
// a is false
for _, m := range msgs {
fmt.Println(m)
// Loops over the errors which would read
// "1.3 is greater than 1.2.3"
// "1.3 is less than 1.4"
}
# Contribute
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
or [create a pull request](https://github.com/Masterminds/semver/pulls).

22
vendor/github.com/Masterminds/semver/appveyor.yml сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,22 @@
version: build-{build}.{branch}
clone_folder: C:\gopath\src\github.com\Masterminds\semver
shallow_clone: true
environment:
GOPATH: C:\gopath
platform:
- x64
install:
- go version
- go env
build_script:
- go install -v ./...
test_script:
- go test -v
deploy: off

24
vendor/github.com/Masterminds/semver/collection.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,24 @@
package semver
// Collection is a collection of Version instances and implements the sort
// interface. See the sort package for more details.
// https://golang.org/pkg/sort/
type Collection []*Version
// Len returns the length of a collection. The number of Version instances
// on the slice.
func (c Collection) Len() int {
return len(c)
}
// Less is needed for the sort interface to compare two Version objects on the
// slice. If checks if one is less than the other.
func (c Collection) Less(i, j int) bool {
return c[i].LessThan(c[j])
}
// Swap is needed for the sort interface to replace the Version objects
// at two different positions in the slice.
func (c Collection) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}

46
vendor/github.com/Masterminds/semver/collection_test.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,46 @@
package semver
import (
"reflect"
"sort"
"testing"
)
func TestCollection(t *testing.T) {
raw := []string{
"1.2.3",
"1.0",
"1.3",
"2",
"0.4.2",
}
vs := make([]*Version, len(raw))
for i, r := range raw {
v, err := NewVersion(r)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
vs[i] = v
}
sort.Sort(Collection(vs))
e := []string{
"0.4.2",
"1.0.0",
"1.2.3",
"1.3.0",
"2.0.0",
}
a := make([]string, len(vs))
for i, v := range vs {
a[i] = v.String()
}
if !reflect.DeepEqual(a, e) {
t.Error("Sorting Collection failed")
}
}

340
vendor/github.com/Masterminds/semver/constraints.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,340 @@
package semver
import (
"errors"
"fmt"
"regexp"
"strings"
)
// Constraints is one or more constraint that a semantic version can be
// checked against.
type Constraints struct {
constraints [][]*constraint
}
// NewConstraint returns a Constraints instance that a Version instance can
// be checked against. If there is a parse error it will be returned.
func NewConstraint(c string) (*Constraints, error) {
// Rewrite - ranges into a comparison operation.
c = rewriteRange(c)
ors := strings.Split(c, "||")
or := make([][]*constraint, len(ors))
for k, v := range ors {
cs := strings.Split(v, ",")
result := make([]*constraint, len(cs))
for i, s := range cs {
pc, err := parseConstraint(s)
if err != nil {
return nil, err
}
result[i] = pc
}
or[k] = result
}
o := &Constraints{constraints: or}
return o, nil
}
// Check tests if a version satisfies the constraints.
func (cs Constraints) Check(v *Version) bool {
// loop over the ORs and check the inner ANDs
for _, o := range cs.constraints {
joy := true
for _, c := range o {
if !c.check(v) {
joy = false
break
}
}
if joy {
return true
}
}
return false
}
// Validate checks if a version satisfies a constraint. If not a slice of
// reasons for the failure are returned in addition to a bool.
func (cs Constraints) Validate(v *Version) (bool, []error) {
// loop over the ORs and check the inner ANDs
var e []error
for _, o := range cs.constraints {
joy := true
for _, c := range o {
if !c.check(v) {
em := fmt.Errorf(c.msg, v, c.orig)
e = append(e, em)
joy = false
}
}
if joy {
return true, []error{}
}
}
return false, e
}
var constraintOps map[string]cfunc
var constraintMsg map[string]string
var constraintRegex *regexp.Regexp
func init() {
constraintOps = map[string]cfunc{
"": constraintTildeOrEqual,
"=": constraintTildeOrEqual,
"!=": constraintNotEqual,
">": constraintGreaterThan,
"<": constraintLessThan,
">=": constraintGreaterThanEqual,
"=>": constraintGreaterThanEqual,
"<=": constraintLessThanEqual,
"=<": constraintLessThanEqual,
"~": constraintTilde,
"~>": constraintTilde,
"^": constraintCaret,
}
constraintMsg = map[string]string{
"": "%s is not equal to %s",
"=": "%s is not equal to %s",
"!=": "%s is equal to %s",
">": "%s is less than or equal to %s",
"<": "%s is greater than or equal to %s",
">=": "%s is less than %s",
"=>": "%s is less than %s",
"<=": "%s is greater than %s",
"=<": "%s is greater than %s",
"~": "%s does not have same major and minor version as %s",
"~>": "%s does not have same major and minor version as %s",
"^": "%s does not have same major version as %s",
}
ops := make([]string, 0, len(constraintOps))
for k := range constraintOps {
ops = append(ops, regexp.QuoteMeta(k))
}
constraintRegex = regexp.MustCompile(fmt.Sprintf(
`^\s*(%s)\s*(%s)\s*$`,
strings.Join(ops, "|"),
cvRegex))
constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
`\s*(%s)\s*-\s*(%s)\s*`,
cvRegex, cvRegex))
}
// An individual constraint
type constraint struct {
// The callback function for the restraint. It performs the logic for
// the constraint.
function cfunc
msg string
// The version used in the constraint check. For example, if a constraint
// is '<= 2.0.0' the con a version instance representing 2.0.0.
con *Version
// The original parsed version (e.g., 4.x from != 4.x)
orig string
// When an x is used as part of the version (e.g., 1.x)
minorDirty bool
dirty bool
}
// Check if a version meets the constraint
func (c *constraint) check(v *Version) bool {
return c.function(v, c)
}
type cfunc func(v *Version, c *constraint) bool
func parseConstraint(c string) (*constraint, error) {
m := constraintRegex.FindStringSubmatch(c)
if m == nil {
return nil, fmt.Errorf("improper constraint: %s", c)
}
ver := m[2]
orig := ver
minorDirty := false
dirty := false
if isX(m[3]) {
ver = "0.0.0"
dirty = true
} else if isX(strings.TrimPrefix(m[4], ".")) {
minorDirty = true
dirty = true
ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
} else if isX(strings.TrimPrefix(m[5], ".")) {
dirty = true
ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
}
con, err := NewVersion(ver)
if err != nil {
// The constraintRegex should catch any regex parsing errors. So,
// we should never get here.
return nil, errors.New("constraint Parser Error")
}
cs := &constraint{
function: constraintOps[m[1]],
msg: constraintMsg[m[1]],
con: con,
orig: orig,
minorDirty: minorDirty,
dirty: dirty,
}
return cs, nil
}
// Constraint functions
func constraintNotEqual(v *Version, c *constraint) bool {
if c.dirty {
if c.con.Major() != v.Major() {
return true
}
if c.con.Minor() != v.Minor() && !c.minorDirty {
return true
} else if c.minorDirty {
return false
}
return false
}
return !v.Equal(c.con)
}
func constraintGreaterThan(v *Version, c *constraint) bool {
return v.Compare(c.con) == 1
}
func constraintLessThan(v *Version, c *constraint) bool {
if !c.dirty {
return v.Compare(c.con) < 0
}
if v.Major() > c.con.Major() {
return false
} else if v.Minor() > c.con.Minor() && !c.minorDirty {
return false
}
return true
}
func constraintGreaterThanEqual(v *Version, c *constraint) bool {
return v.Compare(c.con) >= 0
}
func constraintLessThanEqual(v *Version, c *constraint) bool {
if !c.dirty {
return v.Compare(c.con) <= 0
}
if v.Major() > c.con.Major() {
return false
} else if v.Minor() > c.con.Minor() && !c.minorDirty {
return false
}
return true
}
// ~*, ~>* --> >= 0.0.0 (any)
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
func constraintTilde(v *Version, c *constraint) bool {
if v.LessThan(c.con) {
return false
}
// ~0.0.0 is a special case where all constraints are accepted. It's
// equivalent to >= 0.0.0.
if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 {
return true
}
if v.Major() != c.con.Major() {
return false
}
if v.Minor() != c.con.Minor() && !c.minorDirty {
return false
}
return true
}
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
// it's a straight =
func constraintTildeOrEqual(v *Version, c *constraint) bool {
if c.dirty {
c.msg = constraintMsg["~"]
return constraintTilde(v, c)
}
return v.Equal(c.con)
}
// ^* --> (any)
// ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0
// ^2.0, ^2.0.x --> >=2.0.0, <3.0.0
// ^1.2, ^1.2.x --> >=1.2.0, <2.0.0
// ^1.2.3 --> >=1.2.3, <2.0.0
// ^1.2.0 --> >=1.2.0, <2.0.0
func constraintCaret(v *Version, c *constraint) bool {
if v.LessThan(c.con) {
return false
}
if v.Major() != c.con.Major() {
return false
}
return true
}
type rwfunc func(i string) string
var constraintRangeRegex *regexp.Regexp
const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
func isX(x string) bool {
l := strings.ToLower(x)
return l == "x" || l == "*"
}
func rewriteRange(i string) string {
m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
if m == nil {
return i
}
o := i
for _, v := range m {
t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
o = strings.Replace(o, v[0], t, 1)
}
return o
}

428
vendor/github.com/Masterminds/semver/constraints_test.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,428 @@
package semver
import (
"reflect"
"testing"
)
func TestParseConstraint(t *testing.T) {
tests := []struct {
in string
f cfunc
v string
err bool
}{
{">= 1.2", constraintGreaterThanEqual, "1.2.0", false},
{"1.0", constraintTildeOrEqual, "1.0.0", false},
{"foo", nil, "", true},
{"<= 1.2", constraintLessThanEqual, "1.2.0", false},
{"=< 1.2", constraintLessThanEqual, "1.2.0", false},
{"=> 1.2", constraintGreaterThanEqual, "1.2.0", false},
{"v1.2", constraintTildeOrEqual, "1.2.0", false},
{"=1.5", constraintTildeOrEqual, "1.5.0", false},
{"> 1.3", constraintGreaterThan, "1.3.0", false},
{"< 1.4.1", constraintLessThan, "1.4.1", false},
}
for _, tc := range tests {
c, err := parseConstraint(tc.in)
if tc.err && err == nil {
t.Errorf("Expected error for %s didn't occur", tc.in)
} else if !tc.err && err != nil {
t.Errorf("Unexpected error for %s", tc.in)
}
// If an error was expected continue the loop and don't try the other
// tests as they will cause errors.
if tc.err {
continue
}
if tc.v != c.con.String() {
t.Errorf("Incorrect version found on %s", tc.in)
}
f1 := reflect.ValueOf(tc.f)
f2 := reflect.ValueOf(c.function)
if f1 != f2 {
t.Errorf("Wrong constraint found for %s", tc.in)
}
}
}
func TestConstraintCheck(t *testing.T) {
tests := []struct {
constraint string
version string
check bool
}{
{"= 2.0", "1.2.3", false},
{"= 2.0", "2.0.0", true},
{"4.1", "4.1.0", true},
{"!=4.1", "4.1.0", false},
{"!=4.1", "5.1.0", true},
{">1.1", "4.1.0", true},
{">1.1", "1.1.0", false},
{"<1.1", "0.1.0", true},
{"<1.1", "1.1.0", false},
{"<1.1", "1.1.1", false},
{">=1.1", "4.1.0", true},
{">=1.1", "1.1.0", true},
{">=1.1", "0.0.9", false},
{"<=1.1", "0.1.0", true},
{"<=1.1", "1.1.0", true},
{"<=1.1", "1.1.1", false},
}
for _, tc := range tests {
c, err := parseConstraint(tc.constraint)
if err != nil {
t.Errorf("err: %s", err)
continue
}
v, err := NewVersion(tc.version)
if err != nil {
t.Errorf("err: %s", err)
continue
}
a := c.check(v)
if a != tc.check {
t.Errorf("Constraint '%s' failing", tc.constraint)
}
}
}
func TestNewConstraint(t *testing.T) {
tests := []struct {
input string
ors int
count int
err bool
}{
{">= 1.1", 1, 1, false},
{"2.0", 1, 1, false},
{">= bar", 0, 0, true},
{">= 1.2.3, < 2.0", 1, 2, false},
{">= 1.2.3, < 2.0 || => 3.0, < 4", 2, 2, false},
// The 3-4 should be broken into 2 by the range rewriting
{"3-4 || => 3.0, < 4", 2, 2, false},
}
for _, tc := range tests {
v, err := NewConstraint(tc.input)
if tc.err && err == nil {
t.Errorf("expected but did not get error for: %s", tc.input)
continue
} else if !tc.err && err != nil {
t.Errorf("unexpectederror for input %s: %s", tc.input, err)
continue
}
if tc.err {
continue
}
l := len(v.constraints)
if tc.ors != l {
t.Errorf("Expected %s to have %d ORs but got %d",
tc.input, tc.ors, l)
}
l = len(v.constraints[0])
if tc.count != l {
t.Errorf("Expected %s to have %d constraints but got %d",
tc.input, tc.count, l)
}
}
}
func TestConstraintsCheck(t *testing.T) {
tests := []struct {
constraint string
version string
check bool
}{
{"*", "1.2.3", true},
{"~0.0.0", "1.2.3", true},
{"= 2.0", "1.2.3", false},
{"= 2.0", "2.0.0", true},
{"4.1", "4.1.0", true},
{"4.1.x", "4.1.3", true},
{"1.x", "1.4", true},
{"!=4.1", "4.1.0", false},
{"!=4.1", "5.1.0", true},
{"!=4.x", "5.1.0", true},
{"!=4.x", "4.1.0", false},
{"!=4.1.x", "4.2.0", true},
{"!=4.2.x", "4.2.3", false},
{">1.1", "4.1.0", true},
{">1.1", "1.1.0", false},
{"<1.1", "0.1.0", true},
{"<1.1", "1.1.0", false},
{"<1.1", "1.1.1", false},
{"<1.x", "1.1.1", true},
{"<1.x", "2.1.1", false},
{"<1.1.x", "1.2.1", false},
{"<1.1.x", "1.1.500", true},
{"<1.2.x", "1.1.1", true},
{">=1.1", "4.1.0", true},
{">=1.1", "1.1.0", true},
{">=1.1", "0.0.9", false},
{"<=1.1", "0.1.0", true},
{"<=1.1", "1.1.0", true},
{"<=1.x", "1.1.0", true},
{"<=2.x", "3.1.0", false},
{"<=1.1", "1.1.1", false},
{"<=1.1.x", "1.2.500", false},
{">1.1, <2", "1.1.1", true},
{">1.1, <3", "4.3.2", false},
{">=1.1, <2, !=1.2.3", "1.2.3", false},
{">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true},
{">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true},
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false},
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false},
{"1.1 - 2", "1.1.1", true},
{"1.1-3", "4.3.2", false},
{"^1.1", "1.1.1", true},
{"^1.1", "4.3.2", false},
{"^1.x", "1.1.1", true},
{"^2.x", "1.1.1", false},
{"^1.x", "2.1.1", false},
{"~*", "2.1.1", true},
{"~1.x", "2.1.1", false},
{"~1.x", "1.3.5", true},
{"~1.x", "1.4", true},
{"~1.1", "1.1.1", true},
{"~1.2.3", "1.2.5", true},
{"~1.2.3", "1.2.2", false},
{"~1.2.3", "1.3.2", false},
{"~1.1", "1.2.3", false},
{"~1.3", "2.4.5", false},
}
for _, tc := range tests {
c, err := NewConstraint(tc.constraint)
if err != nil {
t.Errorf("err: %s", err)
continue
}
v, err := NewVersion(tc.version)
if err != nil {
t.Errorf("err: %s", err)
continue
}
a := c.Check(v)
if a != tc.check {
t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version)
}
}
}
func TestRewriteRange(t *testing.T) {
tests := []struct {
c string
nc string
}{
{"2-3", ">= 2, <= 3"},
{"2-3, 2-3", ">= 2, <= 3,>= 2, <= 3"},
{"2-3, 4.0.0-5.1", ">= 2, <= 3,>= 4.0.0, <= 5.1"},
}
for _, tc := range tests {
o := rewriteRange(tc.c)
if o != tc.nc {
t.Errorf("Range %s rewritten incorrectly as '%s'", tc.c, o)
}
}
}
func TestIsX(t *testing.T) {
tests := []struct {
t string
c bool
}{
{"A", false},
{"%", false},
{"X", true},
{"x", true},
{"*", true},
}
for _, tc := range tests {
a := isX(tc.t)
if a != tc.c {
t.Errorf("Function isX error on %s", tc.t)
}
}
}
func TestConstraintsValidate(t *testing.T) {
tests := []struct {
constraint string
version string
check bool
}{
{"*", "1.2.3", true},
{"~0.0.0", "1.2.3", true},
{"= 2.0", "1.2.3", false},
{"= 2.0", "2.0.0", true},
{"4.1", "4.1.0", true},
{"4.1.x", "4.1.3", true},
{"1.x", "1.4", true},
{"!=4.1", "4.1.0", false},
{"!=4.1", "5.1.0", true},
{"!=4.x", "5.1.0", true},
{"!=4.x", "4.1.0", false},
{"!=4.1.x", "4.2.0", true},
{"!=4.2.x", "4.2.3", false},
{">1.1", "4.1.0", true},
{">1.1", "1.1.0", false},
{"<1.1", "0.1.0", true},
{"<1.1", "1.1.0", false},
{"<1.1", "1.1.1", false},
{"<1.x", "1.1.1", true},
{"<1.x", "2.1.1", false},
{"<1.1.x", "1.2.1", false},
{"<1.1.x", "1.1.500", true},
{"<1.2.x", "1.1.1", true},
{">=1.1", "4.1.0", true},
{">=1.1", "1.1.0", true},
{">=1.1", "0.0.9", false},
{"<=1.1", "0.1.0", true},
{"<=1.1", "1.1.0", true},
{"<=1.x", "1.1.0", true},
{"<=2.x", "3.1.0", false},
{"<=1.1", "1.1.1", false},
{"<=1.1.x", "1.2.500", false},
{">1.1, <2", "1.1.1", true},
{">1.1, <3", "4.3.2", false},
{">=1.1, <2, !=1.2.3", "1.2.3", false},
{">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true},
{">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true},
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false},
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false},
{"1.1 - 2", "1.1.1", true},
{"1.1-3", "4.3.2", false},
{"^1.1", "1.1.1", true},
{"^1.1", "4.3.2", false},
{"^1.x", "1.1.1", true},
{"^2.x", "1.1.1", false},
{"^1.x", "2.1.1", false},
{"~*", "2.1.1", true},
{"~1.x", "2.1.1", false},
{"~1.x", "1.3.5", true},
{"~1.x", "1.4", true},
{"~1.1", "1.1.1", true},
{"~1.2.3", "1.2.5", true},
{"~1.2.3", "1.2.2", false},
{"~1.2.3", "1.3.2", false},
{"~1.1", "1.2.3", false},
{"~1.3", "2.4.5", false},
}
for _, tc := range tests {
c, err := NewConstraint(tc.constraint)
if err != nil {
t.Errorf("err: %s", err)
continue
}
v, err := NewVersion(tc.version)
if err != nil {
t.Errorf("err: %s", err)
continue
}
a, msgs := c.Validate(v)
if a != tc.check {
t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version)
} else if a == false && len(msgs) == 0 {
t.Errorf("%q failed with %q but no errors returned", tc.constraint, tc.version)
}
// if a == false {
// for _, m := range msgs {
// t.Errorf("%s", m)
// }
// }
}
v, err := NewVersion("1.2.3")
if err != nil {
t.Errorf("err: %s", err)
}
c, err := NewConstraint("!= 1.2.5, ^2, <= 1.1.x")
if err != nil {
t.Errorf("err: %s", err)
}
_, msgs := c.Validate(v)
if len(msgs) != 2 {
t.Error("Invalid number of validations found")
}
e := msgs[0].Error()
if e != "1.2.3 does not have same major version as 2" {
t.Error("Did not get expected message: 1.2.3 does not have same major version as 2")
}
e = msgs[1].Error()
if e != "1.2.3 is greater than 1.1.x" {
t.Error("Did not get expected message: 1.2.3 is greater than 1.1.x")
}
tests2 := []struct {
constraint, version, msg string
}{
{"= 2.0", "1.2.3", "1.2.3 is not equal to 2.0"},
{"!=4.1", "4.1.0", "4.1.0 is equal to 4.1"},
{"!=4.x", "4.1.0", "4.1.0 is equal to 4.x"},
{"!=4.2.x", "4.2.3", "4.2.3 is equal to 4.2.x"},
{">1.1", "1.1.0", "1.1.0 is less than or equal to 1.1"},
{"<1.1", "1.1.0", "1.1.0 is greater than or equal to 1.1"},
{"<1.1", "1.1.1", "1.1.1 is greater than or equal to 1.1"},
{"<1.x", "2.1.1", "2.1.1 is greater than or equal to 1.x"},
{"<1.1.x", "1.2.1", "1.2.1 is greater than or equal to 1.1.x"},
{">=1.1", "0.0.9", "0.0.9 is less than 1.1"},
{"<=2.x", "3.1.0", "3.1.0 is greater than 2.x"},
{"<=1.1", "1.1.1", "1.1.1 is greater than 1.1"},
{"<=1.1.x", "1.2.500", "1.2.500 is greater than 1.1.x"},
{">1.1, <3", "4.3.2", "4.3.2 is greater than or equal to 3"},
{">=1.1, <2, !=1.2.3", "1.2.3", "1.2.3 is equal to 1.2.3"},
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", "3.0.0 is greater than or equal to 2"},
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", "1.2.3 is equal to 1.2.3"},
{"1.1-3", "4.3.2", "4.3.2 is greater than 3"},
{"^1.1", "4.3.2", "4.3.2 does not have same major version as 1.1"},
{"^2.x", "1.1.1", "1.1.1 does not have same major version as 2.x"},
{"^1.x", "2.1.1", "2.1.1 does not have same major version as 1.x"},
{"~1.x", "2.1.1", "2.1.1 does not have same major and minor version as 1.x"},
{"~1.2.3", "1.2.2", "1.2.2 does not have same major and minor version as 1.2.3"},
{"~1.2.3", "1.3.2", "1.3.2 does not have same major and minor version as 1.2.3"},
{"~1.1", "1.2.3", "1.2.3 does not have same major and minor version as 1.1"},
{"~1.3", "2.4.5", "2.4.5 does not have same major and minor version as 1.3"},
}
for _, tc := range tests2 {
c, err := NewConstraint(tc.constraint)
if err != nil {
t.Errorf("err: %s", err)
continue
}
v, err := NewVersion(tc.version)
if err != nil {
t.Errorf("err: %s", err)
continue
}
_, msgs := c.Validate(v)
e := msgs[0].Error()
if e != tc.msg {
t.Errorf("Did not get expected message %q: %s", tc.msg, e)
}
}
}

115
vendor/github.com/Masterminds/semver/doc.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,115 @@
/*
Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
Specifically it provides the ability to:
* Parse semantic versions
* Sort semantic versions
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix
Parsing Semantic Versions
To parse a semantic version use the `NewVersion` function. For example,
v, err := semver.NewVersion("1.2.3-beta.1+build345")
If there is an error the version wasn't parseable. The version object has methods
to get the parts of the version, compare it to other versions, convert the
version back into a string, and get the original string. For more details
please see the documentation at https://godoc.org/github.com/Masterminds/semver.
Sorting Semantic Versions
A set of versions can be sorted using the `sort` package from the standard library.
For example,
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
v, err := semver.NewVersion(r)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
vs[i] = v
}
sort.Sort(semver.Collection(vs))
Checking Version Constraints
Checking a version against version constraints is one of the most featureful
parts of the package.
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Check if the version meets the constraints. The a variable will be true.
a := c.Check(v)
Basic Comparisons
There are two elements to the comparisons. First, a comparison string is a list
of comma separated and comparisons. These are then separated by || separated or
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
greater than or equal to 4.2.3.
The basic comparisons are:
* `=`: equal (aliased to no operator)
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to
Hyphen Range Comparisons
There are multiple methods to handle ranges and the first is hyphens ranges.
These look like:
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
Wildcards In Comparisons
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
for all comparison operators. When used on the `=` operator it falls
back to the pack level comparison (see tilde below). For example,
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
* `<= 2.x` is equivalent to `<= 3`
* `*` is equivalent to `>= 0.0.0`
Tilde Range Comparisons (Patch)
The tilde (`~`) comparison operator is for patch level ranges when a minor
version is specified and major level changes when the minor number is missing.
For example,
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
* `~1` is equivalent to `>= 1, < 2`
* `~2.3` is equivalent to `>= 2.3, < 2.4`
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `~1.x` is equivalent to `>= 1, < 2`
Caret Range Comparisons (Major)
The caret (`^`) comparison operator is for major level changes. This is useful
when comparisons of API versions as a major change is API breaking. For example,
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
* `^2.3` is equivalent to `>= 2.3, < 3`
* `^2.x` is equivalent to `>= 2.0.0, < 3`
*/
package semver

271
vendor/github.com/Masterminds/semver/version.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,271 @@
package semver
import (
"bytes"
"errors"
"fmt"
"regexp"
"strconv"
"strings"
)
// The compiled version of the regex created at init() is cached here so it
// only needs to be created once.
var versionRegex *regexp.Regexp
var (
// ErrInvalidSemVer is returned a version is found to be invalid when
// being parsed.
ErrInvalidSemVer = errors.New("Invalid Semantic Version")
)
// SemVerRegex id the regular expression used to parse a semantic version.
const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
// Version represents a single semantic version.
type Version struct {
major, minor, patch int64
pre string
metadata string
original string
}
func init() {
versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
}
// NewVersion parses a given version and returns an instance of Version or
// an error if unable to parse the version.
func NewVersion(v string) (*Version, error) {
m := versionRegex.FindStringSubmatch(v)
if m == nil {
return nil, ErrInvalidSemVer
}
sv := &Version{
metadata: m[8],
pre: m[5],
original: v,
}
var temp int64
temp, err := strconv.ParseInt(m[1], 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.major = temp
if m[2] != "" {
temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.minor = temp
} else {
sv.minor = 0
}
if m[3] != "" {
temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.patch = temp
} else {
sv.patch = 0
}
return sv, nil
}
// String converts a Version object to a string.
// Note, if the original version contained a leading v this version will not.
// See the Original() method to retrieve the original value. Semantic Versions
// don't contain a leading v per the spec. Instead it's optional on
// impelementation.
func (v *Version) String() string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
if v.pre != "" {
fmt.Fprintf(&buf, "-%s", v.pre)
}
if v.metadata != "" {
fmt.Fprintf(&buf, "+%s", v.metadata)
}
return buf.String()
}
// Original returns the original value passed in to be parsed.
func (v *Version) Original() string {
return v.original
}
// Major returns the major version.
func (v *Version) Major() int64 {
return v.major
}
// Minor returns the minor version.
func (v *Version) Minor() int64 {
return v.minor
}
// Patch returns the patch version.
func (v *Version) Patch() int64 {
return v.patch
}
// Prerelease returns the pre-release version.
func (v *Version) Prerelease() string {
return v.pre
}
// Metadata returns the metadata on the version.
func (v *Version) Metadata() string {
return v.metadata
}
// LessThan tests if one version is less than another one.
func (v *Version) LessThan(o *Version) bool {
return v.Compare(o) < 0
}
// GreaterThan tests if one version is greater than another one.
func (v *Version) GreaterThan(o *Version) bool {
return v.Compare(o) > 0
}
// Equal tests if two versions are equal to each other.
// Note, versions can be equal with different metadata since metadata
// is not considered part of the comparable version.
func (v *Version) Equal(o *Version) bool {
return v.Compare(o) == 0
}
// Compare compares this version to another one. It returns -1, 0, or 1 if
// the version smaller, equal, or larger than the other version.
//
// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
// lower than the version without a prerelease.
func (v *Version) Compare(o *Version) int {
// Fastpath if both versions are the same.
if v.String() == o.String() {
return 0
}
// Compare the major, minor, and patch version for differences. If a
// difference is found return the comparison.
if d := compareSegment(v.Major(), o.Major()); d != 0 {
return d
}
if d := compareSegment(v.Minor(), o.Minor()); d != 0 {
return d
}
if d := compareSegment(v.Patch(), o.Patch()); d != 0 {
return d
}
// At this point the major, minor, and patch versions are the same.
ps := v.pre
po := o.Prerelease()
if ps == "" && po == "" {
return 0
}
if ps == "" {
return 1
}
if po == "" {
return -1
}
return comparePrerelease(ps, po)
}
func compareSegment(v, o int64) int {
if v < o {
return -1
}
if v > o {
return 1
}
return 0
}
func comparePrerelease(v, o string) int {
// split the prelease versions by their part. The separator, per the spec,
// is a .
sparts := strings.Split(v, ".")
oparts := strings.Split(o, ".")
// Find the longer length of the parts to know how many loop iterations to
// go through.
slen := len(sparts)
olen := len(oparts)
l := slen
if olen > slen {
l = olen
}
// Iterate over each part of the prereleases to compare the differences.
for i := 0; i < l; i++ {
// Since the lentgh of the parts can be different we need to create
// a placeholder. This is to avoid out of bounds issues.
stemp := ""
if i < slen {
stemp = sparts[i]
}
otemp := ""
if i < olen {
otemp = oparts[i]
}
d := comparePrePart(stemp, otemp)
if d != 0 {
return d
}
}
// Reaching here means two versions are of equal value but have different
// metadata (the part following a +). They are not identical in string form
// but the version comparison finds them to be equal.
return 0
}
func comparePrePart(s, o string) int {
// Fastpath if they are equal
if s == o {
return 0
}
// When s or o are empty we can use the other in an attempt to determine
// the response.
if o == "" {
_, n := strconv.ParseInt(s, 10, 64)
if n != nil {
return -1
}
return 1
}
if s == "" {
_, n := strconv.ParseInt(o, 10, 64)
if n != nil {
return 1
}
return -1
}
if s > o {
return 1
}
return -1
}

283
vendor/github.com/Masterminds/semver/version_test.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,283 @@
package semver
import (
"testing"
)
func TestNewVersion(t *testing.T) {
tests := []struct {
version string
err bool
}{
{"1.2.3", false},
{"v1.2.3", false},
{"1.0", false},
{"v1.0", false},
{"1", false},
{"v1", false},
{"1.2.beta", true},
{"v1.2.beta", true},
{"foo", true},
{"1.2-5", false},
{"v1.2-5", false},
{"1.2-beta.5", false},
{"v1.2-beta.5", false},
{"\n1.2", true},
{"\nv1.2", true},
{"1.2.0-x.Y.0+metadata", false},
{"v1.2.0-x.Y.0+metadata", false},
{"1.2.0-x.Y.0+metadata-width-hypen", false},
{"v1.2.0-x.Y.0+metadata-width-hypen", false},
{"1.2.3-rc1-with-hypen", false},
{"v1.2.3-rc1-with-hypen", false},
{"1.2.3.4", true},
{"v1.2.3.4", true},
}
for _, tc := range tests {
_, err := NewVersion(tc.version)
if tc.err && err == nil {
t.Fatalf("expected error for version: %s", tc.version)
} else if !tc.err && err != nil {
t.Fatalf("error for version %s: %s", tc.version, err)
}
}
}
func TestOriginal(t *testing.T) {
tests := []string{
"1.2.3",
"v1.2.3",
"1.0",
"v1.0",
"1",
"v1",
"1.2-5",
"v1.2-5",
"1.2-beta.5",
"v1.2-beta.5",
"1.2.0-x.Y.0+metadata",
"v1.2.0-x.Y.0+metadata",
"1.2.0-x.Y.0+metadata-width-hypen",
"v1.2.0-x.Y.0+metadata-width-hypen",
"1.2.3-rc1-with-hypen",
"v1.2.3-rc1-with-hypen",
}
for _, tc := range tests {
v, err := NewVersion(tc)
if err != nil {
t.Errorf("Error parsing version %s", tc)
}
o := v.Original()
if o != tc {
t.Errorf("Error retrieving originl. Expected '%s' but got '%s'", tc, v)
}
}
}
func TestParts(t *testing.T) {
v, err := NewVersion("1.2.3-beta.1+build.123")
if err != nil {
t.Error("Error parsing version 1.2.3-beta.1+build.123")
}
if v.Major() != 1 {
t.Error("Major() returning wrong value")
}
if v.Minor() != 2 {
t.Error("Minor() returning wrong value")
}
if v.Patch() != 3 {
t.Error("Patch() returning wrong value")
}
if v.Prerelease() != "beta.1" {
t.Error("Prerelease() returning wrong value")
}
if v.Metadata() != "build.123" {
t.Error("Metadata() returning wrong value")
}
}
func TestString(t *testing.T) {
tests := []struct {
version string
expected string
}{
{"1.2.3", "1.2.3"},
{"v1.2.3", "1.2.3"},
{"1.0", "1.0.0"},
{"v1.0", "1.0.0"},
{"1", "1.0.0"},
{"v1", "1.0.0"},
{"1.2-5", "1.2.0-5"},
{"v1.2-5", "1.2.0-5"},
{"1.2-beta.5", "1.2.0-beta.5"},
{"v1.2-beta.5", "1.2.0-beta.5"},
{"1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"},
{"v1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"},
{"1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"},
{"v1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"},
{"1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"},
{"v1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"},
}
for _, tc := range tests {
v, err := NewVersion(tc.version)
if err != nil {
t.Errorf("Error parsing version %s", tc)
}
s := v.String()
if s != tc.expected {
t.Errorf("Error generating string. Expected '%s' but got '%s'", tc.expected, s)
}
}
}
func TestCompare(t *testing.T) {
tests := []struct {
v1 string
v2 string
expected int
}{
{"1.2.3", "1.5.1", -1},
{"2.2.3", "1.5.1", 1},
{"2.2.3", "2.2.2", 1},
{"3.2-beta", "3.2-beta", 0},
{"1.3", "1.1.4", 1},
{"4.2", "4.2-beta", 1},
{"4.2-beta", "4.2", -1},
{"4.2-alpha", "4.2-beta", -1},
{"4.2-alpha", "4.2-alpha", 0},
{"4.2-beta.2", "4.2-beta.1", 1},
{"4.2-beta2", "4.2-beta1", 1},
{"4.2-beta", "4.2-beta.2", -1},
{"4.2-beta", "4.2-beta.foo", 1},
{"4.2-beta.2", "4.2-beta", 1},
{"4.2-beta.foo", "4.2-beta", -1},
{"1.2+bar", "1.2+baz", 0},
}
for _, tc := range tests {
v1, err := NewVersion(tc.v1)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
v2, err := NewVersion(tc.v2)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
a := v1.Compare(v2)
e := tc.expected
if a != e {
t.Errorf(
"Comparison of '%s' and '%s' failed. Expected '%d', got '%d'",
tc.v1, tc.v2, e, a,
)
}
}
}
func TestLessThan(t *testing.T) {
tests := []struct {
v1 string
v2 string
expected bool
}{
{"1.2.3", "1.5.1", true},
{"2.2.3", "1.5.1", false},
{"3.2-beta", "3.2-beta", false},
}
for _, tc := range tests {
v1, err := NewVersion(tc.v1)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
v2, err := NewVersion(tc.v2)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
a := v1.LessThan(v2)
e := tc.expected
if a != e {
t.Errorf(
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
tc.v1, tc.v2, e, a,
)
}
}
}
func TestGreaterThan(t *testing.T) {
tests := []struct {
v1 string
v2 string
expected bool
}{
{"1.2.3", "1.5.1", false},
{"2.2.3", "1.5.1", true},
{"3.2-beta", "3.2-beta", false},
}
for _, tc := range tests {
v1, err := NewVersion(tc.v1)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
v2, err := NewVersion(tc.v2)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
a := v1.GreaterThan(v2)
e := tc.expected
if a != e {
t.Errorf(
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
tc.v1, tc.v2, e, a,
)
}
}
}
func TestEqual(t *testing.T) {
tests := []struct {
v1 string
v2 string
expected bool
}{
{"1.2.3", "1.5.1", false},
{"2.2.3", "1.5.1", false},
{"3.2-beta", "3.2-beta", true},
{"3.2-beta+foo", "3.2-beta+bar", true},
}
for _, tc := range tests {
v1, err := NewVersion(tc.v1)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
v2, err := NewVersion(tc.v2)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
a := v1.Equal(v2)
e := tc.expected
if a != e {
t.Errorf(
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
tc.v1, tc.v2, e, a,
)
}
}
}