| 40 | return "", err |
| 41 | } |
| 42 | } |
| 43 | return a.next, nil |
| 44 | } |
| 45 | |
| 46 | func TestFunction_Call(t *testing.T) { |
| 47 | t.Run("happy path: evaluates output expressions over function scope", func(t *testing.T) { |
| 48 | // Action stores arg "a" multiplied by 2 into a declared variable "result". |
| 49 | action := &fakeAction{ |
| 50 | id: "double", |
| 51 | next: StateIdle, |
| 52 | run: func(s *Scope) error { |
| 53 | v, err := s.Resolve(workflowapi.Reference{SrcId: SrcFnArg, VarId: "a"}) |
| 54 | if err != nil { |
| 55 | return err |
| 56 | } |
| 57 | s.Set(SrcDeclared, "result", expr.IntVal(v.AsInt()*2)) |
| 58 | return nil |
| 59 | }, |
| 60 | } |
| 61 | fn := &Function{ |
| 62 | Info: workflowapi.FunctionInfo{ |
| 63 | Name: "double", |
| 64 | Id: "fn1", |
| 65 | Arguments: []workflowapi.Variable{ |
| 66 | {Uid: "a", DataType: workflowapi.Int}, |
| 67 | }, |
| 68 | Returns: []workflowapi.Variable{ |
| 69 | {Uid: "ret", Name: "value", DataType: workflowapi.Int}, |
| 70 | }, |
| 71 | }, |
| 72 | DeclaredVars: []workflowapi.Variable{ |
| 73 | {Uid: "result", DataType: workflowapi.Int}, |
| 74 | }, |
| 75 | EntryTransition: Transition{TargetID: "double"}, |
| 76 | Executables: map[string]Executable{"double": action}, |
| 77 | OutputAssignments: map[string]workflowapi.Expression{ |
| 78 | "ret": { |
| 79 | Expression: "${}", |
| 80 | DataType: workflowapi.Int, |
| 81 | References: []workflowapi.Reference{{SrcId: SrcDeclared, VarId: "result"}}, |
| 82 | }, |
| 83 | }, |
| 84 | } |
| 85 | |
| 86 | out, err := fn.Call(context.Background(), map[string]expr.Value{"a": expr.IntVal(7)}) |
| 87 | require.NoError(t, err) |
| 88 | assert.Equal(t, expr.IntVal(14), out["ret"]) |
| 89 | }) |
| 90 | |
| 91 | t.Run("missing output assignment errors", func(t *testing.T) { |
| 92 | fn := &Function{ |
| 93 | Info: workflowapi.FunctionInfo{ |
| 94 | Name: "f", |
| 95 | Returns: []workflowapi.Variable{{Uid: "ret", Name: "value", DataType: workflowapi.Int}}, |
| 96 | }, |
| 97 | EntryTransition: Transition{TargetID: StateIdle}, |
| 98 | Executables: map[string]Executable{}, |
| 99 | OutputAssignments: map[string]workflowapi.Expression{}, // missing |