Skip to content

Commit

Permalink
Feature: Testing | Add boolean to enable mocking paginators for tests (
Browse files Browse the repository at this point in the history
…#9)

* * add boolean to pageIterator to define stop conditions for testing purposes
* add comment to explain new boolean behavior
* fix docker-compose formatting for testing

* * add stop on pagination capability test

* * update golangci lint version
  • Loading branch information
razt18 authored Jan 3, 2024
1 parent bc557b2 commit 4d21ac6
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.53.2
version: v1.55.1
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,16 @@ for paginator.HasMorePages() {
...
}
```
### Test Pagination Queries

```go
paginatorMock := goqux.NewPaginator(func(p *goqux.Paginator[T]) ([]T, bool, error) {
stopClause := true
var items []T{}
return items, stopClause, nil
})
EXPECT().ListItems().Return(paginatorMock, ...)
```

## Query building Helpers

Expand Down
21 changes: 14 additions & 7 deletions execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ type PaginationOptions struct {
KeySet []string
}

type PageIterator[T any] func(p *Paginator[T]) ([]T, error)
// PageIterator is a function that returns a page of results and a boolean indicating if there should be a next page or to stop iterating.
type PageIterator[T any] func(p *Paginator[T]) ([]T, bool, error)

// Paginator allows to paginate over result set of T
type Paginator[T any] struct {
hasNext bool
iterator PageIterator[T]
offset uint
values []any
stop bool
}

func NewPaginator[T any](iterator PageIterator[T]) *Paginator[T] {
Expand All @@ -33,15 +35,20 @@ func NewPaginator[T any](iterator PageIterator[T]) *Paginator[T] {
iterator: iterator,
offset: 0,
values: nil,
stop: false,
}
}

func (p *Paginator[T]) HasMorePages() bool {
return p.hasNext
return p.hasNext && !p.stop
}

func (p *Paginator[T]) NextPage() ([]T, error) {
return p.iterator(p)
data, shouldStop, err := p.iterator(p)
if shouldStop {
p.stop = true
}
return data, err
}

func Select[T any](ctx context.Context, querier pgxscan.Querier, tableName string, options ...SelectOption) ([]T, error) {
Expand Down Expand Up @@ -75,7 +82,7 @@ func SelectPagination[T any](ctx context.Context, querier pgxscan.Querier, table
}
}
originalOptions := options
return NewPaginator(func(p *Paginator[T]) ([]T, error) {
return NewPaginator(func(p *Paginator[T]) ([]T, bool, error) {
if paginationOptions.KeySet != nil {
//nolint:gocritic
options = append(originalOptions, WithKeySet(paginationOptions.KeySet, p.values))
Expand All @@ -85,11 +92,11 @@ func SelectPagination[T any](ctx context.Context, querier pgxscan.Querier, table
}
results, err := Select[T](ctx, querier, tableName, append(options, WithSelectLimit(paginationOptions.PageSize))...)
if err != nil {
return nil, fmt.Errorf("goqux: failed to select: %w", err)
return nil, false, fmt.Errorf("goqux: failed to select: %w", err)
}
if len(results) == 0 || len(results) < int(paginationOptions.PageSize) {
p.hasNext = false
return results, nil
return results, false, nil
}
if len(paginationOptions.KeySet) > 0 {
var values = make([]any, len(results))
Expand All @@ -101,7 +108,7 @@ func SelectPagination[T any](ctx context.Context, querier pgxscan.Querier, table
} else {
p.offset += paginationOptions.PageSize
}
return results, nil
return results, false, nil
}), nil
}

Expand Down
20 changes: 20 additions & 0 deletions execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,23 @@ func TestSelectPagination(t *testing.T) {
})
}
}

func TestStopOnPaginations(t *testing.T) {
ctx := context.Background()
conn, err := pgx.Connect(ctx, testPostgresURI)
require.Nil(t, err)
defer func() {
err := conn.Close(context.Background())
require.Nil(t, err)
}()
paginatorMock := goqux.NewPaginator(func(p *goqux.Paginator[User]) ([]User, bool, error) {
return []User{}, true, nil
})
countPages := 0
for paginatorMock.HasMorePages() {
_, err := paginatorMock.NextPage()
require.Nil(t, err)
countPages++
}
require.Equal(t, 1, countPages)
}
2 changes: 1 addition & 1 deletion testing/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ services:
- '5432:5432'
volumes:
- db:/var/lib/postgresql/data
-./init.sql:/docker-entrypoint-initdb.d/init.sql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
db:
driver: local

0 comments on commit 4d21ac6

Please sign in to comment.