package util import ( "testing" "github.com/stretchr/testify/assert" ) func TestIsInterfaceNil(t *testing.T) { testCases := []struct { name string value interface{} expected bool }{ // True nil cases {"true nil interface", nil, true}, {"nil pointer", (*int)(nil), true}, {"nil slice", ([]int)(nil), true}, {"nil map", (map[string]int)(nil), true}, {"nil function", (func())(nil), true}, {"nil interface wrapped in interface", (interface{})(nil), true}, // Channels are not handled by IsInterfaceNil (not in switch statement) {"nil channel - not handled", (chan int)(nil), false}, // Non-nil cases {"non-nil pointer", func() interface{} { val := 42; return &val }(), false}, {"non-nil slice", []int{1, 2, 3}, false}, {"empty slice", []int{}, false}, {"non-nil map", map[string]int{"key": 1}, false}, {"empty map", make(map[string]int), false}, {"non-nil function", func() {}, false}, {"non-nil channel", make(chan int), false}, // Basic value types {"string value", "hello", false}, {"empty string", "", false}, {"int value", 42, false}, {"zero int", 0, false}, {"bool true", true, false}, {"bool false", false, false}, {"float64", 3.14, false}, {"complex128", complex(1, 2), false}, // Composite value types {"struct value", struct{ x int }{x: 1}, false}, {"array value", [3]int{1, 2, 3}, false}, {"zero array", [3]int{}, false}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result := IsInterfaceNil(tc.value) assert.Equal(t, tc.expected, result, "IsInterfaceNil(%v) should return %t", tc.value, tc.expected) }) } } func TestIsInterfaceNil_NestedInterfaces(t *testing.T) { testCases := []struct { name string value interface{} expected bool }{ { name: "nested interface with nil", value: func() interface{} { var inner *int = nil var middle interface{} = inner return middle }(), expected: true, }, { name: "nested interface with value", value: func() interface{} { val := 42 inner := &val var middle interface{} = inner return middle }(), expected: false, }, { name: "interface containing interface with value", value: func() interface{} { var inner interface{} = 42 outer := inner return outer }(), expected: false, }, { name: "interface containing nil interface", value: func() interface{} { var inner interface{} = nil outer := inner return outer }(), expected: true, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result := IsInterfaceNil(tc.value) assert.Equal(t, tc.expected, result) }) } } func TestIsInterfaceNil_ReflectKinds(t *testing.T) { t.Run("handles specific nilable reflect kinds", func(t *testing.T) { // Test the specific nilable kinds that the function handles // according to its switch statement: Ptr, Slice, Map, Func, Interface nilableTestCases := []struct { name string value interface{} }{ {"nil pointer", (*int)(nil)}, {"nil slice", ([]int)(nil)}, {"nil map", (map[string]int)(nil)}, {"nil function", (func())(nil)}, {"nil interface", (interface{})(nil)}, } for _, tc := range nilableTestCases { t.Run(tc.name, func(t *testing.T) { assert.True(t, IsInterfaceNil(tc.value), "%s should be detected as nil", tc.name) }) } }) t.Run("does not handle channels and other nilable types", func(t *testing.T) { // Test that nilable kinds NOT in the switch statement return false unhandledTestCases := []struct { name string value interface{} }{ {"nil channel", (chan int)(nil)}, // UnsafePointer would be another example, but harder to test } for _, tc := range unhandledTestCases { t.Run(tc.name, func(t *testing.T) { assert.False(t, IsInterfaceNil(tc.value), "%s should not be detected as nil (unhandled type)", tc.name) }) } }) t.Run("handles non-nilable kinds", func(t *testing.T) { // Test kinds that cannot be nil nonNilableTestCases := []struct { name string value interface{} }{ {"int", 42}, {"string", "test"}, {"bool", true}, {"struct", struct{ x int }{x: 1}}, {"array", [3]int{1, 2, 3}}, {"float64", 3.14}, {"complex128", complex(1, 2)}, } for _, tc := range nonNilableTestCases { t.Run(tc.name, func(t *testing.T) { assert.False(t, IsInterfaceNil(tc.value), "%s should not be detected as nil (non-nilable)", tc.name) }) } }) }