Repository: danvergara/dblab
Pull request #144 (2023-02-11 06:34:06)

Fix paginator
## Description

I found out that `pagination` was acting up if the result set only has one page, the `total pages` value is always zero.

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How Has This Been Tested?

Refactor the test suite on the `pagination` package to make sure the bug got fixed

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] I have checked my code and corrected any misspellings



Patch:
diff --git a/pkg/pagination/pagination.go b/pkg/pagination/pagination.go
index 74dca3e..237bcb5 100644
--- a/pkg/pagination/pagination.go
+++ b/pkg/pagination/pagination.go
@@ -1,6 +1,9 @@
 package pagination
 
-import "fmt"
+import (
+	"fmt"
+	"math"
+)
 
 // Manager handles the pagination.
 type Manager struct {
@@ -94,7 +97,7 @@ func (m *Manager) setTotalPages(count int) error {
 		return fmt.Errorf("limit should be greater than 0")
 	}
 
-	m.totalPages = count / m.limit
+	m.totalPages = int(math.Ceil(float64(count) / float64(m.limit)))
 
 	return nil
 }


Test patch:
diff --git a/pkg/pagination/pagination_test.go b/pkg/pagination/pagination_test.go
index dc43dc3..388c490 100644
--- a/pkg/pagination/pagination_test.go
+++ b/pkg/pagination/pagination_test.go
@@ -7,37 +7,98 @@ import (
 )
 
 func TestPaginationLifeCycle(t *testing.T) {
-	// This is an example of the pagination life cycle.
-	// It starts off with a limit of 50 and count from a sql query of 10000.
-	// The total pages count should be equal to count / limit = 200
-	// I'm calling the NextPage 3 times and PreviousPage two times.
-	limit := 50
-	count := 150
-
-	m, err := New(limit, count, "users")
-	assert.NoError(t, err)
-
-	for i := 0; i < (count/m.Limit())-1; i++ {
-		_ = m.NextPage()
+	type given struct {
+		count     int
+		limit     int
+		tableName string
 	}
 
-	assert.Equal(t, count/m.Limit(), m.CurrentPage())
-	assert.Equal(t, (m.CurrentPage()-1)*limit, m.Offset())
-
-	err = m.NextPage()
-	assert.Error(t, err)
+	type expected struct {
+		lastPage      int
+		currentOffset int
+		totalPages    int
+		tableName     string
+	}
 
-	for i := 0; i < (count/m.Limit())-1; i++ {
-		_ = m.PreviousPage()
+	var tests = []struct {
+		name     string
+		given    given
+		expected expected
+	}{
+		{
+			name: "count is higher than limit",
+			given: given{
+				limit:     50,
+				count:     150,
+				tableName: "products",
+			},
+			expected: expected{
+				lastPage:      3,
+				currentOffset: 0,
+				totalPages:    3,
+				tableName:     "products",
+			},
+		},
+		{
+			name: "limit is higher than count",
+			given: given{
+				limit:     150,
+				count:     50,
+				tableName: "products",
+			},
+			expected: expected{
+				lastPage:      1,
+				currentOffset: 0,
+				totalPages:    1,
+				tableName:     "products",
+			},
+		},
+		{
+			name: "count is odd and higher than limit",
+			given: given{
+				limit:     50,
+				count:     151,
+				tableName: "products",
+			},
+			expected: expected{
+				lastPage:      4,
+				currentOffset: 0,
+				totalPages:    4,
+				tableName:     "products",
+			},
+		},
 	}
 
-	assert.Equal(t, 1, m.CurrentPage())
-	assert.Equal(t, 0, m.Offset())
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			m, err := New(tc.given.limit, tc.given.count, "users")
+			assert.NoError(t, err)
+
+			assert.Equal(t, tc.expected.totalPages, m.TotalPages())
+
+			for i := 0; i < m.TotalPages(); i++ {
+				_ = m.NextPage()
+			}
 
-	err = m.PreviousPage()
-	assert.Error(t, err)
+			assert.Equal(t, tc.expected.lastPage, m.CurrentPage())
+			assert.Equal(t, (m.CurrentPage()-1)*tc.given.limit, m.Offset())
 
-	m.SetCurrentTable("products")
-	ct := m.CurrentTable()
-	assert.Equal(t, "products", ct)
+			err = m.NextPage()
+			assert.Error(t, err)
+
+			for i := 0; i < m.TotalPages(); i++ {
+				_ = m.PreviousPage()
+			}
+			assert.Equal(t, 1, m.CurrentPage())
+			assert.Equal(t, tc.expected.currentOffset, m.Offset())
+
+			err = m.PreviousPage()
+			assert.Error(t, err)
+
+			m.SetCurrentTable(tc.given.tableName)
+			ct := m.CurrentTable()
+			assert.Equal(t, tc.expected.tableName, ct)
+		})
+	}
 }