From 760aec1c188feff6e3d40573cb3cee966661b825 Mon Sep 17 00:00:00 2001 From: Vivek Patel Date: Wed, 2 Feb 2022 15:38:27 +0530 Subject: [PATCH] Update argument type of set expr function It changes 3rd argument type os set expr function from TypedValue to interface, since GvalParser parses argument to native types before evaluating the expression. --- pkg/expr/expr_types.go | 9 +++- pkg/expr/parser_test.go | 30 ++++++++++++-- pkg/expr/vars_test.go | 6 --- .../0016_set_expression_issue_test.go | 41 +++++++++++++++++++ .../S0016_set_expression_issue/workflow.yaml | 28 +++++++++++++ 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 tests/workflows/0016_set_expression_issue_test.go create mode 100644 tests/workflows/testdata/S0016_set_expression_issue/workflow.yaml diff --git a/pkg/expr/expr_types.go b/pkg/expr/expr_types.go index 670fccd3e..592f8baae 100644 --- a/pkg/expr/expr_types.go +++ b/pkg/expr/expr_types.go @@ -63,13 +63,18 @@ func ResolveTypes(rt resolvableType, resolver func(typ string) Type) error { return rt.ResolveTypes(resolver) } -func set(m merger, key string, val TypedValue) (out TypedValue, err error) { +func set(m merger, key string, val interface{}) (out TypedValue, err error) { out, err = m.Merge() if err != nil { return } - err = Assign(out, key, val) + v, err := Typify(val) + if err != nil { + return + } + + err = Assign(out, key, v) if err != nil { return } diff --git a/pkg/expr/parser_test.go b/pkg/expr/parser_test.go index b78b0c8f5..439d0918e 100644 --- a/pkg/expr/parser_test.go +++ b/pkg/expr/parser_test.go @@ -6,6 +6,12 @@ import ( "testing" ) +func Example_simpleExpression() { + eval(`40 + 2`, nil) + // output: + // 42 +} + func TestParser(t *testing.T) { var ( req = require.New(t) @@ -23,8 +29,24 @@ func TestParser(t *testing.T) { req.True(result) } -func Example_simpleExpresion() { - eval(`40 + 2`, nil) - // output: - // 42 +func TestGvalParser(t *testing.T) { + var ( + req = require.New(t) + ctx = context.Background() + p = NewGvalParser() + vv, err = NewVars(map[string]interface{}{ + "vars": &Vars{}, + "key": "foo", + "value": Must(NewString("foo")), + }) + result interface{} + ) + req.NoError(err) + + pp, err := p.Parse("toJSON(set(vars, key, value))") + req.NoError(err) + + result, err = pp.Eval(ctx, vv) + req.NoError(err) + req.Equal("{\"foo\":{\"@value\":\"foo\",\"@type\":\"String\"}}", result) } diff --git a/pkg/expr/vars_test.go b/pkg/expr/vars_test.go index 1b5d9cbd3..93c5ee7be 100644 --- a/pkg/expr/vars_test.go +++ b/pkg/expr/vars_test.go @@ -2,7 +2,6 @@ package expr import ( "encoding/json" - "fmt" "github.com/stretchr/testify/require" "testing" ) @@ -180,8 +179,6 @@ func TestVars_Assign(t *testing.T) { req.NoError(Assign(vars, "foo", &String{value: "foo"})) req.NoError(Assign(vars, "vars", &Vars{})) req.NoError(Assign(vars, "vars.foo", &String{value: "foo"})) - - fmt.Println("Vars: ", vars) } func TestVars_Set(t *testing.T) { @@ -195,7 +192,6 @@ func TestVars_Set(t *testing.T) { ) out, err := set(vars, "k1", &String{value: "v11"}) - fmt.Println("Out: ", out) req.NoError(err) req.Equal(&String{value: "v11"}, out.(*Vars).GetValue()["k1"]) @@ -223,9 +219,7 @@ func TestVars_MergeVars(t *testing.T) { }} ) - fmt.Println("vars: ", vars) out := vars.MustMerge(&foo, &bar) - fmt.Println("vars: ", out) req.Equal(expected, out) } diff --git a/tests/workflows/0016_set_expression_issue_test.go b/tests/workflows/0016_set_expression_issue_test.go new file mode 100644 index 000000000..9f45a8cbe --- /dev/null +++ b/tests/workflows/0016_set_expression_issue_test.go @@ -0,0 +1,41 @@ +package workflows + +import ( + "context" + "github.com/cortezaproject/corteza-server/pkg/expr" + "github.com/stretchr/testify/require" + "testing" + + "github.com/cortezaproject/corteza-server/automation/types" +) + +func Test0016_set_expression_issue(t *testing.T) { + var ( + ctx = bypassRBAC(context.Background()) + req = require.New(t) + ) + + loadScenario(ctx, t) + + t.Run("set expressions", func(t *testing.T) { + var ( + aux = struct{ Out map[string]expr.TypedValue }{} + vars, _ = mustExecWorkflow(ctx, t, "set_expression", types.WorkflowExecParams{}) + + testString = expr.Must(expr.NewString("testing string")) + testInt = expr.Must(expr.NewInteger(40)) + testVar = expr.Must(expr.NewVars(map[string]interface{}{ + "testString": testString, + "testFloat": expr.Must(expr.NewFloat(50)), + })) + expected = map[string]expr.TypedValue{ + "testString": testString, + "testInt": testInt, + "testVar": testVar, + } + ) + + req.NoError(vars.Decode(&aux)) + req.Equal(expected, aux.Out) + }) +} diff --git a/tests/workflows/testdata/S0016_set_expression_issue/workflow.yaml b/tests/workflows/testdata/S0016_set_expression_issue/workflow.yaml new file mode 100644 index 000000000..932ad63db --- /dev/null +++ b/tests/workflows/testdata/S0016_set_expression_issue/workflow.yaml @@ -0,0 +1,28 @@ +workflows: + set_expression: + enabled: true + trace: true + triggers: + - enabled: true + stepID: 1 + + steps: + - stepID: 1 + kind: expressions + arguments: [ + { target: aux, type: Vars, value: null }, + { target: testString, type: String, value: "testString" }, + { target: foo, type: String, value: "testing string" }, + { target: testInt, type: String, value: "testInt" }, + { target: bar, type: Integer, expr: "40" }, + { target: testVar, type: String, value: "testVar" }, + { target: foobar, type: Vars, expr: "{\"testString\": \"testing string\", \"testFloat\": 50}" }, + { target: out, type: Vars, expr: "set(aux, testString, foo)" }, + { target: out, type: Vars, expr: "set(out, testInt, bar)" }, + { target: out, type: Vars, expr: "set(out, testVar, foobar)" }, + ] + - stepID: 2 + kind: termination + + paths: + - { parentID: 1, childID: 2 }