diff --git a/fxhealthcheck/reflect.go b/fxhealthcheck/reflect.go index d6d18802..1f824108 100644 --- a/fxhealthcheck/reflect.go +++ b/fxhealthcheck/reflect.go @@ -4,12 +4,39 @@ import ( "reflect" ) -// GetType returns the type of a target. +// fullTypeID builds a stable identifier for a type in the form ".". +func fullTypeID(t reflect.Type) string { + if t == nil { + return "" + } + + // Unwrap pointers to get the underlying named type (if any). + for t.Kind() == reflect.Pointer { + t = t.Elem() + } + + // For named types, PkgPath() + Name() gives a unique and stable identity. + if t.Name() != "" && t.PkgPath() != "" { + return t.PkgPath() + "." + t.Name() + } + + // Fallback for non-named kinds (slices, maps, func, etc.). + return t.String() +} + +// GetType returns a stable identifier for the given target’s type. func GetType(target any) string { - return reflect.TypeOf(target).String() + return fullTypeID(reflect.TypeOf(target)) } -// GetReturnType returns the return type of a target. +// GetReturnType returns a stable identifier for the return type of constructor-like target. +// If a target is a function, we examine its first return value (index 0), unwrap pointers, and +// build an identifier for that named type. For non-function or empty-return cases, we return "". func GetReturnType(target any) string { - return reflect.TypeOf(target).Out(0).String() + t := reflect.TypeOf(target) + if t == nil || t.Kind() != reflect.Func || t.NumOut() == 0 { + return "" + } + + return fullTypeID(t.Out(0)) } diff --git a/fxhealthcheck/reflect_test.go b/fxhealthcheck/reflect_test.go index 3c2ca639..0882c4b7 100644 --- a/fxhealthcheck/reflect_test.go +++ b/fxhealthcheck/reflect_test.go @@ -15,10 +15,11 @@ func TestGetType(t *testing.T) { target any expected string }{ + {nil, ""}, {123, "int"}, {"test", "string"}, - {probes.NewSuccessProbe(), "*probes.SuccessProbe"}, - {probes.NewFailureProbe(), "*probes.FailureProbe"}, + {probes.NewSuccessProbe(), "github.com/ankorstore/yokai/fxhealthcheck/testdata/probes.SuccessProbe"}, + {probes.NewFailureProbe(), "github.com/ankorstore/yokai/fxhealthcheck/testdata/probes.FailureProbe"}, } for _, tt := range tests { @@ -40,6 +41,7 @@ func TestGetReturnType(t *testing.T) { target any expected string }{ + {nil, ""}, {func() string { return "test" }, "string"}, {func() int { return 123 }, "int"}, } diff --git a/fxhealthcheck/registry_test.go b/fxhealthcheck/registry_test.go index 1a5b8a8d..4205676e 100644 --- a/fxhealthcheck/registry_test.go +++ b/fxhealthcheck/registry_test.go @@ -30,8 +30,8 @@ func TestResolveCheckerProbesRegistrationsSuccess(t *testing.T) { probes.NewFailureProbe(), }, Definitions: []fxhealthcheck.CheckerProbeDefinition{ - fxhealthcheck.NewCheckerProbeDefinition("*probes.SuccessProbe", healthcheck.Liveness), - fxhealthcheck.NewCheckerProbeDefinition("*probes.FailureProbe", healthcheck.Readiness), + fxhealthcheck.NewCheckerProbeDefinition("github.com/ankorstore/yokai/fxhealthcheck/testdata/probes.SuccessProbe", healthcheck.Liveness), + fxhealthcheck.NewCheckerProbeDefinition("github.com/ankorstore/yokai/fxhealthcheck/testdata/probes.FailureProbe", healthcheck.Readiness), }, }