|
@@ -0,0 +1,158 @@
|
|
|
+package depager
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "testing"
|
|
|
+)
|
|
|
+
|
|
|
+type NoopClient[T any] struct {
|
|
|
+ err error
|
|
|
+ pages []*Aggr[T]
|
|
|
+ m int
|
|
|
+ cnt uint64
|
|
|
+}
|
|
|
+
|
|
|
+func (c *NoopClient[T]) NextPage(
|
|
|
+ page Page[T],
|
|
|
+ _offset uint64,
|
|
|
+) (cnt uint64, err error) {
|
|
|
+ if len(c.pages) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if c.m >= len(c.pages) {
|
|
|
+ err = fmt.Errorf("client: next page: exceeded max pages")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ src := *c.pages[c.m]
|
|
|
+ dst := *page.(*Aggr[T])
|
|
|
+ dst = dst[:min(cap(dst), len(src))]
|
|
|
+ copy(dst, src) // update values
|
|
|
+ *page.(*Aggr[T]) = dst // update slice
|
|
|
+
|
|
|
+ cnt = c.cnt
|
|
|
+ err = c.err
|
|
|
+ c.m++
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func NewNoopClient[T any](
|
|
|
+ cnt int,
|
|
|
+ err error,
|
|
|
+ pages []*Aggr[T],
|
|
|
+) Client[T] {
|
|
|
+ return &NoopClient[T]{
|
|
|
+ cnt: uint64(cnt),
|
|
|
+ err: err,
|
|
|
+ pages: pages,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+type Aggr[T any] []T
|
|
|
+
|
|
|
+func (a *Aggr[T]) Elems() []T {
|
|
|
+ return []T(*a)
|
|
|
+}
|
|
|
+
|
|
|
+func (a *Aggr[T]) URI() string {
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+func TestUsingNoopClient(t *testing.T) {
|
|
|
+ client := NewNoopClient[any](1, nil, []*Aggr[any]{{}})
|
|
|
+ pagePool := make(chan Page[any], 1)
|
|
|
+ for i := 0; i < cap(pagePool); i++ {
|
|
|
+ tmp := Aggr[any](make([]any, 0, 1))
|
|
|
+ pagePool <- &tmp
|
|
|
+ }
|
|
|
+ pager := NewPager(client, pagePool)
|
|
|
+ for range pager.Iter() {
|
|
|
+ }
|
|
|
+ if err := pager.LastErr(); err != nil {
|
|
|
+ t.Errorf("unexpected error in pager with noop client: %v", err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestNoopClientReturnsError(t *testing.T) {
|
|
|
+ client := NewNoopClient[any](0, fmt.Errorf("whomp"),
|
|
|
+ []*Aggr[any]{{}},
|
|
|
+ )
|
|
|
+ pagePool := make(chan Page[any], 1)
|
|
|
+ for i := 0; i < cap(pagePool); i++ {
|
|
|
+ tmp := Aggr[any](make([]any, 0))
|
|
|
+ pagePool <- &tmp
|
|
|
+ }
|
|
|
+ pager := NewPager(client, pagePool)
|
|
|
+ for range pager.Iter() {
|
|
|
+ }
|
|
|
+ if err := pager.LastErr(); err == nil {
|
|
|
+ t.Errorf("unexpected success: %v", err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestClientReturnsNonemptyPage(t *testing.T) {
|
|
|
+ itemCount := 3
|
|
|
+ client := NewNoopClient[any](itemCount, nil,
|
|
|
+ []*Aggr[any]{{1, 2}, {3}},
|
|
|
+ )
|
|
|
+ pagePool := make(chan Page[any], 1)
|
|
|
+ for i := 0; i < cap(pagePool); i++ {
|
|
|
+ tmp := Aggr[any](make([]any, 0, 2))
|
|
|
+ pagePool <- &tmp
|
|
|
+ }
|
|
|
+ pager := NewPager(client, pagePool)
|
|
|
+ var elem int
|
|
|
+ for e := range pager.Iter() {
|
|
|
+ elem = e.(int)
|
|
|
+ }
|
|
|
+ if err := pager.LastErr(); err != nil {
|
|
|
+ t.Errorf("unexpected error in pager: %v", err)
|
|
|
+ }
|
|
|
+ if elem != 3 {
|
|
|
+ t.Errorf("unexpected value: '%v'", elem)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestClientReturnsNonemptyPage2(t *testing.T) {
|
|
|
+ itemCount := 3
|
|
|
+ client := NewNoopClient[any](itemCount, nil,
|
|
|
+ []*Aggr[any]{{1, 2}, {3}},
|
|
|
+ )
|
|
|
+ pagePool := make(chan Page[any], 1)
|
|
|
+ for i := 0; i < cap(pagePool); i++ {
|
|
|
+ tmp := Aggr[any](make([]any, 0, 2))
|
|
|
+ pagePool <- &tmp
|
|
|
+ }
|
|
|
+ pager := NewPager(client, pagePool)
|
|
|
+ var elem int
|
|
|
+ var i int
|
|
|
+ for p := range pager.IterPages() {
|
|
|
+ elem = p.Elems()[0].(int)
|
|
|
+ i++
|
|
|
+ pagePool <- p
|
|
|
+ }
|
|
|
+ if err := pager.LastErr(); err != nil {
|
|
|
+ t.Errorf("unexpected error in pager: %v", err)
|
|
|
+ }
|
|
|
+ if elem != 3 {
|
|
|
+ t.Errorf("unexpected value: '%v'", elem)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestClientReturnsFewerPagesThanExpected(t *testing.T) {
|
|
|
+ pageSize := 1
|
|
|
+ itemCount := pageSize + 1
|
|
|
+ client := NewNoopClient[any](itemCount, nil,
|
|
|
+ []*Aggr[any]{{0}},
|
|
|
+ )
|
|
|
+ pagePool := make(chan Page[any], 1)
|
|
|
+ for i := 0; i < cap(pagePool); i++ {
|
|
|
+ tmp := Aggr[any](make([]any, 0, 1))
|
|
|
+ pagePool <- &tmp
|
|
|
+ }
|
|
|
+ pager := NewPager(client, pagePool)
|
|
|
+ for range pager.Iter() {
|
|
|
+ }
|
|
|
+ if err := pager.LastErr(); err == nil {
|
|
|
+ t.Errorf("unexpected success in pager: %v", err)
|
|
|
+ }
|
|
|
+}
|