| 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/unittest.dart'; | 7 import 'package:unittest/unittest.dart'; | 
| 8 | 8 | 
| 9 import 'package:dev_compiler/src/checker/dart_sdk.dart' | 9 import 'package:dev_compiler/src/checker/dart_sdk.dart' | 
| 10     show mockSdkSources, dartSdkDirectory; | 10     show mockSdkSources, dartSdkDirectory; | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 57   }; | 57   }; | 
| 58 | 58 | 
| 59   nodeOf(String filepath) => graph.nodeFromUri(new Uri.file(filepath)); | 59   nodeOf(String filepath) => graph.nodeFromUri(new Uri.file(filepath)); | 
| 60 | 60 | 
| 61   setUp(() { | 61   setUp(() { | 
| 62     /// We completely reset the TestUriResolver to avoid interference between | 62     /// We completely reset the TestUriResolver to avoid interference between | 
| 63     /// tests (since some tests modify the state of the files). | 63     /// tests (since some tests modify the state of the files). | 
| 64     testUriResolver = new InMemoryUriResolver(testFiles); | 64     testUriResolver = new InMemoryUriResolver(testFiles); | 
| 65     context = new TypeResolver.fromMock(mockSdkSources, options, | 65     context = new TypeResolver.fromMock(mockSdkSources, options, | 
| 66         otherResolvers: [testUriResolver]).context; | 66         otherResolvers: [testUriResolver]).context; | 
| 67     graph = new SourceGraph(context, new LogReporter(), options); | 67     graph = new SourceGraph(context, new LogReporter(context), options); | 
| 68   }); | 68   }); | 
| 69 | 69 | 
| 70   group('HTML deps', () { | 70   group('HTML deps', () { | 
| 71     test('initial deps', () { | 71     test('initial deps', () { | 
| 72       var i1 = nodeOf('/index1.html'); | 72       var i1 = nodeOf('/index1.html'); | 
| 73       var i2 = nodeOf('/index2.html'); | 73       var i2 = nodeOf('/index2.html'); | 
| 74       expect(i1.scripts.length, 0); | 74       expect(i1.scripts.length, 0); | 
| 75       expect(i2.scripts.length, 0); | 75       expect(i2.scripts.length, 0); | 
| 76       i1.update(graph); | 76       i1.update(); | 
| 77       i2.update(graph); | 77       i2.update(); | 
| 78       expect(i1.scripts.length, 0); | 78       expect(i1.scripts.length, 0); | 
| 79       expect(i2.scripts.length, 1); | 79       expect(i2.scripts.length, 1); | 
| 80       expect(i2.scripts.first, nodeOf('/a1.dart')); | 80       expect(i2.scripts.first, nodeOf('/a1.dart')); | 
| 81     }); | 81     }); | 
| 82 | 82 | 
| 83     test('add a dep', () { | 83     test('add a dep', () { | 
| 84       // After initial load, dependencies are 0: | 84       // After initial load, dependencies are 0: | 
| 85       var node = nodeOf('/index1.html'); | 85       var node = nodeOf('/index1.html'); | 
| 86       node.update(graph); | 86       node.update(); | 
| 87       expect(node.scripts.length, 0); | 87       expect(node.scripts.length, 0); | 
| 88 | 88 | 
| 89       // Adding the dependency is discovered on the next round of updates: | 89       // Adding the dependency is discovered on the next round of updates: | 
| 90       node.source.contents.modificationTime++; | 90       node.source.contents.modificationTime++; | 
| 91       node.source.contents.data = | 91       node.source.contents.data = | 
| 92           '<script type="application/dart" src="a2.dart"></script>'; | 92           '<script type="application/dart" src="a2.dart"></script>'; | 
| 93       expect(node.scripts.length, 0); | 93       expect(node.scripts.length, 0); | 
| 94       node.update(graph); | 94       node.update(); | 
| 95       expect(node.scripts.length, 1); | 95       expect(node.scripts.length, 1); | 
| 96       expect(node.scripts.first, nodeOf('/a2.dart')); | 96       expect(node.scripts.first, nodeOf('/a2.dart')); | 
| 97     }); | 97     }); | 
| 98 | 98 | 
| 99     test('add more deps', () { | 99     test('add more deps', () { | 
| 100       // After initial load, dependencies are 1: | 100       // After initial load, dependencies are 1: | 
| 101       var node = nodeOf('/index2.html'); | 101       var node = nodeOf('/index2.html'); | 
| 102       node.update(graph); | 102       node.update(); | 
| 103       expect(node.scripts.length, 1); | 103       expect(node.scripts.length, 1); | 
| 104       expect(node.scripts.first, nodeOf('/a1.dart')); | 104       expect(node.scripts.first, nodeOf('/a1.dart')); | 
| 105 | 105 | 
| 106       node.source.contents.modificationTime++; | 106       node.source.contents.modificationTime++; | 
| 107       node.source.contents.data += | 107       node.source.contents.data += | 
| 108           '<script type="application/dart" src="a2.dart"></script>'; | 108           '<script type="application/dart" src="a2.dart"></script>'; | 
| 109       expect(node.scripts.length, 1); | 109       expect(node.scripts.length, 1); | 
| 110       node.update(graph); | 110       node.update(); | 
| 111       expect(node.scripts.length, 2); | 111       expect(node.scripts.length, 2); | 
| 112       expect(node.scripts.first, nodeOf('/a1.dart')); | 112       expect(node.scripts.first, nodeOf('/a1.dart')); | 
| 113       expect(node.scripts.last, nodeOf('/a2.dart')); | 113       expect(node.scripts.last, nodeOf('/a2.dart')); | 
| 114     }); | 114     }); | 
| 115 | 115 | 
| 116     test('remove all deps', () { | 116     test('remove all deps', () { | 
| 117       // After initial load, dependencies are 1: | 117       // After initial load, dependencies are 1: | 
| 118       var node = nodeOf('/index2.html'); | 118       var node = nodeOf('/index2.html'); | 
| 119       node.update(graph); | 119       node.update(); | 
| 120       expect(node.scripts.length, 1); | 120       expect(node.scripts.length, 1); | 
| 121       expect(node.scripts.first, nodeOf('/a1.dart')); | 121       expect(node.scripts.first, nodeOf('/a1.dart')); | 
| 122 | 122 | 
| 123       // Removing the dependency is discovered on the next round of updates: | 123       // Removing the dependency is discovered on the next round of updates: | 
| 124       node.source.contents.modificationTime++; | 124       node.source.contents.modificationTime++; | 
| 125       node.source.contents.data = ''; | 125       node.source.contents.data = ''; | 
| 126       expect(node.scripts.length, 1); | 126       expect(node.scripts.length, 1); | 
| 127       node.update(graph); | 127       node.update(); | 
| 128       expect(node.scripts.length, 0); | 128       expect(node.scripts.length, 0); | 
| 129     }); | 129     }); | 
| 130   }); | 130   }); | 
| 131 | 131 | 
| 132   group('Dart deps', () { | 132   group('Dart deps', () { | 
| 133     test('initial deps', () { | 133     test('initial deps', () { | 
| 134       var a1 = nodeOf('/a1.dart'); | 134       var a1 = nodeOf('/a1.dart'); | 
| 135       var a2 = nodeOf('/a2.dart'); | 135       var a2 = nodeOf('/a2.dart'); | 
| 136       expect(a1.imports.length, 0); | 136       expect(a1.imports.length, 0); | 
| 137       expect(a1.exports.length, 0); | 137       expect(a1.exports.length, 0); | 
| 138       expect(a1.parts.length, 0); | 138       expect(a1.parts.length, 0); | 
| 139       expect(a2.imports.length, 0); | 139       expect(a2.imports.length, 0); | 
| 140       expect(a2.exports.length, 0); | 140       expect(a2.exports.length, 0); | 
| 141       expect(a2.parts.length, 0); | 141       expect(a2.parts.length, 0); | 
| 142 | 142 | 
| 143       a1.update(graph); | 143       a1.update(); | 
| 144       a2.update(graph); | 144       a2.update(); | 
| 145 | 145 | 
| 146       expect(a1.imports.length, 0); | 146       expect(a1.imports.length, 0); | 
| 147       expect(a1.exports.length, 0); | 147       expect(a1.exports.length, 0); | 
| 148       expect(a1.parts.length, 0); | 148       expect(a1.parts.length, 0); | 
| 149       expect(a2.imports.length, 2); | 149       expect(a2.imports.length, 2); | 
| 150       expect(a2.exports.length, 1); | 150       expect(a2.exports.length, 1); | 
| 151       expect(a2.parts.length, 1); | 151       expect(a2.parts.length, 1); | 
| 152       expect(a2.imports.contains(nodeOf('/a3.dart')), isTrue); | 152       expect(a2.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 153       expect(a2.imports.contains(nodeOf('/a4.dart')), isTrue); | 153       expect(a2.imports.contains(nodeOf('/a4.dart')), isTrue); | 
| 154       expect(a2.exports.contains(nodeOf('/a5.dart')), isTrue); | 154       expect(a2.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 155       expect(a2.parts.contains(nodeOf('/a6.dart')), isTrue); | 155       expect(a2.parts.contains(nodeOf('/a6.dart')), isTrue); | 
| 156     }); | 156     }); | 
| 157 | 157 | 
| 158     test('add deps', () { | 158     test('add deps', () { | 
| 159       var node = nodeOf('/a1.dart'); | 159       var node = nodeOf('/a1.dart'); | 
| 160       node.update(graph); | 160       node.update(); | 
| 161       expect(node.imports.length, 0); | 161       expect(node.imports.length, 0); | 
| 162       expect(node.exports.length, 0); | 162       expect(node.exports.length, 0); | 
| 163       expect(node.parts.length, 0); | 163       expect(node.parts.length, 0); | 
| 164 | 164 | 
| 165       node.source.contents.modificationTime++; | 165       node.source.contents.modificationTime++; | 
| 166       node.source.contents.data = | 166       node.source.contents.data = | 
| 167           'import "a3.dart"; export "a5.dart"; part "a8.dart";'; | 167           'import "a3.dart"; export "a5.dart"; part "a8.dart";'; | 
| 168       node.update(graph); | 168       node.update(); | 
| 169 | 169 | 
| 170       expect(node.imports.length, 1); | 170       expect(node.imports.length, 1); | 
| 171       expect(node.exports.length, 1); | 171       expect(node.exports.length, 1); | 
| 172       expect(node.parts.length, 1); | 172       expect(node.parts.length, 1); | 
| 173       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 173       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 174       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 174       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 175       expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); | 175       expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); | 
| 176     }); | 176     }); | 
| 177 | 177 | 
| 178     test('remove deps', () { | 178     test('remove deps', () { | 
| 179       var node = nodeOf('/a2.dart'); | 179       var node = nodeOf('/a2.dart'); | 
| 180       node.update(graph); | 180       node.update(); | 
| 181       expect(node.imports.length, 2); | 181       expect(node.imports.length, 2); | 
| 182       expect(node.exports.length, 1); | 182       expect(node.exports.length, 1); | 
| 183       expect(node.parts.length, 1); | 183       expect(node.parts.length, 1); | 
| 184       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 184       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 185       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 185       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 
| 186       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 186       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 187       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 187       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 
| 188 | 188 | 
| 189       node.source.contents.modificationTime++; | 189       node.source.contents.modificationTime++; | 
| 190       node.source.contents.data = | 190       node.source.contents.data = | 
| 191           'import "a3.dart"; export "a7.dart"; part "a8.dart";'; | 191           'import "a3.dart"; export "a7.dart"; part "a8.dart";'; | 
| 192       node.update(graph); | 192       node.update(); | 
| 193 | 193 | 
| 194       expect(node.imports.length, 1); | 194       expect(node.imports.length, 1); | 
| 195       expect(node.exports.length, 1); | 195       expect(node.exports.length, 1); | 
| 196       expect(node.parts.length, 1); | 196       expect(node.parts.length, 1); | 
| 197       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 197       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 198       expect(node.exports.contains(nodeOf('/a7.dart')), isTrue); | 198       expect(node.exports.contains(nodeOf('/a7.dart')), isTrue); | 
| 199       expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); | 199       expect(node.parts.contains(nodeOf('/a8.dart')), isTrue); | 
| 200     }); | 200     }); | 
| 201 | 201 | 
| 202     test('change part to library', () { | 202     test('change part to library', () { | 
| 203       var node = nodeOf('/a2.dart'); | 203       var node = nodeOf('/a2.dart'); | 
| 204       node.update(graph); | 204       node.update(); | 
| 205       expect(node.imports.length, 2); | 205       expect(node.imports.length, 2); | 
| 206       expect(node.exports.length, 1); | 206       expect(node.exports.length, 1); | 
| 207       expect(node.parts.length, 1); | 207       expect(node.parts.length, 1); | 
| 208       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 208       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 209       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 209       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 
| 210       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 210       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 211       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 211       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 
| 212 | 212 | 
| 213       node.source.contents.modificationTime++; | 213       node.source.contents.modificationTime++; | 
| 214       node.source.contents.data = ''' | 214       node.source.contents.data = ''' | 
| 215           library a2; | 215           library a2; | 
| 216           import 'a3.dart'; | 216           import 'a3.dart'; | 
| 217           import 'a4.dart'; | 217           import 'a4.dart'; | 
| 218           export 'a5.dart'; | 218           export 'a5.dart'; | 
| 219           import 'a6.dart'; // changed from part | 219           import 'a6.dart'; // changed from part | 
| 220         '''; | 220         '''; | 
| 221       var a6 = nodeOf('/a6.dart'); | 221       var a6 = nodeOf('/a6.dart'); | 
| 222       a6.source.contents.modificationTime++; | 222       a6.source.contents.modificationTime++; | 
| 223       a6.source.contents.data = ''; | 223       a6.source.contents.data = ''; | 
| 224       node.update(graph); | 224       node.update(); | 
| 225 | 225 | 
| 226       expect(node.imports.length, 3); | 226       expect(node.imports.length, 3); | 
| 227       expect(node.exports.length, 1); | 227       expect(node.exports.length, 1); | 
| 228       expect(node.parts.length, 0); | 228       expect(node.parts.length, 0); | 
| 229       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 229       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 230       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 230       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 
| 231       expect(node.imports.contains(nodeOf('/a6.dart')), isTrue); | 231       expect(node.imports.contains(nodeOf('/a6.dart')), isTrue); | 
| 232       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 232       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 233 | 233 | 
| 234       expect(a6.imports.length, 0); | 234       expect(a6.imports.length, 0); | 
| 235       expect(a6.exports.length, 0); | 235       expect(a6.exports.length, 0); | 
| 236       expect(a6.parts.length, 0); | 236       expect(a6.parts.length, 0); | 
| 237     }); | 237     }); | 
| 238 | 238 | 
| 239     test('change library to part', () { | 239     test('change library to part', () { | 
| 240       var node = nodeOf('/a2.dart'); | 240       var node = nodeOf('/a2.dart'); | 
| 241       var a4 = nodeOf('/a4.dart'); | 241       var a4 = nodeOf('/a4.dart'); | 
| 242       node.update(graph); | 242       node.update(); | 
| 243       expect(node.imports.length, 2); | 243       expect(node.imports.length, 2); | 
| 244       expect(node.exports.length, 1); | 244       expect(node.exports.length, 1); | 
| 245       expect(node.parts.length, 1); | 245       expect(node.parts.length, 1); | 
| 246       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 246       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 247       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 247       expect(node.imports.contains(nodeOf('/a4.dart')), isTrue); | 
| 248       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 248       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 249       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 249       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 
| 250 | 250 | 
| 251       a4.update(graph); | 251       a4.update(); | 
| 252       expect(a4.imports.length, 0); | 252       expect(a4.imports.length, 0); | 
| 253       expect(a4.exports.length, 1); | 253       expect(a4.exports.length, 1); | 
| 254       expect(a4.parts.length, 0); | 254       expect(a4.parts.length, 0); | 
| 255 | 255 | 
| 256       node.source.contents.modificationTime++; | 256       node.source.contents.modificationTime++; | 
| 257       node.source.contents.data = ''' | 257       node.source.contents.data = ''' | 
| 258           library a2; | 258           library a2; | 
| 259           import 'a3.dart'; | 259           import 'a3.dart'; | 
| 260           part 'a4.dart'; // changed from export | 260           part 'a4.dart'; // changed from export | 
| 261           export 'a5.dart'; | 261           export 'a5.dart'; | 
| 262           part 'a6.dart'; | 262           part 'a6.dart'; | 
| 263         '''; | 263         '''; | 
| 264       node.update(graph); | 264       node.update(); | 
| 265 | 265 | 
| 266       expect(node.imports.length, 1); | 266       expect(node.imports.length, 1); | 
| 267       expect(node.exports.length, 1); | 267       expect(node.exports.length, 1); | 
| 268       expect(node.parts.length, 2); | 268       expect(node.parts.length, 2); | 
| 269       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 269       expect(node.imports.contains(nodeOf('/a3.dart')), isTrue); | 
| 270       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 270       expect(node.exports.contains(nodeOf('/a5.dart')), isTrue); | 
| 271       expect(node.parts.contains(nodeOf('/a4.dart')), isTrue); | 271       expect(node.parts.contains(nodeOf('/a4.dart')), isTrue); | 
| 272       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 272       expect(node.parts.contains(nodeOf('/a6.dart')), isTrue); | 
| 273 | 273 | 
| 274       // Note, technically we never modified the contents of a4 and it contains | 274       // Note, technically we never modified the contents of a4 and it contains | 
| 275       // an export. This is invalid Dart, but we'll let the analyzer report that | 275       // an export. This is invalid Dart, but we'll let the analyzer report that | 
| 276       // error instead of doing so ourselves. | 276       // error instead of doing so ourselves. | 
| 277       expect(a4.imports.length, 0); | 277       expect(a4.imports.length, 0); | 
| 278       expect(a4.exports.length, 1); | 278       expect(a4.exports.length, 1); | 
| 279       expect(a4.parts.length, 0); | 279       expect(a4.parts.length, 0); | 
| 280 | 280 | 
| 281       // And change it back. | 281       // And change it back. | 
| 282       node.source.contents.modificationTime++; | 282       node.source.contents.modificationTime++; | 
| 283       node.source.contents.data = ''' | 283       node.source.contents.data = ''' | 
| 284           library a2; | 284           library a2; | 
| 285           import 'a3.dart'; | 285           import 'a3.dart'; | 
| 286           import 'a4.dart'; // changed again | 286           import 'a4.dart'; // changed again | 
| 287           export 'a5.dart'; | 287           export 'a5.dart'; | 
| 288           part 'a6.dart'; | 288           part 'a6.dart'; | 
| 289         '''; | 289         '''; | 
| 290       node.update(graph); | 290       node.update(); | 
| 291       expect(node.imports.contains(a4), isTrue); | 291       expect(node.imports.contains(a4), isTrue); | 
| 292       expect(a4.imports.length, 0); | 292       expect(a4.imports.length, 0); | 
| 293       expect(a4.exports.length, 1); | 293       expect(a4.exports.length, 1); | 
| 294       expect(a4.parts.length, 0); | 294       expect(a4.parts.length, 0); | 
| 295     }); | 295     }); | 
| 296   }); | 296   }); | 
| 297 | 297 | 
| 298   group('local changes', () { | 298   group('local changes', () { | 
| 299     group('needs rebuild', () { | 299     group('needs rebuild', () { | 
| 300       test('in HTML', () { | 300       test('in HTML', () { | 
| 301         var node = nodeOf('/index1.html'); | 301         var node = nodeOf('/index1.html'); | 
| 302         node.update(graph); | 302         node.update(); | 
| 303         expect(node.needsRebuild, isTrue); | 303         expect(node.needsRebuild, isTrue); | 
| 304         node.needsRebuild = false; | 304         node.needsRebuild = false; | 
| 305 | 305 | 
| 306         node.update(graph); | 306         node.update(); | 
| 307         expect(node.needsRebuild, isFalse); | 307         expect(node.needsRebuild, isFalse); | 
| 308 | 308 | 
| 309         // For now, an empty modification is enough to trigger a rebuild | 309         // For now, an empty modification is enough to trigger a rebuild | 
| 310         node.source.contents.modificationTime++; | 310         node.source.contents.modificationTime++; | 
| 311         expect(node.needsRebuild, isFalse); | 311         expect(node.needsRebuild, isFalse); | 
| 312         node.update(graph); | 312         node.update(); | 
| 313         expect(node.needsRebuild, isTrue); | 313         expect(node.needsRebuild, isTrue); | 
| 314       }); | 314       }); | 
| 315 | 315 | 
| 316       test('main library in Dart', () { | 316       test('main library in Dart', () { | 
| 317         var node = nodeOf('/a2.dart'); | 317         var node = nodeOf('/a2.dart'); | 
| 318         var partNode = nodeOf('/a6.dart'); | 318         var partNode = nodeOf('/a6.dart'); | 
| 319         node.update(graph); | 319         node.update(); | 
| 320         expect(node.needsRebuild, isTrue); | 320         expect(node.needsRebuild, isTrue); | 
| 321         node.needsRebuild = false; | 321         node.needsRebuild = false; | 
| 322         partNode.needsRebuild = false; | 322         partNode.needsRebuild = false; | 
| 323 | 323 | 
| 324         node.update(graph); | 324         node.update(); | 
| 325         expect(node.needsRebuild, isFalse); | 325         expect(node.needsRebuild, isFalse); | 
| 326 | 326 | 
| 327         // For now, an empty modification is enough to trigger a rebuild | 327         // For now, an empty modification is enough to trigger a rebuild | 
| 328         node.source.contents.modificationTime++; | 328         node.source.contents.modificationTime++; | 
| 329         expect(node.needsRebuild, isFalse); | 329         expect(node.needsRebuild, isFalse); | 
| 330         node.update(graph); | 330         node.update(); | 
| 331         expect(node.needsRebuild, isTrue); | 331         expect(node.needsRebuild, isTrue); | 
| 332       }); | 332       }); | 
| 333 | 333 | 
| 334       test('part of library in Dart', () { | 334       test('part of library in Dart', () { | 
| 335         var node = nodeOf('/a2.dart'); | 335         var node = nodeOf('/a2.dart'); | 
| 336         var importNode = nodeOf('/a3.dart'); | 336         var importNode = nodeOf('/a3.dart'); | 
| 337         var exportNode = nodeOf('/a5.dart'); | 337         var exportNode = nodeOf('/a5.dart'); | 
| 338         var partNode = nodeOf('/a6.dart'); | 338         var partNode = nodeOf('/a6.dart'); | 
| 339         node.update(graph); | 339         node.update(); | 
| 340         expect(node.needsRebuild, isTrue); | 340         expect(node.needsRebuild, isTrue); | 
| 341         node.needsRebuild = false; | 341         node.needsRebuild = false; | 
| 342         partNode.needsRebuild = false; | 342         partNode.needsRebuild = false; | 
| 343 | 343 | 
| 344         node.update(graph); | 344         node.update(); | 
| 345         expect(node.needsRebuild, isFalse); | 345         expect(node.needsRebuild, isFalse); | 
| 346 | 346 | 
| 347         // Modification in imported/exported node makes no difference for local | 347         // Modification in imported/exported node makes no difference for local | 
| 348         // rebuild label (globally that's tested elsewhere) | 348         // rebuild label (globally that's tested elsewhere) | 
| 349         importNode.source.contents.modificationTime++; | 349         importNode.source.contents.modificationTime++; | 
| 350         exportNode.source.contents.modificationTime++; | 350         exportNode.source.contents.modificationTime++; | 
| 351         node.update(graph); | 351         node.update(); | 
| 352         expect(node.needsRebuild, isFalse); | 352         expect(node.needsRebuild, isFalse); | 
| 353         expect(partNode.needsRebuild, isFalse); | 353         expect(partNode.needsRebuild, isFalse); | 
| 354 | 354 | 
| 355         // Modification in part triggers change in containing library: | 355         // Modification in part triggers change in containing library: | 
| 356         partNode.source.contents.modificationTime++; | 356         partNode.source.contents.modificationTime++; | 
| 357         expect(node.needsRebuild, isFalse); | 357         expect(node.needsRebuild, isFalse); | 
| 358         expect(partNode.needsRebuild, isFalse); | 358         expect(partNode.needsRebuild, isFalse); | 
| 359         node.update(graph); | 359         node.update(); | 
| 360         expect(node.needsRebuild, isTrue); | 360         expect(node.needsRebuild, isTrue); | 
| 361         expect(partNode.needsRebuild, isTrue); | 361         expect(partNode.needsRebuild, isTrue); | 
| 362       }); | 362       }); | 
| 363     }); | 363     }); | 
| 364 | 364 | 
| 365     group('structure change', () { | 365     group('structure change', () { | 
| 366       test('no mod in HTML', () { | 366       test('no mod in HTML', () { | 
| 367         var node = nodeOf('/index2.html'); | 367         var node = nodeOf('/index2.html'); | 
| 368         node.update(graph); | 368         node.update(); | 
| 369         expect(node.structureChanged, isTrue); | 369         expect(node.structureChanged, isTrue); | 
| 370         node.structureChanged = false; | 370         node.structureChanged = false; | 
| 371 | 371 | 
| 372         node.update(graph); | 372         node.update(); | 
| 373         expect(node.structureChanged, isFalse); | 373         expect(node.structureChanged, isFalse); | 
| 374 | 374 | 
| 375         // An empty modification will not trigger a structural change | 375         // An empty modification will not trigger a structural change | 
| 376         node.source.contents.modificationTime++; | 376         node.source.contents.modificationTime++; | 
| 377         expect(node.structureChanged, isFalse); | 377         expect(node.structureChanged, isFalse); | 
| 378         node.update(graph); | 378         node.update(); | 
| 379         expect(node.structureChanged, isFalse); | 379         expect(node.structureChanged, isFalse); | 
| 380       }); | 380       }); | 
| 381 | 381 | 
| 382       test('added scripts in HTML', () { | 382       test('added scripts in HTML', () { | 
| 383         var node = nodeOf('/index2.html'); | 383         var node = nodeOf('/index2.html'); | 
| 384         node.update(graph); | 384         node.update(); | 
| 385         expect(node.structureChanged, isTrue); | 385         expect(node.structureChanged, isTrue); | 
| 386         expect(node.scripts.length, 1); | 386         expect(node.scripts.length, 1); | 
| 387 | 387 | 
| 388         node.structureChanged = false; | 388         node.structureChanged = false; | 
| 389         node.update(graph); | 389         node.update(); | 
| 390         expect(node.structureChanged, isFalse); | 390         expect(node.structureChanged, isFalse); | 
| 391 | 391 | 
| 392         // This change will not include new script tags: | 392         // This change will not include new script tags: | 
| 393         node.source.contents.modificationTime++; | 393         node.source.contents.modificationTime++; | 
| 394         node.source.contents.data += '<div></div>'; | 394         node.source.contents.data += '<div></div>'; | 
| 395         expect(node.structureChanged, isFalse); | 395         expect(node.structureChanged, isFalse); | 
| 396         node.update(graph); | 396         node.update(); | 
| 397         expect(node.structureChanged, isFalse); | 397         expect(node.structureChanged, isFalse); | 
| 398         expect(node.scripts.length, 1); | 398         expect(node.scripts.length, 1); | 
| 399 | 399 | 
| 400         node.source.contents.modificationTime++; | 400         node.source.contents.modificationTime++; | 
| 401         node.source.contents.data += | 401         node.source.contents.data += | 
| 402             '<script type="application/dart" src="a4.dart"></script>'; | 402             '<script type="application/dart" src="a4.dart"></script>'; | 
| 403         expect(node.structureChanged, isFalse); | 403         expect(node.structureChanged, isFalse); | 
| 404         node.update(graph); | 404         node.update(); | 
| 405         expect(node.structureChanged, isTrue); | 405         expect(node.structureChanged, isTrue); | 
| 406         expect(node.scripts.length, 2); | 406         expect(node.scripts.length, 2); | 
| 407       }); | 407       }); | 
| 408 | 408 | 
| 409       test('no mod in Dart', () { | 409       test('no mod in Dart', () { | 
| 410         var node = nodeOf('/a2.dart'); | 410         var node = nodeOf('/a2.dart'); | 
| 411         var importNode = nodeOf('/a3.dart'); | 411         var importNode = nodeOf('/a3.dart'); | 
| 412         var exportNode = nodeOf('/a5.dart'); | 412         var exportNode = nodeOf('/a5.dart'); | 
| 413         var partNode = nodeOf('/a6.dart'); | 413         var partNode = nodeOf('/a6.dart'); | 
| 414         node.update(graph); | 414         node.update(); | 
| 415         expect(node.structureChanged, isTrue); | 415         expect(node.structureChanged, isTrue); | 
| 416         node.structureChanged = false; | 416         node.structureChanged = false; | 
| 417 | 417 | 
| 418         node.update(graph); | 418         node.update(); | 
| 419         expect(node.structureChanged, isFalse); | 419         expect(node.structureChanged, isFalse); | 
| 420 | 420 | 
| 421         // These modifications make no difference at all. | 421         // These modifications make no difference at all. | 
| 422         importNode.source.contents.modificationTime++; | 422         importNode.source.contents.modificationTime++; | 
| 423         exportNode.source.contents.modificationTime++; | 423         exportNode.source.contents.modificationTime++; | 
| 424         partNode.source.contents.modificationTime++; | 424         partNode.source.contents.modificationTime++; | 
| 425         node.source.contents.modificationTime++; | 425         node.source.contents.modificationTime++; | 
| 426 | 426 | 
| 427         expect(node.structureChanged, isFalse); | 427         expect(node.structureChanged, isFalse); | 
| 428         node.update(graph); | 428         node.update(); | 
| 429         expect(node.structureChanged, isFalse); | 429         expect(node.structureChanged, isFalse); | 
| 430       }); | 430       }); | 
| 431 | 431 | 
| 432       test('same directives, different order', () { | 432       test('same directives, different order', () { | 
| 433         var node = nodeOf('/a2.dart'); | 433         var node = nodeOf('/a2.dart'); | 
| 434         node.update(graph); | 434         node.update(); | 
| 435         expect(node.structureChanged, isTrue); | 435         expect(node.structureChanged, isTrue); | 
| 436         node.structureChanged = false; | 436         node.structureChanged = false; | 
| 437 | 437 | 
| 438         node.update(graph); | 438         node.update(); | 
| 439         expect(node.structureChanged, isFalse); | 439         expect(node.structureChanged, isFalse); | 
| 440 | 440 | 
| 441         // modified order of imports, but structure stays the same: | 441         // modified order of imports, but structure stays the same: | 
| 442         node.source.contents.modificationTime++; | 442         node.source.contents.modificationTime++; | 
| 443         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 443         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 
| 444             'export "a5.dart"; part "a6.dart";'; | 444             'export "a5.dart"; part "a6.dart";'; | 
| 445         node.update(graph); | 445         node.update(); | 
| 446 | 446 | 
| 447         expect(node.structureChanged, isFalse); | 447         expect(node.structureChanged, isFalse); | 
| 448         node.update(graph); | 448         node.update(); | 
| 449         expect(node.structureChanged, isFalse); | 449         expect(node.structureChanged, isFalse); | 
| 450       }); | 450       }); | 
| 451 | 451 | 
| 452       test('changed parts', () { | 452       test('changed parts', () { | 
| 453         var node = nodeOf('/a2.dart'); | 453         var node = nodeOf('/a2.dart'); | 
| 454         node.update(graph); | 454         node.update(); | 
| 455         expect(node.structureChanged, isTrue); | 455         expect(node.structureChanged, isTrue); | 
| 456         node.structureChanged = false; | 456         node.structureChanged = false; | 
| 457 | 457 | 
| 458         node.update(graph); | 458         node.update(); | 
| 459         expect(node.structureChanged, isFalse); | 459         expect(node.structureChanged, isFalse); | 
| 460 | 460 | 
| 461         // added one. | 461         // added one. | 
| 462         node.source.contents.modificationTime++; | 462         node.source.contents.modificationTime++; | 
| 463         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 463         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 
| 464             'export "a5.dart"; part "a6.dart"; part "a7.dart";'; | 464             'export "a5.dart"; part "a6.dart"; part "a7.dart";'; | 
| 465         expect(node.structureChanged, isFalse); | 465         expect(node.structureChanged, isFalse); | 
| 466         node.update(graph); | 466         node.update(); | 
| 467         expect(node.structureChanged, isTrue); | 467         expect(node.structureChanged, isTrue); | 
| 468 | 468 | 
| 469         // no change | 469         // no change | 
| 470         node.structureChanged = false; | 470         node.structureChanged = false; | 
| 471         node.source.contents.modificationTime++; | 471         node.source.contents.modificationTime++; | 
| 472         node.update(graph); | 472         node.update(); | 
| 473         expect(node.structureChanged, isFalse); | 473         expect(node.structureChanged, isFalse); | 
| 474 | 474 | 
| 475         // removed one | 475         // removed one | 
| 476         node.source.contents.modificationTime++; | 476         node.source.contents.modificationTime++; | 
| 477         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 477         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 
| 478             'export "a5.dart"; part "a7.dart";'; | 478             'export "a5.dart"; part "a7.dart";'; | 
| 479         expect(node.structureChanged, isFalse); | 479         expect(node.structureChanged, isFalse); | 
| 480         node.update(graph); | 480         node.update(); | 
| 481         expect(node.structureChanged, isTrue); | 481         expect(node.structureChanged, isTrue); | 
| 482       }); | 482       }); | 
| 483 | 483 | 
| 484       test('changed import', () { | 484       test('changed import', () { | 
| 485         var node = nodeOf('/a2.dart'); | 485         var node = nodeOf('/a2.dart'); | 
| 486         node.update(graph); | 486         node.update(); | 
| 487         expect(node.structureChanged, isTrue); | 487         expect(node.structureChanged, isTrue); | 
| 488         node.structureChanged = false; | 488         node.structureChanged = false; | 
| 489 | 489 | 
| 490         node.update(graph); | 490         node.update(); | 
| 491         expect(node.structureChanged, isFalse); | 491         expect(node.structureChanged, isFalse); | 
| 492 | 492 | 
| 493         // added one. | 493         // added one. | 
| 494         node.source.contents.modificationTime++; | 494         node.source.contents.modificationTime++; | 
| 495         node.source.contents.data = | 495         node.source.contents.data = | 
| 496             'import "a4.dart"; import "a3.dart"; import "a7.dart";' | 496             'import "a4.dart"; import "a3.dart"; import "a7.dart";' | 
| 497             'export "a5.dart"; part "a6.dart";'; | 497             'export "a5.dart"; part "a6.dart";'; | 
| 498         expect(node.structureChanged, isFalse); | 498         expect(node.structureChanged, isFalse); | 
| 499         node.update(graph); | 499         node.update(); | 
| 500         expect(node.structureChanged, isTrue); | 500         expect(node.structureChanged, isTrue); | 
| 501 | 501 | 
| 502         // no change | 502         // no change | 
| 503         node.structureChanged = false; | 503         node.structureChanged = false; | 
| 504         node.source.contents.modificationTime++; | 504         node.source.contents.modificationTime++; | 
| 505         node.update(graph); | 505         node.update(); | 
| 506         expect(node.structureChanged, isFalse); | 506         expect(node.structureChanged, isFalse); | 
| 507 | 507 | 
| 508         // removed one | 508         // removed one | 
| 509         node.source.contents.modificationTime++; | 509         node.source.contents.modificationTime++; | 
| 510         node.source.contents.data = 'import "a4.dart"; import "a7.dart"; ' | 510         node.source.contents.data = 'import "a4.dart"; import "a7.dart"; ' | 
| 511             'export "a5.dart"; part "a6.dart";'; | 511             'export "a5.dart"; part "a6.dart";'; | 
| 512         expect(node.structureChanged, isFalse); | 512         expect(node.structureChanged, isFalse); | 
| 513         node.update(graph); | 513         node.update(); | 
| 514         expect(node.structureChanged, isTrue); | 514         expect(node.structureChanged, isTrue); | 
| 515       }); | 515       }); | 
| 516 | 516 | 
| 517       test('changed exports', () { | 517       test('changed exports', () { | 
| 518         var node = nodeOf('/a2.dart'); | 518         var node = nodeOf('/a2.dart'); | 
| 519         node.update(graph); | 519         node.update(); | 
| 520         expect(node.structureChanged, isTrue); | 520         expect(node.structureChanged, isTrue); | 
| 521         node.structureChanged = false; | 521         node.structureChanged = false; | 
| 522 | 522 | 
| 523         node.update(graph); | 523         node.update(); | 
| 524         expect(node.structureChanged, isFalse); | 524         expect(node.structureChanged, isFalse); | 
| 525 | 525 | 
| 526         // added one. | 526         // added one. | 
| 527         node.source.contents.modificationTime++; | 527         node.source.contents.modificationTime++; | 
| 528         node.source.contents.data = 'import "a4.dart"; import "a3.dart";' | 528         node.source.contents.data = 'import "a4.dart"; import "a3.dart";' | 
| 529             'export "a5.dart"; export "a9.dart"; part "a6.dart";'; | 529             'export "a5.dart"; export "a9.dart"; part "a6.dart";'; | 
| 530         expect(node.structureChanged, isFalse); | 530         expect(node.structureChanged, isFalse); | 
| 531         node.update(graph); | 531         node.update(); | 
| 532         expect(node.structureChanged, isTrue); | 532         expect(node.structureChanged, isTrue); | 
| 533 | 533 | 
| 534         // no change | 534         // no change | 
| 535         node.structureChanged = false; | 535         node.structureChanged = false; | 
| 536         node.source.contents.modificationTime++; | 536         node.source.contents.modificationTime++; | 
| 537         node.update(graph); | 537         node.update(); | 
| 538         expect(node.structureChanged, isFalse); | 538         expect(node.structureChanged, isFalse); | 
| 539 | 539 | 
| 540         // removed one | 540         // removed one | 
| 541         node.source.contents.modificationTime++; | 541         node.source.contents.modificationTime++; | 
| 542         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 542         node.source.contents.data = 'import "a4.dart"; import "a3.dart"; ' | 
| 543             'export "a5.dart"; part "a6.dart";'; | 543             'export "a5.dart"; part "a6.dart";'; | 
| 544         expect(node.structureChanged, isFalse); | 544         expect(node.structureChanged, isFalse); | 
| 545         node.update(graph); | 545         node.update(); | 
| 546         expect(node.structureChanged, isTrue); | 546         expect(node.structureChanged, isTrue); | 
| 547       }); | 547       }); | 
| 548     }); | 548     }); | 
| 549   }); | 549   }); | 
| 550 | 550 | 
| 551   group('refresh structure and marks', () { | 551   group('refresh structure and marks', () { | 
| 552     test('initial marks', () { | 552     test('initial marks', () { | 
| 553       var node = nodeOf('/index3.html'); | 553       var node = nodeOf('/index3.html'); | 
| 554       expectGraph(node, ''' | 554       expectGraph(node, ''' | 
| 555           index3.html | 555           index3.html | 
| 556           $_RUNTIME_GRAPH | 556           $_RUNTIME_GRAPH | 
| 557           '''); | 557           '''); | 
| 558       refreshStructureAndMarks(node, graph); | 558       refreshStructureAndMarks(node); | 
| 559       expectGraph(node, ''' | 559       expectGraph(node, ''' | 
| 560           index3.html [needs-rebuild] [structure-changed] | 560           index3.html [needs-rebuild] [structure-changed] | 
| 561           |-- a2.dart [needs-rebuild] [structure-changed] | 561           |-- a2.dart [needs-rebuild] [structure-changed] | 
| 562           |    |-- a3.dart [needs-rebuild] | 562           |    |-- a3.dart [needs-rebuild] | 
| 563           |    |-- a4.dart [needs-rebuild] [structure-changed] | 563           |    |-- a4.dart [needs-rebuild] [structure-changed] | 
| 564           |    |    |-- a10.dart [needs-rebuild] | 564           |    |    |-- a10.dart [needs-rebuild] | 
| 565           |    |-- a5.dart [needs-rebuild] | 565           |    |-- a5.dart [needs-rebuild] | 
| 566           |    |-- a6.dart (part) [needs-rebuild] | 566           |    |-- a6.dart (part) [needs-rebuild] | 
| 567           $_RUNTIME_GRAPH_REBUILD | 567           $_RUNTIME_GRAPH_REBUILD | 
| 568           '''); | 568           '''); | 
| 569     }); | 569     }); | 
| 570 | 570 | 
| 571     test('cleared marks stay clear', () { | 571     test('cleared marks stay clear', () { | 
| 572       var node = nodeOf('/index3.html'); | 572       var node = nodeOf('/index3.html'); | 
| 573       refreshStructureAndMarks(node, graph); | 573       refreshStructureAndMarks(node); | 
| 574       expectGraph(node, ''' | 574       expectGraph(node, ''' | 
| 575           index3.html [needs-rebuild] [structure-changed] | 575           index3.html [needs-rebuild] [structure-changed] | 
| 576           |-- a2.dart [needs-rebuild] [structure-changed] | 576           |-- a2.dart [needs-rebuild] [structure-changed] | 
| 577           |    |-- a3.dart [needs-rebuild] | 577           |    |-- a3.dart [needs-rebuild] | 
| 578           |    |-- a4.dart [needs-rebuild] [structure-changed] | 578           |    |-- a4.dart [needs-rebuild] [structure-changed] | 
| 579           |    |    |-- a10.dart [needs-rebuild] | 579           |    |    |-- a10.dart [needs-rebuild] | 
| 580           |    |-- a5.dart [needs-rebuild] | 580           |    |-- a5.dart [needs-rebuild] | 
| 581           |    |-- a6.dart (part) [needs-rebuild] | 581           |    |-- a6.dart (part) [needs-rebuild] | 
| 582           $_RUNTIME_GRAPH_REBUILD | 582           $_RUNTIME_GRAPH_REBUILD | 
| 583           '''); | 583           '''); | 
| 584       clearMarks(node); | 584       clearMarks(node); | 
| 585       expectGraph(node, ''' | 585       expectGraph(node, ''' | 
| 586           index3.html | 586           index3.html | 
| 587           |-- a2.dart | 587           |-- a2.dart | 
| 588           |    |-- a3.dart | 588           |    |-- a3.dart | 
| 589           |    |-- a4.dart | 589           |    |-- a4.dart | 
| 590           |    |    |-- a10.dart | 590           |    |    |-- a10.dart | 
| 591           |    |-- a5.dart | 591           |    |-- a5.dart | 
| 592           |    |-- a6.dart (part) | 592           |    |-- a6.dart (part) | 
| 593           $_RUNTIME_GRAPH | 593           $_RUNTIME_GRAPH | 
| 594           '''); | 594           '''); | 
| 595 | 595 | 
| 596       refreshStructureAndMarks(node, graph); | 596       refreshStructureAndMarks(node); | 
| 597       expectGraph(node, ''' | 597       expectGraph(node, ''' | 
| 598           index3.html | 598           index3.html | 
| 599           |-- a2.dart | 599           |-- a2.dart | 
| 600           |    |-- a3.dart | 600           |    |-- a3.dart | 
| 601           |    |-- a4.dart | 601           |    |-- a4.dart | 
| 602           |    |    |-- a10.dart | 602           |    |    |-- a10.dart | 
| 603           |    |-- a5.dart | 603           |    |-- a5.dart | 
| 604           |    |-- a6.dart (part) | 604           |    |-- a6.dart (part) | 
| 605           $_RUNTIME_GRAPH | 605           $_RUNTIME_GRAPH | 
| 606           '''); | 606           '''); | 
| 607     }); | 607     }); | 
| 608 | 608 | 
| 609     test('needsRebuild mark updated on local modifications', () { | 609     test('needsRebuild mark updated on local modifications', () { | 
| 610       var node = nodeOf('/index3.html'); | 610       var node = nodeOf('/index3.html'); | 
| 611       refreshStructureAndMarks(node, graph); | 611       refreshStructureAndMarks(node); | 
| 612       clearMarks(node); | 612       clearMarks(node); | 
| 613       var a3 = nodeOf('/a3.dart'); | 613       var a3 = nodeOf('/a3.dart'); | 
| 614       a3.source.contents.modificationTime++; | 614       a3.source.contents.modificationTime++; | 
| 615 | 615 | 
| 616       refreshStructureAndMarks(node, graph); | 616       refreshStructureAndMarks(node); | 
| 617       expectGraph(node, ''' | 617       expectGraph(node, ''' | 
| 618           index3.html | 618           index3.html | 
| 619           |-- a2.dart | 619           |-- a2.dart | 
| 620           |    |-- a3.dart [needs-rebuild] | 620           |    |-- a3.dart [needs-rebuild] | 
| 621           |    |-- a4.dart | 621           |    |-- a4.dart | 
| 622           |    |    |-- a10.dart | 622           |    |    |-- a10.dart | 
| 623           |    |-- a5.dart | 623           |    |-- a5.dart | 
| 624           |    |-- a6.dart (part) | 624           |    |-- a6.dart (part) | 
| 625           $_RUNTIME_GRAPH | 625           $_RUNTIME_GRAPH | 
| 626           '''); | 626           '''); | 
| 627     }); | 627     }); | 
| 628 | 628 | 
| 629     test('structuredChanged mark updated on structure modifications', () { | 629     test('structuredChanged mark updated on structure modifications', () { | 
| 630       var node = nodeOf('/index3.html'); | 630       var node = nodeOf('/index3.html'); | 
| 631       refreshStructureAndMarks(node, graph); | 631       refreshStructureAndMarks(node); | 
| 632       clearMarks(node); | 632       clearMarks(node); | 
| 633       var a5 = nodeOf('/a5.dart'); | 633       var a5 = nodeOf('/a5.dart'); | 
| 634       a5.source.contents.modificationTime++; | 634       a5.source.contents.modificationTime++; | 
| 635       a5.source.contents.data = 'import "a8.dart";'; | 635       a5.source.contents.data = 'import "a8.dart";'; | 
| 636 | 636 | 
| 637       refreshStructureAndMarks(node, graph); | 637       refreshStructureAndMarks(node); | 
| 638       expectGraph(node, ''' | 638       expectGraph(node, ''' | 
| 639           index3.html | 639           index3.html | 
| 640           |-- a2.dart | 640           |-- a2.dart | 
| 641           |    |-- a3.dart | 641           |    |-- a3.dart | 
| 642           |    |-- a4.dart | 642           |    |-- a4.dart | 
| 643           |    |    |-- a10.dart | 643           |    |    |-- a10.dart | 
| 644           |    |-- a5.dart [needs-rebuild] [structure-changed] | 644           |    |-- a5.dart [needs-rebuild] [structure-changed] | 
| 645           |    |    |-- a8.dart [needs-rebuild] [structure-changed] | 645           |    |    |-- a8.dart [needs-rebuild] [structure-changed] | 
| 646           |    |    |    |-- a8.dart... | 646           |    |    |    |-- a8.dart... | 
| 647           |    |-- a6.dart (part) | 647           |    |-- a6.dart (part) | 
| 648           $_RUNTIME_GRAPH | 648           $_RUNTIME_GRAPH | 
| 649           '''); | 649           '''); | 
| 650     }); | 650     }); | 
| 651   }); | 651   }); | 
| 652 | 652 | 
| 653   group('server-mode', () { | 653   group('server-mode', () { | 
| 654     setUp(() { | 654     setUp(() { | 
| 655       var options2 = new CompilerOptions( | 655       var options2 = new CompilerOptions( | 
| 656           runtimeDir: '/dev_compiler_runtime/', serverMode: true); | 656           runtimeDir: '/dev_compiler_runtime/', serverMode: true); | 
| 657       context = new TypeResolver.fromMock(mockSdkSources, options2, | 657       context = new TypeResolver.fromMock(mockSdkSources, options2, | 
| 658           otherResolvers: [testUriResolver]).context; | 658           otherResolvers: [testUriResolver]).context; | 
| 659       graph = new SourceGraph(context, new LogReporter(), options2); | 659       graph = new SourceGraph(context, new LogReporter(context), options2); | 
| 660     }); | 660     }); | 
| 661 | 661 | 
| 662     test('messages widget is automatically included', () { | 662     test('messages widget is automatically included', () { | 
| 663       var node = nodeOf('/index3.html'); | 663       var node = nodeOf('/index3.html'); | 
| 664       expectGraph(node, ''' | 664       expectGraph(node, ''' | 
| 665           index3.html | 665           index3.html | 
| 666           $_RUNTIME_GRAPH | 666           $_RUNTIME_GRAPH | 
| 667           |-- messages_widget.js | 667           |-- messages_widget.js | 
| 668           |-- messages.css | 668           |-- messages.css | 
| 669           '''); | 669           '''); | 
| 670       refreshStructureAndMarks(node, graph); | 670       refreshStructureAndMarks(node); | 
| 671       expectGraph(node, ''' | 671       expectGraph(node, ''' | 
| 672           index3.html [needs-rebuild] [structure-changed] | 672           index3.html [needs-rebuild] [structure-changed] | 
| 673           |-- a2.dart [needs-rebuild] [structure-changed] | 673           |-- a2.dart [needs-rebuild] [structure-changed] | 
| 674           |    |-- a3.dart [needs-rebuild] | 674           |    |-- a3.dart [needs-rebuild] | 
| 675           |    |-- a4.dart [needs-rebuild] [structure-changed] | 675           |    |-- a4.dart [needs-rebuild] [structure-changed] | 
| 676           |    |    |-- a10.dart [needs-rebuild] | 676           |    |    |-- a10.dart [needs-rebuild] | 
| 677           |    |-- a5.dart [needs-rebuild] | 677           |    |-- a5.dart [needs-rebuild] | 
| 678           |    |-- a6.dart (part) [needs-rebuild] | 678           |    |-- a6.dart (part) [needs-rebuild] | 
| 679           $_RUNTIME_GRAPH_REBUILD | 679           $_RUNTIME_GRAPH_REBUILD | 
| 680           |-- messages_widget.js [needs-rebuild] | 680           |-- messages_widget.js [needs-rebuild] | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 696       addName(n); | 696       addName(n); | 
| 697       return true; | 697       return true; | 
| 698     } | 698     } | 
| 699 | 699 | 
| 700     setUp(() { | 700     setUp(() { | 
| 701       results = []; | 701       results = []; | 
| 702     }); | 702     }); | 
| 703 | 703 | 
| 704     test('everything build on first run', () { | 704     test('everything build on first run', () { | 
| 705       var node = nodeOf('/index3.html'); | 705       var node = nodeOf('/index3.html'); | 
| 706       rebuild(node, graph, buildNoTransitiveChange); | 706       rebuild(node, buildNoTransitiveChange); | 
| 707       // Note: a6.dart is not included because it built as part of a2.dart | 707       // Note: a6.dart is not included because it built as part of a2.dart | 
| 708       expect(results, ['a3.dart', 'a10.dart', 'a4.dart', 'a5.dart', 'a2.dart'] | 708       expect(results, ['a3.dart', 'a10.dart', 'a4.dart', 'a5.dart', 'a2.dart'] | 
| 709         ..addAll(runtimeFilesWithoutPath) | 709         ..addAll(runtimeFilesWithoutPath) | 
| 710         ..add('index3.html')); | 710         ..add('index3.html')); | 
| 711 | 711 | 
| 712       // Marks are removed automatically by rebuild | 712       // Marks are removed automatically by rebuild | 
| 713       expectGraph(node, ''' | 713       expectGraph(node, ''' | 
| 714           index3.html | 714           index3.html | 
| 715           |-- a2.dart | 715           |-- a2.dart | 
| 716           |    |-- a3.dart | 716           |    |-- a3.dart | 
| 717           |    |-- a4.dart | 717           |    |-- a4.dart | 
| 718           |    |    |-- a10.dart | 718           |    |    |-- a10.dart | 
| 719           |    |-- a5.dart | 719           |    |-- a5.dart | 
| 720           |    |-- a6.dart (part) | 720           |    |-- a6.dart (part) | 
| 721           $_RUNTIME_GRAPH | 721           $_RUNTIME_GRAPH | 
| 722           '''); | 722           '''); | 
| 723     }); | 723     }); | 
| 724 | 724 | 
| 725     test('nothing to do after build', () { | 725     test('nothing to do after build', () { | 
| 726       var node = nodeOf('/index3.html'); | 726       var node = nodeOf('/index3.html'); | 
| 727       rebuild(node, graph, buildNoTransitiveChange); | 727       rebuild(node, buildNoTransitiveChange); | 
| 728 | 728 | 
| 729       results = []; | 729       results = []; | 
| 730       rebuild(node, graph, buildNoTransitiveChange); | 730       rebuild(node, buildNoTransitiveChange); | 
| 731       expect(results, []); | 731       expect(results, []); | 
| 732     }); | 732     }); | 
| 733 | 733 | 
| 734     test('modified part triggers building library', () { | 734     test('modified part triggers building library', () { | 
| 735       var node = nodeOf('/index3.html'); | 735       var node = nodeOf('/index3.html'); | 
| 736       rebuild(node, graph, buildNoTransitiveChange); | 736       rebuild(node, buildNoTransitiveChange); | 
| 737       results = []; | 737       results = []; | 
| 738 | 738 | 
| 739       var a6 = nodeOf('/a6.dart'); | 739       var a6 = nodeOf('/a6.dart'); | 
| 740       a6.source.contents.modificationTime++; | 740       a6.source.contents.modificationTime++; | 
| 741       rebuild(node, graph, buildNoTransitiveChange); | 741       rebuild(node, buildNoTransitiveChange); | 
| 742       expect(results, ['a2.dart']); | 742       expect(results, ['a2.dart']); | 
| 743 | 743 | 
| 744       results = []; | 744       results = []; | 
| 745       rebuild(node, graph, buildNoTransitiveChange); | 745       rebuild(node, buildNoTransitiveChange); | 
| 746       expect(results, []); | 746       expect(results, []); | 
| 747     }); | 747     }); | 
| 748 | 748 | 
| 749     test('non-API change triggers build stays local', () { | 749     test('non-API change triggers build stays local', () { | 
| 750       var node = nodeOf('/index3.html'); | 750       var node = nodeOf('/index3.html'); | 
| 751       rebuild(node, graph, buildNoTransitiveChange); | 751       rebuild(node, buildNoTransitiveChange); | 
| 752       results = []; | 752       results = []; | 
| 753 | 753 | 
| 754       var a3 = nodeOf('/a3.dart'); | 754       var a3 = nodeOf('/a3.dart'); | 
| 755       a3.source.contents.modificationTime++; | 755       a3.source.contents.modificationTime++; | 
| 756       rebuild(node, graph, buildNoTransitiveChange); | 756       rebuild(node, buildNoTransitiveChange); | 
| 757       expect(results, ['a3.dart']); | 757       expect(results, ['a3.dart']); | 
| 758 | 758 | 
| 759       results = []; | 759       results = []; | 
| 760       rebuild(node, graph, buildNoTransitiveChange); | 760       rebuild(node, buildNoTransitiveChange); | 
| 761       expect(results, []); | 761       expect(results, []); | 
| 762     }); | 762     }); | 
| 763 | 763 | 
| 764     test('no-API change in exported file stays local', () { | 764     test('no-API change in exported file stays local', () { | 
| 765       var node = nodeOf('/index3.html'); | 765       var node = nodeOf('/index3.html'); | 
| 766       rebuild(node, graph, buildNoTransitiveChange); | 766       rebuild(node, buildNoTransitiveChange); | 
| 767       results = []; | 767       results = []; | 
| 768 | 768 | 
| 769       // similar to the test above, but a10 is exported from a4. | 769       // similar to the test above, but a10 is exported from a4. | 
| 770       var a3 = nodeOf('/a10.dart'); | 770       var a3 = nodeOf('/a10.dart'); | 
| 771       a3.source.contents.modificationTime++; | 771       a3.source.contents.modificationTime++; | 
| 772       rebuild(node, graph, buildNoTransitiveChange); | 772       rebuild(node, buildNoTransitiveChange); | 
| 773       expect(results, ['a10.dart']); | 773       expect(results, ['a10.dart']); | 
| 774 | 774 | 
| 775       results = []; | 775       results = []; | 
| 776       rebuild(node, graph, buildNoTransitiveChange); | 776       rebuild(node, buildNoTransitiveChange); | 
| 777       expect(results, []); | 777       expect(results, []); | 
| 778     }); | 778     }); | 
| 779 | 779 | 
| 780     test('API change in lib, triggers build on imports', () { | 780     test('API change in lib, triggers build on imports', () { | 
| 781       var node = nodeOf('/index3.html'); | 781       var node = nodeOf('/index3.html'); | 
| 782       rebuild(node, graph, buildNoTransitiveChange); | 782       rebuild(node, buildNoTransitiveChange); | 
| 783       results = []; | 783       results = []; | 
| 784 | 784 | 
| 785       var a3 = nodeOf('/a3.dart'); | 785       var a3 = nodeOf('/a3.dart'); | 
| 786       a3.source.contents.modificationTime++; | 786       a3.source.contents.modificationTime++; | 
| 787       rebuild(node, graph, buildWithTransitiveChange); | 787       rebuild(node, buildWithTransitiveChange); | 
| 788       expect(results, ['a3.dart', 'a2.dart']); | 788       expect(results, ['a3.dart', 'a2.dart']); | 
| 789 | 789 | 
| 790       results = []; | 790       results = []; | 
| 791       rebuild(node, graph, buildNoTransitiveChange); | 791       rebuild(node, buildNoTransitiveChange); | 
| 792       expect(results, []); | 792       expect(results, []); | 
| 793     }); | 793     }); | 
| 794 | 794 | 
| 795     test('API change in export, triggers build on imports', () { | 795     test('API change in export, triggers build on imports', () { | 
| 796       var node = nodeOf('/index3.html'); | 796       var node = nodeOf('/index3.html'); | 
| 797       rebuild(node, graph, buildNoTransitiveChange); | 797       rebuild(node, buildNoTransitiveChange); | 
| 798       results = []; | 798       results = []; | 
| 799 | 799 | 
| 800       var a3 = nodeOf('/a10.dart'); | 800       var a3 = nodeOf('/a10.dart'); | 
| 801       a3.source.contents.modificationTime++; | 801       a3.source.contents.modificationTime++; | 
| 802       rebuild(node, graph, buildWithTransitiveChange); | 802       rebuild(node, buildWithTransitiveChange); | 
| 803 | 803 | 
| 804       // Node: a4.dart reexports a10.dart, but it doesn't import it, so we don't | 804       // Node: a4.dart reexports a10.dart, but it doesn't import it, so we don't | 
| 805       // need to rebuild it. | 805       // need to rebuild it. | 
| 806       expect(results, ['a10.dart', 'a2.dart']); | 806       expect(results, ['a10.dart', 'a2.dart']); | 
| 807 | 807 | 
| 808       results = []; | 808       results = []; | 
| 809       rebuild(node, graph, buildNoTransitiveChange); | 809       rebuild(node, buildNoTransitiveChange); | 
| 810       expect(results, []); | 810       expect(results, []); | 
| 811     }); | 811     }); | 
| 812 | 812 | 
| 813     test('structural change rebuilds HTML, but skips unreachable code', () { | 813     test('structural change rebuilds HTML, but skips unreachable code', () { | 
| 814       var node = nodeOf('/index3.html'); | 814       var node = nodeOf('/index3.html'); | 
| 815       rebuild(node, graph, buildNoTransitiveChange); | 815       rebuild(node, buildNoTransitiveChange); | 
| 816       results = []; | 816       results = []; | 
| 817 | 817 | 
| 818       var a2 = nodeOf('/a2.dart'); | 818       var a2 = nodeOf('/a2.dart'); | 
| 819       a2.source.contents.modificationTime++; | 819       a2.source.contents.modificationTime++; | 
| 820       a2.source.contents.data = 'import "a4.dart";'; | 820       a2.source.contents.data = 'import "a4.dart";'; | 
| 821 | 821 | 
| 822       var a3 = nodeOf('/a3.dart'); | 822       var a3 = nodeOf('/a3.dart'); | 
| 823       a3.source.contents.modificationTime++; | 823       a3.source.contents.modificationTime++; | 
| 824       rebuild(node, graph, buildNoTransitiveChange); | 824       rebuild(node, buildNoTransitiveChange); | 
| 825 | 825 | 
| 826       // a3 will become unreachable, index3 reflects structural changes. | 826       // a3 will become unreachable, index3 reflects structural changes. | 
| 827       expect(results, ['a2.dart', 'index3.html']); | 827       expect(results, ['a2.dart', 'index3.html']); | 
| 828 | 828 | 
| 829       results = []; | 829       results = []; | 
| 830       rebuild(node, graph, buildNoTransitiveChange); | 830       rebuild(node, buildNoTransitiveChange); | 
| 831       expect(results, []); | 831       expect(results, []); | 
| 832     }); | 832     }); | 
| 833 | 833 | 
| 834     test('newly discovered files get built too', () { | 834     test('newly discovered files get built too', () { | 
| 835       var node = nodeOf('/index3.html'); | 835       var node = nodeOf('/index3.html'); | 
| 836       rebuild(node, graph, buildNoTransitiveChange); | 836       rebuild(node, buildNoTransitiveChange); | 
| 837       results = []; | 837       results = []; | 
| 838 | 838 | 
| 839       var a2 = nodeOf('/a2.dart'); | 839       var a2 = nodeOf('/a2.dart'); | 
| 840       a2.source.contents.modificationTime++; | 840       a2.source.contents.modificationTime++; | 
| 841       a2.source.contents.data = 'import "a9.dart";'; | 841       a2.source.contents.data = 'import "a9.dart";'; | 
| 842 | 842 | 
| 843       rebuild(node, graph, buildNoTransitiveChange); | 843       rebuild(node, buildNoTransitiveChange); | 
| 844       expect(results, ['a8.dart', 'a9.dart', 'a2.dart', 'index3.html']); | 844       expect(results, ['a8.dart', 'a9.dart', 'a2.dart', 'index3.html']); | 
| 845 | 845 | 
| 846       results = []; | 846       results = []; | 
| 847       rebuild(node, graph, buildNoTransitiveChange); | 847       rebuild(node, buildNoTransitiveChange); | 
| 848       expect(results, []); | 848       expect(results, []); | 
| 849     }); | 849     }); | 
| 850 | 850 | 
| 851     group('file upgrades', () { | 851     group('file upgrades', () { | 
| 852       // Normally upgrading involves two changes: | 852       // Normally upgrading involves two changes: | 
| 853       //  (a) change the affected file | 853       //  (a) change the affected file | 
| 854       //  (b) change directive from part to import (or viceversa) | 854       //  (b) change directive from part to import (or viceversa) | 
| 855       // These could happen in any order and we should reach a consistent state | 855       // These could happen in any order and we should reach a consistent state | 
| 856       // in the end. | 856       // in the end. | 
| 857 | 857 | 
| 858       test('convert part to a library before updating the import', () { | 858       test('convert part to a library before updating the import', () { | 
| 859         var node = nodeOf('/index3.html'); | 859         var node = nodeOf('/index3.html'); | 
| 860         var a2 = nodeOf('/a2.dart'); | 860         var a2 = nodeOf('/a2.dart'); | 
| 861         var a6 = nodeOf('/a6.dart'); | 861         var a6 = nodeOf('/a6.dart'); | 
| 862         rebuild(node, graph, buildNoTransitiveChange); | 862         rebuild(node, buildNoTransitiveChange); | 
| 863 | 863 | 
| 864         expectGraph(node, ''' | 864         expectGraph(node, ''' | 
| 865             index3.html | 865             index3.html | 
| 866             |-- a2.dart | 866             |-- a2.dart | 
| 867             |    |-- a3.dart | 867             |    |-- a3.dart | 
| 868             |    |-- a4.dart | 868             |    |-- a4.dart | 
| 869             |    |    |-- a10.dart | 869             |    |    |-- a10.dart | 
| 870             |    |-- a5.dart | 870             |    |-- a5.dart | 
| 871             |    |-- a6.dart (part) | 871             |    |-- a6.dart (part) | 
| 872             $_RUNTIME_GRAPH | 872             $_RUNTIME_GRAPH | 
| 873             '''); | 873             '''); | 
| 874 | 874 | 
| 875         // Modify the file first: | 875         // Modify the file first: | 
| 876         a6.source.contents.modificationTime++; | 876         a6.source.contents.modificationTime++; | 
| 877         a6.source.contents.data = 'library a6; import "a5.dart";'; | 877         a6.source.contents.data = 'library a6; import "a5.dart";'; | 
| 878         results = []; | 878         results = []; | 
| 879         rebuild(node, graph, buildNoTransitiveChange); | 879         rebuild(node, buildNoTransitiveChange); | 
| 880 | 880 | 
| 881         // Looks to us like a change in a part, we'll report errors that the | 881         // Looks to us like a change in a part, we'll report errors that the | 
| 882         // part is not really a part-file. Note that a6.dart is not included | 882         // part is not really a part-file. Note that a6.dart is not included | 
| 883         // below, because we don't build it as a library. | 883         // below, because we don't build it as a library. | 
| 884         expect(results, ['a2.dart']); | 884         expect(results, ['a2.dart']); | 
| 885         expectGraph(node, ''' | 885         expectGraph(node, ''' | 
| 886             index3.html | 886             index3.html | 
| 887             |-- a2.dart | 887             |-- a2.dart | 
| 888             |    |-- a3.dart | 888             |    |-- a3.dart | 
| 889             |    |-- a4.dart | 889             |    |-- a4.dart | 
| 890             |    |    |-- a10.dart | 890             |    |    |-- a10.dart | 
| 891             |    |-- a5.dart | 891             |    |-- a5.dart | 
| 892             |    |-- a6.dart (part) | 892             |    |-- a6.dart (part) | 
| 893             $_RUNTIME_GRAPH | 893             $_RUNTIME_GRAPH | 
| 894             '''); | 894             '''); | 
| 895 | 895 | 
| 896         a2.source.contents.modificationTime++; | 896         a2.source.contents.modificationTime++; | 
| 897         a2.source.contents.data = ''' | 897         a2.source.contents.data = ''' | 
| 898             library a2; | 898             library a2; | 
| 899             import 'a3.dart'; | 899             import 'a3.dart'; | 
| 900             import 'a4.dart'; | 900             import 'a4.dart'; | 
| 901             import 'a6.dart'; // properly import it | 901             import 'a6.dart'; // properly import it | 
| 902             export 'a5.dart'; | 902             export 'a5.dart'; | 
| 903           '''; | 903           '''; | 
| 904         results = []; | 904         results = []; | 
| 905         rebuild(node, graph, buildNoTransitiveChange); | 905         rebuild(node, buildNoTransitiveChange); | 
| 906         // Note that a6 is now included, because we haven't built it as a | 906         // Note that a6 is now included, because we haven't built it as a | 
| 907         // library until now: | 907         // library until now: | 
| 908         expect(results, ['a6.dart', 'a2.dart', 'index3.html']); | 908         expect(results, ['a6.dart', 'a2.dart', 'index3.html']); | 
| 909 | 909 | 
| 910         a6.source.contents.modificationTime++; | 910         a6.source.contents.modificationTime++; | 
| 911         results = []; | 911         results = []; | 
| 912         rebuild(node, graph, buildNoTransitiveChange); | 912         rebuild(node, buildNoTransitiveChange); | 
| 913         expect(results, ['a6.dart']); | 913         expect(results, ['a6.dart']); | 
| 914 | 914 | 
| 915         expectGraph(node, ''' | 915         expectGraph(node, ''' | 
| 916             index3.html | 916             index3.html | 
| 917             |-- a2.dart | 917             |-- a2.dart | 
| 918             |    |-- a3.dart | 918             |    |-- a3.dart | 
| 919             |    |-- a4.dart | 919             |    |-- a4.dart | 
| 920             |    |    |-- a10.dart | 920             |    |    |-- a10.dart | 
| 921             |    |-- a6.dart | 921             |    |-- a6.dart | 
| 922             |    |    |-- a5.dart | 922             |    |    |-- a5.dart | 
| 923             |    |-- a5.dart... | 923             |    |-- a5.dart... | 
| 924             $_RUNTIME_GRAPH | 924             $_RUNTIME_GRAPH | 
| 925             '''); | 925             '''); | 
| 926       }); | 926       }); | 
| 927 | 927 | 
| 928       test('convert part to a library after updating the import', () { | 928       test('convert part to a library after updating the import', () { | 
| 929         var node = nodeOf('/index3.html'); | 929         var node = nodeOf('/index3.html'); | 
| 930         var a2 = nodeOf('/a2.dart'); | 930         var a2 = nodeOf('/a2.dart'); | 
| 931         var a6 = nodeOf('/a6.dart'); | 931         var a6 = nodeOf('/a6.dart'); | 
| 932         rebuild(node, graph, buildNoTransitiveChange); | 932         rebuild(node, buildNoTransitiveChange); | 
| 933 | 933 | 
| 934         expectGraph(node, ''' | 934         expectGraph(node, ''' | 
| 935             index3.html | 935             index3.html | 
| 936             |-- a2.dart | 936             |-- a2.dart | 
| 937             |    |-- a3.dart | 937             |    |-- a3.dart | 
| 938             |    |-- a4.dart | 938             |    |-- a4.dart | 
| 939             |    |    |-- a10.dart | 939             |    |    |-- a10.dart | 
| 940             |    |-- a5.dart | 940             |    |-- a5.dart | 
| 941             |    |-- a6.dart (part) | 941             |    |-- a6.dart (part) | 
| 942             $_RUNTIME_GRAPH | 942             $_RUNTIME_GRAPH | 
| 943             '''); | 943             '''); | 
| 944 | 944 | 
| 945         a2.source.contents.modificationTime++; | 945         a2.source.contents.modificationTime++; | 
| 946         a2.source.contents.data = ''' | 946         a2.source.contents.data = ''' | 
| 947             library a2; | 947             library a2; | 
| 948             import 'a3.dart'; | 948             import 'a3.dart'; | 
| 949             import 'a4.dart'; | 949             import 'a4.dart'; | 
| 950             import 'a6.dart'; // properly import it | 950             import 'a6.dart'; // properly import it | 
| 951             export 'a5.dart'; | 951             export 'a5.dart'; | 
| 952           '''; | 952           '''; | 
| 953         results = []; | 953         results = []; | 
| 954         rebuild(node, graph, buildNoTransitiveChange); | 954         rebuild(node, buildNoTransitiveChange); | 
| 955         expect(results, ['a6.dart', 'a2.dart', 'index3.html']); | 955         expect(results, ['a6.dart', 'a2.dart', 'index3.html']); | 
| 956         expectGraph(node, ''' | 956         expectGraph(node, ''' | 
| 957             index3.html | 957             index3.html | 
| 958             |-- a2.dart | 958             |-- a2.dart | 
| 959             |    |-- a3.dart | 959             |    |-- a3.dart | 
| 960             |    |-- a4.dart | 960             |    |-- a4.dart | 
| 961             |    |    |-- a10.dart | 961             |    |    |-- a10.dart | 
| 962             |    |-- a6.dart | 962             |    |-- a6.dart | 
| 963             |    |-- a5.dart | 963             |    |-- a5.dart | 
| 964             $_RUNTIME_GRAPH | 964             $_RUNTIME_GRAPH | 
| 965             '''); | 965             '''); | 
| 966 | 966 | 
| 967         a6.source.contents.modificationTime++; | 967         a6.source.contents.modificationTime++; | 
| 968         a6.source.contents.data = 'library a6; import "a5.dart";'; | 968         a6.source.contents.data = 'library a6; import "a5.dart";'; | 
| 969         results = []; | 969         results = []; | 
| 970         rebuild(node, graph, buildNoTransitiveChange); | 970         rebuild(node, buildNoTransitiveChange); | 
| 971         expect(results, ['a6.dart', 'index3.html']); | 971         expect(results, ['a6.dart', 'index3.html']); | 
| 972         expectGraph(node, ''' | 972         expectGraph(node, ''' | 
| 973             index3.html | 973             index3.html | 
| 974             |-- a2.dart | 974             |-- a2.dart | 
| 975             |    |-- a3.dart | 975             |    |-- a3.dart | 
| 976             |    |-- a4.dart | 976             |    |-- a4.dart | 
| 977             |    |    |-- a10.dart | 977             |    |    |-- a10.dart | 
| 978             |    |-- a6.dart | 978             |    |-- a6.dart | 
| 979             |    |    |-- a5.dart | 979             |    |    |-- a5.dart | 
| 980             |    |-- a5.dart... | 980             |    |-- a5.dart... | 
| 981             $_RUNTIME_GRAPH | 981             $_RUNTIME_GRAPH | 
| 982             '''); | 982             '''); | 
| 983       }); | 983       }); | 
| 984 | 984 | 
| 985       test('disconnect part making it a library', () { | 985       test('disconnect part making it a library', () { | 
| 986         var node = nodeOf('/index3.html'); | 986         var node = nodeOf('/index3.html'); | 
| 987         var a2 = nodeOf('/a2.dart'); | 987         var a2 = nodeOf('/a2.dart'); | 
| 988         var a6 = nodeOf('/a6.dart'); | 988         var a6 = nodeOf('/a6.dart'); | 
| 989         rebuild(node, graph, buildNoTransitiveChange); | 989         rebuild(node, buildNoTransitiveChange); | 
| 990 | 990 | 
| 991         expectGraph(node, ''' | 991         expectGraph(node, ''' | 
| 992             index3.html | 992             index3.html | 
| 993             |-- a2.dart | 993             |-- a2.dart | 
| 994             |    |-- a3.dart | 994             |    |-- a3.dart | 
| 995             |    |-- a4.dart | 995             |    |-- a4.dart | 
| 996             |    |    |-- a10.dart | 996             |    |    |-- a10.dart | 
| 997             |    |-- a5.dart | 997             |    |-- a5.dart | 
| 998             |    |-- a6.dart (part) | 998             |    |-- a6.dart (part) | 
| 999             $_RUNTIME_GRAPH | 999             $_RUNTIME_GRAPH | 
| 1000             '''); | 1000             '''); | 
| 1001 | 1001 | 
| 1002         a2.source.contents.modificationTime++; | 1002         a2.source.contents.modificationTime++; | 
| 1003         a2.source.contents.data = ''' | 1003         a2.source.contents.data = ''' | 
| 1004             library a2; | 1004             library a2; | 
| 1005             import 'a3.dart'; | 1005             import 'a3.dart'; | 
| 1006             import 'a4.dart'; | 1006             import 'a4.dart'; | 
| 1007             export 'a5.dart'; | 1007             export 'a5.dart'; | 
| 1008           '''; | 1008           '''; | 
| 1009         a6.source.contents.modificationTime++; | 1009         a6.source.contents.modificationTime++; | 
| 1010         a6.source.contents.data = 'library a6; import "a5.dart";'; | 1010         a6.source.contents.data = 'library a6; import "a5.dart";'; | 
| 1011         results = []; | 1011         results = []; | 
| 1012         rebuild(node, graph, buildNoTransitiveChange); | 1012         rebuild(node, buildNoTransitiveChange); | 
| 1013         // a6 is not here, it's not reachable so we don't build it. | 1013         // a6 is not here, it's not reachable so we don't build it. | 
| 1014         expect(results, ['a2.dart', 'index3.html']); | 1014         expect(results, ['a2.dart', 'index3.html']); | 
| 1015         expectGraph(node, ''' | 1015         expectGraph(node, ''' | 
| 1016             index3.html | 1016             index3.html | 
| 1017             |-- a2.dart | 1017             |-- a2.dart | 
| 1018             |    |-- a3.dart | 1018             |    |-- a3.dart | 
| 1019             |    |-- a4.dart | 1019             |    |-- a4.dart | 
| 1020             |    |    |-- a10.dart | 1020             |    |    |-- a10.dart | 
| 1021             |    |-- a5.dart | 1021             |    |-- a5.dart | 
| 1022             $_RUNTIME_GRAPH | 1022             $_RUNTIME_GRAPH | 
| 1023             '''); | 1023             '''); | 
| 1024       }); | 1024       }); | 
| 1025 | 1025 | 
| 1026       test('convert a library to a part', () { | 1026       test('convert a library to a part', () { | 
| 1027         var node = nodeOf('/index3.html'); | 1027         var node = nodeOf('/index3.html'); | 
| 1028         var a2 = nodeOf('/a2.dart'); | 1028         var a2 = nodeOf('/a2.dart'); | 
| 1029         var a5 = nodeOf('/a5.dart'); | 1029         var a5 = nodeOf('/a5.dart'); | 
| 1030         rebuild(node, graph, buildNoTransitiveChange); | 1030         rebuild(node, buildNoTransitiveChange); | 
| 1031 | 1031 | 
| 1032         expectGraph(node, ''' | 1032         expectGraph(node, ''' | 
| 1033             index3.html | 1033             index3.html | 
| 1034             |-- a2.dart | 1034             |-- a2.dart | 
| 1035             |    |-- a3.dart | 1035             |    |-- a3.dart | 
| 1036             |    |-- a4.dart | 1036             |    |-- a4.dart | 
| 1037             |    |    |-- a10.dart | 1037             |    |    |-- a10.dart | 
| 1038             |    |-- a5.dart | 1038             |    |-- a5.dart | 
| 1039             |    |-- a6.dart (part) | 1039             |    |-- a6.dart (part) | 
| 1040             $_RUNTIME_GRAPH | 1040             $_RUNTIME_GRAPH | 
| 1041             '''); | 1041             '''); | 
| 1042 | 1042 | 
| 1043         a2.source.contents.modificationTime++; | 1043         a2.source.contents.modificationTime++; | 
| 1044         a2.source.contents.data = ''' | 1044         a2.source.contents.data = ''' | 
| 1045             library a2; | 1045             library a2; | 
| 1046             import 'a3.dart'; | 1046             import 'a3.dart'; | 
| 1047             import 'a4.dart'; | 1047             import 'a4.dart'; | 
| 1048             part 'a5.dart'; // make it a part | 1048             part 'a5.dart'; // make it a part | 
| 1049             part 'a6.dart'; | 1049             part 'a6.dart'; | 
| 1050           '''; | 1050           '''; | 
| 1051         results = []; | 1051         results = []; | 
| 1052         rebuild(node, graph, buildNoTransitiveChange); | 1052         rebuild(node, buildNoTransitiveChange); | 
| 1053         expect(results, ['a2.dart', 'index3.html']); | 1053         expect(results, ['a2.dart', 'index3.html']); | 
| 1054         expectGraph(node, ''' | 1054         expectGraph(node, ''' | 
| 1055             index3.html | 1055             index3.html | 
| 1056             |-- a2.dart | 1056             |-- a2.dart | 
| 1057             |    |-- a3.dart | 1057             |    |-- a3.dart | 
| 1058             |    |-- a4.dart | 1058             |    |-- a4.dart | 
| 1059             |    |    |-- a10.dart | 1059             |    |    |-- a10.dart | 
| 1060             |    |-- a5.dart (part) | 1060             |    |-- a5.dart (part) | 
| 1061             |    |-- a6.dart (part) | 1061             |    |-- a6.dart (part) | 
| 1062             $_RUNTIME_GRAPH | 1062             $_RUNTIME_GRAPH | 
| 1063             '''); | 1063             '''); | 
| 1064 | 1064 | 
| 1065         a5.source.contents.modificationTime++; | 1065         a5.source.contents.modificationTime++; | 
| 1066         a5.source.contents.data = 'part of a2;'; | 1066         a5.source.contents.data = 'part of a2;'; | 
| 1067         results = []; | 1067         results = []; | 
| 1068         rebuild(node, graph, buildNoTransitiveChange); | 1068         rebuild(node, buildNoTransitiveChange); | 
| 1069         expect(results, ['a2.dart']); | 1069         expect(results, ['a2.dart']); | 
| 1070         expectGraph(node, ''' | 1070         expectGraph(node, ''' | 
| 1071             index3.html | 1071             index3.html | 
| 1072             |-- a2.dart | 1072             |-- a2.dart | 
| 1073             |    |-- a3.dart | 1073             |    |-- a3.dart | 
| 1074             |    |-- a4.dart | 1074             |    |-- a4.dart | 
| 1075             |    |    |-- a10.dart | 1075             |    |    |-- a10.dart | 
| 1076             |    |-- a5.dart (part) | 1076             |    |-- a5.dart (part) | 
| 1077             |    |-- a6.dart (part) | 1077             |    |-- a6.dart (part) | 
| 1078             $_RUNTIME_GRAPH | 1078             $_RUNTIME_GRAPH | 
| 1079             '''); | 1079             '''); | 
| 1080       }); | 1080       }); | 
| 1081     }); | 1081     }); | 
| 1082 | 1082 | 
| 1083     group('represented non-existing files', () { | 1083     group('represented non-existing files', () { | 
| 1084       test('recognize locally change between existing and not-existing', () { | 1084       test('recognize locally change between existing and not-existing', () { | 
| 1085         var n = nodeOf('/foo.dart'); | 1085         var n = nodeOf('/foo.dart'); | 
| 1086         expect(n.source, isNotNull); | 1086         expect(n.source, isNotNull); | 
| 1087         expect(n.source.exists(), isFalse); | 1087         expect(n.source.exists(), isFalse); | 
| 1088         var source = testUriResolver.files[new Uri.file('/foo.dart')]; | 1088         var source = testUriResolver.files[new Uri.file('/foo.dart')]; | 
| 1089         expect(n.source, source); | 1089         expect(n.source, source); | 
| 1090         source.contents.data = "hi"; | 1090         source.contents.data = "hi"; | 
| 1091         source.contents.modificationTime++; | 1091         source.contents.modificationTime++; | 
| 1092         expect(n.source.exists(), isTrue); | 1092         expect(n.source.exists(), isTrue); | 
| 1093       }); | 1093       }); | 
| 1094 | 1094 | 
| 1095       test('non-existing files are tracked in dependencies', () { | 1095       test('non-existing files are tracked in dependencies', () { | 
| 1096         var node = nodeOf('/foo.dart'); | 1096         var node = nodeOf('/foo.dart'); | 
| 1097         node.source.contents.data = "import 'bar.dart';"; | 1097         node.source.contents.data = "import 'bar.dart';"; | 
| 1098         rebuild(node, graph, buildNoTransitiveChange); | 1098         rebuild(node, buildNoTransitiveChange); | 
| 1099         expect(node.allDeps.contains(nodeOf('/bar.dart')), isTrue); | 1099         expect(node.allDeps.contains(nodeOf('/bar.dart')), isTrue); | 
| 1100 | 1100 | 
| 1101         var source = nodeOf('/bar.dart').source; | 1101         var source = nodeOf('/bar.dart').source; | 
| 1102         source.contents.data = "hi"; | 1102         source.contents.data = "hi"; | 
| 1103         source.contents.modificationTime++; | 1103         source.contents.modificationTime++; | 
| 1104         results = []; | 1104         results = []; | 
| 1105         rebuild(node, graph, buildWithTransitiveChange); | 1105         rebuild(node, buildWithTransitiveChange); | 
| 1106         expect(results, ['bar.dart', 'foo.dart']); | 1106         expect(results, ['bar.dart', 'foo.dart']); | 
| 1107       }); | 1107       }); | 
| 1108     }); | 1108     }); | 
| 1109 | 1109 | 
| 1110     group('null for non-existing files', () { | 1110     group('null for non-existing files', () { | 
| 1111       setUp(() { | 1111       setUp(() { | 
| 1112         testUriResolver = new InMemoryUriResolver(testFiles, | 1112         testUriResolver = new InMemoryUriResolver(testFiles, | 
| 1113             representNonExistingFiles: false); | 1113             representNonExistingFiles: false); | 
| 1114         context = new TypeResolver.fromMock(mockSdkSources, options, | 1114         context = new TypeResolver.fromMock(mockSdkSources, options, | 
| 1115             otherResolvers: [testUriResolver]).context; | 1115             otherResolvers: [testUriResolver]).context; | 
| 1116         graph = new SourceGraph(context, new LogReporter(), options); | 1116         graph = new SourceGraph(context, new LogReporter(context), options); | 
| 1117       }); | 1117       }); | 
| 1118 | 1118 | 
| 1119       test('recognize locally change between existing and not-existing', () { | 1119       test('recognize locally change between existing and not-existing', () { | 
| 1120         var n = nodeOf('/foo.dart'); | 1120         var n = nodeOf('/foo.dart'); | 
| 1121         expect(n.source, isNull); | 1121         expect(n.source, isNull); | 
| 1122         var source = new InMemorySource(new Uri.file('/foo.dart'), "hi"); | 1122         var source = new InMemorySource(new Uri.file('/foo.dart'), "hi"); | 
| 1123         testUriResolver.files[source.uri] = source; | 1123         testUriResolver.files[source.uri] = source; | 
| 1124         expect(n.source, isNull); | 1124         expect(n.source, isNull); | 
| 1125         n.update(graph); | 1125         n.update(); | 
| 1126         expect(n.source, source); | 1126         expect(n.source, source); | 
| 1127         expect(n.source.exists(), isTrue); | 1127         expect(n.source.exists(), isTrue); | 
| 1128         expect(n.needsRebuild, isTrue); | 1128         expect(n.needsRebuild, isTrue); | 
| 1129       }); | 1129       }); | 
| 1130 | 1130 | 
| 1131       test('non-existing files are tracked in dependencies', () { | 1131       test('non-existing files are tracked in dependencies', () { | 
| 1132         var s1 = | 1132         var s1 = | 
| 1133             new InMemorySource(new Uri.file('/foo.dart'), "import 'bar.dart';"); | 1133             new InMemorySource(new Uri.file('/foo.dart'), "import 'bar.dart';"); | 
| 1134         testUriResolver.files[s1.uri] = s1; | 1134         testUriResolver.files[s1.uri] = s1; | 
| 1135         var node = nodeOf('/foo.dart'); | 1135         var node = nodeOf('/foo.dart'); | 
| 1136         rebuild(node, graph, buildNoTransitiveChange); | 1136         rebuild(node, buildNoTransitiveChange); | 
| 1137         expect(node.allDeps.length, 1); | 1137         expect(node.allDeps.length, 1); | 
| 1138         expect(node.allDeps.contains(nodeOf('/bar.dart')), isTrue); | 1138         expect(node.allDeps.contains(nodeOf('/bar.dart')), isTrue); | 
| 1139         expect(nodeOf('/bar.dart').source, isNull); | 1139         expect(nodeOf('/bar.dart').source, isNull); | 
| 1140 | 1140 | 
| 1141         var s2 = new InMemorySource(new Uri.file('/bar.dart'), "hi"); | 1141         var s2 = new InMemorySource(new Uri.file('/bar.dart'), "hi"); | 
| 1142         testUriResolver.files[s2.uri] = s2; | 1142         testUriResolver.files[s2.uri] = s2; | 
| 1143         results = []; | 1143         results = []; | 
| 1144         rebuild(node, graph, buildWithTransitiveChange); | 1144         rebuild(node, buildWithTransitiveChange); | 
| 1145         expect(results, ['bar.dart', 'foo.dart']); | 1145         expect(results, ['bar.dart', 'foo.dart']); | 
| 1146       }); | 1146       }); | 
| 1147     }); | 1147     }); | 
| 1148   }); | 1148   }); | 
| 1149 } | 1149 } | 
| 1150 | 1150 | 
| 1151 expectGraph(SourceNode node, String expectation) { | 1151 expectGraph(SourceNode node, String expectation) { | 
| 1152   expect(printReachable(node), equalsIgnoringWhitespace(expectation)); | 1152   expect(printReachable(node), equalsIgnoringWhitespace(expectation)); | 
| 1153 } | 1153 } | 
| 1154 | 1154 | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1192 } | 1192 } | 
| 1193 | 1193 | 
| 1194 final runtimeFilesWithoutPath = defaultRuntimeFiles | 1194 final runtimeFilesWithoutPath = defaultRuntimeFiles | 
| 1195     .map((f) => f.replaceAll('dart/', '')) | 1195     .map((f) => f.replaceAll('dart/', '')) | 
| 1196     .toList(growable: false); | 1196     .toList(growable: false); | 
| 1197 final _RUNTIME_GRAPH = runtimeFilesWithoutPath.map((s) => '|--  $s').join('\n'); | 1197 final _RUNTIME_GRAPH = runtimeFilesWithoutPath.map((s) => '|--  $s').join('\n'); | 
| 1198 final _RUNTIME_GRAPH_REBUILD = | 1198 final _RUNTIME_GRAPH_REBUILD = | 
| 1199     runtimeFilesWithoutPath.map((s) => '|--  $s [needs-rebuild]').join('\n'); | 1199     runtimeFilesWithoutPath.map((s) => '|--  $s [needs-rebuild]').join('\n'); | 
| 1200 | 1200 | 
| 1201 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 1201 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 
| OLD | NEW | 
|---|