Browse Source

Change to value arguments

Benedikt Lang 11 years ago
parent
commit
c8864c2e3e
3 changed files with 68 additions and 59 deletions
  1. +30
    -30
      semver.go
  2. +37
    -28
      semver_test.go
  3. +1
    -1
      sql.go

+ 30
- 30
semver.go View File

@ -27,7 +27,7 @@ type Version struct {
Major uint64
Minor uint64
Patch uint64
Pre []*PRVersion
Pre []PRVersion
Build []string //No Precendence
}
@ -56,22 +56,22 @@ func (v Version) String() string {
}
// Checks if v is greater than o.
func (v Version) GT(o *Version) bool {
func (v Version) GT(o Version) bool {
return (v.Compare(o) == 1)
}
// Checks if v is greater than or equal to o.
func (v Version) GTE(o *Version) bool {
func (v Version) GTE(o Version) bool {
return (v.Compare(o) >= 0)
}
// Checks if v is less than o.
func (v Version) LT(o *Version) bool {
func (v Version) LT(o Version) bool {
return (v.Compare(o) == -1)
}
// Checks if v is less than or equal to o.
func (v Version) LTE(o *Version) bool {
func (v Version) LTE(o Version) bool {
return (v.Compare(o) <= 0)
}
@ -79,7 +79,7 @@ func (v Version) LTE(o *Version) bool {
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v Version) Compare(o *Version) int {
func (v Version) Compare(o Version) int {
if v.Major != o.Major {
if v.Major > o.Major {
return 1
@ -166,44 +166,44 @@ func (v Version) Validate() error {
}
// Alias for Parse, parses version string and returns a validated Version or error
func New(s string) (*Version, error) {
func New(s string) (Version, error) {
return Parse(s)
}
// Parses version string and returns a validated Version or error
func Parse(s string) (*Version, error) {
func Parse(s string) (Version, error) {
if len(s) == 0 {
return nil, errors.New("Version string empty")
return Version{}, errors.New("Version string empty")
}
// Split into major.minor.(patch+pr+meta)
parts := strings.SplitN(s, ".", 3)
if len(parts) != 3 {
return nil, errors.New("No Major.Minor.Patch elements found")
return Version{}, errors.New("No Major.Minor.Patch elements found")
}
// Major
if !containsOnly(parts[0], numbers) {
return nil, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
}
if hasLeadingZeroes(parts[0]) {
return nil, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
}
major, err := strconv.ParseUint(parts[0], 10, 64)
if err != nil {
return nil, err
return Version{}, err
}
// Minor
if !containsOnly(parts[1], numbers) {
return nil, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
}
if hasLeadingZeroes(parts[1]) {
return nil, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
}
minor, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return nil, err
return Version{}, err
}
preIndex := strings.Index(parts[2], "-")
@ -228,16 +228,16 @@ func Parse(s string) (*Version, error) {
}
if !containsOnly(parts[2][:subVersionIndex], numbers) {
return nil, fmt.Errorf("Invalid character(s) found in patch number %q", parts[2][:subVersionIndex])
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", parts[2][:subVersionIndex])
}
if hasLeadingZeroes(parts[2][:subVersionIndex]) {
return nil, fmt.Errorf("Patch number must not contain leading zeroes %q", parts[2][:subVersionIndex])
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", parts[2][:subVersionIndex])
}
patch, err := strconv.ParseUint(parts[2][:subVersionIndex], 10, 64)
if err != nil {
return nil, err
return Version{}, err
}
v := &Version{}
v := Version{}
v.Major = major
v.Minor = minor
v.Patch = patch
@ -254,7 +254,7 @@ func Parse(s string) (*Version, error) {
for _, prstr := range prparts {
parsedPR, err := NewPRVersion(prstr)
if err != nil {
return nil, err
return Version{}, err
}
v.Pre = append(v.Pre, parsedPR)
}
@ -266,10 +266,10 @@ func Parse(s string) (*Version, error) {
buildParts := strings.Split(buildStr, ".")
for _, str := range buildParts {
if len(str) == 0 {
return nil, errors.New("Build meta data is empty")
return Version{}, errors.New("Build meta data is empty")
}
if !containsOnly(str, alphanum) {
return nil, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
}
v.Build = append(v.Build, str)
}
@ -286,20 +286,20 @@ type PRVersion struct {
}
// Creates a new valid prerelease version
func NewPRVersion(s string) (*PRVersion, error) {
func NewPRVersion(s string) (PRVersion, error) {
if len(s) == 0 {
return nil, errors.New("Prerelease is empty")
return PRVersion{}, errors.New("Prerelease is empty")
}
v := &PRVersion{}
v := PRVersion{}
if containsOnly(s, numbers) {
if hasLeadingZeroes(s) {
return nil, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
}
num, err := strconv.ParseUint(s, 10, 64)
// Might never be hit, but just in case
if err != nil {
return nil, err
return PRVersion{}, err
}
v.VersionNum = num
v.IsNum = true
@ -307,7 +307,7 @@ func NewPRVersion(s string) (*PRVersion, error) {
v.VersionStr = s
v.IsNum = false
} else {
return nil, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
}
return v, nil
}
@ -321,7 +321,7 @@ func (v PRVersion) IsNumeric() bool {
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v PRVersion) Compare(o *PRVersion) int {
func (v PRVersion) Compare(o PRVersion) int {
if v.IsNum && !o.IsNum {
return -1
} else if !v.IsNum && o.IsNum {


+ 37
- 28
semver_test.go View File

@ -4,12 +4,12 @@ import (
"testing"
)
func prstr(s string) *PRVersion {
return &PRVersion{s, 0, false}
func prstr(s string) PRVersion {
return PRVersion{s, 0, false}
}
func prnum(i uint64) *PRVersion {
return &PRVersion{"", i, true}
func prnum(i uint64) PRVersion {
return PRVersion{"", i, true}
}
type formatTest struct {
@ -20,14 +20,14 @@ type formatTest struct {
var formatTests = []formatTest{
{Version{1, 2, 3, nil, nil}, "1.2.3"},
{Version{0, 0, 1, nil, nil}, "0.0.1"},
{Version{0, 0, 1, []*PRVersion{prstr("alpha"), prstr("preview")}, []string{"123", "456"}}, "0.0.1-alpha.preview+123.456"},
{Version{1, 2, 3, []*PRVersion{prstr("alpha"), prnum(1)}, []string{"123", "456"}}, "1.2.3-alpha.1+123.456"},
{Version{1, 2, 3, []*PRVersion{prstr("alpha"), prnum(1)}, nil}, "1.2.3-alpha.1"},
{Version{0, 0, 1, []PRVersion{prstr("alpha"), prstr("preview")}, []string{"123", "456"}}, "0.0.1-alpha.preview+123.456"},
{Version{1, 2, 3, []PRVersion{prstr("alpha"), prnum(1)}, []string{"123", "456"}}, "1.2.3-alpha.1+123.456"},
{Version{1, 2, 3, []PRVersion{prstr("alpha"), prnum(1)}, nil}, "1.2.3-alpha.1"},
{Version{1, 2, 3, nil, []string{"123", "456"}}, "1.2.3+123.456"},
// Prereleases and build metadata hyphens
{Version{1, 2, 3, []*PRVersion{prstr("alpha"), prstr("b-eta")}, []string{"123", "b-uild"}}, "1.2.3-alpha.b-eta+123.b-uild"},
{Version{1, 2, 3, []PRVersion{prstr("alpha"), prstr("b-eta")}, []string{"123", "b-uild"}}, "1.2.3-alpha.b-eta+123.b-uild"},
{Version{1, 2, 3, nil, []string{"123", "b-uild"}}, "1.2.3+123.b-uild"},
{Version{1, 2, 3, []*PRVersion{prstr("alpha"), prstr("b-eta")}, nil}, "1.2.3-alpha.b-eta"},
{Version{1, 2, 3, []PRVersion{prstr("alpha"), prstr("b-eta")}, nil}, "1.2.3-alpha.b-eta"},
}
func TestStringer(t *testing.T) {
@ -42,7 +42,7 @@ func TestParse(t *testing.T) {
for _, test := range formatTests {
if v, err := Parse(test.result); err != nil {
t.Errorf("Error parsing %q: %q", test.result, err)
} else if comp := v.Compare(&test.v); comp != 0 {
} else if comp := v.Compare(test.v); comp != 0 {
t.Errorf("Parsing, expected %q but got %q, comp: %d ", test.v, v, comp)
} else if err := v.Validate(); err != nil {
t.Errorf("Error validating parsed version %q: %q", test.v, err)
@ -82,14 +82,14 @@ var compareTests = []compareTest{
{Version{2, 1, 0, nil, nil}, Version{2, 1, 1, nil, nil}, -1},
// Spec Examples #9
{Version{1, 0, 0, nil, nil}, Version{1, 0, 0, []*PRVersion{prstr("alpha")}, nil}, 1},
{Version{1, 0, 0, []*PRVersion{prstr("alpha")}, nil}, Version{1, 0, 0, []*PRVersion{prstr("alpha"), prnum(1)}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("alpha"), prnum(1)}, nil}, Version{1, 0, 0, []*PRVersion{prstr("alpha"), prstr("beta")}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("alpha"), prstr("beta")}, nil}, Version{1, 0, 0, []*PRVersion{prstr("beta")}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("beta")}, nil}, Version{1, 0, 0, []*PRVersion{prstr("beta"), prnum(2)}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("beta"), prnum(2)}, nil}, Version{1, 0, 0, []*PRVersion{prstr("beta"), prnum(11)}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("beta"), prnum(11)}, nil}, Version{1, 0, 0, []*PRVersion{prstr("rc"), prnum(1)}, nil}, -1},
{Version{1, 0, 0, []*PRVersion{prstr("rc"), prnum(1)}, nil}, Version{1, 0, 0, nil, nil}, -1},
{Version{1, 0, 0, nil, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}, 1},
{Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha"), prnum(1)}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("alpha"), prnum(1)}, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha"), prstr("beta")}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("alpha"), prstr("beta")}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta")}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("beta")}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(2)}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(2)}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(11)}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(11)}, nil}, Version{1, 0, 0, []PRVersion{prstr("rc"), prnum(1)}, nil}, -1},
{Version{1, 0, 0, []PRVersion{prstr("rc"), prnum(1)}, nil}, Version{1, 0, 0, nil, nil}, -1},
// Ignore Build metadata
{Version{1, 0, 0, nil, []string{"1", "2", "3"}}, Version{1, 0, 0, nil, nil}, 0},
@ -97,11 +97,11 @@ var compareTests = []compareTest{
func TestCompare(t *testing.T) {
for _, test := range compareTests {
if res := test.v1.Compare(&test.v2); res != test.result {
if res := test.v1.Compare(test.v2); res != test.result {
t.Errorf("Comparing %q : %q, expected %d but got %d", test.v1, test.v2, test.result, res)
}
//Test counterpart
if res := test.v2.Compare(&test.v1); res != -test.result {
if res := test.v2.Compare(test.v1); res != -test.result {
t.Errorf("Comparing %q : %q, expected %d but got %d", test.v2, test.v1, -test.result, res)
}
}
@ -142,13 +142,13 @@ var wrongformatTests = []wrongformatTest{
{nil, "1.1.1-001"},
{nil, "1.1.1-beta.01"},
{nil, "1.1.1-beta.001"},
{&Version{0, 0, 0, []*PRVersion{prstr("!")}, nil}, "0.0.0-!"},
{&Version{0, 0, 0, []PRVersion{prstr("!")}, nil}, "0.0.0-!"},
{&Version{0, 0, 0, nil, []string{"!"}}, "0.0.0+!"},
// empty prversion
{&Version{0, 0, 0, []*PRVersion{prstr(""), prstr("alpha")}, nil}, "0.0.0-.alpha"},
{&Version{0, 0, 0, []PRVersion{prstr(""), prstr("alpha")}, nil}, "0.0.0-.alpha"},
// empty build meta data
{&Version{0, 0, 0, []*PRVersion{prstr("alpha")}, []string{""}}, "0.0.0-alpha+"},
{&Version{0, 0, 0, []*PRVersion{prstr("alpha")}, []string{"test", ""}}, "0.0.0-alpha+test."},
{&Version{0, 0, 0, []PRVersion{prstr("alpha")}, []string{""}}, "0.0.0-alpha+"},
{&Version{0, 0, 0, []PRVersion{prstr("alpha")}, []string{"test", ""}}, "0.0.0-alpha+test."},
}
func TestWrongFormat(t *testing.T) {
@ -167,8 +167,8 @@ func TestWrongFormat(t *testing.T) {
}
func TestCompareHelper(t *testing.T) {
v := &Version{1, 0, 0, []*PRVersion{prstr("alpha")}, nil}
v1 := &Version{1, 0, 0, nil, nil}
v := Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}
v1 := Version{1, 0, 0, nil, nil}
if !v.GTE(v) {
t.Errorf("%q should be greater than or equal to %q", v, v)
}
@ -239,13 +239,14 @@ func TestNewHelper(t *testing.T) {
if err != nil {
t.Fatalf("Unexpected error %q", err)
}
if v.Compare(&Version{1, 2, 3, nil, nil}) != 0 {
if v.Compare(Version{1, 2, 3, nil, nil}) != 0 {
t.Fatal("Unexpected comparison problem")
}
}
func BenchmarkParseSimple(b *testing.B) {
const VERSION = "0.0.1"
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
New(VERSION)
@ -254,6 +255,7 @@ func BenchmarkParseSimple(b *testing.B) {
func BenchmarkParseComplex(b *testing.B) {
const VERSION = "0.0.1-alpha.preview+123.456"
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
New(VERSION)
@ -262,6 +264,7 @@ func BenchmarkParseComplex(b *testing.B) {
func BenchmarkParseAverage(b *testing.B) {
l := len(formatTests)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
New(formatTests[n%l].result)
@ -271,6 +274,7 @@ func BenchmarkParseAverage(b *testing.B) {
func BenchmarkValidateSimple(b *testing.B) {
const VERSION = "0.0.1"
v, _ := New(VERSION)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
v.Validate()
@ -280,6 +284,7 @@ func BenchmarkValidateSimple(b *testing.B) {
func BenchmarkValidateComplex(b *testing.B) {
const VERSION = "0.0.1-alpha.preview+123.456"
v, _ := New(VERSION)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
v.Validate()
@ -288,6 +293,7 @@ func BenchmarkValidateComplex(b *testing.B) {
func BenchmarkValidateAverage(b *testing.B) {
l := len(formatTests)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
formatTests[n%l].v.Validate()
@ -297,6 +303,7 @@ func BenchmarkValidateAverage(b *testing.B) {
func BenchmarkCompareSimple(b *testing.B) {
const VERSION = "0.0.1"
v, _ := New(VERSION)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
v.Compare(v)
@ -306,6 +313,7 @@ func BenchmarkCompareSimple(b *testing.B) {
func BenchmarkCompareComplex(b *testing.B) {
const VERSION = "0.0.1-alpha.preview+123.456"
v, _ := New(VERSION)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
v.Compare(v)
@ -314,8 +322,9 @@ func BenchmarkCompareComplex(b *testing.B) {
func BenchmarkCompareAverage(b *testing.B) {
l := len(compareTests)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
compareTests[n%l].v1.Compare(&(compareTests[n%l].v2))
compareTests[n%l].v1.Compare((compareTests[n%l].v2))
}
}

+ 1
- 1
sql.go View File

@ -21,7 +21,7 @@ func (v *Version) Scan(src interface{}) (err error) {
if err != nil {
return
}
*v = *tmpv
*v = tmpv
return
}


Loading…
Cancel
Save