From 625a0bbeb3e0591f67f7c09897a11607c161a314 Mon Sep 17 00:00:00 2001 From: James Cox Date: Tue, 5 Apr 2022 11:11:46 +0100 Subject: [PATCH] FFM-2934 Bugfix - compare custom attributes based on string values --- evaluation/evaluator.go | 19 +++++++++- evaluation/util_test.go | 77 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/evaluation/evaluator.go b/evaluation/evaluator.go index 2a9ab690..d307dbca 100644 --- a/evaluation/evaluator.go +++ b/evaluation/evaluator.go @@ -3,6 +3,7 @@ package evaluation import ( "encoding/json" "fmt" + "reflect" "regexp" "sort" "strconv" @@ -83,7 +84,23 @@ func (e Evaluator) evaluateClause(clause *rest.Clause, target *Target) bool { return false } - object := attrValue.String() + object := "" + switch attrValue.Kind() { + case reflect.Int, reflect.Int64: + object = strconv.FormatInt(attrValue.Int(), 10) + case reflect.Bool: + object = strconv.FormatBool(attrValue.Bool()) + case reflect.String: + object = attrValue.String() + case reflect.Array, reflect.Chan, reflect.Complex128, reflect.Complex64, reflect.Func, reflect.Interface, + reflect.Invalid, reflect.Ptr, reflect.Slice, reflect.Struct, reflect.Uintptr, reflect.UnsafePointer, + reflect.Float32, reflect.Float64, reflect.Int16, reflect.Int32, reflect.Int8, reflect.Map, reflect.Uint, + reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8: + object = fmt.Sprintf("%v", object) + default: + // Use string formatting as last ditch effort for any unexpected values + object = fmt.Sprintf("%v", object) + } switch operator { case startsWithOperator: diff --git a/evaluation/util_test.go b/evaluation/util_test.go index 0ef6dd20..429f3936 100644 --- a/evaluation/util_test.go +++ b/evaluation/util_test.go @@ -2,6 +2,7 @@ package evaluation import ( "reflect" + "strconv" "testing" "github.com/harness/ff-golang-server-sdk/rest" @@ -54,9 +55,10 @@ func Test_getAttrValue(t *testing.T) { attr string } tests := []struct { - name string - args args - want reflect.Value + name string + args args + want reflect.Value + wantStr string }{ { name: "check identifier", @@ -66,7 +68,8 @@ func Test_getAttrValue(t *testing.T) { }, attr: identifier, }, - want: reflect.ValueOf(harness), + want: reflect.ValueOf(harness), + wantStr: "harness", }, { name: "check name", @@ -76,7 +79,8 @@ func Test_getAttrValue(t *testing.T) { }, attr: "name", }, - want: reflect.ValueOf(harness), + want: reflect.ValueOf(harness), + wantStr: "harness", }, { name: "check attributes", @@ -89,14 +93,73 @@ func Test_getAttrValue(t *testing.T) { }, attr: "email", }, - want: reflect.ValueOf(email), + want: reflect.ValueOf(email), + wantStr: email, + }, + { + name: "check integer attributes", + args: args{ + target: &Target{ + Identifier: identifier, + Attributes: &map[string]interface{}{ + "age": 123, + }, + }, + attr: "age", + }, + want: reflect.ValueOf(123), + wantStr: "123", + }, + { + name: "check int64 attributes", + args: args{ + target: &Target{ + Identifier: identifier, + Attributes: &map[string]interface{}{ + "age": int64(123), + }, + }, + attr: "age", + }, + want: reflect.ValueOf(int64(123)), + wantStr: "123", + }, + { + name: "check boolean attributes", + args: args{ + target: &Target{ + Identifier: identifier, + Attributes: &map[string]interface{}{ + "active": true, + }, + }, + attr: "active", + }, + want: reflect.ValueOf(true), + wantStr: "true", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getAttrValue(tt.args.target, tt.args.attr); !reflect.DeepEqual(got.Interface(), tt.want.Interface()) { + got := getAttrValue(tt.args.target, tt.args.attr) + if !reflect.DeepEqual(got.Interface(), tt.want.Interface()) { t.Errorf("getAttrValue() = %v, want %v", got, tt.want) } + + expObjString := "" + //nolint + switch got.Kind() { + case reflect.Int, reflect.Int64: + expObjString = strconv.FormatInt(got.Int(), 10) + case reflect.Bool: + expObjString = strconv.FormatBool(got.Bool()) + case reflect.String: + expObjString = got.String() + } + + if expObjString != tt.wantStr { + t.Errorf("getAttrValue() expObjString= %v, want %v", got.String(), tt.wantStr) + } }) } }