funcs_cols_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. // Copyright 2022 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package function
  15. import (
  16. "fmt"
  17. "reflect"
  18. "testing"
  19. "github.com/lf-edge/ekuiper/internal/conf"
  20. kctx "github.com/lf-edge/ekuiper/internal/topo/context"
  21. "github.com/lf-edge/ekuiper/internal/topo/state"
  22. "github.com/lf-edge/ekuiper/pkg/api"
  23. "github.com/lf-edge/ekuiper/pkg/ast"
  24. )
  25. func TestValidation(t *testing.T) {
  26. f, ok := builtins["changed_cols"]
  27. if !ok {
  28. t.Fatal("builtin not found")
  29. }
  30. tests := []struct {
  31. args []ast.Expr
  32. err error
  33. }{
  34. {
  35. args: []ast.Expr{
  36. &ast.StringLiteral{Val: "foo"},
  37. },
  38. err: fmt.Errorf("expect more than two args but got 1"),
  39. }, {
  40. args: []ast.Expr{
  41. &ast.StringLiteral{Val: "foo"},
  42. &ast.StringLiteral{Val: "bar"},
  43. },
  44. err: fmt.Errorf("expect more than two args but got 2"),
  45. }, {
  46. args: []ast.Expr{
  47. &ast.StringLiteral{Val: "foo"},
  48. &ast.StringLiteral{Val: "bar"},
  49. &ast.StringLiteral{Val: "baz"},
  50. },
  51. err: fmt.Errorf("Expect bool type for parameter 2"),
  52. }, {
  53. args: []ast.Expr{
  54. &ast.IntegerLiteral{Val: 20},
  55. &ast.BooleanLiteral{Val: true},
  56. &ast.StringLiteral{Val: "baz"},
  57. },
  58. err: fmt.Errorf("Expect string type for parameter 1"),
  59. }, {
  60. args: []ast.Expr{
  61. &ast.FieldRef{
  62. StreamName: "demo",
  63. Name: "a",
  64. AliasRef: nil,
  65. },
  66. &ast.BooleanLiteral{Val: true},
  67. &ast.StringLiteral{Val: "baz"},
  68. },
  69. err: nil,
  70. },
  71. }
  72. for i, tt := range tests {
  73. err := f.val(nil, tt.args)
  74. if !reflect.DeepEqual(err, tt.err) {
  75. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  76. }
  77. }
  78. }
  79. func TestExec(t *testing.T) {
  80. f, ok := builtins["changed_cols"]
  81. if !ok {
  82. t.Fatal("builtin not found")
  83. }
  84. contextLogger := conf.Log.WithField("rule", "testExec")
  85. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  86. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  87. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  88. var nilResult ResultCols
  89. tests := []struct {
  90. args []interface{}
  91. result interface{}
  92. }{
  93. { // 0
  94. args: []interface{}{
  95. "foo",
  96. "bar",
  97. "baz",
  98. },
  99. result: fmt.Errorf("the last arg is not the key list but got baz"),
  100. }, { // 1
  101. args: []interface{}{
  102. "foo",
  103. "bar",
  104. []string{"baz"},
  105. },
  106. result: fmt.Errorf("expect more than two args but got 2"),
  107. }, { // 2
  108. args: []interface{}{
  109. "foo",
  110. "bar",
  111. "baz",
  112. []string{"baz"},
  113. },
  114. result: fmt.Errorf("second arg is not a bool but got bar"),
  115. }, { // 3
  116. args: []interface{}{
  117. "ab_",
  118. true,
  119. "baz",
  120. 44,
  121. []string{"a", "b", "col1", "col2"},
  122. },
  123. result: ResultCols{
  124. "ab_col1": "baz",
  125. "ab_col2": 44,
  126. },
  127. }, { // 4
  128. args: []interface{}{
  129. "ab_",
  130. true,
  131. "baz",
  132. 44,
  133. []string{"a", "b", "col1", "col2"},
  134. },
  135. result: nilResult,
  136. }, { // 5
  137. args: []interface{}{
  138. "cd_",
  139. true,
  140. "baz",
  141. 45,
  142. []string{"a", "b", "col1", "col2"},
  143. },
  144. result: ResultCols{
  145. "cd_col2": 45,
  146. },
  147. }, { // 6
  148. args: []interface{}{
  149. "ab_",
  150. true,
  151. "foo",
  152. 46,
  153. []string{"a", "b", "col1", "col2"},
  154. },
  155. result: ResultCols{
  156. "ab_col1": "foo",
  157. "ab_col2": 46,
  158. },
  159. }, { // 7
  160. args: []interface{}{
  161. "ab_",
  162. true,
  163. "foo",
  164. 46,
  165. []string{"a", "b", "col1", "col2"},
  166. },
  167. result: nilResult,
  168. }, { // 8
  169. args: []interface{}{
  170. "ab_",
  171. true,
  172. "baz",
  173. 44,
  174. []string{"a", "b", "col1", "col2"},
  175. },
  176. result: ResultCols{
  177. "ab_col1": "baz",
  178. "ab_col2": 44,
  179. },
  180. },
  181. }
  182. for i, tt := range tests {
  183. result, _ := f.exec(fctx, tt.args)
  184. if !reflect.DeepEqual(result, tt.result) {
  185. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  186. }
  187. }
  188. }
  189. func TestExecIgnoreNull(t *testing.T) {
  190. f, ok := builtins["changed_cols"]
  191. if !ok {
  192. t.Fatal("builtin not found")
  193. }
  194. contextLogger := conf.Log.WithField("rule", "testExec")
  195. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  196. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  197. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  198. var nilResult ResultCols
  199. tests := []struct {
  200. args []interface{}
  201. result interface{}
  202. }{
  203. { // 0
  204. args: []interface{}{
  205. "foo",
  206. "bar",
  207. "baz",
  208. },
  209. result: fmt.Errorf("the last arg is not the key list but got baz"),
  210. }, { // 1
  211. args: []interface{}{
  212. "foo",
  213. "bar",
  214. []string{"baz"},
  215. },
  216. result: fmt.Errorf("expect more than two args but got 2"),
  217. }, { // 2
  218. args: []interface{}{
  219. "foo",
  220. "bar",
  221. "baz",
  222. []string{"baz"},
  223. },
  224. result: fmt.Errorf("second arg is not a bool but got bar"),
  225. }, { // 3
  226. args: []interface{}{
  227. "ab_",
  228. false,
  229. "baz",
  230. 44,
  231. []string{"a", "b", "col1", "col2"},
  232. },
  233. result: ResultCols{
  234. "ab_col1": "baz",
  235. "ab_col2": 44,
  236. },
  237. }, { // 4
  238. args: []interface{}{
  239. "ab_",
  240. false,
  241. nil,
  242. 44,
  243. []string{"a", "b", "col1", "col2"},
  244. },
  245. result: ResultCols{
  246. "ab_col1": nil,
  247. },
  248. }, { // 5
  249. args: []interface{}{
  250. "cd_",
  251. false,
  252. "baz",
  253. 45,
  254. []string{"a", "b", "col1", "col2"},
  255. },
  256. result: ResultCols{
  257. "cd_col1": "baz",
  258. "cd_col2": 45,
  259. },
  260. }, { // 6
  261. args: []interface{}{
  262. "ab_",
  263. true,
  264. "foo",
  265. 46,
  266. []string{"a", "b", "col1", "col2"},
  267. },
  268. result: ResultCols{
  269. "ab_col1": "foo",
  270. "ab_col2": 46,
  271. },
  272. }, { // 7
  273. args: []interface{}{
  274. "ab_",
  275. true,
  276. "foo",
  277. 46,
  278. []string{"a", "b", "col1", "col2"},
  279. },
  280. result: nilResult,
  281. }, { // 8
  282. args: []interface{}{
  283. "ab_",
  284. true,
  285. "baz",
  286. 44,
  287. []string{"a", "b", "col1", "col2"},
  288. },
  289. result: ResultCols{
  290. "ab_col1": "baz",
  291. "ab_col2": 44,
  292. },
  293. },
  294. }
  295. for i, tt := range tests {
  296. result, _ := f.exec(fctx, tt.args)
  297. if !reflect.DeepEqual(result, tt.result) {
  298. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  299. }
  300. }
  301. }