Files
cursor/cursor_test.go

294 lines
7.4 KiB
Go

package cursor
import (
"encoding/json"
"testing"
"time"
"github.com/go-jet/jet/v2/mysql"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestColumnKey(t *testing.T) {
assert := assert.New(t)
empty := ColumnKey{}
assert.True(empty.IsEmpty())
assert.Equal("user.id", NewColumnKey(User.ID).String())
columnKey := NewColumnKey(User.ID)
assert.Equal(User.TableName(), columnKey.Table)
assert.Equal(User.ID.Name(), columnKey.Column)
assert.False(columnKey.IsEmpty())
bytes, err := json.Marshal(columnKey)
assert.NoError(err)
assert.Equal(`{"table":"user","column":"id"}`, string(bytes))
var res ColumnKey
err = json.Unmarshal(bytes, &res)
assert.NoError(err)
assert.Equal(User.TableName(), res.Table)
assert.Equal(User.ID.Name(), res.Column)
}
func TestColumnRegistry(t *testing.T) {
assert := assert.New(t)
RegisterColumn(User.ID)
col, err := GetColumn(User.TableName(), User.ID.Name())
assert.NoError(err)
assert.Equal(User.ID, col)
_, err = GetColumn(User.TableName(), "nonexistent")
assert.Error(err)
col, err = GetColumnByKey(ColumnKey{
Table: User.TableName(),
Column: User.ID.Name(),
})
assert.NoError(err)
assert.Equal(User.ID, col)
_, err = GetColumnByKey(ColumnKey{
Table: User.TableName(),
Column: "nonexistent",
})
assert.Error(err)
_, err = GetColumn(User.TableName(), User.CreatedAt.Name())
assert.Error(err)
}
func TestRegisterColumnList(t *testing.T) {
assert := assert.New(t)
RegisterColumnList(Address.AllColumns)
col, err := GetColumn(Address.TableName(), Address.ID.Name())
assert.NoError(err)
assert.Equal(Address.ID, col)
}
func TestOrderDirection(t *testing.T) {
assert := assert.New(t)
bytes, err := json.Marshal(OrderAscending)
assert.NoError(err)
assert.Equal(`"ASC"`, string(bytes))
var res OrderDirection
err = json.Unmarshal(bytes, &res)
assert.NoError(err)
assert.Equal(OrderAscending, res)
bytes, err = json.Marshal(OrderDescending)
assert.NoError(err)
assert.Equal(`"DESC"`, string(bytes))
err = json.Unmarshal(bytes, &res)
assert.NoError(err)
assert.Equal(OrderDescending, res)
var invalid OrderDirection
err = json.Unmarshal([]byte(`"INVALID"`), &invalid)
assert.Error(err)
_, err = OrderDirection(99).MarshalJSON()
assert.Error(err)
}
func TestInt64Value(t *testing.T) {
assert := assert.New(t)
v := NewInt64Value(1, Scratch.ID)
assert.Equal(int64(1), v.Val)
assert.Equal(Scratch.ID.Name(), v.Key.Column)
assert.Equal(Scratch.TableName(), v.Key.Table)
assert.Equal(mysql.Int64(1), v.Expr())
assert.Panics(func() { v.Col() })
RegisterColumn(Scratch.ID)
assert.Equal(Scratch.ID, v.Col())
assert.False(v.IsEmpty())
bytes, err := json.Marshal(v)
assert.NoError(err)
assert.Equal(`{"key":{"table":"scratch","column":"id"},"val":1}`, string(bytes))
var res Int64Value
assert.True(res.IsEmpty())
err = json.Unmarshal(bytes, &res)
assert.NoError(err)
assert.Equal(int64(1), res.Val)
assert.Equal(Scratch.ID.Name(), res.Key.Column)
assert.Equal(Scratch.TableName(), res.Key.Table)
assert.Equal(mysql.Int64(1), res.Expr())
assert.Equal(Scratch.ID, v.Col())
}
func TestUint64Value(t *testing.T) {
assert := assert.New(t)
v := NewUint64Value(42, Spare.ID)
assert.Equal(uint64(42), v.Val)
assert.Equal(mysql.Uint64(42), v.Expr())
assert.Panics(func() { v.Col() })
RegisterColumn(Spare.ID)
assert.Equal(Spare.ID, v.Col())
assert.False(v.IsEmpty())
bytes, err := json.Marshal(v)
assert.NoError(err)
var res Uint64Value
assert.True(res.IsEmpty())
err = json.Unmarshal(bytes, &res)
assert.NoError(err)
assert.Equal(uint64(42), res.Val)
}
func TestStringValueIsEmpty(t *testing.T) {
assert := assert.New(t)
registerMeetingCursorColumns(t)
empty := NewStringValue("", Meeting.ID)
assert.True(empty.IsEmpty())
nonEmpty := NewStringValue("meeting-uuid-1", Meeting.ID)
assert.False(nonEmpty.IsEmpty())
defaultMeetingCursor := NewCursor(
NewStringValue("", Meeting.ID),
Meeting.StartTime,
OrderDescending,
)
assert.True(defaultMeetingCursor.IsEmpty())
}
func TestNewCursor(t *testing.T) {
assert := assert.New(t)
empty := Cursor[mysql.IntegerExpression, mysql.ColumnInteger]{}
assert.True(empty.IsEmpty())
v := NewInt64Value(1, User.ID)
cursor := NewCursor(v, User.ID, OrderAscending)
assert.Equal(v, cursor.Index)
assert.Equal(NewColumnKey(User.ID), cursor.OrderColumnKey)
assert.Equal(OrderAscending, cursor.OrderDir)
bytes, err := json.Marshal(cursor)
assert.NoError(err)
assert.Equal(`{"index":{"key":{"table":"user","column":"id"},"val":1},"order_col":{"table":"user","column":"id"},"order_dir":"ASC"}`, string(bytes))
}
func TestCopyWithVal(t *testing.T) {
assert := assert.New(t)
RegisterColumn(User.ID)
original := NewCursor(NewInt64Value(1, User.ID), User.ID, OrderDescending)
copied := original.CopyWithVal(NewInt64Value(99, User.ID))
assert.Equal(int64(99), copied.Index.(*Int64Value).Val)
assert.Equal(OrderDescending, copied.OrderDir)
assert.Equal(NewColumnKey(User.ID), copied.OrderColumnKey)
}
func TestNewCursorFromJSON(t *testing.T) {
assert := assert.New(t)
v := NewInt64Value(1, User.ID)
cursor := NewCursor(v, User.ID, OrderDescending)
bytes, err := json.Marshal(cursor)
assert.NoError(err)
zv := NewInt64Value(0, User.ID)
res, err := NewCursorFromJSON(zv, bytes)
assert.NoError(err)
assert.NotNil(res)
assert.Equal(int64(1), res.Index.(*Int64Value).Val)
assert.Equal(NewColumnKey(User.ID), res.OrderColumnKey)
assert.Equal(OrderDescending, res.OrderDir)
}
func TestNewCursorFromJSONComposite(t *testing.T) {
assert := assert.New(t)
registerMeetingCursorColumns(t)
when := time.Date(2026, 6, 1, 9, 0, 0, 0, time.UTC)
original := NewCursor(
NewStringValue("", Meeting.ID),
Meeting.StartTime,
OrderDescending,
).CopyWithVals(
NewStringValue("meeting-uuid-1", Meeting.ID),
NewTimestampValue(when, Meeting.StartTime),
)
bytes, err := json.Marshal(original)
require.NoError(t, err)
zv := NewStringValue("", Meeting.ID)
res, err := NewCursorFromJSON(zv, bytes)
require.NoError(t, err)
assert.True(res.IsComposite())
assert.Equal("meeting-uuid-1", res.Index.(*StringValue).Val)
assert.Equal(when, res.GenericOrderValue().(*TimestampValue).Val)
}
func TestDecodeAndOrder(t *testing.T) {
assert := assert.New(t)
RegisterColumn(User.ID)
encoded, err := NewCursor(
NewInt64Value(5, User.ID),
User.ID,
OrderDescending,
).Encode()
require.NoError(t, err)
c := NewCursor(NewInt64Value(0, User.ID), User.ID, OrderAscending)
require.NoError(t, c.DecodeAndOrder(encoded, OrderAscending))
assert.Equal(OrderAscending, c.OrderDir)
assert.Equal(int64(5), c.Index.(*Int64Value).Val)
}
func TestCursorDecodeNilReceiver(t *testing.T) {
var c *Cursor[mysql.IntegerExpression, mysql.ColumnInteger]
assert.Error(t, c.Decode("{}"))
}
func TestNewCursorFromAfterPtr(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
RegisterColumn(User.ID)
newZero := func() *Cursor[mysql.IntegerExpression, mysql.ColumnInteger] {
return NewCursor(NewInt64Value(0, User.ID), User.ID, OrderDescending)
}
c, err := NewCursorFromAfterPtr(newZero, nil)
require.NoError(err)
assert.Nil(c)
empty := ""
c, err = NewCursorFromAfterPtr(newZero, &empty)
require.NoError(err)
assert.Nil(c)
encoded, err := NewCursor(
NewInt64Value(42, User.ID),
User.ID,
OrderDescending,
).Encode()
require.NoError(err)
c, err = NewCursorFromAfterPtr(newZero, &encoded)
require.NoError(err)
require.NotNil(c)
assert.Equal(int64(42), c.Index.(*Int64Value).Val)
}