package dbx import ( "testing" "time" "github.com/go-jet/jet/v2/mysql" "github.com/stretchr/testify/assert" "golang.org/x/exp/constraints" ) func Test_ApplyPtr(t *testing.T) { targetCol := mysql.StringColumn("test") var empty string cases := []struct { name string current *string new *string expected *string length int }{ {"apply updated value", Ptr("hello"), Ptr("world"), Ptr("world"), 1}, {"apply same value", Ptr("hello"), Ptr("hello"), Ptr("hello"), 0}, {"apply new value to nil", nil, Ptr("hello"), Ptr("hello"), 1}, {"apply nil to existing value", Ptr("hello"), nil, Ptr("hello"), 0}, {"apply empty string to existing value", Ptr("hello"), &empty, nil, 1}, {"apply empty string to nil", nil, &empty, nil, 0}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { modified := make(mysql.ColumnList, 0) updated := ApplyPtr(c.current, c.new, &modified, targetCol) assert.Len(t, modified, c.length) if c.expected == nil { assert.Nil(t, updated, "Expected updated value to be nil") } else { assert.NotNil(t, updated, "Expected updated value to be not nil") if updated != nil { assert.Equal(t, *c.expected, *updated, "Expected updated value to be equal to new value") } } }) } } func applyComplexPtr_tc[ Current constraints.Float | constraints.Integer, New constraints.Float | constraints.Integer, ]( t *testing.T, name string, current *Current, new *New, expected *Current, length int, ) { targetCol := mysql.IntegerColumn("test") t.Run(name, func(t *testing.T) { modified := make(mysql.ColumnList, 0) updated := ApplyComplexPtr(current, new, &modified, targetCol) assert.Len(t, modified, length) if expected == nil { assert.Nil(t, updated, "Expected updated value to be nil") } else { assert.NotNil(t, updated, "Expected updated value to be not nil") if updated != nil { assert.Equal(t, *expected, *updated, "Expected updated value to be equal to new value") } } }) } func Test_ApplyComplexPtr(t *testing.T) { var empty int applyComplexPtr_tc(t, "apply updated value", Ptr(1), Ptr(2), Ptr(2), 1) applyComplexPtr_tc(t, "apply same value", Ptr(1), Ptr(1), Ptr(1), 0) applyComplexPtr_tc(t, "apply new value to nil", nil, Ptr(2), Ptr(2), 1) applyComplexPtr_tc[int, int](t, "apply nil to existing value", Ptr(1), nil, Ptr(1), 0) applyComplexPtr_tc(t, "apply zero value to existing value", Ptr(1), &empty, nil, 1) applyComplexPtr_tc(t, "apply different type to existing value", Ptr[uint64](1), Ptr[uint16](2), Ptr[uint64](2), 1) applyComplexPtr_tc[int](t, "apply zero value to nil", nil, &empty, nil, 0) } func applyInterfacePtr_tc[ T ApplyInterface[T], ]( t *testing.T, name string, current *T, new *T, expected *T, length int, ) { targetCol := mysql.StringColumn("test") t.Run(name, func(t *testing.T) { modified := make(mysql.ColumnList, 0) updated := ApplyInterfacePtr(current, new, &modified, targetCol) assert.Len(t, modified, length) if expected == nil { assert.Nil(t, updated, "Expected updated value to be nil") } else { assert.NotNil(t, updated, "Expected updated value to be not nil") if updated != nil { assert.Equal(t, *expected, *updated, "Expected updated value to be equal to new value") } } }) } func Test_ApplyInterfacePtr(t *testing.T) { var zero time.Time applyInterfacePtr_tc(t, "apply updated value", Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), Ptr(time.Date(2023, 10, 2, 0, 0, 0, 0, time.UTC)), Ptr(time.Date(2023, 10, 2, 0, 0, 0, 0, time.UTC)), 1, ) applyInterfacePtr_tc(t, "apply same value", Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), 0, ) applyInterfacePtr_tc(t, "apply new value to nil", nil, Ptr(time.Date(2023, 10, 2, 0, 0, 0, 0, time.UTC)), Ptr(time.Date(2023, 10, 2, 0, 0, 0, 0, time.UTC)), 1, ) applyInterfacePtr_tc(t, "apply nil to existing value", Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), nil, Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), 0, ) applyInterfacePtr_tc(t, "apply zero value to existing value", Ptr(time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC)), &zero, nil, 1, ) applyInterfacePtr_tc(t, "apply zero value to nil", nil, &zero, nil, 0, ) } func Test_ApplyVal(t *testing.T) { targetCol := mysql.StringColumn("test") var empty string cases := []struct { name string current string new *string expected string length int }{ {"apply updated value", "hello", Ptr("world"), "world", 1}, {"apply same value", "hello", Ptr("hello"), "hello", 0}, {"apply new value to empty value", "", Ptr("hello"), "hello", 1}, {"apply nil to existing value", "hello", nil, "hello", 0}, {"apply empty string to existing value", "hello", &empty, "", 1}, {"apply empty string to empty value", "", &empty, "", 0}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { modified := make(mysql.ColumnList, 0) updated := ApplyVal(c.current, c.new, &modified, targetCol) assert.Equal(t, c.expected, updated, "Expected updated value to be equal to new value") assert.Len(t, modified, c.length) }) } }