Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func TestConformance_Containment(t *testing.T) {
}
}

//nolint:gocognit
func TestConformance_VersionComparison(t *testing.T) {
files := []string{
"nuget_version_cmp_test.json",
Expand Down Expand Up @@ -189,20 +190,19 @@ func TestConformance_VersionComparison(t *testing.T) {

t.Run("cmp_"+v1+"_"+v2, func(t *testing.T) {
cmp := CompareWithScheme(v1, v2, input.InputScheme)
// expected[0] should be less than expected[1]
// Use comparison to determine which version v1 matches (handles case normalization)
v1MatchesFirst := CompareWithScheme(v1, expected[0], input.InputScheme) == 0
if expected[0] == expected[1] || CompareWithScheme(expected[0], expected[1], input.InputScheme) == 0 {
versionsEqual := expected[0] == expected[1] || CompareWithScheme(expected[0], expected[1], input.InputScheme) == 0

switch {
case versionsEqual:
if cmp != 0 {
t.Errorf("CompareWithScheme(%q, %q, %q) = %d, want 0 (equal versions)", v1, v2, input.InputScheme, cmp)
}
} else if v1MatchesFirst {
// v1 matches the smaller version, so cmp(v1, v2) should be < 0
case v1MatchesFirst:
if cmp >= 0 {
t.Errorf("CompareWithScheme(%q, %q, %q) = %d, want < 0 (expected order: %v)", v1, v2, input.InputScheme, cmp, expected)
}
} else {
// v1 matches the larger version, so cmp(v1, v2) should be > 0
default:
if cmp <= 0 {
t.Errorf("CompareWithScheme(%q, %q, %q) = %d, want > 0 (expected order: %v)", v1, v2, input.InputScheme, cmp, expected)
}
Expand Down
44 changes: 24 additions & 20 deletions interval.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,43 +114,47 @@ func (i Interval) Intersect(other Interval) Interval {
result := Interval{}

// Determine new minimum
if i.Min != "" && other.Min != "" {
switch {
case i.Min != "" && other.Min != "":
cmp := CompareVersions(i.Min, other.Min)
if cmp > 0 {
switch {
case cmp > 0:
result.Min = i.Min
result.MinInclusive = i.MinInclusive
} else if cmp < 0 {
case cmp < 0:
result.Min = other.Min
result.MinInclusive = other.MinInclusive
} else {
default:
result.Min = i.Min
result.MinInclusive = i.MinInclusive && other.MinInclusive
}
} else if i.Min != "" {
case i.Min != "":
result.Min = i.Min
result.MinInclusive = i.MinInclusive
} else if other.Min != "" {
case other.Min != "":
result.Min = other.Min
result.MinInclusive = other.MinInclusive
}

// Determine new maximum
if i.Max != "" && other.Max != "" {
switch {
case i.Max != "" && other.Max != "":
cmp := CompareVersions(i.Max, other.Max)
if cmp < 0 {
switch {
case cmp < 0:
result.Max = i.Max
result.MaxInclusive = i.MaxInclusive
} else if cmp > 0 {
case cmp > 0:
result.Max = other.Max
result.MaxInclusive = other.MaxInclusive
} else {
default:
result.Max = i.Max
result.MaxInclusive = i.MaxInclusive && other.MaxInclusive
}
} else if i.Max != "" {
case i.Max != "":
result.Max = i.Max
result.MaxInclusive = i.MaxInclusive
} else if other.Max != "" {
case other.Max != "":
result.Max = other.Max
result.MaxInclusive = other.MaxInclusive
}
Expand Down Expand Up @@ -200,37 +204,37 @@ func (i Interval) Union(other Interval) *Interval {

// Determine new minimum (take the smaller one, "" means unbounded)
if i.Min == "" || other.Min == "" {
// Either side is unbounded below, so the union is too
result.Min = ""
result.MinInclusive = false
} else {
cmp := CompareVersions(i.Min, other.Min)
if cmp < 0 {
switch {
case cmp < 0:
result.Min = i.Min
result.MinInclusive = i.MinInclusive
} else if cmp > 0 {
case cmp > 0:
result.Min = other.Min
result.MinInclusive = other.MinInclusive
} else {
default:
result.Min = i.Min
result.MinInclusive = i.MinInclusive || other.MinInclusive
}
}

// Determine new maximum (take the larger one, "" means unbounded)
if i.Max == "" || other.Max == "" {
// Either side is unbounded above, so the union is too
result.Max = ""
result.MaxInclusive = false
} else {
cmp := CompareVersions(i.Max, other.Max)
if cmp > 0 {
switch {
case cmp > 0:
result.Max = i.Max
result.MaxInclusive = i.MaxInclusive
} else if cmp < 0 {
case cmp < 0:
result.Max = other.Max
result.MaxInclusive = other.MaxInclusive
} else {
default:
result.Max = i.Max
result.MaxInclusive = i.MaxInclusive || other.MaxInclusive
}
Expand Down
6 changes: 3 additions & 3 deletions interval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import "testing"

func TestNewInterval(t *testing.T) {
i := NewInterval("1.0.0", "2.0.0", true, false)
if i.Min != "1.0.0" {
if i.Min != "1.0.0" { //nolint:goconst
t.Errorf("Min = %q, want %q", i.Min, "1.0.0")
}
if i.Max != "2.0.0" {
if i.Max != "2.0.0" { //nolint:goconst
t.Errorf("Max = %q, want %q", i.Max, "2.0.0")
}
if !i.MinInclusive {
Expand Down Expand Up @@ -176,7 +176,7 @@ func TestIntervalIntersect(t *testing.T) {
NewInterval("1.0.0", "3.0.0", true, true),
NewInterval("2.0.0", "4.0.0", true, true),
func(r Interval) bool {
return r.Min == "2.0.0" && r.Max == "3.0.0" && r.MinInclusive && r.MaxInclusive
return r.Min == "2.0.0" && r.Max == "3.0.0" && r.MinInclusive && r.MaxInclusive //nolint:goconst
},
},
{
Expand Down
22 changes: 10 additions & 12 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (p *Parser) ParseNative(constraint string, scheme string) (*Range, error) {
return p.parsePypiRange(constraint)
case "maven":
return p.parseMavenRange(constraint)
case "nuget":
case "nuget": //nolint:goconst
return p.parseNugetRange(constraint)
case "cargo":
return p.parseCargoRange(constraint)
Expand Down Expand Up @@ -359,7 +359,7 @@ func (p *Parser) parseNpmSingleRange(s string) (*Range, error) {

// Hyphen range: 1.2.3 - 2.0.0
if strings.Contains(s, " - ") {
parts := strings.SplitN(s, " - ", 2)
parts := strings.SplitN(s, " - ", 2) //nolint:mnd
return NewRange([]Interval{
NewInterval(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), true, true),
}), nil
Expand Down Expand Up @@ -405,11 +405,12 @@ func (p *Parser) parseCaretRange(version string) (*Range, error) {
}

var upper string
if v.Major > 0 {
switch {
case v.Major > 0:
upper = fmt.Sprintf("%d.0.0", v.Major+1)
} else if v.Minor > 0 {
case v.Minor > 0:
upper = fmt.Sprintf("0.%d.0", v.Minor+1)
} else {
default:
upper = fmt.Sprintf("0.0.%d", v.Patch+1)
}

Expand Down Expand Up @@ -446,7 +447,7 @@ func (p *Parser) parseTildeRange(version string) (*Range, error) {
segments := strings.Count(version, ".") + 1

var upper string
if segments >= 2 {
if segments >= 2 { //nolint:mnd
// ~1.2.3 := >=1.2.3 <1.3.0
// ~1.0.0 := >=1.0.0 <1.1.0
// ~1.0 := >=1.0.0 <1.1.0
Expand Down Expand Up @@ -532,14 +533,11 @@ func (p *Parser) parsePessimisticRange(version string) (*Range, error) {
segments := strings.Count(version, ".") + 1

var upper string
if segments >= 3 {
if segments >= 3 { //nolint:mnd
// ~> 1.2.3 bumps minor: < 1.3
upper = fmt.Sprintf("%d.%d", v.Major, v.Minor+1)
} else if segments == 2 {
// ~> 1.2 bumps major: < 2.0
upper = fmt.Sprintf("%d.0", v.Major+1)
} else {
// ~> 1 bumps major: < 2.0
// ~> 1.2 or ~> 1 bumps major: < 2.0
upper = fmt.Sprintf("%d.0", v.Major+1)
}

Expand Down Expand Up @@ -593,7 +591,7 @@ func (p *Parser) parseBracketRange(s string) (*Range, error) {
maxInclusive := s[len(s)-1] == ']'

inner := s[1 : len(s)-1]
parts := strings.SplitN(inner, ",", 2)
parts := strings.SplitN(inner, ",", 2) //nolint:mnd

if len(parts) == 1 {
// Exact version: [1.0]
Expand Down
Loading