github.com/mattn/anko@v0.1.10/vm/vmFunctions_test.go (about) 1 package vm 2 3 import ( 4 "bytes" 5 "fmt" 6 "reflect" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/mattn/anko/env" 12 ) 13 14 func TestReturns(t *testing.T) { 15 t.Parallel() 16 17 tests := []Test{ 18 {Script: `return 1++`, RunError: fmt.Errorf("invalid operation")}, 19 {Script: `return 1, 1++`, RunError: fmt.Errorf("invalid operation")}, 20 {Script: `return 1, 2, 1++`, RunError: fmt.Errorf("invalid operation")}, 21 22 {Script: `return`, RunOutput: nil}, 23 {Script: `return nil`, RunOutput: nil}, 24 {Script: `return true`, RunOutput: true}, 25 {Script: `return 1`, RunOutput: int64(1)}, 26 {Script: `return 1.1`, RunOutput: float64(1.1)}, 27 {Script: `return "a"`, RunOutput: "a"}, 28 29 {Script: `b()`, Input: map[string]interface{}{"b": func() {}}, RunOutput: nil}, 30 {Script: `b()`, Input: map[string]interface{}{"b": func() reflect.Value { return reflect.Value{} }}, RunOutput: reflect.Value{}}, 31 {Script: `b()`, Input: map[string]interface{}{"b": func() interface{} { return nil }}, RunOutput: nil}, 32 {Script: `b()`, Input: map[string]interface{}{"b": func() bool { return true }}, RunOutput: true}, 33 {Script: `b()`, Input: map[string]interface{}{"b": func() int32 { return int32(1) }}, RunOutput: int32(1)}, 34 {Script: `b()`, Input: map[string]interface{}{"b": func() int64 { return int64(1) }}, RunOutput: int64(1)}, 35 {Script: `b()`, Input: map[string]interface{}{"b": func() float32 { return float32(1.1) }}, RunOutput: float32(1.1)}, 36 {Script: `b()`, Input: map[string]interface{}{"b": func() float64 { return float64(1.1) }}, RunOutput: float64(1.1)}, 37 {Script: `b()`, Input: map[string]interface{}{"b": func() string { return "a" }}, RunOutput: "a"}, 38 39 {Script: `b(a)`, Input: map[string]interface{}{"a": reflect.Value{}, "b": func(c reflect.Value) reflect.Value { return c }}, RunOutput: reflect.Value{}, Output: map[string]interface{}{"a": reflect.Value{}}}, 40 {Script: `b(a)`, Input: map[string]interface{}{"a": nil, "b": func(c interface{}) interface{} { return c }}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 41 {Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c bool) bool { return c }}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 42 {Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int32) int32 { return c }}, RunOutput: int32(1), Output: map[string]interface{}{"a": int32(1)}}, 43 {Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int64) int64 { return c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 44 {Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.1), "b": func(c float32) float32 { return c }}, RunOutput: float32(1.1), Output: map[string]interface{}{"a": float32(1.1)}}, 45 {Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.1), "b": func(c float64) float64 { return c }}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 46 {Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c string) string { return c }}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}}, 47 48 {Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c bool) bool { return c }}, RunError: fmt.Errorf("function wants argument type bool but received type string"), Output: map[string]interface{}{"a": "a"}}, 49 {Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int32) int32 { return c }}, RunOutput: int32(1), Output: map[string]interface{}{"a": int64(1)}}, 50 {Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int64) int64 { return c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int32(1)}}, 51 {Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.25), "b": func(c float32) float32 { return c }}, RunOutput: float32(1.25), Output: map[string]interface{}{"a": float64(1.25)}}, 52 {Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.25), "b": func(c float64) float64 { return c }}, RunOutput: float64(1.25), Output: map[string]interface{}{"a": float32(1.25)}}, 53 {Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c string) string { return c }}, RunError: fmt.Errorf("function wants argument type string but received type bool"), Output: map[string]interface{}{"a": true}}, 54 55 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueBool, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueBool, Output: map[string]interface{}{"a": testVarValueBool}}, 56 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt32, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueInt32, Output: map[string]interface{}{"a": testVarValueInt32}}, 57 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt64, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueInt64, Output: map[string]interface{}{"a": testVarValueInt64}}, 58 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat32, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueFloat32, Output: map[string]interface{}{"a": testVarValueFloat32}}, 59 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat64, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueFloat64, Output: map[string]interface{}{"a": testVarValueFloat64}}, 60 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueString, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueString, Output: map[string]interface{}{"a": testVarValueString}}, 61 62 {Script: `func aFunc() {}; aFunc()`, RunOutput: nil}, 63 {Script: `func aFunc() { return }; aFunc()`, RunOutput: nil}, 64 {Script: `func aFunc() { return }; a = aFunc()`, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 65 {Script: `func aFunc() { return 1 }; aFunc()`, RunOutput: int64(1)}, 66 {Script: `func aFunc() { return 1 }; a = aFunc()`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 67 68 {Script: `func aFunc() {return nil}; aFunc()`, RunOutput: nil}, 69 {Script: `func aFunc() {return true}; aFunc()`, RunOutput: true}, 70 {Script: `func aFunc() {return 1}; aFunc()`, RunOutput: int64(1)}, 71 {Script: `func aFunc() {return 1.1}; aFunc()`, RunOutput: float64(1.1)}, 72 {Script: `func aFunc() {return "a"}; aFunc()`, RunOutput: "a"}, 73 74 {Script: `func aFunc() {return 1 + 2}; aFunc()`, RunOutput: int64(3)}, 75 {Script: `func aFunc() {return 1.25 + 2.25}; aFunc()`, RunOutput: float64(3.5)}, 76 {Script: `func aFunc() {return "a" + "b"}; aFunc()`, RunOutput: "ab"}, 77 78 {Script: `func aFunc() {return 1 + 2, 3 + 4}; aFunc()`, RunOutput: []interface{}{int64(3), int64(7)}}, 79 {Script: `func aFunc() {return 1.25 + 2.25, 3.25 + 4.25}; aFunc()`, RunOutput: []interface{}{float64(3.5), float64(7.5)}}, 80 {Script: `func aFunc() {return "a" + "b", "c" + "d"}; aFunc()`, RunOutput: []interface{}{"ab", "cd"}}, 81 82 {Script: `func aFunc() {return nil, nil}; aFunc()`, RunOutput: []interface{}{nil, nil}}, 83 {Script: `func aFunc() {return true, false}; aFunc()`, RunOutput: []interface{}{true, false}}, 84 {Script: `func aFunc() {return 1, 2}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}}, 85 {Script: `func aFunc() {return 1.1, 2.2}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}}, 86 {Script: `func aFunc() {return "a", "b"}; aFunc()`, RunOutput: []interface{}{"a", "b"}}, 87 88 {Script: `func aFunc() {return [nil]}; aFunc()`, RunOutput: []interface{}{nil}}, 89 {Script: `func aFunc() {return [nil, nil]}; aFunc()`, RunOutput: []interface{}{nil, nil}}, 90 {Script: `func aFunc() {return [nil, nil, nil]}; aFunc()`, RunOutput: []interface{}{nil, nil, nil}}, 91 {Script: `func aFunc() {return [nil, nil], [nil, nil]}; aFunc()`, RunOutput: []interface{}{[]interface{}{nil, nil}, []interface{}{nil, nil}}}, 92 93 {Script: `func aFunc() {return [true]}; aFunc()`, RunOutput: []interface{}{true}}, 94 {Script: `func aFunc() {return [true, false]}; aFunc()`, RunOutput: []interface{}{true, false}}, 95 {Script: `func aFunc() {return [true, false, true]}; aFunc()`, RunOutput: []interface{}{true, false, true}}, 96 {Script: `func aFunc() {return [true, false], [false, true]}; aFunc()`, RunOutput: []interface{}{[]interface{}{true, false}, []interface{}{false, true}}}, 97 98 {Script: `func aFunc() {return []}; aFunc()`, RunOutput: []interface{}{}}, 99 {Script: `func aFunc() {return [1]}; aFunc()`, RunOutput: []interface{}{int64(1)}}, 100 {Script: `func aFunc() {return [1, 2]}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}}, 101 {Script: `func aFunc() {return [1, 2, 3]}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2), int64(3)}}, 102 {Script: `func aFunc() {return [1, 2], [3, 4]}; aFunc()`, RunOutput: []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}, 103 104 {Script: `func aFunc() {return [1.1]}; aFunc()`, RunOutput: []interface{}{float64(1.1)}}, 105 {Script: `func aFunc() {return [1.1, 2.2]}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}}, 106 {Script: `func aFunc() {return [1.1, 2.2, 3.3]}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2), float64(3.3)}}, 107 {Script: `func aFunc() {return [1.1, 2.2], [3.3, 4.4]}; aFunc()`, RunOutput: []interface{}{[]interface{}{float64(1.1), float64(2.2)}, []interface{}{float64(3.3), float64(4.4)}}}, 108 109 {Script: `func aFunc() {return ["a"]}; aFunc()`, RunOutput: []interface{}{"a"}}, 110 {Script: `func aFunc() {return ["a", "b"]}; aFunc()`, RunOutput: []interface{}{"a", "b"}}, 111 {Script: `func aFunc() {return ["a", "b", "c"]}; aFunc()`, RunOutput: []interface{}{"a", "b", "c"}}, 112 {Script: `func aFunc() {return ["a", "b"], ["c", "d"]}; aFunc()`, RunOutput: []interface{}{[]interface{}{"a", "b"}, []interface{}{"c", "d"}}}, 113 114 {Script: `func aFunc() {return nil, nil}; aFunc()`, RunOutput: []interface{}{interface{}(nil), interface{}(nil)}}, 115 {Script: `func aFunc() {return true, false}; aFunc()`, RunOutput: []interface{}{true, false}}, 116 {Script: `func aFunc() {return 1, 2}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}}, 117 {Script: `func aFunc() {return 1.1, 2.2}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}}, 118 {Script: `func aFunc() {return "a", "b"}; aFunc()`, RunOutput: []interface{}{"a", "b"}}, 119 120 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunOutput: reflect.Value{}, Output: map[string]interface{}{"a": reflect.Value{}}}, 121 122 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 123 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 124 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 125 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 126 {Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}}, 127 128 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunOutput: []interface{}{reflect.Value{}, reflect.Value{}}, Output: map[string]interface{}{"a": reflect.Value{}}}, 129 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: []interface{}{nil, nil}, Output: map[string]interface{}{"a": nil}}, 130 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: []interface{}{true, true}, Output: map[string]interface{}{"a": true}}, 131 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: []interface{}{int32(1), int32(1)}, Output: map[string]interface{}{"a": int32(1)}}, 132 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: []interface{}{int64(1), int64(1)}, Output: map[string]interface{}{"a": int64(1)}}, 133 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": float32(1.1)}, RunOutput: []interface{}{float32(1.1), float32(1.1)}, Output: map[string]interface{}{"a": float32(1.1)}}, 134 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: []interface{}{float64(1.1), float64(1.1)}, Output: map[string]interface{}{"a": float64(1.1)}}, 135 {Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: []interface{}{"a", "a"}, Output: map[string]interface{}{"a": "a"}}, 136 137 {Script: `func a(x) { return x}; a(nil)`, RunOutput: nil}, 138 {Script: `func a(x) { return x}; a(true)`, RunOutput: true}, 139 {Script: `func a(x) { return x}; a(1)`, RunOutput: int64(1)}, 140 {Script: `func a(x) { return x}; a(1.1)`, RunOutput: float64(1.1)}, 141 {Script: `func a(x) { return x}; a("a")`, RunOutput: "a"}, 142 143 {Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 144 {Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": true}, RunOutput: nil, Output: map[string]interface{}{"a": true}}, 145 {Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 146 {Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: nil, Output: map[string]interface{}{"a": float64(1.1)}}, 147 {Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": "a"}, RunOutput: nil, Output: map[string]interface{}{"a": "a"}}, 148 149 {Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 150 {Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 151 {Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 152 {Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 153 {Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}}, 154 155 {Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 156 {Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 157 {Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 158 {Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 159 {Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}}, 160 161 {Script: `func aFunc() {return nil, nil}; a, b = aFunc()`, RunOutput: nil, Output: map[string]interface{}{"a": nil, "b": nil}}, 162 {Script: `func aFunc() {return true, false}; a, b = aFunc()`, RunOutput: false, Output: map[string]interface{}{"a": true, "b": false}}, 163 {Script: `func aFunc() {return 1, 2}; a, b = aFunc()`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(1), "b": int64(2)}}, 164 {Script: `func aFunc() {return 1.1, 2.2}; a, b = aFunc()`, RunOutput: float64(2.2), Output: map[string]interface{}{"a": float64(1.1), "b": float64(2.2)}}, 165 {Script: `func aFunc() {return "a", "b"}; a, b = aFunc()`, RunOutput: "b", Output: map[string]interface{}{"a": "a", "b": "b"}}, 166 } 167 runTests(t, tests, nil, &Options{Debug: true}) 168 } 169 170 func TestFunctions(t *testing.T) { 171 t.Parallel() 172 173 tests := []Test{ 174 {Script: `a()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunError: fmt.Errorf("cannot call type struct")}, 175 {Script: `a = nil; a()`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": nil}}, 176 {Script: `a = true; a()`, RunError: fmt.Errorf("cannot call type bool"), Output: map[string]interface{}{"a": true}}, 177 {Script: `a = nil; b = func c(d) { return d == nil }; c = nil; c(a)`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": nil}}, 178 {Script: `a = [true]; a()`, RunError: fmt.Errorf("cannot call type slice")}, 179 {Script: `a = [true]; func b(c) { return c() }; b(a)`, RunError: fmt.Errorf("cannot call type slice")}, 180 {Script: `a = {}; a.missing()`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": map[interface{}]interface{}{}}}, 181 {Script: `a = 1; b = func(,a){}; a`, ParseError: fmt.Errorf("syntax error: unexpected ','"), RunOutput: int64(1)}, 182 183 {Script: `func a(b) { }; a()`, RunError: fmt.Errorf("function wants 1 arguments but received 0")}, 184 {Script: `func a(b) { }; a(true, true)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")}, 185 {Script: `func a(b, c) { }; a()`, RunError: fmt.Errorf("function wants 2 arguments but received 0")}, 186 {Script: `func a(b, c) { }; a(true)`, RunError: fmt.Errorf("function wants 2 arguments but received 1")}, 187 {Script: `func a(b, c) { }; a(true, true, true)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")}, 188 189 {Script: `func a() { return "a" }; a.b()`, RunError: fmt.Errorf("type func does not support member operation")}, 190 {Script: `a = [func () { return nil}]; func b(c) { return c() }; b(a[1])`, RunError: fmt.Errorf("index out of range")}, 191 {Script: `func a() { return "a" }; b()`, RunError: fmt.Errorf("undefined symbol 'b'")}, 192 {Script: ` func a() { return "a" }; 1++()`, RunError: fmt.Errorf("invalid operation")}, 193 {Script: ` func a(b) { return b }; a(1++)`, RunError: fmt.Errorf("invalid operation")}, 194 195 {Script: `a`, Input: map[string]interface{}{"a": testVarFunc}, RunOutput: testVarFunc, Output: map[string]interface{}{"a": testVarFunc}}, 196 {Script: `a()`, Input: map[string]interface{}{"a": testVarFunc}, RunOutput: int64(1), Output: map[string]interface{}{"a": testVarFunc}}, 197 {Script: `a`, Input: map[string]interface{}{"a": testVarFuncP}, RunOutput: testVarFuncP, Output: map[string]interface{}{"a": testVarFuncP}}, 198 // TOFIX: 199 // {Script: `a()`, Input: map[string]interface{}{"a": testVarFuncP}, RunOutput: int64(1), Output: map[string]interface{}{"a": testVarFuncP}}, 200 201 {Script: `module a { func b() { return } }; a.b()`, RunOutput: nil}, 202 {Script: `module a { func b() { return nil} }; a.b()`, RunOutput: nil}, 203 {Script: `module a { func b() { return true} }; a.b()`, RunOutput: true}, 204 {Script: `module a { func b() { return 1} }; a.b()`, RunOutput: int64(1)}, 205 {Script: `module a { func b() { return 1.1} }; a.b()`, RunOutput: float64(1.1)}, 206 {Script: `module a { func b() { return "a"} }; a.b()`, RunOutput: "a"}, 207 208 {Script: `if true { module a { func b() { return } } }; a.b()`, RunError: fmt.Errorf("undefined symbol 'a'")}, 209 210 {Script: `a = 1; func b() { a = 2 }; b()`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 211 {Script: `b(a); a`, Input: map[string]interface{}{"a": int64(1), "b": func(c interface{}) { c = int64(2); _ = c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 212 {Script: `func b() { }; go b()`, RunOutput: nil}, 213 214 {Script: `b(a)`, Input: map[string]interface{}{"a": nil, "b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 215 {Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 216 {Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int32) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int32(1)}}, 217 {Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int64) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 218 {Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.1), "b": func(c float32) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float32(1.1)}}, 219 {Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.1), "b": func(c float64) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 220 {Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 221 222 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueBool, "b": func(c reflect.Value) bool { return c == testVarValueBool }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueBool}}, 223 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt32, "b": func(c reflect.Value) bool { return c == testVarValueInt32 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueInt32}}, 224 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt64, "b": func(c reflect.Value) bool { return c == testVarValueInt64 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueInt64}}, 225 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat32, "b": func(c reflect.Value) bool { return c == testVarValueFloat32 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueFloat32}}, 226 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat64, "b": func(c reflect.Value) bool { return c == testVarValueFloat64 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueFloat64}}, 227 {Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueString, "b": func(c reflect.Value) bool { return c == testVarValueString }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueString}}, 228 229 {Script: `x(a, b, c, d, e, f, g)`, Input: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g", 230 "x": func(a interface{}, b bool, c int32, d int64, e float32, f float64, g string) bool { 231 return a == nil && b == true && c == 1 && d == 2 && e == 1.1 && f == 2.2 && g == "g" 232 }}, RunOutput: true, Output: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g"}}, 233 {Script: `x(a, b, c, d, e, f, g)`, Input: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g", 234 "x": func(a interface{}, b bool, c int32, d int64, e float32, f float64, g string) (interface{}, bool, int32, int64, float32, float64, string) { 235 return a, b, c, d, e, f, g 236 }}, RunOutput: []interface{}{nil, true, int32(1), int64(2), float32(1.1), float64(2.2), "g"}, Output: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g"}}, 237 238 {Script: `b = a()`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}, Output: map[string]interface{}{"b": []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}}}, 239 {Script: `b = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}, Output: map[string]interface{}{"b": []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}}}, 240 {Script: `b, c = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1)}}, 241 {Script: `b, c, d = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2)}}, 242 {Script: `b, c, d, e = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3)}}, 243 {Script: `b, c, d, e, f = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3), "f": float64(4.4)}}, 244 {Script: `b, c, d, e, f, g = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3), "f": float64(4.4), "g": "5"}}, 245 246 {Script: `a = nil; b(a)`, Input: map[string]interface{}{"b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 247 {Script: `a = true; b(a)`, Input: map[string]interface{}{"b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 248 {Script: `a = 1; b(a)`, Input: map[string]interface{}{"b": func(c int64) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 249 {Script: `a = 1.1; b(a)`, Input: map[string]interface{}{"b": func(c float64) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 250 {Script: `a = "a"; b(a)`, Input: map[string]interface{}{"b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 251 252 {Script: `func b(c) { return c == nil }; b(a)`, Input: map[string]interface{}{"a": nil}, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 253 {Script: `func b(c) { return c == true }; b(a)`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 254 {Script: `func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: true, Output: map[string]interface{}{"a": int32(1)}}, 255 {Script: `func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 256 {Script: `func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float32(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float32(1.1)}}, 257 {Script: `func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 258 {Script: `func b(c) { return c == "a" }; b(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 259 260 {Script: `a = nil; func b(c) { return c == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 261 {Script: `a = true; func b(c) { return c == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}}, 262 {Script: `a = 1; func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 263 {Script: `a = 1.1; func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 264 {Script: `a = "a"; func b(c) { return c == "a" }; b(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 265 266 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{nil}, "b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}}, 267 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{true}, "b": func(c interface{}) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}}, 268 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int32(1)}, "b": func(c interface{}) bool { return c == int32(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int32(1)}}}, 269 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int64(1)}, "b": func(c interface{}) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 270 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}, "b": func(c interface{}) bool { return c == float32(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}}, 271 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}, "b": func(c interface{}) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}}, 272 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{"a"}, "b": func(c interface{}) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}}, 273 274 // TOFIX: 275 // {Script: `b(a)`, 276 // Input: map[string]interface{}{"a": []bool{true, false, true}, "b": func(c ...bool) bool { return c[len(c)-1] }}, 277 // RunOutput: true, Output: map[string]interface{}{"a": true}}, 278 279 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{true}, "b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}}, 280 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int32(1)}, "b": func(c int32) bool { return c == int32(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int32(1)}}}, 281 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int64(1)}, "b": func(c int64) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 282 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}, "b": func(c float32) bool { return c == float32(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}}, 283 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}, "b": func(c float64) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}}, 284 {Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{"a"}, "b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}}, 285 286 {Script: `a = [nil]; b(a[0])`, Input: map[string]interface{}{"b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}}, 287 {Script: `a = [true]; b(a[0])`, Input: map[string]interface{}{"b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}}, 288 {Script: `a = [1]; b(a[0])`, Input: map[string]interface{}{"b": func(c int64) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 289 {Script: `a = [1.1]; b(a[0])`, Input: map[string]interface{}{"b": func(c float64) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}}, 290 {Script: `a = ["a"]; b(a[0])`, Input: map[string]interface{}{"b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}}, 291 292 {Script: `a = [nil]; func b(c) { c == nil }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}}, 293 {Script: `a = [true]; func b(c) { c == true }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}}, 294 {Script: `a = [1]; func b(c) { c == 1 }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 295 {Script: `a = [1.1]; func b(c) { c == 1.1 }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}}, 296 {Script: `a = ["a"]; func b(c) { c == "a" }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}}, 297 298 {Script: `a = nil; b = func (d) { return d == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 299 {Script: `a = true; b = func (d) { return d == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}}, 300 {Script: `a = 1; b = func (d) { return d == 1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 301 {Script: `a = 1.1; b = func (d) { return d == 1.1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 302 {Script: `a = "a"; b = func (d) { return d == "a" }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 303 304 {Script: `a = nil; b = func c(d) { return d == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 305 {Script: `a = true; b = func c(d) { return d == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}}, 306 {Script: `a = 1; b = func c(d) { return d == 1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 307 {Script: `a = 1.1; b = func c(d) { return d == 1.1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 308 {Script: `a = "a"; b = func c(d) { return d == "a" }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 309 310 {Script: `a = nil; b = func c(d) { return d == nil }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 311 {Script: `a = true; b = func c(d) { return d == true }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}}, 312 {Script: `a = 1; b = func c(d) { return d == 1 }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 313 {Script: `a = 1.1; b = func c(d) { return d == 1.1 }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 314 {Script: `a = "a"; b = func c(d) { return d == "a" }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 315 316 {Script: `a = nil; func b() { return func c(d) { d == nil } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 317 {Script: `a = true; func b() { return func c(d) { d == true } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}}, 318 {Script: `a = 1; func b() { return func c(d) { d == 1 } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}}, 319 {Script: `a = 1.1; func b() { return func c(d) { d == 1.1 } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}}, 320 {Script: `a = "a"; func b() { return func c(d) { d == "a" } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}}, 321 322 {Script: `a = func () { return nil }; func b(c) { return c() }; b(a)`, RunOutput: nil}, 323 {Script: `a = func () { return true }; func b(c) { return c() }; b(a)`, RunOutput: true}, 324 {Script: `a = func () { return 1 }; func b(c) { return c() }; b(a)`, RunOutput: int64(1)}, 325 {Script: `a = func () { return 1.1 }; func b(c) { return c() }; b(a)`, RunOutput: float64(1.1)}, 326 {Script: `a = func () { return "a" }; func b(c) { return c() }; b(a)`, RunOutput: "a"}, 327 328 {Script: `a = [nil]; func c(d) { return d[0] }; c(a)`, RunOutput: nil}, 329 {Script: `a = [true]; func c(d) { return d[0] }; c(a)`, RunOutput: true}, 330 {Script: `a = [1]; func c(d) { return d[0] }; c(a)`, RunOutput: int64(1)}, 331 {Script: `a = [1.1]; func c(d) { return d[0] }; c(a)`, RunOutput: float64(1.1)}, 332 {Script: `a = ["a"]; func c(d) { return d[0] }; c(a)`, RunOutput: "a"}, 333 334 {Script: `a = {"b": nil}; func c(d) { return d.b }; c(a)`, RunOutput: nil}, 335 {Script: `a = {"b": true}; func c(d) { return d.b }; c(a)`, RunOutput: true}, 336 {Script: `a = {"b": 1}; func c(d) { return d.b }; c(a)`, RunOutput: int64(1)}, 337 {Script: `a = {"b": 1.1}; func c(d) { return d.b }; c(a)`, RunOutput: float64(1.1)}, 338 {Script: `a = {"b": "a"}; func c(d) { return d.b }; c(a)`, RunOutput: "a"}, 339 340 {Script: `a = func() { return func(c) { return c + "c"} }; a()("a")`, RunOutput: "ac"}, 341 {Script: `a = func() { return func(c) { return c + "c"} }(); a("a")`, RunOutput: "ac"}, 342 {Script: `a = func() { return func(c) { return c + "c"} }()("a")`, RunOutput: "ac"}, 343 {Script: `func() { return func(c) { return c + "c"} }()("a")`, RunOutput: "ac"}, 344 345 {Script: `a = func(b) { return func() { return b + "c"} }; b = a("a"); b()`, RunOutput: "ac"}, 346 {Script: `a = func(b) { return func() { return b + "c"} }("a"); a()`, RunOutput: "ac"}, 347 {Script: `a = func(b) { return func() { return b + "c"} }("a")()`, RunOutput: "ac"}, 348 {Script: `func(b) { return func() { return b + "c"} }("a")()`, RunOutput: "ac"}, 349 350 {Script: `a = func(b) { return func(c) { return b[c] } }; b = a({"x": "x"}); b("x")`, RunOutput: "x"}, 351 {Script: `a = func(b) { return func(c) { return b[c] } }({"x": "x"}); a("x")`, RunOutput: "x"}, 352 {Script: `a = func(b) { return func(c) { return b[c] } }({"x": "x"})("x")`, RunOutput: "x"}, 353 {Script: `func(b) { return func(c) { return b[c] } }({"x": "x"})("x")`, RunOutput: "x"}, 354 355 {Script: `a = func(b) { return func(c) { return b[c] } }; x = {"y": "y"}; b = a(x); x = {"y": "y"}; b("y")`, RunOutput: "y"}, 356 {Script: `a = func(b) { return func(c) { return b[c] } }; x = {"y": "y"}; b = a(x); x.y = "z"; b("y")`, RunOutput: "z"}, 357 358 {Script: ` func a() { return "a" }; a()`, RunOutput: "a"}, 359 {Script: `a = func a() { return "a" }; a = func() { return "b" }; a()`, RunOutput: "b"}, 360 {Script: `a = "a.b"; func a() { return "a" }; a()`, RunOutput: "a"}, 361 362 {Script: `a = func() { b = "b"; return func() { b += "c" } }(); a()`, RunOutput: "bc"}, 363 {Script: `a = func() { b = "b"; return func() { b += "c"; return b} }(); a()`, RunOutput: "bc"}, 364 {Script: `a = func(b) { return func(c) { return func(d) { return d + "d" }(c) + "c" }(b) + "b" }("a")`, RunOutput: "adcb"}, 365 {Script: `a = func(b) { return "b" + func(c) { return "c" + func(d) { return "d" + d }(c) }(b) }("a")`, RunOutput: "bcda"}, 366 {Script: `a = func(b) { return b + "b" }; a( func(c) { return c + "c" }("a") )`, RunOutput: "acb"}, 367 368 {Script: `a = func(x, y) { return func() { x(y) } }; b = a(func (z) { return z + "z" }, "b"); b()`, RunOutput: "bz"}, 369 370 {Script: `a = make(Time); a.IsZero()`, Types: map[string]interface{}{"Time": time.Time{}}, RunOutput: true}, 371 372 {Script: `a = make(Buffer); n, err = a.WriteString("a"); if err != nil { return err }; n`, Types: map[string]interface{}{"Buffer": bytes.Buffer{}}, RunOutput: 1}, 373 {Script: `a = make(Buffer); n, err = a.WriteString("a"); if err != nil { return err }; a.String()`, Types: map[string]interface{}{"Buffer": bytes.Buffer{}}, RunOutput: "a"}, 374 375 {Script: `b = {}; c = a(b.c); c`, Input: map[string]interface{}{"a": func(b string) bool { 376 if b == "" { 377 return true 378 } 379 return false 380 }}, RunOutput: true}, 381 } 382 runTests(t, tests, nil, &Options{Debug: true}) 383 } 384 385 func TestPointerFunctions(t *testing.T) { 386 t.Parallel() 387 388 testFunctionPointer := func(b interface{}) string { 389 rv := reflect.ValueOf(b) 390 if !rv.IsValid() { 391 return "invalid" 392 } 393 if rv.Kind() != reflect.Ptr { 394 return fmt.Sprintf("not ptr: " + rv.Kind().String()) 395 } 396 if rv.IsNil() { 397 return "IsNil" 398 } 399 if !rv.Elem().CanInterface() { 400 return "cannot interface" 401 } 402 if rv.Elem().Interface() != int64(1) { 403 return fmt.Sprintf("not 1: %v", rv.Elem().Interface()) 404 } 405 if !rv.Elem().CanSet() { 406 return "cannot set" 407 } 408 slice := reflect.MakeSlice(interfaceSliceType, 0, 1) 409 value, _ := makeValue(stringType) 410 value.SetString("b") 411 slice = reflect.Append(slice, value) 412 rv.Elem().Set(slice) 413 return "good" 414 } 415 tests := []Test{ 416 {Script: `b = 1; a(&b)`, Input: map[string]interface{}{"a": testFunctionPointer}, RunOutput: "good", Output: map[string]interface{}{"b": []interface{}{"b"}}}, 417 } 418 runTests(t, tests, nil, &Options{Debug: true}) 419 } 420 421 func TestVariadicFunctions(t *testing.T) { 422 t.Parallel() 423 424 tests := []Test{ 425 // params Variadic arg !Variadic 426 {Script: `func a(b...) { return b }; a()`, RunOutput: []interface{}{}}, 427 {Script: `func a(b...) { return b }; a(true)`, RunOutput: []interface{}{true}}, 428 {Script: `func a(b...) { return b }; a(true, true)`, RunOutput: []interface{}{true, true}}, 429 {Script: `func a(b...) { return b }; a([true])`, RunOutput: []interface{}{[]interface{}{true}}}, 430 {Script: `func a(b...) { return b }; a([true, true])`, RunOutput: []interface{}{[]interface{}{true, true}}}, 431 {Script: `func a(b...) { return b }; a([true, true], [true, true])`, RunOutput: []interface{}{[]interface{}{true, true}, []interface{}{true, true}}}, 432 433 // params Variadic arg !Variadic 434 {Script: `func a(b, c...) { return c }; a()`, RunError: fmt.Errorf("function wants 2 arguments but received 0")}, 435 {Script: `func a(b, c...) { return c }; a(true)`, RunOutput: []interface{}{}}, 436 {Script: `func a(b, c...) { return c }; a(true, true)`, RunOutput: []interface{}{true}}, 437 {Script: `func a(b, c...) { return c }; a(true, true, true)`, RunOutput: []interface{}{true, true}}, 438 {Script: `func a(b, c...) { return c }; a([true])`, RunOutput: []interface{}{}}, 439 {Script: `func a(b, c...) { return c }; a([true], [true])`, RunOutput: []interface{}{[]interface{}{true}}}, 440 {Script: `func a(b, c...) { return c }; a([true], [true], [true])`, RunOutput: []interface{}{[]interface{}{true}, []interface{}{true}}}, 441 {Script: `func a(b, c...) { return c }; a([true], [true, true], [true, true])`, RunOutput: []interface{}{[]interface{}{true, true}, []interface{}{true, true}}}, 442 443 // params Variadic arg Variadic 444 {Script: `func a(b...) { return b }; a([true]...)`, RunOutput: []interface{}{true}}, 445 {Script: `func a(b...) { return b }; a([true, true]...)`, RunOutput: []interface{}{true, true}}, 446 {Script: `func a(b...) { return b }; a(true, [true]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")}, 447 448 // params Variadic arg Variadic 449 {Script: `func a(b, c...) { return c }; a([true]...)`, RunOutput: []interface{}{}}, 450 {Script: `func a(b, c...) { return c }; a([true, true]...)`, RunOutput: []interface{}{}}, 451 {Script: `func a(b, c...) { return c }; a(true, [true]...)`, RunOutput: []interface{}{true}}, 452 {Script: `func a(b, c...) { return c }; a(true, [true, true]...)`, RunOutput: []interface{}{true, true}}, 453 454 // params !Variadic arg Variadic 455 {Script: `func a() { return "a" }; a([true]...)`, RunOutput: "a"}, 456 {Script: `func a() { return "a" }; a(true, [true]...)`, RunOutput: "a"}, 457 {Script: `func a() { return "a" }; a(true, [true, true]...)`, RunOutput: "a"}, 458 459 // params !Variadic arg Variadic 460 {Script: `func a(b) { return b }; a(true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")}, 461 {Script: `func a(b) { return b }; a([true]...)`, RunOutput: true}, 462 {Script: `func a(b) { return b }; a(true, false...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")}, 463 {Script: `func a(b) { return b }; a(true, [1]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")}, 464 {Script: `func a(b) { return b }; a(true, [1, 2]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")}, 465 {Script: `func a(b) { return b }; a([true, 1]...)`, RunOutput: true}, 466 {Script: `func a(b) { return b }; a([true, 1, 2]...)`, RunOutput: true}, 467 468 // params !Variadic arg Variadi 469 {Script: `func a(b, c) { return c }; a(false...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")}, 470 {Script: `func a(b, c) { return c }; a([1]...)`, RunError: fmt.Errorf("function wants 2 arguments but received 1")}, 471 {Script: `func a(b, c) { return c }; a(1, true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")}, 472 {Script: `func a(b, c) { return c }; a(1, [true]...)`, RunOutput: true}, 473 {Script: `func a(b, c) { return c }; a([1, true]...)`, RunOutput: true}, 474 {Script: `func a(b, c) { return c }; a(1, true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")}, 475 {Script: `func a(b, c) { return c }; a(1, [true]...)`, RunOutput: true}, 476 {Script: `func a(b, c) { return c }; a(1, true, false...)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")}, 477 {Script: `func a(b, c) { return c }; a(1, true, [2]...)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")}, 478 {Script: `func a(b, c) { return c }; a(1, [true, 2]...)`, RunOutput: true}, 479 {Script: `func a(b, c) { return c }; a([1, true, 2]...)`, RunOutput: true}, 480 } 481 runTests(t, tests, nil, &Options{Debug: true}) 482 } 483 484 func TestFunctionsInArraysAndMaps(t *testing.T) { 485 t.Parallel() 486 487 tests := []Test{ 488 {Script: `a = [func () { return nil }]; a[0]()`, RunOutput: nil}, 489 {Script: `a = [func () { return true }]; a[0]()`, RunOutput: true}, 490 {Script: `a = [func () { return 1 }]; a[0]()`, RunOutput: int64(1)}, 491 {Script: `a = [func () { return 1.1 }]; a[0]()`, RunOutput: float64(1.1)}, 492 {Script: `a = [func () { return "a" }]; a[0]()`, RunOutput: "a"}, 493 494 {Script: `a = [func () { return nil }]; b = a[0]; b()`, RunOutput: nil}, 495 {Script: `a = [func () { return true }]; b = a[0]; b()`, RunOutput: true}, 496 {Script: `a = [func () { return 1 }]; b = a[0]; b()`, RunOutput: int64(1)}, 497 {Script: `a = [func () { return 1.1 }]; b = a[0]; b()`, RunOutput: float64(1.1)}, 498 {Script: `a = [func () { return "a" }]; b = a[0]; b()`, RunOutput: "a"}, 499 500 {Script: `a = [func () { return nil}]; func b(c) { return c() }; b(a[0])`, RunOutput: nil}, 501 {Script: `a = [func () { return true}]; func b(c) { return c() }; b(a[0])`, RunOutput: true}, 502 {Script: `a = [func () { return 1}]; func b(c) { return c() }; b(a[0])`, RunOutput: int64(1)}, 503 {Script: `a = [func () { return 1.1}]; func b(c) { return c() }; b(a[0])`, RunOutput: float64(1.1)}, 504 {Script: `a = [func () { return "a"}]; func b(c) { return c() }; b(a[0])`, RunOutput: "a"}, 505 506 {Script: `a = {"b": func () { return nil }}; a["b"]()`, RunOutput: nil}, 507 {Script: `a = {"b": func () { return true }}; a["b"]()`, RunOutput: true}, 508 {Script: `a = {"b": func () { return 1 }}; a["b"]()`, RunOutput: int64(1)}, 509 {Script: `a = {"b": func () { return 1.1 }}; a["b"]()`, RunOutput: float64(1.1)}, 510 {Script: `a = {"b": func () { return "a" }}; a["b"]()`, RunOutput: "a"}, 511 512 {Script: `a = {"b": func () { return nil }}; a.b()`, RunOutput: nil}, 513 {Script: `a = {"b": func () { return true }}; a.b()`, RunOutput: true}, 514 {Script: `a = {"b": func () { return 1 }}; a.b()`, RunOutput: int64(1)}, 515 {Script: `a = {"b": func () { return 1.1 }}; a.b()`, RunOutput: float64(1.1)}, 516 {Script: `a = {"b": func () { return "a" }}; a.b()`, RunOutput: "a"}, 517 518 {Script: `a = {"b": func () { return nil }}; func c(d) { return d() }; c(a.b)`, RunOutput: nil}, 519 {Script: `a = {"b": func () { return true }}; func c(d) { return d() }; c(a.b)`, RunOutput: true}, 520 {Script: `a = {"b": func () { return 1 }}; func c(d) { return d() }; c(a.b)`, RunOutput: int64(1)}, 521 {Script: `a = {"b": func () { return 1.1 }}; func c(d) { return d() }; c(a.b)`, RunOutput: float64(1.1)}, 522 {Script: `a = {"b": func () { return "a" }}; func c(d) { return d() }; c(a.b)`, RunOutput: "a"}, 523 } 524 runTests(t, tests, nil, &Options{Debug: true}) 525 } 526 527 func TestFunctionConversions(t *testing.T) { 528 t.Parallel() 529 530 tests := []Test{ 531 {Script: `b = func(c){ return c }; a("x", b)`, Input: map[string]interface{}{"a": func(b string, c func(string) string) string { return c(b) }}, RunOutput: "x"}, 532 {Script: `b = make(struct1); b.A = func (c, d) { return c == d }; b.A(2, 2)`, Types: map[string]interface{}{"struct1": &struct { 533 A func(int, int) bool 534 }{}}, 535 RunOutput: true}, 536 {Script: `b = 1; a(&b)`, Input: map[string]interface{}{"a": func(b *int64) { *b = int64(2) }}, Output: map[string]interface{}{"b": int64(2)}}, 537 {Script: `b = func(){ return true, 1, 2, 3.3, 4.4, "5" }; c, d, e, f, g, h = a(b); c`, Input: map[string]interface{}{"a": func(b func() (bool, int32, int64, float32, float64, string)) (bool, int32, int64, float32, float64, string) { 538 return b() 539 }}, RunOutput: true, Output: map[string]interface{}{"c": true, "d": int32(1), "e": int64(2), "f": float32(3.3), "g": float64(4.4), "h": "5"}}, 540 541 // string to byte 542 {Script: `b = a("yz"); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunError: fmt.Errorf("function wants argument type uint8 but received type string")}, 543 {Script: `b = a("x"); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunOutput: "x"}, 544 {Script: `b = a(""); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunOutput: "\x00"}, 545 // string to rune 546 {Script: `b = a("yz"); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunError: fmt.Errorf("function wants argument type int32 but received type string")}, 547 {Script: `b = a("x"); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunOutput: "x"}, 548 {Script: `b = a(""); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunOutput: "\x00"}, 549 550 // slice inteface unable to convert to int 551 {Script: `b = [1, 2.2, "3"]; a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }}, RunError: fmt.Errorf("function wants argument type []int but received type []interface {}"), Output: map[string]interface{}{"b": []interface{}{int64(1), float64(2.2), "3"}}}, 552 // slice no sub convertible conversion 553 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }, "b": []int64{1}}, RunOutput: int(1), Output: map[string]interface{}{"b": []int64{1}}}, 554 // array no sub convertible conversion 555 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [2]int64{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]int64{1, 2}}}, 556 // slice no sub to interface conversion 557 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b []interface{}) int { return len(b) }, "b": []int64{1}}, RunOutput: int(1), Output: map[string]interface{}{"b": []int64{1}}}, 558 // array no sub to interface conversion 559 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]interface{}) int { return len(b) }, "b": [2]int64{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]int64{1, 2}}}, 560 // slice no sub from interface conversion 561 {Script: `b = [1]; a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }}, RunOutput: int(1), Output: map[string]interface{}{"b": []interface{}{int64(1)}}}, 562 // array no sub from interface conversion 563 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [2]interface{}{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]interface{}{1, 2}}}, 564 565 // slice sub mismatch 566 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }, "b": [][]int64{{1, 2}}}, RunError: fmt.Errorf("function wants argument type []int but received type [][]int64"), Output: map[string]interface{}{"b": [][]int64{{1, 2}}}}, 567 // array sub mismatch 568 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [1][2]int64{{1, 2}}}, RunError: fmt.Errorf("function wants argument type [2]int but received type [1][2]int64"), Output: map[string]interface{}{"b": [1][2]int64{{1, 2}}}}, 569 570 // slice with sub int64 to int conversion 571 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [][]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]int64{{1, 2}, {3, 4}}}}, 572 // array with sub int64 to int conversion 573 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [2][2]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]int64{{1, 2}, {3, 4}}}}, 574 // slice with sub interface to int conversion 575 {Script: `b = [[1, 2], [3, 4]]; a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }}, RunOutput: int(2), Output: map[string]interface{}{"b": []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}}, 576 // slice with sub interface to int conversion 577 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [][]interface{}{{int64(1), int32(2)}, {float64(3.3), float32(4.4)}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]interface{}{{int64(1), int32(2)}, {float64(3.3), float32(4.4)}}}}, 578 // array with sub interface to int conversion 579 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [2][2]interface{}{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]interface{}{{1, 2}, {3, 4}}}}, 580 // slice with single interface to double interface 581 {Script: `b = [[1, 2], [3, 4]]; a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }}, RunOutput: int(2), Output: map[string]interface{}{"b": []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}}, 582 // slice with sub int64 to double interface conversion 583 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }, "b": [][]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]int64{{1, 2}, {3, 4}}}}, 584 // array with sub int64 to double interface conversion 585 {Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }, "b": [2][2]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]int64{{1, 2}, {3, 4}}}}, 586 587 // TOFIX: not able to change pointer value 588 // {Script: `b = 1; c = &b; a(c); *c`, Input: map[string]interface{}{"a": func(b *int64) { *b = int64(2) }}, RunOutput: int64(2), Output: map[string]interface{}{"b": int64(2)}}, 589 590 // map [interface]interface to [interface]interface 591 {Script: `b = {nil:nil}; c = nil; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{nil: nil}, "c": nil}}, 592 {Script: `b = {true:true}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: true}, "c": true}}, 593 {Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}}, 594 {Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}}, 595 {Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}}, 596 597 // map [interface]interface to [bool]interface 598 {Script: `b = {"a":"b"}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[bool]interface {} but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": true}}, 599 {Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[bool]interface {} but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}}, 600 {Script: `b = {true:"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type bool but received type string"), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: "b"}, "c": "a"}}, 601 {Script: `b = {true:nil}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: nil}, "c": true}}, 602 {Script: `b = {true:true}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: true}, "c": true}}, 603 {Script: `b = {true:2}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: int64(2)}, "c": true}}, 604 {Script: `b = {true:2.2}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: float64(2.2)}, "c": true}}, 605 {Script: `b = {true:"b"}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{true: "b"}, "c": true}}, 606 607 // map [interface]interface to [int32]interface 608 {Script: `b = {1:nil}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): nil}, "c": int64(1)}}, 609 {Script: `b = {1:true}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): true}, "c": int64(1)}}, 610 {Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}}, 611 {Script: `b = {1:2.2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): float64(2.2)}, "c": int64(1)}}, 612 {Script: `b = {1:"b"}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): "b"}, "c": int64(1)}}, 613 614 // map [interface]interface to [int64]interface 615 {Script: `b = {1:nil}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): nil}, "c": int64(1)}}, 616 {Script: `b = {1:true}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): true}, "c": int64(1)}}, 617 {Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}}, 618 {Script: `b = {1:2.2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): float64(2.2)}, "c": int64(1)}}, 619 {Script: `b = {1:"b"}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): "b"}, "c": int64(1)}}, 620 621 // map [interface]interface to [float32]interface 622 {Script: `b = {1.1:nil}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): nil}, "c": float64(1.1)}}, 623 {Script: `b = {1.1:true}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): true}, "c": float64(1.1)}}, 624 {Script: `b = {1.1:2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): int64(2)}, "c": float64(1.1)}}, 625 {Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}}, 626 {Script: `b = {1.1:"b"}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): "b"}, "c": float64(1.1)}}, 627 628 // map [interface]interface to [float64]interface 629 {Script: `b = {1.1:nil}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): nil}, "c": float64(1.1)}}, 630 {Script: `b = {1.1:true}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): true}, "c": float64(1.1)}}, 631 {Script: `b = {1.1:2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): int64(2)}, "c": float64(1.1)}}, 632 {Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}}, 633 {Script: `b = {1.1:"b"}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): "b"}, "c": float64(1.1)}}, 634 635 // map [interface]interface to [string]interface 636 {Script: `b = {"a":nil}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": nil}, "c": "a"}}, 637 {Script: `b = {"a":true}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": true}, "c": "a"}}, 638 {Script: `b = {"a":2}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(2)}, "c": "a"}}, 639 {Script: `b = {"a":2.2}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(2.2)}, "c": "a"}}, 640 {Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}}, 641 642 // map [interface]interface to [string]X 643 {Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]bool, c string) bool { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[string]bool but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}}, 644 {Script: `b = {"a":true}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]bool, c string) bool { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": true}, "c": "a"}}, 645 {Script: `b = {"a":1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]int32, c string) int32 { return b[c] }}, RunOutput: int32(1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(1)}, "c": "a"}}, 646 {Script: `b = {"a":1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]int64, c string) int64 { return b[c] }}, RunOutput: int64(1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(1)}, "c": "a"}}, 647 {Script: `b = {"a":1.1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]float32, c string) float32 { return b[c] }}, RunOutput: float32(1.1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(1.1)}, "c": "a"}}, 648 {Script: `b = {"a":1.1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]float64, c string) float64 { return b[c] }}, RunOutput: float64(1.1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(1.1)}, "c": "a"}}, 649 {Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]string, c string) string { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}}, 650 } 651 runTests(t, tests, nil, &Options{Debug: true}) 652 653 tests = []Test{ 654 {Script: `c = a(b)`, 655 Input: map[string]interface{}{"a": func(b func() bool) bool { 656 return b() 657 }, "b": func(c func(bool)) { c(true) }}, RunError: fmt.Errorf("function wants argument type func() bool but received type func(func(bool))")}, 658 {Script: `b = func(){ return 1++ }; c = a(b)`, 659 Input: map[string]interface{}{"a": func(b func() bool) bool { 660 return b() 661 }}, RunError: fmt.Errorf("invalid operation")}, 662 {Script: `b = func(){ return true }; c = a(b)`, 663 Input: map[string]interface{}{"a": func(b func() string) string { 664 return b() 665 }}, RunError: fmt.Errorf("function wants return type string but received type bool")}, 666 {Script: `b = func(){ return true }; c = a(b)`, 667 Input: map[string]interface{}{"a": func(b func() (bool, string)) (bool, string) { 668 return b() 669 }}, RunError: fmt.Errorf("function wants 2 return values but received bool")}, 670 {Script: `b = func(){ return true, 1 }; c = a(b)`, 671 Input: map[string]interface{}{"a": func(b func() (bool, int64, string)) (bool, int64, string) { 672 return b() 673 }}, RunError: fmt.Errorf("function wants 3 return values but received 2 values")}, 674 {Script: `b = func(){ return "1", true }; c = a(b)`, 675 Input: map[string]interface{}{"a": func(b func() (bool, string)) (bool, string) { 676 return b() 677 }}, RunError: fmt.Errorf("function wants return type bool but received type string")}, 678 } 679 runTests(t, tests, nil, &Options{Debug: false}) 680 } 681 682 func TestVariadicFunctionConversions(t *testing.T) { 683 t.Parallel() 684 685 testSumFunc := func(nums ...int64) int64 { 686 var total int64 687 for _, num := range nums { 688 total += num 689 } 690 return total 691 } 692 tests := []Test{ 693 // params Variadic arg !Variadic 694 {Script: `a(true)`, Input: map[string]interface{}{"a": func(b ...interface{}) []interface{} { return b }}, RunOutput: []interface{}{true}}, 695 696 {Script: `a()`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(0)}, 697 {Script: `a(1)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(1)}, 698 {Script: `a(1, 2)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(3)}, 699 {Script: `a(1, 2, 3)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(6)}, 700 701 // TODO: add more tests 702 } 703 runTests(t, tests, nil, &Options{Debug: true}) 704 } 705 706 func TestLen(t *testing.T) { 707 t.Parallel() 708 709 tests := []Test{ 710 {Script: `len(1++)`, RunError: fmt.Errorf("invalid operation")}, 711 {Script: `len(true)`, RunError: fmt.Errorf("type bool does not support len operation")}, 712 713 {Script: `a = ""; len(a)`, RunOutput: int64(0)}, 714 {Script: `a = "test"; len(a)`, RunOutput: int64(4)}, 715 {Script: `a = []; len(a)`, RunOutput: int64(0)}, 716 {Script: `a = [nil]; len(a)`, RunOutput: int64(1)}, 717 {Script: `a = [true]; len(a)`, RunOutput: int64(1)}, 718 {Script: `a = ["test"]; len(a)`, RunOutput: int64(1)}, 719 {Script: `a = [1]; len(a)`, RunOutput: int64(1)}, 720 {Script: `a = [1.1]; len(a)`, RunOutput: int64(1)}, 721 722 {Script: `a = [[]]; len(a)`, RunOutput: int64(1)}, 723 {Script: `a = [[nil]]; len(a)`, RunOutput: int64(1)}, 724 {Script: `a = [[true]]; len(a)`, RunOutput: int64(1)}, 725 {Script: `a = [["test"]]; len(a)`, RunOutput: int64(1)}, 726 {Script: `a = [[1]]; len(a)`, RunOutput: int64(1)}, 727 {Script: `a = [[1.1]]; len(a)`, RunOutput: int64(1)}, 728 729 {Script: `a = [[]]; len(a[0])`, RunOutput: int64(0)}, 730 {Script: `a = [[nil]]; len(a[0])`, RunOutput: int64(1)}, 731 {Script: `a = [[true]]; len(a[0])`, RunOutput: int64(1)}, 732 {Script: `a = [["test"]]; len(a[0])`, RunOutput: int64(1)}, 733 {Script: `a = [[1]]; len(a[0])`, RunOutput: int64(1)}, 734 {Script: `a = [[1.1]]; len(a[0])`, RunOutput: int64(1)}, 735 736 {Script: `len(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: int64(1), Output: map[string]interface{}{"a": "a"}}, 737 {Script: `len(a)`, Input: map[string]interface{}{"a": map[string]interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": map[string]interface{}{}}}, 738 {Script: `len(a)`, Input: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}, RunOutput: int64(1), Output: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}}, 739 {Script: `len(a["test"])`, Input: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}, RunOutput: int64(4), Output: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}}, 740 741 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": []interface{}{}}}, 742 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{nil}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{nil}}}, 743 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{true}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{true}}}, 744 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{int32(1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{int32(1)}}}, 745 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{int64(1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 746 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}}, 747 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}}, 748 {Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{"a"}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{"a"}}}, 749 750 {Script: `len(a[0])`, Input: map[string]interface{}{"a": []interface{}{"test"}}, RunOutput: int64(4), Output: map[string]interface{}{"a": []interface{}{"test"}}}, 751 752 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": [][]interface{}{}}}, 753 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{nil}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{nil}}}, 754 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{nil}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{nil}}}}, 755 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{true}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{true}}}}, 756 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}}, 757 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}}, 758 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}}, 759 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}}, 760 {Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{"a"}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{"a"}}}}, 761 762 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{nil}}, RunOutput: int64(0), Output: map[string]interface{}{"a": [][]interface{}{nil}}}, 763 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{nil}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{nil}}}}, 764 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{true}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{true}}}}, 765 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}}, 766 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}}, 767 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}}, 768 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}}, 769 {Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{"a"}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{"a"}}}}, 770 771 {Script: `len(a[0][0])`, Input: map[string]interface{}{"a": [][]interface{}{{"test"}}}, RunOutput: int64(4), Output: map[string]interface{}{"a": [][]interface{}{{"test"}}}}, 772 } 773 runTests(t, tests, nil, &Options{Debug: true}) 774 } 775 776 func TestCallFunctionWithVararg(t *testing.T) { 777 t.Parallel() 778 779 e := env.NewEnv() 780 err := e.Define("X", func(args ...string) []string { 781 return args 782 }) 783 if err != nil { 784 t.Errorf("Define error: %v", err) 785 } 786 want := []string{"foo", "bar", "baz"} 787 err = e.Define("a", want) 788 if err != nil { 789 t.Errorf("Define error: %v", err) 790 } 791 got, err := Execute(e, nil, "X(a...)") 792 if err != nil { 793 t.Errorf("execute error - received %#v - expected: %#v", err, nil) 794 } 795 if !reflect.DeepEqual(got, want) { 796 t.Errorf("execute error - received %#v - expected: %#v", got, want) 797 } 798 } 799 800 func TestGoFunctionConcurrency(t *testing.T) { 801 t.Parallel() 802 803 tests := []Test{ 804 {Script: ` 805 waitGroup.Add(5); 806 a = []; b = []; c = []; d = []; e = [] 807 fa = func() { for i = 0; i < 100; i++ { a += 1 }; waitGroup.Done() } 808 fb = func() { for i = 0; i < 100; i++ { b += 2 }; waitGroup.Done() } 809 fc = func() { for i = 0; i < 100; i++ { c += 3 }; waitGroup.Done() } 810 fd = func() { for i = 0; i < 100; i++ { d += 4 }; waitGroup.Done() } 811 fe = func() { for i = 0; i < 100; i++ { e += 5 }; waitGroup.Done() } 812 go fa(); go fb(); go fc(); go fd(); go fe() 813 waitGroup.Wait()`, 814 Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}}, 815 Output: map[string]interface{}{ 816 "a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}, 817 "b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)}, 818 "c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)}, 819 "d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)}, 820 "e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)}, 821 }}, 822 {Script: ` 823 waitGroup.Add(5); 824 x = [1, 2, 3, 4, 5] 825 a = []; b = []; c = []; d = []; e = [] 826 fa = func() { for i = 0; i < 100; i++ { a += x[0] }; waitGroup.Done() } 827 fb = func() { for i = 0; i < 100; i++ { b += x[1] }; waitGroup.Done() } 828 fc = func() { for i = 0; i < 100; i++ { c += x[2] }; waitGroup.Done() } 829 fd = func() { for i = 0; i < 100; i++ { d += x[3] }; waitGroup.Done() } 830 fe = func() { for i = 0; i < 100; i++ { e += x[4] }; waitGroup.Done() } 831 go fa(); go fb(); go fc(); go fd(); go fe() 832 waitGroup.Wait()`, 833 Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}}, 834 Output: map[string]interface{}{ 835 "a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}, 836 "b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)}, 837 "c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)}, 838 "d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)}, 839 "e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)}, 840 }}, 841 {Script: ` 842 waitGroup.Add(5); 843 x = func(y) { return y } 844 a = []; b = []; c = []; d = []; e = [] 845 fa = func() { for i = 0; i < 100; i++ { a += x(1) }; waitGroup.Done() } 846 fb = func() { for i = 0; i < 100; i++ { b += x(2) }; waitGroup.Done() } 847 fc = func() { for i = 0; i < 100; i++ { c += x(3) }; waitGroup.Done() } 848 fd = func() { for i = 0; i < 100; i++ { d += x(4) }; waitGroup.Done() } 849 fe = func() { for i = 0; i < 100; i++ { e += x(5) }; waitGroup.Done() } 850 go fa(); go fb(); go fc(); go fd(); go fe() 851 waitGroup.Wait()`, 852 Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}}, 853 Output: map[string]interface{}{ 854 "a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}, 855 "b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)}, 856 "c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)}, 857 "d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)}, 858 "e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)}, 859 }}, 860 } 861 862 runTests(t, tests, nil, &Options{Debug: true}) 863 }