diff --git a/interval.go b/interval.go index de686ab..a7a1f43 100644 --- a/interval.go +++ b/interval.go @@ -198,8 +198,12 @@ func (i Interval) Union(other Interval) *Interval { result := Interval{} - // Determine new minimum (take the smaller one) - if i.Min != "" && other.Min != "" { + // 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 { result.Min = i.Min @@ -211,16 +215,14 @@ func (i Interval) Union(other Interval) *Interval { result.Min = i.Min result.MinInclusive = i.MinInclusive || other.MinInclusive } - } else if i.Min == "" { - result.Min = other.Min - result.MinInclusive = other.MinInclusive - } else { - result.Min = i.Min - result.MinInclusive = i.MinInclusive } - // Determine new maximum (take the larger one) - if i.Max != "" && other.Max != "" { + // 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 { result.Max = i.Max @@ -232,12 +234,6 @@ func (i Interval) Union(other Interval) *Interval { result.Max = i.Max result.MaxInclusive = i.MaxInclusive || other.MaxInclusive } - } else if i.Max == "" { - result.Max = other.Max - result.MaxInclusive = other.MaxInclusive - } else { - result.Max = i.Max - result.MaxInclusive = i.MaxInclusive } return &result diff --git a/interval_test.go b/interval_test.go index 796dc7b..ebbc0c9 100644 --- a/interval_test.go +++ b/interval_test.go @@ -312,6 +312,33 @@ func TestIntervalUnion(t *testing.T) { return r.MinInclusive && r.MaxInclusive }, }, + { + "unbounded min with bounded", + LessThanInterval("2.0.0", true), + NewInterval("1.0.0", "3.0.0", true, true), + false, + func(r *Interval) bool { + return r.Min == "" && r.Max == "3.0.0" && r.MaxInclusive + }, + }, + { + "bounded with unbounded max", + NewInterval("1.0.0", "3.0.0", true, true), + GreaterThanInterval("2.0.0", true), + false, + func(r *Interval) bool { + return r.Min == "1.0.0" && r.MinInclusive && r.Max == "" + }, + }, + { + "unbounded min with unbounded max", + LessThanInterval("2.0.0", true), + GreaterThanInterval("1.0.0", true), + false, + func(r *Interval) bool { + return r.Min == "" && r.Max == "" + }, + }, } for _, tt := range tests {