|
@@ -25,7 +25,7 @@ import (
|
|
|
"github.com/lf-edge/ekuiper/pkg/api"
|
|
|
)
|
|
|
|
|
|
-func TestArrayFunctions(t *testing.T) {
|
|
|
+func TestArrayCommonFunctions(t *testing.T) {
|
|
|
contextLogger := conf.Log.WithField("rule", "testExec")
|
|
|
ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
|
|
|
tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
|
|
@@ -452,6 +452,242 @@ func TestArrayFunctions(t *testing.T) {
|
|
|
},
|
|
|
result: []interface{}{10, 7, 4, 1},
|
|
|
},
|
|
|
+ {
|
|
|
+ name: "array_cardinality",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ result: 3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_cardinality",
|
|
|
+ args: []interface{}{
|
|
|
+ 1, 2, 3,
|
|
|
+ },
|
|
|
+ result: errorArrayFirstArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_flatten",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{
|
|
|
+ []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ result: []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_flatten",
|
|
|
+ args: []interface{}{
|
|
|
+ 1, 2,
|
|
|
+ },
|
|
|
+ result: errorArrayFirstArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_flatten",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 2, 3}, 4,
|
|
|
+ },
|
|
|
+ result: errorArrayNotArrayElementError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_flatten",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{
|
|
|
+ []interface{}{1, 2, 3},
|
|
|
+ []interface{}{4, 5, 6},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ result: []interface{}{1, 2, 3, 4, 5, 6},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_distinct",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ result: []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_distinct",
|
|
|
+ args: []interface{}{
|
|
|
+ 1, 1,
|
|
|
+ },
|
|
|
+ result: errorArrayFirstArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_distinct",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 1, 1},
|
|
|
+ },
|
|
|
+ result: []interface{}{1},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_distinct",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 2, 2, 1},
|
|
|
+ },
|
|
|
+ result: []interface{}{1, 2},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "round", []interface{}{0, 0.4, 1.2},
|
|
|
+ },
|
|
|
+ result: []interface{}{0.0, 0.0, 1.0},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ 123, []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ result: errorArrayFirstArgumentNotStringError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "round", 1,
|
|
|
+ },
|
|
|
+ result: errorArraySecondArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "abs", []interface{}{0, -0.4, 1.2},
|
|
|
+ },
|
|
|
+ result: []interface{}{0, 0.4, 1.2},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "pow", []interface{}{0, -0.4, 1.2},
|
|
|
+ },
|
|
|
+ result: fmt.Errorf("unknown built-in function: pow."),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "avg", []interface{}{0, -0.4, 1.2},
|
|
|
+ },
|
|
|
+ result: fmt.Errorf("first argument should be a scalar function."),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "ceil", []interface{}{0, -1, 1.2},
|
|
|
+ },
|
|
|
+ result: []interface{}{0.0, -1.0, 2.0},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_map",
|
|
|
+ args: []interface{}{
|
|
|
+ "power", []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ result: fmt.Errorf("validate function arguments failed."),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ "a", "",
|
|
|
+ },
|
|
|
+ result: errorArrayFirstArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, 123, "a",
|
|
|
+ },
|
|
|
+ result: errorArraySecondArgumentNotStringError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, ":", 123,
|
|
|
+ },
|
|
|
+ result: errorArrayThirdArgumentNotStringError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{123, "b", "c"}, ":", "a",
|
|
|
+ },
|
|
|
+ result: errorArrayNotStringElementError,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, "",
|
|
|
+ },
|
|
|
+ result: "abc",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", nil, "b"}, ":",
|
|
|
+ },
|
|
|
+ result: "a:b",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, ":",
|
|
|
+ },
|
|
|
+ result: "a:b:c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, ":,%",
|
|
|
+ },
|
|
|
+ result: "a:,%b:,%c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", nil, "c"}, ":", "nullReplacementStr",
|
|
|
+ },
|
|
|
+ result: "a:nullReplacementStr:c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", nil, "c"}, ":", "nullReplacementStr",
|
|
|
+ },
|
|
|
+ result: "a:nullReplacementStr:c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, ":", "a",
|
|
|
+ },
|
|
|
+ result: "a:b:c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", "c"}, ":",
|
|
|
+ },
|
|
|
+ result: "a:b:c",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{nil, nil, nil}, ",", "nullReplacementStr",
|
|
|
+ },
|
|
|
+ result: "nullReplacementStr,nullReplacementStr,nullReplacementStr",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{nil, nil, nil}, ",",
|
|
|
+ },
|
|
|
+ result: "",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_join",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{"a", "b", nil}, ",",
|
|
|
+ },
|
|
|
+ result: "a,b",
|
|
|
+ },
|
|
|
}
|
|
|
for i, tt := range tests {
|
|
|
f, ok := builtins[tt.name]
|
|
@@ -464,3 +700,53 @@ func TestArrayFunctions(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestArrayShuffle(t *testing.T) {
|
|
|
+ contextLogger := conf.Log.WithField("rule", "testExec")
|
|
|
+ ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
|
|
|
+ tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
|
|
|
+ fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
|
|
|
+ tests := []struct {
|
|
|
+ name string
|
|
|
+ args []interface{}
|
|
|
+ result []interface{}
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ name: "array_shuffle",
|
|
|
+ args: []interface{}{
|
|
|
+ []interface{}{1, 2, 3},
|
|
|
+ },
|
|
|
+ result: []interface{}{
|
|
|
+ []interface{}{1, 2, 3}, []interface{}{1, 3, 2}, []interface{}{2, 1, 3}, []interface{}{2, 3, 1}, []interface{}{3, 1, 2}, []interface{}{3, 2, 1},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "array_shuffle",
|
|
|
+ args: []interface{}{
|
|
|
+ 1,
|
|
|
+ },
|
|
|
+ result: []interface{}{
|
|
|
+ errorArrayFirstArgumentNotArrayError,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ for i, tt := range tests {
|
|
|
+ f, ok := builtins[tt.name]
|
|
|
+ if !ok {
|
|
|
+ t.Fatal(fmt.Sprintf("builtin %v not found", tt.name))
|
|
|
+ }
|
|
|
+ result, _ := f.exec(fctx, tt.args)
|
|
|
+ flag := false
|
|
|
+ for _, actual := range tt.result {
|
|
|
+ if reflect.DeepEqual(result, actual) {
|
|
|
+ flag = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if !flag {
|
|
|
+ t.Errorf("%d result mismatch,\ngot:\t%v \nwant in:\t%v", i, result, tt.result)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|