Repository: open-feature/go-sdk
Pull request #84 (2022-09-29 16:40:44)

feat!: changed client details signatures to return new type
Signed-off-by: Skye Gill <gill.skye95@gmail.com>


Patch:
diff --git a/pkg/openfeature/client.go b/pkg/openfeature/client.go
index 65328bb..8b77192 100644
--- a/pkg/openfeature/client.go
+++ b/pkg/openfeature/client.go
@@ -19,11 +19,11 @@ type IClient interface {
 	FloatValue(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (float64, error)
 	IntValue(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (int64, error)
 	ObjectValue(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (interface{}, error)
-	BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-	StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-	FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-	IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-	ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
+	BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (BooleanEvaluationDetails, error)
+	StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (StringEvaluationDetails, error)
+	FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (FloatEvaluationDetails, error)
+	IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (IntEvaluationDetails, error)
+	ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (InterfaceEvaluationDetails, error)
 }
 
 // ClientMetadata provides a client's metadata
@@ -110,10 +110,34 @@ var typeToString = map[Type]string{
 type EvaluationDetails struct {
 	FlagKey  string
 	FlagType Type
-	Value    interface{}
 	ResolutionDetail
 }
 
+type BooleanEvaluationDetails struct {
+	Value bool
+	EvaluationDetails
+}
+
+type StringEvaluationDetails struct {
+	Value string
+	EvaluationDetails
+}
+
+type FloatEvaluationDetails struct {
+	Value float64
+	EvaluationDetails
+}
+
+type IntEvaluationDetails struct {
+	Value int64
+	EvaluationDetails
+}
+
+type InterfaceEvaluationDetails struct {
+	Value interface{}
+	EvaluationDetails
+}
+
 type ResolutionDetail struct {
 	Variant      string
 	Reason       Reason
@@ -292,13 +316,41 @@ func (c Client) ObjectValue(ctx context.Context, flag string, defaultValue inter
 // - defaultValue is returned if an error occurs
 // - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
 // - options are optional additional evaluation options e.g. WithHooks & WithHookHints
-func (c Client) BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error) {
+func (c Client) BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (BooleanEvaluationDetails, error) {
 	evalOptions := &EvaluationOptions{}
 	for _, option := range options {
 		option(evalOptions)
 	}
 
-	return c.evaluate(ctx, flag, Boolean, defaultValue, evalCtx, *evalOptions)
+	evalDetails, err := c.evaluate(ctx, flag, Boolean, defaultValue, evalCtx, *evalOptions)
+	if err != nil {
+		return BooleanEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}, err
+	}
+
+	value, ok := evalDetails.Value.(bool)
+	if !ok {
+		err := errors.New("evaluated value is not a boolean")
+		c.logger().Error(
+			err, "invalid flag resolution type", "expectedType", "boolean",
+			"gotType", fmt.Sprintf("%T", evalDetails.Value),
+		)
+		boolEvalDetails := BooleanEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}
+		boolEvalDetails.EvaluationDetails.ErrorCode = TypeMismatchCode
+		boolEvalDetails.EvaluationDetails.ErrorMessage = err.Error()
+
+		return boolEvalDetails, err
+	}
+
+	return BooleanEvaluationDetails{
+		Value:             value,
+		EvaluationDetails: evalDetails.EvaluationDetails,
+	}, nil
 }
 
 // StringValueDetails performs a flag evaluation that returns an evaluation details struct.
@@ -309,13 +361,41 @@ func (c Client) BooleanValueDetails(ctx context.Context, flag string, defaultVal
 // - defaultValue is returned if an error occurs
 // - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
 // - options are optional additional evaluation options e.g. WithHooks & WithHookHints
-func (c Client) StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error) {
+func (c Client) StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (StringEvaluationDetails, error) {
 	evalOptions := &EvaluationOptions{}
 	for _, option := range options {
 		option(evalOptions)
 	}
 
-	return c.evaluate(ctx, flag, String, defaultValue, evalCtx, *evalOptions)
+	evalDetails, err := c.evaluate(ctx, flag, String, defaultValue, evalCtx, *evalOptions)
+	if err != nil {
+		return StringEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}, err
+	}
+
+	value, ok := evalDetails.Value.(string)
+	if !ok {
+		err := errors.New("evaluated value is not a string")
+		c.logger().Error(
+			err, "invalid flag resolution type", "expectedType", "string",
+			"gotType", fmt.Sprintf("%T", evalDetails.Value),
+		)
+		strEvalDetails := StringEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}
+		strEvalDetails.EvaluationDetails.ErrorCode = TypeMismatchCode
+		strEvalDetails.EvaluationDetails.ErrorMessage = err.Error()
+
+		return strEvalDetails, err
+	}
+
+	return StringEvaluationDetails{
+		Value:             value,
+		EvaluationDetails: evalDetails.EvaluationDetails,
+	}, nil
 }
 
 // FloatValueDetails performs a flag evaluation that returns an evaluation details struct.
@@ -326,13 +406,41 @@ func (c Client) StringValueDetails(ctx context.Context, flag string, defaultValu
 // - defaultValue is returned if an error occurs
 // - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
 // - options are optional additional evaluation options e.g. WithHooks & WithHookHints
-func (c Client) FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error) {
+func (c Client) FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (FloatEvaluationDetails, error) {
 	evalOptions := &EvaluationOptions{}
 	for _, option := range options {
 		option(evalOptions)
 	}
 
-	return c.evaluate(ctx, flag, Float, defaultValue, evalCtx, *evalOptions)
+	evalDetails, err := c.evaluate(ctx, flag, Float, defaultValue, evalCtx, *evalOptions)
+	if err != nil {
+		return FloatEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}, err
+	}
+
+	value, ok := evalDetails.Value.(float64)
+	if !ok {
+		err := errors.New("evaluated value is not a float64")
+		c.logger().Error(
+			err, "invalid flag resolution type", "expectedType", "float64",
+			"gotType", fmt.Sprintf("%T", evalDetails.Value),
+		)
+		floatEvalDetails := FloatEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}
+		floatEvalDetails.EvaluationDetails.ErrorCode = TypeMismatchCode
+		floatEvalDetails.EvaluationDetails.ErrorMessage = err.Error()
+
+		return floatEvalDetails, err
+	}
+
+	return FloatEvaluationDetails{
+		Value:             value,
+		EvaluationDetails: evalDetails.EvaluationDetails,
+	}, nil
 }
 
 // IntValueDetails performs a flag evaluation that returns an evaluation details struct.
@@ -343,13 +451,41 @@ func (c Client) FloatValueDetails(ctx context.Context, flag string, defaultValue
 // - defaultValue is returned if an error occurs
 // - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
 // - options are optional additional evaluation options e.g. WithHooks & WithHookHints
-func (c Client) IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error) {
+func (c Client) IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (IntEvaluationDetails, error) {
 	evalOptions := &EvaluationOptions{}
 	for _, option := range options {
 		option(evalOptions)
 	}
 
-	return c.evaluate(ctx, flag, Int, defaultValue, evalCtx, *evalOptions)
+	evalDetails, err := c.evaluate(ctx, flag, Int, defaultValue, evalCtx, *evalOptions)
+	if err != nil {
+		return IntEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}, err
+	}
+
+	value, ok := evalDetails.Value.(int64)
+	if !ok {
+		err := errors.New("evaluated value is not an int64")
+		c.logger().Error(
+			err, "invalid flag resolution type", "expectedType", "int64",
+			"gotType", fmt.Sprintf("%T", evalDetails.Value),
+		)
+		intEvalDetails := IntEvaluationDetails{
+			Value:             defaultValue,
+			EvaluationDetails: evalDetails.EvaluationDetails,
+		}
+		intEvalDetails.EvaluationDetails.ErrorCode = TypeMismatchCode
+		intEvalDetails.EvaluationDetails.ErrorMessage = err.Error()
+
+		return intEvalDetails, err
+	}
+
+	return IntEvaluationDetails{
+		Value:             value,
+		EvaluationDetails: evalDetails.EvaluationDetails,
+	}, nil
 }
 
 // ObjectValueDetails performs a flag evaluation that returns an evaluation details struct.
@@ -360,7 +496,7 @@ func (c Client) IntValueDetails(ctx context.Context, flag string, defaultValue i
 // - defaultValue is returned if an error occurs
 // - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
 // - options are optional additional evaluation options e.g. WithHooks & WithHookHints
-func (c Client) ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error) {
+func (c Client) ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (InterfaceEvaluationDetails, error) {
 	evalOptions := &EvaluationOptions{}
 	for _, option := range options {
 		option(evalOptions)
@@ -371,7 +507,7 @@ func (c Client) ObjectValueDetails(ctx context.Context, flag string, defaultValu
 
 func (c Client) evaluate(
 	ctx context.Context, flag string, flagType Type, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions,
-) (EvaluationDetails, error) {
+) (InterfaceEvaluationDetails, error) {
 	c.logger().V(debug).Info(
 		"evaluating flag", "flag", flag, "type", flagType.String(), "defaultValue", defaultValue,
 		"evaluationContext", evalCtx, "evaluationOptions", options,
@@ -387,10 +523,12 @@ func (c Client) evaluate(
 		providerMetadata:  api.provider.Metadata(),
 		evaluationContext: evalCtx,
 	}
-	evalDetails := EvaluationDetails{
-		FlagKey:  flag,
-		FlagType: flagType,
-		Value:    defaultValue,
+	evalDetails := InterfaceEvaluationDetails{
+		Value: defaultValue,
+		EvaluationDetails: EvaluationDetails{
+			FlagKey:  flag,
+			FlagType: flagType,
+		},
 	}
 
 	apiClientInvocationProviderHooks := append(append(append(api.hooks, c.hooks...), options.hooks...), api.provider.Hooks()...) // API, Client, Invocation, Provider
@@ -500,7 +638,7 @@ func (c Client) beforeHooks(
 }
 
 func (c Client) afterHooks(
-	hookCtx HookContext, hooks []Hook, evalDetails EvaluationDetails, options EvaluationOptions,
+	hookCtx HookContext, hooks []Hook, evalDetails InterfaceEvaluationDetails, options EvaluationOptions,
 ) error {
 	c.logger().V(debug).Info("executing after hooks")
 	defer c.logger().V(debug).Info("executed after hooks")
diff --git a/pkg/openfeature/hooks.go b/pkg/openfeature/hooks.go
index b934863..d0e5c4e 100644
--- a/pkg/openfeature/hooks.go
+++ b/pkg/openfeature/hooks.go
@@ -5,7 +5,7 @@ package openfeature
 // https://github.com/open-feature/spec/blob/main/specification/hooks.md
 type Hook interface {
 	Before(hookContext HookContext, hookHints HookHints) (*EvaluationContext, error)
-	After(hookContext HookContext, flagEvaluationDetails EvaluationDetails, hookHints HookHints) error
+	After(hookContext HookContext, flagEvaluationDetails InterfaceEvaluationDetails, hookHints HookHints) error
 	Error(hookContext HookContext, err error, hookHints HookHints)
 	Finally(hookContext HookContext, hookHints HookHints)
 }
@@ -81,7 +81,7 @@ func (u UnimplementedHook) Before(hookContext HookContext, hookHints HookHints)
 	return nil, nil
 }
 
-func (u UnimplementedHook) After(hookContext HookContext, flagEvaluationDetails EvaluationDetails, hookHints HookHints) error {
+func (u UnimplementedHook) After(hookContext HookContext, flagEvaluationDetails InterfaceEvaluationDetails, hookHints HookHints) error {
 	return nil
 }
 
diff --git a/pkg/openfeature/resolution_error.go b/pkg/openfeature/resolution_error.go
index 612ae52..a0d5b0d 100644
--- a/pkg/openfeature/resolution_error.go
+++ b/pkg/openfeature/resolution_error.go
@@ -27,6 +27,10 @@ type ResolutionError struct {
 	message string
 }
 
+func (r ResolutionError) Error() string {
+	return string(r.code)
+}
+
 // NewProviderNotReadyResolutionError constructs a resolution error with code PROVIDER_NOT_READY
 //
 // Explanation - The value was resolved before the provider was ready.


Test patch:
diff --git a/pkg/openfeature/client_test.go b/pkg/openfeature/client_test.go
index 81f385d..899fe72 100644
--- a/pkg/openfeature/client_test.go
+++ b/pkg/openfeature/client_test.go
@@ -82,11 +82,11 @@ func TestRequirement_1_4_1(t *testing.T) {
 	client := NewClient("test-client")
 
 	type requirements interface {
-		BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-		StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-		FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-		IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-		ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
+		BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (BooleanEvaluationDetails, error)
+		StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (StringEvaluationDetails, error)
+		FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (FloatEvaluationDetails, error)
+		IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (IntEvaluationDetails, error)
+		ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (InterfaceEvaluationDetails, error)
 	}
 
 	var clientI interface{} = client
@@ -298,7 +298,7 @@ func TestRequirement_1_4_9(t *testing.T) {
 			t.Error("expected BooleanValueDetails to return an error, got nil")
 		}
 
-		if valueDetails.Value.(bool) != defaultValue {
+		if valueDetails.Value != defaultValue {
 			t.Errorf("expected default value from BooleanValueDetails, got %v", value)
 		}
 	})
@@ -332,7 +332,7 @@ func TestRequirement_1_4_9(t *testing.T) {
 			t.Error("expected StringValueDetails to return an error, got nil")
 		}
 
-		if valueDetails.Value.(string) != defaultValue {
+		if valueDetails.Value != defaultValue {
 			t.Errorf("expected default value from StringValueDetails, got %v", value)
 		}
 	})
@@ -366,7 +366,7 @@ func TestRequirement_1_4_9(t *testing.T) {
 			t.Error("expected FloatValueDetails to return an error, got nil")
 		}
 
-		if valueDetails.Value.(float64) != defaultValue {
+		if valueDetails.Value != defaultValue {
 			t.Errorf("expected default value from FloatValueDetails, got %v", value)
 		}
 	})
@@ -400,7 +400,7 @@ func TestRequirement_1_4_9(t *testing.T) {
 			t.Error("expected FloatValueDetails to return an error, got nil")
 		}
 
-		if valueDetails.Value.(int64) != defaultValue {
+		if valueDetails.Value != defaultValue {
 			t.Errorf("expected default value from IntValueDetails, got %v", value)
 		}
 	})
diff --git a/pkg/openfeature/evaluation_context_test.go b/pkg/openfeature/evaluation_context_test.go
index af6a3b8..4617314 100644
--- a/pkg/openfeature/evaluation_context_test.go
+++ b/pkg/openfeature/evaluation_context_test.go
@@ -69,11 +69,11 @@ func TestRequirement_3_2_1(t *testing.T) {
 			FloatValue(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (float64, error)
 			IntValue(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (int64, error)
 			ObjectValue(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (interface{}, error)
-			BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
+			BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (BooleanEvaluationDetails, error)
+			StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (StringEvaluationDetails, error)
+			FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (FloatEvaluationDetails, error)
+			IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (IntEvaluationDetails, error)
+			ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (InterfaceEvaluationDetails, error)
 		}
 
 		var clientI interface{} = client
diff --git a/pkg/openfeature/hooks_mock_test.go b/pkg/openfeature/hooks_mock_test.go
index 2fcef1f..cddee6f 100644
--- a/pkg/openfeature/hooks_mock_test.go
+++ b/pkg/openfeature/hooks_mock_test.go
@@ -34,7 +34,7 @@ func (m *MockHook) EXPECT() *MockHookMockRecorder {
 }
 
 // After mocks base method.
-func (m *MockHook) After(hookContext HookContext, flagEvaluationDetails EvaluationDetails, hookHints HookHints) error {
+func (m *MockHook) After(hookContext HookContext, flagEvaluationDetails InterfaceEvaluationDetails, hookHints HookHints) error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "After", hookContext, flagEvaluationDetails, hookHints)
 	ret0, _ := ret[0].(error)
diff --git a/pkg/openfeature/hooks_test.go b/pkg/openfeature/hooks_test.go
index c65c62e..866fda6 100644
--- a/pkg/openfeature/hooks_test.go
+++ b/pkg/openfeature/hooks_test.go
@@ -345,7 +345,7 @@ func TestRequirement_4_3_5(t *testing.T) {
 		mockHook := NewMockHook(ctrl)
 
 		type requirement interface {
-			After(hookContext HookContext, flagEvaluationDetails EvaluationDetails, hookHints HookHints) error
+			After(hookContext HookContext, flagEvaluationDetails InterfaceEvaluationDetails, hookHints HookHints) error
 		}
 
 		var hookI interface{} = mockHook
@@ -566,11 +566,11 @@ func TestRequirement_4_4_1(t *testing.T) {
 			FloatValue(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (float64, error)
 			IntValue(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (int64, error)
 			ObjectValue(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (interface{}, error)
-			BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
-			ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (EvaluationDetails, error)
+			BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options ...Option) (BooleanEvaluationDetails, error)
+			StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options ...Option) (StringEvaluationDetails, error)
+			FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options ...Option) (FloatEvaluationDetails, error)
+			IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options ...Option) (IntEvaluationDetails, error)
+			ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options ...Option) (InterfaceEvaluationDetails, error)
 		}
 
 		var clientI interface{} = client
@@ -779,9 +779,8 @@ func TestRequirement_4_4_7(t *testing.T) {
 		t.Error("expected error, got nil")
 	}
 
-	resString := res.Value.(string)
-	if resString != defaultValue {
-		t.Errorf("expected default value, got %s", resString)
+	if res.Value != defaultValue {
+		t.Errorf("expected default value, got %s", res.Value)
 	}
 }