package reflectutil import ( "reflect" "testing" ) type testStruct struct { Name string Age int Active bool Nested *nestedStruct Private string } type nestedStruct struct { Value string Count int } func TestDeref(t *testing.T) { tests := []struct { name string input interface{} wantValid bool wantKind reflect.Kind }{ { name: "non-pointer int", input: 42, wantValid: true, wantKind: reflect.Int, }, { name: "single pointer", input: ptrInt(42), wantValid: true, wantKind: reflect.Int, }, { name: "double pointer", input: ptrPtr(ptrInt(42)), wantValid: true, wantKind: reflect.Int, }, { name: "nil pointer", input: (*int)(nil), wantValid: false, wantKind: reflect.Ptr, }, { name: "string", input: "test", wantValid: true, wantKind: reflect.String, }, { name: "struct", input: testStruct{Name: "test"}, wantValid: true, wantKind: reflect.Struct, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { v := reflect.ValueOf(tt.input) got, valid := Deref(v) if valid != tt.wantValid { t.Errorf("Deref() valid = %v, want %v", valid, tt.wantValid) } if got.Kind() != tt.wantKind { t.Errorf("Deref() kind = %v, want %v", got.Kind(), tt.wantKind) } }) } } func TestDerefInterface(t *testing.T) { i := 42 pi := &i ppi := &pi tests := []struct { name string input interface{} wantKind reflect.Kind }{ {"int", 42, reflect.Int}, {"pointer to int", &i, reflect.Int}, {"double pointer to int", ppi, reflect.Int}, {"string", "test", reflect.String}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := DerefInterface(tt.input) if got.Kind() != tt.wantKind { t.Errorf("DerefInterface() kind = %v, want %v", got.Kind(), tt.wantKind) } }) } } func TestGetFieldValue(t *testing.T) { ts := testStruct{ Name: "John", Age: 30, Active: true, Nested: &nestedStruct{Value: "nested", Count: 5}, } tests := []struct { name string item interface{} field string want interface{} }{ {"struct field Name", ts, "Name", "John"}, {"struct field Age", ts, "Age", 30}, {"struct field Active", ts, "Active", true}, {"struct non-existent field", ts, "NonExistent", nil}, {"pointer to struct", &ts, "Name", "John"}, {"map string key", map[string]string{"key": "value"}, "key", "value"}, {"map int key", map[string]int{"count": 42}, "count", 42}, {"map non-existent key", map[string]string{"key": "value"}, "missing", nil}, {"nil pointer", (*testStruct)(nil), "Name", nil}, {"non-struct non-map", 42, "field", nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := GetFieldValue(tt.item, tt.field) if !reflect.DeepEqual(got, tt.want) { t.Errorf("GetFieldValue() = %v, want %v", got, tt.want) } }) } } func TestIsSliceOrArray(t *testing.T) { arr := [3]int{1, 2, 3} tests := []struct { name string input interface{} want bool }{ {"slice", []int{1, 2, 3}, true}, {"array", arr, true}, {"pointer to slice", &[]int{1, 2, 3}, true}, {"string", "test", false}, {"int", 42, false}, {"map", map[string]int{}, false}, {"nil slice", ([]int)(nil), true}, // nil slice is still Kind==Slice {"nil pointer", (*[]int)(nil), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := IsSliceOrArray(tt.input) if got != tt.want { t.Errorf("IsSliceOrArray() = %v, want %v", got, tt.want) } }) } } func TestIsMap(t *testing.T) { tests := []struct { name string input interface{} want bool }{ {"map[string]int", map[string]int{"a": 1}, true}, {"map[int]string", map[int]string{1: "a"}, true}, {"pointer to map", &map[string]int{"a": 1}, true}, {"slice", []int{1, 2, 3}, false}, {"string", "test", false}, {"int", 42, false}, {"nil map", (map[string]int)(nil), true}, // nil map is still Kind==Map {"nil pointer", (*map[string]int)(nil), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := IsMap(tt.input) if got != tt.want { t.Errorf("IsMap() = %v, want %v", got, tt.want) } }) } } func TestSliceLen(t *testing.T) { arr := [3]int{1, 2, 3} tests := []struct { name string input interface{} want int }{ {"slice length 3", []int{1, 2, 3}, 3}, {"empty slice", []int{}, 0}, {"array length 3", arr, 3}, {"pointer to slice", &[]int{1, 2, 3}, 3}, {"not a slice", "test", 0}, {"int", 42, 0}, {"nil slice", ([]int)(nil), 0}, {"nil pointer", (*[]int)(nil), 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := SliceLen(tt.input) if got != tt.want { t.Errorf("SliceLen() = %v, want %v", got, tt.want) } }) } } func TestMapLen(t *testing.T) { tests := []struct { name string input interface{} want int }{ {"map length 2", map[string]int{"a": 1, "b": 2}, 2}, {"empty map", map[string]int{}, 0}, {"pointer to map", &map[string]int{"a": 1}, 1}, {"not a map", []int{1, 2, 3}, 0}, {"string", "test", 0}, {"nil map", (map[string]int)(nil), 0}, {"nil pointer", (*map[string]int)(nil), 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := MapLen(tt.input) if got != tt.want { t.Errorf("MapLen() = %v, want %v", got, tt.want) } }) } } func TestSliceToInterfaces(t *testing.T) { tests := []struct { name string input interface{} want []interface{} }{ {"int slice", []int{1, 2, 3}, []interface{}{1, 2, 3}}, {"string slice", []string{"a", "b"}, []interface{}{"a", "b"}}, {"empty slice", []int{}, []interface{}{}}, {"pointer to slice", &[]int{1, 2}, []interface{}{1, 2}}, {"not a slice", "test", []interface{}{}}, {"nil slice", ([]int)(nil), []interface{}{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := SliceToInterfaces(tt.input) if !reflect.DeepEqual(got, tt.want) { t.Errorf("SliceToInterfaces() = %v, want %v", got, tt.want) } }) } } func TestMapKeys(t *testing.T) { tests := []struct { name string input interface{} want []interface{} }{ {"map with keys", map[string]int{"a": 1, "b": 2}, []interface{}{"a", "b"}}, {"empty map", map[string]int{}, []interface{}{}}, {"not a map", []int{1, 2, 3}, []interface{}{}}, {"nil map", (map[string]int)(nil), []interface{}{}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := MapKeys(tt.input) if len(got) != len(tt.want) { t.Errorf("MapKeys() length = %v, want %v", len(got), len(tt.want)) } // For maps, order is not guaranteed, so just check length }) } } func TestMapValues(t *testing.T) { tests := []struct { name string input interface{} want int // length of values }{ {"map with values", map[string]int{"a": 1, "b": 2}, 2}, {"empty map", map[string]int{}, 0}, {"not a map", []int{1, 2, 3}, 0}, {"nil map", (map[string]int)(nil), 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := MapValues(tt.input) if len(got) != tt.want { t.Errorf("MapValues() length = %v, want %v", len(got), tt.want) } }) } } func TestMapGet(t *testing.T) { m := map[string]int{"a": 1, "b": 2} tests := []struct { name string input interface{} key interface{} want interface{} }{ {"existing key", m, "a", 1}, {"existing key b", m, "b", 2}, {"non-existing key", m, "c", nil}, {"pointer to map", &m, "a", 1}, {"not a map", []int{1, 2}, 0, nil}, {"nil map", (map[string]int)(nil), "a", nil}, {"nil pointer", (*map[string]int)(nil), "a", nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := MapGet(tt.input, tt.key) if !reflect.DeepEqual(got, tt.want) { t.Errorf("MapGet() = %v, want %v", got, tt.want) } }) } } func TestSliceIndex(t *testing.T) { s := []int{10, 20, 30} tests := []struct { name string slice interface{} index int want interface{} }{ {"index 0", s, 0, 10}, {"index 1", s, 1, 20}, {"index 2", s, 2, 30}, {"negative index", s, -1, nil}, {"out of bounds", s, 5, nil}, {"pointer to slice", &s, 1, 20}, {"not a slice", "test", 0, nil}, {"nil slice", ([]int)(nil), 0, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := SliceIndex(tt.slice, tt.index) if !reflect.DeepEqual(got, tt.want) { t.Errorf("SliceIndex() = %v, want %v", got, tt.want) } }) } } func TestCompareValues(t *testing.T) { tests := []struct { name string a interface{} b interface{} want int }{ {"both nil", nil, nil, 0}, {"a nil", nil, 5, -1}, {"b nil", 5, nil, 1}, {"equal strings", "abc", "abc", 0}, {"a less than b strings", "abc", "xyz", -1}, {"a greater than b strings", "xyz", "abc", 1}, {"equal ints", 5, 5, 0}, {"a less than b ints", 3, 7, -1}, {"a greater than b ints", 10, 5, 1}, {"equal floats", 3.14, 3.14, 0}, {"a less than b floats", 2.5, 5.5, -1}, {"a greater than b floats", 10.5, 5.5, 1}, {"equal uints", uint(5), uint(5), 0}, {"different types", "abc", 123, 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := CompareValues(tt.a, tt.b) if got != tt.want { t.Errorf("CompareValues(%v, %v) = %v, want %v", tt.a, tt.b, got, tt.want) } }) } } func TestGetNestedValue(t *testing.T) { nested := map[string]interface{}{ "level1": map[string]interface{}{ "level2": map[string]interface{}{ "value": "deep", }, }, } ts := testStruct{ Name: "John", Nested: &nestedStruct{ Value: "nested value", Count: 42, }, } tests := []struct { name string input interface{} path string want interface{} }{ {"empty path", nested, "", nested}, {"single level map", nested, "level1", nested["level1"]}, {"nested map", nested, "level1.level2", map[string]interface{}{"value": "deep"}}, {"deep nested map", nested, "level1.level2.value", "deep"}, {"struct field", ts, "Name", "John"}, {"nested struct field", ts, "Nested", ts.Nested}, {"non-existent path", nested, "missing.path", nil}, {"nil input", nil, "path", nil}, {"partial missing path", nested, "level1.missing", nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := GetNestedValue(tt.input, tt.path) if !reflect.DeepEqual(got, tt.want) { t.Errorf("GetNestedValue() = %v, want %v", got, tt.want) } }) } } func TestDeepEqual(t *testing.T) { tests := []struct { name string a interface{} b interface{} want bool }{ {"equal ints", 42, 42, true}, {"different ints", 42, 43, false}, {"equal strings", "test", "test", true}, {"different strings", "test", "other", false}, {"equal slices", []int{1, 2, 3}, []int{1, 2, 3}, true}, {"different slices", []int{1, 2, 3}, []int{1, 2, 4}, false}, {"equal maps", map[string]int{"a": 1}, map[string]int{"a": 1}, true}, {"different maps", map[string]int{"a": 1}, map[string]int{"a": 2}, false}, {"both nil", nil, nil, true}, {"one nil", nil, 42, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := DeepEqual(tt.a, tt.b) if got != tt.want { t.Errorf("DeepEqual(%v, %v) = %v, want %v", tt.a, tt.b, got, tt.want) } }) } } // Helper functions func ptrInt(i int) *int { return &i } func ptrPtr(p *int) **int { return &p }