OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 trydart.incremental_compilation_update_test; | |
6 | |
7 import 'dart:html' hide | |
8 Element; | |
9 | |
10 import 'dart:async' show | |
11 Future; | |
12 | |
13 import 'package:async_helper/async_helper.dart' show | |
14 asyncTest; | |
15 | |
16 import 'package:expect/expect.dart' show | |
17 Expect; | |
18 | |
19 import 'package:try/src/interaction_manager.dart' show | |
20 splitLines; | |
21 | |
22 import 'package:try/poi/scope_information_visitor.dart' show | |
23 ScopeInformationVisitor; | |
24 | |
25 import 'sandbox.dart' show | |
26 appendIFrame, | |
27 listener; | |
28 | |
29 import 'web_compiler_test_case.dart' show | |
30 WebCompilerTestCase, | |
31 WebInputProvider; | |
32 | |
33 import '../poi/compiler_test_case.dart' show | |
34 CompilerTestCase; | |
35 | |
36 import 'package:compiler/src/elements/elements.dart' show | |
37 Element, | |
38 LibraryElement; | |
39 | |
40 import 'package:compiler/src/compiler.dart' show | |
41 Compiler; | |
42 | |
43 import 'package:dart2js_incremental/dart2js_incremental.dart' show | |
44 IncrementalCompilationFailed; | |
45 | |
46 import 'program_result.dart'; | |
47 | |
48 const int TIMEOUT = 100; | |
49 | |
50 const List<EncodedResult> tests = const <EncodedResult>[ | |
51 // Basic hello-world test. | |
52 const EncodedResult( | |
53 const [ | |
54 "main() { print('Hello, ", | |
55 const ["", "Brave New "], | |
56 "World!'); }", | |
57 ], | |
58 const <ProgramExpectation>[ | |
59 const ProgramExpectation( | |
60 const <String>['Hello, World!']), | |
61 const ProgramExpectation( | |
62 const <String>['Hello, Brave New World!']), | |
63 ]), | |
64 | |
65 // Test that the test framework handles more than one update. | |
66 const EncodedResult( | |
67 const [ | |
68 "main() { print('", | |
69 const [ | |
70 "Hello darkness, my old friend", | |
71 "I\\'ve come to talk with you again", | |
72 "Because a vision softly creeping", | |
73 ], | |
74 "'); }", | |
75 ], | |
76 const <ProgramExpectation>[ | |
77 const ProgramExpectation( | |
78 const <String>['Hello darkness, my old friend']), | |
79 const ProgramExpectation( | |
80 const <String>['I\'ve come to talk with you again']), | |
81 const ProgramExpectation( | |
82 const <String>['Because a vision softly creeping']), | |
83 ]), | |
84 | |
85 // Test that that isolate support works. | |
86 const EncodedResult( | |
87 const [ | |
88 "main(arguments) { print(", | |
89 const [ | |
90 "'Hello, Isolated World!'", | |
91 "arguments" | |
92 ], | |
93 "); }", | |
94 ], | |
95 const <ProgramExpectation>[ | |
96 const ProgramExpectation( | |
97 const <String>['Hello, Isolated World!']), | |
98 const ProgramExpectation( | |
99 const <String>['[]']), | |
100 ]), | |
101 | |
102 const EncodedResult( | |
103 const [ | |
104 r""" | |
105 // Test that a stored closure changes behavior when updated. | |
106 | |
107 var closure; | |
108 | |
109 foo(a, [b = 'b']) { | |
110 """, | |
111 const [ | |
112 r""" | |
113 print('$a $b'); | |
114 """, | |
115 r""" | |
116 print('$b $a'); | |
117 """, | |
118 ], | |
119 r""" | |
120 } | |
121 | |
122 main() { | |
123 if (closure == null) { | |
124 print('[closure] is null.'); | |
125 closure = foo; | |
126 } | |
127 closure('a'); | |
128 closure('a', 'c'); | |
129 } | |
130 """], | |
131 const <ProgramExpectation>[ | |
132 const ProgramExpectation( | |
133 const <String>['[closure] is null.', 'a b', 'a c']), | |
134 const ProgramExpectation( | |
135 const <String>['b a', 'c a']), | |
136 ]), | |
137 | |
138 const EncodedResult( | |
139 const [ | |
140 """ | |
141 // Test modifying a static method works. | |
142 | |
143 class C { | |
144 static m() { | |
145 """, | |
146 const [ | |
147 r""" | |
148 print('v1'); | |
149 """, | |
150 r""" | |
151 print('v2'); | |
152 """, | |
153 ], | |
154 """ | |
155 } | |
156 } | |
157 main() { | |
158 C.m(); | |
159 } | |
160 """, | |
161 ], | |
162 const <ProgramExpectation>[ | |
163 const ProgramExpectation( | |
164 const <String>['v1']), | |
165 const ProgramExpectation( | |
166 const <String>['v2']), | |
167 ]), | |
168 | |
169 const EncodedResult( | |
170 const [ | |
171 """ | |
172 // Test modifying an instance method works. | |
173 | |
174 class C { | |
175 m() { | |
176 """, | |
177 const [ | |
178 r""" | |
179 print('v1'); | |
180 """, | |
181 r""" | |
182 print('v2'); | |
183 """, | |
184 ], | |
185 """ | |
186 } | |
187 } | |
188 var instance; | |
189 main() { | |
190 if (instance == null) { | |
191 print('instance is null'); | |
192 instance = new C(); | |
193 } | |
194 instance.m(); | |
195 } | |
196 """, | |
197 | |
198 ], | |
199 const <ProgramExpectation>[ | |
200 const ProgramExpectation( | |
201 const <String>['instance is null', 'v1']), | |
202 const ProgramExpectation( | |
203 const <String>['v2']), | |
204 ]), | |
205 | |
206 const EncodedResult( | |
207 const [ | |
208 """ | |
209 // Test that a stored instance tearoff changes behavior when updated. | |
210 | |
211 class C { | |
212 m() { | |
213 """, | |
214 const [ | |
215 r""" | |
216 print('v1'); | |
217 """, | |
218 r""" | |
219 print('v2'); | |
220 """, | |
221 ], | |
222 """ | |
223 } | |
224 } | |
225 var closure; | |
226 main() { | |
227 if (closure == null) { | |
228 print('closure is null'); | |
229 closure = new C().m; | |
230 } | |
231 closure(); | |
232 } | |
233 """, | |
234 | |
235 ], | |
236 const <ProgramExpectation>[ | |
237 const ProgramExpectation( | |
238 const <String>['closure is null', 'v1']), | |
239 const ProgramExpectation( | |
240 const <String>['v2']), | |
241 ]), | |
242 | |
243 const EncodedResult( | |
244 const [ | |
245 """ | |
246 // Test that deleting an instance method works. | |
247 | |
248 class C { | |
249 """, | |
250 const [ | |
251 """ | |
252 m() { | |
253 print('v1'); | |
254 } | |
255 """, | |
256 """ | |
257 """, | |
258 ], | |
259 """ | |
260 } | |
261 var instance; | |
262 main() { | |
263 if (instance == null) { | |
264 print('instance is null'); | |
265 instance = new C(); | |
266 } | |
267 try { | |
268 instance.m(); | |
269 } catch (e) { | |
270 print('threw'); | |
271 } | |
272 } | |
273 """, | |
274 ], | |
275 const <ProgramExpectation>[ | |
276 const ProgramExpectation( | |
277 const <String>['instance is null', 'v1']), | |
278 const ProgramExpectation( | |
279 const <String>['threw']), | |
280 ]), | |
281 | |
282 const EncodedResult( | |
283 const [ | |
284 """ | |
285 // Test that deleting an instance method works, even when accessed through | |
286 // super. | |
287 | |
288 class A { | |
289 m() { | |
290 print('v2'); | |
291 } | |
292 } | |
293 class B extends A { | |
294 """, | |
295 const [ | |
296 """ | |
297 m() { | |
298 print('v1'); | |
299 } | |
300 """, | |
301 """ | |
302 """, | |
303 ], | |
304 """ | |
305 } | |
306 class C extends B { | |
307 m() { | |
308 super.m(); | |
309 } | |
310 } | |
311 var instance; | |
312 main() { | |
313 if (instance == null) { | |
314 print('instance is null'); | |
315 instance = new C(); | |
316 } | |
317 instance.m(); | |
318 } | |
319 """, | |
320 | |
321 ], | |
322 const <ProgramExpectation>[ | |
323 const ProgramExpectation( | |
324 const <String>['instance is null', 'v1']), | |
325 const ProgramExpectation( | |
326 const <String>['v2']), | |
327 ]), | |
328 | |
329 const EncodedResult( | |
330 const [ | |
331 """ | |
332 // Test that deleting a top-level method works. | |
333 | |
334 """, | |
335 const [ | |
336 """ | |
337 toplevel() { | |
338 print('v1'); | |
339 } | |
340 """, | |
341 """ | |
342 """, | |
343 ], | |
344 """ | |
345 class C { | |
346 m() { | |
347 try { | |
348 toplevel(); | |
349 } catch (e) { | |
350 print('threw'); | |
351 } | |
352 } | |
353 } | |
354 var instance; | |
355 main() { | |
356 if (instance == null) { | |
357 print('instance is null'); | |
358 instance = new C(); | |
359 } | |
360 instance.m(); | |
361 } | |
362 """, | |
363 ], | |
364 const <ProgramExpectation>[ | |
365 const ProgramExpectation( | |
366 const <String>['instance is null', 'v1']), | |
367 const ProgramExpectation( | |
368 const <String>['threw']), | |
369 ]), | |
370 | |
371 const EncodedResult( | |
372 const [ | |
373 """ | |
374 // Test that deleting a static method works. | |
375 | |
376 class B { | |
377 """, | |
378 const [ | |
379 """ | |
380 static staticMethod() { | |
381 print('v1'); | |
382 } | |
383 """, | |
384 """ | |
385 """, | |
386 ], | |
387 """ | |
388 } | |
389 class C { | |
390 m() { | |
391 try { | |
392 B.staticMethod(); | |
393 } catch (e) { | |
394 print('threw'); | |
395 } | |
396 try { | |
397 // Ensure that noSuchMethod support is compiled. This test is not about | |
398 // adding new classes. | |
399 B.missingMethod(); | |
400 print('bad'); | |
401 } catch (e) { | |
402 } | |
403 } | |
404 } | |
405 var instance; | |
406 main() { | |
407 if (instance == null) { | |
408 print('instance is null'); | |
409 instance = new C(); | |
410 } | |
411 instance.m(); | |
412 } | |
413 """, | |
414 ], | |
415 const <ProgramExpectation>[ | |
416 const ProgramExpectation( | |
417 const <String>['instance is null', 'v1']), | |
418 const ProgramExpectation( | |
419 const <String>['threw']), | |
420 ]), | |
421 | |
422 const EncodedResult( | |
423 const [ | |
424 """ | |
425 // Test that a newly instantiated class is handled. | |
426 | |
427 class A { | |
428 m() { | |
429 print('Called A.m'); | |
430 } | |
431 } | |
432 | |
433 class B { | |
434 m() { | |
435 print('Called B.m'); | |
436 } | |
437 } | |
438 | |
439 var instance; | |
440 main() { | |
441 if (instance == null) { | |
442 print('instance is null'); | |
443 instance = new A(); | |
444 """, | |
445 const [ | |
446 """ | |
447 """, | |
448 """ | |
449 } else { | |
450 instance = new B(); | |
451 """, | |
452 ], | |
453 """ | |
454 } | |
455 instance.m(); | |
456 } | |
457 """, | |
458 | |
459 ], | |
460 const <ProgramExpectation>[ | |
461 const ProgramExpectation( | |
462 const <String>['instance is null', 'Called A.m']), | |
463 const ProgramExpectation( | |
464 const <String>['Called B.m']), | |
465 ]), | |
466 | |
467 const EncodedResult( | |
468 const [ | |
469 """ | |
470 // Test that source maps don't throw exceptions. | |
471 | |
472 main() { | |
473 print('a'); | |
474 """, | |
475 const [ | |
476 """ | |
477 """, | |
478 """ | |
479 print('b'); | |
480 print('c'); | |
481 """, | |
482 ], | |
483 """ | |
484 } | |
485 """, | |
486 ], | |
487 const <ProgramExpectation>[ | |
488 const ProgramExpectation( | |
489 const <String>['a']), | |
490 const ProgramExpectation( | |
491 const <String>['a', 'b', 'c']), | |
492 ]), | |
493 | |
494 const EncodedResult( | |
495 const [ | |
496 r""" | |
497 // Test that a newly instantiated class is handled. | |
498 | |
499 class A { | |
500 get name => 'A.m'; | |
501 | |
502 m() { | |
503 print('Called $name'); | |
504 } | |
505 } | |
506 | |
507 class B extends A { | |
508 get name => 'B.m'; | |
509 } | |
510 | |
511 var instance; | |
512 main() { | |
513 if (instance == null) { | |
514 print('instance is null'); | |
515 instance = new A(); | |
516 """, | |
517 const [ | |
518 r""" | |
519 """, | |
520 r""" | |
521 } else { | |
522 instance = new B(); | |
523 """, | |
524 ], | |
525 r""" | |
526 } | |
527 instance.m(); | |
528 } | |
529 """, | |
530 ], | |
531 const <ProgramExpectation>[ | |
532 const ProgramExpectation( | |
533 const <String>['instance is null', 'Called A.m']), | |
534 const ProgramExpectation( | |
535 const <String>['Called B.m']), | |
536 ]), | |
537 | |
538 const EncodedResult( | |
539 const [ | |
540 r""" | |
541 // Test that fields of a newly instantiated class are handled. | |
542 | |
543 class A { | |
544 var x; | |
545 A(this.x); | |
546 } | |
547 var instance; | |
548 foo() { | |
549 if (instance != null) { | |
550 print(instance.x); | |
551 } else { | |
552 print('v1'); | |
553 } | |
554 } | |
555 main() { | |
556 """, | |
557 const [ | |
558 r""" | |
559 """, | |
560 r""" | |
561 instance = new A('v2'); | |
562 """, | |
563 ], | |
564 r""" | |
565 foo(); | |
566 } | |
567 """, | |
568 ], | |
569 const <ProgramExpectation>[ | |
570 const ProgramExpectation( | |
571 const <String>['v1']), | |
572 const ProgramExpectation( | |
573 const <String>['v2']), | |
574 ]), | |
575 | |
576 const EncodedResult( | |
577 const [ | |
578 r""" | |
579 // Test that top-level functions can be added. | |
580 | |
581 """, | |
582 const [ | |
583 "", | |
584 r""" | |
585 foo() { | |
586 print('v2'); | |
587 } | |
588 """, | |
589 ], | |
590 r""" | |
591 main() { | |
592 try { | |
593 foo(); | |
594 } catch(e) { | |
595 print('threw'); | |
596 } | |
597 } | |
598 """, | |
599 ], | |
600 const <ProgramExpectation>[ | |
601 const ProgramExpectation( | |
602 const <String>['threw']), | |
603 const ProgramExpectation( | |
604 const <String>['v2']), | |
605 ]), | |
606 | |
607 const EncodedResult( | |
608 const [ | |
609 r""" | |
610 // Test that static methods can be added. | |
611 | |
612 class C { | |
613 """, | |
614 const [ | |
615 "", | |
616 r""" | |
617 static foo() { | |
618 print('v2'); | |
619 } | |
620 """, | |
621 ], | |
622 r""" | |
623 } | |
624 | |
625 main() { | |
626 try { | |
627 C.foo(); | |
628 } catch(e) { | |
629 print('threw'); | |
630 } | |
631 } | |
632 """, | |
633 | |
634 ], | |
635 const <ProgramExpectation>[ | |
636 const ProgramExpectation( | |
637 const <String>['threw']), | |
638 const ProgramExpectation( | |
639 const <String>['v2']), | |
640 ]), | |
641 | |
642 const EncodedResult( | |
643 const [ | |
644 r""" | |
645 // Test that instance methods can be added. | |
646 | |
647 class C { | |
648 """, | |
649 const [ | |
650 "", | |
651 r""" | |
652 foo() { | |
653 print('v2'); | |
654 } | |
655 """, | |
656 ], | |
657 r""" | |
658 } | |
659 | |
660 var instance; | |
661 | |
662 main() { | |
663 if (instance == null) { | |
664 print('instance is null'); | |
665 instance = new C(); | |
666 } | |
667 | |
668 try { | |
669 instance.foo(); | |
670 } catch(e) { | |
671 print('threw'); | |
672 } | |
673 } | |
674 """, | |
675 ], | |
676 const <ProgramExpectation>[ | |
677 const ProgramExpectation( | |
678 const <String>['instance is null', 'threw']), | |
679 const ProgramExpectation( | |
680 const <String>['v2']), | |
681 ]), | |
682 | |
683 const EncodedResult( | |
684 const [ | |
685 r""" | |
686 // Test that top-level functions can have signature changed. | |
687 | |
688 """, | |
689 const [ | |
690 r""" | |
691 foo() { | |
692 print('v1'); | |
693 """, | |
694 r""" | |
695 void foo() { | |
696 print('v2'); | |
697 """, | |
698 ], | |
699 r""" | |
700 } | |
701 | |
702 main() { | |
703 foo(); | |
704 } | |
705 """, | |
706 ], | |
707 const <ProgramExpectation>[ | |
708 const ProgramExpectation( | |
709 const <String>['v1']), | |
710 const ProgramExpectation( | |
711 const <String>['v2']), | |
712 ]), | |
713 | |
714 const EncodedResult( | |
715 const [ | |
716 r""" | |
717 // Test that static methods can have signature changed. | |
718 | |
719 class C { | |
720 """, | |
721 const [ | |
722 r""" | |
723 static foo() { | |
724 print('v1'); | |
725 """, | |
726 r""" | |
727 static void foo() { | |
728 print('v2'); | |
729 """, | |
730 ], | |
731 r""" | |
732 } | |
733 } | |
734 | |
735 main() { | |
736 C.foo(); | |
737 } | |
738 """, | |
739 ], | |
740 const <ProgramExpectation>[ | |
741 const ProgramExpectation( | |
742 const <String>['v1']), | |
743 const ProgramExpectation( | |
744 const <String>['v2']), | |
745 ]), | |
746 | |
747 const EncodedResult( | |
748 const [ | |
749 r""" | |
750 // Test that instance methods can have signature changed. | |
751 | |
752 class C { | |
753 """, | |
754 const [ | |
755 r""" | |
756 foo() { | |
757 print('v1'); | |
758 """, | |
759 r""" | |
760 void foo() { | |
761 print('v2'); | |
762 """, | |
763 ], | |
764 r""" | |
765 } | |
766 } | |
767 | |
768 var instance; | |
769 | |
770 main() { | |
771 if (instance == null) { | |
772 print('instance is null'); | |
773 instance = new C(); | |
774 } | |
775 | |
776 instance.foo(); | |
777 } | |
778 """, | |
779 ], | |
780 const <ProgramExpectation>[ | |
781 const ProgramExpectation( | |
782 const <String>['instance is null', 'v1']), | |
783 const ProgramExpectation( | |
784 const <String>['v2']), | |
785 ]), | |
786 | |
787 const EncodedResult( | |
788 const [ | |
789 r""" | |
790 // Test that adding a class is supported. | |
791 | |
792 """, | |
793 const [ | |
794 "", | |
795 r""" | |
796 class C { | |
797 void foo() { | |
798 print('v2'); | |
799 } | |
800 } | |
801 """, | |
802 ], | |
803 r""" | |
804 main() { | |
805 """, | |
806 const [ | |
807 r""" | |
808 print('v1'); | |
809 """, | |
810 r""" | |
811 new C().foo(); | |
812 """, | |
813 ], | |
814 r""" | |
815 } | |
816 """, | |
817 ], | |
818 const <ProgramExpectation>[ | |
819 const ProgramExpectation( | |
820 const <String>['v1']), | |
821 const ProgramExpectation( | |
822 const <String>['v2']), | |
823 ]), | |
824 | |
825 const EncodedResult( | |
826 const [ | |
827 r""" | |
828 // Test that removing a class is supported, using constructor. | |
829 | |
830 """, | |
831 const [ | |
832 r""" | |
833 class C { | |
834 } | |
835 """, | |
836 "" | |
837 ], | |
838 r""" | |
839 main() { | |
840 try { | |
841 new C(); | |
842 print('v1'); | |
843 } catch (e) { | |
844 print('v2'); | |
845 } | |
846 } | |
847 """, | |
848 ], | |
849 const <ProgramExpectation>[ | |
850 const ProgramExpectation( | |
851 const <String>['v1']), | |
852 const ProgramExpectation( | |
853 const <String>['v2']), | |
854 ]), | |
855 | |
856 const EncodedResult( | |
857 const [ | |
858 r""" | |
859 // Test that removing a class is supported, using a static method. | |
860 | |
861 """, | |
862 const [ | |
863 r""" | |
864 class C { | |
865 static m() { | |
866 print('v1'); | |
867 } | |
868 } | |
869 """, | |
870 "", | |
871 ], | |
872 r""" | |
873 main() { | |
874 try { | |
875 C.m(); | |
876 } catch (e) { | |
877 print('v2'); | |
878 } | |
879 } | |
880 """, | |
881 ], | |
882 const <ProgramExpectation>[ | |
883 const ProgramExpectation( | |
884 const <String>['v1']), | |
885 const ProgramExpectation( | |
886 const <String>['v2']), | |
887 ]), | |
888 | |
889 const EncodedResult( | |
890 const [ | |
891 r""" | |
892 // Test that changing the supertype of a class. | |
893 | |
894 class A { | |
895 m() { | |
896 print('v2'); | |
897 } | |
898 } | |
899 class B extends A { | |
900 m() { | |
901 print('v1'); | |
902 } | |
903 } | |
904 """, | |
905 const [ | |
906 r""" | |
907 class C extends B { | |
908 """, | |
909 r""" | |
910 class C extends A { | |
911 """, | |
912 ], | |
913 r""" | |
914 m() { | |
915 super.m(); | |
916 } | |
917 } | |
918 | |
919 var instance; | |
920 | |
921 main() { | |
922 if (instance == null) { | |
923 print('instance is null'); | |
924 instance = new C(); | |
925 } | |
926 instance.m(); | |
927 } | |
928 """, | |
929 ], | |
930 const <ProgramExpectation>[ | |
931 const ProgramExpectation( | |
932 const <String>['instance is null', 'v1']), | |
933 const ProgramExpectation( | |
934 const <String>['v2']), | |
935 ]), | |
936 | |
937 const EncodedResult( | |
938 const [ | |
939 r""" | |
940 // Test adding a field to a class works. | |
941 | |
942 class A { | |
943 """, | |
944 const [ | |
945 "", | |
946 r""" | |
947 var x; | |
948 """, | |
949 ], | |
950 r""" | |
951 } | |
952 | |
953 var instance; | |
954 | |
955 main() { | |
956 if (instance == null) { | |
957 print('instance is null'); | |
958 instance = new A(); | |
959 } | |
960 try { | |
961 instance.x = 'v2'; | |
962 } catch(e) { | |
963 print('setter threw'); | |
964 } | |
965 try { | |
966 print(instance.x); | |
967 } catch (e) { | |
968 print('getter threw'); | |
969 } | |
970 } | |
971 """, | |
972 ], | |
973 const <ProgramExpectation>[ | |
974 const ProgramExpectation( | |
975 const <String>['instance is null', 'setter threw', 'getter threw
']), | |
976 const ProgramExpectation( | |
977 const <String>['v2']), | |
978 ]), | |
979 | |
980 const EncodedResult( | |
981 const [ | |
982 r""" | |
983 // Test removing a field from a class works. | |
984 | |
985 class A { | |
986 """, | |
987 const [ | |
988 r""" | |
989 var x; | |
990 """, | |
991 "", | |
992 ], | |
993 r""" | |
994 } | |
995 | |
996 var instance; | |
997 | |
998 main() { | |
999 if (instance == null) { | |
1000 print('instance is null'); | |
1001 instance = new A(); | |
1002 } | |
1003 try { | |
1004 instance.x = 'v1'; | |
1005 } catch(e) { | |
1006 print('setter threw'); | |
1007 } | |
1008 try { | |
1009 print(instance.x); | |
1010 } catch (e) { | |
1011 print('getter threw'); | |
1012 } | |
1013 } | |
1014 """, | |
1015 ], | |
1016 const <ProgramExpectation>[ | |
1017 const ProgramExpectation( | |
1018 const <String>['instance is null', 'v1']), | |
1019 const ProgramExpectation( | |
1020 const <String>['setter threw', 'getter threw']), | |
1021 ]), | |
1022 | |
1023 const EncodedResult( | |
1024 const [ | |
1025 r""" | |
1026 // Test that named arguments can be called. | |
1027 | |
1028 class C { | |
1029 foo({a, named: 'v1', x}) { | |
1030 print(named); | |
1031 } | |
1032 } | |
1033 | |
1034 var instance; | |
1035 | |
1036 main() { | |
1037 if (instance == null) { | |
1038 print('instance is null'); | |
1039 instance = new C(); | |
1040 } | |
1041 """, | |
1042 const [ | |
1043 r""" | |
1044 instance.foo(); | |
1045 """, | |
1046 r""" | |
1047 instance.foo(named: 'v2'); | |
1048 """, | |
1049 ], | |
1050 r""" | |
1051 } | |
1052 """, | |
1053 ], | |
1054 const <ProgramExpectation>[ | |
1055 const ProgramExpectation( | |
1056 const <String>['instance is null', 'v1']), | |
1057 const ProgramExpectation( | |
1058 const <String>['v2']), | |
1059 ]), | |
1060 | |
1061 const EncodedResult( | |
1062 const [ | |
1063 r""" | |
1064 // Test than named arguments can be called. | |
1065 | |
1066 class C { | |
1067 foo({a, named: 'v2', x}) { | |
1068 print(named); | |
1069 } | |
1070 } | |
1071 | |
1072 var instance; | |
1073 | |
1074 main() { | |
1075 if (instance == null) { | |
1076 print('instance is null'); | |
1077 instance = new C(); | |
1078 } | |
1079 """, | |
1080 const [ | |
1081 r""" | |
1082 instance.foo(named: 'v1'); | |
1083 """, | |
1084 r""" | |
1085 instance.foo(); | |
1086 """, | |
1087 ], | |
1088 r""" | |
1089 } | |
1090 """, | |
1091 ], | |
1092 const <ProgramExpectation>[ | |
1093 const ProgramExpectation( | |
1094 const <String>['instance is null', 'v1']), | |
1095 const ProgramExpectation( | |
1096 const <String>['v2']), | |
1097 ]), | |
1098 | |
1099 const EncodedResult( | |
1100 const [ | |
1101 r""" | |
1102 // Test that an instance tear-off with named parameters can be called. | |
1103 | |
1104 class C { | |
1105 foo({a, named: 'v1', x}) { | |
1106 print(named); | |
1107 } | |
1108 } | |
1109 | |
1110 var closure; | |
1111 | |
1112 main() { | |
1113 if (closure == null) { | |
1114 print('closure is null'); | |
1115 closure = new C().foo; | |
1116 } | |
1117 """, | |
1118 const [ | |
1119 r""" | |
1120 closure(); | |
1121 """, | |
1122 r""" | |
1123 closure(named: 'v2'); | |
1124 """, | |
1125 ], | |
1126 r""" | |
1127 } | |
1128 """, | |
1129 ], | |
1130 const <ProgramExpectation>[ | |
1131 const ProgramExpectation( | |
1132 const <String>['closure is null', 'v1']), | |
1133 const ProgramExpectation( | |
1134 const <String>['v2']), | |
1135 ]), | |
1136 | |
1137 const EncodedResult( | |
1138 const [ | |
1139 r""" | |
1140 // Test that a lazy static is supported. | |
1141 | |
1142 var normal; | |
1143 | |
1144 """, | |
1145 const [ | |
1146 r""" | |
1147 foo() { | |
1148 print(normal); | |
1149 } | |
1150 """, | |
1151 r""" | |
1152 var lazy = bar(); | |
1153 | |
1154 foo() { | |
1155 print(lazy); | |
1156 } | |
1157 | |
1158 bar() { | |
1159 print('v2'); | |
1160 return 'lazy'; | |
1161 } | |
1162 | |
1163 """, | |
1164 ], | |
1165 r""" | |
1166 main() { | |
1167 if (normal == null) { | |
1168 normal = 'v1'; | |
1169 } else { | |
1170 normal = ''; | |
1171 } | |
1172 foo(); | |
1173 } | |
1174 """, | |
1175 ], | |
1176 const <ProgramExpectation>[ | |
1177 const ProgramExpectation( | |
1178 const <String>['v1']), | |
1179 const ProgramExpectation( | |
1180 const <String>['v2', 'lazy']), | |
1181 ]), | |
1182 | |
1183 const EncodedResult( | |
1184 const [ | |
1185 r""" | |
1186 // Test that superclasses of directly instantiated classes are also emitted. | |
1187 class A { | |
1188 } | |
1189 | |
1190 class B extends A { | |
1191 } | |
1192 | |
1193 main() { | |
1194 """, | |
1195 const [ | |
1196 r""" | |
1197 print('v1'); | |
1198 """, | |
1199 r""" | |
1200 new B(); | |
1201 print('v2'); | |
1202 """, | |
1203 ], | |
1204 r""" | |
1205 } | |
1206 """, | |
1207 ], | |
1208 const <ProgramExpectation>[ | |
1209 const ProgramExpectation( | |
1210 const <String>['v1']), | |
1211 const ProgramExpectation( | |
1212 const <String>['v2']), | |
1213 ]), | |
1214 | |
1215 const EncodedResult( | |
1216 const [ | |
1217 r""" | |
1218 // Test that interceptor classes are handled correctly. | |
1219 | |
1220 main() { | |
1221 """, | |
1222 const [ | |
1223 r""" | |
1224 print('v1'); | |
1225 """, | |
1226 r""" | |
1227 ['v2'].forEach(print); | |
1228 """, | |
1229 ], | |
1230 r""" | |
1231 } | |
1232 """, | |
1233 ], | |
1234 const <ProgramExpectation>[ | |
1235 const ProgramExpectation( | |
1236 const <String>['v1']), | |
1237 const ProgramExpectation( | |
1238 const <String>['v2']), | |
1239 ]), | |
1240 | |
1241 const EncodedResult( | |
1242 const [ | |
1243 r""" | |
1244 // Test that newly instantiated superclasses are handled correctly when there | |
1245 // is more than one change. | |
1246 | |
1247 class A { | |
1248 foo() { | |
1249 print('Called foo'); | |
1250 } | |
1251 | |
1252 bar() { | |
1253 print('Called bar'); | |
1254 } | |
1255 } | |
1256 | |
1257 class B extends A { | |
1258 } | |
1259 | |
1260 main() { | |
1261 """, | |
1262 const [ | |
1263 r""" | |
1264 new B().foo(); | |
1265 """, | |
1266 r""" | |
1267 new B().foo(); | |
1268 """, | |
1269 r""" | |
1270 new A().bar(); | |
1271 """, | |
1272 ], | |
1273 r""" | |
1274 } | |
1275 """, | |
1276 ], | |
1277 const <ProgramExpectation>[ | |
1278 const ProgramExpectation( | |
1279 const <String>['Called foo']), | |
1280 const ProgramExpectation( | |
1281 const <String>['Called foo']), | |
1282 const ProgramExpectation( | |
1283 const <String>['Called bar']), | |
1284 ]), | |
1285 | |
1286 const EncodedResult( | |
1287 const [ | |
1288 r""" | |
1289 // Test that newly instantiated subclasses are handled correctly when there is | |
1290 // more than one change. | |
1291 | |
1292 class A { | |
1293 foo() { | |
1294 print('Called foo'); | |
1295 } | |
1296 | |
1297 bar() { | |
1298 print('Called bar'); | |
1299 } | |
1300 } | |
1301 | |
1302 class B extends A { | |
1303 } | |
1304 | |
1305 main() { | |
1306 """, | |
1307 const [ | |
1308 r""" | |
1309 new A().foo(); | |
1310 """, | |
1311 r""" | |
1312 new A().foo(); | |
1313 """, | |
1314 r""" | |
1315 new B().bar(); | |
1316 """, | |
1317 ], | |
1318 r""" | |
1319 } | |
1320 """, | |
1321 ], | |
1322 const <ProgramExpectation>[ | |
1323 const ProgramExpectation( | |
1324 const <String>['Called foo']), | |
1325 const ProgramExpectation( | |
1326 const <String>['Called foo']), | |
1327 const ProgramExpectation( | |
1328 const <String>['Called bar']), | |
1329 ]), | |
1330 | |
1331 const EncodedResult( | |
1332 const [ | |
1333 r""" | |
1334 // Test that constants are handled correctly. | |
1335 | |
1336 class C { | |
1337 final String value; | |
1338 const C(this.value); | |
1339 } | |
1340 | |
1341 main() { | |
1342 """, | |
1343 const [ | |
1344 r""" | |
1345 print(const C('v1').value); | |
1346 """, | |
1347 r""" | |
1348 print(const C('v2').value); | |
1349 """, | |
1350 ], | |
1351 r""" | |
1352 } | |
1353 """, | |
1354 ], | |
1355 const <ProgramExpectation>[ | |
1356 const ProgramExpectation( | |
1357 const <String>['v1']), | |
1358 const ProgramExpectation( | |
1359 const <String>['v2']), | |
1360 ]), | |
1361 | |
1362 const EncodedResult( | |
1363 const [ | |
1364 r""" | |
1365 // Test that an instance field can be added to a compound declaration. | |
1366 | |
1367 class C { | |
1368 """, | |
1369 const [ | |
1370 r""" | |
1371 int x; | |
1372 """, | |
1373 r""" | |
1374 int x, y; | |
1375 """, | |
1376 ], | |
1377 r""" | |
1378 } | |
1379 | |
1380 var instance; | |
1381 | |
1382 main() { | |
1383 if (instance == null) { | |
1384 print('[instance] is null'); | |
1385 instance = new C(); | |
1386 instance.x = 'v1'; | |
1387 } else { | |
1388 instance.y = 'v2'; | |
1389 } | |
1390 try { | |
1391 print(instance.x); | |
1392 } catch (e) { | |
1393 print('[instance.x] threw'); | |
1394 } | |
1395 try { | |
1396 print(instance.y); | |
1397 } catch (e) { | |
1398 print('[instance.y] threw'); | |
1399 } | |
1400 } | |
1401 """, | |
1402 ], | |
1403 const <ProgramExpectation>[ | |
1404 const ProgramExpectation( | |
1405 const <String>[ | |
1406 '[instance] is null', 'v1', '[instance.y] threw']), | |
1407 const ProgramExpectation( | |
1408 const <String>['v1', 'v2'], | |
1409 // TODO(ahe): Shouldn't throw. | |
1410 compileUpdatesShouldThrow: true), | |
1411 ]), | |
1412 | |
1413 const EncodedResult( | |
1414 const [ | |
1415 r""" | |
1416 // Test that an instance field can be removed from a compound declaration. | |
1417 | |
1418 class C { | |
1419 """, | |
1420 const [ | |
1421 r""" | |
1422 int x, y; | |
1423 """, | |
1424 r""" | |
1425 int x; | |
1426 """, | |
1427 ], | |
1428 r""" | |
1429 } | |
1430 | |
1431 var instance; | |
1432 | |
1433 main() { | |
1434 if (instance == null) { | |
1435 print('[instance] is null'); | |
1436 instance = new C(); | |
1437 instance.x = 'v1'; | |
1438 instance.y = 'v2'; | |
1439 } | |
1440 try { | |
1441 print(instance.x); | |
1442 } catch (e) { | |
1443 print('[instance.x] threw'); | |
1444 } | |
1445 try { | |
1446 print(instance.y); | |
1447 } catch (e) { | |
1448 print('[instance.y] threw'); | |
1449 } | |
1450 } | |
1451 """, | |
1452 ], | |
1453 const <ProgramExpectation>[ | |
1454 const ProgramExpectation( | |
1455 const <String>['[instance] is null', 'v1', 'v2']), | |
1456 const ProgramExpectation( | |
1457 const <String>['v1', '[instance.y] threw'], | |
1458 // TODO(ahe): Shouldn't throw. | |
1459 compileUpdatesShouldThrow: true), | |
1460 ]), | |
1461 | |
1462 const EncodedResult( | |
1463 const [ | |
1464 r""" | |
1465 // Test that a static field can be made an instance field. | |
1466 | |
1467 class C { | |
1468 """, | |
1469 | |
1470 const [ | |
1471 r""" | |
1472 static int x; | |
1473 """, | |
1474 r""" | |
1475 int x; | |
1476 """, | |
1477 ], | |
1478 r""" | |
1479 } | |
1480 | |
1481 var instance; | |
1482 | |
1483 main() { | |
1484 if (instance == null) { | |
1485 print('[instance] is null'); | |
1486 instance = new C(); | |
1487 C.x = 'v1'; | |
1488 } else { | |
1489 instance.x = 'v2'; | |
1490 } | |
1491 try { | |
1492 print(C.x); | |
1493 } catch (e) { | |
1494 print('[C.x] threw'); | |
1495 } | |
1496 try { | |
1497 print(instance.x); | |
1498 } catch (e) { | |
1499 print('[instance.x] threw'); | |
1500 } | |
1501 } | |
1502 """, | |
1503 ], | |
1504 const <ProgramExpectation>[ | |
1505 const ProgramExpectation( | |
1506 const <String>['[instance] is null', 'v1', '[instance.x] threw']
), | |
1507 const ProgramExpectation( | |
1508 const <String>['[C.x] threw', 'v2'], | |
1509 // TODO(ahe): Shouldn't throw. | |
1510 compileUpdatesShouldThrow: true), | |
1511 ]), | |
1512 | |
1513 const EncodedResult( | |
1514 const [ | |
1515 r""" | |
1516 // Test that instance field can be made static. | |
1517 | |
1518 class C { | |
1519 """, | |
1520 const [ | |
1521 r""" | |
1522 int x; | |
1523 """, | |
1524 r""" | |
1525 static int x; | |
1526 """, | |
1527 ], | |
1528 r""" | |
1529 } | |
1530 | |
1531 var instance; | |
1532 | |
1533 main() { | |
1534 if (instance == null) { | |
1535 print('[instance] is null'); | |
1536 instance = new C(); | |
1537 instance.x = 'v1'; | |
1538 } else { | |
1539 C.x = 'v2'; | |
1540 } | |
1541 try { | |
1542 print(C.x); | |
1543 } catch (e) { | |
1544 print('[C.x] threw'); | |
1545 } | |
1546 try { | |
1547 print(instance.x); | |
1548 } catch (e) { | |
1549 print('[instance.x] threw'); | |
1550 } | |
1551 } | |
1552 """, | |
1553 ], | |
1554 const <ProgramExpectation>[ | |
1555 const ProgramExpectation( | |
1556 const <String>['[instance] is null', '[C.x] threw', 'v1']), | |
1557 const ProgramExpectation( | |
1558 const <String>['v2', '[instance.x] threw'], | |
1559 // TODO(ahe): Shouldn't throw. | |
1560 compileUpdatesShouldThrow: true), | |
1561 ]), | |
1562 | |
1563 const EncodedResult( | |
1564 const [ | |
1565 r""" | |
1566 // Test compound constants. | |
1567 | |
1568 class A { | |
1569 final value; | |
1570 const A(this.value); | |
1571 | |
1572 toString() => 'A($value)'; | |
1573 } | |
1574 | |
1575 class B { | |
1576 final value; | |
1577 const B(this.value); | |
1578 | |
1579 toString() => 'B($value)'; | |
1580 } | |
1581 | |
1582 main() { | |
1583 """, | |
1584 const [ | |
1585 r""" | |
1586 print(const A('v1')); | |
1587 print(const B('v1')); | |
1588 """, | |
1589 r""" | |
1590 print(const B(const A('v2'))); | |
1591 print(const A(const B('v2'))); | |
1592 """, | |
1593 ], | |
1594 r""" | |
1595 } | |
1596 """, | |
1597 ], | |
1598 const <ProgramExpectation>[ | |
1599 const ProgramExpectation( | |
1600 const <String>['A(v1)', 'B(v1)']), | |
1601 const ProgramExpectation( | |
1602 const <String>['B(A(v2))', 'A(B(v2))']), | |
1603 ]), | |
1604 | |
1605 const EncodedResult( | |
1606 const [ | |
1607 r""" | |
1608 // Test constants of new classes. | |
1609 | |
1610 class A { | |
1611 final value; | |
1612 const A(this.value); | |
1613 | |
1614 toString() => 'A($value)'; | |
1615 } | |
1616 """, | |
1617 const [ | |
1618 "", | |
1619 r""" | |
1620 class B { | |
1621 final value; | |
1622 const B(this.value); | |
1623 | |
1624 toString() => 'B($value)'; | |
1625 } | |
1626 | |
1627 """, | |
1628 ], | |
1629 r""" | |
1630 main() { | |
1631 """, | |
1632 | |
1633 const [ | |
1634 r""" | |
1635 print(const A('v1')); | |
1636 """, | |
1637 r""" | |
1638 print(const A('v2')); | |
1639 print(const B('v2')); | |
1640 print(const B(const A('v2'))); | |
1641 print(const A(const B('v2'))); | |
1642 """, | |
1643 ], | |
1644 r""" | |
1645 } | |
1646 """, | |
1647 | |
1648 ], | |
1649 const <ProgramExpectation>[ | |
1650 const ProgramExpectation( | |
1651 const <String>['A(v1)']), | |
1652 const ProgramExpectation( | |
1653 const <String>['A(v2)', 'B(v2)', 'B(A(v2))', 'A(B(v2))']), | |
1654 ]), | |
1655 | |
1656 const EncodedResult( | |
1657 r""" | |
1658 ==> main.dart <== | |
1659 // Test that a change in a part is handled. | |
1660 library test.main; | |
1661 | |
1662 part 'part.dart'; | |
1663 | |
1664 | |
1665 ==> part.dart.patch <== | |
1666 part of test.main; | |
1667 | |
1668 main() { | |
1669 <<<<<<< | |
1670 print('Hello, World!'); | |
1671 ======= | |
1672 print('Hello, Brave New World!'); | |
1673 >>>>>>> | |
1674 } | |
1675 """, | |
1676 const [ | |
1677 'Hello, World!', | |
1678 'Hello, Brave New World!', | |
1679 ]), | |
1680 | |
1681 const EncodedResult( | |
1682 r""" | |
1683 ==> main.dart.patch <== | |
1684 // Test that a change in library name is handled. | |
1685 <<<<<<< | |
1686 library test.main1; | |
1687 ======= | |
1688 library test.main2; | |
1689 >>>>>>> | |
1690 | |
1691 main() { | |
1692 print('Hello, World!'); | |
1693 } | |
1694 """, | |
1695 const [ | |
1696 'Hello, World!', | |
1697 const ProgramExpectation( | |
1698 const <String>['Hello, World!'], | |
1699 // TODO(ahe): Shouldn't throw. | |
1700 compileUpdatesShouldThrow: true), | |
1701 ]), | |
1702 | |
1703 const EncodedResult( | |
1704 r""" | |
1705 ==> main.dart.patch <== | |
1706 // Test that adding an import is handled. | |
1707 <<<<<<< | |
1708 ======= | |
1709 import 'dart:core'; | |
1710 >>>>>>> | |
1711 | |
1712 main() { | |
1713 print('Hello, World!'); | |
1714 } | |
1715 """, | |
1716 const [ | |
1717 'Hello, World!', | |
1718 const ProgramExpectation( | |
1719 const <String>['Hello, World!'], | |
1720 // TODO(ahe): Shouldn't throw. | |
1721 compileUpdatesShouldThrow: true), | |
1722 ]), | |
1723 | |
1724 const EncodedResult( | |
1725 r""" | |
1726 ==> main.dart.patch <== | |
1727 // Test that adding an export is handled. | |
1728 <<<<<<< | |
1729 ======= | |
1730 export 'dart:core'; | |
1731 >>>>>>> | |
1732 | |
1733 main() { | |
1734 print('Hello, World!'); | |
1735 } | |
1736 """, | |
1737 const [ | |
1738 'Hello, World!', | |
1739 const ProgramExpectation( | |
1740 const <String>['Hello, World!'], | |
1741 // TODO(ahe): Shouldn't throw. | |
1742 compileUpdatesShouldThrow: true), | |
1743 ]), | |
1744 | |
1745 const EncodedResult( | |
1746 r""" | |
1747 ==> main.dart.patch <== | |
1748 // Test that adding a part is handled. | |
1749 library test.main; | |
1750 | |
1751 <<<<<<< | |
1752 ======= | |
1753 part 'part.dart'; | |
1754 >>>>>>> | |
1755 | |
1756 main() { | |
1757 print('Hello, World!'); | |
1758 } | |
1759 | |
1760 | |
1761 ==> part.dart <== | |
1762 part of test.main | |
1763 """, | |
1764 const [ | |
1765 'Hello, World!', | |
1766 const ProgramExpectation( | |
1767 const <String>['Hello, World!'], | |
1768 // TODO(ahe): Shouldn't throw. | |
1769 compileUpdatesShouldThrow: true), | |
1770 ]), | |
1771 | |
1772 const EncodedResult( | |
1773 r""" | |
1774 ==> main.dart <== | |
1775 // Test that changes in multiple libraries is handled. | |
1776 import 'library1.dart' as lib1; | |
1777 import 'library2.dart' as lib2; | |
1778 | |
1779 main() { | |
1780 lib1.method(); | |
1781 lib2.method(); | |
1782 } | |
1783 | |
1784 | |
1785 ==> library1.dart.patch <== | |
1786 library test.library1; | |
1787 | |
1788 method() { | |
1789 <<<<<<< | |
1790 print('lib1.v1'); | |
1791 ======= | |
1792 print('lib1.v2'); | |
1793 ======= | |
1794 print('lib1.v3'); | |
1795 >>>>>>> | |
1796 } | |
1797 | |
1798 | |
1799 ==> library2.dart.patch <== | |
1800 library test.library2; | |
1801 | |
1802 method() { | |
1803 <<<<<<< | |
1804 print('lib2.v1'); | |
1805 ======= | |
1806 print('lib2.v2'); | |
1807 ======= | |
1808 print('lib2.v3'); | |
1809 >>>>>>> | |
1810 } | |
1811 """, | |
1812 const [ | |
1813 const <String>['lib1.v1', 'lib2.v1'], | |
1814 const <String>['lib1.v2', 'lib2.v2'], | |
1815 const <String>['lib1.v3', 'lib2.v3'], | |
1816 ]), | |
1817 ]; | |
1818 | |
1819 void main() { | |
1820 listener.start(); | |
1821 | |
1822 document.head.append(lineNumberStyle()); | |
1823 | |
1824 summary = new SpanElement(); | |
1825 document.body.append(new HeadingElement.h1() | |
1826 ..appendText("Incremental compiler tests") | |
1827 ..append(summary)); | |
1828 | |
1829 String query = window.location.search; | |
1830 int skip = 0; | |
1831 if (query != null && query.length > 1) { | |
1832 query = query.substring(1); | |
1833 String skipParameter = Uri.splitQueryString(window.location.search)['skip']; | |
1834 if (skipParameter != null) { | |
1835 skip = int.parse(skipParameter); | |
1836 } | |
1837 String verboseParameter = | |
1838 Uri.splitQueryString(window.location.search)['verbose']; | |
1839 verboseStatus = verboseParameter != null; | |
1840 } | |
1841 testCount += skip; | |
1842 | |
1843 return asyncTest(() => Future.forEach(tests.skip(skip), compileAndRun) | |
1844 .then(updateSummary)); | |
1845 } | |
1846 | |
1847 SpanElement summary; | |
1848 | |
1849 int testCount = 1; | |
1850 | |
1851 bool verboseStatus = false; | |
1852 | |
1853 void updateSummary(_) { | |
1854 summary.text = " (${testCount - 1}/${tests.length})"; | |
1855 } | |
1856 | |
1857 Future compileAndRun(EncodedResult encodedResult) { | |
1858 updateSummary(null); | |
1859 List<ProgramResult> programs = encodedResult.decode(); | |
1860 var status = new DivElement(); | |
1861 document.body.append(status); | |
1862 | |
1863 IFrameElement iframe = | |
1864 appendIFrame( | |
1865 '/root_dart/tests/try/web/incremental_compilation_update.html', | |
1866 document.body) | |
1867 ..style.width = '100%' | |
1868 ..style.height = '600px'; | |
1869 | |
1870 return listener.expect('iframe-ready').then((_) { | |
1871 ProgramResult program = programs.first; | |
1872 | |
1873 status.append( | |
1874 new HeadingElement.h2() | |
1875 ..appendText("Full program #${testCount++}:")); | |
1876 status.append(numberedLines(program.code)); | |
1877 | |
1878 status.style.color = 'orange'; | |
1879 WebCompilerTestCase test = new WebCompilerTestCase(program.code); | |
1880 return test.run().then((String jsCode) { | |
1881 status.style.color = 'red'; | |
1882 var objectUrl = | |
1883 Url.createObjectUrl(new Blob([jsCode], 'application/javascript')); | |
1884 | |
1885 iframe.contentWindow.postMessage(['add-script', objectUrl], '*'); | |
1886 Future future = | |
1887 listener.expect(program.messagesWith('iframe-dart-main-done')); | |
1888 return future.then((_) { | |
1889 int version = 2; | |
1890 return Future.forEach(programs.skip(1), (ProgramResult program) { | |
1891 | |
1892 status.append(new HeadingElement.h2()..appendText("Update:")); | |
1893 status.append(numberedLines(program.code)); | |
1894 | |
1895 WebInputProvider inputProvider = | |
1896 test.incrementalCompiler.inputProvider; | |
1897 Uri base = test.scriptUri; | |
1898 Map<String, String> code = program.code is String | |
1899 ? { 'main.dart': program.code } | |
1900 : program.code; | |
1901 Map<Uri, Uri> uriMap = <Uri, Uri>{}; | |
1902 for (String name in code.keys) { | |
1903 Uri uri = base.resolve('$name?v${version++}'); | |
1904 inputProvider.cachedSources[uri] = new Future.value(code[name]); | |
1905 uriMap[base.resolve(name)] = uri; | |
1906 } | |
1907 Future future = test.incrementalCompiler.compileUpdates( | |
1908 uriMap, logVerbose: logger, logTime: logger); | |
1909 bool compileUpdatesThrew = false; | |
1910 future = future.catchError((error, trace) { | |
1911 String statusMessage; | |
1912 Future result; | |
1913 compileUpdatesThrew = true; | |
1914 if (program.compileUpdatesShouldThrow && | |
1915 error is IncrementalCompilationFailed) { | |
1916 statusMessage = "Expected error in compileUpdates."; | |
1917 result = null; | |
1918 } else { | |
1919 statusMessage = "Unexpected error in compileUpdates."; | |
1920 result = new Future.error(error, trace); | |
1921 } | |
1922 status.append(new HeadingElement.h3()..appendText(statusMessage)); | |
1923 return result; | |
1924 }); | |
1925 return future.then((String update) { | |
1926 if (program.compileUpdatesShouldThrow) { | |
1927 Expect.isTrue( | |
1928 compileUpdatesThrew, | |
1929 "Expected an exception in compileUpdates"); | |
1930 Expect.isNull( update, "Expected update == null"); | |
1931 return null; | |
1932 } | |
1933 print({'update': update}); | |
1934 iframe.contentWindow.postMessage(['apply-update', update], '*'); | |
1935 | |
1936 return listener.expect( | |
1937 program.messagesWith('iframe-dart-updated-main-done')) | |
1938 .then((_) { | |
1939 // TODO(ahe): Enable SerializeScopeTestCase for multiple | |
1940 // parts. | |
1941 if (program.code is! String) return null; | |
1942 return new SerializeScopeTestCase( | |
1943 program.code, test.incrementalCompiler.mainApp, | |
1944 test.incrementalCompiler.compiler).run(); | |
1945 }); | |
1946 }); | |
1947 }); | |
1948 }); | |
1949 }); | |
1950 }).then((_) { | |
1951 status.style.color = 'limegreen'; | |
1952 | |
1953 // Remove the iframe and status to work around a bug in test.dart | |
1954 // (https://code.google.com/p/dart/issues/detail?id=21691). | |
1955 if (!verboseStatus) status.remove(); | |
1956 iframe.remove(); | |
1957 }); | |
1958 } | |
1959 | |
1960 class SerializeScopeTestCase extends CompilerTestCase { | |
1961 final String scopeInfo; | |
1962 | |
1963 SerializeScopeTestCase( | |
1964 String source, | |
1965 LibraryElement library, | |
1966 Compiler compiler) | |
1967 : scopeInfo = computeScopeInfo(compiler, library), | |
1968 super(source, '${library.canonicalUri}'); | |
1969 | |
1970 Future run() => loadMainApp().then(checkScopes); | |
1971 | |
1972 void checkScopes(LibraryElement library) { | |
1973 Expect.stringEquals(computeScopeInfo(compiler, library), scopeInfo); | |
1974 } | |
1975 | |
1976 static String computeScopeInfo(Compiler compiler, LibraryElement library) { | |
1977 ScopeInformationVisitor visitor = | |
1978 new ScopeInformationVisitor(compiler, library, 0); | |
1979 | |
1980 visitor.ignoreImports = true; | |
1981 visitor.sortMembers = true; | |
1982 visitor.indented.write('[\n'); | |
1983 visitor.indentationLevel++; | |
1984 visitor.indented; | |
1985 library.accept(visitor); | |
1986 library.forEachLocalMember((Element member) { | |
1987 if (member.isClass) { | |
1988 visitor.buffer.write(',\n'); | |
1989 visitor.indented; | |
1990 member.accept(visitor); | |
1991 } | |
1992 }); | |
1993 visitor.buffer.write('\n'); | |
1994 visitor.indentationLevel--; | |
1995 visitor.indented.write(']'); | |
1996 return '${visitor.buffer}'; | |
1997 } | |
1998 } | |
1999 | |
2000 void logger(x) { | |
2001 print(x); | |
2002 bool isCheckedMode = false; | |
2003 assert(isCheckedMode = true); | |
2004 int timeout = isCheckedMode ? TIMEOUT * 2 : TIMEOUT; | |
2005 if (listener.elapsed > timeout) { | |
2006 throw 'Test timed out.'; | |
2007 } | |
2008 } | |
2009 | |
2010 DivElement numberedLines(code) { | |
2011 if (code is! Map) { | |
2012 code = {'main.dart': code}; | |
2013 } | |
2014 DivElement result = new DivElement(); | |
2015 code.forEach((String fileName, String code) { | |
2016 result.append(new HeadingElement.h4()..appendText(fileName)); | |
2017 DivElement lines = new DivElement(); | |
2018 result.append(lines); | |
2019 lines.classes.add("output"); | |
2020 | |
2021 for (String text in splitLines(code)) { | |
2022 PreElement line = new PreElement() | |
2023 ..appendText(text.trimRight()) | |
2024 ..classes.add("line"); | |
2025 lines.append(line); | |
2026 } | |
2027 }); | |
2028 return result; | |
2029 } | |
2030 | |
2031 StyleElement lineNumberStyle() { | |
2032 StyleElement style = new StyleElement()..appendText(''' | |
2033 h2, h3, h4 { | |
2034 color: black; | |
2035 } | |
2036 | |
2037 .output { | |
2038 padding: 0px; | |
2039 counter-reset: line-number; | |
2040 padding-bottom: 1em; | |
2041 } | |
2042 | |
2043 .line { | |
2044 white-space: pre-wrap; | |
2045 padding-left: 3.5em; | |
2046 margin-top: 0; | |
2047 margin-bottom: 0; | |
2048 } | |
2049 | |
2050 .line::before { | |
2051 counter-increment: line-number; | |
2052 content: counter(line-number) " "; | |
2053 position: absolute; | |
2054 left: 0px; | |
2055 width: 3em; | |
2056 text-align: right; | |
2057 background-color: lightgoldenrodyellow; | |
2058 } | |
2059 '''); | |
2060 style.type = 'text/css'; | |
2061 return style; | |
2062 } | |
OLD | NEW |