[🤖] Add Unit-Tests
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s

This commit is contained in:
2026-04-27 10:46:08 +02:00
parent dad0e3240d
commit 02d6894ec6
116 changed files with 18795 additions and 1 deletions
+213
View File
@@ -0,0 +1,213 @@
package sq
import (
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
"strings"
"testing"
)
func TestBuildInsertStatementBasic(t *testing.T) {
type r struct {
ID string `db:"id"`
Name string `db:"name"`
}
q := fakeQueryable{}
sqlstr, pp, err := BuildInsertStatement(q, "users", r{ID: "1", Name: "alice"})
tst.AssertNoErr(t, err)
tst.AssertTrue(t, strings.HasPrefix(sqlstr, "INSERT INTO users ("))
tst.AssertTrue(t, strings.Contains(sqlstr, "id"))
tst.AssertTrue(t, strings.Contains(sqlstr, "name"))
tst.AssertEqual(t, 2, len(pp))
values := []any{}
for _, v := range pp {
values = append(values, v)
}
hasID, hasName := false, false
for _, v := range values {
if vs, ok := v.(string); ok {
if vs == "1" {
hasID = true
}
if vs == "alice" {
hasName = true
}
}
}
tst.AssertTrue(t, hasID)
tst.AssertTrue(t, hasName)
}
func TestBuildInsertStatementSkipsUnexported(t *testing.T) {
type r struct {
ID string `db:"id"`
hidden string `db:"hidden"` //nolint:unused
}
q := fakeQueryable{}
sqlstr, pp, err := BuildInsertStatement(q, "users", r{ID: "1"})
tst.AssertNoErr(t, err)
tst.AssertEqual(t, 1, len(pp))
tst.AssertTrue(t, !strings.Contains(sqlstr, "hidden"))
}
func TestBuildInsertStatementSkipsNoTagAndDash(t *testing.T) {
type r struct {
ID string `db:"id"`
Skip1 string `db:"-"`
Skip2 string
}
q := fakeQueryable{}
sqlstr, pp, err := BuildInsertStatement(q, "users", r{ID: "1", Skip1: "x", Skip2: "y"})
tst.AssertNoErr(t, err)
tst.AssertEqual(t, 1, len(pp))
tst.AssertTrue(t, !strings.Contains(sqlstr, "Skip"))
}
func TestBuildInsertStatementNoFields(t *testing.T) {
type r struct {
Skip string
}
q := fakeQueryable{}
_, _, err := BuildInsertStatement(q, "x", r{})
if err == nil {
t.Fatal("expected error for no usable fields")
}
}
func TestBuildInsertStatementNilPointer(t *testing.T) {
type r struct {
ID string `db:"id"`
Note *string `db:"note"`
}
q := fakeQueryable{}
sqlstr, pp, err := BuildInsertStatement(q, "users", r{ID: "1", Note: nil})
tst.AssertNoErr(t, err)
// Only id is parameterized; nil pointer becomes literal NULL
tst.AssertEqual(t, 1, len(pp))
tst.AssertTrue(t, strings.Contains(sqlstr, "NULL"))
}
func TestBuildInsertStatementWithConverter(t *testing.T) {
type r struct {
ID string `db:"id"`
Flag bool `db:"flag"`
}
q := fakeQueryable{converters: []DBTypeConverter{ConverterBoolToBit}}
_, pp, err := BuildInsertStatement(q, "users", r{ID: "1", Flag: true})
tst.AssertNoErr(t, err)
tst.AssertEqual(t, 2, len(pp))
foundOne := false
for _, v := range pp {
if vi, ok := v.(int64); ok && vi == 1 {
foundOne = true
}
}
tst.AssertTrue(t, foundOne)
}
func TestBuildUpdateStatementBasic(t *testing.T) {
type r struct {
ID string `db:"id"`
Name string `db:"name"`
}
q := fakeQueryable{}
sqlstr, pp, err := BuildUpdateStatement(q, "users", r{ID: "1", Name: "alice"}, "id")
tst.AssertNoErr(t, err)
tst.AssertTrue(t, strings.HasPrefix(sqlstr, "UPDATE users SET "))
tst.AssertTrue(t, strings.Contains(sqlstr, "name = :"))
tst.AssertTrue(t, strings.Contains(sqlstr, "(id = :"))
tst.AssertEqual(t, 2, len(pp))
}
func TestBuildUpdateStatementMissingID(t *testing.T) {
type r struct {
Name string `db:"name"`
}
q := fakeQueryable{}
_, _, err := BuildUpdateStatement(q, "users", r{Name: "alice"}, "id")
if err == nil {
t.Fatal("expected error for missing id column")
}
}
func TestBuildUpdateStatementOnlyID(t *testing.T) {
type r struct {
ID string `db:"id"`
}
q := fakeQueryable{}
_, _, err := BuildUpdateStatement(q, "users", r{ID: "1"}, "id")
if err == nil {
t.Fatal("expected error when no SET clauses")
}
}
func TestBuildUpdateStatementNilPointer(t *testing.T) {
type r struct {
ID string `db:"id"`
Note *string `db:"note"`
}
q := fakeQueryable{}
sqlstr, _, err := BuildUpdateStatement(q, "users", r{ID: "1", Note: nil}, "id")
tst.AssertNoErr(t, err)
tst.AssertTrue(t, strings.Contains(sqlstr, "note = NULL"))
}
func TestBuildInsertMultipleStatementBasic(t *testing.T) {
type r struct {
ID string `db:"id"`
Name string `db:"name"`
}
q := fakeQueryable{}
sqlstr, pp, err := BuildInsertMultipleStatement(q, "users", []r{
{ID: "1", Name: "alice"},
{ID: "2", Name: "bob"},
})
tst.AssertNoErr(t, err)
tst.AssertTrue(t, strings.Contains(sqlstr, `INSERT INTO "users"`))
tst.AssertTrue(t, strings.Contains(sqlstr, `"id"`))
tst.AssertTrue(t, strings.Contains(sqlstr, `"name"`))
// 2 rows × 2 fields = 4 placeholders
tst.AssertEqual(t, 4, len(pp))
// Two value tuples should appear -> exactly one "), (" separator
tst.AssertEqual(t, 1, strings.Count(sqlstr, "), ("))
}
func TestBuildInsertMultipleStatementEmpty(t *testing.T) {
type r struct {
ID string `db:"id"`
}
q := fakeQueryable{}
_, _, err := BuildInsertMultipleStatement(q, "x", []r{})
if err == nil {
t.Fatal("expected error for empty input")
}
}
func TestBuildInsertMultipleStatementNilPointer(t *testing.T) {
type r struct {
ID string `db:"id"`
Note *string `db:"note"`
}
q := fakeQueryable{}
sqlstr, _, err := BuildInsertMultipleStatement(q, "users", []r{{ID: "1", Note: nil}})
tst.AssertNoErr(t, err)
tst.AssertTrue(t, strings.Contains(sqlstr, "NULL"))
}