blob: 2027f14b8883c2106e74002f61787713d4b16d04 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.21
package quic
import (
"reflect"
"testing"
)
func TestRangeSize(t *testing.T) {
for _, test := range []struct {
r i64range[int64]
want int64
}{{
r: i64range[int64]{0, 100},
want: 100,
}, {
r: i64range[int64]{10, 20},
want: 10,
}} {
if got := test.r.size(); got != test.want {
t.Errorf("%+v.size = %v, want %v", test.r, got, test.want)
}
}
}
func TestRangeContains(t *testing.T) {
r := i64range[int64]{5, 10}
for _, i := range []int64{0, 4, 10, 15} {
if r.contains(i) {
t.Errorf("%v.contains(%v) = true, want false", r, i)
}
}
for _, i := range []int64{5, 6, 7, 8, 9} {
if !r.contains(i) {
t.Errorf("%v.contains(%v) = false, want true", r, i)
}
}
}
func TestRangesetAdd(t *testing.T) {
for _, test := range []struct {
desc string
set rangeset[int64]
add i64range[int64]
want rangeset[int64]
}{{
desc: "add to empty set",
set: rangeset[int64]{},
add: i64range[int64]{0, 100},
want: rangeset[int64]{{0, 100}},
}, {
desc: "add empty range",
set: rangeset[int64]{},
add: i64range[int64]{100, 100},
want: rangeset[int64]{},
}, {
desc: "append nonadjacent range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{300, 400},
want: rangeset[int64]{{100, 200}, {300, 400}},
}, {
desc: "prepend nonadjacent range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{0, 50},
want: rangeset[int64]{{0, 50}, {100, 200}},
}, {
desc: "insert nonadjacent range",
set: rangeset[int64]{{100, 200}, {500, 600}},
add: i64range[int64]{300, 400},
want: rangeset[int64]{{100, 200}, {300, 400}, {500, 600}},
}, {
desc: "prepend adjacent range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{50, 100},
want: rangeset[int64]{{50, 200}},
}, {
desc: "append adjacent range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{200, 250},
want: rangeset[int64]{{100, 250}},
}, {
desc: "prepend overlapping range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{50, 150},
want: rangeset[int64]{{50, 200}},
}, {
desc: "append overlapping range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{150, 250},
want: rangeset[int64]{{100, 250}},
}, {
desc: "replace range",
set: rangeset[int64]{{100, 200}},
add: i64range[int64]{50, 250},
want: rangeset[int64]{{50, 250}},
}, {
desc: "prepend and combine",
set: rangeset[int64]{{100, 200}, {300, 400}, {500, 600}},
add: i64range[int64]{50, 300},
want: rangeset[int64]{{50, 400}, {500, 600}},
}, {
desc: "combine several ranges",
set: rangeset[int64]{{100, 200}, {300, 400}, {500, 600}, {700, 800}, {900, 1000}},
add: i64range[int64]{300, 850},
want: rangeset[int64]{{100, 200}, {300, 850}, {900, 1000}},
}} {
test := test
t.Run(test.desc, func(t *testing.T) {
got := test.set
got.add(test.add.start, test.add.end)
if !reflect.DeepEqual(got, test.want) {
t.Errorf("add [%v,%v) to %v", test.add.start, test.add.end, test.set)
t.Errorf(" got: %v", got)
t.Errorf(" want: %v", test.want)
}
})
}
}
func TestRangesetSub(t *testing.T) {
for _, test := range []struct {
desc string
set rangeset[int64]
sub i64range[int64]
want rangeset[int64]
}{{
desc: "subtract from empty set",
set: rangeset[int64]{},
sub: i64range[int64]{0, 100},
want: rangeset[int64]{},
}, {
desc: "subtract empty range",
set: rangeset[int64]{{0, 100}},
sub: i64range[int64]{0, 0},
want: rangeset[int64]{{0, 100}},
}, {
desc: "subtract not present in set",
set: rangeset[int64]{{0, 100}, {200, 300}},
sub: i64range[int64]{100, 200},
want: rangeset[int64]{{0, 100}, {200, 300}},
}, {
desc: "subtract prefix",
set: rangeset[int64]{{100, 200}},
sub: i64range[int64]{0, 150},
want: rangeset[int64]{{150, 200}},
}, {
desc: "subtract suffix",
set: rangeset[int64]{{100, 200}},
sub: i64range[int64]{150, 300},
want: rangeset[int64]{{100, 150}},
}, {
desc: "subtract middle",
set: rangeset[int64]{{0, 100}},
sub: i64range[int64]{40, 60},
want: rangeset[int64]{{0, 40}, {60, 100}},
}, {
desc: "subtract from two ranges",
set: rangeset[int64]{{0, 100}, {200, 300}},
sub: i64range[int64]{50, 250},
want: rangeset[int64]{{0, 50}, {250, 300}},
}, {
desc: "subtract removes range",
set: rangeset[int64]{{0, 100}, {200, 300}, {400, 500}},
sub: i64range[int64]{200, 300},
want: rangeset[int64]{{0, 100}, {400, 500}},
}, {
desc: "subtract removes multiple ranges",
set: rangeset[int64]{{0, 100}, {200, 300}, {400, 500}, {600, 700}},
sub: i64range[int64]{50, 650},
want: rangeset[int64]{{0, 50}, {650, 700}},
}, {
desc: "subtract only range",
set: rangeset[int64]{{0, 100}},
sub: i64range[int64]{0, 100},
want: rangeset[int64]{},
}} {
test := test
t.Run(test.desc, func(t *testing.T) {
got := test.set
got.sub(test.sub.start, test.sub.end)
if !reflect.DeepEqual(got, test.want) {
t.Errorf("sub [%v,%v) from %v", test.sub.start, test.sub.end, test.set)
t.Errorf(" got: %v", got)
t.Errorf(" want: %v", test.want)
}
})
}
}
func TestRangesetContains(t *testing.T) {
var s rangeset[int64]
s.add(10, 20)
s.add(30, 40)
for i := int64(0); i < 50; i++ {
want := (i >= 10 && i < 20) || (i >= 30 && i < 40)
if got := s.contains(i); got != want {
t.Errorf("%v.contains(%v) = %v, want %v", s, i, got, want)
}
}
}
func TestRangesetRangeContaining(t *testing.T) {
var s rangeset[int64]
s.add(10, 20)
s.add(30, 40)
for _, test := range []struct {
v int64
want i64range[int64]
}{
{0, i64range[int64]{0, 0}},
{9, i64range[int64]{0, 0}},
{10, i64range[int64]{10, 20}},
{15, i64range[int64]{10, 20}},
{19, i64range[int64]{10, 20}},
{20, i64range[int64]{0, 0}},
{29, i64range[int64]{0, 0}},
{30, i64range[int64]{30, 40}},
{39, i64range[int64]{30, 40}},
{40, i64range[int64]{0, 0}},
} {
got := s.rangeContaining(test.v)
if got != test.want {
t.Errorf("%v.rangeContaining(%v) = %v, want %v", s, test.v, got, test.want)
}
}
}
func TestRangesetLimits(t *testing.T) {
for _, test := range []struct {
s rangeset[int64]
wantMin int64
wantMax int64
wantEnd int64
}{{
s: rangeset[int64]{},
wantMin: 0,
wantMax: 0,
wantEnd: 0,
}, {
s: rangeset[int64]{{10, 20}},
wantMin: 10,
wantMax: 19,
wantEnd: 20,
}, {
s: rangeset[int64]{{10, 20}, {30, 40}, {50, 60}},
wantMin: 10,
wantMax: 59,
wantEnd: 60,
}} {
if got, want := test.s.min(), test.wantMin; got != want {
t.Errorf("%+v.min() = %v, want %v", test.s, got, want)
}
if got, want := test.s.max(), test.wantMax; got != want {
t.Errorf("%+v.max() = %v, want %v", test.s, got, want)
}
if got, want := test.s.end(), test.wantEnd; got != want {
t.Errorf("%+v.end() = %v, want %v", test.s, got, want)
}
}
}
func TestRangesetIsRange(t *testing.T) {
for _, test := range []struct {
s rangeset[int64]
r i64range[int64]
want bool
}{{
s: rangeset[int64]{{0, 100}},
r: i64range[int64]{0, 100},
want: true,
}, {
s: rangeset[int64]{{0, 100}},
r: i64range[int64]{0, 101},
want: false,
}, {
s: rangeset[int64]{{0, 10}, {11, 100}},
r: i64range[int64]{0, 100},
want: false,
}, {
s: rangeset[int64]{},
r: i64range[int64]{0, 0},
want: true,
}, {
s: rangeset[int64]{},
r: i64range[int64]{0, 1},
want: false,
}} {
if got := test.s.isrange(test.r.start, test.r.end); got != test.want {
t.Errorf("%+v.isrange(%v, %v) = %v, want %v", test.s, test.r.start, test.r.end, got, test.want)
}
}
}
func TestRangesetNumRanges(t *testing.T) {
for _, test := range []struct {
s rangeset[int64]
want int
}{{
s: rangeset[int64]{},
want: 0,
}, {
s: rangeset[int64]{{0, 100}},
want: 1,
}, {
s: rangeset[int64]{{0, 100}, {200, 300}},
want: 2,
}} {
if got, want := test.s.numRanges(), test.want; got != want {
t.Errorf("%+v.numRanges() = %v, want %v", test.s, got, want)
}
}
}