| 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 |