Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: pkg/analyzer/test/services/formatter_test.dart

Issue 1001403002: Remove the old formatter from analyzer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 library formatter_test;
6
7 import 'dart:io';
8
9 import 'package:path/path.dart';
10 import 'package:unittest/unittest.dart';
11
12 import 'package:analyzer/src/generated/scanner.dart';
13 import 'package:analyzer/src/services/formatter_impl.dart';
14 import 'package:analyzer/src/services/writer.dart';
15
16 // Test data location ('pkg/analyzer/test/services/data')
17 final TEST_DATA_DIR = join(dirname(fromUri(Platform.script)), 'data');
18
19 main() {
20
21 /// Data-driven statement tests
22 group('stmt_tests.data', () {
23 // NOTE: statement tests are run with transforms enabled
24 runTests('stmt_tests.data', (input, expectedOutput) {
25 expect(formatStatement(input,
26 options: new FormatterOptions(codeTransforms: true)) +
27 '\n', equals(expectedOutput));
28 });
29 });
30
31 /// Data-driven compilation unit tests
32 group('cu_tests.data', () {
33 runTests('cu_tests.data', (input, expectedOutput) {
34 expectCUFormatsTo(input, expectedOutput);
35 });
36 });
37
38 /// Data-driven Style Guide acceptance tests
39 group('style_guide_tests.data', () {
40 runTests('style_guide_tests.data', (input, expectedOutput) {
41 expectCUFormatsTo(input, expectedOutput);
42 });
43 });
44
45 /// Data-driven wrapping tests
46 group('wrap_tests.data', () {
47 runTests('wrap_tests.data', (input, expectedOutput) {
48 expectCUFormatsTo(input, expectedOutput);
49 });
50 });
51
52 /// Formatter tests
53 group('formatter', () {
54 test('failed parse', () {
55 var formatter = new CodeFormatter();
56 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'),
57 throwsA(new isInstanceOf<FormatterException>()));
58 });
59
60 test('indent', () {
61 var original = 'class A {\n'
62 ' var z;\n'
63 ' inc(int x) => ++x;\n'
64 ' foo(int x) {\n'
65 ' if (x == 0) {\n'
66 ' return true;\n'
67 ' }\n'
68 ' }\n'
69 '}\n';
70 expectCUFormatsTo(original, original);
71 expectIndentFormatsTo(3, false, original, 'class A {\n'
72 ' var z;\n'
73 ' inc(int x) => ++x;\n'
74 ' foo(int x) {\n'
75 ' if (x == 0) {\n'
76 ' return true;\n'
77 ' }\n'
78 ' }\n'
79 '}\n');
80 expectIndentFormatsTo(1, true, original, 'class A {\n'
81 '\tvar z;\n'
82 '\tinc(int x) => ++x;\n'
83 '\tfoo(int x) {\n'
84 '\t\tif (x == 0) {\n'
85 '\t\t\treturn true;\n'
86 '\t\t}\n'
87 '\t}\n'
88 '}\n');
89 });
90
91 test('CU (1)', () {
92 expectCUFormatsTo('class A {\n'
93 ' var z;\n'
94 ' inc(int x) => ++x;\n'
95 '}\n', 'class A {\n'
96 ' var z;\n'
97 ' inc(int x) => ++x;\n'
98 '}\n');
99 });
100
101 test('CU (2)', () {
102 expectCUFormatsTo('class A { \n'
103 '}\n', 'class A {\n'
104 '}\n');
105 });
106
107 test('CU (3)', () {
108 expectCUFormatsTo('class A {\n'
109 ' }', 'class A {\n'
110 '}\n');
111 });
112
113 test('CU (4)', () {
114 expectCUFormatsTo(' class A {\n'
115 '}\n', 'class A {\n'
116 '}\n');
117 });
118
119 test('CU (5)', () {
120 expectCUFormatsTo('class A { int meaningOfLife() => 42; }', 'class A {\n'
121 ' int meaningOfLife() => 42;\n'
122 '}\n');
123 });
124
125 test('CU - EOL comments', () {
126 expectCUFormatsTo('//comment one\n\n'
127 '//comment two\n\n', '//comment one\n\n'
128 '//comment two\n\n');
129 expectCUFormatsTo('var x; //x\n', 'var x; //x\n');
130 expectCUFormatsTo('library foo;\n'
131 '\n'
132 '//comment one\n'
133 '\n'
134 'class C {\n'
135 '}\n', 'library foo;\n'
136 '\n'
137 '//comment one\n'
138 '\n'
139 'class C {\n'
140 '}\n');
141 expectCUFormatsTo('library foo;\n'
142 '\n'
143 '//comment one\n'
144 '\n'
145 '//comment two\n'
146 '\n'
147 'class C {\n'
148 '}\n', 'library foo;\n'
149 '\n'
150 '//comment one\n'
151 '\n'
152 '//comment two\n'
153 '\n'
154 'class C {\n'
155 '}\n');
156 expectCUFormatsTo('main() {\n'
157 '// print(1);\n'
158 '// print(2);\n'
159 ' print(3);\n'
160 '}\n', 'main() {\n'
161 '// print(1);\n'
162 '// print(2);\n'
163 ' print(3);\n'
164 '}\n');
165 expectCUFormatsTo('class A {\n'
166 '// int a;\n'
167 '// int b;\n'
168 ' int c;\n'
169 '}\n', 'class A {\n'
170 '// int a;\n'
171 '// int b;\n'
172 ' int c;\n'
173 '}\n');
174 });
175
176 test('CU - nested functions', () {
177 expectCUFormatsTo('x() {\n'
178 ' y() {\n'
179 ' }\n'
180 '}\n', 'x() {\n'
181 ' y() {\n'
182 ' }\n'
183 '}\n');
184 });
185
186 test('CU - top level', () {
187 expectCUFormatsTo('\n\n'
188 'foo() {\n'
189 '}\n'
190 'bar() {\n'
191 '}\n', '\n\n'
192 'foo() {\n'
193 '}\n'
194 'bar() {\n'
195 '}\n');
196 expectCUFormatsTo('const A = 42;\n'
197 'final foo = 32;\n', 'const A = 42;\n'
198 'final foo = 32;\n');
199 });
200
201 test('CU - imports', () {
202 expectCUFormatsTo('import "dart:io";\n\n'
203 'import "package:unittest/unittest.dart";\n'
204 'foo() {\n'
205 '}\n', 'import "dart:io";\n\n'
206 'import "package:unittest/unittest.dart";\n'
207 'foo() {\n'
208 '}\n');
209 expectCUFormatsTo('library a; class B { }', 'library a;\n'
210 'class B {}\n');
211 });
212
213 test('CU - method invocations', () {
214 expectCUFormatsTo('class A {\n'
215 ' foo() {\n'
216 ' bar();\n'
217 ' for (int i = 0; i < 42; i++) {\n'
218 ' baz();\n'
219 ' }\n'
220 ' }\n'
221 '}\n', 'class A {\n'
222 ' foo() {\n'
223 ' bar();\n'
224 ' for (int i = 0; i < 42; i++) {\n'
225 ' baz();\n'
226 ' }\n'
227 ' }\n'
228 '}\n');
229 });
230
231 test('CU w/class decl comment', () {
232 expectCUFormatsTo('import "foo";\n\n'
233 '//Killer class\n'
234 'class A {\n'
235 '}', 'import "foo";\n\n'
236 '//Killer class\n'
237 'class A {\n'
238 '}\n');
239 });
240
241 test('CU (method body)', () {
242 expectCUFormatsTo('class A {\n'
243 ' foo(path) {\n'
244 ' var buffer = new StringBuffer();\n'
245 ' var file = new File(path);\n'
246 ' return file;\n'
247 ' }\n'
248 '}\n', 'class A {\n'
249 ' foo(path) {\n'
250 ' var buffer = new StringBuffer();\n'
251 ' var file = new File(path);\n'
252 ' return file;\n'
253 ' }\n'
254 '}\n');
255 expectCUFormatsTo('class A {\n'
256 ' foo(files) {\n'
257 ' for (var file in files) {\n'
258 ' print(file);\n'
259 ' }\n'
260 ' }\n'
261 '}\n', 'class A {\n'
262 ' foo(files) {\n'
263 ' for (var file in files) {\n'
264 ' print(file);\n'
265 ' }\n'
266 ' }\n'
267 '}\n');
268 });
269
270 test('CU (method indent)', () {
271 expectCUFormatsTo('class A {\n'
272 'void x(){\n'
273 '}\n'
274 '}\n', 'class A {\n'
275 ' void x() {\n'
276 ' }\n'
277 '}\n');
278 });
279
280 test('CU (method indent - 2)', () {
281 expectCUFormatsTo('class A {\n'
282 ' static bool x(){\n'
283 'return true; }\n'
284 ' }\n', 'class A {\n'
285 ' static bool x() {\n'
286 ' return true;\n'
287 ' }\n'
288 '}\n');
289 });
290
291 test('CU (method indent - 3)', () {
292 expectCUFormatsTo('class A {\n'
293 ' int x() => 42 + 3 ; \n'
294 ' }\n', 'class A {\n'
295 ' int x() => 42 + 3;\n'
296 '}\n');
297 });
298
299 test('CU (method indent - 4)', () {
300 expectCUFormatsTo('class A {\n'
301 ' int x() { \n'
302 'if (true) {\n'
303 'return 42;\n'
304 '} else {\n'
305 'return 13;\n }\n'
306 ' }'
307 '}\n', 'class A {\n'
308 ' int x() {\n'
309 ' if (true) {\n'
310 ' return 42;\n'
311 ' } else {\n'
312 ' return 13;\n'
313 ' }\n'
314 ' }\n'
315 '}\n');
316 });
317
318 test('CU (multiple members)', () {
319 expectCUFormatsTo('class A {\n'
320 '}\n'
321 'class B {\n'
322 '}\n', 'class A {\n'
323 '}\n'
324 'class B {\n'
325 '}\n');
326 });
327
328 test('CU (multiple members w/blanks)', () {
329 expectCUFormatsTo('class A {\n'
330 '}\n\n'
331 'class B {\n\n\n'
332 ' int b() => 42;\n\n'
333 ' int c() => b();\n\n'
334 '}\n', 'class A {\n'
335 '}\n\n'
336 'class B {\n\n\n'
337 ' int b() => 42;\n\n'
338 ' int c() => b();\n\n'
339 '}\n');
340 });
341
342 test('CU - Block comments', () {
343 expectCUFormatsTo('/** Old school class comment */\n'
344 'class C {\n'
345 ' /** Foo! */ int foo() => 42;\n'
346 '}\n', '/** Old school class comment */\n'
347 'class C {\n'
348 ' /** Foo! */\n'
349 ' int foo() => 42;\n'
350 '}\n');
351 expectCUFormatsTo('library foo;\n'
352 'class C /* is cool */ {\n'
353 ' /* int */ foo() => 42;\n'
354 '}\n', 'library foo;\n'
355 'class C /* is cool */ {\n'
356 ' /* int */ foo() => 42;\n'
357 '}\n');
358 expectCUFormatsTo('library foo;\n'
359 '/* A long\n'
360 ' * Comment\n'
361 '*/\n'
362 'class C /* is cool */ {\n'
363 ' /* int */ foo() => 42;\n'
364 '}\n', 'library foo;\n'
365 '/* A long\n'
366 ' * Comment\n'
367 '*/\n'
368 'class C /* is cool */ {\n'
369 ' /* int */ foo() => 42;\n'
370 '}\n');
371 expectCUFormatsTo('library foo;\n'
372 '/* A long\n'
373 ' * Comment\n'
374 '*/\n'
375 '\n'
376 '/* And\n'
377 ' * another...\n'
378 '*/\n'
379 '\n'
380 '// Mixing it up\n'
381 '\n'
382 'class C /* is cool */ {\n'
383 ' /* int */ foo() => 42;\n'
384 '}\n', 'library foo;\n'
385 '/* A long\n'
386 ' * Comment\n'
387 '*/\n'
388 '\n'
389 '/* And\n'
390 ' * another...\n'
391 '*/\n'
392 '\n'
393 '// Mixing it up\n'
394 '\n'
395 'class C /* is cool */ {\n'
396 ' /* int */ foo() => 42;\n'
397 '}\n');
398 expectCUFormatsTo('/// Copyright info\n'
399 '\n'
400 'library foo;\n'
401 '/// Class comment\n'
402 '//TODO: implement\n'
403 'class C {\n'
404 '}\n', '/// Copyright info\n'
405 '\n'
406 'library foo;\n'
407 '/// Class comment\n'
408 '//TODO: implement\n'
409 'class C {\n'
410 '}\n');
411 });
412
413 test('CU - mixed comments', () {
414 expectCUFormatsTo('library foo;\n'
415 '\n'
416 '\n'
417 '/* Comment 1 */\n'
418 '\n'
419 '// Comment 2\n'
420 '\n'
421 '/* Comment 3 */', 'library foo;\n'
422 '\n'
423 '\n'
424 '/* Comment 1 */\n'
425 '\n'
426 '// Comment 2\n'
427 '\n'
428 '/* Comment 3 */\n');
429 });
430
431 test('CU - comments (EOF)', () {
432 expectCUFormatsTo('library foo; //zamm',
433 'library foo; //zamm\n' //<-- note extra NEWLINE
434 );
435 });
436
437 test('CU - comments (0)', () {
438 expectCUFormatsTo('library foo; //zamm\n'
439 '\n'
440 'class A {\n'
441 '}\n', 'library foo; //zamm\n'
442 '\n'
443 'class A {\n'
444 '}\n');
445 });
446
447 test('CU - comments (1)', () {
448 expectCUFormatsTo('/* foo */ /* bar */\n', '/* foo */ /* bar */\n');
449 });
450
451 test('CU - comments (2)', () {
452 expectCUFormatsTo('/** foo */ /** bar */\n', '/** foo */\n'
453 '/** bar */\n');
454 });
455
456 test('CU - comments (3)', () {
457 expectCUFormatsTo('var x; //x\n', 'var x; //x\n');
458 });
459
460 test('CU - comments (4)', () {
461 expectCUFormatsTo('class X { //X!\n'
462 '}', 'class X { //X!\n'
463 '}\n');
464 });
465
466 test('CU - comments (5)', () {
467 expectCUFormatsTo('//comment one\n\n'
468 '//comment two\n\n', '//comment one\n\n'
469 '//comment two\n\n');
470 });
471
472 test('CU - comments (6)', () {
473 expectCUFormatsTo('var x; //x\n', 'var x; //x\n');
474 });
475
476 test('CU - comments (6)', () {
477 expectCUFormatsTo('var /* int */ x; //x\n', 'var /* int */ x; //x\n');
478 });
479
480 test('CU - comments (7)', () {
481 expectCUFormatsTo('library foo;\n'
482 '\n'
483 '/// Docs\n'
484 '/// spanning\n'
485 '/// lines.\n'
486 'class A {\n'
487 '}\n'
488 '\n'
489 '/// ... and\n'
490 '\n'
491 '/// Dangling ones too\n'
492 'int x;\n', 'library foo;\n'
493 '\n'
494 '/// Docs\n'
495 '/// spanning\n'
496 '/// lines.\n'
497 'class A {\n'
498 '}\n'
499 '\n'
500 '/// ... and\n'
501 '\n'
502 '/// Dangling ones too\n'
503 'int x;\n');
504 });
505
506 test('CU - comments (8)', () {
507 expectCUFormatsTo('var x /* X */, y;\n', 'var x /* X */, y;\n');
508 });
509
510 test('CU - comments (9)', () {
511 expectCUFormatsTo('main() {\n'
512 ' foo(1 /* bang */, 2);\n'
513 '}\n'
514 'foo(x, y) => null;\n', 'main() {\n'
515 ' foo(1 /* bang */, 2);\n'
516 '}\n'
517 'foo(x, y) => null;\n');
518 });
519
520 test('CU - comments (10)', () {
521 expectCUFormatsTo(
522 'var l = [1 /* bang */, 2];\n', 'var l = [1 /* bang */, 2];\n');
523 });
524
525 test('CU - comments (11)', () {
526 expectCUFormatsTo('var m = {1: 2 /* bang */, 3: 4};\n', 'var m = {\n'
527 ' 1: 2 /* bang */,\n'
528 ' 3: 4\n'
529 '};\n');
530 });
531
532 test('CU - EOF nl', () {
533 expectCUFormatsTo('var x = 1;', 'var x = 1;\n');
534 });
535
536 test('CU - constructor', () {
537 expectCUFormatsTo('class A {\n'
538 ' const _a;\n'
539 ' A();\n'
540 ' int a() => _a;\n'
541 '}\n', 'class A {\n'
542 ' const _a;\n'
543 ' A();\n'
544 ' int a() => _a;\n'
545 '}\n');
546 });
547
548 test('CU - method decl w/ named params', () {
549 expectCUFormatsTo('class A {\n'
550 ' int a(var x, {optional: null}) => null;\n'
551 '}\n', 'class A {\n'
552 ' int a(var x, {optional: null}) => null;\n'
553 '}\n');
554 });
555
556 test('CU - method decl w/ optional params', () {
557 expectCUFormatsTo('class A {\n'
558 ' int a(var x, [optional = null]) => null;\n'
559 '}\n', 'class A {\n'
560 ' int a(var x, [optional = null]) => null;\n'
561 '}\n');
562 });
563
564 test('CU - factory constructor redirects', () {
565 expectCUFormatsTo('class A {\n'
566 ' const factory A() = B;\n'
567 '}\n', 'class A {\n'
568 ' const factory A() = B;\n'
569 '}\n');
570 });
571
572 test('CU - constructor auto field inits', () {
573 expectCUFormatsTo('class A {\n'
574 ' int _a;\n'
575 ' A(this._a);\n'
576 '}\n', 'class A {\n'
577 ' int _a;\n'
578 ' A(this._a);\n'
579 '}\n');
580 });
581
582 test('CU - parts', () {
583 expectCUFormatsTo('part of foo;', 'part of foo;\n');
584 });
585
586 test('CU (cons inits)', () {
587 expectCUFormatsTo('class X {\n'
588 ' var x, y;\n'
589 ' X() : x = 1, y = 2;\n'
590 '}\n', 'class X {\n'
591 ' var x, y;\n'
592 ' X()\n'
593 ' : x = 1,\n'
594 ' y = 2;\n'
595 '}\n');
596 });
597
598 test('CU (empty cons bodies)', () {
599 expectCUFormatsTo('class A {\n'
600 ' A() {\n'
601 ' }\n'
602 '}\n', 'class A {\n'
603 ' A();\n'
604 '}\n', transforms: true);
605 expectCUFormatsTo('class A {\n'
606 ' A() {\n'
607 ' }\n'
608 '}\n', 'class A {\n'
609 ' A() {\n'
610 ' }\n'
611 '}\n', transforms: false);
612 });
613
614 test('stmt', () {
615 expectStmtFormatsTo('if (true){\n'
616 'if (true){\n'
617 'if (true){\n'
618 'return true;\n'
619 '} else{\n'
620 'return false;\n'
621 '}\n'
622 '}\n'
623 '}else{\n'
624 'return false;\n'
625 '}', 'if (true) {\n'
626 ' if (true) {\n'
627 ' if (true) {\n'
628 ' return true;\n'
629 ' } else {\n'
630 ' return false;\n'
631 ' }\n'
632 ' }\n'
633 '} else {\n'
634 ' return false;\n'
635 '}');
636 });
637
638 test('stmt (switch)', () {
639 expectStmtFormatsTo('switch (fruit) {\n'
640 'case "apple":\n'
641 'print("delish");\n'
642 'break;\n'
643 'case "fig":\n'
644 'print("bleh");\n'
645 'break;\n'
646 '}', 'switch (fruit) {\n'
647 ' case "apple":\n'
648 ' print("delish");\n'
649 ' break;\n'
650 ' case "fig":\n'
651 ' print("bleh");\n'
652 ' break;\n'
653 '}');
654 });
655
656 test('stmt (empty while body)', () {
657 expectStmtFormatsTo('while (true);', 'while (true);');
658 });
659
660 test('stmt (empty for body)', () {
661 expectStmtFormatsTo('for ( ; ; );', 'for ( ; ; );');
662 });
663
664 test('stmt (cascades)', () {
665 expectStmtFormatsTo('"foo"\n'
666 '..toString()\n'
667 '..toString();', '"foo"\n'
668 ' ..toString()\n'
669 ' ..toString();');
670 });
671
672 test('stmt (generics)', () {
673 expectStmtFormatsTo('var numbers = <int>[1, 2, (3 + 4)];',
674 'var numbers = <int>[1, 2, (3 + 4)];');
675 });
676
677 test('stmt (lists)', () {
678 expectStmtFormatsTo('var l = [1,2,3,4];', 'var l = [1, 2, 3, 4];');
679 expectStmtFormatsTo('var l = [\n'
680 '1,\n'
681 '2,\n'
682 '];', 'var l = [1, 2,];');
683 //Dangling ','
684 expectStmtFormatsTo('var l = [1,];', 'var l = [1,];');
685 });
686
687 test('stmt (maps)', () {
688 expectStmtFormatsTo('var map = const {"foo": "bar", "fuz": null};',
689 'var map = const {\n'
690 ' "foo": "bar",\n'
691 ' "fuz": null\n'
692 '};');
693
694 expectStmtFormatsTo('var map = {\n'
695 '"foo": "bar",\n'
696 '"bar": "baz"\n'
697 '};', 'var map = {\n'
698 ' "foo": "bar",\n'
699 ' "bar": "baz"\n'
700 '};');
701
702 //Dangling ','
703 expectStmtFormatsTo('var map = {"foo": "bar",};', 'var map = {\n'
704 ' "foo": "bar",\n'
705 '};');
706 });
707
708 test('stmt (try/catch)', () {
709 expectStmtFormatsTo('try {\n'
710 'doSomething();\n'
711 '} catch (e) {\n'
712 'print(e);\n'
713 '}', 'try {\n'
714 ' doSomething();\n'
715 '} catch (e) {\n'
716 ' print(e);\n'
717 '}');
718 expectStmtFormatsTo('try{\n'
719 'doSomething();\n'
720 '}on Exception catch (e){\n'
721 'print(e);\n'
722 '}', 'try {\n'
723 ' doSomething();\n'
724 '} on Exception catch (e) {\n'
725 ' print(e);\n'
726 '}');
727 });
728
729 test('stmt (binary/ternary ops)', () {
730 expectStmtFormatsTo(
731 'var a = 1 + 2 / (3 * -b);', 'var a = 1 + 2 / (3 * -b);');
732 expectStmtFormatsTo(
733 'var c = !condition == a > b;', 'var c = !condition == a > b;');
734 expectStmtFormatsTo('var d = condition ? b : object.method(a, b, c);',
735 'var d = condition ? b : object.method(a, b, c);');
736 expectStmtFormatsTo(
737 'var d = obj is! SomeType;', 'var d = obj is! SomeType;');
738 });
739
740 test('stmt (for in)', () {
741 expectStmtFormatsTo('for (Foo foo in bar.foos) {\n'
742 ' print(foo);\n'
743 '}', 'for (Foo foo in bar.foos) {\n'
744 ' print(foo);\n'
745 '}');
746 expectStmtFormatsTo('for (final Foo foo in bar.foos) {\n'
747 ' print(foo);\n'
748 '}', 'for (final Foo foo in bar.foos) {\n'
749 ' print(foo);\n'
750 '}');
751 expectStmtFormatsTo('for (final foo in bar.foos) {\n'
752 ' print(foo);\n'
753 '}', 'for (final foo in bar.foos) {\n'
754 ' print(foo);\n'
755 '}');
756 });
757
758 test('Statement (if)', () {
759 expectStmtFormatsTo(
760 'if (true) print("true!");', 'if (true) print("true!");');
761 expectStmtFormatsTo('if (true) { print("true!"); }', 'if (true) {\n'
762 ' print("true!");\n'
763 '}');
764 expectStmtFormatsTo('if (true) print("true!"); else print("false!");',
765 'if (true) {\n'
766 ' print("true!");\n'
767 '} else {\n'
768 ' print("false!");\n'
769 '}');
770 expectStmtFormatsTo('if (true) print("true!"); else print("false!");',
771 'if (true) print("true!"); else print("false!");', transforms: false);
772 });
773
774 test('String - multiline - short - same line', () {
775 expectCUFormatsTo('main() {\n'
776 ' print("""01234567890123456789012345678901234567890123456789""");\n'
777 '}\n', 'main() {\n'
778 ' print("""01234567890123456789012345678901234567890123456789""");\n'
779 '}\n');
780 });
781
782 test('String - multiline - short - next line', () {
783 expectCUFormatsTo('main() {\n'
784 ' print("""\n'
785 '01234567890123456789012345678901234567890123456789\n'
786 '""");\n'
787 '}\n', 'main() {\n'
788 ' print("""\n'
789 '01234567890123456789012345678901234567890123456789\n'
790 '""");\n'
791 '}\n');
792 });
793
794 test('String - multiline - long', () {
795 expectCUFormatsTo('main() {\n'
796 ' print("""\n'
797 '01234567890123456789012345678901234567890123456789\n'
798 '01234567890123456789012345678901234567890123456789\n'
799 '01234567890123456789012345678901234567890123456789\n'
800 '""");\n'
801 '}\n', 'main() {\n'
802 ' print("""\n'
803 '01234567890123456789012345678901234567890123456789\n'
804 '01234567890123456789012345678901234567890123456789\n'
805 '01234567890123456789012345678901234567890123456789\n'
806 '""");\n'
807 '}\n');
808 });
809
810 // smoketest to ensure we're enforcing the 'no gratuitous linebreaks'
811 // opinion
812 test('CU (eat newlines)', () {
813 expectCUFormatsTo('abstract\n'
814 'class\n'
815 'A{}', 'abstract class A {}\n');
816 });
817
818 // test('line continuations - 1', () {
819 // expectStmtFormatsTo(
820 // 'if (x &&\n'
821 // ' y) {\n'
822 // ' print("yes!");\n'
823 // '}',
824 // 'if (x &&\n'
825 // ' y) {\n'
826 // ' print("yes!");\n'
827 // '}'
828 // );
829 // expectStmtFormatsTo(
830 // 'var x =\n'
831 // ' 1234567890;',
832 // 'var x =\n'
833 // ' 1234567890;'
834 // );
835 // expectStmtFormatsTo(
836 // 'foo() {\n'
837 // ' var x = 0;\n'
838 // ' x =\n'
839 // ' 1234567890;\n'
840 // '}',
841 // 'foo() {\n'
842 // ' var x = 0;\n'
843 // ' x =\n'
844 // ' 1234567890;\n'
845 // '}'
846 // );
847 // expectStmtFormatsTo(
848 // 'foo() {\n'
849 // ' while (true &&\n'
850 // ' true) {\n'
851 // ' print("!");\n'
852 // ' }\n'
853 // '}',
854 // 'foo() {\n'
855 // ' while (true &&\n'
856 // ' true) {\n'
857 // ' print("!");\n'
858 // ' }\n'
859 // '}'
860 // );
861 // expectStmtFormatsTo(
862 // 'foo() {\n'
863 // ' do {\n'
864 // ' print("!");\n'
865 // ' } while (true &&\n'
866 // ' true);\n'
867 // '}',
868 // 'foo() {\n'
869 // ' do {\n'
870 // ' print("!");\n'
871 // ' } while (true &&\n'
872 // ' true);\n'
873 // '}'
874 // );
875 // expectStmtFormatsTo(
876 // 'int foo() {\n'
877 // ' return\n'
878 // ' foo();\n'
879 // '}',
880 // 'int foo() {\n'
881 // ' return\n'
882 // ' foo();\n'
883 // '}'
884 // );
885 // expectStmtFormatsTo(
886 // 'int foo() {\n'
887 // ' return\n'
888 // ' 13;\n'
889 // '}',
890 // 'int foo() {\n'
891 // ' return\n'
892 // ' 13;\n'
893 // '}'
894 // );
895 // expectStmtFormatsTo(
896 // 'foo(fn()) {\n'
897 // ' return foo(() {\n'
898 // ' return 1;\n'
899 // '});\n'
900 // '}',
901 // 'foo(fn()) {\n'
902 // ' return foo(() {\n'
903 // ' return 1;\n'
904 // '});\n'
905 // '}'
906 // );
907 // expectStmtFormatsTo(
908 // 'true ? foo() :\n'
909 // ' bar();',
910 // 'true ? foo() :\n'
911 // ' bar();'
912 // );
913 // expectCUFormatsTo(
914 // 'import "dart:core" as\n'
915 // ' core;\n',
916 // 'import "dart:core" as\n'
917 // ' core;\n'
918 // );
919 // expectCUFormatsTo(
920 // 'export "package:foo/foo.dart" show\n'
921 // ' Foo;\n',
922 // 'export "package:foo/foo.dart" show\n'
923 // ' Foo;\n'
924 // );
925 // expectCUFormatsTo(
926 // 'class Foo extends Bar implements\n'
927 // ' Baz {\n'
928 // '}\n',
929 // 'class Foo extends Bar implements\n'
930 // ' Baz {\n'
931 // '}\n'
932 // );
933 // });
934
935 test('initialIndent', () {
936 var formatter =
937 new CodeFormatter(new FormatterOptions(initialIndentationLevel: 2));
938 var formattedSource =
939 formatter.format(CodeKind.STATEMENT, 'var x;').source;
940 expect(formattedSource, startsWith(' '));
941 });
942
943 test('selections', () {
944 expectSelectedPostFormat('class X {}', '}');
945 expectSelectedPostFormat('class X{}', '{');
946 expectSelectedPostFormat('class X{int y;}', ';');
947 expectSelectedPostFormat('class X{int y;}', '}');
948 expectSelectedPostFormat('class X {}', ' {');
949 });
950 });
951
952 /// Token streams
953 group('token streams', () {
954 test('string tokens', () {
955 expectTokenizedEqual('class A{}', 'class A{ }');
956 expectTokenizedEqual('class A{}', 'class A{\n }\n');
957 expectTokenizedEqual('class A {}', 'class A{ }');
958 expectTokenizedEqual(' class A {}', 'class A{ }');
959 });
960
961 test('string tokens - w/ comments', () {
962 expectTokenizedEqual('//foo\nint bar;', '//foo\nint bar;');
963 expectTokenizedNotEqual('int bar;', '//foo\nint bar;');
964 expectTokenizedNotEqual('//foo\nint bar;', 'int bar;');
965 });
966
967 test('INDEX', () {
968 /// '[' ']' => '[]'
969 var t1 = openSqBracket()..setNext(closeSqBracket()..setNext(eof()));
970 var t2 = index()..setNext(eof());
971 expectStreamsEqual(t1, t2);
972 });
973
974 test('GT_GT', () {
975 /// '>' '>' => '>>'
976 var t1 = gt()..setNext(gt()..setNext(eof()));
977 var t2 = gt_gt()..setNext(eof());
978 expectStreamsEqual(t1, t2);
979 });
980
981 test('t1 < t2', () {
982 var t1 = string('foo')..setNext(eof());
983 var t2 = string('foo')..setNext(string('bar')..setNext(eof()));
984 expectStreamsNotEqual(t1, t2);
985 });
986
987 test('t1 > t2', () {
988 var t1 = string('foo')..setNext(string('bar')..setNext(eof()));
989 var t2 = string('foo')..setNext(eof());
990 expectStreamsNotEqual(t1, t2);
991 });
992 });
993
994 /// Line tests
995 group('line', () {
996 test('space', () {
997 var line = new Line(indentLevel: 0);
998 line.addSpaces(2);
999 expect(line.toString(), equals(' '));
1000 });
1001
1002 test('initial indent', () {
1003 var line = new Line(indentLevel: 2);
1004 expect(line.toString(), equals(' '));
1005 });
1006
1007 test('initial indent (tabbed)', () {
1008 var line = new Line(indentLevel: 1, useTabs: true);
1009 expect(line.toString(), equals('\t'));
1010 });
1011
1012 test('addToken', () {
1013 var line = new Line();
1014 line.addToken(new LineToken('foo'));
1015 expect(line.toString(), equals('foo'));
1016 });
1017
1018 test('addToken (2)', () {
1019 var line = new Line(indentLevel: 1);
1020 line.addToken(new LineToken('foo'));
1021 expect(line.toString(), equals(' foo'));
1022 });
1023
1024 test('isWhitespace', () {
1025 var line = new Line(indentLevel: 1);
1026 expect(line.isWhitespace(), isTrue);
1027 });
1028 });
1029
1030 /// Writer tests
1031 group('writer', () {
1032 test('basic print', () {
1033 var writer = new SourceWriter();
1034 writer.write('foo');
1035 writer.write(' ');
1036 writer.write('bar');
1037 expect(writer.toString(), equals('foo bar'));
1038 });
1039
1040 test('newline', () {
1041 var writer = new SourceWriter();
1042 writer.write('foo');
1043 writer.newline();
1044 expect(writer.toString(), equals('foo\n'));
1045 });
1046
1047 test('newline trims whitespace', () {
1048 var writer = new SourceWriter(indentCount: 2);
1049 writer.newline();
1050 expect(writer.toString(), equals('\n'));
1051 });
1052
1053 test('basic print (with indents)', () {
1054 var writer = new SourceWriter();
1055 writer.write('foo');
1056 writer.indent();
1057 writer.newline();
1058 writer.write('bar');
1059 writer.unindent();
1060 writer.newline();
1061 writer.write('baz');
1062 expect(writer.toString(), equals('foo\n bar\nbaz'));
1063 });
1064
1065 test('write - multiline', () {
1066 var writer = new SourceWriter();
1067 writer.indent();
1068 writer.newline();
1069 writer.write('aaa\nbbb\nccc');
1070 expect(writer.toString(), equals('\n aaa\nbbb\nccc'));
1071 expect(writer.currentLine.toString(), equals('ccc'));
1072 });
1073 });
1074
1075 /// Line breaker tests
1076 group('linebreaker', () {
1077 List<Chunk> breakLine(Line line, int maxLength) =>
1078 new SimpleLineBreaker(maxLength).breakLine(line);
1079
1080 String printLine(Line line, int maxLength) =>
1081 new SimpleLineBreaker(maxLength, (n) => new List.filled(n, ' ').join())
1082 .printLine(line);
1083
1084 Line line(List tokens) {
1085 var line = new Line();
1086 tokens
1087 .forEach((t) => line.addToken(t is LineToken ? t : new LineToken(t)));
1088 return line;
1089 }
1090
1091 expectTextsEqual(List<Chunk> chunks, List<String> texts) {
1092 expect(chunks.map((chunk) => chunk.toString()), orderedEquals(texts));
1093 }
1094
1095 expectTokensEqual(List<LineToken> tokens, List<String> texts) {
1096 expect(tokens.map((token) => token.toString()), orderedEquals(texts));
1097 }
1098
1099 final SP_1 = new SpaceToken(1, breakWeight: DEFAULT_SPACE_WEIGHT);
1100 final SP_w1 = new SpaceToken(1, breakWeight: 1);
1101 final SP_w2 = new SpaceToken(1, breakWeight: 2);
1102 final SP_i = new SpaceToken(1, breakWeight: SINGLE_SPACE_WEIGHT);
1103
1104 // 'foo|1|bar|1|baz|1|foo|1|bar|1|baz'
1105 final LINE_1 = line([
1106 'foo',
1107 SP_1,
1108 'bar',
1109 SP_1,
1110 'baz',
1111 SP_1,
1112 'foo',
1113 SP_1,
1114 'bar',
1115 SP_1,
1116 'baz'
1117 ]);
1118
1119 // ' foo|1|bar|1|baz|1|foo|1|bar|1|baz'
1120 final LINE_2 = line([
1121 ' foo',
1122 SP_1,
1123 'bar',
1124 SP_1,
1125 'baz',
1126 SP_1,
1127 'foo',
1128 SP_1,
1129 'bar',
1130 SP_1,
1131 'baz'
1132 ]);
1133
1134 test('breakLine - 0', () {
1135 var chunks = breakLine(line([' foo']), 8);
1136 expectTextsEqual(chunks, [' foo']);
1137 });
1138
1139 test('breakLine - 1', () {
1140 var chunks = breakLine(LINE_1, 1);
1141 expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
1142 });
1143
1144 test('breakLine - 2', () {
1145 var chunks = breakLine(LINE_1, 4);
1146 expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
1147 });
1148
1149 test('breakLine - 3', () {
1150 var chunks = breakLine(LINE_1, 8);
1151 expectTextsEqual(chunks, ['foo bar', 'baz foo', 'bar baz']);
1152 });
1153
1154 test('breakLine - 4', () {
1155 var chunks = breakLine(LINE_1, 12);
1156 expectTextsEqual(chunks, ['foo bar baz', 'foo bar baz']);
1157 });
1158
1159 test('breakLine - 5', () {
1160 var chunks = breakLine(LINE_2, 16);
1161 expectTextsEqual(chunks, [' foo bar baz', 'foo bar baz']);
1162 });
1163
1164 test('breakLine - use weights - 1', () {
1165 var source = line([
1166 '111',
1167 SP_w2,
1168 '222',
1169 SP_w1,
1170 '333',
1171 SP_w2,
1172 '444',
1173 SP_w1,
1174 '555',
1175 SP_w2,
1176 '666'
1177 ]);
1178 var chunks = breakLine(source, 12);
1179 expectTextsEqual(chunks, ['111 222', '333 444', '555 666']);
1180 });
1181
1182 test('printLine - 1', () {
1183 var line = printLine(LINE_1, 1);
1184 expect(line, 'foo\n bar\n baz\n foo\n bar\n baz');
1185 });
1186
1187 test('printLine - 2', () {
1188 var line = printLine(LINE_1, 4);
1189 expect(line, 'foo\n bar\n baz\n foo\n bar\n baz');
1190 });
1191
1192 test('printLine - 3', () {
1193 var line = printLine(LINE_1, 8);
1194 expect(line, 'foo bar\n baz foo\n bar baz');
1195 });
1196
1197 test('printLine - 4', () {
1198 var line = printLine(LINE_1, 12);
1199 expect(line, 'foo bar baz\n foo bar baz');
1200 });
1201
1202 test('printLine - use weight - 1', () {
1203 var source = line([
1204 '111111',
1205 SP_w2,
1206 '222222',
1207 SP_w1,
1208 '333333',
1209 SP_w2,
1210 '444444',
1211 SP_w1,
1212 '555555',
1213 SP_w2,
1214 '666666'
1215 ]);
1216 var result = printLine(source, 20);
1217 expect(result, '111111 222222\n 333333 444444\n 555555 666666');
1218 });
1219
1220 test('printLine - use weight - initializer - success', () {
1221 var source = line(['111111', SP_i, '2222', SP_w1, '3333', SP_w1, '4444']);
1222 var result = printLine(source, 20);
1223 expect(result, '111111\n 2222 3333 4444');
1224 });
1225
1226 test('printLine - use weight - initializer - rest too long', () {
1227 var source = line([
1228 '111',
1229 SP_i,
1230 '222',
1231 SP_w1,
1232 '333',
1233 SP_w1,
1234 '444',
1235 SP_w1,
1236 '555',
1237 SP_w1,
1238 '666'
1239 ]);
1240 var result = printLine(source, 15);
1241 expect(result, '111 222\n 333\n 444\n 555\n 666');
1242 });
1243
1244 test('printLine - use weight - initializer - decl/rest too long', () {
1245 var source = line([
1246 '111',
1247 SP_i,
1248 '2222222222222',
1249 SP_w1,
1250 '333',
1251 SP_w1,
1252 '444',
1253 SP_w1,
1254 '555',
1255 SP_w1,
1256 '666'
1257 ]);
1258 var result = printLine(source, 15);
1259 expect(result, '111\n 2222222222222\n'
1260 ' 333\n 444\n 555\n 666');
1261 });
1262
1263 test('isWhitespace', () {
1264 expect(isWhitespace('foo'), false);
1265 expect(isWhitespace(' foo'), false);
1266 expect(isWhitespace('foo '), false);
1267 expect(isWhitespace(' foo '), false);
1268 expect(isWhitespace(' '), true);
1269 expect(isWhitespace(' '), true);
1270 expect(isWhitespace('\t'), true);
1271 expect(isWhitespace('\t\t'), true);
1272 expect(isWhitespace('\n'), true);
1273 expect(isWhitespace('\r'), true);
1274 });
1275
1276 test('preprocess - 1', () {
1277 var tokens = line(['f', 'o', 'o', SP_1, 'b', 'a', 'r']).tokens;
1278 var processed = SimpleLineBreaker.preprocess(tokens);
1279 expectTokensEqual(processed, ['foo', ' ', 'bar']);
1280 });
1281
1282 test('preprocess - 2', () {
1283 var tokens = line(['f', 'o', 'o', SP_1, SP_1, 'b', 'a', 'r']).tokens;
1284 var processed = SimpleLineBreaker.preprocess(tokens);
1285 expectTokensEqual(processed, ['foo', ' ', ' ', 'bar']);
1286 });
1287
1288 test('preprocess - 3', () {
1289 var tokens = line(['f', 'o', 'o', SP_1, 'b', 'a', 'r', SP_1]).tokens;
1290 var processed = SimpleLineBreaker.preprocess(tokens);
1291 expectTokensEqual(processed, ['foo', ' ', 'bar', ' ']);
1292 });
1293 });
1294
1295 /// Helper method tests
1296 group('helpers', () {
1297 test('indentString', () {
1298 expect(getIndentString(0), '');
1299 expect(getIndentString(1), ' ');
1300 expect(getIndentString(4), ' ');
1301 });
1302
1303 test('indentString (tabbed)', () {
1304 expect(getIndentString(0, useTabs: true), '');
1305 expect(getIndentString(1, useTabs: true), '\t');
1306 expect(getIndentString(3, useTabs: true), '\t\t\t');
1307 });
1308
1309 test('repeat', () {
1310 expect(repeat('x', 0), '');
1311 expect(repeat('x', 1), 'x');
1312 expect(repeat('x', 4), 'xxxx');
1313 });
1314 });
1315 }
1316
1317 Token closeSqBracket() => new Token(TokenType.CLOSE_SQUARE_BRACKET, 0);
1318
1319 Token eof() => new Token(TokenType.EOF, 0);
1320
1321 Token gt() => new Token(TokenType.GT, 0);
1322
1323 Token gt_gt() => new Token(TokenType.GT_GT, 0);
1324
1325 Token index() => new Token(TokenType.INDEX, 0);
1326
1327 Token openSqBracket() => new BeginToken(TokenType.OPEN_SQUARE_BRACKET, 0);
1328
1329 Token string(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
1330
1331 Token classKeyword(int offset) => new KeywordToken(Keyword.CLASS, offset);
1332
1333 Token identifier(String value, int offset) =>
1334 new StringToken(TokenType.IDENTIFIER, value, offset);
1335
1336 Token openParen(int offset) =>
1337 new StringToken(TokenType.OPEN_PAREN, '{', offset);
1338
1339 Token closeParen(int offset) =>
1340 new StringToken(TokenType.CLOSE_PAREN, '}', offset);
1341
1342 Token chain(List<Token> tokens) {
1343 for (var i = 0; i < tokens.length - 1; ++i) {
1344 tokens[i].setNext(tokens[i + 1]);
1345 }
1346 return tokens[0];
1347 }
1348
1349 FormattedSource formatCU(src, {options: const FormatterOptions(), selection}) =>
1350 new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src,
1351 selection: selection);
1352
1353 String formatStatement(src, {options: const FormatterOptions()}) =>
1354 new CodeFormatter(options).format(CodeKind.STATEMENT, src).source;
1355
1356 Token tokenize(String str) {
1357 var reader = new CharSequenceReader(str);
1358 return new Scanner(null, reader, null).tokenize();
1359 }
1360
1361 expectSelectedPostFormat(src, token) {
1362 var preOffset = src.indexOf(token);
1363 var length = token.length;
1364 var formatted = formatCU(src, selection: new Selection(preOffset, length));
1365 var postOffset = formatted.selection.offset;
1366 expect(formatted.source.substring(postOffset, postOffset + length),
1367 equals(src.substring(preOffset, preOffset + length)));
1368 }
1369
1370 expectTokenizedEqual(String s1, String s2) =>
1371 expectStreamsEqual(tokenize(s1), tokenize(s2));
1372
1373 expectTokenizedNotEqual(String s1, String s2) => expect(
1374 () => expectStreamsEqual(tokenize(s1), tokenize(s2)),
1375 throwsA(new isInstanceOf<FormatterException>()));
1376
1377 expectStreamsEqual(Token t1, Token t2) =>
1378 new TokenStreamComparator(null, t1, t2).verifyEquals();
1379
1380 expectStreamsNotEqual(Token t1, Token t2) => expect(
1381 () => new TokenStreamComparator(null, t1, t2).verifyEquals(),
1382 throwsA(new isInstanceOf<FormatterException>()));
1383
1384 expectCUFormatsTo(src, expected, {transforms: true}) => expect(formatCU(src,
1385 options: new FormatterOptions(codeTransforms: transforms)).source,
1386 equals(expected));
1387
1388 expectIndentFormatsTo(spacesPerIndent, tabsForIndent, src, expected) => expect(
1389 formatCU(src,
1390 options: new FormatterOptions(
1391 spacesPerIndent: spacesPerIndent,
1392 tabsForIndent: tabsForIndent)).source, equals(expected));
1393
1394 expectStmtFormatsTo(src, expected, {transforms: true}) => expect(
1395 formatStatement(src,
1396 options: new FormatterOptions(codeTransforms: transforms)),
1397 equals(expected));
1398
1399 runTests(testFileName, expectClause(String input, String output)) {
1400 var testIndex = 1;
1401 var testFile = new File(join(TEST_DATA_DIR, testFileName));
1402 var lines = testFile.readAsLinesSync();
1403 for (var i = 1; i < lines.length; ++i) {
1404 var input = '',
1405 expectedOutput = '';
1406 while (!lines[i].startsWith('<<<')) {
1407 input += lines[i++] + '\n';
1408 }
1409 while (++i < lines.length && !lines[i].startsWith('>>>')) {
1410 expectedOutput += lines[i] + '\n';
1411 }
1412 test('test - (${testIndex++})', () {
1413 expectClause(input, expectedOutput);
1414 });
1415 }
1416 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698