add pagination engine to render
This commit is contained in:
parent
aa16e20958
commit
c777ef7056
@ -8,6 +8,7 @@ todo te será familiar.
|
||||
|
||||
- Sin dependencias
|
||||
- Procesamiento y salida de ficheros HTML
|
||||
- Paginación lista para usar
|
||||
- Vinculación entrada formulario y JSON a tipos estructurados.
|
||||
|
||||
## Motivación
|
||||
|
||||
@ -6,17 +6,73 @@ import (
|
||||
"ron"
|
||||
)
|
||||
|
||||
type SomethingElements struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
var elements = []SomethingElements{
|
||||
{"element 1", "description 1"},
|
||||
{"element 2", "description 2"},
|
||||
{"element 3", "description 3"},
|
||||
{"element 4", "description 4"},
|
||||
{"element 5", "description 5"},
|
||||
{"element 6", "description 6"},
|
||||
{"element 7", "description 7"},
|
||||
{"element 8", "description 8"},
|
||||
{"element 9", "description 9"},
|
||||
{"element 10", "description 10"},
|
||||
{"element 11", "description 11"},
|
||||
{"element 12", "description 12"},
|
||||
{"element 13", "description 13"},
|
||||
{"element 14", "description 14"},
|
||||
{"element 15", "description 15"},
|
||||
{"element 16", "description 16"},
|
||||
{"element 17", "description 17"},
|
||||
{"element 18", "description 18"},
|
||||
{"element 19", "description 19"},
|
||||
{"element 20", "description 20"},
|
||||
{"element 21", "description 21"},
|
||||
{"element 22", "description 22"},
|
||||
{"element 23", "description 23"},
|
||||
{"element 24", "description 24"},
|
||||
{"element 25", "description 25"},
|
||||
{"element 26", "description 26"},
|
||||
{"element 27", "description 27"},
|
||||
{"element 28", "description 28"},
|
||||
{"element 29", "description 29"},
|
||||
{"element 30", "description 30"},
|
||||
{"element 31", "description 31"},
|
||||
{"element 32", "description 32"},
|
||||
{"element 33", "description 33"},
|
||||
{"element 34", "description 34"},
|
||||
{"element 35", "description 35"},
|
||||
{"element 36", "description 36"},
|
||||
{"element 37", "description 37"},
|
||||
{"element 38", "description 38"},
|
||||
{"element 39", "description 39"},
|
||||
{"element 40", "description 40"},
|
||||
{"element 41", "description 41"},
|
||||
{"element 42", "description 42"},
|
||||
{"element 43", "description 43"},
|
||||
{"element 44", "description 44"},
|
||||
{"element 45", "description 45"},
|
||||
{"element 46", "description 46"},
|
||||
{"element 47", "description 47"},
|
||||
{"element 48", "description 48"},
|
||||
{"element 49", "description 49"},
|
||||
}
|
||||
|
||||
func main() {
|
||||
r := ron.New(func(e *ron.Engine) {
|
||||
e.LogLevel = slog.LevelDebug
|
||||
})
|
||||
|
||||
htmlRender := ron.NewHTMLRender()
|
||||
r.Renderer = htmlRender
|
||||
r.Render = htmlRender
|
||||
|
||||
r.Static("static", "static")
|
||||
|
||||
//r.GET("/", helloWorld)
|
||||
r.GET("/json", helloWorldJSON)
|
||||
r.POST("/another", anotherHelloWorld)
|
||||
r.GET("/html", helloWorldHTML)
|
||||
@ -39,12 +95,23 @@ func helloWorldJSON(c *ron.Context) {
|
||||
}
|
||||
|
||||
func helloWorldHTML(c *ron.Context) {
|
||||
c.HTML(200, "page.index.gohtml", ron.Data{
|
||||
"title": "hello world",
|
||||
"message": "hello world from html",
|
||||
})
|
||||
|
||||
pages := ron.Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 5,
|
||||
}
|
||||
|
||||
pages.PaginationParams(c.R)
|
||||
elementsPaginated := pages.PaginateArray(elements)
|
||||
|
||||
td := &ron.TemplateData{
|
||||
Data: ron.Data{"title": "hello world", "message": "hello world from html", "elements": elementsPaginated},
|
||||
Pages: pages,
|
||||
}
|
||||
|
||||
c.HTML(200, "page.index.gohtml", td)
|
||||
}
|
||||
|
||||
func componentHTML(c *ron.Context) {
|
||||
c.HTML(200, "component.list.gohtml", ron.Data{})
|
||||
c.HTML(200, "component.list.gohtml", nil)
|
||||
}
|
||||
|
||||
@ -12,6 +12,40 @@
|
||||
|
||||
{{ .Data.message }}
|
||||
|
||||
{{ range .Data.elements }}
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
{{ .Name }}
|
||||
{{ .Description }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ if not .Pages.HasPrevious }}
|
||||
primera página
|
||||
{{ else }}
|
||||
<a href="html?page={{ .Pages.First }}">primera</a>
|
||||
<a href="html?page={{ .Pages.Previous }}">anterior</a>
|
||||
{{ end }}
|
||||
|
||||
{{ range .Pages.PageRange 5 }}
|
||||
{{ if .Active }}
|
||||
<strong>{{ .Number }}</strong>
|
||||
{{ else }}
|
||||
<a href="html?page={{ .Number }}">{{ .Number }}</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if not .Pages.HasNext }}
|
||||
última página
|
||||
{{ else }}
|
||||
<a href="html?page={{ .Pages.Next }}">siguiente</a>
|
||||
<a href="html?page={{ .Pages.Last }}">última</a>
|
||||
{{ end }}
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
8
ron.go
8
ron.go
@ -27,7 +27,7 @@ type (
|
||||
Engine struct {
|
||||
mux *http.ServeMux
|
||||
LogLevel slog.Level
|
||||
Renderer *Render
|
||||
Render *Render
|
||||
}
|
||||
)
|
||||
|
||||
@ -120,12 +120,10 @@ func (c *Context) JSON(code int, data any) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) HTML(code int, name string, data Data) {
|
||||
func (c *Context) HTML(code int, name string, td *TemplateData) {
|
||||
c.W.WriteHeader(code)
|
||||
c.W.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
err := c.E.Renderer.Template(c.W, name, &TemplateData{
|
||||
Data: data,
|
||||
})
|
||||
err := c.E.Render.Template(c.W, name, td)
|
||||
if err != nil {
|
||||
http.Error(c.W, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
12
ron_test.go
12
ron_test.go
@ -19,17 +19,17 @@ func Test_New(t *testing.T) {
|
||||
if e == nil {
|
||||
t.Error("Expected Engine, Actual: nil")
|
||||
}
|
||||
if e.Renderer != nil {
|
||||
if e.Render != nil {
|
||||
t.Error("No expected Renderer, Actual: Renderer")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_applyEngineConfig(t *testing.T) {
|
||||
e := New(func(e *Engine) {
|
||||
e.Renderer = NewHTMLRender()
|
||||
e.Render = NewHTMLRender()
|
||||
e.LogLevel = 1
|
||||
})
|
||||
if e.Renderer == nil {
|
||||
if e.Render == nil {
|
||||
t.Error("Expected Renderer, Actual: nil")
|
||||
}
|
||||
if e.LogLevel != 1 {
|
||||
@ -151,15 +151,17 @@ func Test_HTML(t *testing.T) {
|
||||
c := &Context{
|
||||
W: rr,
|
||||
E: &Engine{
|
||||
Renderer: NewHTMLRender(),
|
||||
Render: NewHTMLRender(),
|
||||
},
|
||||
}
|
||||
|
||||
expected := `<h1>foo</h1><h2>bar</h2>`
|
||||
|
||||
c.HTML(http.StatusOK, "page.index.gohtml", Data{
|
||||
c.HTML(http.StatusOK, "page.index.gohtml", &TemplateData{
|
||||
Data: Data{
|
||||
"heading1": "foo",
|
||||
"heading2": "bar",
|
||||
},
|
||||
})
|
||||
|
||||
if status := rr.Code; status != http.StatusOK {
|
||||
|
||||
179
template.go
179
template.go
@ -7,6 +7,8 @@ import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -15,6 +17,7 @@ type (
|
||||
|
||||
TemplateData struct {
|
||||
Data Data
|
||||
Pages Pages
|
||||
}
|
||||
|
||||
RenderOptions func(*Render)
|
||||
@ -22,6 +25,7 @@ type (
|
||||
EnableCache bool
|
||||
TemplatesPath string
|
||||
Functions template.FuncMap
|
||||
TemplateData TemplateData
|
||||
templateCache templateCache
|
||||
}
|
||||
)
|
||||
@ -30,8 +34,9 @@ func defaultHTMLRender() *Render {
|
||||
return &Render{
|
||||
EnableCache: false,
|
||||
TemplatesPath: "templates",
|
||||
Functions: make(template.FuncMap),
|
||||
templateCache: make(templateCache),
|
||||
TemplateData: TemplateData{},
|
||||
Functions: template.FuncMap{},
|
||||
templateCache: templateCache{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,3 +144,173 @@ func (re *Render) createTemplateCache() (templateCache, error) {
|
||||
|
||||
return cache, nil
|
||||
}
|
||||
|
||||
// Pages contiene la información de paginación.
|
||||
type Pages struct {
|
||||
// TotalElements son la cantidad de elementos totales a paginar. Pueden ser
|
||||
// total de filas o total de páginas de blog.
|
||||
TotalElements int
|
||||
// ElementsPerPage muestra la cantidad máxima de elementos a mostrar en una
|
||||
// página.
|
||||
ElementsPerPage int
|
||||
// ActualPage es la página actual, utilizado como ayuda para mostrar la
|
||||
// página activa.
|
||||
ActualPage int
|
||||
}
|
||||
|
||||
func (p *Pages) PaginationParams(r *http.Request) {
|
||||
limit := r.FormValue("limit")
|
||||
page := r.FormValue("page")
|
||||
|
||||
if limit == "" {
|
||||
if p.ElementsPerPage != 0 {
|
||||
limit = strconv.Itoa(p.ElementsPerPage)
|
||||
} else {
|
||||
limit = "20"
|
||||
}
|
||||
}
|
||||
|
||||
if page == "" || page == "0" {
|
||||
if p.ActualPage != 0 {
|
||||
page = strconv.Itoa(p.ActualPage)
|
||||
} else {
|
||||
page = "1"
|
||||
}
|
||||
}
|
||||
|
||||
limitInt, _ := strconv.Atoi(limit)
|
||||
pageInt, _ := strconv.Atoi(page)
|
||||
offset := (pageInt - 1) * limitInt
|
||||
currentPage := offset/limitInt + 1
|
||||
|
||||
p.ElementsPerPage = limitInt
|
||||
p.ActualPage = currentPage
|
||||
}
|
||||
|
||||
func (p Pages) PaginateArray(elements any) any {
|
||||
itemsValue := reflect.ValueOf(elements)
|
||||
|
||||
if p.ActualPage < 1 {
|
||||
p.ActualPage = 1
|
||||
}
|
||||
|
||||
if p.ActualPage > p.TotalPages() {
|
||||
p.ActualPage = p.TotalPages()
|
||||
}
|
||||
|
||||
startIndex := (p.ActualPage - 1) * p.ElementsPerPage
|
||||
endIndex := startIndex + p.ElementsPerPage
|
||||
|
||||
return itemsValue.Slice(startIndex, endIndex).Interface()
|
||||
}
|
||||
|
||||
func (p Pages) CurrentPage() int {
|
||||
return p.ActualPage
|
||||
}
|
||||
|
||||
// TotalPages devuelve la cantidad total de páginas.
|
||||
func (p Pages) TotalPages() int {
|
||||
return (p.TotalElements + p.ElementsPerPage - 1) / p.ElementsPerPage
|
||||
}
|
||||
|
||||
// IsFirst indica si la página actual es la primera.
|
||||
func (p Pages) IsFirst() bool {
|
||||
return p.ActualPage == 1
|
||||
}
|
||||
|
||||
// IsLast indica si la página actual es la última.
|
||||
func (p Pages) IsLast() bool {
|
||||
return p.ActualPage == p.TotalPages()
|
||||
}
|
||||
|
||||
// HasPrevious indica si hay una página anterior.
|
||||
func (p Pages) HasPrevious() bool {
|
||||
return p.ActualPage > 1
|
||||
}
|
||||
|
||||
// HasNext indica si hay una página siguiente.
|
||||
func (p Pages) HasNext() bool {
|
||||
return p.ActualPage < p.TotalPages()
|
||||
}
|
||||
|
||||
// Previous devuelve el número de la página anterior.
|
||||
func (p Pages) Previous() int {
|
||||
if p.ActualPage > p.TotalPages() {
|
||||
return p.TotalPages()
|
||||
}
|
||||
return p.ActualPage - 1
|
||||
}
|
||||
|
||||
// Next devuelve el número de la página siguiente.
|
||||
func (p Pages) Next() int {
|
||||
if p.ActualPage < 1 {
|
||||
return 1
|
||||
}
|
||||
return p.ActualPage + 1
|
||||
}
|
||||
|
||||
func (p Pages) GoToPage(page int) int {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
} else if page > p.TotalPages() {
|
||||
page = p.TotalPages()
|
||||
}
|
||||
return page
|
||||
}
|
||||
|
||||
func (p Pages) First() int {
|
||||
return p.GoToPage(1)
|
||||
}
|
||||
|
||||
func (p Pages) Last() int {
|
||||
return p.GoToPage(p.TotalPages())
|
||||
}
|
||||
|
||||
// Page contiene la información de una página. Utilizado para la barra de
|
||||
// paginación que suelen mostrarse en la parte inferior de una lista o tabla.
|
||||
type Page struct {
|
||||
// Number es el número de página.
|
||||
Number int
|
||||
// Active es un dato lógico que indica si la página es la actual.
|
||||
Active bool
|
||||
}
|
||||
|
||||
func (p Page) NumberOfPage() int {
|
||||
return p.Number
|
||||
}
|
||||
|
||||
// IsActive indica si la página es la actual.
|
||||
func (p Page) IsActive() bool {
|
||||
return p.Active
|
||||
}
|
||||
|
||||
// PagesRange muestra un rango de páginas a mostrar en la paginación.
|
||||
func (p Pages) PageRange(maxPagesToShow int) []Page {
|
||||
var pages []Page
|
||||
totalPages := p.TotalPages()
|
||||
|
||||
startPage := p.ActualPage - (maxPagesToShow / 2)
|
||||
endPage := p.ActualPage + (maxPagesToShow / 2)
|
||||
|
||||
if startPage < 1 {
|
||||
startPage = 1
|
||||
endPage = maxPagesToShow
|
||||
}
|
||||
|
||||
if endPage > totalPages {
|
||||
endPage = totalPages
|
||||
startPage = totalPages - maxPagesToShow + 1
|
||||
if startPage < 1 {
|
||||
startPage = 1
|
||||
}
|
||||
}
|
||||
|
||||
for i := startPage; i <= endPage; i++ {
|
||||
pages = append(pages, Page{
|
||||
Number: i,
|
||||
Active: i == p.ActualPage,
|
||||
})
|
||||
}
|
||||
|
||||
return pages
|
||||
}
|
||||
|
||||
218
template_test.go
218
template_test.go
@ -2,6 +2,7 @@ package ron
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"reflect"
|
||||
@ -13,8 +14,9 @@ func Test_DefaultHTMLRender(t *testing.T) {
|
||||
expected := &Render{
|
||||
EnableCache: false,
|
||||
TemplatesPath: "templates",
|
||||
Functions: make(template.FuncMap),
|
||||
templateCache: make(templateCache),
|
||||
TemplateData: TemplateData{},
|
||||
Functions: template.FuncMap{},
|
||||
templateCache: templateCache{},
|
||||
}
|
||||
|
||||
actual := defaultHTMLRender()
|
||||
@ -27,8 +29,9 @@ func Test_HTMLRender(t *testing.T) {
|
||||
expected := &Render{
|
||||
EnableCache: false,
|
||||
TemplatesPath: "templates",
|
||||
Functions: make(template.FuncMap),
|
||||
templateCache: make(templateCache),
|
||||
TemplateData: TemplateData{},
|
||||
Functions: template.FuncMap{},
|
||||
templateCache: templateCache{},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@ -58,15 +61,17 @@ func Test_applyRenderConfig(t *testing.T) {
|
||||
{"Empty OptionFunc", &Render{
|
||||
EnableCache: false,
|
||||
TemplatesPath: "templates",
|
||||
Functions: make(template.FuncMap),
|
||||
templateCache: make(templateCache),
|
||||
TemplateData: TemplateData{},
|
||||
Functions: template.FuncMap{},
|
||||
templateCache: templateCache{},
|
||||
}, defaultHTMLRender()},
|
||||
{
|
||||
name: "Two OptionFunc", expected: &Render{
|
||||
EnableCache: true,
|
||||
TemplatesPath: "foobar",
|
||||
Functions: make(template.FuncMap),
|
||||
templateCache: make(templateCache),
|
||||
TemplateData: TemplateData{},
|
||||
Functions: template.FuncMap{},
|
||||
templateCache: templateCache{},
|
||||
},
|
||||
actual: NewHTMLRender(func(r *Render) {
|
||||
r.EnableCache = true
|
||||
@ -193,3 +198,200 @@ func Test_TemplateDefault(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type SomethingElements struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
func createDummyElements() []SomethingElements {
|
||||
return []SomethingElements{
|
||||
{"element 1", "description 1"},
|
||||
{"element 2", "description 2"},
|
||||
{"element 3", "description 3"},
|
||||
{"element 4", "description 4"},
|
||||
{"element 5", "description 5"},
|
||||
{"element 6", "description 6"},
|
||||
{"element 7", "description 7"},
|
||||
{"element 8", "description 8"},
|
||||
{"element 9", "description 9"},
|
||||
{"element 10", "description 10"},
|
||||
{"element 11", "description 11"},
|
||||
{"element 12", "description 12"},
|
||||
{"element 13", "description 13"},
|
||||
{"element 14", "description 14"},
|
||||
{"element 15", "description 15"},
|
||||
{"element 16", "description 16"},
|
||||
{"element 17", "description 17"},
|
||||
{"element 18", "description 18"},
|
||||
{"element 19", "description 19"},
|
||||
{"element 20", "description 20"},
|
||||
{"element 21", "description 21"},
|
||||
{"element 22", "description 22"},
|
||||
{"element 23", "description 23"},
|
||||
{"element 24", "description 24"},
|
||||
{"element 25", "description 25"},
|
||||
{"element 26", "description 26"},
|
||||
{"element 27", "description 27"},
|
||||
{"element 28", "description 28"},
|
||||
{"element 29", "description 29"},
|
||||
{"element 30", "description 30"},
|
||||
{"element 31", "description 31"},
|
||||
{"element 32", "description 32"},
|
||||
{"element 33", "description 33"},
|
||||
{"element 34", "description 34"},
|
||||
{"element 35", "description 35"},
|
||||
{"element 36", "description 36"},
|
||||
{"element 37", "description 37"},
|
||||
{"element 38", "description 38"},
|
||||
{"element 39", "description 39"},
|
||||
{"element 40", "description 40"},
|
||||
{"element 41", "description 41"},
|
||||
{"element 42", "description 42"},
|
||||
{"element 43", "description 43"},
|
||||
{"element 44", "description 44"},
|
||||
{"element 45", "description 45"},
|
||||
{"element 46", "description 46"},
|
||||
{"element 47", "description 47"},
|
||||
{"element 48", "description 48"},
|
||||
{"element 49", "description 49"},
|
||||
{"element 50", "description 50"},
|
||||
}
|
||||
}
|
||||
|
||||
func Test_PaginationParams(t *testing.T) {
|
||||
elements := createDummyElements()
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
given *Pages
|
||||
expected *Pages
|
||||
}{
|
||||
{
|
||||
name: "All defaults",
|
||||
req: httptest.NewRequest("GET", "/", nil),
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
},
|
||||
expected: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 20,
|
||||
ActualPage: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Without params",
|
||||
req: httptest.NewRequest("GET", "/", nil),
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 3,
|
||||
},
|
||||
expected: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "With page param",
|
||||
req: httptest.NewRequest("GET", "/?page=2", nil),
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
},
|
||||
expected: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 20,
|
||||
ActualPage: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "With limit param",
|
||||
req: httptest.NewRequest("GET", "/?limit=10", nil),
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
},
|
||||
expected: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "With page and limit param",
|
||||
req: httptest.NewRequest("GET", "/?page=2&limit=10", nil),
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
},
|
||||
expected: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.given.PaginationParams(tt.req)
|
||||
if !reflect.DeepEqual(tt.expected, tt.given) {
|
||||
t.Errorf("Expected: %v, Actual: %v", tt.expected, tt.given)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_PaginateArray(t *testing.T) {
|
||||
elements := createDummyElements()
|
||||
tests := []struct {
|
||||
name string
|
||||
given *Pages
|
||||
expected []SomethingElements
|
||||
}{
|
||||
{
|
||||
name: "First page",
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 1,
|
||||
},
|
||||
expected: elements[:10],
|
||||
},
|
||||
{
|
||||
name: "Second page",
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 2,
|
||||
},
|
||||
expected: elements[10:20],
|
||||
},
|
||||
{
|
||||
name: "Out of range superior",
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: 999,
|
||||
},
|
||||
expected: elements[40:50],
|
||||
},
|
||||
{
|
||||
name: "Out of range inferior",
|
||||
given: &Pages{
|
||||
TotalElements: len(elements),
|
||||
ElementsPerPage: 10,
|
||||
ActualPage: -1,
|
||||
},
|
||||
expected: elements[:10],
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := tt.given.PaginateArray(elements)
|
||||
if !reflect.DeepEqual(tt.expected, actual) {
|
||||
t.Errorf("Expected: %v, Actual: %v", tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user