github.com/mattn/anko@v0.1.10/vm/vmOperators_test.go (about) 1 package vm 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 ) 8 9 func TestBasicOperators(t *testing.T) { 10 t.Parallel() 11 12 tests := []Test{ 13 {Script: `]`, ParseError: fmt.Errorf("syntax error")}, 14 15 {Script: `2 + 1`, RunOutput: int64(3)}, 16 {Script: `2 - 1`, RunOutput: int64(1)}, 17 {Script: `2 * 1`, RunOutput: int64(2)}, 18 {Script: `2 / 1`, RunOutput: float64(2)}, 19 {Script: `2.1 + 1.1`, RunOutput: float64(3.2)}, 20 {Script: `2.1 - 1.1`, RunOutput: float64(1)}, 21 {Script: `2 + 1.1`, RunOutput: float64(3.1)}, 22 {Script: `2.1 + 1`, RunOutput: float64(3.1)}, 23 {Script: `3 - 1.5`, RunOutput: float64(1.5)}, 24 {Script: `2.1 - 1`, RunOutput: float64(1.1)}, 25 {Script: `2.1 * 2.0`, RunOutput: float64(4.2)}, 26 {Script: `6.5 / 2.0`, RunOutput: float64(3.25)}, 27 28 {Script: `2-1`, RunOutput: int64(1)}, 29 {Script: `2 -1`, RunOutput: int64(1)}, 30 {Script: `2- 1`, RunOutput: int64(1)}, 31 {Script: `2 - -1`, RunOutput: int64(3)}, 32 {Script: `2- -1`, RunOutput: int64(3)}, 33 {Script: `2 - - 1`, RunOutput: int64(3)}, 34 {Script: `2- - 1`, RunOutput: int64(3)}, 35 36 {Script: `a + b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(3)}, 37 {Script: `a - b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(1)}, 38 {Script: `a * b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(2)}, 39 {Script: `a / b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: float64(2)}, 40 {Script: `a + b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(1.1)}, RunOutput: float64(3.2)}, 41 {Script: `a - b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(1.1)}, RunOutput: float64(1)}, 42 {Script: `a * b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(2)}, RunOutput: float64(4.2)}, 43 {Script: `a / b`, Input: map[string]interface{}{"a": float64(6.5), "b": float64(2)}, RunOutput: float64(3.25)}, 44 45 {Script: `a + b`, Input: map[string]interface{}{"a": "a", "b": "b"}, RunOutput: "ab"}, 46 {Script: `a + b`, Input: map[string]interface{}{"a": "a", "b": int64(1)}, RunOutput: "a1"}, 47 {Script: `a + b`, Input: map[string]interface{}{"a": "a", "b": float64(1.1)}, RunOutput: "a1.1"}, 48 {Script: `a + b`, Input: map[string]interface{}{"a": int64(2), "b": "b"}, RunOutput: "2b"}, 49 {Script: `a + b`, Input: map[string]interface{}{"a": float64(2.5), "b": "b"}, RunOutput: "2.5b"}, 50 51 {Script: `a + z`, Input: map[string]interface{}{"a": "a"}, RunError: fmt.Errorf("undefined symbol 'z'"), RunOutput: nil}, 52 {Script: `z + b`, Input: map[string]interface{}{"a": "a"}, RunError: fmt.Errorf("undefined symbol 'z'"), RunOutput: nil}, 53 54 {Script: `c = a + b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(3), Output: map[string]interface{}{"c": int64(3)}}, 55 {Script: `c = a - b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"c": int64(1)}}, 56 {Script: `c = a * b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: int64(2), Output: map[string]interface{}{"c": int64(2)}}, 57 {Script: `c = a / b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: float64(2), Output: map[string]interface{}{"c": float64(2)}}, 58 {Script: `c = a + b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(1.1)}, RunOutput: float64(3.2), Output: map[string]interface{}{"c": float64(3.2)}}, 59 {Script: `c = a - b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(1.1)}, RunOutput: float64(1), Output: map[string]interface{}{"c": float64(1)}}, 60 {Script: `c = a * b`, Input: map[string]interface{}{"a": float64(2.1), "b": float64(2)}, RunOutput: float64(4.2), Output: map[string]interface{}{"c": float64(4.2)}}, 61 {Script: `c = a / b`, Input: map[string]interface{}{"a": float64(6.5), "b": float64(2)}, RunOutput: float64(3.25), Output: map[string]interface{}{"c": float64(3.25)}}, 62 63 {Script: `a = nil; a++`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 64 {Script: `a = false; a++`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 65 {Script: `a = true; a++`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 66 {Script: `a = 1; a++`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 67 {Script: `a = 1.5; a++`, RunOutput: float64(2.5), Output: map[string]interface{}{"a": float64(2.5)}}, 68 {Script: `a = "1"; a++`, RunOutput: "11", Output: map[string]interface{}{"a": "11"}}, 69 {Script: `a = "a"; a++`, RunOutput: "a1", Output: map[string]interface{}{"a": "a1"}}, 70 71 {Script: `a = nil; a--`, RunOutput: int64(-1), Output: map[string]interface{}{"a": int64(-1)}}, 72 {Script: `a = false; a--`, RunOutput: int64(-1), Output: map[string]interface{}{"a": int64(-1)}}, 73 {Script: `a = true; a--`, RunOutput: int64(0), Output: map[string]interface{}{"a": int64(0)}}, 74 {Script: `a = 2; a--`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 75 {Script: `a = 2.5; a--`, RunOutput: float64(1.5), Output: map[string]interface{}{"a": float64(1.5)}}, 76 77 {Script: `a++`, Input: map[string]interface{}{"a": nil}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 78 {Script: `a++`, Input: map[string]interface{}{"a": false}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 79 {Script: `a++`, Input: map[string]interface{}{"a": true}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 80 {Script: `a++`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 81 {Script: `a++`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 82 {Script: `a++`, Input: map[string]interface{}{"a": float32(3.5)}, RunOutput: float64(4.5), Output: map[string]interface{}{"a": float64(4.5)}}, 83 {Script: `a++`, Input: map[string]interface{}{"a": float64(4.5)}, RunOutput: float64(5.5), Output: map[string]interface{}{"a": float64(5.5)}}, 84 {Script: `a++`, Input: map[string]interface{}{"a": "2"}, RunOutput: "21", Output: map[string]interface{}{"a": "21"}}, 85 {Script: `a++`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a1", Output: map[string]interface{}{"a": "a1"}}, 86 87 {Script: `a--`, Input: map[string]interface{}{"a": nil}, RunOutput: int64(-1), Output: map[string]interface{}{"a": int64(-1)}}, 88 {Script: `a--`, Input: map[string]interface{}{"a": false}, RunOutput: int64(-1), Output: map[string]interface{}{"a": int64(-1)}}, 89 {Script: `a--`, Input: map[string]interface{}{"a": true}, RunOutput: int64(0), Output: map[string]interface{}{"a": int64(0)}}, 90 {Script: `a--`, Input: map[string]interface{}{"a": int32(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 91 {Script: `a--`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 92 {Script: `a--`, Input: map[string]interface{}{"a": float32(2.5)}, RunOutput: float64(1.5), Output: map[string]interface{}{"a": float64(1.5)}}, 93 {Script: `a--`, Input: map[string]interface{}{"a": float64(2.5)}, RunOutput: float64(1.5), Output: map[string]interface{}{"a": float64(1.5)}}, 94 {Script: `a--`, Input: map[string]interface{}{"a": "2"}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 95 {Script: `a--`, Input: map[string]interface{}{"a": "a"}, RunOutput: int64(-1), Output: map[string]interface{}{"a": int64(-1)}}, 96 97 {Script: `1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 98 {Script: `1--`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 99 {Script: `z++`, RunError: fmt.Errorf("undefined symbol 'z'"), RunOutput: nil}, 100 {Script: `z--`, RunError: fmt.Errorf("undefined symbol 'z'"), RunOutput: nil}, 101 {Script: `!(1++)`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 102 {Script: `1 + 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 103 {Script: `1 - 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 104 {Script: `1 * 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 105 {Script: `1 / 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 106 {Script: `1++ + 1`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 107 {Script: `1++ - 1`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 108 {Script: `1++ * 1`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 109 {Script: `1++ / 1`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 110 111 {Script: `a = 1; b = 2; a + b`, RunOutput: int64(3)}, 112 {Script: `a = [1]; b = 2; a[0] + b`, RunOutput: int64(3)}, 113 {Script: `a = 1; b = [2]; a + b[0]`, RunOutput: int64(3)}, 114 {Script: `a = 2; b = 1; a - b`, RunOutput: int64(1)}, 115 {Script: `a = [2]; b = 1; a[0] - b`, RunOutput: int64(1)}, 116 {Script: `a = 2; b = [1]; a - b[0]`, RunOutput: int64(1)}, 117 {Script: `a = 1; b = 2; a * b`, RunOutput: int64(2)}, 118 {Script: `a = [1]; b = 2; a[0] * b`, RunOutput: int64(2)}, 119 {Script: `a = 1; b = [2]; a * b[0]`, RunOutput: int64(2)}, 120 {Script: `a = 4; b = 2; a / b`, RunOutput: float64(2)}, 121 {Script: `a = [4]; b = 2; a[0] / b`, RunOutput: float64(2)}, 122 {Script: `a = 4; b = [2]; a / b[0]`, RunOutput: float64(2)}, 123 124 {Script: `a += 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 125 {Script: `a -= 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 126 {Script: `a *= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(4), Output: map[string]interface{}{"a": int64(4)}}, 127 {Script: `a /= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: float64(1), Output: map[string]interface{}{"a": float64(1)}}, 128 {Script: `a += 1`, Input: map[string]interface{}{"a": 2.1}, RunOutput: float64(3.1), Output: map[string]interface{}{"a": float64(3.1)}}, 129 {Script: `a -= 1`, Input: map[string]interface{}{"a": 2.1}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 130 {Script: `a *= 2`, Input: map[string]interface{}{"a": 2.1}, RunOutput: float64(4.2), Output: map[string]interface{}{"a": float64(4.2)}}, 131 {Script: `a /= 2`, Input: map[string]interface{}{"a": 6.5}, RunOutput: float64(3.25), Output: map[string]interface{}{"a": float64(3.25)}}, 132 133 {Script: `a &= 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(0), Output: map[string]interface{}{"a": int64(0)}}, 134 {Script: `a &= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 135 {Script: `a &= 1`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(0), Output: map[string]interface{}{"a": int64(0)}}, 136 {Script: `a &= 2`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 137 138 {Script: `a |= 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 139 {Script: `a |= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 140 {Script: `a |= 1`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 141 {Script: `a |= 2`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 142 143 {Script: `a << 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(8), Output: map[string]interface{}{"a": int64(2)}}, 144 {Script: `a >> 2`, Input: map[string]interface{}{"a": int64(8)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(8)}}, 145 {Script: `a << 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: int64(8), Output: map[string]interface{}{"a": float64(2)}}, 146 {Script: `a >> 2`, Input: map[string]interface{}{"a": float64(8)}, RunOutput: int64(2), Output: map[string]interface{}{"a": float64(8)}}, 147 148 {Script: `a % 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(0), Output: map[string]interface{}{"a": int64(2)}}, 149 {Script: `a % 3`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 150 {Script: `a % 2`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(0), Output: map[string]interface{}{"a": float64(2.1)}}, 151 {Script: `a % 3`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": float64(2.1)}}, 152 153 {Script: `a * 4`, Input: map[string]interface{}{"a": "a"}, RunOutput: "aaaa", Output: map[string]interface{}{"a": "a"}}, 154 {Script: `a * 4.0`, Input: map[string]interface{}{"a": "a"}, RunOutput: float64(0), Output: map[string]interface{}{"a": "a"}}, 155 156 {Script: `-a`, Input: map[string]interface{}{"a": nil}, RunOutput: float64(-0), Output: map[string]interface{}{"a": nil}}, 157 {Script: `-a`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: int64(-1), Output: map[string]interface{}{"a": int32(1)}}, 158 {Script: `-a`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(-2), Output: map[string]interface{}{"a": int64(2)}}, 159 {Script: `-a`, Input: map[string]interface{}{"a": float32(3.5)}, RunOutput: float64(-3.5), Output: map[string]interface{}{"a": float32(3.5)}}, 160 {Script: `-a`, Input: map[string]interface{}{"a": float64(4.5)}, RunOutput: float64(-4.5), Output: map[string]interface{}{"a": float64(4.5)}}, 161 {Script: `-a`, Input: map[string]interface{}{"a": "a"}, RunOutput: float64(-0), Output: map[string]interface{}{"a": "a"}}, 162 {Script: `-a`, Input: map[string]interface{}{"a": "1"}, RunOutput: float64(-1), Output: map[string]interface{}{"a": "1"}}, 163 164 {Script: `^a`, Input: map[string]interface{}{"a": nil}, RunOutput: int64(-1), Output: map[string]interface{}{"a": nil}}, 165 {Script: `^a`, Input: map[string]interface{}{"a": "a"}, RunOutput: int64(-1), Output: map[string]interface{}{"a": "a"}}, 166 {Script: `^a`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(-3), Output: map[string]interface{}{"a": int64(2)}}, 167 {Script: `^a`, Input: map[string]interface{}{"a": float64(2.1)}, RunOutput: int64(-3), Output: map[string]interface{}{"a": float64(2.1)}}, 168 169 {Script: `!true`, RunOutput: false}, 170 {Script: `!false`, RunOutput: true}, 171 {Script: `!1`, RunOutput: false}, 172 } 173 runTests(t, tests, nil, &Options{Debug: true}) 174 } 175 176 func TestComparisonOperators(t *testing.T) { 177 t.Parallel() 178 179 tests := []Test{ 180 {Script: `1++ == 2`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 181 {Script: `2 == 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 182 {Script: `1++ || true`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 183 {Script: `false || 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 184 {Script: `1++ && true`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 185 {Script: `true && 1++`, RunError: fmt.Errorf("invalid operation"), RunOutput: nil}, 186 187 {Script: `a == 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 188 {Script: `a == 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 189 {Script: `a != 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 190 {Script: `a != 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 191 {Script: `a == 1.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 192 {Script: `a == 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 193 {Script: `a != 1.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 194 {Script: `a != 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 195 196 {Script: `a == 1`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 197 {Script: `a == 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 198 {Script: `a != 1`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 199 {Script: `a != 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 200 {Script: `a == 1.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 201 {Script: `a == 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 202 {Script: `a != 1.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 203 {Script: `a != 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 204 205 {Script: `a == nil`, Input: map[string]interface{}{"a": nil}, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 206 {Script: `a == nil`, Input: map[string]interface{}{"a": nil}, RunOutput: true, Output: map[string]interface{}{"a": nil}}, 207 {Script: `a == nil`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 208 {Script: `a == nil`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 209 {Script: `a == 2`, Input: map[string]interface{}{"a": nil}, RunOutput: false, Output: map[string]interface{}{"a": nil}}, 210 {Script: `a == 2.0`, Input: map[string]interface{}{"a": nil}, RunOutput: false, Output: map[string]interface{}{"a": nil}}, 211 212 {Script: `1 == 1.0`, RunOutput: true}, 213 {Script: `1 != 1.0`, RunOutput: false}, 214 {Script: `"a" != "a"`, RunOutput: false}, 215 216 {Script: `a > 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 217 {Script: `a > 1`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 218 {Script: `a < 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 219 {Script: `a < 3`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 220 {Script: `a > 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 221 {Script: `a > 1.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 222 {Script: `a < 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 223 {Script: `a < 3.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 224 225 {Script: `a > 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 226 {Script: `a > 1`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 227 {Script: `a < 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 228 {Script: `a < 3`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 229 {Script: `a > 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 230 {Script: `a > 1.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 231 {Script: `a < 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 232 {Script: `a < 3.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 233 234 {Script: `a >= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 235 {Script: `a >= 3`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 236 {Script: `a <= 2`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 237 {Script: `a <= 3`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 238 {Script: `a >= 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 239 {Script: `a >= 3.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 240 {Script: `a <= 2.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 241 {Script: `a <= 3.0`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2)}}, 242 243 {Script: `a >= 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 244 {Script: `a >= 3`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 245 {Script: `a <= 2`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 246 {Script: `a <= 3`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 247 {Script: `a >= 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 248 {Script: `a >= 3.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2)}}, 249 {Script: `a <= 2.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 250 {Script: `a <= 3.0`, Input: map[string]interface{}{"a": float64(2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2)}}, 251 252 {Script: `a = false; b = false; a && b`, RunOutput: false}, 253 {Script: `a = false; b = true; a && b`, RunOutput: false}, 254 {Script: `a = true; b = false; a && b`, RunOutput: false}, 255 {Script: `a = true; b = true; a && b`, RunOutput: true}, 256 {Script: `a = false; b = false; a || b`, RunOutput: false}, 257 {Script: `a = false; b = true; a || b`, RunOutput: true}, 258 {Script: `a = true; b = false; a || b`, RunOutput: true}, 259 {Script: `a = true; b = true; a || b`, RunOutput: true}, 260 261 {Script: `a = [false]; b = false; a[0] && b`, RunOutput: false}, 262 {Script: `a = [false]; b = true; a[0] && b`, RunOutput: false}, 263 {Script: `a = [true]; b = false; a[0] && b`, RunOutput: false}, 264 {Script: `a = [true]; b = true; a[0] && b`, RunOutput: true}, 265 {Script: `a = [false]; b = false; a[0] || b`, RunOutput: false}, 266 {Script: `a = [false]; b = true; a[0] || b`, RunOutput: true}, 267 {Script: `a = [true]; b = false; a[0] || b`, RunOutput: true}, 268 {Script: `a = [true]; b = true; a[0] || b`, RunOutput: true}, 269 270 {Script: `a = false; b = [false]; a && b[0]`, RunOutput: false}, 271 {Script: `a = false; b = [true]; a && b[0]`, RunOutput: false}, 272 {Script: `a = true; b = [false]; a && b[0]`, RunOutput: false}, 273 {Script: `a = true; b = [true]; a && b[0]`, RunOutput: true}, 274 {Script: `a = false; b = [false]; a || b[0]`, RunOutput: false}, 275 {Script: `a = false; b = [true]; a || b[0]`, RunOutput: true}, 276 {Script: `a = true; b = [false]; a || b[0]`, RunOutput: true}, 277 {Script: `a = true; b = [true]; a || b[0]`, RunOutput: true}, 278 279 {Script: `0 && 0`, RunOutput: false}, 280 {Script: `0 && 1`, RunOutput: false}, 281 {Script: `1 && 0`, RunOutput: false}, 282 {Script: `1 && 1`, RunOutput: true}, 283 {Script: `0 || 0`, RunOutput: false}, 284 {Script: `0 || 1`, RunOutput: true}, 285 {Script: `1 || 0`, RunOutput: true}, 286 {Script: `1 || 1`, RunOutput: true}, 287 288 {Script: `1 == 1 && 1 == 1`, RunOutput: true}, 289 {Script: `1 == 1 && 1 == 2`, RunOutput: false}, 290 {Script: `1 == 2 && 1 == 1`, RunOutput: false}, 291 {Script: `1 == 2 && 1 == 2`, RunOutput: false}, 292 {Script: `1 == 1 || 1 == 1`, RunOutput: true}, 293 {Script: `1 == 1 || 1 == 2`, RunOutput: true}, 294 {Script: `1 == 2 || 1 == 1`, RunOutput: true}, 295 {Script: `1 == 2 || 1 == 2`, RunOutput: false}, 296 297 {Script: `true == "1"`, RunOutput: true}, 298 {Script: `true == "t"`, RunOutput: true}, 299 {Script: `true == "T"`, RunOutput: true}, 300 {Script: `true == "true"`, RunOutput: true}, 301 {Script: `true == "TRUE"`, RunOutput: true}, 302 {Script: `true == "True"`, RunOutput: true}, 303 {Script: `true == "false"`, RunOutput: false}, 304 {Script: `false == "0"`, RunOutput: true}, 305 {Script: `false == "f"`, RunOutput: true}, 306 {Script: `false == "F"`, RunOutput: true}, 307 {Script: `false == "false"`, RunOutput: true}, 308 {Script: `false == "false"`, RunOutput: true}, 309 {Script: `false == "FALSE"`, RunOutput: true}, 310 {Script: `false == "False"`, RunOutput: true}, 311 {Script: `false == "true"`, RunOutput: false}, 312 {Script: `false == "foo"`, RunOutput: false}, 313 {Script: `true == "foo"`, RunOutput: true}, 314 315 {Script: `0 == "0"`, RunOutput: true}, 316 {Script: `"1.0" == 1`, RunOutput: true}, 317 {Script: `1 == "1"`, RunOutput: true}, 318 {Script: `0.0 == "0"`, RunOutput: true}, 319 {Script: `0.0 == "0.0"`, RunOutput: true}, 320 {Script: `1.0 == "1.0"`, RunOutput: true}, 321 {Script: `1.2 == "1.2"`, RunOutput: true}, 322 {Script: `"7" == 7.2`, RunOutput: false}, 323 {Script: `1.2 == "1"`, RunOutput: false}, 324 {Script: `"1.1" == 1`, RunOutput: false}, 325 {Script: `0 == "1"`, RunOutput: false}, 326 327 {Script: `a == b`, Input: map[string]interface{}{"a": reflect.Value{}, "b": reflect.Value{}}, RunOutput: true, Output: map[string]interface{}{"a": reflect.Value{}, "b": reflect.Value{}}}, 328 {Script: `a == b`, Input: map[string]interface{}{"a": reflect.Value{}, "b": true}, RunOutput: false, Output: map[string]interface{}{"a": reflect.Value{}, "b": true}}, 329 {Script: `a == b`, Input: map[string]interface{}{"a": true, "b": reflect.Value{}}, RunOutput: false, Output: map[string]interface{}{"a": true, "b": reflect.Value{}}}, 330 331 {Script: `a == b`, Input: map[string]interface{}{"a": nil, "b": nil}, RunOutput: true, Output: map[string]interface{}{"a": nil, "b": nil}}, 332 {Script: `a == b`, Input: map[string]interface{}{"a": nil, "b": true}, RunOutput: false, Output: map[string]interface{}{"a": nil, "b": true}}, 333 {Script: `a == b`, Input: map[string]interface{}{"a": true, "b": nil}, RunOutput: false, Output: map[string]interface{}{"a": true, "b": nil}}, 334 335 {Script: `a == b`, Input: map[string]interface{}{"a": false, "b": false}, RunOutput: true, Output: map[string]interface{}{"a": false, "b": false}}, 336 {Script: `a == b`, Input: map[string]interface{}{"a": false, "b": true}, RunOutput: false, Output: map[string]interface{}{"a": false, "b": true}}, 337 {Script: `a == b`, Input: map[string]interface{}{"a": true, "b": false}, RunOutput: false, Output: map[string]interface{}{"a": true, "b": false}}, 338 {Script: `a == b`, Input: map[string]interface{}{"a": true, "b": true}, RunOutput: true, Output: map[string]interface{}{"a": true, "b": true}}, 339 340 {Script: `a == b`, Input: map[string]interface{}{"a": int32(1), "b": int32(1)}, RunOutput: true, Output: map[string]interface{}{"a": int32(1), "b": int32(1)}}, 341 {Script: `a == b`, Input: map[string]interface{}{"a": int32(1), "b": int32(2)}, RunOutput: false, Output: map[string]interface{}{"a": int32(1), "b": int32(2)}}, 342 {Script: `a == b`, Input: map[string]interface{}{"a": int32(2), "b": int32(1)}, RunOutput: false, Output: map[string]interface{}{"a": int32(2), "b": int32(1)}}, 343 {Script: `a == b`, Input: map[string]interface{}{"a": int32(2), "b": int32(2)}, RunOutput: true, Output: map[string]interface{}{"a": int32(2), "b": int32(2)}}, 344 345 {Script: `a == b`, Input: map[string]interface{}{"a": int64(1), "b": int64(1)}, RunOutput: true, Output: map[string]interface{}{"a": int64(1), "b": int64(1)}}, 346 {Script: `a == b`, Input: map[string]interface{}{"a": int64(1), "b": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(1), "b": int64(2)}}, 347 {Script: `a == b`, Input: map[string]interface{}{"a": int64(2), "b": int64(1)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2), "b": int64(1)}}, 348 {Script: `a == b`, Input: map[string]interface{}{"a": int64(2), "b": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": int64(2), "b": int64(2)}}, 349 350 {Script: `a == b`, Input: map[string]interface{}{"a": float32(1.1), "b": float32(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float32(1.1), "b": float32(1.1)}}, 351 {Script: `a == b`, Input: map[string]interface{}{"a": float32(1.1), "b": float32(2.2)}, RunOutput: false, Output: map[string]interface{}{"a": float32(1.1), "b": float32(2.2)}}, 352 {Script: `a == b`, Input: map[string]interface{}{"a": float32(2.2), "b": float32(1.1)}, RunOutput: false, Output: map[string]interface{}{"a": float32(2.2), "b": float32(1.1)}}, 353 {Script: `a == b`, Input: map[string]interface{}{"a": float32(2.2), "b": float32(2.2)}, RunOutput: true, Output: map[string]interface{}{"a": float32(2.2), "b": float32(2.2)}}, 354 355 {Script: `a == b`, Input: map[string]interface{}{"a": float64(1.1), "b": float64(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1), "b": float64(1.1)}}, 356 {Script: `a == b`, Input: map[string]interface{}{"a": float64(1.1), "b": float64(2.2)}, RunOutput: false, Output: map[string]interface{}{"a": float64(1.1), "b": float64(2.2)}}, 357 {Script: `a == b`, Input: map[string]interface{}{"a": float64(2.2), "b": float64(1.1)}, RunOutput: false, Output: map[string]interface{}{"a": float64(2.2), "b": float64(1.1)}}, 358 {Script: `a == b`, Input: map[string]interface{}{"a": float64(2.2), "b": float64(2.2)}, RunOutput: true, Output: map[string]interface{}{"a": float64(2.2), "b": float64(2.2)}}, 359 360 {Script: `a == b`, Input: map[string]interface{}{"a": 'a', "b": 'a'}, RunOutput: true, Output: map[string]interface{}{"a": 'a', "b": 'a'}}, 361 {Script: `a == b`, Input: map[string]interface{}{"a": 'a', "b": 'b'}, RunOutput: false, Output: map[string]interface{}{"a": 'a', "b": 'b'}}, 362 {Script: `a == b`, Input: map[string]interface{}{"a": 'b', "b": 'a'}, RunOutput: false, Output: map[string]interface{}{"a": 'b', "b": 'a'}}, 363 {Script: `a == b`, Input: map[string]interface{}{"a": 'b', "b": 'b'}, RunOutput: true, Output: map[string]interface{}{"a": 'b', "b": 'b'}}, 364 365 {Script: `a == b`, Input: map[string]interface{}{"a": "a", "b": "a"}, RunOutput: true, Output: map[string]interface{}{"a": "a", "b": "a"}}, 366 {Script: `a == b`, Input: map[string]interface{}{"a": "a", "b": "b"}, RunOutput: false, Output: map[string]interface{}{"a": "a", "b": "b"}}, 367 {Script: `a == b`, Input: map[string]interface{}{"a": "b", "b": "a"}, RunOutput: false, Output: map[string]interface{}{"a": "b", "b": "a"}}, 368 {Script: `a == b`, Input: map[string]interface{}{"a": "b", "b": "b"}, RunOutput: true, Output: map[string]interface{}{"a": "b", "b": "b"}}, 369 370 {Script: `b = "\"a\""; a == b`, Input: map[string]interface{}{"a": `"a"`}, RunOutput: true, Output: map[string]interface{}{"a": `"a"`, "b": `"a"`}}, 371 372 {Script: `a = "test"; a == "test"`, RunOutput: true}, 373 {Script: `a = "test"; a[0:1] == "t"`, RunOutput: true}, 374 {Script: `a = "test"; a[0:2] == "te"`, RunOutput: true}, 375 {Script: `a = "test"; a[1:3] == "es"`, RunOutput: true}, 376 {Script: `a = "test"; a[0:4] == "test"`, RunOutput: true}, 377 378 {Script: `a = "a b"; a[1] == ' '`, RunOutput: true}, 379 {Script: `a = "test"; a[0] == 't'`, RunOutput: true}, 380 {Script: `a = "test"; a[1] == 'e'`, RunOutput: true}, 381 {Script: `a = "test"; a[3] == 't'`, RunOutput: true}, 382 383 {Script: `a = "a b"; a[1] != ' '`, RunOutput: false}, 384 {Script: `a = "test"; a[0] != 't'`, RunOutput: false}, 385 {Script: `a = "test"; a[1] != 'e'`, RunOutput: false}, 386 {Script: `a = "test"; a[3] != 't'`, RunOutput: false}, 387 } 388 runTests(t, tests, nil, &Options{Debug: true}) 389 } 390 391 func TestThrows(t *testing.T) { 392 t.Parallel() 393 394 tests := []Test{ 395 {Script: `throw(1++)`, RunError: fmt.Errorf("invalid operation")}, 396 // {Script: `throw(a)`, Input: map[string]interface{}{"a": reflect.Value{}}, RunError: fmt.Errorf("invalid operation")}, 397 398 {Script: `true && func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 399 {Script: `false && func(){throw('abcde')}()`, RunOutput: false}, 400 {Script: `true || func(){throw('abcde')}()`, RunOutput: true}, 401 {Script: `false || func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 402 {Script: `true && true && func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 403 {Script: `true && false && func(){throw('abcde')}()`, RunOutput: false}, 404 {Script: `true && func(){throw('abcde')}() && true`, RunError: fmt.Errorf("abcde")}, 405 {Script: `false && func(){throw('abcde')}() && func(){throw('abcde')}() `, RunOutput: false}, 406 407 {Script: `true && func(){throw('abcde')}() || false`, RunError: fmt.Errorf("abcde")}, 408 {Script: `true && false || func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 409 {Script: `true && true || func(){throw('abcde')}()`, RunOutput: true}, 410 411 {Script: `true || func(){throw('abcde')}() || func(){throw('abcde')}()`, RunOutput: true}, 412 {Script: `false || func(){throw('abcde')}() || true`, RunError: fmt.Errorf("abcde")}, 413 {Script: `false || true || func(){throw('abcde')}()`, RunOutput: true}, 414 {Script: `false || false || func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 415 416 {Script: `false || false && func(){throw('abcde')}()`, RunOutput: false}, 417 {Script: `false || true && func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 418 {Script: `false || func(){throw('abcde')}() || true`, RunError: fmt.Errorf("abcde")}, 419 420 {Script: `1 == 1 && func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 421 {Script: `1 == 2 && func(){throw('abcde')}()`, RunOutput: false}, 422 {Script: `1 == 1 || func(){throw('abcde')}()`, RunOutput: true}, 423 {Script: `1 == 2 || func(){throw('abcde')}()`, RunError: fmt.Errorf("abcde")}, 424 425 {Script: `(true || func(){throw('abcde')}()) && (true || func(){throw('hello')}())`, RunOutput: true}, 426 {Script: `(true || func(){throw('abcde')}()) && (true && func(){throw('hello')}())`, RunError: fmt.Errorf("hello")}, 427 {Script: `(true || func(){throw('abcde')}()) || (true && func(){throw('hello')}())`, RunOutput: true}, 428 {Script: `(true && func(){throw('abcde')}()) && (true && func(){throw('hello')}())`, RunError: fmt.Errorf("abcde")}, 429 {Script: `(true || func(){throw('abcde')}()) && (false || func(){throw('hello')}())`, RunError: fmt.Errorf("hello")}, 430 } 431 runTests(t, tests, nil, &Options{Debug: true}) 432 } 433 434 func TestTernaryOperator(t *testing.T) { 435 t.Parallel() 436 437 tests := []Test{ 438 {Script: `a = a ? 1 : 2`, RunError: fmt.Errorf("undefined symbol 'a'")}, 439 {Script: `a = z ? 1 : 2`, RunError: fmt.Errorf("undefined symbol 'z'")}, 440 {Script: `a = 0; a = a ? 1 : z`, RunError: fmt.Errorf("undefined symbol 'z'")}, 441 {Script: `a = 1; a = a ? z : 1`, RunError: fmt.Errorf("undefined symbol 'z'")}, 442 {Script: `a = b[1] ? 2 : 1`, Input: map[string]interface{}{"b": []interface{}{}}, RunError: fmt.Errorf("index out of range")}, 443 {Script: `a = b[1][2] ? 2 : 1`, Input: map[string]interface{}{"b": []interface{}{}}, RunError: fmt.Errorf("index out of range")}, 444 {Script: `a = b["test"][1] ? 2 : 1`, Input: map[string]interface{}{"b": map[string]interface{}{"test": 2}}, RunError: fmt.Errorf("type int does not support index operation")}, 445 446 {Script: `a = 1 ? 2 : z`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 447 {Script: `a = -1 ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 448 {Script: `a = true ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 449 {Script: `a = false ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 450 {Script: `a = "true" ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 451 {Script: `a = "false" ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 452 {Script: `a = "-1" ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 453 {Script: `a = "0" ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 454 {Script: `a = "0.0" ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 455 {Script: `a = "2" ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 456 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": int64(0)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 457 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": int64(2)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 458 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": float64(0.0)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 459 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": float64(2.0)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 460 {Script: `a = b ? 2 : 1.0`, Input: map[string]interface{}{"b": float64(0.0)}, RunOutput: float64(1.0), Output: map[string]interface{}{"a": float64(1.0)}}, 461 {Script: `a = b ? 2 : 1.0`, Input: map[string]interface{}{"b": float64(0.1)}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 462 {Script: `a = b ? 2 : 1.0`, Input: map[string]interface{}{"b": nil}, RunOutput: float64(1.0), Output: map[string]interface{}{"a": float64(1.0)}}, 463 {Script: `a = nil ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 464 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": []interface{}{}}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 465 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": map[string]interface{}{}}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 466 {Script: `a = [] ? 2 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 467 {Script: `a = [2] ? 2 : 1`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 468 {Script: `a = b ? 2 : 1`, Input: map[string]interface{}{"b": map[string]interface{}{"test": int64(2)}}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 469 {Script: `a = b["test"] ? 2 : 1`, Input: map[string]interface{}{"b": map[string]interface{}{"test": int64(2)}}, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 470 {Script: `b = "test"; a = b ? 2 : "empty"`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 471 {Script: `b = "test"; a = b[1:3] ? 2 : "empty"`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}}, 472 {Script: `b = "test"; a = b[2:2] ? 2 : "empty"`, RunOutput: "empty", Output: map[string]interface{}{"a": "empty"}}, 473 {Script: `b = "0.0"; a = false ? 2 : b ? 3 : 1`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 474 {Script: `b = "true"; a = false ? 2 : b ? 3 : 1`, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 475 } 476 runTests(t, tests, nil, &Options{Debug: true}) 477 } 478 479 func TestNilCoalescingOperator(t *testing.T) { 480 t.Parallel() 481 482 tests := []Test{ 483 {Script: `nil ?? nil`, RunOutput: nil}, 484 {Script: `false ?? nil`, RunOutput: false}, 485 {Script: `true ?? nil`, RunOutput: true}, 486 {Script: `nil ?? false`, RunOutput: false}, 487 {Script: `nil ?? true`, RunOutput: true}, 488 {Script: `1 ?? nil`, RunOutput: int64(1)}, 489 {Script: `1 ?? 2`, RunOutput: int64(1)}, 490 {Script: `nil ?? 1`, RunOutput: int64(1)}, 491 492 {Script: `a ?? 1`, RunOutput: int64(1)}, 493 {Script: `a ?? b`, RunError: fmt.Errorf("undefined symbol 'b'")}, 494 495 {Script: `a ?? 2`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 496 {Script: `a ?? b`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 497 {Script: `a ?? b`, Input: map[string]interface{}{"a": int64(1), "b": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1), "b": int64(2)}}, 498 {Script: `a ?? b`, Input: map[string]interface{}{"a": nil, "b": int64(2)}, RunOutput: int64(2), Output: map[string]interface{}{"a": nil, "b": int64(2)}}, 499 500 {Script: `[] ?? 1`, RunOutput: []interface{}{}}, 501 {Script: `{} ?? 1`, RunOutput: map[interface{}]interface{}{}}, 502 503 // test nil array and map 504 {Script: `a ?? 5`, Input: map[string]interface{}{"a": testSliceEmpty}, RunOutput: int64(5), Output: map[string]interface{}{"a": testSliceEmpty}}, 505 {Script: `a ?? 6`, Input: map[string]interface{}{"a": testMapEmpty}, RunOutput: int64(6), Output: map[string]interface{}{"a": testMapEmpty}}, 506 } 507 runTests(t, tests, nil, &Options{Debug: true}) 508 } 509 510 func TestIf(t *testing.T) { 511 t.Parallel() 512 513 tests := []Test{ 514 {Script: `if 1++ {}`, RunError: fmt.Errorf("invalid operation")}, 515 {Script: `if false {} else if 1++ {}`, RunError: fmt.Errorf("invalid operation")}, 516 {Script: `if false {} else if true { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 517 518 {Script: `if true {}`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 519 {Script: `if true {}`, Input: map[string]interface{}{"a": true}, RunOutput: nil, Output: map[string]interface{}{"a": true}}, 520 {Script: `if true {}`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 521 {Script: `if true {}`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: nil, Output: map[string]interface{}{"a": float64(1.1)}}, 522 {Script: `if true {}`, Input: map[string]interface{}{"a": "a"}, RunOutput: nil, Output: map[string]interface{}{"a": "a"}}, 523 524 {Script: `if true {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 525 {Script: `if true {a = true}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: true, Output: map[string]interface{}{"a": true}}, 526 {Script: `if true {a = 1}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 527 {Script: `if true {a = 1.1}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}}, 528 {Script: `if true {a = "a"}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}}, 529 530 {Script: `if a == 1 {a = 1}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 531 {Script: `if a == 2 {a = 1}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 532 {Script: `if a == 1 {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 533 {Script: `if a == 2 {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 534 535 {Script: `if a == 1 {a = 1} else {a = 3}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 536 {Script: `if a == 2 {a = 1} else {a = 3}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}}, 537 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 538 {Script: `if a == 1 {a = 1} else if a == 2 {a = 3}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 539 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else {a = 4}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(4), Output: map[string]interface{}{"a": int64(4)}}, 540 541 {Script: `if a == 1 {a = 1} else {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 542 {Script: `if a == 2 {a = nil} else {a = 3}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 543 {Script: `if a == 1 {a = nil} else if a == 3 {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: false, Output: map[string]interface{}{"a": int64(2)}}, 544 {Script: `if a == 1 {a = 1} else if a == 2 {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 545 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 546 547 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else if a == 4 {a = 4} else {a = 5}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(5)}}, 548 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else if a == 4 {a = 4} else {a = nil}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 549 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else if a == 2 {a = 4} else {a = 5}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: int64(4), Output: map[string]interface{}{"a": int64(4)}}, 550 {Script: `if a == 1 {a = 1} else if a == 3 {a = 3} else if a == 2 {a = nil} else {a = 5}`, Input: map[string]interface{}{"a": int64(2)}, RunOutput: nil, Output: map[string]interface{}{"a": nil}}, 551 552 // check scope 553 {Script: `a = 1; if a == 1 { b = 2 }; b`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": int64(1)}}, 554 {Script: `a = 1; if a == 2 { b = 3 } else { b = 4 }; b`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": int64(1)}}, 555 {Script: `a = 1; if a == 2 { b = 3 } else if a == 1 { b = 4 }; b`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": int64(1)}}, 556 {Script: `a = 1; if a == 2 { b = 4 } else if a == 5 { b = 6 } else if a == 1 { c = b }`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": int64(1)}}, 557 {Script: `a = 1; if a == 2 { b = 4 } else if a == 5 { b = 6 } else if a == 1 { b = 7 }; b`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": int64(1)}}, 558 } 559 runTests(t, tests, nil, &Options{Debug: true}) 560 } 561 562 func TestSwitch(t *testing.T) { 563 t.Parallel() 564 565 tests := []Test{ 566 // test parse errors 567 {Script: `switch {}`, ParseError: fmt.Errorf("syntax error")}, 568 {Script: `a = 1; switch a; {}`, ParseError: fmt.Errorf("syntax error")}, 569 {Script: `a = 1; switch a = 2 {}`, ParseError: fmt.Errorf("syntax error")}, 570 {Script: `a = 1; switch a {default: return 6; default: return 7}`, ParseError: fmt.Errorf("multiple default statement"), RunOutput: int64(7)}, 571 {Script: `a = 1; switch a {case 1: return 5; default: return 6; default: return 7}`, ParseError: fmt.Errorf("multiple default statement"), RunOutput: int64(5)}, 572 573 // test run errors 574 {Script: `a = 1; switch 1++ {}`, RunError: fmt.Errorf("invalid operation")}, 575 {Script: `a = 1; switch a {case 1++: return 2}`, RunError: fmt.Errorf("invalid operation")}, 576 577 // test no or empty cases 578 {Script: `a = 1; switch a {}`, Output: map[string]interface{}{"a": int64(1)}}, 579 {Script: `a = 1; switch a {case: return 2}`, Output: map[string]interface{}{"a": int64(1)}}, 580 {Script: `a = 1; switch a {case: return 2; case: return 3}`, Output: map[string]interface{}{"a": int64(1)}}, 581 582 // test 1 case 583 {Script: `a = 1; switch a {case 1: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 584 {Script: `a = 2; switch a {case 1: return 5}`, Output: map[string]interface{}{"a": int64(2)}}, 585 {Script: `a = 1; switch a {case 1,2: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 586 {Script: `a = 2; switch a {case 1,2: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(2)}}, 587 {Script: `a = 3; switch a {case 1,2: return 5}`, Output: map[string]interface{}{"a": int64(3)}}, 588 {Script: `a = 1; switch a {case 1,2,3: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 589 {Script: `a = 2; switch a {case 1,2,3: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(2)}}, 590 {Script: `a = 3; switch a {case 1,2,3: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(3)}}, 591 {Script: `a = 4; switch a {case 1,2,3: return 5}`, Output: map[string]interface{}{"a": int64(4)}}, 592 {Script: `a = func() { return 1 }; switch a() {case 1: return 5}`, RunOutput: int64(5)}, 593 {Script: `a = func() { return 2 }; switch a() {case 1: return 5}`}, 594 {Script: `a = func() { return 5 }; b = 1; switch b {case 1: return a() }`, RunOutput: int64(5), Output: map[string]interface{}{"b": int64(1)}}, 595 {Script: `a = func() { return 6 }; b = 2; switch b {case 1: return a() }`, Output: map[string]interface{}{"b": int64(2)}}, 596 597 // test 2 cases 598 {Script: `a = 1; switch a {case 1: return 5; case 2: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 599 {Script: `a = 2; switch a {case 1: return 5; case 2: return 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(2)}}, 600 {Script: `a = 3; switch a {case 1: return 5; case 2: return 6}`, Output: map[string]interface{}{"a": int64(3)}}, 601 {Script: `a = 1; switch a {case 1: return 5; case 2,3: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 602 {Script: `a = 2; switch a {case 1: return 5; case 2,3: return 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(2)}}, 603 {Script: `a = 3; switch a {case 1: return 5; case 2,3: return 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(3)}}, 604 {Script: `a = 4; switch a {case 1: return 5; case 2,3: return 6}`, Output: map[string]interface{}{"a": int64(4)}}, 605 606 // test 3 cases 607 {Script: `a = 1; switch a {case 1,2: return 5; case 3: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 608 {Script: `a = 2; switch a {case 1,2: return 5; case 3: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(2)}}, 609 {Script: `a = 3; switch a {case 1,2: return 5; case 3: return 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(3)}}, 610 {Script: `a = 4; switch a {case 1,2: return 5; case 3: return 6}`, Output: map[string]interface{}{"a": int64(4)}}, 611 {Script: `a = 1; switch a {case 1,2: return 5; case 2,3: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 612 {Script: `a = 2; switch a {case 1,2: return 5; case 2,3: return 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(2)}}, 613 {Script: `a = 3; switch a {case 1,2: return 5; case 2,3: return 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(3)}}, 614 {Script: `a = 4; switch a {case 1,2: return 5; case 2,3: return 6}`, Output: map[string]interface{}{"a": int64(4)}}, 615 616 // test default 617 {Script: `a = 1; switch a {default: return 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 618 {Script: `a = 1; switch a {case 1: return 5; case 2: return 6; default: return 7}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 619 {Script: `a = 2; switch a {case 1: return 5; case 2: return 6; default: return 7}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(2)}}, 620 {Script: `a = 3; switch a {case 1: return 5; case 2: return 6; default: return 7}`, RunOutput: int64(7), Output: map[string]interface{}{"a": int64(3)}}, 621 {Script: `a = 1; switch a {case 1: return 5; case 2,3: return 6; default: return 7}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 622 {Script: `a = 2; switch a {case 1: return 5; case 2,3: return 6; default: return 7}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(2)}}, 623 {Script: `a = 3; switch a {case 1: return 5; case 2,3: return 6; default: return 7}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(3)}}, 624 {Script: `a = 4; switch a {case 1: return 5; case 2,3: return 6; default: return 7}`, RunOutput: int64(7), Output: map[string]interface{}{"a": int64(4)}}, 625 {Script: `a = 1; switch a {case 1,2: return 5; case 3: return 6; default: return 7}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 626 {Script: `a = 2; switch a {case 1,2: return 5; case 3: return 6; default: return 7}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(2)}}, 627 {Script: `a = 3; switch a {case 1,2: return 5; case 3: return 6; default: return 7}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(3)}}, 628 {Script: `a = 4; switch a {case 1,2: return 5; case 3: return 6; default: return 7}`, RunOutput: int64(7), Output: map[string]interface{}{"a": int64(4)}}, 629 630 // test scope 631 {Script: `a = 1; switch a {case 1: a = 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(5)}}, 632 {Script: `a = 2; switch a {case 1: a = 5}`, Output: map[string]interface{}{"a": int64(2)}}, 633 {Script: `a = 1; b = 5; switch a {case 1: b = 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(1), "b": int64(6)}}, 634 {Script: `a = 2; b = 5; switch a {case 1: b = 6}`, Output: map[string]interface{}{"a": int64(2), "b": int64(5)}}, 635 {Script: `a = 1; b = 5; switch a {case 1: b = 6; default: b = 7}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(1), "b": int64(6)}}, 636 {Script: `a = 2; b = 5; switch a {case 1: b = 6; default: b = 7}`, RunOutput: int64(7), Output: map[string]interface{}{"a": int64(2), "b": int64(7)}}, 637 638 // test scope without define b 639 {Script: `a = 1; switch a {case 1: b = 5}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 640 {Script: `a = 2; switch a {case 1: b = 5}`, Output: map[string]interface{}{"a": int64(2)}}, 641 {Script: `a = 1; switch a {case 1: b = 5}; b`, RunError: fmt.Errorf("undefined symbol 'b'"), RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 642 {Script: `a = 2; switch a {case 1: b = 5}; b`, RunError: fmt.Errorf("undefined symbol 'b'"), RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 643 {Script: `a = 1; switch a {case 1: b = 5; default: b = 6}`, RunOutput: int64(5), Output: map[string]interface{}{"a": int64(1)}}, 644 {Script: `a = 2; switch a {case 1: b = 5; default: b = 6}`, RunOutput: int64(6), Output: map[string]interface{}{"a": int64(2)}}, 645 {Script: `a = 1; switch a {case 1: b = 5; default: b = 6}; b`, RunError: fmt.Errorf("undefined symbol 'b'"), RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 646 {Script: `a = 2; switch a {case 1: b = 5; default: b = 6}; b`, RunError: fmt.Errorf("undefined symbol 'b'"), RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 647 648 // test new lines 649 {Script: ` 650 a = 1; 651 switch a { 652 case 1: 653 return 1 654 }`, RunOutput: int64(1)}, 655 } 656 runTests(t, tests, nil, &Options{Debug: true}) 657 } 658 659 func TestForLoop(t *testing.T) { 660 t.Parallel() 661 662 tests := []Test{ 663 {Script: `for in [1] { }`, ParseError: fmt.Errorf("missing identifier")}, 664 {Script: `for a, b, c in [1] { }`, ParseError: fmt.Errorf("too many identifiers")}, 665 666 {Script: `break`, RunError: fmt.Errorf("unexpected break statement")}, 667 {Script: `continue`, RunError: fmt.Errorf("unexpected continue statement")}, 668 {Script: `for 1++ { }`, RunError: fmt.Errorf("invalid operation")}, 669 {Script: `for { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 670 {Script: `for a in 1++ { }`, RunError: fmt.Errorf("invalid operation")}, 671 672 {Script: `for { break }`, RunOutput: nil}, 673 {Script: `for {a = 1; if a == 1 { break } }`, RunOutput: nil}, 674 {Script: `a = 1; for { if a == 1 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 675 {Script: `a = 1; for { if a == 1 { break }; a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 676 {Script: `a = 1; for { if a == 3 { break }; a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 677 678 {Script: `a = 1; for { if a == 1 { return }; a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 679 {Script: `a = 1; for { if a == 3 { return }; a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 680 {Script: `a = 1; for { if a == 1 { return 2 }; a++ }`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(1)}}, 681 {Script: `a = 1; for { if a == 3 { return 2 }; a++ }`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(3)}}, 682 683 {Script: `a = 1; for { if a == 3 { return 3 }; a++ }; return 2`, RunOutput: int64(3), Output: map[string]interface{}{"a": int64(3)}}, 684 685 {Script: `a = 1; for { a++; if a == 2 { continue } else { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 686 {Script: `a = 1; for { a++; if a == 2 { continue }; if a == 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 687 688 {Script: `for a in [1] { if a == 1 { break } }`, RunOutput: nil}, 689 {Script: `for a in [1, 2] { if a == 2 { break } }`, RunOutput: nil}, 690 {Script: `for a in [1, 2, 3] { if a == 3 { break } }`, RunOutput: nil}, 691 692 {Script: `for a in [1, 2, 3] { if a == 2 { return 2 } }; return 3`, RunOutput: int64(2)}, 693 694 {Script: `a = [1]; for b in a { if b == 1 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1)}}}, 695 {Script: `a = [1, 2]; for b in a { if b == 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1), int64(2)}}}, 696 {Script: `a = [1, 2, 3]; for b in a { if b == 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1), int64(2), int64(3)}}}, 697 698 {Script: `a = [1]; b = 0; for c in a { b = c }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1)}, "b": int64(1)}}, 699 {Script: `a = [1, 2]; b = 0; for c in a { b = c }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1), int64(2)}, "b": int64(2)}}, 700 {Script: `a = [1, 2, 3]; b = 0; for c in a { b = c }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1), int64(2), int64(3)}, "b": int64(3)}}, 701 702 {Script: `a = 1; for a < 2 { a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 703 {Script: `a = 1; for a < 3 { a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 704 705 {Script: `a = 1; for nil { a++; if a > 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 706 {Script: `a = 1; for nil { a++; if a > 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 707 {Script: `a = 1; for true { a++; if a > 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 708 {Script: `a = 1; for true { a++; if a > 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(4)}}, 709 710 {Script: `func x() { return [1] }; for b in x() { if b == 1 { break } }`, RunOutput: nil}, 711 {Script: `func x() { return [1, 2] }; for b in x() { if b == 2 { break } }`, RunOutput: nil}, 712 {Script: `func x() { return [1, 2, 3] }; for b in x() { if b == 3 { break } }`, RunOutput: nil}, 713 714 {Script: `func x() { a = 1; for { if a == 1 { return } } }; x()`, RunOutput: nil}, 715 {Script: `func x() { a = 1; for { if a == 1 { return nil } } }; x()`, RunOutput: nil}, 716 {Script: `func x() { a = 1; for { if a == 1 { return true } } }; x()`, RunOutput: true}, 717 {Script: `func x() { a = 1; for { if a == 1 { return 1 } } }; x()`, RunOutput: int64(1)}, 718 {Script: `func x() { a = 1; for { if a == 1 { return 1.1 } } }; x()`, RunOutput: float64(1.1)}, 719 {Script: `func x() { a = 1; for { if a == 1 { return "a" } } }; x()`, RunOutput: "a"}, 720 721 {Script: `func x() { for a in [1, 2, 3] { if a == 3 { return } } }; x()`, RunOutput: nil}, 722 {Script: `func x() { for a in [1, 2, 3] { if a == 3 { return 3 } }; return 2 }; x()`, RunOutput: int64(3)}, 723 {Script: `func x() { for a in [1, 2, 3] { if a == 1 { continue } } }; x()`, RunOutput: nil}, 724 {Script: `func x() { for a in [1, 2, 3] { if a == 1 { continue }; if a == 3 { return } } }; x()`, RunOutput: nil}, 725 726 {Script: `func x() { return [1, 2] }; a = 1; for i in x() { a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 727 {Script: `func x() { return [1, 2, 3] }; a = 1; for i in x() { a++ }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(4)}}, 728 729 {Script: `for a = 1; nil; nil { return }`}, 730 // TOFIX: 731 // {Script: `for a, b = 1; nil; nil { return }`}, 732 // {Script: `for a, b = 1, 2; nil; nil { return }`}, 733 734 {Script: `var a = 1; for ; ; { return a }`, RunOutput: int64(1)}, 735 {Script: `var a = 1; for ; ; a++ { return a }`, RunOutput: int64(1)}, 736 {Script: `var a = 1; for ; a > 0 ; { return a }`, RunOutput: int64(1)}, 737 {Script: `var a = 1; for ; a > 0 ; a++ { return a }`, RunOutput: int64(1)}, 738 {Script: `for var a = 1 ; ; { return a }`, RunOutput: int64(1)}, 739 {Script: `for var a = 1 ; ; a++ { return a }`, RunOutput: int64(1)}, 740 {Script: `for var a = 1 ; a > 0 ; { return a }`, RunOutput: int64(1)}, 741 {Script: `for var a = 1 ; a > 0 ; a++ { return a }`, RunOutput: int64(1)}, 742 743 {Script: `for var a = 1; nil; nil { return }`}, 744 {Script: `for var a = 1, 2; nil; nil { return }`}, 745 {Script: `for var a, b = 1; nil; nil { return }`}, 746 {Script: `for var a, b = 1, 2; nil; nil { return }`}, 747 748 {Script: `for a.b = 1; nil; nil { return }`, RunError: fmt.Errorf("undefined symbol 'a'")}, 749 750 {Script: `for a = 1; nil; nil { if a == 1 { break } }`, RunOutput: nil}, 751 {Script: `for a = 1; nil; nil { if a == 2 { break }; a++ }`, RunOutput: nil}, 752 {Script: `for a = 1; nil; nil { a++; if a == 3 { break } }`, RunOutput: nil}, 753 754 {Script: `for a = 1; a < 1; nil { }`, RunOutput: nil}, 755 {Script: `for a = 1; a > 1; nil { }`, RunOutput: nil}, 756 {Script: `for a = 1; a == 1; nil { break }`, RunOutput: nil}, 757 758 {Script: `for a = 1; a == 1; a++ { }`, RunOutput: nil}, 759 {Script: `for a = 1; a < 2; a++ { }`, RunOutput: nil}, 760 {Script: `for a = 1; a < 3; a++ { }`, RunOutput: nil}, 761 762 {Script: `for a = 1; a < 5; a++ { if a == 3 { return 3 } }; return 2`, RunOutput: int64(3)}, 763 764 {Script: `a = 1; for b = 1; a < 1; a++ { }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 765 {Script: `a = 1; for b = 1; a < 2; a++ { }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 766 {Script: `a = 1; for b = 1; a < 3; a++ { }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 767 768 {Script: `a = 1; for b = 1; a < 1; a++ { if a == 1 { continue } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 769 {Script: `a = 1; for b = 1; a < 2; a++ { if a == 1 { continue } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 770 {Script: `a = 1; for b = 1; a < 3; a++ { if a == 1 { continue } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 771 772 {Script: `a = 1; for b = 1; a < 1; a++ { if a == 1 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 773 {Script: `a = 1; for b = 1; a < 2; a++ { if a == 1 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 774 {Script: `a = 1; for b = 1; a < 3; a++ { if a == 1 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 775 {Script: `a = 1; for b = 1; a < 1; a++ { if a == 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 776 {Script: `a = 1; for b = 1; a < 2; a++ { if a == 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 777 {Script: `a = 1; for b = 1; a < 3; a++ { if a == 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 778 {Script: `a = 1; for b = 1; a < 1; a++ { if a == 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}}, 779 {Script: `a = 1; for b = 1; a < 2; a++ { if a == 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(2)}}, 780 {Script: `a = 1; for b = 1; a < 3; a++ { if a == 3 { break } }`, RunOutput: nil, Output: map[string]interface{}{"a": int64(3)}}, 781 782 {Script: `a = ["123", "456", "789"]; b = ""; for i = 0; i < len(a); i++ { b += a[i][len(a[i]) - 2:]; b += a[i][:len(a[i]) - 2] }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{"123", "456", "789"}, "b": "231564897"}}, 783 {Script: `a = [[["123"], ["456"]], [["789"]]]; b = ""; for i = 0; i < len(a); i++ { for j = 0; j < len(a[i]); j++ { for k = 0; k < len(a[i][j]); k++ { for l = 0; l < len(a[i][j][k]); l++ { b += a[i][j][k][l] + "-" } } } }`, 784 RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{[]interface{}{[]interface{}{"123"}, []interface{}{"456"}}, []interface{}{[]interface{}{"789"}}}, "b": "1-2-3-4-5-6-7-8-9-"}}, 785 786 {Script: `func x() { for a = 1; a < 3; a++ { if a == 1 { return a } } }; x()`, RunOutput: int64(1)}, 787 {Script: `func x() { for a = 1; a < 3; a++ { if a == 2 { return a } } }; x()`, RunOutput: int64(2)}, 788 {Script: `func x() { for a = 1; a < 3; a++ { if a == 3 { return a } } }; x()`, RunOutput: nil}, 789 {Script: `func x() { for a = 1; a < 3; a++ { if a == 4 { return a } } }; x()`, RunOutput: nil}, 790 791 {Script: `func x() { a = 1; for b = 1; a < 3; a++ { if a == 1 { continue } }; return a }; x()`, RunOutput: int64(3)}, 792 {Script: `func x() { a = 1; for b = 1; a < 3; a++ { if a == 2 { continue } }; return a }; x()`, RunOutput: int64(3)}, 793 {Script: `func x() { a = 1; for b = 1; a < 3; a++ { if a == 3 { continue } }; return a }; x()`, RunOutput: int64(3)}, 794 {Script: `func x() { a = 1; for b = 1; a < 3; a++ { if a == 4 { continue } }; return a }; x()`, RunOutput: int64(3)}, 795 796 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{reflect.Value{}}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{reflect.Value{}}, "b": reflect.Value{}}}, 797 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{nil}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{nil}, "b": nil}}, 798 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{true}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{true}, "b": true}}, 799 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{int32(1)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int32(1)}, "b": int32(1)}}, 800 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{int64(1)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{int64(1)}, "b": int64(1)}}, 801 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{float32(1.1)}, "b": float32(1.1)}}, 802 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}, "b": float64(1.1)}}, 803 804 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(reflect.Value{})}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(reflect.Value{})}, "b": interface{}(reflect.Value{})}}, 805 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(nil)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(nil)}, "b": interface{}(nil)}}, 806 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(true)}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(true)}, "b": interface{}(true)}}, 807 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(int32(1))}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(int32(1))}, "b": interface{}(int32(1))}}, 808 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(int64(1))}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(int64(1))}, "b": interface{}(int64(1))}}, 809 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(float32(1.1))}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(float32(1.1))}, "b": interface{}(float32(1.1))}}, 810 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": []interface{}{interface{}(float64(1.1))}}, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{interface{}(float64(1.1))}, "b": interface{}(float64(1.1))}}, 811 812 {Script: `b = 0; for i in a { b = i }`, Input: map[string]interface{}{"a": interface{}([]interface{}{nil})}, RunOutput: nil, Output: map[string]interface{}{"a": interface{}([]interface{}{nil}), "b": nil}}, 813 814 {Script: `for i in nil { }`, RunError: fmt.Errorf("for cannot loop over type interface")}, 815 {Script: `for i in true { }`, RunError: fmt.Errorf("for cannot loop over type bool")}, 816 {Script: `for i in a { }`, Input: map[string]interface{}{"a": reflect.Value{}}, RunError: fmt.Errorf("for cannot loop over type struct"), Output: map[string]interface{}{"a": reflect.Value{}}}, 817 {Script: `for i in a { }`, Input: map[string]interface{}{"a": interface{}(nil)}, RunError: fmt.Errorf("for cannot loop over type interface"), Output: map[string]interface{}{"a": interface{}(nil)}}, 818 {Script: `for i in a { }`, Input: map[string]interface{}{"a": interface{}(true)}, RunError: fmt.Errorf("for cannot loop over type bool"), Output: map[string]interface{}{"a": interface{}(true)}}, 819 {Script: `for i in [1, 2, 3] { b++ }`, RunError: fmt.Errorf("undefined symbol 'b'")}, 820 {Script: `for a = 1; a < 3; a++ { b++ }`, RunError: fmt.Errorf("undefined symbol 'b'")}, 821 {Script: `for a = b; a < 3; a++ { }`, RunError: fmt.Errorf("undefined symbol 'b'")}, 822 {Script: `for a = 1; b < 3; a++ { }`, RunError: fmt.Errorf("undefined symbol 'b'")}, 823 {Script: `for a = 1; a < 3; b++ { }`, RunError: fmt.Errorf("undefined symbol 'b'")}, 824 825 {Script: `a = 1; b = [{"c": "c"}]; for i in b { a = i }`, RunOutput: nil, Output: map[string]interface{}{"a": map[interface{}]interface{}{"c": "c"}, "b": []interface{}{map[interface{}]interface{}{"c": "c"}}}}, 826 {Script: `a = 1; b = {"x": [{"y": "y"}]}; for i in b.x { a = i }`, RunOutput: nil, Output: map[string]interface{}{"a": map[interface{}]interface{}{"y": "y"}, "b": map[interface{}]interface{}{"x": []interface{}{map[interface{}]interface{}{"y": "y"}}}}}, 827 828 {Script: `a = {}; b = 1; for i in a { b = i }; b`, RunOutput: int64(1), Output: map[string]interface{}{"a": map[interface{}]interface{}{}, "b": int64(1)}}, 829 {Script: `a = {"x": 2}; b = 1; for i in a { b = i }; b`, RunOutput: "x", Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2)}, "b": "x"}}, 830 {Script: `a = {"x": 2, "y": 3}; b = 0; for i in a { b++ }; b`, RunOutput: int64(2), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}, "b": int64(2)}}, 831 {Script: `a = {"x": 2, "y": 3}; for i in a { b++ }`, RunError: fmt.Errorf("undefined symbol 'b'"), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}}}, 832 833 {Script: `a = {"x": 2, "y": 3}; b = 0; for i in a { if i == "x" { continue }; b = i }; b`, RunOutput: "y", Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}, "b": "y"}}, 834 {Script: `a = {"x": 2, "y": 3}; b = 0; for i in a { if i == "y" { continue }; b = i }; b`, RunOutput: "x", Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}, "b": "x"}}, 835 {Script: `a = {"x": 2, "y": 3}; for i in a { if i == "x" { return 1 } }`, RunOutput: int64(1), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}}}, 836 {Script: `a = {"x": 2, "y": 3}; for i in a { if i == "y" { return 2 } }`, RunOutput: int64(2), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}}}, 837 {Script: `a = {"x": 2, "y": 3}; b = 0; for i in a { if i == "x" { break }; b++ }; if b > 1 { return false } else { return true }`, RunOutput: true, Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}}}, 838 {Script: `a = {"x": 2, "y": 3}; b = 0; for i in a { if i == "y" { break }; b++ }; if b > 1 { return false } else { return true }`, RunOutput: true, Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}}}, 839 {Script: `a = {"x": 2, "y": 3}; b = 1; for i in a { if (i == "x" || i == "y") { break }; b++ }; b`, RunOutput: int64(1), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2), "y": int64(3)}, "b": int64(1)}}, 840 841 {Script: `a = ["123", "456", "789"]; b = ""; for v in a { b += v[len(v) - 2:]; b += v[:len(v) - 2] }`, RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{"123", "456", "789"}, "b": "231564897"}}, 842 {Script: `a = [[["123"], ["456"]], [["789"]]]; b = ""; for x in a { for y in x { for z in y { for i = 0; i < len(z); i++ { b += z[i] + "-" } } } }`, 843 RunOutput: nil, Output: map[string]interface{}{"a": []interface{}{[]interface{}{[]interface{}{"123"}, []interface{}{"456"}}, []interface{}{[]interface{}{"789"}}}, "b": "1-2-3-4-5-6-7-8-9-"}}, 844 845 {Script: `a = {"x": 2}; b = 0; for k, v in a { b = k }; b`, RunOutput: "x", Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2)}, "b": "x"}}, 846 {Script: `a = {"x": 2}; b = 0; for k, v in a { b = v }; b`, RunOutput: int64(2), Output: map[string]interface{}{"a": map[interface{}]interface{}{"x": int64(2)}, "b": int64(2)}}, 847 848 {Script: `a = make(chan int64, 2); a <- 1; v = 0; for val in a { v = val; break; }; v`, RunOutput: int64(1), Output: map[string]interface{}{"v": int64(1)}}, 849 {Script: `a = make(chan int64, 4); a <- 1; a <- 2; a <- 3; for i in a { if i == 2 { return 2 } }; return 4`, RunOutput: int64(2)}, 850 {Script: `a = make(chan int64, 2); a <- 1; for i in a { if i < 4 { a <- i + 1; continue }; return 4 }; return 6`, RunOutput: int64(4)}, 851 852 // test non-buffer and go func 853 {Script: `a = make(chan int64); go func() { a <- 1; a <- 2; a <- 3 }(); b = []; for i in a { b += i; if i > 2 { break } }`, RunOutput: nil, Output: map[string]interface{}{"b": []interface{}{int64(1), int64(2), int64(3)}}}, 854 {Script: `a = make(chan int64); go func() { a <- 1; a <- 2; a <- 3; close(a) }(); b = []; for i in a { b += i }`, RunOutput: nil, Output: map[string]interface{}{"b": []interface{}{int64(1), int64(2), int64(3)}}}, 855 } 856 runTests(t, tests, nil, &Options{Debug: true}) 857 } 858 859 func TestItemInList(t *testing.T) { 860 t.Parallel() 861 862 tests := []Test{ 863 {Script: `"a" in ["a"]`, RunOutput: true}, 864 {Script: `"a" in ["b"]`, RunOutput: false}, 865 {Script: `"a" in ["c", "b", "a"]`, RunOutput: true}, 866 {Script: `"a" in ["a", "b", 1]`, RunOutput: true}, 867 {Script: `"a" in l`, Input: map[string]interface{}{"l": []interface{}{"a"}}, RunOutput: true}, 868 {Script: `"a" in l`, Input: map[string]interface{}{"l": []interface{}{"b"}}, RunOutput: false}, 869 {Script: `"a" in l`, Input: map[string]interface{}{"l": []interface{}{"c", "b", "a"}}, RunOutput: true}, 870 {Script: `"a" in l`, Input: map[string]interface{}{"l": []interface{}{"a", "b", 1}}, RunOutput: true}, 871 872 {Script: `1 in [1]`, RunOutput: true}, 873 {Script: `1 in [2]`, RunOutput: false}, 874 {Script: `1 in [3, 2, 1]`, RunOutput: true}, 875 {Script: `1 in ["1"]`, RunOutput: true}, 876 {Script: `1 in l`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 877 {Script: `"1" in l`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 878 {Script: `1 in l`, Input: map[string]interface{}{"l": []interface{}{2}}, RunOutput: false}, 879 {Script: `1 in l`, Input: map[string]interface{}{"l": []interface{}{3, 2, 1}}, RunOutput: true}, 880 {Script: `1 in l`, Input: map[string]interface{}{"l": []interface{}{"1"}}, RunOutput: true}, 881 882 {Script: `0.9 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 883 {Script: `1.0 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 884 {Script: `1.1 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 885 {Script: `1 in [0.9]`, Input: map[string]interface{}{"l": []interface{}{0.9}}, RunOutput: false}, 886 {Script: `1 in [1.0]`, Input: map[string]interface{}{"l": []interface{}{1.0}}, RunOutput: true}, 887 {Script: `1 in [1.1]`, Input: map[string]interface{}{"l": []interface{}{1.1}}, RunOutput: false}, 888 {Script: `0.9 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 889 {Script: `1.0 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 890 {Script: `1.1 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 891 {Script: `1 in [0.9]`, Input: map[string]interface{}{"l": []interface{}{0.9}}, RunOutput: false}, 892 {Script: `1 in [1.0]`, Input: map[string]interface{}{"l": []interface{}{1.0}}, RunOutput: true}, 893 {Script: `1 in [1.1]`, Input: map[string]interface{}{"l": []interface{}{1.1}}, RunOutput: false}, 894 895 {Script: `true in ["true"]`, RunOutput: true}, 896 {Script: `true in [true]`, RunOutput: true}, 897 {Script: `true in [true, false]`, RunOutput: true}, 898 {Script: `false in [false, true]`, RunOutput: true}, 899 {Script: `true in l`, Input: map[string]interface{}{"l": []interface{}{"true"}}, RunOutput: true}, 900 {Script: `true in l`, Input: map[string]interface{}{"l": []interface{}{true}}, RunOutput: true}, 901 {Script: `true in l`, Input: map[string]interface{}{"l": []interface{}{true, false}}, RunOutput: true}, 902 {Script: `false in l`, Input: map[string]interface{}{"l": []interface{}{false, true}}, RunOutput: true}, 903 904 {Script: `"a" in ["b", "a", "c"][1:]`, RunOutput: true}, 905 {Script: `"a" in ["b", "a", "c"][:1]`, RunOutput: false}, 906 {Script: `"a" in ["b", "a", "c"][1:2]`, RunOutput: true}, 907 {Script: `l = ["b", "a", "c"];"a" in l[1:]`, RunOutput: true}, 908 {Script: `l = ["b", "a", "c"];"a" in l[:1]`, RunOutput: false}, 909 {Script: `l = ["b", "a", "c"];"a" in l[1:2]`, RunOutput: true}, 910 {Script: `"a" in l[1:]`, Input: map[string]interface{}{"l": []interface{}{"b", "a", "c"}}, RunOutput: true}, 911 {Script: `"a" in l[:1]`, Input: map[string]interface{}{"l": []interface{}{"b", "a", "c"}}, RunOutput: false}, 912 {Script: `"a" in l[1:2]`, Input: map[string]interface{}{"l": []interface{}{"b", "a", "c"}}, RunOutput: true}, 913 914 // for i in list && item in list 915 {Script: `list_of_list = [["a"]];for l in list_of_list { return "a" in l }`, RunOutput: true}, 916 {Script: `for l in list_of_list { return "a" in l }`, Input: map[string]interface{}{"list_of_list": []interface{}{[]interface{}{"a"}}}, RunOutput: true}, 917 918 // not slice or array 919 // todo: support `"a" in "aaa"` ? 920 {Script: `"a" in "aaa"`, RunError: fmt.Errorf("second argument must be slice or array; but have string")}, 921 {Script: `1 in 12345`, RunError: fmt.Errorf("second argument must be slice or array; but have int64")}, 922 923 // a in item in list 924 {Script: `"a" in 5 in [1, 2, 3]`, RunError: fmt.Errorf("second argument must be slice or array; but have bool")}, 925 926 // applying a in b in several part of expresstion/statement 927 {Script: `switch 1 in [1] {case true: return true;default: return false}`, RunOutput: true}, 928 {Script: `switch 1 in [2,3] {case true: return true;default: return false}`, RunOutput: false}, 929 {Script: `switch true {case 1 in [1]: return true;default: return false}`, RunOutput: true}, 930 {Script: `switch false {case 1 in [1]: return true;default: return false}`, RunOutput: false}, 931 {Script: `if 1 in [1] {return true} else {return false}`, RunOutput: true}, 932 {Script: `if 1 in [2,3] {return true} else {return false}`, RunOutput: false}, 933 {Script: `for i in [1,2,3] { i++ }`}, 934 {Script: `a=1; a=a in [1]`, RunOutput: true}, 935 {Script: `a=1; a=a in [2,3]`, RunOutput: false}, 936 {Script: `1 in [1] && true`, RunOutput: true}, 937 {Script: `1 in [1] && false`, RunOutput: false}, 938 {Script: `1 in [1] || true`, RunOutput: true}, 939 {Script: `1 in [1] || false`, RunOutput: true}, 940 {Script: `1 in [2,3] && true`, RunOutput: false}, 941 {Script: `1 in [2,3] && false`, RunOutput: false}, 942 {Script: `1 in [2,3] || true`, RunOutput: true}, 943 {Script: `1 in [2,3] || false`, RunOutput: false}, 944 {Script: `1++ in [1, 2, 3]`, RunError: fmt.Errorf("invalid operation")}, 945 {Script: `3++ in [1, 2, 3]`, RunError: fmt.Errorf("invalid operation")}, 946 {Script: `1 in 1++`, RunError: fmt.Errorf("invalid operation")}, 947 {Script: `a=1;a++ in [1, 2, 3]`, RunOutput: true}, 948 {Script: `a=3;a++ in [1, 2, 3]`, RunOutput: false}, 949 {Script: `switch 1 in l {case true: return true;default: return false}`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 950 {Script: `switch 1 in l {case true: return true;default: return false}`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 951 {Script: `switch true {case 1 in l: return true;default: return false}`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 952 {Script: `switch false {case 1 in l: return true;default: return false}`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 953 {Script: `if 1 in l {return true} else {return false}`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 954 {Script: `if 1 in l {return true} else {return false}`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 955 {Script: `for i in l { i++ }`, Input: map[string]interface{}{"l": []interface{}{1, 2, 3}}}, 956 {Script: `a=1; a=a in l`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 957 {Script: `a=1; a=a in l`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 958 {Script: `1 in l && true`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 959 {Script: `1 in l && false`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 960 {Script: `1 in l || true`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 961 {Script: `1 in l || false`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 962 {Script: `1 in l && true`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 963 {Script: `1 in l && false`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 964 {Script: `1 in l || true`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: true}, 965 {Script: `1 in l || false`, Input: map[string]interface{}{"l": []interface{}{2, 3}}, RunOutput: false}, 966 {Script: `1++ in l`, Input: map[string]interface{}{"l": []interface{}{1, 2, 3}}, RunError: fmt.Errorf("invalid operation")}, 967 {Script: `3++ in l`, Input: map[string]interface{}{"l": []interface{}{1, 2, 3}}, RunError: fmt.Errorf("invalid operation")}, 968 {Script: `a=1;a++ in l`, Input: map[string]interface{}{"l": []interface{}{1, 2, 3}}, RunOutput: true}, 969 {Script: `a=3;a++ in l`, Input: map[string]interface{}{"l": []interface{}{1, 2, 3}}, RunOutput: false}, 970 971 // multidimensional slice 972 {Script: `1 in [1]`, RunOutput: true}, 973 {Script: `1 in [[1]]`, RunOutput: false}, 974 {Script: `1 in [[[1]]]`, RunOutput: false}, 975 {Script: `1 in [[1],[[1]],1]`, RunOutput: true}, 976 {Script: `[1] in [1]`, RunOutput: false}, 977 {Script: `[1] in [[1]]`, RunOutput: true}, 978 {Script: `[1] in [[[1]]]`, RunOutput: false}, 979 {Script: `[[1]] in [1]`, RunOutput: false}, 980 {Script: `[[1]] in [[1]]`, RunOutput: false}, 981 {Script: `[[1]] in [[[1]]]`, RunOutput: true}, 982 {Script: `1 in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: true}, 983 {Script: `1 in [[1]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{1}}}, RunOutput: false}, 984 {Script: `1 in [[[1]]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{[]interface{}{1}}}}, RunOutput: false}, 985 {Script: `1 in [[1],[[1]],1]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{1}, []interface{}{[]interface{}{1}}, 1}}, RunOutput: true}, 986 {Script: `[1] in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 987 {Script: `[1] in [[1]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{1}}}, RunOutput: true}, 988 {Script: `[1] in [[[1]]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{[]interface{}{1}}}}, RunOutput: false}, 989 {Script: `[[1]] in [1]`, Input: map[string]interface{}{"l": []interface{}{1}}, RunOutput: false}, 990 {Script: `[[1]] in [[1]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{1}}}, RunOutput: false}, 991 {Script: `[[1]] in [[[1]]]`, Input: map[string]interface{}{"l": []interface{}{[]interface{}{[]interface{}{1}}}}, RunOutput: true}, 992 } 993 runTests(t, tests, nil, &Options{Debug: true}) 994 } 995 996 func TestOperatorPrecedence(t *testing.T) { 997 t.Parallel() 998 999 tests := []Test{ 1000 // test && > || 1001 {Script: `true || true && false`, RunOutput: true}, 1002 {Script: `(true || true) && false`, RunOutput: false}, 1003 {Script: `false && true || true`, RunOutput: true}, 1004 {Script: `false && (true || true)`, RunOutput: false}, 1005 1006 // test == > || 1007 {Script: `0 == 1 || 1 == 1`, RunOutput: true}, 1008 {Script: `0 == (1 || 1) == 1`, RunOutput: false}, 1009 1010 // test + > == 1011 {Script: `1 + 2 == 2 + 1`, RunOutput: true}, 1012 {Script: `1 + (2 == 2) + 1`, RunOutput: int64(3)}, 1013 1014 // test * > + 1015 {Script: `2 * 3 + 4 * 5`, RunOutput: int64(26)}, 1016 {Script: `2 * (3 + 4) * 5`, RunOutput: int64(70)}, 1017 1018 // test * > && 1019 {Script: `2 * 0 && 3 * 4`, RunOutput: false}, 1020 {Script: `2 * (0 && 3) * 4`, RunOutput: int64(0)}, 1021 1022 // test ++ > * 1023 {Script: `a = 1; b = 2; a++ * b++`, RunOutput: int64(6)}, 1024 1025 // test ++ > * 1026 {Script: `a = 1; b = 2; a++ * b++`, RunOutput: int64(6)}, 1027 1028 // test unary - > + 1029 {Script: `a = 1; b = 2; -a + b`, RunOutput: int64(1)}, 1030 {Script: `a = 1; b = 2; -(a + b)`, RunOutput: int64(-3)}, 1031 {Script: `a = 1; b = 2; a + -b`, RunOutput: int64(-1)}, 1032 1033 // test ! > || 1034 {Script: `!true || true`, RunOutput: true}, 1035 {Script: `!(true || true)`, RunOutput: false}, 1036 } 1037 runTests(t, tests, nil, &Options{Debug: true}) 1038 } 1039 1040 func TestTry(t *testing.T) { 1041 t.Parallel() 1042 1043 tests := []Test{ 1044 {Script: `try { 1++ } catch { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 1045 {Script: `try { 1++ } catch a { return a }`, RunOutput: fmt.Errorf("invalid operation")}, 1046 {Script: `try { 1++ } catch a { a = 2 }; return a`, RunError: fmt.Errorf("undefined symbol 'a'")}, 1047 1048 // test finally 1049 {Script: `try { 1++ } catch { 1++ } finally { return 1 }`, RunError: fmt.Errorf("invalid operation")}, 1050 {Script: `try { } catch { } finally { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 1051 {Script: `try { } catch { 1 } finally { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 1052 {Script: `try { 1++ } catch { } finally { 1++ }`, RunError: fmt.Errorf("invalid operation")}, 1053 {Script: `try { 1++ } catch a { } finally { return a }`, RunOutput: fmt.Errorf("invalid operation")}, 1054 {Script: `try { 1++ } catch a { } finally { a = 2 }; return a`, RunError: fmt.Errorf("undefined symbol 'a'")}, 1055 1056 {Script: `try { } catch { }`, RunOutput: nil}, 1057 {Script: `try { 1++ } catch { }`, RunOutput: nil}, 1058 {Script: `try { } catch { 1++ }`, RunOutput: nil}, 1059 {Script: `try { return 1 } catch { }`, RunOutput: int64(1)}, 1060 {Script: `try { return 1 } catch { return 2 }`, RunOutput: int64(2)}, 1061 {Script: `try { 1++ } catch { return 1 }`, RunOutput: int64(1)}, 1062 1063 // test finally 1064 {Script: `try { } catch { } finally { return 1 }`, RunOutput: int64(1)}, 1065 {Script: `try { 1++ } catch { } finally { return 1 }`, RunOutput: int64(1)}, 1066 {Script: `try { 1++ } catch { return 1 } finally { 1++ }`, RunOutput: int64(1)}, 1067 1068 // test variable scope 1069 {Script: `try { 1++ } catch a { if a.Error() == "invalid operation" { return 1 } else { return 2 } }`, RunOutput: int64(1)}, 1070 {Script: `try { 1++ } catch a { } finally { if a.Error() == "invalid operation" { return 1 } else { return 2 } }`, RunOutput: int64(1)}, 1071 } 1072 runTests(t, tests, nil, &Options{Debug: true}) 1073 }