func TestIterator(t *testing.T) { t.Parallel() s := newMemStore() c := s.SetCollection("zup", nil) prev := []byte{} for i := 5; i < 100; i++ { data := mkNum(int64(i)) c.Set(data, prev) prev = data } get := func(c C, t *iterator) interface{} { ret := interface{}(nil) t.next(nil, func(i *gkvlite.Item) { if i != nil { ret = readNum(i.Key) } }) return ret } skipGet := func(c C, t *iterator, skipTo int64) interface{} { ret := interface{}(nil) t.next(mkNum(skipTo), func(i *gkvlite.Item) { if i != nil { ret = readNum(i.Key) } }) return ret } Convey("Test iterator", t, func() { Convey("start at nil", func(ctx C) { t := (&iterDefinition{c: c}).mkIter() defer t.stop() So(get(ctx, t), ShouldEqual, 5) So(get(ctx, t), ShouldEqual, 6) So(get(ctx, t), ShouldEqual, 7) Convey("And can skip", func(ctx C) { So(skipGet(ctx, t, 10), ShouldEqual, 10) So(get(ctx, t), ShouldEqual, 11) Convey("But not forever", func(ctx C) { t.next(mkNum(200), func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) t.next(nil, func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) }) }) Convey("Can iterate explicitly", func(ctx C) { So(skipGet(ctx, t, 7), ShouldEqual, 8) So(skipGet(ctx, t, 8), ShouldEqual, 9) // Giving the immediately next key doesn't cause an internal reset. So(skipGet(ctx, t, 10), ShouldEqual, 10) }) Convey("Can stop", func(ctx C) { t.stop() t.next(mkNum(200), func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) t.next(nil, func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) So(t.stop, ShouldNotPanic) }) Convey("Going backwards is ignored", func(ctx C) { So(skipGet(ctx, t, 3), ShouldEqual, 8) So(get(ctx, t), ShouldEqual, 9) So(skipGet(ctx, t, 20), ShouldEqual, 20) So(get(ctx, t), ShouldEqual, 21) }) Convey("will stop at the end of the list", func(ctx C) { So(skipGet(ctx, t, 95), ShouldEqual, 95) So(get(ctx, t), ShouldEqual, 96) So(get(ctx, t), ShouldEqual, 97) So(get(ctx, t), ShouldEqual, 98) So(get(ctx, t), ShouldEqual, 99) So(get(ctx, t), ShouldBeNil) So(get(ctx, t), ShouldBeNil) }) }) Convey("can have caps on both sides", func(ctx C) { t := (&iterDefinition{c: c, start: mkNum(20), end: mkNum(25)}).mkIter() So(get(ctx, t), ShouldEqual, 20) So(get(ctx, t), ShouldEqual, 21) So(get(ctx, t), ShouldEqual, 22) So(get(ctx, t), ShouldEqual, 23) So(get(ctx, t), ShouldEqual, 24) t.next(nil, func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) }) Convey("can skip over starting cap", func(ctx C) { t := (&iterDefinition{c: c, start: mkNum(20), end: mkNum(25)}).mkIter() So(skipGet(ctx, t, 22), ShouldEqual, 22) So(get(ctx, t), ShouldEqual, 23) So(get(ctx, t), ShouldEqual, 24) t.next(nil, func(i *gkvlite.Item) { ctx.So(i, ShouldBeNil) }) }) }) }