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 }