2026-03-07 19:27:44 +08:00
|
|
|
package testing
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-20 13:36:59 +08:00
|
|
|
"errors"
|
2026-03-07 19:27:44 +08:00
|
|
|
"testing"
|
|
|
|
|
"time"
|
2026-03-20 13:36:59 +08:00
|
|
|
|
|
|
|
|
"b612.me/stardb"
|
2026-03-07 19:27:44 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestStarResult_MustString(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
name := row.MustString("name")
|
|
|
|
|
if name != "Alice" {
|
|
|
|
|
t.Errorf("Expected 'Alice', got '%s'", name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
email := row.MustString("email")
|
|
|
|
|
if email != "alice@example.com" {
|
|
|
|
|
t.Errorf("Expected 'alice@example.com', got '%s'", email)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test non-existent column
|
|
|
|
|
nonexistent := row.MustString("nonexistent")
|
|
|
|
|
if nonexistent != "" {
|
|
|
|
|
t.Errorf("Expected empty string for non-existent column, got '%s'", nonexistent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_MustInt(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Bob")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
age := row.MustInt("age")
|
|
|
|
|
if age != 30 {
|
|
|
|
|
t.Errorf("Expected age 30, got %d", age)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
id := row.MustInt("id")
|
|
|
|
|
if id <= 0 {
|
|
|
|
|
t.Errorf("Expected positive id, got %d", id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_MustInt64(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Charlie")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
age := row.MustInt64("age")
|
|
|
|
|
if age != 35 {
|
|
|
|
|
t.Errorf("Expected age 35, got %d", age)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_MustFloat64(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
balance := row.MustFloat64("balance")
|
|
|
|
|
if balance != 100.50 {
|
|
|
|
|
t.Errorf("Expected balance 100.50, got %f", balance)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_MustBool(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users ORDER BY name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
// Alice - active
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
active := row.MustBool("active")
|
|
|
|
|
if !active {
|
|
|
|
|
t.Errorf("Expected Alice to be active")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Charlie - inactive
|
|
|
|
|
row = rows.Row(2)
|
|
|
|
|
active = row.MustBool("active")
|
|
|
|
|
if active {
|
|
|
|
|
t.Errorf("Expected Charlie to be inactive")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_IsNil(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
// Insert a row with NULL value
|
|
|
|
|
_, err := db.Exec("INSERT INTO users (name, email, age, balance, active, created_at) VALUES (?, ?, NULL, ?, ?, ?)",
|
|
|
|
|
"David", "david@example.com", 150.0, true, time.Now())
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Insert failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "David")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
if !row.IsNil("age") {
|
|
|
|
|
t.Errorf("Expected age to be NULL")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if row.IsNil("name") {
|
|
|
|
|
t.Errorf("Expected name to not be NULL")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResultCol_MustString(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users ORDER BY name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
col := rows.Col("name")
|
|
|
|
|
names := col.MustString()
|
|
|
|
|
|
|
|
|
|
expected := []string{"Alice", "Bob", "Charlie"}
|
|
|
|
|
for i, name := range names {
|
|
|
|
|
if name != expected[i] {
|
|
|
|
|
t.Errorf("Expected name '%s', got '%s'", expected[i], name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResultCol_MustInt(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users ORDER BY name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
col := rows.Col("age")
|
|
|
|
|
ages := col.MustInt()
|
|
|
|
|
|
|
|
|
|
expected := []int{25, 30, 35}
|
|
|
|
|
for i, age := range ages {
|
|
|
|
|
if age != expected[i] {
|
|
|
|
|
t.Errorf("Expected age %d, got %d", expected[i], age)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResultCol_MustFloat64(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users ORDER BY name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
col := rows.Col("balance")
|
|
|
|
|
balances := col.MustFloat64()
|
|
|
|
|
|
|
|
|
|
expected := []float64{100.50, 200.75, 300.25}
|
|
|
|
|
for i, balance := range balances {
|
|
|
|
|
if balance != expected[i] {
|
|
|
|
|
t.Errorf("Expected balance %f, got %f", expected[i], balance)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResultCol_MustBool(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users ORDER BY name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
col := rows.Col("active")
|
|
|
|
|
actives := col.MustBool()
|
|
|
|
|
|
|
|
|
|
expected := []bool{true, true, false}
|
|
|
|
|
for i, active := range actives {
|
|
|
|
|
if active != expected[i] {
|
|
|
|
|
t.Errorf("Expected active %v, got %v", expected[i], active)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-20 13:36:59 +08:00
|
|
|
|
|
|
|
|
func TestStarResult_GetColumnNotFoundError(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
_, err = row.GetString("does_not_exist")
|
|
|
|
|
if !errors.Is(err, stardb.ErrColumnNotFound) {
|
|
|
|
|
t.Fatalf("Expected ErrColumnNotFound, got %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_GetNullValues(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
_, err := db.Exec(
|
|
|
|
|
"INSERT INTO users (name, email, age, balance, active, created_at) VALUES (?, ?, ?, ?, ?, ?)",
|
|
|
|
|
"NullUser", "null@example.com", nil, nil, nil, nil,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Insert failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT * FROM users WHERE name = ?", "NullUser")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
row := rows.Row(0)
|
|
|
|
|
|
|
|
|
|
name, err := row.GetNullString("name")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullString failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if !name.Valid || name.String != "NullUser" {
|
|
|
|
|
t.Fatalf("Expected valid name NullUser, got %+v", name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
age, err := row.GetNullInt64("age")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullInt64 failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if age.Valid {
|
|
|
|
|
t.Fatalf("Expected NULL age, got %+v", age)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
balance, err := row.GetNullFloat64("balance")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullFloat64 failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if balance.Valid {
|
|
|
|
|
t.Fatalf("Expected NULL balance, got %+v", balance)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
active, err := row.GetNullBool("active")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullBool failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if active.Valid {
|
|
|
|
|
t.Fatalf("Expected NULL active, got %+v", active)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createdAt, err := row.GetNullTime("created_at")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullTime failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if createdAt.Valid {
|
|
|
|
|
t.Fatalf("Expected NULL created_at, got %+v", createdAt)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestStarResult_GetNullTime_Valid(t *testing.T) {
|
|
|
|
|
db := setupTestDB(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
rows, err := db.Query("SELECT created_at FROM users WHERE name = ?", "Alice")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Query failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
value, err := rows.Row(0).GetNullTime("created_at")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("GetNullTime failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if !value.Valid {
|
|
|
|
|
t.Fatal("Expected valid created_at")
|
|
|
|
|
}
|
|
|
|
|
}
|