| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library parser_test; | 5 library parser_test; |
| 6 | 6 |
| 7 import 'package:polymer_expressions/parser.dart'; | 7 import 'package:polymer_expressions/parser.dart'; |
| 8 import 'package:polymer_expressions/expression.dart'; | 8 import 'package:polymer_expressions/expression.dart'; |
| 9 import 'package:unittest/unittest.dart'; | 9 import 'package:unittest/unittest.dart'; |
| 10 | 10 |
| 11 expectParse(String s, Expression e) => | 11 expectParse(String s, Expression e) => |
| 12 expect(new Parser(s).parse(), e, reason: s); | 12 expect(new Parser(s).parse(), e, reason: s); |
| 13 | 13 |
| 14 final Matcher throwsParseException = |
| 15 throwsA(new isInstanceOf<ParseException>('ParseException')); |
| 16 |
| 14 main() { | 17 main() { |
| 15 | 18 |
| 16 group('parser', () { | 19 group('parser', () { |
| 17 | 20 |
| 18 test('should parse an empty expression', () { | 21 test('should parse an empty expression', () { |
| 19 expectParse('', empty()); | 22 expectParse('', empty()); |
| 20 }); | 23 }); |
| 21 | 24 |
| 22 test('should parse an identifier', () { | 25 test('should parse an identifier', () { |
| 23 expectParse('abc', ident('abc')); | 26 expectParse('abc', ident('abc')); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 47 test('should parse a positive double literal', () { | 50 test('should parse a positive double literal', () { |
| 48 expectParse('+1.23', literal(1.23)); | 51 expectParse('+1.23', literal(1.23)); |
| 49 }); | 52 }); |
| 50 | 53 |
| 51 test('should parse a negative double literal', () { | 54 test('should parse a negative double literal', () { |
| 52 expectParse('-1.23', literal(-1.23)); | 55 expectParse('-1.23', literal(-1.23)); |
| 53 }); | 56 }); |
| 54 | 57 |
| 55 test('should parse binary operators', () { | 58 test('should parse binary operators', () { |
| 56 var operators = ['+', '-', '*', '/', '%', '^', '==', '!=', '>', '<', | 59 var operators = ['+', '-', '*', '/', '%', '^', '==', '!=', '>', '<', |
| 57 '>=', '<=', '||', '&&', '&']; | 60 '>=', '<=', '||', '&&', '&', '===', '!==', '|']; |
| 58 for (var op in operators) { | 61 for (var op in operators) { |
| 59 expectParse('a $op b', binary(ident('a'), op, ident('b'))); | 62 expectParse('a $op b', binary(ident('a'), op, ident('b'))); |
| 60 expectParse('1 $op 2', binary(literal(1), op, literal(2))); | 63 expectParse('1 $op 2', binary(literal(1), op, literal(2))); |
| 61 expectParse('this $op null', binary(ident('this'), op, literal(null))); | 64 expectParse('this $op null', binary(ident('this'), op, literal(null))); |
| 62 } | 65 } |
| 63 }); | 66 }); |
| 64 | 67 |
| 68 test('should thrown on unknown operators', () { |
| 69 expect(() => parse('a ?? b'), throwsParseException); |
| 70 expect(() => parse('a &&& b'), throwsParseException); |
| 71 expect(() => parse('a ==== b'), throwsParseException); |
| 72 }); |
| 73 |
| 65 test('should give multiply higher associativity than plus', () { | 74 test('should give multiply higher associativity than plus', () { |
| 66 expectParse('a + b * c', | 75 expectParse('a + b * c', |
| 67 binary(ident('a'), '+', binary(ident('b'), '*', ident('c')))); | 76 binary(ident('a'), '+', binary(ident('b'), '*', ident('c')))); |
| 68 expectParse('a * b + c', | 77 expectParse('a * b + c', |
| 69 binary(binary(ident('a'), '*', ident('b')), '+', ident('c'))); | 78 binary(binary(ident('a'), '*', ident('b')), '+', ident('c'))); |
| 70 }); | 79 }); |
| 71 | 80 |
| 72 test('should parse a dot operator', () { | 81 test('should parse a dot operator', () { |
| 73 expectParse('a.b', getter(ident('a'), 'b')); | 82 expectParse('a.b', getter(ident('a'), 'b')); |
| 74 }); | 83 }); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 expectParse('a[b] + c[d]', binary( | 157 expectParse('a[b] + c[d]', binary( |
| 149 index(ident('a'), ident('b')), | 158 index(ident('a'), ident('b')), |
| 150 '+', | 159 '+', |
| 151 index(ident('c'), ident('d')))); | 160 index(ident('c'), ident('d')))); |
| 152 }); | 161 }); |
| 153 | 162 |
| 154 test('should parse ternary operators', () { | 163 test('should parse ternary operators', () { |
| 155 expectParse('a ? b : c', ternary(ident('a'), ident('b'), ident('c'))); | 164 expectParse('a ? b : c', ternary(ident('a'), ident('b'), ident('c'))); |
| 156 expectParse('a.a ? b.a : c.a', ternary(getter(ident('a'), 'a'), | 165 expectParse('a.a ? b.a : c.a', ternary(getter(ident('a'), 'a'), |
| 157 getter(ident('b'), 'a'), getter(ident('c'), 'a'))); | 166 getter(ident('b'), 'a'), getter(ident('c'), 'a'))); |
| 158 expect(() => parse('a + 1 ? b + 1 :: c.d + 3'), throws); | 167 expect(() => parse('a + 1 ? b + 1 :: c.d + 3'), throwsParseException); |
| 159 }); | 168 }); |
| 160 | 169 |
| 161 test('ternary operators have lowest associativity', () { | 170 test('ternary operators have lowest associativity', () { |
| 162 expectParse('a == b ? c + d : e - f', ternary( | 171 expectParse('a == b ? c + d : e - f', ternary( |
| 163 binary(ident('a'), '==', ident('b')), | 172 binary(ident('a'), '==', ident('b')), |
| 164 binary(ident('c'), '+', ident('d')), | 173 binary(ident('c'), '+', ident('d')), |
| 165 binary(ident('e'), '-', ident('f')))); | 174 binary(ident('e'), '-', ident('f')))); |
| 166 | 175 |
| 167 expectParse('a.x == b.y ? c + d : e - f', ternary( | 176 expectParse('a.x == b.y ? c + d : e - f', ternary( |
| 168 binary(getter(ident('a'), 'x'), '==', getter(ident('b'), 'y')), | 177 binary(getter(ident('a'), 'x'), '==', getter(ident('b'), 'y')), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 182 | 191 |
| 183 test('should parse "in" expression', () { | 192 test('should parse "in" expression', () { |
| 184 expectParse('a in b', inExpr(ident('a'), ident('b'))); | 193 expectParse('a in b', inExpr(ident('a'), ident('b'))); |
| 185 expectParse('a in b.c', | 194 expectParse('a in b.c', |
| 186 inExpr(ident('a'), getter(ident('b'), 'c'))); | 195 inExpr(ident('a'), getter(ident('b'), 'c'))); |
| 187 expectParse('a in b + c', | 196 expectParse('a in b + c', |
| 188 inExpr(ident('a'), binary(ident('b'), '+', ident('c')))); | 197 inExpr(ident('a'), binary(ident('b'), '+', ident('c')))); |
| 189 }); | 198 }); |
| 190 | 199 |
| 191 test('should reject comprehension with non-assignable left expression', () { | 200 test('should reject comprehension with non-assignable left expression', () { |
| 192 expect(() => parse('a + 1 in b'), throwsException); | 201 expect(() => parse('a + 1 in b'), throwsParseException); |
| 193 }); | 202 }); |
| 194 | 203 |
| 195 test('should parse "as" expressions', () { | 204 test('should parse "as" expressions', () { |
| 196 expectParse('a as b', asExpr(ident('a'), ident('b'))); | 205 expectParse('a as b', asExpr(ident('a'), ident('b'))); |
| 197 }); | 206 }); |
| 198 | 207 |
| 199 skip_test('should reject keywords as identifiers', () { | 208 skip_test('should reject keywords as identifiers', () { |
| 200 expect(() => parse('a.in'), throws); | 209 expect(() => parse('a.in'), throwsParseException); |
| 201 expect(() => parse('a.as'), throws); | 210 expect(() => parse('a.as'), throwsParseException); |
| 202 // TODO: re-enable when 'this' is a keyword | 211 expect(() => parse('a.this'), throwsParseException); |
| 203 // expect(() => parse('a.this'), throws); | |
| 204 }); | 212 }); |
| 205 | 213 |
| 206 test('should parse map literals', () { | 214 test('should parse map literals', () { |
| 207 expectParse("{'a': 1}", | 215 expectParse("{'a': 1}", |
| 208 mapLiteral([mapLiteralEntry(literal('a'), literal(1))])); | 216 mapLiteral([mapLiteralEntry(literal('a'), literal(1))])); |
| 209 expectParse("{'a': 1, 'b': 2 + 3}", | 217 expectParse("{'a': 1, 'b': 2 + 3}", |
| 210 mapLiteral([ | 218 mapLiteral([ |
| 211 mapLiteralEntry(literal('a'), literal(1)), | 219 mapLiteralEntry(literal('a'), literal(1)), |
| 212 mapLiteralEntry(literal('b'), | 220 mapLiteralEntry(literal('b'), |
| 213 binary(literal(2), '+', literal(3)))])); | 221 binary(literal(2), '+', literal(3)))])); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 | 235 |
| 228 test('should parse list literals', () { | 236 test('should parse list literals', () { |
| 229 expectParse('[1, "a", b]', | 237 expectParse('[1, "a", b]', |
| 230 listLiteral([literal(1), literal('a'), ident('b')])); | 238 listLiteral([literal(1), literal('a'), ident('b')])); |
| 231 expectParse('[[1, 2], [3, 4]]', | 239 expectParse('[[1, 2], [3, 4]]', |
| 232 listLiteral([listLiteral([literal(1), literal(2)]), | 240 listLiteral([listLiteral([literal(1), literal(2)]), |
| 233 listLiteral([literal(3), literal(4)])])); | 241 listLiteral([literal(3), literal(4)])])); |
| 234 }); | 242 }); |
| 235 }); | 243 }); |
| 236 } | 244 } |
| OLD | NEW |