readysite / pkg / database / mirror_test.go
3.7 KB
mirror_test.go
package database

import (
	"reflect"
	"testing"
	"time"
)

type MirrorTestEntity struct {
	Model
	Name    string
	Count   int
	Score   float64
	Active  bool
	Extra   string
}

func TestMirror_Reflect(t *testing.T) {
	mirror := Reflect[MirrorTestEntity]()

	if mirror.Name() != "MirrorTestEntity" {
		t.Errorf("expected name 'MirrorTestEntity', got '%s'", mirror.Name())
	}

	columns := mirror.Columns()
	if len(columns) != 8 { // ID, CreatedAt, UpdatedAt, Name, Count, Score, Active, Extra
		t.Errorf("expected 8 columns, got %d", len(columns))
	}

	// Verify column types
	colMap := make(map[string]Column)
	for _, col := range columns {
		colMap[col.Name] = col
	}

	if colMap["ID"].Type != "TEXT" || !colMap["ID"].Primary {
		t.Errorf("expected ID to be TEXT PRIMARY, got %v", colMap["ID"])
	}
	if colMap["Name"].Type != "TEXT" {
		t.Errorf("expected Name to be TEXT, got %s", colMap["Name"].Type)
	}
	if colMap["Count"].Type != "INTEGER" {
		t.Errorf("expected Count to be INTEGER, got %s", colMap["Count"].Type)
	}
	if colMap["Score"].Type != "REAL" {
		t.Errorf("expected Score to be REAL, got %s", colMap["Score"].Type)
	}
	if colMap["Active"].Type != "INTEGER" {
		t.Errorf("expected Active to be INTEGER, got %s", colMap["Active"].Type)
	}
	if colMap["CreatedAt"].Type != "DATETIME" {
		t.Errorf("expected CreatedAt to be DATETIME, got %s", colMap["CreatedAt"].Type)
	}
}

func TestMirror_New(t *testing.T) {
	mirror := Reflect[MirrorTestEntity]()

	entity := mirror.New()
	if entity == nil {
		t.Fatal("expected non-nil entity")
	}

	// Should be able to cast to *MirrorTestEntity
	if _, ok := entity.(*MirrorTestEntity); !ok {
		t.Errorf("expected *MirrorTestEntity, got %T", entity)
	}
}

func TestMirror_Field(t *testing.T) {
	mirror := Reflect[MirrorTestEntity]()

	entity := &MirrorTestEntity{Name: "test", Count: 42}
	entity.ID = "abc-123"

	v := reflect.ValueOf(entity).Elem()

	// Test direct field
	name := mirror.Field(v, "Name")
	if name.String() != "test" {
		t.Errorf("expected 'test', got '%s'", name.String())
	}

	// Test embedded field (from Model)
	id := mirror.Field(v, "ID")
	if id.String() != "abc-123" {
		t.Errorf("expected 'abc-123', got '%s'", id.String())
	}

	// Test setting field
	mirror.Field(v, "Count").SetInt(100)
	if entity.Count != 100 {
		t.Errorf("expected Count 100, got %d", entity.Count)
	}

	// Test invalid field
	invalid := mirror.Field(v, "NonExistent")
	if invalid.IsValid() {
		t.Error("expected invalid field for NonExistent")
	}
}

func TestMirror_Values(t *testing.T) {
	mirror := Reflect[MirrorTestEntity]()

	now := time.Now()
	entity := &MirrorTestEntity{
		Name:   "test",
		Count:  42,
		Score:  3.14,
		Active: true,
		Extra:  "extra",
	}
	entity.ID = "id-1"
	entity.CreatedAt = now
	entity.UpdatedAt = now

	v := reflect.ValueOf(entity).Elem()
	values := mirror.Values(v)

	if len(values) != 8 {
		t.Fatalf("expected 8 values, got %d", len(values))
	}

	// Values should be in column order: ID, CreatedAt, UpdatedAt, Name, Count, Score, Active, Extra
	if values[0].(string) != "id-1" {
		t.Errorf("expected ID 'id-1', got %v", values[0])
	}
	if values[3].(string) != "test" {
		t.Errorf("expected Name 'test', got %v", values[3])
	}
	if values[4].(int) != 42 {
		t.Errorf("expected Count 42, got %v", values[4])
	}
}

func TestMirror_Pointers(t *testing.T) {
	mirror := Reflect[MirrorTestEntity]()

	entity := &MirrorTestEntity{}
	v := reflect.ValueOf(entity).Elem()

	ptrs := mirror.Pointers(v)
	if len(ptrs) != 8 {
		t.Fatalf("expected 8 pointers, got %d", len(ptrs))
	}

	// Each pointer should be addressable
	for i, ptr := range ptrs {
		if ptr == nil {
			t.Errorf("pointer %d is nil", i)
		}
	}

	// Setting via pointer should update entity
	*(ptrs[0].(*string)) = "new-id"
	if entity.ID != "new-id" {
		t.Errorf("expected ID 'new-id', got '%s'", entity.ID)
	}
}
← Back