github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/test/unit/specs/parsers/expression_spec.js (about) 1 var expParser = require('src/parsers/expression') 2 3 var testCases = [ 4 { 5 // simple path 6 exp: 'a.b.d', 7 scope: { 8 a: { b: { d: 123 }} 9 }, 10 expected: 123, 11 paths: ['a'] 12 }, 13 // complex path 14 { 15 exp: 'a["b"].c', 16 scope: { 17 a: { b: { c: 234 }} 18 }, 19 expected: 234, 20 paths: ['a'] 21 }, 22 { 23 // string concat 24 exp: 'a+b', 25 scope: { 26 a: 'hello', 27 b: 'world' 28 }, 29 expected: 'helloworld', 30 paths: ['a', 'b'] 31 }, 32 { 33 // math 34 exp: 'a - b * 2 + 45', 35 scope: { 36 a: 100, 37 b: 23 38 }, 39 expected: 100 - 23 * 2 + 45, 40 paths: ['a', 'b'] 41 }, 42 { 43 // boolean logic 44 exp: '(a && b) ? c : d || e', 45 scope: { 46 a: true, 47 b: false, 48 c: null, 49 d: false, 50 e: 'worked' 51 }, 52 expected: 'worked', 53 paths: ['a', 'b', 'c', 'd', 'e'] 54 }, 55 { 56 // inline string with newline 57 exp: "a + 'hel\nlo'", 58 scope: { 59 a: 'inline ' 60 }, 61 expected: 'inline hel\nlo', 62 paths: ['a'] 63 }, 64 { 65 // multiline expressions 66 exp: "{\n a: '35',\n b: c}", 67 scope: {c: 32}, 68 expected: { a: '35', b: 32 } 69 }, 70 { 71 // dollar signs and underscore 72 exp: "_a + ' ' + $b", 73 scope: { 74 _a: 'underscore', 75 $b: 'dollar' 76 }, 77 expected: 'underscore dollar', 78 paths: ['_a', '$b'] 79 }, 80 { 81 // complex with nested values 82 exp: "todo.title + ' : ' + (todo['done'] ? 'yep' : 'nope')", 83 scope: { 84 todo: { 85 title: 'write tests', 86 done: false 87 } 88 }, 89 expected: 'write tests : nope', 90 paths: ['todo'] 91 }, 92 { 93 // expression with no data variables 94 exp: "'a' + 'b'", 95 scope: {}, 96 expected: 'ab', 97 paths: [] 98 }, 99 { 100 // values with same variable name inside strings 101 exp: "'\"test\"' + test + \"'hi'\" + hi", 102 scope: { 103 test: 1, 104 hi: 2 105 }, 106 expected: '"test"1\'hi\'2', 107 paths: ['test', 'hi'] 108 }, 109 { 110 // expressions with inline object literals 111 exp: "sortRows({ column: 'name', test: foo, durrr: 123 })", 112 scope: { 113 sortRows: function (params) { 114 return params.column + params.test + params.durrr 115 }, 116 foo: 'bar' 117 }, 118 expected: 'namebar123', 119 paths: ['sortRows', 'bar'] 120 }, 121 { 122 // space between path segments 123 exp: ' a . b . c + d', 124 scope: { 125 a: { b: { c: 12 }}, 126 d: 3 127 }, 128 expected: 15, 129 paths: ['a', 'd'] 130 }, 131 { 132 // space in bracket identifiers 133 exp: ' a[ " a.b.c " ] + b [ \' e \' ]', 134 scope: { 135 a: {' a.b.c ': 123}, 136 b: {' e ': 234} 137 }, 138 expected: 357, 139 paths: ['a', 'b'] 140 }, 141 { 142 // number literal 143 exp: 'a * 1e2 + 1.1', 144 scope: { 145 a: 3 146 }, 147 expected: 301.1, 148 paths: ['a'] 149 }, 150 { 151 // keyowrd + keyword literal 152 exp: 'true && a.true', 153 scope: { 154 a: { 'true': false } 155 }, 156 expected: false, 157 paths: ['a'] 158 }, 159 { 160 // super complex 161 exp: ' $a + b[ " a.b.c " ][\'123\'].$e&&c[ " d " ].e + Math.round(e) ', 162 scope: { 163 $a: 1, 164 b: { 165 ' a.b.c ': { 166 '123': { $e: 2 } 167 } 168 }, 169 c: { ' d ': {e: 3}}, 170 e: 4.5 171 }, 172 expected: 8, 173 paths: ['$a', 'b', 'c', 'e'] 174 }, 175 { 176 // string with escaped quotes 177 exp: "'a\\'b' + c", 178 scope: { 179 c: '\'c' 180 }, 181 expected: "a'b'c", 182 paths: ['c'] 183 }, 184 { 185 // dynamic sub path 186 exp: "a['b' + i + 'c']", 187 scope: { 188 i: 0, 189 a: { 190 'b0c': 123 191 } 192 }, 193 expected: 123, 194 paths: ['a', 'i'] 195 }, 196 { 197 // Math global, simple path 198 exp: 'Math.PI', 199 scope: {}, 200 expected: Math.PI, 201 paths: [] 202 }, 203 { 204 // Math global, exp 205 exp: 'Math.sin(a)', 206 scope: { 207 a: 1 208 }, 209 expected: Math.sin(1), 210 paths: ['a'] 211 }, 212 { 213 // boolean literal 214 exp: 'true', 215 scope: { 216 true: false 217 }, 218 expected: true, 219 paths: [] 220 }, 221 { 222 // Date global 223 exp: 'Date.now() > new Date("2000-01-01")', 224 scope: {}, 225 expected: true, 226 paths: [] 227 }, 228 // typeof operator 229 { 230 exp: 'typeof test === "string"', 231 scope: { test: '123' }, 232 expected: true, 233 paths: ['test'] 234 }, 235 // isNaN 236 { 237 exp: 'isNaN(a)', 238 scope: { a: 2 }, 239 expected: false, 240 paths: ['a'] 241 }, 242 // parseFloat & parseInt 243 { 244 exp: 'parseInt(a, 10) + parseFloat(b)', 245 scope: { a: 2.33, b: '3.45' }, 246 expected: 5.45, 247 paths: ['a', 'b'] 248 } 249 ] 250 251 describe('Expression Parser', function () { 252 testCases.forEach(function (testCase) { 253 it('parse getter: ' + testCase.exp, function () { 254 var res = expParser.parseExpression(testCase.exp, true) 255 expect(res.get(testCase.scope)).toEqual(testCase.expected) 256 }) 257 }) 258 259 it('dynamic setter', function () { 260 // make sure checkSetter works: 261 // should add setter if a cache hit doesn't have hit function. 262 expParser.parseExpression('a[b]') 263 var res = expParser.parseExpression('a[b]', true) 264 var scope = { 265 a: { c: 1 }, 266 b: 'c' 267 } 268 res.set(scope, 2) 269 expect(scope.a.c).toBe(2) 270 }) 271 272 it('simple path setter', function () { 273 var res = expParser.parseExpression('a.b.c', true) 274 var scope = {} 275 expect(function () { 276 res.set(scope, 123) 277 }).not.toThrow() 278 scope.a = {b: {c: 0}} 279 res.set(scope, 123) 280 expect(scope.a.b.c).toBe(123) 281 }) 282 283 it('cache', function () { 284 var res1 = expParser.parseExpression('a + b') 285 var res2 = expParser.parseExpression('a + b') 286 expect(res1).toBe(res2) 287 }) 288 289 if (canMakeTemplateStringFunction()) { 290 it('ES2015 template string handling', function () { 291 var res = expParser.parseExpression('a + `hi ${ b }` + c') 292 expect(res.get.toString().indexOf('scope.a+`hi ${scope.b}`+scope.c') > -1).toBe(true) 293 res = expParser.parseExpression('`hi ${ b + `${ d }` }`') 294 expect(res.get.toString().indexOf('`hi ${scope.b+`${scope.d}`}`') > -1).toBe(true) 295 res = expParser.parseExpression('{transform:`rotate(${x}deg)`}') 296 expect(res.get.toString().indexOf('{transform:`rotate(${scope.x}deg)`}') > -1).toBe(true) 297 }) 298 } 299 300 describe('invalid expression', function () { 301 it('should warn on invalid expression', function () { 302 expect(getWarnCount()).toBe(0) 303 expParser.parseExpression('a--b"ffff') 304 expect('Invalid expression').toHaveBeenWarned() 305 }) 306 307 it('should warn on invalid setter expression', function () { 308 expect(getWarnCount()).toBe(0) 309 expParser.parseExpression('a+b', true) 310 expect('Invalid setter expression').toHaveBeenWarned() 311 }) 312 313 it('should warn if expression contains improper reserved keywords', function () { 314 expect(getWarnCount()).toBe(0) 315 expParser.parseExpression('break + 1') 316 expect('Avoid using reserved keywords').toHaveBeenWarned() 317 }) 318 }) 319 }) 320 321 function canMakeTemplateStringFunction () { 322 try { 323 /* eslint-disable no-new-func */ 324 new Function('a', 'return `${a}`') 325 } catch (e) { 326 return false 327 } 328 return true 329 }