OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dev_compiler.test.dependency_graph_test; | 5 library dev_compiler.test.dependency_graph_test; |
6 | 6 |
7 import 'package:unittest/compact_vm_config.dart'; | 7 import 'package:unittest/compact_vm_config.dart'; |
8 import 'package:unittest/unittest.dart'; | 8 import 'package:unittest/unittest.dart'; |
9 | 9 |
10 import 'package:dev_compiler/src/checker/dart_sdk.dart' | 10 import 'package:dev_compiler/src/checker/dart_sdk.dart' |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 '/a3.dart': 'library a3;', | 48 '/a3.dart': 'library a3;', |
49 '/a4.dart': 'library a4; export "a10.dart";', | 49 '/a4.dart': 'library a4; export "a10.dart";', |
50 '/a5.dart': 'library a5;', | 50 '/a5.dart': 'library a5;', |
51 '/a6.dart': 'part of a2;', | 51 '/a6.dart': 'part of a2;', |
52 '/a7.dart': 'library a7;', | 52 '/a7.dart': 'library a7;', |
53 '/a8.dart': 'library a8; import "a8.dart";', | 53 '/a8.dart': 'library a8; import "a8.dart";', |
54 '/a9.dart': 'library a9; import "a8.dart";', | 54 '/a9.dart': 'library a9; import "a8.dart";', |
55 '/a10.dart': 'library a10;', | 55 '/a10.dart': 'library a10;', |
56 }; | 56 }; |
57 | 57 |
58 nodeOf(String filepath, [bool isPart = false]) => | 58 nodeOf(String filepath) => graph.nodeFromUri(new Uri.file(filepath)); |
59 graph.nodeFromUri(new Uri.file(filepath), isPart); | |
60 | 59 |
61 setUp(() { | 60 setUp(() { |
62 /// We completely reset the TestUriResolver to avoid interference between | 61 /// We completely reset the TestUriResolver to avoid interference between |
63 /// tests (since some tests modify the state of the files). | 62 /// tests (since some tests modify the state of the files). |
64 testUriResolver = new TestUriResolver(testFiles); | 63 testUriResolver = new TestUriResolver(testFiles); |
65 context = new TypeResolver.fromMock(mockSdkSources, options, | 64 context = new TypeResolver.fromMock(mockSdkSources, options, |
66 otherResolvers: [testUriResolver]).context; | 65 otherResolvers: [testUriResolver]).context; |
67 graph = new SourceGraph(context, options); | 66 graph = new SourceGraph(context, options); |
68 }); | 67 }); |
69 | 68 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 'import "a3.dart"; export "a7.dart"; part "a8.dart";'; | 190 'import "a3.dart"; export "a7.dart"; part "a8.dart";'; |
192 node.update(graph); | 191 node.update(graph); |
193 | 192 |
194 expect(node.imports.length, 1); | 193 expect(node.imports.length, 1); |
195 expect(node.exports.length, 1); | 194 expect(node.exports.length, 1); |
196 expect(node.parts.length, 1); | 195 expect(node.parts.length, 1); |
197 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 196 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); |
198 expect(node.exports.contains(nodeOf('/a7.dart')), isTrue); | 197 expect(node.exports.contains(nodeOf('/a7.dart')), isTrue); |
199 expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); | 198 expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); |
200 }); | 199 }); |
| 200 |
| 201 test('change part to library', () { |
| 202 var node = nodeOf('/a2.dart'); |
| 203 node.update(graph); |
| 204 expect(node.imports.length, 2); |
| 205 expect(node.exports.length, 1); |
| 206 expect(node.parts.length, 1); |
| 207 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); |
| 208 expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); |
| 209 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); |
| 210 expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); |
| 211 |
| 212 node.source.contents.modificationTime++; |
| 213 node.source.contents.data = ''' |
| 214 library a2; |
| 215 import 'a3.dart'; |
| 216 import 'a4.dart'; |
| 217 export 'a5.dart'; |
| 218 import 'a6.dart'; // changed from part |
| 219 '''; |
| 220 var a6 = nodeOf('/a6.dart'); |
| 221 a6.source.contents.modificationTime++; |
| 222 a6.source.contents.data = ''; |
| 223 node.update(graph); |
| 224 |
| 225 expect(node.imports.length, 3); |
| 226 expect(node.exports.length, 1); |
| 227 expect(node.parts.length, 0); |
| 228 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); |
| 229 expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); |
| 230 expect(node.imports.contains(nodeOf('/a6.dart')), isTrue); |
| 231 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); |
| 232 |
| 233 expect(a6.imports.length, 0); |
| 234 expect(a6.exports.length, 0); |
| 235 expect(a6.parts.length, 0); |
| 236 }); |
| 237 |
| 238 test('change library to part', () { |
| 239 var node = nodeOf('/a2.dart'); |
| 240 var a4 = nodeOf('/a4.dart'); |
| 241 node.update(graph); |
| 242 expect(node.imports.length, 2); |
| 243 expect(node.exports.length, 1); |
| 244 expect(node.parts.length, 1); |
| 245 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); |
| 246 expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); |
| 247 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); |
| 248 expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); |
| 249 |
| 250 a4.update(graph); |
| 251 expect(a4.imports.length, 0); |
| 252 expect(a4.exports.length, 1); |
| 253 expect(a4.parts.length, 0); |
| 254 |
| 255 node.source.contents.modificationTime++; |
| 256 node.source.contents.data = ''' |
| 257 library a2; |
| 258 import 'a3.dart'; |
| 259 part 'a4.dart'; // changed from export |
| 260 export 'a5.dart'; |
| 261 part 'a6.dart'; |
| 262 '''; |
| 263 node.update(graph); |
| 264 |
| 265 expect(node.imports.length, 1); |
| 266 expect(node.exports.length, 1); |
| 267 expect(node.parts.length, 2); |
| 268 expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); |
| 269 expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); |
| 270 expect(node.parts.contains(nodeOf('/a4.dart')), isTrue); |
| 271 expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); |
| 272 |
| 273 // Note, technically we never modified the contents of a4 and it contains |
| 274 // an export. This is invalid Dart, but we'll let the analyzer report that |
| 275 // error instead of doing so ourselves. |
| 276 expect(a4.imports.length, 0); |
| 277 expect(a4.exports.length, 1); |
| 278 expect(a4.parts.length, 0); |
| 279 |
| 280 // And change it back. |
| 281 node.source.contents.modificationTime++; |
| 282 node.source.contents.data = ''' |
| 283 library a2; |
| 284 import 'a3.dart'; |
| 285 import 'a4.dart'; // changed again |
| 286 export 'a5.dart'; |
| 287 part 'a6.dart'; |
| 288 '''; |
| 289 node.update(graph); |
| 290 expect(node.imports.contains(a4), isTrue); |
| 291 expect(a4.imports.length, 0); |
| 292 expect(a4.exports.length, 1); |
| 293 expect(a4.parts.length, 0); |
| 294 }); |
201 }); | 295 }); |
202 | 296 |
203 group('local changes', () { | 297 group('local changes', () { |
204 group('needs rebuild', () { | 298 group('needs rebuild', () { |
205 test('in HTML', () { | 299 test('in HTML', () { |
206 var node = nodeOf('/index1.html'); | 300 var node = nodeOf('/index1.html'); |
207 node.update(graph); | 301 node.update(graph); |
208 expect(node.needsRebuild, isTrue); | 302 expect(node.needsRebuild, isTrue); |
209 node.needsRebuild = false; | 303 node.needsRebuild = false; |
210 | 304 |
211 node.update(graph); | 305 node.update(graph); |
212 expect(node.needsRebuild, isFalse); | 306 expect(node.needsRebuild, isFalse); |
213 | 307 |
214 // For now, an empty modification is enough to trigger a rebuild | 308 // For now, an empty modification is enough to trigger a rebuild |
215 node.source.contents.modificationTime++; | 309 node.source.contents.modificationTime++; |
216 expect(node.needsRebuild, isFalse); | 310 expect(node.needsRebuild, isFalse); |
217 node.update(graph); | 311 node.update(graph); |
218 expect(node.needsRebuild, isTrue); | 312 expect(node.needsRebuild, isTrue); |
219 }); | 313 }); |
220 | 314 |
221 test('main library in Dart', () { | 315 test('main library in Dart', () { |
222 var node = nodeOf('/a2.dart'); | 316 var node = nodeOf('/a2.dart'); |
223 var partNode = nodeOf('/a6.dart', true); | 317 var partNode = nodeOf('/a6.dart'); |
224 node.update(graph); | 318 node.update(graph); |
225 expect(node.needsRebuild, isTrue); | 319 expect(node.needsRebuild, isTrue); |
226 node.needsRebuild = false; | 320 node.needsRebuild = false; |
227 partNode.needsRebuild = false; | 321 partNode.needsRebuild = false; |
228 | 322 |
229 node.update(graph); | 323 node.update(graph); |
230 expect(node.needsRebuild, isFalse); | 324 expect(node.needsRebuild, isFalse); |
231 | 325 |
232 // For now, an empty modification is enough to trigger a rebuild | 326 // For now, an empty modification is enough to trigger a rebuild |
233 node.source.contents.modificationTime++; | 327 node.source.contents.modificationTime++; |
234 expect(node.needsRebuild, isFalse); | 328 expect(node.needsRebuild, isFalse); |
235 node.update(graph); | 329 node.update(graph); |
236 expect(node.needsRebuild, isTrue); | 330 expect(node.needsRebuild, isTrue); |
237 }); | 331 }); |
238 | 332 |
239 test('part of library in Dart', () { | 333 test('part of library in Dart', () { |
240 var node = nodeOf('/a2.dart'); | 334 var node = nodeOf('/a2.dart'); |
241 var importNode = nodeOf('/a3.dart'); | 335 var importNode = nodeOf('/a3.dart'); |
242 var exportNode = nodeOf('/a5.dart'); | 336 var exportNode = nodeOf('/a5.dart'); |
243 var partNode = nodeOf('/a6.dart', true); | 337 var partNode = nodeOf('/a6.dart'); |
244 node.update(graph); | 338 node.update(graph); |
245 expect(node.needsRebuild, isTrue); | 339 expect(node.needsRebuild, isTrue); |
246 node.needsRebuild = false; | 340 node.needsRebuild = false; |
247 partNode.needsRebuild = false; | 341 partNode.needsRebuild = false; |
248 | 342 |
249 node.update(graph); | 343 node.update(graph); |
250 expect(node.needsRebuild, isFalse); | 344 expect(node.needsRebuild, isFalse); |
251 | 345 |
252 // Modification in imported/exported node makes no difference for local | 346 // Modification in imported/exported node makes no difference for local |
253 // rebuild label (globally that's tested elsewhere) | 347 // rebuild label (globally that's tested elsewhere) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 expect(node.structureChanged, isFalse); | 402 expect(node.structureChanged, isFalse); |
309 node.update(graph); | 403 node.update(graph); |
310 expect(node.structureChanged, isTrue); | 404 expect(node.structureChanged, isTrue); |
311 expect(node.scripts.length, 2); | 405 expect(node.scripts.length, 2); |
312 }); | 406 }); |
313 | 407 |
314 test('no mod in Dart', () { | 408 test('no mod in Dart', () { |
315 var node = nodeOf('/a2.dart'); | 409 var node = nodeOf('/a2.dart'); |
316 var importNode = nodeOf('/a3.dart'); | 410 var importNode = nodeOf('/a3.dart'); |
317 var exportNode = nodeOf('/a5.dart'); | 411 var exportNode = nodeOf('/a5.dart'); |
318 var partNode = nodeOf('/a6.dart', true); | 412 var partNode = nodeOf('/a6.dart'); |
319 node.update(graph); | 413 node.update(graph); |
320 expect(node.structureChanged, isTrue); | 414 expect(node.structureChanged, isTrue); |
321 node.structureChanged = false; | 415 node.structureChanged = false; |
322 | 416 |
323 node.update(graph); | 417 node.update(graph); |
324 expect(node.structureChanged, isFalse); | 418 expect(node.structureChanged, isFalse); |
325 | 419 |
326 // These modifications make no difference at all. | 420 // These modifications make no difference at all. |
327 importNode.source.contents.modificationTime++; | 421 importNode.source.contents.modificationTime++; |
328 exportNode.source.contents.modificationTime++; | 422 exportNode.source.contents.modificationTime++; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 var node = nodeOf('/index3.html'); | 552 var node = nodeOf('/index3.html'); |
459 expectGraph(node, 'index3.html'); | 553 expectGraph(node, 'index3.html'); |
460 refreshStructureAndMarks(node, graph); | 554 refreshStructureAndMarks(node, graph); |
461 expectGraph(node, ''' | 555 expectGraph(node, ''' |
462 index3.html [needs-rebuild] [structure-changed] | 556 index3.html [needs-rebuild] [structure-changed] |
463 |-- a2.dart [needs-rebuild] [structure-changed] | 557 |-- a2.dart [needs-rebuild] [structure-changed] |
464 | |-- a3.dart [needs-rebuild] | 558 | |-- a3.dart [needs-rebuild] |
465 | |-- a4.dart [needs-rebuild] [structure-changed] | 559 | |-- a4.dart [needs-rebuild] [structure-changed] |
466 | | |-- a10.dart [needs-rebuild] | 560 | | |-- a10.dart [needs-rebuild] |
467 | |-- a5.dart [needs-rebuild] | 561 | |-- a5.dart [needs-rebuild] |
468 | |-- a6.dart [needs-rebuild] | 562 | |-- a6.dart (part) [needs-rebuild] |
469 '''); | 563 '''); |
470 }); | 564 }); |
471 | 565 |
472 test('cleared marks stay clear', () { | 566 test('cleared marks stay clear', () { |
473 var node = nodeOf('/index3.html'); | 567 var node = nodeOf('/index3.html'); |
474 refreshStructureAndMarks(node, graph); | 568 refreshStructureAndMarks(node, graph); |
475 expectGraph(node, ''' | 569 expectGraph(node, ''' |
476 index3.html [needs-rebuild] [structure-changed] | 570 index3.html [needs-rebuild] [structure-changed] |
477 |-- a2.dart [needs-rebuild] [structure-changed] | 571 |-- a2.dart [needs-rebuild] [structure-changed] |
478 | |-- a3.dart [needs-rebuild] | 572 | |-- a3.dart [needs-rebuild] |
479 | |-- a4.dart [needs-rebuild] [structure-changed] | 573 | |-- a4.dart [needs-rebuild] [structure-changed] |
480 | | |-- a10.dart [needs-rebuild] | 574 | | |-- a10.dart [needs-rebuild] |
481 | |-- a5.dart [needs-rebuild] | 575 | |-- a5.dart [needs-rebuild] |
482 | |-- a6.dart [needs-rebuild] | 576 | |-- a6.dart (part) [needs-rebuild] |
483 '''); | 577 '''); |
484 clearMarks(node); | 578 clearMarks(node); |
485 expectGraph(node, ''' | 579 expectGraph(node, ''' |
486 index3.html | 580 index3.html |
487 |-- a2.dart | 581 |-- a2.dart |
488 | |-- a3.dart | 582 | |-- a3.dart |
489 | |-- a4.dart | 583 | |-- a4.dart |
490 | | |-- a10.dart | 584 | | |-- a10.dart |
491 | |-- a5.dart | 585 | |-- a5.dart |
492 | |-- a6.dart | 586 | |-- a6.dart (part) |
493 '''); | 587 '''); |
494 | 588 |
495 refreshStructureAndMarks(node, graph); | 589 refreshStructureAndMarks(node, graph); |
496 expectGraph(node, ''' | 590 expectGraph(node, ''' |
497 index3.html | 591 index3.html |
498 |-- a2.dart | 592 |-- a2.dart |
499 | |-- a3.dart | 593 | |-- a3.dart |
500 | |-- a4.dart | 594 | |-- a4.dart |
501 | | |-- a10.dart | 595 | | |-- a10.dart |
502 | |-- a5.dart | 596 | |-- a5.dart |
503 | |-- a6.dart | 597 | |-- a6.dart (part) |
504 '''); | 598 '''); |
505 }); | 599 }); |
506 | 600 |
507 test('needsRebuild mark updated on local modifications', () { | 601 test('needsRebuild mark updated on local modifications', () { |
508 var node = nodeOf('/index3.html'); | 602 var node = nodeOf('/index3.html'); |
509 refreshStructureAndMarks(node, graph); | 603 refreshStructureAndMarks(node, graph); |
510 clearMarks(node); | 604 clearMarks(node); |
511 var a3 = nodeOf('/a3.dart'); | 605 var a3 = nodeOf('/a3.dart'); |
512 a3.source.contents.modificationTime++; | 606 a3.source.contents.modificationTime++; |
513 | 607 |
514 refreshStructureAndMarks(node, graph); | 608 refreshStructureAndMarks(node, graph); |
515 expectGraph(node, ''' | 609 expectGraph(node, ''' |
516 index3.html | 610 index3.html |
517 |-- a2.dart | 611 |-- a2.dart |
518 | |-- a3.dart [needs-rebuild] | 612 | |-- a3.dart [needs-rebuild] |
519 | |-- a4.dart | 613 | |-- a4.dart |
520 | | |-- a10.dart | 614 | | |-- a10.dart |
521 | |-- a5.dart | 615 | |-- a5.dart |
522 | |-- a6.dart | 616 | |-- a6.dart (part) |
523 '''); | 617 '''); |
524 }); | 618 }); |
525 | 619 |
526 test('structuredChanged mark updated on structure modifications', () { | 620 test('structuredChanged mark updated on structure modifications', () { |
527 var node = nodeOf('/index3.html'); | 621 var node = nodeOf('/index3.html'); |
528 refreshStructureAndMarks(node, graph); | 622 refreshStructureAndMarks(node, graph); |
529 clearMarks(node); | 623 clearMarks(node); |
530 var a5 = nodeOf('/a5.dart'); | 624 var a5 = nodeOf('/a5.dart'); |
531 a5.source.contents.modificationTime++; | 625 a5.source.contents.modificationTime++; |
532 a5.source.contents.data = 'import "a8.dart";'; | 626 a5.source.contents.data = 'import "a8.dart";'; |
533 | 627 |
534 refreshStructureAndMarks(node, graph); | 628 refreshStructureAndMarks(node, graph); |
535 expectGraph(node, ''' | 629 expectGraph(node, ''' |
536 index3.html | 630 index3.html |
537 |-- a2.dart | 631 |-- a2.dart |
538 | |-- a3.dart | 632 | |-- a3.dart |
539 | |-- a4.dart | 633 | |-- a4.dart |
540 | | |-- a10.dart | 634 | | |-- a10.dart |
541 | |-- a5.dart [needs-rebuild] [structure-changed] | 635 | |-- a5.dart [needs-rebuild] [structure-changed] |
542 | | |-- a8.dart [needs-rebuild] [structure-changed] | 636 | | |-- a8.dart [needs-rebuild] [structure-changed] |
543 | | | |-- a8.dart... | 637 | | | |-- a8.dart... |
544 | |-- a6.dart | 638 | |-- a6.dart (part) |
545 '''); | 639 '''); |
546 }); | 640 }); |
547 }); | 641 }); |
548 | 642 |
549 group('rebuild', () { | 643 group('rebuild', () { |
550 var results; | 644 var results; |
551 void addName(SourceNode n) => results.add(nameFor(n)); | 645 void addName(SourceNode n) => results.add(nameFor(n)); |
552 | 646 |
553 bool buildNoTransitiveChange(SourceNode n) { | 647 bool buildNoTransitiveChange(SourceNode n) { |
554 addName(n); | 648 addName(n); |
(...skipping 23 matching lines...) Expand all Loading... |
578 ]); | 672 ]); |
579 | 673 |
580 // Marks are removed automatically by rebuild | 674 // Marks are removed automatically by rebuild |
581 expectGraph(node, ''' | 675 expectGraph(node, ''' |
582 index3.html | 676 index3.html |
583 |-- a2.dart | 677 |-- a2.dart |
584 | |-- a3.dart | 678 | |-- a3.dart |
585 | |-- a4.dart | 679 | |-- a4.dart |
586 | | |-- a10.dart | 680 | | |-- a10.dart |
587 | |-- a5.dart | 681 | |-- a5.dart |
588 | |-- a6.dart | 682 | |-- a6.dart (part) |
589 '''); | 683 '''); |
590 }); | 684 }); |
591 | 685 |
592 test('nothing to do after build', () { | 686 test('nothing to do after build', () { |
593 var node = nodeOf('/index3.html'); | 687 var node = nodeOf('/index3.html'); |
594 rebuild(node, graph, buildNoTransitiveChange); | 688 rebuild(node, graph, buildNoTransitiveChange); |
595 | 689 |
596 results = []; | 690 results = []; |
597 rebuild(node, graph, buildNoTransitiveChange); | 691 rebuild(node, graph, buildNoTransitiveChange); |
598 expect(results, []); | 692 expect(results, []); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 a2.source.contents.modificationTime++; | 801 a2.source.contents.modificationTime++; |
708 a2.source.contents.data = 'import "a9.dart";'; | 802 a2.source.contents.data = 'import "a9.dart";'; |
709 | 803 |
710 rebuild(node, graph, buildNoTransitiveChange); | 804 rebuild(node, graph, buildNoTransitiveChange); |
711 expect(results, ['a8.dart', 'a9.dart', 'a2.dart', 'index3.html']); | 805 expect(results, ['a8.dart', 'a9.dart', 'a2.dart', 'index3.html']); |
712 | 806 |
713 results = []; | 807 results = []; |
714 rebuild(node, graph, buildNoTransitiveChange); | 808 rebuild(node, graph, buildNoTransitiveChange); |
715 expect(results, []); | 809 expect(results, []); |
716 }); | 810 }); |
| 811 |
| 812 group('file upgrades', () { |
| 813 // Normally upgrading involves two changes: |
| 814 // (a) change the affected file |
| 815 // (b) change directive from part to import (or viceversa) |
| 816 // These could happen in any order and we should reach a consistent state |
| 817 // in the end. |
| 818 |
| 819 test('convert part to a library before updating the import', () { |
| 820 var node = nodeOf('/index3.html'); |
| 821 var a2 = nodeOf('/a2.dart'); |
| 822 var a6 = nodeOf('/a6.dart'); |
| 823 rebuild(node, graph, buildNoTransitiveChange); |
| 824 |
| 825 expectGraph(node, ''' |
| 826 index3.html |
| 827 |-- a2.dart |
| 828 | |-- a3.dart |
| 829 | |-- a4.dart |
| 830 | | |-- a10.dart |
| 831 | |-- a5.dart |
| 832 | |-- a6.dart (part) |
| 833 '''); |
| 834 |
| 835 // Modify the file first: |
| 836 a6.source.contents.modificationTime++; |
| 837 a6.source.contents.data = 'library a6; import "a5.dart";'; |
| 838 results = []; |
| 839 rebuild(node, graph, buildNoTransitiveChange); |
| 840 |
| 841 // Looks to us like a change in a part, we'll report errors that the |
| 842 // part is not really a part-file. Note that a6.dart is not included |
| 843 // below, because we don't build it as a library. |
| 844 expect(results, ['a2.dart']); |
| 845 expectGraph(node, ''' |
| 846 index3.html |
| 847 |-- a2.dart |
| 848 | |-- a3.dart |
| 849 | |-- a4.dart |
| 850 | | |-- a10.dart |
| 851 | |-- a5.dart |
| 852 | |-- a6.dart (part) |
| 853 '''); |
| 854 |
| 855 a2.source.contents.modificationTime++; |
| 856 a2.source.contents.data = ''' |
| 857 library a2; |
| 858 import 'a3.dart'; |
| 859 import 'a4.dart'; |
| 860 import 'a6.dart'; // properly import it |
| 861 export 'a5.dart'; |
| 862 '''; |
| 863 results = []; |
| 864 rebuild(node, graph, buildNoTransitiveChange); |
| 865 // Note that a6 is now included, because we haven't built it as a |
| 866 // library until now: |
| 867 expect(results, ['a6.dart', 'a2.dart', 'index3.html']); |
| 868 |
| 869 a6.source.contents.modificationTime++; |
| 870 results = []; |
| 871 rebuild(node, graph, buildNoTransitiveChange); |
| 872 expect(results, ['a6.dart']); |
| 873 |
| 874 expectGraph(node, ''' |
| 875 index3.html |
| 876 |-- a2.dart |
| 877 | |-- a3.dart |
| 878 | |-- a4.dart |
| 879 | | |-- a10.dart |
| 880 | |-- a6.dart |
| 881 | | |-- a5.dart |
| 882 | |-- a5.dart... |
| 883 '''); |
| 884 }); |
| 885 |
| 886 test('convert part to a library after updating the import', () { |
| 887 var node = nodeOf('/index3.html'); |
| 888 var a2 = nodeOf('/a2.dart'); |
| 889 var a6 = nodeOf('/a6.dart'); |
| 890 rebuild(node, graph, buildNoTransitiveChange); |
| 891 |
| 892 expectGraph(node, ''' |
| 893 index3.html |
| 894 |-- a2.dart |
| 895 | |-- a3.dart |
| 896 | |-- a4.dart |
| 897 | | |-- a10.dart |
| 898 | |-- a5.dart |
| 899 | |-- a6.dart (part) |
| 900 '''); |
| 901 |
| 902 a2.source.contents.modificationTime++; |
| 903 a2.source.contents.data = ''' |
| 904 library a2; |
| 905 import 'a3.dart'; |
| 906 import 'a4.dart'; |
| 907 import 'a6.dart'; // properly import it |
| 908 export 'a5.dart'; |
| 909 '''; |
| 910 results = []; |
| 911 rebuild(node, graph, buildNoTransitiveChange); |
| 912 expect(results, ['a6.dart', 'a2.dart', 'index3.html']); |
| 913 expectGraph(node, ''' |
| 914 index3.html |
| 915 |-- a2.dart |
| 916 | |-- a3.dart |
| 917 | |-- a4.dart |
| 918 | | |-- a10.dart |
| 919 | |-- a6.dart |
| 920 | |-- a5.dart |
| 921 '''); |
| 922 |
| 923 a6.source.contents.modificationTime++; |
| 924 a6.source.contents.data = 'library a6; import "a5.dart";'; |
| 925 results = []; |
| 926 rebuild(node, graph, buildNoTransitiveChange); |
| 927 expect(results, ['a6.dart', 'index3.html']); |
| 928 expectGraph(node, ''' |
| 929 index3.html |
| 930 |-- a2.dart |
| 931 | |-- a3.dart |
| 932 | |-- a4.dart |
| 933 | | |-- a10.dart |
| 934 | |-- a6.dart |
| 935 | | |-- a5.dart |
| 936 | |-- a5.dart... |
| 937 '''); |
| 938 }); |
| 939 |
| 940 test('disconnect part making it a library', () { |
| 941 var node = nodeOf('/index3.html'); |
| 942 var a2 = nodeOf('/a2.dart'); |
| 943 var a6 = nodeOf('/a6.dart'); |
| 944 rebuild(node, graph, buildNoTransitiveChange); |
| 945 |
| 946 expectGraph(node, ''' |
| 947 index3.html |
| 948 |-- a2.dart |
| 949 | |-- a3.dart |
| 950 | |-- a4.dart |
| 951 | | |-- a10.dart |
| 952 | |-- a5.dart |
| 953 | |-- a6.dart (part) |
| 954 '''); |
| 955 |
| 956 a2.source.contents.modificationTime++; |
| 957 a2.source.contents.data = ''' |
| 958 library a2; |
| 959 import 'a3.dart'; |
| 960 import 'a4.dart'; |
| 961 export 'a5.dart'; |
| 962 '''; |
| 963 a6.source.contents.modificationTime++; |
| 964 a6.source.contents.data = 'library a6; import "a5.dart";'; |
| 965 results = []; |
| 966 rebuild(node, graph, buildNoTransitiveChange); |
| 967 // a6 is not here, it's not reachable so we don't build it. |
| 968 expect(results, ['a2.dart', 'index3.html']); |
| 969 expectGraph(node, ''' |
| 970 index3.html |
| 971 |-- a2.dart |
| 972 | |-- a3.dart |
| 973 | |-- a4.dart |
| 974 | | |-- a10.dart |
| 975 | |-- a5.dart |
| 976 '''); |
| 977 }); |
| 978 |
| 979 test('convert a library to a part', () { |
| 980 var node = nodeOf('/index3.html'); |
| 981 var a2 = nodeOf('/a2.dart'); |
| 982 var a5 = nodeOf('/a5.dart'); |
| 983 rebuild(node, graph, buildNoTransitiveChange); |
| 984 |
| 985 expectGraph(node, ''' |
| 986 index3.html |
| 987 |-- a2.dart |
| 988 | |-- a3.dart |
| 989 | |-- a4.dart |
| 990 | | |-- a10.dart |
| 991 | |-- a5.dart |
| 992 | |-- a6.dart (part) |
| 993 '''); |
| 994 |
| 995 a2.source.contents.modificationTime++; |
| 996 a2.source.contents.data = ''' |
| 997 library a2; |
| 998 import 'a3.dart'; |
| 999 import 'a4.dart'; |
| 1000 part 'a5.dart'; // make it a part |
| 1001 part 'a6.dart'; |
| 1002 '''; |
| 1003 results = []; |
| 1004 rebuild(node, graph, buildNoTransitiveChange); |
| 1005 expect(results, ['a2.dart', 'index3.html']); |
| 1006 expectGraph(node, ''' |
| 1007 index3.html |
| 1008 |-- a2.dart |
| 1009 | |-- a3.dart |
| 1010 | |-- a4.dart |
| 1011 | | |-- a10.dart |
| 1012 | |-- a5.dart (part) |
| 1013 | |-- a6.dart (part) |
| 1014 '''); |
| 1015 |
| 1016 a5.source.contents.modificationTime++; |
| 1017 a5.source.contents.data = 'part of a2;'; |
| 1018 results = []; |
| 1019 rebuild(node, graph, buildNoTransitiveChange); |
| 1020 expect(results, ['a2.dart']); |
| 1021 expectGraph(node, ''' |
| 1022 index3.html |
| 1023 |-- a2.dart |
| 1024 | |-- a3.dart |
| 1025 | |-- a4.dart |
| 1026 | | |-- a10.dart |
| 1027 | |-- a5.dart (part) |
| 1028 | |-- a6.dart (part) |
| 1029 '''); |
| 1030 }); |
| 1031 }); |
717 }); | 1032 }); |
718 } | 1033 } |
719 | 1034 |
720 expectGraph(SourceNode node, String expectation) { | 1035 expectGraph(SourceNode node, String expectation) { |
721 expect(printReachable(node), equalsIgnoringWhitespace(expectation)); | 1036 expect(printReachable(node), equalsIgnoringWhitespace(expectation)); |
722 } | 1037 } |
723 | 1038 |
724 nameFor(SourceNode node) => path.basename(node.uri.path); | 1039 nameFor(SourceNode node) => path.basename(node.uri.path); |
725 printReachable(SourceNode node) { | 1040 printReachable(SourceNode node) { |
726 var seen = new Set(); | 1041 var seen = new Set(); |
727 var sb = new StringBuffer(); | 1042 var sb = new StringBuffer(); |
728 helper(n, {indent: 0}) { | 1043 helper(n, {indent: 0}) { |
729 if (indent > 0) { | 1044 if (indent > 0) { |
730 sb | 1045 sb |
731 ..write("| " * (indent - 1)) | 1046 ..write("| " * (indent - 1)) |
732 ..write("|-- "); | 1047 ..write("|-- "); |
733 } | 1048 } |
734 sb.write(nameFor(n)); | 1049 sb.write(nameFor(n)); |
735 if (seen.contains(n)) { | 1050 if (seen.contains(n)) { |
736 sb.write('...\n'); | 1051 sb.write('...\n'); |
737 return; | 1052 return; |
738 } | 1053 } |
739 seen.add(n); | 1054 seen.add(n); |
740 sb | 1055 sb |
741 ..write(' ') | 1056 ..write(' ') |
742 ..write(n.needsRebuild ? '[needs-rebuild] ' : '') | 1057 ..write(n.needsRebuild ? '[needs-rebuild] ' : '') |
743 ..write(n.structureChanged ? '[structure-changed] ' : ' ') | 1058 ..write(n.structureChanged ? '[structure-changed] ' : ' ') |
744 ..write('\n'); | 1059 ..write('\n'); |
745 n.directDeps.forEach((e) => helper(e, indent: indent + 1)); | 1060 n.depsWithoutParts.forEach((e) => helper(e, indent: indent + 1)); |
| 1061 if (n is DartSourceNode) { |
| 1062 n.parts.forEach((e) { |
| 1063 sb |
| 1064 ..write("| " * indent) |
| 1065 ..write("|-- ") |
| 1066 ..write(nameFor(e)) |
| 1067 ..write(" (part) ") |
| 1068 ..write(e.needsRebuild ? '[needs-rebuild] ' : '') |
| 1069 ..write(e.structureChanged ? '[structure-changed] ' : ' ') |
| 1070 ..write('\n'); |
| 1071 }); |
| 1072 } |
746 } | 1073 } |
747 helper(node); | 1074 helper(node); |
748 return sb.toString(); | 1075 return sb.toString(); |
749 } | 1076 } |
750 | 1077 |
751 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 1078 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); |
OLD | NEW |