package cache import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func Test_FirstContainsIndex(t *testing.T) { cases := []struct { title string arr []*Range pos int64 want int }{ { "空数组", []*Range{}, 100, -1, }, { "只有一个元素,pos在范围内", []*Range{{100, 100}}, 100, 0, }, { "区间不连续,但在范围内-奇数区间数", []*Range{{100, 100}, {300, 100}, {500, 100}}, 350, 1, }, { "区间不连续,但在范围内-偶数区间数", []*Range{{100, 100}, {300, 100}}, 350, 1, }, { "区间不连续,pos在最左边", []*Range{{100, 100}, {300, 100}, {500, 100}}, 10, -1, }, { "区间不连续,pos在靠左的第一个空洞中", []*Range{{100, 100}, {300, 100}, {500, 100}}, 200, 0, }, { "区间不连续,pos在靠左的第一个空洞中-偶数区间数", []*Range{{100, 100}, {300, 100}, {500, 100}, {700, 100}}, 200, 0, }, { "区间不连续,pos在最右边", []*Range{{100, 100}, {300, 100}, {500, 100}}, 601, 2, }, } for _, c := range cases { Convey(c.title, t, func() { got := FirstContainsIndex(c.arr, c.pos) So(got, ShouldEqual, c.want) }) } } func Test_AddRange(t *testing.T) { cases := []struct { title string arr []*Range r *Range want []*Range }{ { "空数组", []*Range{}, &Range{100, 100}, []*Range{{100, 100}}, }, { "单个区间,连接在左侧", []*Range{{100, 100}}, &Range{0, 100}, []*Range{{0, 200}}, }, { "单个区间,连接在右侧", []*Range{{100, 100}}, &Range{200, 100}, []*Range{{100, 200}}, }, { "单个区间,左边重叠了一部分", []*Range{{100, 100}}, &Range{50, 100}, []*Range{{50, 150}}, }, { "单个区间,右边重叠了一部分", []*Range{{100, 100}}, &Range{150, 100}, []*Range{{100, 150}}, }, { "单个区间,被新区间完全覆盖", []*Range{{100, 100}}, &Range{50, 150}, []*Range{{50, 150}}, }, { "单个区间,在左边但有空洞", []*Range{{100, 100}}, &Range{0, 50}, []*Range{{0, 50}, {100, 100}}, }, { "单个区间,在右边但有空洞", []*Range{{100, 100}}, &Range{250, 50}, []*Range{{100, 100}, {250, 50}}, }, { "恰好连接了两个区间", []*Range{{100, 100}, {300, 100}}, &Range{200, 100}, []*Range{{100, 300}}, }, { "连接了两个区间,但在左边有重叠", []*Range{{100, 100}, {300, 100}}, &Range{150, 150}, []*Range{{100, 300}}, }, { "连接了两个区间,但在右边有重叠", []*Range{{100, 100}, {300, 100}}, &Range{150, 200}, []*Range{{100, 300}}, }, { "覆盖了多个区间,但不是完全连接", []*Range{{100, 100}, {300, 100}, {500, 100}, {700, 100}}, &Range{150, 400}, []*Range{{100, 500}, {700, 100}}, }, { "完全覆盖所有区间", []*Range{{100, 100}, {300, 100}, {500, 100}, {700, 100}}, &Range{0, 900}, []*Range{{0, 900}}, }, } for _, c := range cases { Convey(c.title, t, func() { got := AddRange(c.arr, c.r) So(got, ShouldResemble, c.want) }) } } func Test_MergeRanges(t *testing.T) { cases := []struct { title string arr1 []*Range arr2 []*Range want []*Range }{ { "两个都是空数组", []*Range{}, []*Range{}, nil, }, { "其中一个是空数组", []*Range{{100, 100}}, []*Range{}, []*Range{{100, 100}}, }, { "两个都是单个区间,没有重叠", []*Range{{100, 100}}, []*Range{{300, 100}}, []*Range{{100, 100}, {300, 100}}, }, { "两个都是单个区间,恰好连接", []*Range{{100, 100}}, []*Range{{200, 100}}, []*Range{{100, 200}}, }, { "两个都是单个区间,有重叠", []*Range{{100, 100}}, []*Range{{150, 100}}, []*Range{{100, 150}}, }, { "多区间恰好连接", []*Range{{100, 100}, {300, 100}, {500, 100}}, []*Range{{200, 100}, {400, 100}}, []*Range{{100, 500}}, }, { "多区间各种情况", []*Range{{100, 100}, {300, 100}, {500, 100}, {700, 100}}, []*Range{{150, 100}, {260, 90}, {400, 100}, {550, 250}}, []*Range{{100, 150}, {260, 540}}, }, } for _, c := range cases { Convey(c.title, t, func() { got := MergeRanges(c.arr1, c.arr2) So(got, ShouldResemble, c.want) }) } } func Test_TruncateRange(t *testing.T) { cases := []struct { title string arr []*Range pos int64 want []*Range }{ { "空数组", []*Range{}, 100, []*Range{}, }, { "截断的长度比现有长", []*Range{{100, 100}}, 300, []*Range{{100, 100}}, }, { "截断的长度等于现有长", []*Range{{100, 100}}, 200, []*Range{{100, 100}}, }, { "截断的长度小于现有长", []*Range{{100, 100}, {300, 100}}, 150, []*Range{{100, 50}}, }, { "截断了所有", []*Range{{100, 100}, {300, 100}}, 0, []*Range{}, }, { "截断的位置在空洞内", []*Range{{100, 100}, {300, 100}}, 250, []*Range{{100, 100}}, }, } for _, c := range cases { Convey(c.title, t, func() { got := TruncateRange(c.arr, c.pos) So(got, ShouldResemble, c.want) }) } } func Test_DifferentRange(t *testing.T) { cases := []struct { title string rng *Range arr []*Range want *Range }{ { "空数组", &Range{100, 100}, []*Range{}, &Range{100, 100}, }, { "区间的右边被截断", &Range{50, 150}, []*Range{{100, 100}, {300, 100}}, &Range{50, 50}, }, { "区间的左边被截断", &Range{150, 150}, []*Range{{100, 100}, {300, 100}}, &Range{200, 100}, }, { "区间被彻底截断", &Range{100, 100}, []*Range{{100, 100}, {300, 100}}, &Range{200, 0}, }, { "区间被截断成多份1", &Range{0, 400}, []*Range{{100, 100}, {300, 100}}, &Range{0, 100}, }, { "区间被截断成多份2", &Range{100, 300}, []*Range{{100, 100}, {300, 100}}, &Range{200, 100}, }, } for _, c := range cases { Convey(c.title, t, func() { DifferentRange(c.rng, c.arr) So(c.rng, ShouldResemble, c.want) }) } }