OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'package:unittest/unittest.dart'; | |
6 | |
7 import 'package:analyzer_experimental/src/generated/java_core.dart' show CharSeq
uence; | |
8 import 'package:analyzer_experimental/src/generated/scanner.dart'; | |
9 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; | |
10 import 'package:analyzer_experimental/src/services/writer.dart'; | |
11 | |
12 main() { | |
13 | |
14 /// Formatter tests | |
15 group('formatter', () { | |
16 | |
17 test('failed parse', () { | |
18 var formatter = new CodeFormatter(); | |
19 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'), | |
20 throwsA(new isInstanceOf<FormatterException>())); | |
21 }); | |
22 | |
23 test('CU (1)', () { | |
24 expectCUFormatsTo( | |
25 'class A {\n' | |
26 ' var z;\n' | |
27 ' inc(int x) => ++x;\n' | |
28 '}\n', | |
29 'class A {\n' | |
30 ' var z;\n' | |
31 ' inc(int x) => ++x;\n' | |
32 '}\n' | |
33 ); | |
34 }); | |
35 | |
36 test('CU (2)', () { | |
37 expectCUFormatsTo( | |
38 'class A { \n' | |
39 '}\n', | |
40 'class A {\n' | |
41 '}\n' | |
42 ); | |
43 }); | |
44 | |
45 test('CU (3)', () { | |
46 expectCUFormatsTo( | |
47 'class A {\n' | |
48 ' }', | |
49 'class A {\n' | |
50 '}\n' | |
51 ); | |
52 }); | |
53 | |
54 test('CU (4)', () { | |
55 expectCUFormatsTo( | |
56 ' class A {\n' | |
57 '}\n', | |
58 'class A {\n' | |
59 '}\n' | |
60 ); | |
61 }); | |
62 | |
63 test('CU (5)', () { | |
64 expectCUFormatsTo( | |
65 'class A { int meaningOfLife() => 42; }', | |
66 'class A {\n' | |
67 ' int meaningOfLife() => 42;\n' | |
68 '}\n' | |
69 ); | |
70 }); | |
71 | |
72 test('CU - EOL comments', () { | |
73 expectCUFormatsTo( | |
74 '//comment one\n\n' | |
75 '//comment two\n\n', | |
76 '//comment one\n\n' | |
77 '//comment two\n\n' | |
78 ); | |
79 expectCUFormatsTo( | |
80 'var x; //x\n', | |
81 'var x; //x\n' | |
82 ); | |
83 expectCUFormatsTo( | |
84 'library foo;\n' | |
85 '\n' | |
86 '//comment one\n' | |
87 '\n' | |
88 'class C {\n' | |
89 '}\n', | |
90 'library foo;\n' | |
91 '\n' | |
92 '//comment one\n' | |
93 '\n' | |
94 'class C {\n' | |
95 '}\n' | |
96 ); | |
97 expectCUFormatsTo( | |
98 'library foo;\n' | |
99 '\n' | |
100 '//comment one\n' | |
101 '\n' | |
102 '//comment two\n' | |
103 '\n' | |
104 'class C {\n' | |
105 '}\n', | |
106 'library foo;\n' | |
107 '\n' | |
108 '//comment one\n' | |
109 '\n' | |
110 '//comment two\n' | |
111 '\n' | |
112 'class C {\n' | |
113 '}\n' | |
114 ); | |
115 }); | |
116 | |
117 test('CU - nested functions', () { | |
118 expectCUFormatsTo( | |
119 'x() {\n' | |
120 ' y() {\n' | |
121 ' }\n' | |
122 '}\n', | |
123 'x() {\n' | |
124 ' y() {\n' | |
125 ' }\n' | |
126 '}\n' | |
127 ); | |
128 }); | |
129 | |
130 test('CU - top level', () { | |
131 expectCUFormatsTo( | |
132 '\n\n' | |
133 'foo() {\n' | |
134 '}\n' | |
135 'bar() {\n' | |
136 '}\n', | |
137 '\n\n' | |
138 'foo() {\n' | |
139 '}\n' | |
140 'bar() {\n' | |
141 '}\n' | |
142 ); | |
143 expectCUFormatsTo( | |
144 'const A = 42;\n' | |
145 'final foo = 32;\n', | |
146 'const A = 42;\n' | |
147 'final foo = 32;\n' | |
148 ); | |
149 }); | |
150 | |
151 test('CU - imports', () { | |
152 expectCUFormatsTo( | |
153 'import "dart:io";\n\n' | |
154 'import "package:unittest/unittest.dart";\n' | |
155 'foo() {\n' | |
156 '}\n', | |
157 'import "dart:io";\n\n' | |
158 'import "package:unittest/unittest.dart";\n' | |
159 'foo() {\n' | |
160 '}\n' | |
161 ); | |
162 expectCUFormatsTo( | |
163 'library a; class B { }', | |
164 'library a;\n' | |
165 'class B {\n' | |
166 '}\n' | |
167 ); | |
168 }); | |
169 | |
170 test('CU - method invocations', () { | |
171 expectCUFormatsTo( | |
172 'class A {\n' | |
173 ' foo() {\n' | |
174 ' bar();\n' | |
175 ' for (int i = 0; i < 42; i++) {\n' | |
176 ' baz();\n' | |
177 ' }\n' | |
178 ' }\n' | |
179 '}\n', | |
180 'class A {\n' | |
181 ' foo() {\n' | |
182 ' bar();\n' | |
183 ' for (int i = 0; i < 42; i++) {\n' | |
184 ' baz();\n' | |
185 ' }\n' | |
186 ' }\n' | |
187 '}\n' | |
188 ); | |
189 }); | |
190 | |
191 test('CU w/class decl comment', () { | |
192 expectCUFormatsTo( | |
193 'import "foo";\n\n' | |
194 '//Killer class\n' | |
195 'class A {\n' | |
196 '}', | |
197 'import "foo";\n\n' | |
198 '//Killer class\n' | |
199 'class A {\n' | |
200 '}\n' | |
201 ); | |
202 }); | |
203 | |
204 test('CU (method body)', () { | |
205 expectCUFormatsTo( | |
206 'class A {\n' | |
207 ' foo(path) {\n' | |
208 ' var buffer = new StringBuffer();\n' | |
209 ' var file = new File(path);\n' | |
210 ' return file;\n' | |
211 ' }\n' | |
212 '}\n', | |
213 'class A {\n' | |
214 ' foo(path) {\n' | |
215 ' var buffer = new StringBuffer();\n' | |
216 ' var file = new File(path);\n' | |
217 ' return file;\n' | |
218 ' }\n' | |
219 '}\n' | |
220 ); | |
221 expectCUFormatsTo( | |
222 'class A {\n' | |
223 ' foo(files) {\n' | |
224 ' for (var file in files) {\n' | |
225 ' print(file);\n' | |
226 ' }\n' | |
227 ' }\n' | |
228 '}\n', | |
229 'class A {\n' | |
230 ' foo(files) {\n' | |
231 ' for (var file in files) {\n' | |
232 ' print(file);\n' | |
233 ' }\n' | |
234 ' }\n' | |
235 '}\n' | |
236 ); | |
237 }); | |
238 | |
239 test('CU (method indent)', () { | |
240 expectCUFormatsTo( | |
241 'class A {\n' | |
242 'void x(){\n' | |
243 '}\n' | |
244 '}\n', | |
245 'class A {\n' | |
246 ' void x() {\n' | |
247 ' }\n' | |
248 '}\n' | |
249 ); | |
250 }); | |
251 | |
252 test('CU (method indent - 2)', () { | |
253 expectCUFormatsTo( | |
254 'class A {\n' | |
255 ' static bool x(){\n' | |
256 'return true; }\n' | |
257 ' }\n', | |
258 'class A {\n' | |
259 ' static bool x() {\n' | |
260 ' return true;\n' | |
261 ' }\n' | |
262 '}\n' | |
263 ); | |
264 }); | |
265 | |
266 test('CU (method indent - 3)', () { | |
267 expectCUFormatsTo( | |
268 'class A {\n' | |
269 ' int x() => 42 + 3 ; \n' | |
270 ' }\n', | |
271 'class A {\n' | |
272 ' int x() => 42 + 3;\n' | |
273 '}\n' | |
274 ); | |
275 }); | |
276 | |
277 test('CU (method indent - 4)', () { | |
278 expectCUFormatsTo( | |
279 'class A {\n' | |
280 ' int x() { \n' | |
281 'if (true) {\n' | |
282 'return 42;\n' | |
283 '} else {\n' | |
284 'return 13;\n }\n' | |
285 ' }' | |
286 '}\n', | |
287 'class A {\n' | |
288 ' int x() {\n' | |
289 ' if (true) {\n' | |
290 ' return 42;\n' | |
291 ' } else {\n' | |
292 ' return 13;\n' | |
293 ' }\n' | |
294 ' }\n' | |
295 '}\n' | |
296 ); | |
297 }); | |
298 | |
299 test('CU (multiple members)', () { | |
300 expectCUFormatsTo( | |
301 'class A {\n' | |
302 '}\n' | |
303 'class B {\n' | |
304 '}\n', | |
305 'class A {\n' | |
306 '}\n' | |
307 'class B {\n' | |
308 '}\n' | |
309 ); | |
310 }); | |
311 | |
312 test('CU (multiple members w/blanks)', () { | |
313 expectCUFormatsTo( | |
314 'class A {\n' | |
315 '}\n\n' | |
316 'class B {\n\n\n' | |
317 ' int b() => 42;\n\n' | |
318 ' int c() => b();\n\n' | |
319 '}\n', | |
320 'class A {\n' | |
321 '}\n\n' | |
322 'class B {\n\n\n' | |
323 ' int b() => 42;\n\n' | |
324 ' int c() => b();\n\n' | |
325 '}\n' | |
326 ); | |
327 }); | |
328 | |
329 test('CU - Block comments', () { | |
330 expectCUFormatsTo( | |
331 '/** Old school class comment */\n' | |
332 'class C {\n' | |
333 ' /** Foo! */ int foo() => 42;\n' | |
334 '}\n', | |
335 '/** Old school class comment */\n' | |
336 'class C {\n' | |
337 ' /** Foo! */\n' | |
338 ' int foo() => 42;\n' | |
339 '}\n' | |
340 ); | |
341 expectCUFormatsTo( | |
342 'library foo;\n' | |
343 'class C /* is cool */ {\n' | |
344 ' /* int */ foo() => 42;\n' | |
345 '}\n', | |
346 'library foo;\n' | |
347 'class C /* is cool */ {\n' | |
348 ' /* int */ foo() => 42;\n' | |
349 '}\n' | |
350 ); | |
351 expectCUFormatsTo( | |
352 'library foo;\n' | |
353 '/* A long\n' | |
354 ' * Comment\n' | |
355 '*/\n' | |
356 'class C /* is cool */ {\n' | |
357 ' /* int */ foo() => 42;\n' | |
358 '}\n', | |
359 'library foo;\n' | |
360 '/* A long\n' | |
361 ' * Comment\n' | |
362 '*/\n' | |
363 'class C /* is cool */ {\n' | |
364 ' /* int */ foo() => 42;\n' | |
365 '}\n' | |
366 ); | |
367 expectCUFormatsTo( | |
368 'library foo;\n' | |
369 '/* A long\n' | |
370 ' * Comment\n' | |
371 '*/\n' | |
372 '\n' | |
373 '/* And\n' | |
374 ' * another...\n' | |
375 '*/\n' | |
376 '\n' | |
377 '// Mixing it up\n' | |
378 '\n' | |
379 'class C /* is cool */ {\n' | |
380 ' /* int */ foo() => 42;\n' | |
381 '}\n', | |
382 'library foo;\n' | |
383 '/* A long\n' | |
384 ' * Comment\n' | |
385 '*/\n' | |
386 '\n' | |
387 '/* And\n' | |
388 ' * another...\n' | |
389 '*/\n' | |
390 '\n' | |
391 '// Mixing it up\n' | |
392 '\n' | |
393 'class C /* is cool */ {\n' | |
394 ' /* int */ foo() => 42;\n' | |
395 '}\n' | |
396 ); | |
397 expectCUFormatsTo( | |
398 '/// Copyright info\n' | |
399 '\n' | |
400 'library foo;\n' | |
401 '/// Class comment\n' | |
402 '//TODO: implement\n' | |
403 'class C {\n' | |
404 '}\n', | |
405 '/// Copyright info\n' | |
406 '\n' | |
407 'library foo;\n' | |
408 '/// Class comment\n' | |
409 '//TODO: implement\n' | |
410 'class C {\n' | |
411 '}\n' | |
412 ); | |
413 }); | |
414 | |
415 test('CU - mixed comments', () { | |
416 expectCUFormatsTo( | |
417 'library foo;\n' | |
418 '\n' | |
419 '\n' | |
420 '/* Comment 1 */\n' | |
421 '\n' | |
422 '// Comment 2\n' | |
423 '\n' | |
424 '/* Comment 3 */', | |
425 'library foo;\n' | |
426 '\n' | |
427 '\n' | |
428 '/* Comment 1 */\n' | |
429 '\n' | |
430 '// Comment 2\n' | |
431 '\n' | |
432 '/* Comment 3 */\n' | |
433 ); | |
434 }); | |
435 | |
436 test('CU - comments (EOF)', () { | |
437 expectCUFormatsTo( | |
438 'library foo; //zamm', | |
439 'library foo; //zamm\n' //<-- note extra NEWLINE | |
440 ); | |
441 }); | |
442 | |
443 test('CU - comments (0)', () { | |
444 expectCUFormatsTo( | |
445 'library foo; //zamm\n' | |
446 '\n' | |
447 'class A {\n' | |
448 '}\n', | |
449 'library foo; //zamm\n' | |
450 '\n' | |
451 'class A {\n' | |
452 '}\n' | |
453 ); | |
454 }); | |
455 | |
456 test('CU - comments (1)', () { | |
457 expectCUFormatsTo( | |
458 '/* foo */ /* bar */\n', | |
459 '/* foo */ /* bar */\n' | |
460 ); | |
461 }); | |
462 | |
463 test('CU - comments (2)', () { | |
464 expectCUFormatsTo( | |
465 '/** foo */ /** bar */\n', | |
466 '/** foo */\n' | |
467 '/** bar */\n' | |
468 ); | |
469 }); | |
470 | |
471 test('CU - comments (3)', () { | |
472 expectCUFormatsTo( | |
473 'var x; //x\n', | |
474 'var x; //x\n' | |
475 ); | |
476 }); | |
477 | |
478 test('CU - comments (4)', () { | |
479 expectCUFormatsTo( | |
480 'class X { //X!\n' | |
481 '}', | |
482 'class X { //X!\n' | |
483 '}\n' | |
484 ); | |
485 }); | |
486 | |
487 test('CU - comments (5)', () { | |
488 expectCUFormatsTo( | |
489 '//comment one\n\n' | |
490 '//comment two\n\n', | |
491 '//comment one\n\n' | |
492 '//comment two\n\n' | |
493 ); | |
494 }); | |
495 | |
496 test('CU - comments (6)', () { | |
497 expectCUFormatsTo( | |
498 'var x; //x\n', | |
499 'var x; //x\n' | |
500 ); | |
501 }); | |
502 | |
503 test('CU - comments (6)', () { | |
504 expectCUFormatsTo( | |
505 'var /* int */ x; //x\n', | |
506 'var /* int */ x; //x\n' | |
507 ); | |
508 }); | |
509 | |
510 test('CU - comments (7)', () { | |
511 expectCUFormatsTo( | |
512 'library foo;\n' | |
513 '\n' | |
514 '/// Docs\n' | |
515 '/// spanning\n' | |
516 '/// lines.\n' | |
517 'class A {\n' | |
518 '}\n' | |
519 '\n' | |
520 '/// ... and\n' | |
521 '\n' | |
522 '/// Dangling ones too\n' | |
523 'int x;\n', | |
524 'library foo;\n' | |
525 '\n' | |
526 '/// Docs\n' | |
527 '/// spanning\n' | |
528 '/// lines.\n' | |
529 'class A {\n' | |
530 '}\n' | |
531 '\n' | |
532 '/// ... and\n' | |
533 '\n' | |
534 '/// Dangling ones too\n' | |
535 'int x;\n' | |
536 ); | |
537 }); | |
538 | |
539 test('CU - EOF nl', () { | |
540 expectCUFormatsTo( | |
541 'var x = 1;', | |
542 'var x = 1;\n' | |
543 ); | |
544 }); | |
545 | |
546 test('CU - constructor', () { | |
547 expectCUFormatsTo( | |
548 'class A {\n' | |
549 ' const _a;\n' | |
550 ' A();\n' | |
551 ' int a() => _a;\n' | |
552 '}\n', | |
553 'class A {\n' | |
554 ' const _a;\n' | |
555 ' A();\n' | |
556 ' int a() => _a;\n' | |
557 '}\n' | |
558 ); | |
559 }); | |
560 | |
561 test('CU - method decl w/ named params', () { | |
562 expectCUFormatsTo( | |
563 'class A {\n' | |
564 ' int a(var x, {optional: null}) => null;\n' | |
565 '}\n', | |
566 'class A {\n' | |
567 ' int a(var x, {optional: null}) => null;\n' | |
568 '}\n' | |
569 ); | |
570 }); | |
571 | |
572 test('CU - method decl w/ optional params', () { | |
573 expectCUFormatsTo( | |
574 'class A {\n' | |
575 ' int a(var x, [optional = null]) => null;\n' | |
576 '}\n', | |
577 'class A {\n' | |
578 ' int a(var x, [optional = null]) => null;\n' | |
579 '}\n' | |
580 ); | |
581 }); | |
582 | |
583 test('CU - factory constructor redirects', () { | |
584 expectCUFormatsTo( | |
585 'class A {\n' | |
586 ' const factory A() = B;\n' | |
587 '}\n', | |
588 'class A {\n' | |
589 ' const factory A() = B;\n' | |
590 '}\n' | |
591 ); | |
592 }); | |
593 | |
594 test('CU - constructor initializers', () { | |
595 expectCUFormatsTo( | |
596 'class A {\n' | |
597 ' int _a;\n' | |
598 ' A(a) : _a = a;\n' | |
599 '}\n', | |
600 'class A {\n' | |
601 ' int _a;\n' | |
602 ' A(a)\n' | |
603 ' : _a = a;\n' | |
604 '}\n' | |
605 ); | |
606 }); | |
607 | |
608 test('CU - constructor auto field inits', () { | |
609 expectCUFormatsTo( | |
610 'class A {\n' | |
611 ' int _a;\n' | |
612 ' A(this._a);\n' | |
613 '}\n', | |
614 'class A {\n' | |
615 ' int _a;\n' | |
616 ' A(this._a);\n' | |
617 '}\n' | |
618 ); | |
619 }); | |
620 | |
621 test('CU - parts', () { | |
622 expectCUFormatsTo( | |
623 'part of foo;', | |
624 'part of foo;\n' | |
625 ); | |
626 }); | |
627 | |
628 test('CU (cons inits)', () { | |
629 expectCUFormatsTo('class X {\n' | |
630 ' var x, y;\n' | |
631 ' X() : x = 1, y = 2;\n' | |
632 '}\n', | |
633 'class X {\n' | |
634 ' var x, y;\n' | |
635 ' X()\n' | |
636 ' : x = 1,\n' | |
637 ' y = 2;\n' | |
638 '}\n' | |
639 ); | |
640 }); | |
641 | |
642 test('CU (empty cons bodies)', () { | |
643 expectCUFormatsTo( | |
644 'class A {\n' | |
645 ' A() {\n' | |
646 ' }\n' | |
647 '}\n', | |
648 'class A {\n' | |
649 ' A();\n' | |
650 '}\n', | |
651 transforms: true | |
652 ); | |
653 expectCUFormatsTo( | |
654 'class A {\n' | |
655 ' A() {\n' | |
656 ' }\n' | |
657 '}\n', | |
658 'class A {\n' | |
659 ' A() {\n' | |
660 ' }\n' | |
661 '}\n', | |
662 transforms: false | |
663 ); | |
664 }); | |
665 | |
666 test('stmt', () { | |
667 expectStmtFormatsTo( | |
668 'if (true){\n' | |
669 'if (true){\n' | |
670 'if (true){\n' | |
671 'return true;\n' | |
672 '} else{\n' | |
673 'return false;\n' | |
674 '}\n' | |
675 '}\n' | |
676 '}else{\n' | |
677 'return false;\n' | |
678 '}', | |
679 'if (true) {\n' | |
680 ' if (true) {\n' | |
681 ' if (true) {\n' | |
682 ' return true;\n' | |
683 ' } else {\n' | |
684 ' return false;\n' | |
685 ' }\n' | |
686 ' }\n' | |
687 '} else {\n' | |
688 ' return false;\n' | |
689 '}' | |
690 ); | |
691 }); | |
692 | |
693 test('stmt (switch)', () { | |
694 expectStmtFormatsTo( | |
695 'switch (fruit) {\n' | |
696 'case "apple":\n' | |
697 'print("delish");\n' | |
698 'break;\n' | |
699 'case "fig":\n' | |
700 'print("bleh");\n' | |
701 'break;\n' | |
702 '}', | |
703 'switch (fruit) {\n' | |
704 ' case "apple":\n' | |
705 ' print("delish");\n' | |
706 ' break;\n' | |
707 ' case "fig":\n' | |
708 ' print("bleh");\n' | |
709 ' break;\n' | |
710 '}' | |
711 ); | |
712 }); | |
713 | |
714 test('stmt (cascades)', () { | |
715 expectStmtFormatsTo( | |
716 '"foo"\n' | |
717 '..toString()\n' | |
718 '..toString();', | |
719 '"foo"\n' | |
720 ' ..toString()\n' | |
721 ' ..toString();' | |
722 ); | |
723 }); | |
724 | |
725 test('stmt (generics)', () { | |
726 expectStmtFormatsTo( | |
727 'var numbers = <int>[1, 2, (3 + 4)];', | |
728 'var numbers = <int>[1, 2, (3 + 4)];' | |
729 ); | |
730 }); | |
731 | |
732 test('stmt (lists)', () { | |
733 expectStmtFormatsTo( | |
734 'var l = [1,2,3,4];', | |
735 'var l = [1, 2, 3, 4];' | |
736 ); | |
737 //Dangling ',' | |
738 expectStmtFormatsTo( | |
739 'var l = [1,];', | |
740 'var l = [1,];' | |
741 ); | |
742 }); | |
743 | |
744 test('stmt (maps)', () { | |
745 expectStmtFormatsTo( | |
746 'var map = const {"foo": "bar", "fuz": null};', | |
747 'var map = const {"foo": "bar", "fuz": null};' | |
748 ); | |
749 | |
750 //Dangling ',' | |
751 expectStmtFormatsTo( | |
752 'var map = {"foo": "bar",};', | |
753 'var map = {"foo": "bar",};' | |
754 ); | |
755 }); | |
756 | |
757 test('stmt (try/catch)', () { | |
758 expectStmtFormatsTo( | |
759 'try {\n' | |
760 'doSomething();\n' | |
761 '} catch (e) {\n' | |
762 'print(e);\n' | |
763 '}', | |
764 'try {\n' | |
765 ' doSomething();\n' | |
766 '} catch (e) {\n' | |
767 ' print(e);\n' | |
768 '}' | |
769 ); | |
770 }); | |
771 | |
772 test('stmt (binary/ternary ops)', () { | |
773 expectStmtFormatsTo( | |
774 'var a = 1 + 2 / (3 * -b);', | |
775 'var a = 1 + 2 / (3 * -b);' | |
776 ); | |
777 expectStmtFormatsTo( | |
778 'var c = !condition == a > b;', | |
779 'var c = !condition == a > b;' | |
780 ); | |
781 expectStmtFormatsTo( | |
782 'var d = condition ? b : object.method(a, b, c);', | |
783 'var d = condition ? b : object.method(a, b, c);' | |
784 ); | |
785 expectStmtFormatsTo( | |
786 'var d = obj is! SomeType;', | |
787 'var d = obj is! SomeType;' | |
788 ); | |
789 }); | |
790 | |
791 test('stmt (for in)', () { | |
792 expectStmtFormatsTo( | |
793 'for (Foo foo in bar.foos) {\n' | |
794 ' print(foo);\n' | |
795 '}', | |
796 'for (Foo foo in bar.foos) {\n' | |
797 ' print(foo);\n' | |
798 '}' | |
799 ); | |
800 expectStmtFormatsTo( | |
801 'for (final Foo foo in bar.foos) {\n' | |
802 ' print(foo);\n' | |
803 '}', | |
804 'for (final Foo foo in bar.foos) {\n' | |
805 ' print(foo);\n' | |
806 '}' | |
807 ); | |
808 expectStmtFormatsTo( | |
809 'for (final foo in bar.foos) {\n' | |
810 ' print(foo);\n' | |
811 '}', | |
812 'for (final foo in bar.foos) {\n' | |
813 ' print(foo);\n' | |
814 '}' | |
815 ); | |
816 }); | |
817 | |
818 test('Statement (if)', () { | |
819 expectStmtFormatsTo('if (true) print("true!");', | |
820 'if (true) print("true!");'); | |
821 expectStmtFormatsTo('if (true) { print("true!"); }', | |
822 'if (true) {\n' | |
823 ' print("true!");\n' | |
824 '}'); | |
825 expectStmtFormatsTo('if (true) print("true!"); else print("false!");', | |
826 'if (true) {\n' | |
827 ' print("true!");\n' | |
828 '} else {\n' | |
829 ' print("false!");\n' | |
830 '}'); | |
831 expectStmtFormatsTo('if (true) print("true!"); else print("false!");', | |
832 'if (true) print("true!"); else print("false!");', | |
833 transforms: false); | |
834 }); | |
835 | |
836 test('initialIndent', () { | |
837 var formatter = new CodeFormatter( | |
838 new FormatterOptions(initialIndentationLevel: 2)); | |
839 var formattedSource = | |
840 formatter.format(CodeKind.STATEMENT, 'var x;').source; | |
841 expect(formattedSource, startsWith(' ')); | |
842 }); | |
843 | |
844 test('selections', () { | |
845 expectSelectedPostFormat('class X {}', '}'); | |
846 expectSelectedPostFormat('class X{}', '{'); | |
847 expectSelectedPostFormat('class X{int y;}', ';'); | |
848 expectSelectedPostFormat('class X{int y;}', '}'); | |
849 expectSelectedPostFormat('class X {}', ' {'); | |
850 }); | |
851 | |
852 }); | |
853 | |
854 | |
855 /// Token streams | |
856 group('token streams', () { | |
857 | |
858 test('string tokens', () { | |
859 expectTokenizedEqual('class A{}', 'class A{ }'); | |
860 expectTokenizedEqual('class A{}', 'class A{\n }\n'); | |
861 expectTokenizedEqual('class A {}', 'class A{ }'); | |
862 expectTokenizedEqual(' class A {}', 'class A{ }'); | |
863 }); | |
864 | |
865 test('string tokens - w/ comments', () { | |
866 expectTokenizedEqual('//foo\nint bar;', '//foo\nint bar;'); | |
867 expectTokenizedNotEqual('int bar;', '//foo\nint bar;'); | |
868 expectTokenizedNotEqual('//foo\nint bar;', 'int bar;'); | |
869 }); | |
870 | |
871 test('INDEX', () { | |
872 /// '[' ']' => '[]' | |
873 var t1 = openSqBracket()..setNext(closeSqBracket()..setNext(eof())); | |
874 var t2 = index()..setNext(eof()); | |
875 expectStreamsEqual(t1, t2); | |
876 }); | |
877 | |
878 test('GT_GT', () { | |
879 /// '>' '>' => '>>' | |
880 var t1 = gt()..setNext(gt()..setNext(eof())); | |
881 var t2 = gt_gt()..setNext(eof()); | |
882 expectStreamsEqual(t1, t2); | |
883 }); | |
884 | |
885 test('t1 < t2', () { | |
886 var t1 = string('foo')..setNext(eof()); | |
887 var t2 = string('foo')..setNext(string('bar')..setNext(eof())); | |
888 expectStreamsNotEqual(t1, t2); | |
889 }); | |
890 | |
891 test('t1 > t2', () { | |
892 var t1 = string('foo')..setNext(string('bar')..setNext(eof())); | |
893 var t2 = string('foo')..setNext(eof()); | |
894 expectStreamsNotEqual(t1, t2); | |
895 }); | |
896 | |
897 }); | |
898 | |
899 | |
900 /// Line tests | |
901 group('line', () { | |
902 | |
903 test('space', () { | |
904 var line = new Line(indent: 0); | |
905 line.addSpaces(2); | |
906 expect(line.toString(), equals(' ')); | |
907 }); | |
908 | |
909 test('initial indent', () { | |
910 var line = new Line(indent: 2); | |
911 expect(line.toString(), equals(' ')); | |
912 }); | |
913 | |
914 test('initial indent (tabbed)', () { | |
915 var line = new Line(indent:1, useTabs: true); | |
916 expect(line.toString(), equals('\t')); | |
917 }); | |
918 | |
919 test('addToken', () { | |
920 var line = new Line(); | |
921 line.addToken(new LineToken('foo')); | |
922 expect(line.toString(), equals('foo')); | |
923 }); | |
924 | |
925 test('addToken (2)', () { | |
926 var line = new Line(indent: 1); | |
927 line.addToken(new LineToken('foo')); | |
928 expect(line.toString(), equals(' foo')); | |
929 }); | |
930 | |
931 test('isWhitespace', () { | |
932 var line = new Line(indent: 1); | |
933 expect(line.isWhitespace(), isTrue); | |
934 }); | |
935 | |
936 }); | |
937 | |
938 | |
939 /// Writer tests | |
940 group('writer', () { | |
941 | |
942 test('basic print', () { | |
943 var writer = new SourceWriter(); | |
944 writer.print('foo'); | |
945 writer.print(' '); | |
946 writer.print('bar'); | |
947 expect(writer.toString(), equals('foo bar')); | |
948 }); | |
949 | |
950 test('newline', () { | |
951 var writer = new SourceWriter(); | |
952 writer.print('foo'); | |
953 writer.newline(); | |
954 expect(writer.toString(), equals('foo\n')); | |
955 }); | |
956 | |
957 test('newline trims whitespace', () { | |
958 var writer = new SourceWriter(indentCount:2); | |
959 writer.newline(); | |
960 expect(writer.toString(), equals('\n')); | |
961 }); | |
962 | |
963 test('basic print (with indents)', () { | |
964 var writer = new SourceWriter(); | |
965 writer.print('foo'); | |
966 writer.indent(); | |
967 writer.newline(); | |
968 writer.print('bar'); | |
969 writer.unindent(); | |
970 writer.newline(); | |
971 writer.print('baz'); | |
972 expect(writer.toString(), equals('foo\n bar\nbaz')); | |
973 }); | |
974 | |
975 }); | |
976 | |
977 | |
978 /// Helper method tests | |
979 group('helpers', () { | |
980 | |
981 test('indentString', () { | |
982 expect(getIndentString(0), ''); | |
983 expect(getIndentString(1), ' '); | |
984 expect(getIndentString(4), ' '); | |
985 }); | |
986 | |
987 test('indentString (tabbed)', () { | |
988 expect(getIndentString(0, useTabs: true), ''); | |
989 expect(getIndentString(1, useTabs: true), '\t'); | |
990 expect(getIndentString(3, useTabs: true), '\t\t\t'); | |
991 }); | |
992 | |
993 test('repeat', () { | |
994 expect(repeat('x', 0), ''); | |
995 expect(repeat('x', 1), 'x'); | |
996 expect(repeat('x', 4), 'xxxx'); | |
997 }); | |
998 | |
999 }); | |
1000 | |
1001 } | |
1002 | |
1003 Token closeSqBracket() => new Token(TokenType.CLOSE_SQUARE_BRACKET, 0); | |
1004 | |
1005 Token eof() => new Token(TokenType.EOF, 0); | |
1006 | |
1007 Token gt() => new Token(TokenType.GT, 0); | |
1008 | |
1009 Token gt_gt() => new Token(TokenType.GT_GT, 0); | |
1010 | |
1011 Token index() => new Token(TokenType.INDEX, 0); | |
1012 | |
1013 Token openSqBracket() => new BeginToken(TokenType.OPEN_SQUARE_BRACKET, 0); | |
1014 | |
1015 Token string(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0); | |
1016 | |
1017 Token classKeyword(int offset) => new KeywordToken(Keyword.CLASS, offset); | |
1018 | |
1019 Token identifier(String value, int offset) => | |
1020 new StringToken(TokenType.IDENTIFIER, value, offset); | |
1021 | |
1022 Token openParen(int offset) => | |
1023 new StringToken(TokenType.OPEN_PAREN, '{', offset); | |
1024 | |
1025 Token closeParen(int offset) => | |
1026 new StringToken(TokenType.CLOSE_PAREN, '}', offset); | |
1027 | |
1028 Token chain(List<Token> tokens) { | |
1029 for (var i = 0; i < tokens.length - 1; ++i) { | |
1030 tokens[i].setNext(tokens[i + 1]); | |
1031 } | |
1032 return tokens[0]; | |
1033 } | |
1034 | |
1035 FormattedSource formatCU(src, {options: const FormatterOptions(), selection}) => | |
1036 new CodeFormatter(options).format( | |
1037 CodeKind.COMPILATION_UNIT, src, selection: selection); | |
1038 | |
1039 String formatStatement(src, {options: const FormatterOptions()}) => | |
1040 new CodeFormatter(options).format(CodeKind.STATEMENT, src).source; | |
1041 | |
1042 Token tokenize(String str) { | |
1043 var reader = new CharSequenceReader(new CharSequence(str)); | |
1044 return new Scanner(null, reader, null).tokenize(); | |
1045 } | |
1046 | |
1047 expectSelectedPostFormat(src, token) { | |
1048 var preOffset = src.indexOf(token); | |
1049 var length = token.length; | |
1050 var formatted = formatCU(src, selection: new Selection(preOffset, length)); | |
1051 var postOffset = formatted.selection.offset; | |
1052 expect(formatted.source.substring(postOffset, postOffset + length), | |
1053 equals(src.substring(preOffset, preOffset + length))); | |
1054 } | |
1055 | |
1056 expectTokenizedEqual(String s1, String s2) => | |
1057 expectStreamsEqual(tokenize(s1), tokenize(s2)); | |
1058 | |
1059 expectTokenizedNotEqual(String s1, String s2) => | |
1060 expect(()=> expectStreamsEqual(tokenize(s1), tokenize(s2)), | |
1061 throwsA(new isInstanceOf<FormatterException>())); | |
1062 | |
1063 expectStreamsEqual(Token t1, Token t2) => | |
1064 new TokenStreamComparator(null, t1, t2).verifyEquals(); | |
1065 | |
1066 expectStreamsNotEqual(Token t1, Token t2) => | |
1067 expect(() => new TokenStreamComparator(null, t1, t2).verifyEquals(), | |
1068 throwsA(new isInstanceOf<FormatterException>())); | |
1069 | |
1070 expectCUFormatsTo(src, expected, {transforms: true}) => | |
1071 expect(formatCU(src, options: new FormatterOptions( | |
1072 codeTransforms: transforms)).source, equals(expected)); | |
1073 | |
1074 expectStmtFormatsTo(src, expected, {transforms: true}) => | |
1075 expect(formatStatement(src, options: | |
1076 new FormatterOptions(codeTransforms: transforms)), equals(expected)); | |
OLD | NEW |