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

Side by Side Diff: test/dependency_graph_test.dart

Issue 973433003: Initial cut for a development server (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
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
« no previous file with comments | « test/codegen_test.dart ('k') | test/end_to_end_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 ddc.test.dependency_graph_test;
6
7 import 'package:unittest/compact_vm_config.dart';
8 import 'package:unittest/unittest.dart';
9
10 import 'package:dev_compiler/src/checker/dart_sdk.dart'
11 show mockSdkSources, dartSdkDirectory;
12 import 'package:dev_compiler/src/testing.dart';
13 import 'package:dev_compiler/src/options.dart';
14 import 'package:dev_compiler/src/checker/resolver.dart';
15 import 'package:dev_compiler/src/dependency_graph.dart';
16 import 'package:path/path.dart' as path;
17
18 main() {
19 groupSep = " > ";
20 useCompactVMConfiguration();
21
22 var options = new CompilerOptions();
23 var testUriResolver;
24 var context;
25 var graph;
26
27 /// Initial values for test files
28 var testFiles = {
29 '/index1.html': '''
30 <script src="foo.js"></script>
31 ''',
32 '/index2.html': '''
33 <script type="application/dart" src="a1.dart"></script>
34 ''',
35 '/index3.html': '''
36 <script type="application/dart" src="a2.dart"></script>
37 ''',
38 '/a1.dart': '''
39 library a1;
40 ''',
41 '/a2.dart': '''
42 library a2;
43 import 'a3.dart';
44 import 'a4.dart';
45 export 'a5.dart';
46 part 'a6.dart';
47 ''',
48 '/a3.dart': 'library a3;',
49 '/a4.dart': 'library a4; export "a10.dart";',
50 '/a5.dart': 'library a5;',
51 '/a6.dart': 'part of a2;',
52 '/a8.dart': 'library a8; import "a8.dart";',
53 '/a9.dart': 'library a9; import "a8.dart";',
54 '/a10.dart': 'library a10;',
55 };
56
57 nodeOf(String filepath, [bool isPart = false]) =>
58 graph.nodeFromUri(new Uri.file(filepath), isPart);
59
60 setUp(() {
61 /// We completely reset the TestUriResolver to avoid interference between
62 /// tests (since some tests modify the state of the files).
63 testUriResolver = new TestUriResolver(testFiles);
64 context = new TypeResolver.fromMock(mockSdkSources, options,
65 otherResolvers: [testUriResolver]).context;
66 graph = new SourceGraph(context, options);
67 });
68
69 group('HTML deps', () {
70 test('initial deps', () {
71 var i1 = nodeOf('/index1.html');
72 var i2 = nodeOf('/index2.html');
73 expect(i1.scripts.length, 0);
74 expect(i2.scripts.length, 0);
75 i1.update(graph);
76 i2.update(graph);
77 expect(i1.scripts.length, 0);
78 expect(i2.scripts.length, 1);
79 expect(i2.scripts.first, nodeOf('/a1.dart'));
80 });
81
82 test('add a dep', () {
83 // After initial load, dependencies are 0:
84 var node = nodeOf('/index1.html');
85 node.update(graph);
86 expect(node.scripts.length, 0);
87
88 // Adding the dependency is discovered on the next round of updates:
89 node.source.contents.modificationTime++;
90 node.source.contents.data =
91 '<script type="application/dart" src="a2.dart"></script>';
92 expect(node.scripts.length, 0);
93 node.update(graph);
94 expect(node.scripts.length, 1);
95 expect(node.scripts.first, nodeOf('/a2.dart'));
96 });
97
98 test('add more deps', () {
99 // After initial load, dependencies are 1:
100 var node = nodeOf('/index2.html');
101 node.update(graph);
102 expect(node.scripts.length, 1);
103 expect(node.scripts.first, nodeOf('/a1.dart'));
104
105 node.source.contents.modificationTime++;
106 node.source.contents.data +=
107 '<script type="application/dart" src="a2.dart"></script>';
108 expect(node.scripts.length, 1);
109 node.update(graph);
110 expect(node.scripts.length, 2);
111 expect(node.scripts.first, nodeOf('/a1.dart'));
112 expect(node.scripts.last, nodeOf('/a2.dart'));
113 });
114
115 test('remove all deps', () {
116 // After initial load, dependencies are 1:
117 var node = nodeOf('/index2.html');
118 node.update(graph);
119 expect(node.scripts.length, 1);
120 expect(node.scripts.first, nodeOf('/a1.dart'));
121
122 // Removing the dependency is discovered on the next round of updates:
123 node.source.contents.modificationTime++;
124 node.source.contents.data = '';
125 expect(node.scripts.length, 1);
126 node.update(graph);
127 expect(node.scripts.length, 0);
128 });
129 });
130
131 group('Dart deps', () {
132 test('initial deps', () {
133 var a1 = nodeOf('/a1.dart');
134 var a2 = nodeOf('/a2.dart');
135 expect(a1.imports.length, 0);
136 expect(a1.exports.length, 0);
137 expect(a1.parts.length, 0);
138 expect(a2.imports.length, 0);
139 expect(a2.exports.length, 0);
140 expect(a2.parts.length, 0);
141
142 a1.update(graph);
143 a2.update(graph);
144
145 expect(a1.imports.length, 0);
146 expect(a1.exports.length, 0);
147 expect(a1.parts.length, 0);
148 expect(a2.imports.length, 2);
149 expect(a2.exports.length, 1);
150 expect(a2.parts.length, 1);
151 expect(a2.imports.contains(nodeOf('/a3.dart')), isTrue);
152 expect(a2.imports.contains(nodeOf('/a4.dart')), isTrue);
153 expect(a2.exports.contains(nodeOf('/a5.dart')), isTrue);
154 expect(a2.parts.contains(nodeOf('/a6.dart')), isTrue);
155 });
156
157 test('add deps', () {
158 var node = nodeOf('/a1.dart');
159 node.update(graph);
160 expect(node.imports.length, 0);
161 expect(node.exports.length, 0);
162 expect(node.parts.length, 0);
163
164 node.source.contents.modificationTime++;
165 node.source.contents.data =
166 'import "a3.dart"; export "a5.dart"; part "a8.dart";';
167 node.update(graph);
168
169 expect(node.imports.length, 1);
170 expect(node.exports.length, 1);
171 expect(node.parts.length, 1);
172 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue);
173 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue);
174 expect(node.parts.contains(nodeOf('/a8.dart')), isTrue);
175 });
176
177 test('remove deps', () {
178 var node = nodeOf('/a2.dart');
179 node.update(graph);
180 expect(node.imports.length, 2);
181 expect(node.exports.length, 1);
182 expect(node.parts.length, 1);
183 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue);
184 expect(node.imports.contains(nodeOf('/a4.dart')), isTrue);
185 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue);
186 expect(node.parts.contains(nodeOf('/a6.dart')), isTrue);
187
188 node.source.contents.modificationTime++;
189 node.source.contents.data =
190 'import "a3.dart"; export "a6.dart"; part "a8.dart";';
191 node.update(graph);
192
193 expect(node.imports.length, 1);
194 expect(node.exports.length, 1);
195 expect(node.parts.length, 1);
196 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue);
197 expect(node.exports.contains(nodeOf('/a6.dart')), isTrue);
198 expect(node.parts.contains(nodeOf('/a8.dart')), isTrue);
199 });
200 });
201
202 group('local changes', () {
203 group('needs rebuild', () {
204 test('in HTML', () {
205 var node = nodeOf('/index1.html');
206 node.update(graph);
207 expect(node.needsRebuild, isTrue);
208 node.needsRebuild = false;
209
210 node.update(graph);
211 expect(node.needsRebuild, isFalse);
212
213 // For now, an empty modification is enough to trigger a rebuild
214 node.source.contents.modificationTime++;
215 expect(node.needsRebuild, isFalse);
216 node.update(graph);
217 expect(node.needsRebuild, isTrue);
218 });
219
220 test('main library in Dart', () {
221 var node = nodeOf('/a2.dart');
222 var partNode = nodeOf('/a6.dart', true);
223 node.update(graph);
224 expect(node.needsRebuild, isTrue);
225 node.needsRebuild = false;
226 partNode.needsRebuild = false;
227
228 node.update(graph);
229 expect(node.needsRebuild, isFalse);
230
231 // For now, an empty modification is enough to trigger a rebuild
232 node.source.contents.modificationTime++;
233 expect(node.needsRebuild, isFalse);
234 node.update(graph);
235 expect(node.needsRebuild, isTrue);
236 });
237
238 test('part of library in Dart', () {
239 var node = nodeOf('/a2.dart');
240 var importNode = nodeOf('/a3.dart');
241 var exportNode = nodeOf('/a5.dart');
242 var partNode = nodeOf('/a6.dart', true);
243 node.update(graph);
244 expect(node.needsRebuild, isTrue);
245 node.needsRebuild = false;
246 partNode.needsRebuild = false;
247
248 node.update(graph);
249 expect(node.needsRebuild, isFalse);
250
251 // Modification in imported/exported node makes no difference for local
252 // rebuild label (globally that's tested elsewhere)
253 importNode.source.contents.modificationTime++;
254 exportNode.source.contents.modificationTime++;
255 node.update(graph);
256 expect(node.needsRebuild, isFalse);
257 expect(partNode.needsRebuild, isFalse);
258
259 // Modification in part triggers change in containing library:
260 partNode.source.contents.modificationTime++;
261 expect(node.needsRebuild, isFalse);
262 expect(partNode.needsRebuild, isFalse);
263 node.update(graph);
264 expect(node.needsRebuild, isTrue);
265 expect(partNode.needsRebuild, isTrue);
266 });
267 });
268
269 group('structure change', () {
270 test('no mod in HTML', () {
271 var node = nodeOf('/index2.html');
272 node.update(graph);
273 expect(node.structureChanged, isTrue);
274 node.structureChanged = false;
275
276 node.update(graph);
277 expect(node.structureChanged, isFalse);
278
279 // An empty modification will not trigger a structural change
280 node.source.contents.modificationTime++;
281 expect(node.structureChanged, isFalse);
282 node.update(graph);
283 expect(node.structureChanged, isFalse);
284 });
285
286 test('added scripts in HTML', () {
287 var node = nodeOf('/index2.html');
288 node.update(graph);
289 expect(node.structureChanged, isTrue);
290 expect(node.scripts.length, 1);
291
292 node.structureChanged = false;
293 node.update(graph);
294 expect(node.structureChanged, isFalse);
295
296 // This change will not include new script tags:
297 node.source.contents.modificationTime++;
298 node.source.contents.data += '<div></div>';
299 expect(node.structureChanged, isFalse);
300 node.update(graph);
301 expect(node.structureChanged, isFalse);
302 expect(node.scripts.length, 1);
303
304 node.source.contents.modificationTime++;
305 node.source.contents.data +=
306 '<script type="application/dart" src="a4.dart"></script>';
307 expect(node.structureChanged, isFalse);
308 node.update(graph);
309 expect(node.structureChanged, isTrue);
310 expect(node.scripts.length, 2);
311 });
312
313 test('no mod in Dart', () {
314 var node = nodeOf('/a2.dart');
315 var importNode = nodeOf('/a3.dart');
316 var exportNode = nodeOf('/a5.dart');
317 var partNode = nodeOf('/a6.dart', true);
318 node.update(graph);
319 expect(node.structureChanged, isTrue);
320 node.structureChanged = false;
321
322 node.update(graph);
323 expect(node.structureChanged, isFalse);
324
325 // These modifications make no difference at all.
326 importNode.source.contents.modificationTime++;
327 exportNode.source.contents.modificationTime++;
328 partNode.source.contents.modificationTime++;
329 node.source.contents.modificationTime++;
330
331 expect(node.structureChanged, isFalse);
332 node.update(graph);
333 expect(node.structureChanged, isFalse);
334 });
335
336 test('same directives, different order', () {
337 var node = nodeOf('/a2.dart');
338 node.update(graph);
339 expect(node.structureChanged, isTrue);
340 node.structureChanged = false;
341
342 node.update(graph);
343 expect(node.structureChanged, isFalse);
344
345 // modified order of imports, but structure stays the same:
346 node.source.contents.modificationTime++;
347 node.source.contents.data = 'import "a4.dart"; import "a3.dart"; '
348 'export "a5.dart"; part "a6.dart";';
349 node.update(graph);
350
351 expect(node.structureChanged, isFalse);
352 node.update(graph);
353 expect(node.structureChanged, isFalse);
354 });
355
356 test('changed parts', () {
357 var node = nodeOf('/a2.dart');
358 node.update(graph);
359 expect(node.structureChanged, isTrue);
360 node.structureChanged = false;
361
362 node.update(graph);
363 expect(node.structureChanged, isFalse);
364
365 // added one.
366 node.source.contents.modificationTime++;
367 node.source.contents.data = 'import "a4.dart"; import "a3.dart"; '
368 'export "a5.dart"; part "a6.dart"; part "a7.dart";';
369 expect(node.structureChanged, isFalse);
370 node.update(graph);
371 expect(node.structureChanged, isTrue);
372
373 // no change
374 node.structureChanged = false;
375 node.source.contents.modificationTime++;
376 node.update(graph);
377 expect(node.structureChanged, isFalse);
378
379 // removed one
380 node.source.contents.modificationTime++;
381 node.source.contents.data = 'import "a4.dart"; import "a3.dart"; '
382 'export "a5.dart"; part "a7.dart";';
383 expect(node.structureChanged, isFalse);
384 node.update(graph);
385 expect(node.structureChanged, isTrue);
386 });
387
388 test('changed import', () {
389 var node = nodeOf('/a2.dart');
390 node.update(graph);
391 expect(node.structureChanged, isTrue);
392 node.structureChanged = false;
393
394 node.update(graph);
395 expect(node.structureChanged, isFalse);
396
397 // added one.
398 node.source.contents.modificationTime++;
399 node.source.contents.data =
400 'import "a4.dart"; import "a3.dart"; import "a7.dart";'
401 'export "a5.dart"; part "a6.dart";';
402 expect(node.structureChanged, isFalse);
403 node.update(graph);
404 expect(node.structureChanged, isTrue);
405
406 // no change
407 node.structureChanged = false;
408 node.source.contents.modificationTime++;
409 node.update(graph);
410 expect(node.structureChanged, isFalse);
411
412 // removed one
413 node.source.contents.modificationTime++;
414 node.source.contents.data = 'import "a4.dart"; import "a7.dart"; '
415 'export "a5.dart"; part "a6.dart";';
416 expect(node.structureChanged, isFalse);
417 node.update(graph);
418 expect(node.structureChanged, isTrue);
419 });
420
421 test('changed exports', () {
422 var node = nodeOf('/a2.dart');
423 node.update(graph);
424 expect(node.structureChanged, isTrue);
425 node.structureChanged = false;
426
427 node.update(graph);
428 expect(node.structureChanged, isFalse);
429
430 // added one.
431 node.source.contents.modificationTime++;
432 node.source.contents.data = 'import "a4.dart"; import "a3.dart";'
433 'export "a5.dart"; export "a9.dart"; part "a6.dart";';
434 expect(node.structureChanged, isFalse);
435 node.update(graph);
436 expect(node.structureChanged, isTrue);
437
438 // no change
439 node.structureChanged = false;
440 node.source.contents.modificationTime++;
441 node.update(graph);
442 expect(node.structureChanged, isFalse);
443
444 // removed one
445 node.source.contents.modificationTime++;
446 node.source.contents.data = 'import "a4.dart"; import "a3.dart"; '
447 'export "a5.dart"; part "a6.dart";';
448 expect(node.structureChanged, isFalse);
449 node.update(graph);
450 expect(node.structureChanged, isTrue);
451 });
452 });
453 });
454
455 group('refresh structure and marks', () {
456 test('initial marks', () {
457 var node = nodeOf('/index3.html');
458 expectGraph(node, 'index3.html');
459 refreshStructureAndMarks(node, graph);
460 expectGraph(node, '''
461 index3.html [needs-rebuild] [structure-changed]
462 |-- a2.dart [needs-rebuild] [structure-changed]
463 | |-- a3.dart [needs-rebuild]
464 | |-- a4.dart [needs-rebuild] [structure-changed]
465 | | |-- a10.dart [needs-rebuild]
466 | |-- a5.dart [needs-rebuild]
467 | |-- a6.dart [needs-rebuild]
468 ''');
469 });
470
471 test('cleared marks stay clear', () {
472 var node = nodeOf('/index3.html');
473 refreshStructureAndMarks(node, graph);
474 expectGraph(node, '''
475 index3.html [needs-rebuild] [structure-changed]
476 |-- a2.dart [needs-rebuild] [structure-changed]
477 | |-- a3.dart [needs-rebuild]
478 | |-- a4.dart [needs-rebuild] [structure-changed]
479 | | |-- a10.dart [needs-rebuild]
480 | |-- a5.dart [needs-rebuild]
481 | |-- a6.dart [needs-rebuild]
482 ''');
483 clearMarks(node);
484 expectGraph(node, '''
485 index3.html
486 |-- a2.dart
487 | |-- a3.dart
488 | |-- a4.dart
489 | | |-- a10.dart
490 | |-- a5.dart
491 | |-- a6.dart
492 ''');
493
494 refreshStructureAndMarks(node, graph);
495 expectGraph(node, '''
496 index3.html
497 |-- a2.dart
498 | |-- a3.dart
499 | |-- a4.dart
500 | | |-- a10.dart
501 | |-- a5.dart
502 | |-- a6.dart
503 ''');
504 });
505
506 test('needsRebuild mark updated on local modifications', () {
507 var node = nodeOf('/index3.html');
508 refreshStructureAndMarks(node, graph);
509 clearMarks(node);
510 var a3 = nodeOf('/a3.dart');
511 a3.source.contents.modificationTime++;
512
513 refreshStructureAndMarks(node, graph);
514 expectGraph(node, '''
515 index3.html
516 |-- a2.dart
517 | |-- a3.dart [needs-rebuild]
518 | |-- a4.dart
519 | | |-- a10.dart
520 | |-- a5.dart
521 | |-- a6.dart
522 ''');
523 });
524
525 test('structuredChanged mark updated on structure modifications', () {
526 var node = nodeOf('/index3.html');
527 refreshStructureAndMarks(node, graph);
528 clearMarks(node);
529 var a5 = nodeOf('/a5.dart');
530 a5.source.contents.modificationTime++;
531 a5.source.contents.data = 'import "a8.dart";';
532
533 refreshStructureAndMarks(node, graph);
534 expectGraph(node, '''
535 index3.html
536 |-- a2.dart
537 | |-- a3.dart
538 | |-- a4.dart
539 | | |-- a10.dart
540 | |-- a5.dart [needs-rebuild] [structure-changed]
541 | | |-- a8.dart [needs-rebuild] [structure-changed]
542 | | | |-- a8.dart...
543 | |-- a6.dart
544 ''');
545 });
546 });
547
548 group('rebuild', () {
549 var results;
550 void addName(SourceNode n) => results.add(nameFor(n));
551
552 bool buildNoTransitiveChange(SourceNode n) {
553 addName(n);
554 return false;
555 }
556
557 bool buildWithTransitiveChange(SourceNode n) {
558 addName(n);
559 return true;
560 }
561
562 setUp(() {
563 results = [];
564 });
565
566 test('everything build on first run', () {
567 var node = nodeOf('/index3.html');
568 rebuild(node, graph, buildNoTransitiveChange);
569 // Note: a6.dart is not included because it built as part of a2.dart
570 expect(results, [
571 'a3.dart',
572 'a10.dart',
573 'a4.dart',
574 'a5.dart',
575 'a2.dart',
576 'index3.html'
577 ]);
578
579 // Marks are removed automatically by rebuild
580 expectGraph(node, '''
581 index3.html
582 |-- a2.dart
583 | |-- a3.dart
584 | |-- a4.dart
585 | | |-- a10.dart
586 | |-- a5.dart
587 | |-- a6.dart
588 ''');
589 });
590
591 test('nothing to do after build', () {
592 var node = nodeOf('/index3.html');
593 rebuild(node, graph, buildNoTransitiveChange);
594
595 results = [];
596 rebuild(node, graph, buildNoTransitiveChange);
597 expect(results, []);
598 });
599
600 test('modified part triggers building library', () {
601 var node = nodeOf('/index3.html');
602 rebuild(node, graph, buildNoTransitiveChange);
603 results = [];
604
605 var a6 = nodeOf('/a6.dart');
606 a6.source.contents.modificationTime++;
607 rebuild(node, graph, buildNoTransitiveChange);
608 expect(results, ['a2.dart']);
609
610 results = [];
611 rebuild(node, graph, buildNoTransitiveChange);
612 expect(results, []);
613 });
614
615 test('non-API change triggers build stays local', () {
616 var node = nodeOf('/index3.html');
617 rebuild(node, graph, buildNoTransitiveChange);
618 results = [];
619
620 var a3 = nodeOf('/a3.dart');
621 a3.source.contents.modificationTime++;
622 rebuild(node, graph, buildNoTransitiveChange);
623 expect(results, ['a3.dart']);
624
625 results = [];
626 rebuild(node, graph, buildNoTransitiveChange);
627 expect(results, []);
628 });
629
630 test('no-API change in exported file stays local', () {
631 var node = nodeOf('/index3.html');
632 rebuild(node, graph, buildNoTransitiveChange);
633 results = [];
634
635 // similar to the test above, but a10 is exported from a4.
636 var a3 = nodeOf('/a10.dart');
637 a3.source.contents.modificationTime++;
638 rebuild(node, graph, buildNoTransitiveChange);
639 expect(results, ['a10.dart']);
640
641 results = [];
642 rebuild(node, graph, buildNoTransitiveChange);
643 expect(results, []);
644 });
645
646 test('API change in lib, triggers build on imports', () {
647 var node = nodeOf('/index3.html');
648 rebuild(node, graph, buildNoTransitiveChange);
649 results = [];
650
651 var a3 = nodeOf('/a3.dart');
652 a3.source.contents.modificationTime++;
653 rebuild(node, graph, buildWithTransitiveChange);
654 expect(results, ['a3.dart', 'a2.dart']);
655
656 results = [];
657 rebuild(node, graph, buildNoTransitiveChange);
658 expect(results, []);
659 });
660
661 test('API change in export, triggers build on imports', () {
662 var node = nodeOf('/index3.html');
663 rebuild(node, graph, buildNoTransitiveChange);
664 results = [];
665
666 var a3 = nodeOf('/a10.dart');
667 a3.source.contents.modificationTime++;
668 rebuild(node, graph, buildWithTransitiveChange);
669
670 // Node: a4.dart reexports a10.dart, but it doesn't import it, so we don't
671 // need to rebuild it.
672 expect(results, ['a10.dart', 'a2.dart']);
673
674 results = [];
675 rebuild(node, graph, buildNoTransitiveChange);
676 expect(results, []);
677 });
678
679 test('structural change rebuilds HTML, but skips unreachable code', () {
680 var node = nodeOf('/index3.html');
681 rebuild(node, graph, buildNoTransitiveChange);
682 results = [];
683
684 var a2 = nodeOf('/a2.dart');
685 a2.source.contents.modificationTime++;
686 a2.source.contents.data = 'import "a4.dart";';
687
688 var a3 = nodeOf('/a3.dart');
689 a3.source.contents.modificationTime++;
690 rebuild(node, graph, buildNoTransitiveChange);
691
692 // a3 will become unreachable, index3 reflects structural changes.
693 expect(results, ['a2.dart', 'index3.html']);
694
695 results = [];
696 rebuild(node, graph, buildNoTransitiveChange);
697 expect(results, []);
698 });
699
700 test('newly discovered files get built too', () {
701 var node = nodeOf('/index3.html');
702 rebuild(node, graph, buildNoTransitiveChange);
703 results = [];
704
705 var a2 = nodeOf('/a2.dart');
706 a2.source.contents.modificationTime++;
707 a2.source.contents.data = 'import "a9.dart";';
708
709 rebuild(node, graph, buildNoTransitiveChange);
710 expect(results, ['a8.dart', 'a9.dart', 'a2.dart', 'index3.html']);
711
712 results = [];
713 rebuild(node, graph, buildNoTransitiveChange);
714 expect(results, []);
715 });
716 });
717 }
718
719 expectGraph(SourceNode node, String expectation) {
720 expect(printReachable(node), equalsIgnoringWhitespace(expectation));
721 }
722
723 nameFor(SourceNode node) => path.basename(node.uri.path);
724 printReachable(SourceNode node) {
725 var seen = new Set();
726 var sb = new StringBuffer();
727 helper(n, {indent: 0}) {
728 if (indent > 0) {
729 sb
730 ..write("| " * (indent - 1))
731 ..write("|-- ");
732 }
733 sb.write(nameFor(n));
734 if (seen.contains(n)) {
735 sb.write('...\n');
736 return;
737 }
738 seen.add(n);
739 sb
740 ..write(' ')
741 ..write(n.needsRebuild ? '[needs-rebuild] ' : '')
742 ..write(n.structureChanged ? '[structure-changed] ' : ' ')
743 ..write('\n');
744 n.directDeps.forEach((e) => helper(e, indent: indent + 1));
745 }
746 helper(node);
747 return sb.toString();
748 }
749
750 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b);
OLDNEW
« no previous file with comments | « test/codegen_test.dart ('k') | test/end_to_end_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698