Rework/simplify expr.Vars handling
This commit is contained in:
@@ -24,14 +24,12 @@ func (i *sequenceIterator) more() bool {
|
||||
func (i *sequenceIterator) Start(context.Context, *Vars) error { return nil }
|
||||
|
||||
func (i *sequenceIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
scope := RVars{
|
||||
"counter": Must(NewInteger(i.counter)),
|
||||
"isFirst": Must(NewBoolean(i.counter == i.cFirst)),
|
||||
"isLast": Must(NewBoolean(!i.more())),
|
||||
}.Vars()
|
||||
|
||||
out := &Vars{}
|
||||
out.Set("counter", i.counter)
|
||||
out.Set("isFirst", i.counter == i.cFirst)
|
||||
out.Set("isLast", !i.more())
|
||||
i.counter = i.counter + i.cStep
|
||||
return scope, nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -66,19 +64,10 @@ func (i *collectionIterator) More(context.Context, *Vars) (bool, error) {
|
||||
func (i *collectionIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
|
||||
|
||||
func (i *collectionIterator) Next(context.Context, *Vars) (out *Vars, err error) {
|
||||
var item TypedValue
|
||||
switch c := i.set[i.ptr].(type) {
|
||||
case TypedValue:
|
||||
item = c
|
||||
default:
|
||||
if item, err = Typify(c); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
out = &Vars{}
|
||||
out.Set("line", i.set[i.ptr])
|
||||
i.ptr++
|
||||
|
||||
return RVars{"item": item}.Vars(), nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -101,6 +90,7 @@ func (i *lineIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return RVars{"line": Must(NewString(i.s.Text()))}.Vars(), nil
|
||||
|
||||
out := &Vars{}
|
||||
out.Set("line", i.s.Text())
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func (set ExprSet) Eval(ctx context.Context, in *expr.Vars) (*expr.Vars, error)
|
||||
scope = (&expr.Vars{}).Merge(in)
|
||||
|
||||
// Prepare output scope
|
||||
out = &expr.Vars{}
|
||||
out, _ = expr.NewVars(nil)
|
||||
|
||||
// Untyped evaluation result
|
||||
value interface{}
|
||||
|
||||
@@ -14,25 +14,25 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
cc = []struct {
|
||||
name string
|
||||
set ExprSet
|
||||
input RVars
|
||||
output RVars
|
||||
input map[string]interface{}
|
||||
output map[string]interface{}
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
set: ExprSet{},
|
||||
output: nil,
|
||||
output: make(map[string]interface{}),
|
||||
},
|
||||
{
|
||||
name: "constant assignment",
|
||||
set: ExprSet{&Expr{Target: "foo", Expr: `"bar"`}},
|
||||
output: RVars{"foo": Must(NewString("bar"))},
|
||||
output: map[string]interface{}{"foo": Must(NewString("bar"))},
|
||||
},
|
||||
{
|
||||
name: "vars with path",
|
||||
set: ExprSet{&Expr{Target: "l1.l2", Expr: `"bar"`}},
|
||||
input: RVars{"l1": RVars{}.Vars()},
|
||||
output: RVars{"l1": RVars{"l2": Must(Typify("bar"))}.Vars()},
|
||||
input: map[string]interface{}{"l1": map[string]interface{}{}},
|
||||
output: map[string]interface{}{"l1": map[string]interface{}{"l2": Must(Typify("bar"))}},
|
||||
},
|
||||
{
|
||||
name: "copy vars with same types",
|
||||
@@ -40,7 +40,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "aa", Value: "vv", typ: &String{}},
|
||||
&Expr{Target: "bb", Source: "aa", typ: &String{}},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"aa": Must(NewString("vv")),
|
||||
"bb": Must(NewString("vv")),
|
||||
},
|
||||
@@ -51,7 +51,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "aa", Value: "should be always String", typ: &String{}},
|
||||
&Expr{Target: "bb", Source: "aa"},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"aa": Must(NewString("should be always String")),
|
||||
"bb": Must(NewString("should be always String")),
|
||||
},
|
||||
@@ -62,7 +62,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "aa", Value: "42", typ: &String{}},
|
||||
&Expr{Target: "bb", Source: "aa", typ: &Integer{}},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"aa": Must(NewString("42")),
|
||||
"bb": Must(NewInteger(42)),
|
||||
},
|
||||
@@ -81,7 +81,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "a", typ: &KV{}},
|
||||
&Expr{Target: "a.b", Value: "c", typ: &String{}},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"a": Must(NewKV(map[string]string{
|
||||
"b": "c",
|
||||
})),
|
||||
@@ -93,7 +93,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "arr", typ: &Array{}, Expr: `[]`},
|
||||
&Expr{Target: "arr", typ: &Array{}, Expr: `push(arr, "foo")`},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"arr": Must(NewArray([]string{
|
||||
"foo",
|
||||
})),
|
||||
@@ -105,7 +105,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
&Expr{Target: "arr", typ: &Array{}, Expr: `[]`},
|
||||
&Expr{Target: "arr", typ: &Any{}, Expr: `push(arr, "foo")`},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"arr": Must(NewArray([]string{
|
||||
"foo",
|
||||
})),
|
||||
@@ -116,7 +116,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
set: ExprSet{
|
||||
&Expr{Target: "arr", typ: &Array{}, Expr: `push([], "foo")`},
|
||||
},
|
||||
output: RVars{
|
||||
output: map[string]interface{}{
|
||||
"arr": Must(NewArray([]TypedValue{
|
||||
Must(Typify("foo")),
|
||||
})),
|
||||
@@ -153,7 +153,7 @@ func TestExprSet_Eval(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
req.Equal(c.output.Vars(), output)
|
||||
req.Equal(Must(Typify(c.output)), output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,11 +77,11 @@ func TestRecordFieldValuesAccess(t *testing.T) {
|
||||
&types.RecordValue{Name: "ref2", Value: "", Ref: 2, Place: 0},
|
||||
}}
|
||||
|
||||
tval = &ComposeRecord{value: raw}
|
||||
scope = expr.RVars{
|
||||
tval = &ComposeRecord{value: raw}
|
||||
scope, _ = expr.NewVars(map[string]interface{}{
|
||||
"rec": tval,
|
||||
"nil": nil,
|
||||
}.Vars()
|
||||
})
|
||||
)
|
||||
|
||||
// @todo see not above re. back-ref to record
|
||||
@@ -121,6 +121,8 @@ func TestRecordFieldValuesAccess(t *testing.T) {
|
||||
expr string
|
||||
}{
|
||||
{false, `nil`},
|
||||
{true, `rec`},
|
||||
{true, `rec.values`},
|
||||
|
||||
// interaction with set values
|
||||
{true, `rec.values.s1 == "sVal1"`},
|
||||
|
||||
@@ -318,12 +318,11 @@ func (i *recordSetIterator) More(context.Context, *Vars) (bool, error) {
|
||||
func (i *recordSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
|
||||
|
||||
func (i *recordSetIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
out := RVars{
|
||||
"record": Must(NewComposeRecord(i.set[i.ptr])),
|
||||
"index": Must(NewUnsignedInteger(i.ptr)),
|
||||
"total": Must(NewUnsignedInteger(i.filter.Total)),
|
||||
}
|
||||
out := &Vars{}
|
||||
out.Set("record", Must(NewComposeRecord(i.set[i.ptr])))
|
||||
out.Set("index", i.ptr)
|
||||
out.Set("total", i.filter.Total)
|
||||
|
||||
i.ptr++
|
||||
return out.Vars(), nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -425,14 +425,14 @@ func (res composeBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res composeBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res composeBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -849,26 +849,38 @@ func (res moduleBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res moduleBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res moduleBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["module"], err = automation.NewComposeModule(res.module); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeModule(res.module); err == nil {
|
||||
err = out.Set("module", v)
|
||||
}
|
||||
|
||||
if rvars["oldModule"], err = automation.NewComposeModule(res.oldModule); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rvars["namespace"], err = automation.NewComposeNamespace(res.namespace); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeModule(res.oldModule); err == nil {
|
||||
err = out.Set("oldModule", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewComposeNamespace(res.namespace); err == nil {
|
||||
err = out.Set("namespace", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -1277,22 +1289,30 @@ func (res namespaceBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res namespaceBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res namespaceBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["namespace"], err = automation.NewComposeNamespace(res.namespace); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeNamespace(res.namespace); err == nil {
|
||||
err = out.Set("namespace", v)
|
||||
}
|
||||
|
||||
if rvars["oldNamespace"], err = automation.NewComposeNamespace(res.oldNamespace); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewComposeNamespace(res.oldNamespace); err == nil {
|
||||
err = out.Set("oldNamespace", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -1737,22 +1757,26 @@ func (res pageBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res pageBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res pageBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for *types.Page
|
||||
|
||||
// Could not found expression-type counterpart for *types.Page
|
||||
|
||||
if rvars["namespace"], err = automation.NewComposeNamespace(res.namespace); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeNamespace(res.namespace); err == nil {
|
||||
err = out.Set("namespace", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -2330,34 +2354,54 @@ func (res recordBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res recordBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res recordBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["record"], err = automation.NewComposeRecord(res.record); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeRecord(res.record); err == nil {
|
||||
err = out.Set("record", v)
|
||||
}
|
||||
|
||||
if rvars["oldRecord"], err = automation.NewComposeRecord(res.oldRecord); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rvars["module"], err = automation.NewComposeModule(res.module); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeRecord(res.oldRecord); err == nil {
|
||||
err = out.Set("oldRecord", v)
|
||||
}
|
||||
|
||||
if rvars["namespace"], err = automation.NewComposeNamespace(res.namespace); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rvars["recordValueErrors"], err = automation.NewComposeRecordValueErrorSet(res.recordValueErrors); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewComposeModule(res.module); err == nil {
|
||||
err = out.Set("module", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewComposeNamespace(res.namespace); err == nil {
|
||||
err = out.Set("namespace", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewComposeRecordValueErrorSet(res.recordValueErrors); err == nil {
|
||||
err = out.Set("recordValueErrors", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
|
||||
@@ -147,25 +147,27 @@ func (res {{ camelCase .ResourceIdent "base" }}) Encode() (args map[string][]byt
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res {{ camelCase .ResourceIdent "base" }}) EncodeVars() (vars *expr.Vars, err error) {
|
||||
func (res {{ camelCase .ResourceIdent "base" }}) EncodeVars() (out *expr.Vars, err error) {
|
||||
{{- if $r.Properties }}
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
{{ range $r.Properties }}
|
||||
{{- if .ExprType }}
|
||||
if rvars[{{ printf "%q" .Name }}], err = automation.{{ export "new" .ExprType }}(res.{{ .Name }}); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.{{ export "new" .ExprType }}(res.{{ .Name }}); err == nil {
|
||||
err = out.Set({{ printf "%q" .Name }},v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
{{- else }}
|
||||
// Could not found expression-type counterpart for {{ .Type }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
return rvars.Vars(), err
|
||||
{{ else }}
|
||||
return
|
||||
{{ end -}}
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
|
||||
+10
-10
@@ -39,19 +39,19 @@ func TestVars(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
|
||||
vars = RVars{
|
||||
vars = Must(Typify(map[string]interface{}{
|
||||
"int": Must(NewInteger(42)),
|
||||
"sub": RVars{
|
||||
"sub": map[string]interface{}{
|
||||
"foo": Must(NewString("foo")),
|
||||
}.Vars(),
|
||||
"three": RVars{
|
||||
"two": RVars{
|
||||
"one": RVars{
|
||||
},
|
||||
"three": map[string]interface{}{
|
||||
"two": map[string]interface{}{
|
||||
"one": map[string]interface{}{
|
||||
"go": Must(NewString("!")),
|
||||
}.Vars(),
|
||||
}.Vars(),
|
||||
}.Vars(),
|
||||
}.Vars()
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
tv = func(in interface{}) TypedValue {
|
||||
switch cnv := in.(type) {
|
||||
|
||||
@@ -550,8 +550,12 @@ func (t *UnsignedInteger) Assign(val interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Vars is an expression type, wrapper for RVars type
|
||||
type Vars struct{ value RVars }
|
||||
// Vars is an expression type, wrapper for map[string]TypedValue type
|
||||
type Vars struct{ value map[string]TypedValue }
|
||||
|
||||
func EmptyVars() *Vars {
|
||||
return &Vars{make(map[string]TypedValue)}
|
||||
}
|
||||
|
||||
// NewVars creates new instance of Vars expression type
|
||||
func NewVars(val interface{}) (*Vars, error) {
|
||||
@@ -566,12 +570,12 @@ func NewVars(val interface{}) (*Vars, error) {
|
||||
func (t Vars) Get() interface{} { return t.value }
|
||||
|
||||
// Return underlying value on Vars
|
||||
func (t Vars) GetValue() RVars { return t.value }
|
||||
func (t Vars) GetValue() map[string]TypedValue { return t.value }
|
||||
|
||||
// Return type name
|
||||
func (Vars) Type() string { return "Vars" }
|
||||
|
||||
// Convert value to RVars
|
||||
// Convert value to map[string]TypedValue
|
||||
func (Vars) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewVars(val)
|
||||
}
|
||||
|
||||
+12
-3
@@ -24,6 +24,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func EmptyVars() *Vars {
|
||||
return &Vars{value: map[string]TypedValue{}}
|
||||
}
|
||||
|
||||
func ResolveTypes(rt resolvableType, resolver func(typ string) Type) error {
|
||||
return rt.ResolveTypes(resolver)
|
||||
}
|
||||
@@ -36,9 +40,6 @@ func Typify(in interface{}) (tv TypedValue, err error) {
|
||||
}
|
||||
|
||||
switch c := in.(type) {
|
||||
// @todo
|
||||
//case map[string]interface{}:
|
||||
// return NewVars()
|
||||
case []TypedValue:
|
||||
return &Array{value: c}, nil
|
||||
case bool:
|
||||
@@ -75,6 +76,14 @@ func Typify(in interface{}) (tv TypedValue, err error) {
|
||||
return &Duration{value: *c}, nil
|
||||
case time.Duration:
|
||||
return &Duration{value: c}, nil
|
||||
case map[string]interface{}:
|
||||
if v, err := CastToVars(c); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Vars{v}, nil
|
||||
}
|
||||
case map[string]TypedValue:
|
||||
return &Vars{c}, nil
|
||||
case map[string]string:
|
||||
return &KV{value: c}, nil
|
||||
case map[string][]string:
|
||||
|
||||
@@ -11,7 +11,7 @@ types:
|
||||
as: '[]TypedValue'
|
||||
|
||||
Vars:
|
||||
as: 'RVars'
|
||||
as: 'map[string]TypedValue'
|
||||
|
||||
Boolean:
|
||||
as: 'bool'
|
||||
|
||||
+15
-11
@@ -9,13 +9,13 @@ import (
|
||||
)
|
||||
|
||||
func TestTypedValueOperations(t *testing.T) {
|
||||
scope := RVars{
|
||||
"xUint": Must(NewUnsignedInteger(1)),
|
||||
"xInt": Must(NewInteger(1)),
|
||||
"xBoolT": Must(NewBoolean(true)),
|
||||
"xBoolF": Must(NewBoolean(false)),
|
||||
"xString": Must(NewString("foo")),
|
||||
}.Vars()
|
||||
scope, _ := NewVars(map[string]interface{}{
|
||||
"xUint": uint(1),
|
||||
"xInt": 1,
|
||||
"xBoolT": true,
|
||||
"xBoolF": false,
|
||||
"xString": "foo",
|
||||
})
|
||||
|
||||
tcc := []struct {
|
||||
expects interface{}
|
||||
@@ -27,11 +27,11 @@ func TestTypedValueOperations(t *testing.T) {
|
||||
|
||||
// uint ops
|
||||
{true, "xUint == 1"},
|
||||
{uint64(1), "xUint"},
|
||||
{uint(1), "xUint"},
|
||||
|
||||
// uint ops
|
||||
{true, "xInt == 1"},
|
||||
{int64(1), "xInt"},
|
||||
{int(1), "xInt"},
|
||||
|
||||
// string ops
|
||||
{true, `xString == "foo"`},
|
||||
@@ -157,12 +157,16 @@ func TestArrayDecode(t *testing.T) {
|
||||
})
|
||||
|
||||
req.NoError(err)
|
||||
req.NoError(RVars{
|
||||
|
||||
vars, err := NewVars(map[string]interface{}{
|
||||
"strings": &Array{arr},
|
||||
"iface": Must(NewString("typed")),
|
||||
"typed": Must(NewString("typed")),
|
||||
"values": &Array{arr},
|
||||
}.Vars().Decode(&foo))
|
||||
})
|
||||
|
||||
req.NoError(err)
|
||||
req.NoError(vars.Decode(&foo))
|
||||
req.Len(foo.Strings, 2)
|
||||
req.Len(foo.Values, 2)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func isEmpty(i interface{}) bool {
|
||||
}
|
||||
|
||||
switch reflect.TypeOf(i).Kind() {
|
||||
case reflect.Slice, reflect.Array, reflect.Ptr, reflect.Map:
|
||||
case reflect.Slice, reflect.Array, reflect.Map:
|
||||
return reflect.ValueOf(i).Len() == 0
|
||||
}
|
||||
|
||||
+2
-2
@@ -66,11 +66,11 @@ func (p *gvalParser) ParseEvaluators(ee ...Evaluator) error {
|
||||
}
|
||||
|
||||
func (e *gvalEval) Eval(ctx context.Context, scope *Vars) (interface{}, error) {
|
||||
return e.evaluable(ctx, scope.Dict())
|
||||
return e.evaluable(ctx, scope)
|
||||
}
|
||||
|
||||
func (e *gvalEval) Test(ctx context.Context, scope *Vars) (bool, error) {
|
||||
r, err := e.evaluable(ctx, scope.Dict())
|
||||
r, err := e.evaluable(ctx, scope)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
+50
-33
@@ -12,16 +12,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
// RVars or raw-vars, used as internal type for Vars expr type
|
||||
RVars map[string]TypedValue
|
||||
)
|
||||
|
||||
// Vars is a utility func that returns RVars wrapped in Vars
|
||||
func (v RVars) Vars() *Vars {
|
||||
return &Vars{value: v}
|
||||
}
|
||||
|
||||
func (t Vars) Len() int {
|
||||
return len(t.value)
|
||||
}
|
||||
@@ -36,7 +26,7 @@ func (t Vars) Select(k string) (TypedValue, error) {
|
||||
|
||||
func (t *Vars) AssignFieldValue(key string, val TypedValue) (err error) {
|
||||
if t.value == nil {
|
||||
t.value = make(RVars)
|
||||
t.value = make(map[string]TypedValue)
|
||||
}
|
||||
|
||||
t.value[key] = val
|
||||
@@ -70,7 +60,7 @@ func (t Vars) ResolveTypes(res func(typ string) Type) (err error) {
|
||||
// Assign takes base variables and assigns all new variables
|
||||
func (t *Vars) Merge(nn ...Iterator) *Vars {
|
||||
var (
|
||||
out = &Vars{value: make(RVars)}
|
||||
out = &Vars{value: make(map[string]TypedValue)}
|
||||
)
|
||||
|
||||
nn = append([]Iterator{t}, nn...)
|
||||
@@ -92,7 +82,7 @@ func (t *Vars) Copy(dst *Vars, kk ...string) {
|
||||
}
|
||||
|
||||
if dst.value == nil {
|
||||
dst.value = make(RVars)
|
||||
dst.value = make(map[string]TypedValue)
|
||||
}
|
||||
|
||||
for _, k := range kk {
|
||||
@@ -135,17 +125,12 @@ func (t *Vars) HasAny(key string, kk ...string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Vars) Dict() map[string]interface{} {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
var _ gval.Selector = &Vars{}
|
||||
|
||||
func (t *Vars) Dict() map[string]interface{} {
|
||||
dict := make(map[string]interface{})
|
||||
for k, v := range t.value {
|
||||
switch v := v.(type) {
|
||||
case gval.Selector:
|
||||
dict[k] = v
|
||||
|
||||
case Dict:
|
||||
dict[k] = v.Dict()
|
||||
|
||||
@@ -227,25 +212,31 @@ func (t *Vars) Value() (driver.Value, error) {
|
||||
}
|
||||
|
||||
func (t Vars) SelectGVal(_ context.Context, k string) (interface{}, error) {
|
||||
return t.Select(k)
|
||||
val, err := t.Select(k)
|
||||
switch c := val.(type) {
|
||||
case gval.Selector:
|
||||
return c, nil
|
||||
default:
|
||||
return UntypedValue(val), err
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON
|
||||
func (t *Vars) UnmarshalJSON(in []byte) (err error) {
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
aux = make(map[string]*typedValueWrap)
|
||||
)
|
||||
|
||||
if err = json.Unmarshal(in, &aux); err != nil {
|
||||
return
|
||||
if t.value == nil {
|
||||
t.value = make(map[string]TypedValue)
|
||||
}
|
||||
|
||||
if t.value == nil && len(aux) > 0 {
|
||||
t.value = make(map[string]TypedValue)
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(in, &aux); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range aux {
|
||||
@@ -271,6 +262,15 @@ func (t *Vars) Each(fn func(k string, v TypedValue) error) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (t *Vars) Set(k string, v interface{}) (err error) {
|
||||
if t.value == nil {
|
||||
t.value = make(map[string]TypedValue)
|
||||
}
|
||||
|
||||
t.value[k], err = Typify(v)
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses sort expression when passed inside JSON
|
||||
func (t Vars) MarshalJSON() ([]byte, error) {
|
||||
aux := make(map[string]*typedValueWrap)
|
||||
@@ -307,8 +307,12 @@ func decode(dst reflect.Value, src TypedValue) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
raw := UntypedValue(src)
|
||||
if reflect.ValueOf(src).Type().ConvertibleTo(dst.Type()) {
|
||||
dst.Set(reflect.ValueOf(src))
|
||||
return
|
||||
}
|
||||
|
||||
raw := UntypedValue(src)
|
||||
// Optimistically try to decode source to destination by comparing (internal) value type for destination
|
||||
if reflect.ValueOf(raw).Type().ConvertibleTo(dst.Type()) {
|
||||
dst.Set(reflect.ValueOf(raw))
|
||||
@@ -349,6 +353,9 @@ func decode(dst reflect.Value, src TypedValue) (err error) {
|
||||
dst.SetString(vString)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
dst.Set(reflect.ValueOf(src.Get()))
|
||||
|
||||
//case reflect.Interface:
|
||||
// dst.Set(reflect.ValueOf(raw))
|
||||
|
||||
@@ -363,18 +370,28 @@ func decode(dst reflect.Value, src TypedValue) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CastToVars(val interface{}) (out RVars, err error) {
|
||||
func CastToVars(val interface{}) (out map[string]TypedValue, err error) {
|
||||
val = UntypedValue(val)
|
||||
|
||||
if val == nil {
|
||||
return make(RVars), nil
|
||||
return make(map[string]TypedValue), nil
|
||||
}
|
||||
|
||||
switch c := val.(type) {
|
||||
case *Vars:
|
||||
return c.value, nil
|
||||
case RVars:
|
||||
case map[string]TypedValue:
|
||||
return c, nil
|
||||
case map[string]interface{}:
|
||||
out = make(map[string]TypedValue)
|
||||
for k, v := range c {
|
||||
out[k], err = Typify(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unable to cast type %T to %T", val, out)
|
||||
|
||||
+39
-26
@@ -9,7 +9,6 @@ import (
|
||||
// extract typed-value
|
||||
|
||||
func TestVars_Decode(t *testing.T) {
|
||||
|
||||
t.Run("mix", func(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
@@ -23,12 +22,12 @@ func TestVars_Decode(t *testing.T) {
|
||||
Unexisting byte
|
||||
}{}
|
||||
|
||||
vars = RVars{
|
||||
vars, _ = NewVars(map[string]interface{}{
|
||||
"int": Must(NewInteger(42)),
|
||||
"STRING": Must(NewString("foo")),
|
||||
"bool": Must(NewBoolean(true)),
|
||||
"missing": Must(NewBoolean(true)),
|
||||
}.Vars()
|
||||
})
|
||||
)
|
||||
|
||||
req.NoError(vars.Decode(dst))
|
||||
@@ -48,11 +47,11 @@ func TestVars_Decode(t *testing.T) {
|
||||
IBool interface{} `var:"iBool"`
|
||||
}{}
|
||||
|
||||
vars = RVars{
|
||||
vars, _ = NewVars(map[string]interface{}{
|
||||
"iString": Must(NewString("foo")),
|
||||
"iInteger": Must(NewInteger(42)),
|
||||
"iBool": Must(NewBoolean(true)),
|
||||
}.Vars()
|
||||
})
|
||||
)
|
||||
|
||||
req.NoError(vars.Decode(dst))
|
||||
@@ -63,12 +62,12 @@ func TestVars_Decode(t *testing.T) {
|
||||
req = require.New(t)
|
||||
|
||||
dst = &struct {
|
||||
Vars RVars `var:"vars"`
|
||||
Vars *Vars `var:"vars"`
|
||||
}{}
|
||||
|
||||
vars = RVars{
|
||||
"vars": RVars{"foo": Must(NewString("bar"))}.Vars(),
|
||||
}.Vars()
|
||||
vars, _ = NewVars(map[string]interface{}{
|
||||
"vars": map[string]interface{}{"foo": Must(NewString("bar"))},
|
||||
})
|
||||
)
|
||||
|
||||
req.NoError(vars.Decode(dst))
|
||||
@@ -83,10 +82,10 @@ func TestVars_Decode(t *testing.T) {
|
||||
Uint64 uint64
|
||||
}{}
|
||||
|
||||
vars = RVars{
|
||||
vars, _ = NewVars(map[string]TypedValue{
|
||||
"uint64": Must(NewAny("42")),
|
||||
"int": Must(NewAny("42")),
|
||||
}.Vars()
|
||||
})
|
||||
)
|
||||
|
||||
dst.Uint64 = 0
|
||||
@@ -96,52 +95,66 @@ func TestVars_Decode(t *testing.T) {
|
||||
req.Equal(uint64(42), dst.Uint64)
|
||||
req.Equal(int64(42), dst.Int)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestVars_Assign(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
vars = &Vars{}
|
||||
)
|
||||
|
||||
req.NoError(Assign(vars, "foo", &String{value: "foo"}))
|
||||
req.NoError(Assign(vars, "vars", &Vars{}))
|
||||
req.NoError(Assign(vars, "vars.foo", &String{value: "foo"}))
|
||||
}
|
||||
|
||||
func TestVars_UnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
json string
|
||||
vars *Vars
|
||||
vars map[string]interface{}
|
||||
}{
|
||||
{"empty", "", &Vars{}},
|
||||
{"empty", "{}", &Vars{}},
|
||||
{"string", `{"a":{"@value":"b"}}`, RVars{"a": &Unresolved{value: "b"}}.Vars()},
|
||||
{"empty", "", make(map[string]interface{})},
|
||||
{"object", "{}", make(map[string]interface{})},
|
||||
{"string", `{"a":{"@value":"b"}}`, map[string]interface{}{"a": &Unresolved{value: "b"}}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
var (
|
||||
r = require.New(t)
|
||||
v = &Vars{}
|
||||
r = require.New(t)
|
||||
unmarshaled = &Vars{}
|
||||
aux, _ = NewVars(c.vars)
|
||||
)
|
||||
|
||||
r.NoError(v.UnmarshalJSON([]byte(c.json)))
|
||||
r.Equal(c.vars, v)
|
||||
r.NoError(unmarshaled.UnmarshalJSON([]byte(c.json)))
|
||||
r.Equal(aux, unmarshaled)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVars_UMarshalJSON(t *testing.T) {
|
||||
func TestVars_MarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
json string
|
||||
vars *Vars
|
||||
vars map[string]interface{}
|
||||
}{
|
||||
{"empty", "{}", &Vars{}},
|
||||
{"string", `{"a":{"@value":"b","@type":"String"}}`, RVars{"a": &String{value: "b"}}.Vars()},
|
||||
{"empty", "{}", nil},
|
||||
{"string", `{"a":{"@value":"b","@type":"String"}}`, map[string]interface{}{"a": &String{value: "b"}}},
|
||||
{"array",
|
||||
`{"arr":{"@value":[{"@value":"foo","@type":"String"},{"@value":"bar","@type":"String"}],"@type":"Array"}}`,
|
||||
RVars{"arr": &Array{value: []TypedValue{&String{value: "foo"}, &String{value: "bar"}}}}.Vars()},
|
||||
map[string]interface{}{"arr": &Array{value: []TypedValue{&String{value: "foo"}, &String{value: "bar"}}}}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
var (
|
||||
r = require.New(t)
|
||||
r = require.New(t)
|
||||
aux, _ = NewVars(c.vars)
|
||||
)
|
||||
|
||||
j, err := json.Marshal(c.vars)
|
||||
j, err := json.Marshal(aux)
|
||||
r.NoError(err)
|
||||
r.Equal(c.json, string(j))
|
||||
})
|
||||
|
||||
@@ -3,18 +3,21 @@ package wfexec
|
||||
import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func gt(key string, val int64) pathTester {
|
||||
return func(ctx context.Context, variables *expr.Vars) (bool, error) {
|
||||
return expr.Must(expr.Select(variables, key)).Get().(int64) > val, nil
|
||||
return cast.ToInt64(expr.Must(expr.Select(variables, key)).Get()) > val, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeIntVars(k string, num int) *expr.Vars {
|
||||
return expr.RVars{k: expr.Must(expr.NewInteger(num))}.Vars()
|
||||
o := &expr.Vars{}
|
||||
_ = o.Set(k, num)
|
||||
return o
|
||||
}
|
||||
|
||||
func TestJoinGateway(t *testing.T) {
|
||||
|
||||
@@ -483,10 +483,9 @@ func (s *Session) queueScheduledSuspended() {
|
||||
delete(s.delayed, id)
|
||||
|
||||
// Set state input when step is resumed
|
||||
sus.state.input = expr.RVars{
|
||||
"resumed": expr.Must(expr.NewBoolean(true)),
|
||||
"resumeAt": expr.Must(expr.NewDateTime(sus.resumeAt)),
|
||||
}.Vars()
|
||||
sus.state.input = &expr.Vars{}
|
||||
sus.state.input.Set("resumed", true)
|
||||
sus.state.input.Set("resumeAt", sus.resumeAt)
|
||||
s.qState <- sus.state
|
||||
}
|
||||
}
|
||||
|
||||
+28
-21
@@ -33,20 +33,22 @@ func (s *sesTestStep) Exec(ctx context.Context, r *ExecRequest) (ExecResponse, e
|
||||
return s.exec(ctx, r)
|
||||
}
|
||||
|
||||
var args = &struct {
|
||||
Path string
|
||||
Counter int64
|
||||
}{}
|
||||
var (
|
||||
args = &struct {
|
||||
Path string
|
||||
Counter int64
|
||||
}{}
|
||||
)
|
||||
|
||||
if err := r.Scope.Decode(args); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return expr.RVars{
|
||||
"counter": expr.Must(expr.NewInteger(args.Counter + 1)),
|
||||
"path": expr.Must(expr.NewString(args.Path + "/" + s.name)),
|
||||
s.name: expr.Must(expr.NewString("executed")),
|
||||
}.Vars(), nil
|
||||
return expr.NewVars(map[string]interface{}{
|
||||
"counter": args.Counter + 1,
|
||||
"path": args.Path + "/" + s.name,
|
||||
s.name: "executed",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *sesTestTemporal) Exec(ctx context.Context, r *ExecRequest) (ExecResponse, error) {
|
||||
@@ -58,9 +60,9 @@ func (s *sesTestTemporal) Exec(ctx context.Context, r *ExecRequest) (ExecRespons
|
||||
return Delay(s.until), nil
|
||||
}
|
||||
|
||||
return expr.RVars{
|
||||
"waitForMoment": expr.Must(expr.NewString("executed")),
|
||||
}.Vars(), nil
|
||||
return expr.NewVars(map[string]interface{}{
|
||||
"waitForMoment": "executed",
|
||||
})
|
||||
}
|
||||
|
||||
func TestSession_TwoStepWorkflow(t *testing.T) {
|
||||
@@ -72,11 +74,16 @@ func TestSession_TwoStepWorkflow(t *testing.T) {
|
||||
|
||||
s1 = &sesTestStep{name: "s1"}
|
||||
s2 = &sesTestStep{name: "s2"}
|
||||
|
||||
scope = &expr.Vars{}
|
||||
)
|
||||
|
||||
scope.Set("two", 1)
|
||||
scope.Set("three", 1)
|
||||
|
||||
wf.AddStep(s1, s2) // 1st execute s1 then s2
|
||||
ses.Exec(ctx, s1, expr.RVars{"two": expr.Must(expr.NewInteger(1)), "three": expr.Must(expr.NewInteger(1))}.Vars())
|
||||
ses.Wait(ctx)
|
||||
req.NoError(ses.Exec(ctx, s1, scope))
|
||||
req.NoError(ses.Wait(ctx))
|
||||
req.NoError(ses.Error())
|
||||
req.NotNil(ses.Result())
|
||||
req.Equal("/s1/s2", expr.Must(expr.Select(ses.Result(), "path")).Get())
|
||||
@@ -140,10 +147,8 @@ func TestSession_Delays(t *testing.T) {
|
||||
return Prompt(0, "", nil), nil
|
||||
}
|
||||
|
||||
out := expr.RVars{
|
||||
"waitForInput": expr.Must(expr.NewString("executed")),
|
||||
}.Vars()
|
||||
|
||||
out := &expr.Vars{}
|
||||
_ = out.Set("waitForInput", "executed")
|
||||
r.Input.Copy(out, "input")
|
||||
|
||||
return out, nil
|
||||
@@ -159,7 +164,7 @@ func TestSession_Delays(t *testing.T) {
|
||||
req.NoError(ses.Exec(ctx, start, nil))
|
||||
|
||||
// wait-for-moment step needs to be executed before we can resume wait-for-input
|
||||
ses.Wait(ctx)
|
||||
req.NoError(ses.Wait(ctx))
|
||||
time.Sleep(delay + unit)
|
||||
req.NotZero(waitForInputStateId.Load())
|
||||
|
||||
@@ -168,10 +173,12 @@ func TestSession_Delays(t *testing.T) {
|
||||
req.True(ses.Suspended())
|
||||
|
||||
// push in the input
|
||||
req.NoError(ses.Resume(ctx, waitForInputStateId.Load(), expr.RVars{"input": expr.Must(expr.NewString("foo"))}.Vars()))
|
||||
input := &expr.Vars{}
|
||||
input.Set("inout", "foo")
|
||||
req.NoError(ses.Resume(ctx, waitForInputStateId.Load(), input))
|
||||
|
||||
req.False(ses.Suspended())
|
||||
ses.Wait(ctx)
|
||||
req.NoError(ses.Wait(ctx))
|
||||
time.Sleep(2 * unit)
|
||||
|
||||
// should not be completed yet...
|
||||
|
||||
@@ -3,6 +3,7 @@ package automation
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
@@ -130,17 +131,7 @@ func CastToRenderOptions(val interface{}) (out map[string]string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func CastToRenderVariables(val interface{}) (out map[string]interface{}, err error) {
|
||||
switch val := expr.UntypedValue(val).(type) {
|
||||
case map[string]interface{}:
|
||||
return val, nil
|
||||
case nil:
|
||||
return make(map[string]interface{}), nil
|
||||
default:
|
||||
out, err = cast.ToStringMapE(val)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to cast type %T to %T", val, out)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
func (doc renderedDocument) String() string {
|
||||
aux, _ := ioutil.ReadAll(doc.Document)
|
||||
return string(aux)
|
||||
}
|
||||
|
||||
@@ -23,16 +23,17 @@ func TestUser(t *testing.T) {
|
||||
|
||||
func TestUser_Expr(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
u, err = NewUser(&types.User{Handle: "hendl"})
|
||||
req = require.New(t)
|
||||
u, _ = NewUser(&types.User{Handle: "hendl"})
|
||||
scope = &expr.Vars{}
|
||||
)
|
||||
|
||||
req.NoError(err)
|
||||
req.NoError(scope.Set("user", u))
|
||||
|
||||
eval, err := expr.NewParser().Parse("user.handle")
|
||||
req.NoError(err)
|
||||
|
||||
res, err := eval.Eval(context.Background(), expr.RVars{"user": u}.Vars())
|
||||
res, err := eval.Eval(context.Background(), scope)
|
||||
req.NoError(err)
|
||||
|
||||
req.Equal("hendl", res.(string))
|
||||
|
||||
@@ -218,11 +218,11 @@ func (i *roleSetIterator) More(context.Context, *Vars) (bool, error) {
|
||||
func (i *roleSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
|
||||
|
||||
func (i *roleSetIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
out := RVars{
|
||||
"role": Must(NewRole(i.set[i.ptr])),
|
||||
"total": Must(NewUnsignedInteger(i.filter.Total)),
|
||||
}
|
||||
out := &Vars{}
|
||||
out.Set("role", Must(NewRole(i.set[i.ptr])))
|
||||
out.Set("index", i.ptr)
|
||||
out.Set("total", i.filter.Total)
|
||||
|
||||
i.ptr++
|
||||
return out.Vars(), nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -746,7 +746,7 @@ type (
|
||||
DocumentType string
|
||||
|
||||
hasVariables bool
|
||||
Variables expr.RVars
|
||||
Variables *expr.Vars
|
||||
|
||||
hasOptions bool
|
||||
Options map[string]string
|
||||
|
||||
@@ -163,11 +163,6 @@ func (h templatesHandler) recover(ctx context.Context, args *templatesRecoverArg
|
||||
func (h templatesHandler) render(ctx context.Context, args *templatesRenderArgs) (*templatesRenderResults, error) {
|
||||
var err error
|
||||
|
||||
vars := args.Variables.Vars().Dict()
|
||||
if vars == nil {
|
||||
vars = make(map[string]interface{})
|
||||
}
|
||||
|
||||
opts := make(map[string]string)
|
||||
if args.hasOptions {
|
||||
opts, err = cast.ToStringMapStringE(args.Options)
|
||||
@@ -181,7 +176,7 @@ func (h templatesHandler) render(ctx context.Context, args *templatesRenderArgs)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
doc, err := h.tSvc.Render(ctx, tplID, args.DocumentType, vars, opts)
|
||||
doc, err := h.tSvc.Render(ctx, tplID, args.DocumentType, args.Variables.Dict(), opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -204,13 +199,13 @@ func (i *templateSetIterator) More(context.Context, *Vars) (bool, error) {
|
||||
func (i *templateSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
|
||||
|
||||
func (i *templateSetIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
out := RVars{
|
||||
"template": Must(NewTemplate(i.set[i.ptr])),
|
||||
"total": Must(NewUnsignedInteger(i.filter.Total)),
|
||||
}
|
||||
out := &Vars{}
|
||||
out.Set("template", Must(NewTemplate(i.set[i.ptr])))
|
||||
out.Set("index", i.ptr)
|
||||
out.Set("total", i.filter.Total)
|
||||
|
||||
i.ptr++
|
||||
return out.Vars(), nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func lookupTemplate(ctx context.Context, svc templateService, args templateLookup) (*types.Template, error) {
|
||||
|
||||
@@ -153,7 +153,7 @@ functions:
|
||||
- { wf: String }
|
||||
variables:
|
||||
types:
|
||||
- { wf: Vars, go: 'expr.RVars' }
|
||||
- { wf: Vars, go: '*expr.Vars' }
|
||||
options:
|
||||
types:
|
||||
- { wf: RenderOptions }
|
||||
|
||||
@@ -219,11 +219,11 @@ func (i *userSetIterator) More(context.Context, *Vars) (bool, error) {
|
||||
func (i *userSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
|
||||
|
||||
func (i *userSetIterator) Next(context.Context, *Vars) (*Vars, error) {
|
||||
out := RVars{
|
||||
"user": Must(NewUser(i.set[i.ptr])),
|
||||
"total": Must(NewUnsignedInteger(i.filter.Total)),
|
||||
}
|
||||
out := &Vars{}
|
||||
out.Set("user", Must(NewUser(i.set[i.ptr])))
|
||||
out.Set("index", i.ptr)
|
||||
out.Set("total", i.filter.Total)
|
||||
|
||||
i.ptr++
|
||||
return out.Vars(), nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -536,14 +536,14 @@ func (res systemBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res systemBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res systemBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -921,10 +921,9 @@ func (res applicationBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res applicationBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res applicationBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for *types.Application
|
||||
|
||||
@@ -932,7 +931,8 @@ func (res applicationBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -1214,20 +1214,24 @@ func (res authBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res authBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res authBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["user"], err = automation.NewUser(res.user); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewUser(res.user); err == nil {
|
||||
err = out.Set("user", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for *types.AuthProvider
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -1639,10 +1643,9 @@ func (res authClientBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res authClientBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res authClientBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for *types.AuthClient
|
||||
|
||||
@@ -1650,7 +1653,8 @@ func (res authClientBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -1861,16 +1865,16 @@ func (res mailBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res mailBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res mailBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for *types.MailMessage
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -2265,22 +2269,30 @@ func (res roleBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res roleBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res roleBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["role"], err = automation.NewRole(res.role); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewRole(res.role); err == nil {
|
||||
err = out.Set("role", v)
|
||||
}
|
||||
|
||||
if rvars["oldRole"], err = automation.NewRole(res.oldRole); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewRole(res.oldRole); err == nil {
|
||||
err = out.Set("oldRole", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -2570,22 +2582,30 @@ func (res roleMemberBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res roleMemberBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res roleMemberBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["user"], err = automation.NewUser(res.user); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewUser(res.user); err == nil {
|
||||
err = out.Set("user", v)
|
||||
}
|
||||
|
||||
if rvars["role"], err = automation.NewRole(res.role); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewRole(res.role); err == nil {
|
||||
err = out.Set("role", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -2759,10 +2779,9 @@ func (res sinkBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res sinkBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res sinkBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
// Could not found expression-type counterpart for *types.SinkResponse
|
||||
|
||||
@@ -2770,7 +2789,8 @@ func (res sinkBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
@@ -3168,22 +3188,30 @@ func (res userBase) Encode() (args map[string][]byte, err error) {
|
||||
}
|
||||
|
||||
// Encode internal data to be passed as event params & arguments to workflow
|
||||
func (res userBase) EncodeVars() (vars *expr.Vars, err error) {
|
||||
var (
|
||||
rvars = expr.RVars{}
|
||||
)
|
||||
func (res userBase) EncodeVars() (out *expr.Vars, err error) {
|
||||
out = &expr.Vars{}
|
||||
var v expr.TypedValue
|
||||
|
||||
if rvars["user"], err = automation.NewUser(res.user); err != nil {
|
||||
return nil, err
|
||||
if v, err = automation.NewUser(res.user); err == nil {
|
||||
err = out.Set("user", v)
|
||||
}
|
||||
|
||||
if rvars["oldUser"], err = automation.NewUser(res.oldUser); err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if v, err = automation.NewUser(res.oldUser); err == nil {
|
||||
err = out.Set("oldUser", v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Could not found expression-type counterpart for auth.Identifiable
|
||||
|
||||
return rvars.Vars(), err
|
||||
_ = v
|
||||
return
|
||||
}
|
||||
|
||||
// Decode return values from Corredor script into struct props
|
||||
|
||||
@@ -151,7 +151,7 @@ func TestTriggerCreateFull(t *testing.T) {
|
||||
WorkflowID: wf.ID,
|
||||
ResourceType: "wf-full-test",
|
||||
Enabled: true,
|
||||
Input: &expr.Vars{},
|
||||
Input: expr.EmptyVars(),
|
||||
OwnedBy: 42,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -183,11 +183,15 @@ func TestWorkflowCreateFull(t *testing.T) {
|
||||
Enabled: true,
|
||||
Trace: true,
|
||||
KeepSessions: 10000,
|
||||
Scope: expr.RVars{"foo": expr.Must(expr.NewString("bar"))}.Vars(),
|
||||
Steps: types.WorkflowStepSet{},
|
||||
Paths: types.WorkflowPathSet{},
|
||||
RunAs: 0,
|
||||
OwnedBy: 42,
|
||||
Scope: func() *expr.Vars {
|
||||
o := &expr.Vars{}
|
||||
_ = o.Set("foo", "bar")
|
||||
return o
|
||||
}(),
|
||||
Steps: types.WorkflowStepSet{},
|
||||
Paths: types.WorkflowPathSet{},
|
||||
RunAs: 0,
|
||||
OwnedBy: 42,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user