| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import 'package:analyzer/file_system/file_system.dart'; | |
| 6 import 'package:analyzer/source/package_map_resolver.dart'; | |
| 7 import 'package:analyzer/src/generated/source.dart'; | |
| 8 import 'package:analyzer/src/summary/format.dart'; | |
| 9 import 'package:analyzer/src/summary/idl.dart'; | |
| 10 import 'package:analyzer/src/summary/pub_summary.dart'; | |
| 11 import 'package:analyzer/src/summary/summarize_elements.dart'; | |
| 12 import 'package:path/path.dart' as pathos; | |
| 13 import 'package:test/test.dart'; | |
| 14 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
| 15 | |
| 16 import '../context/abstract_context.dart'; | |
| 17 import '../context/mock_sdk.dart'; | |
| 18 | |
| 19 main() { | |
| 20 defineReflectiveSuite(() { | |
| 21 defineReflectiveTests(PubSummaryManagerTest); | |
| 22 }); | |
| 23 } | |
| 24 | |
| 25 @reflectiveTest | |
| 26 class PubSummaryManagerTest extends AbstractContextTest { | |
| 27 /** | |
| 28 * The path to the root of the pubcache directory used in these tests. The | |
| 29 * path has not been converted to the current platform, and is therefore only | |
| 30 * appropriate for composing paths that will later be converted. | |
| 31 */ | |
| 32 static const String CACHE = '/home/.pub-cache/hosted/pub.dartlang.org'; | |
| 33 | |
| 34 PubSummaryManager manager; | |
| 35 | |
| 36 Folder getFolder(String path) => | |
| 37 resourceProvider.getFolder(resourceProvider.convertPath(path)); | |
| 38 | |
| 39 File newFile(String path, String content) { | |
| 40 //, [int stamp]) { | |
| 41 return resourceProvider.newFile( | |
| 42 resourceProvider.convertPath(path), content); | |
| 43 } | |
| 44 | |
| 45 Folder newFolder(String path) => | |
| 46 resourceProvider.newFolder(resourceProvider.convertPath(path)); | |
| 47 | |
| 48 void setUp() { | |
| 49 super.setUp(); | |
| 50 _createManager(); | |
| 51 } | |
| 52 | |
| 53 test_computeUnlinkedForFolder() async { | |
| 54 // Create package files. | |
| 55 newFile( | |
| 56 '/flutter/aaa/lib/a.dart', | |
| 57 ''' | |
| 58 class A {} | |
| 59 '''); | |
| 60 newFile( | |
| 61 '/flutter/bbb/lib/b.dart', | |
| 62 ''' | |
| 63 class B {} | |
| 64 '''); | |
| 65 | |
| 66 // Configure packages resolution. | |
| 67 Folder libFolderA = newFolder('/flutter/aaa/lib'); | |
| 68 Folder libFolderB = newFolder('/flutter/bbb/lib'); | |
| 69 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 70 sdkResolver, | |
| 71 resourceResolver, | |
| 72 new PackageMapUriResolver(resourceProvider, { | |
| 73 'aaa': [libFolderA], | |
| 74 'bbb': [libFolderB], | |
| 75 }) | |
| 76 ]); | |
| 77 | |
| 78 await manager.computeUnlinkedForFolder('aaa', libFolderA); | |
| 79 await manager.computeUnlinkedForFolder('bbb', libFolderB); | |
| 80 | |
| 81 // The files must be created. | |
| 82 _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME); | |
| 83 _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 84 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME); | |
| 85 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 86 } | |
| 87 | |
| 88 test_getLinkedBundles_cached() async { | |
| 89 String pathA1 = '$CACHE/aaa-1.0.0'; | |
| 90 String pathA2 = '$CACHE/aaa-2.0.0'; | |
| 91 newFile( | |
| 92 '$pathA1/lib/a.dart', | |
| 93 ''' | |
| 94 class A {} | |
| 95 int a; | |
| 96 '''); | |
| 97 newFile( | |
| 98 '$pathA2/lib/a.dart', | |
| 99 ''' | |
| 100 class A2 {} | |
| 101 int a; | |
| 102 '''); | |
| 103 newFile( | |
| 104 '$CACHE/bbb/lib/b.dart', | |
| 105 ''' | |
| 106 import 'package:aaa/a.dart'; | |
| 107 A b; | |
| 108 '''); | |
| 109 Folder folderA1 = getFolder(pathA1); | |
| 110 Folder folderA2 = getFolder(pathA2); | |
| 111 Folder folderB = getFolder('$CACHE/bbb'); | |
| 112 | |
| 113 // Configure packages resolution. | |
| 114 Folder libFolderA1 = newFolder('$pathA1/lib'); | |
| 115 Folder libFolderA2 = newFolder('$pathA2/lib'); | |
| 116 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 117 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 118 sdkResolver, | |
| 119 resourceResolver, | |
| 120 new PackageMapUriResolver(resourceProvider, { | |
| 121 'aaa': [libFolderA1], | |
| 122 'bbb': [libFolderB], | |
| 123 }) | |
| 124 ]); | |
| 125 | |
| 126 // Session 1. | |
| 127 // Create linked bundles and store them in files. | |
| 128 String linkedHashA; | |
| 129 String linkedHashB; | |
| 130 { | |
| 131 // Ensure unlinked bundles. | |
| 132 manager.getUnlinkedBundles(context); | |
| 133 await manager.onUnlinkedComplete; | |
| 134 | |
| 135 // Now we should be able to get linked bundles. | |
| 136 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 137 expect(linkedPackages, hasLength(2)); | |
| 138 | |
| 139 // Verify that files with linked bundles were created. | |
| 140 LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa'); | |
| 141 LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb'); | |
| 142 linkedHashA = packageA.linkedHash; | |
| 143 linkedHashB = packageB.linkedHash; | |
| 144 _assertFileExists(folderA1, 'linked_spec_$linkedHashA.ds'); | |
| 145 _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds'); | |
| 146 } | |
| 147 | |
| 148 // Session 2. | |
| 149 // Recreate manager and ask again. | |
| 150 { | |
| 151 _createManager(); | |
| 152 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 153 expect(linkedPackages, hasLength(2)); | |
| 154 | |
| 155 // Verify that linked packages have the same hashes, so they must | |
| 156 // be have been read from the previously created files. | |
| 157 LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa'); | |
| 158 LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb'); | |
| 159 expect(packageA.linkedHash, linkedHashA); | |
| 160 expect(packageB.linkedHash, linkedHashB); | |
| 161 } | |
| 162 | |
| 163 // Session 2 with different 'aaa' version. | |
| 164 // Different linked bundles. | |
| 165 { | |
| 166 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 167 sdkResolver, | |
| 168 resourceResolver, | |
| 169 new PackageMapUriResolver(resourceProvider, { | |
| 170 'aaa': [libFolderA2], | |
| 171 'bbb': [libFolderB], | |
| 172 }) | |
| 173 ]); | |
| 174 | |
| 175 // Ensure unlinked bundles. | |
| 176 manager.getUnlinkedBundles(context); | |
| 177 await manager.onUnlinkedComplete; | |
| 178 | |
| 179 // Now we should be able to get linked bundles. | |
| 180 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 181 expect(linkedPackages, hasLength(2)); | |
| 182 | |
| 183 // Verify that new files with linked bundles were created. | |
| 184 LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa'); | |
| 185 LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb'); | |
| 186 expect(packageA.linkedHash, isNot(linkedHashA)); | |
| 187 expect(packageB.linkedHash, isNot(linkedHashB)); | |
| 188 _assertFileExists(folderA2, 'linked_spec_${packageA.linkedHash}.ds'); | |
| 189 _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds'); | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 test_getLinkedBundles_cached_declaredVariables_export() async { | |
| 194 await _testImpl_getLinkedBundles_cached_declaredVariables('export'); | |
| 195 } | |
| 196 | |
| 197 test_getLinkedBundles_cached_declaredVariables_import() async { | |
| 198 await _testImpl_getLinkedBundles_cached_declaredVariables('import'); | |
| 199 } | |
| 200 | |
| 201 test_getLinkedBundles_cached_differentSdk() async { | |
| 202 String pathA = '$CACHE/aaa'; | |
| 203 newFile( | |
| 204 '$pathA/lib/a.dart', | |
| 205 ''' | |
| 206 class A {} | |
| 207 int a; | |
| 208 '''); | |
| 209 newFile( | |
| 210 '$CACHE/bbb/lib/b.dart', | |
| 211 ''' | |
| 212 import 'package:aaa/a.dart'; | |
| 213 A b; | |
| 214 '''); | |
| 215 Folder folderA = getFolder(pathA); | |
| 216 Folder folderB = getFolder('$CACHE/bbb'); | |
| 217 | |
| 218 // Configure packages resolution. | |
| 219 Folder libFolderA = newFolder('$pathA/lib'); | |
| 220 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 221 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 222 sdkResolver, | |
| 223 resourceResolver, | |
| 224 new PackageMapUriResolver(resourceProvider, { | |
| 225 'aaa': [libFolderA], | |
| 226 'bbb': [libFolderB], | |
| 227 }) | |
| 228 ]); | |
| 229 | |
| 230 // Session 1. | |
| 231 // Create linked bundles and store them in files. | |
| 232 String linkedHashA; | |
| 233 String linkedHashB; | |
| 234 { | |
| 235 // Ensure unlinked bundles. | |
| 236 manager.getUnlinkedBundles(context); | |
| 237 await manager.onUnlinkedComplete; | |
| 238 | |
| 239 // Now we should be able to get linked bundles. | |
| 240 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 241 expect(linkedPackages, hasLength(2)); | |
| 242 | |
| 243 // Verify that files with linked bundles were created. | |
| 244 LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa'); | |
| 245 LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb'); | |
| 246 linkedHashA = packageA.linkedHash; | |
| 247 linkedHashB = packageB.linkedHash; | |
| 248 _assertFileExists(folderA, 'linked_spec_$linkedHashA.ds'); | |
| 249 _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds'); | |
| 250 } | |
| 251 | |
| 252 // Session 2. | |
| 253 // Use DartSdk with a different API signature. | |
| 254 // Different linked bundles should be created. | |
| 255 { | |
| 256 MockSdk sdk = new MockSdk(resourceProvider: resourceProvider); | |
| 257 sdk.updateUriFile('dart:math', (String content) { | |
| 258 return content + ' class NewMathClass {}'; | |
| 259 }); | |
| 260 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 261 new DartUriResolver(sdk), | |
| 262 resourceResolver, | |
| 263 new PackageMapUriResolver(resourceProvider, { | |
| 264 'aaa': [libFolderA], | |
| 265 'bbb': [libFolderB], | |
| 266 }) | |
| 267 ]); | |
| 268 | |
| 269 // Ensure unlinked bundles. | |
| 270 manager.getUnlinkedBundles(context); | |
| 271 await manager.onUnlinkedComplete; | |
| 272 | |
| 273 // Now we should be able to get linked bundles. | |
| 274 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 275 expect(linkedPackages, hasLength(2)); | |
| 276 | |
| 277 // Verify that new files with linked bundles were created. | |
| 278 LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa'); | |
| 279 LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb'); | |
| 280 expect(packageA.linkedHash, isNot(linkedHashA)); | |
| 281 expect(packageB.linkedHash, isNot(linkedHashB)); | |
| 282 _assertFileExists(folderA, 'linked_spec_${packageA.linkedHash}.ds'); | |
| 283 _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds'); | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 test_getLinkedBundles_cached_inconsistent_majorVersion() async { | |
| 288 String pathA = '$CACHE/aaa'; | |
| 289 newFile( | |
| 290 '$pathA/lib/a.dart', | |
| 291 ''' | |
| 292 class A {} | |
| 293 int a; | |
| 294 '''); | |
| 295 // Configure packages resolution. | |
| 296 Folder libFolderA = newFolder('$pathA/lib'); | |
| 297 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 298 sdkResolver, | |
| 299 resourceResolver, | |
| 300 new PackageMapUriResolver(resourceProvider, { | |
| 301 'aaa': [libFolderA], | |
| 302 }) | |
| 303 ]); | |
| 304 | |
| 305 // Session 1. | |
| 306 // Create the linked bundle and cache it in a file. | |
| 307 { | |
| 308 // Ensure unlinked bundles. | |
| 309 manager.getUnlinkedBundles(context); | |
| 310 await manager.onUnlinkedComplete; | |
| 311 | |
| 312 // Now we should be able to get the linked bundle. | |
| 313 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 314 expect(linkedPackages, hasLength(1)); | |
| 315 } | |
| 316 | |
| 317 // Session 2. | |
| 318 // Recreate manager with a different major version. | |
| 319 // It cannot use the previously cache linked bundle. | |
| 320 // The reason is that we cannot use the cached unlinked bundle. | |
| 321 { | |
| 322 _createManager(majorVersion: 12345); | |
| 323 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 324 expect(linkedPackages, isEmpty); | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 test_getLinkedBundles_hasCycle() async { | |
| 329 newFile( | |
| 330 '$CACHE/aaa/lib/a.dart', | |
| 331 ''' | |
| 332 import 'package:bbb/b.dart'; | |
| 333 class A {} | |
| 334 int a1; | |
| 335 B a2; | |
| 336 '''); | |
| 337 newFile( | |
| 338 '$CACHE/bbb/lib/b.dart', | |
| 339 ''' | |
| 340 import 'package:ccc/c.dart'; | |
| 341 class B {} | |
| 342 C b; | |
| 343 '''); | |
| 344 newFile( | |
| 345 '$CACHE/ccc/lib/c.dart', | |
| 346 ''' | |
| 347 import 'package:aaa/a.dart'; | |
| 348 import 'package:ddd/d.dart'; | |
| 349 class C {} | |
| 350 A c1; | |
| 351 D c2; | |
| 352 '''); | |
| 353 newFile( | |
| 354 '$CACHE/ddd/lib/d.dart', | |
| 355 ''' | |
| 356 class D {} | |
| 357 String d; | |
| 358 '''); | |
| 359 | |
| 360 // Configure packages resolution. | |
| 361 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 362 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 363 Folder libFolderC = newFolder('$CACHE/ccc/lib'); | |
| 364 Folder libFolderD = newFolder('$CACHE/ddd/lib'); | |
| 365 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 366 sdkResolver, | |
| 367 resourceResolver, | |
| 368 new PackageMapUriResolver(resourceProvider, { | |
| 369 'aaa': [libFolderA], | |
| 370 'bbb': [libFolderB], | |
| 371 'ccc': [libFolderC], | |
| 372 'ddd': [libFolderD], | |
| 373 }) | |
| 374 ]); | |
| 375 | |
| 376 // Ensure unlinked bundles. | |
| 377 manager.getUnlinkedBundles(context); | |
| 378 await manager.onUnlinkedComplete; | |
| 379 | |
| 380 // Now we should be able to get linked bundles. | |
| 381 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 382 expect(linkedPackages, hasLength(4)); | |
| 383 | |
| 384 // package:aaa | |
| 385 { | |
| 386 LinkedPubPackage linkedPackage = linkedPackages | |
| 387 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 388 expect(linkedPackage.linked.linkedLibraryUris, ['package:aaa/a.dart']); | |
| 389 _assertHasLinkedVariable(linkedPackage, 'a1', 'int', | |
| 390 expectedTypeNameUri: 'dart:core'); | |
| 391 _assertHasLinkedVariable(linkedPackage, 'a2', 'B', | |
| 392 expectedTypeNameUri: 'package:bbb/b.dart'); | |
| 393 } | |
| 394 | |
| 395 // package:bbb | |
| 396 { | |
| 397 LinkedPubPackage linkedPackage = linkedPackages | |
| 398 .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb'); | |
| 399 expect(linkedPackage.linked.linkedLibraryUris, ['package:bbb/b.dart']); | |
| 400 _assertHasLinkedVariable(linkedPackage, 'b', 'C', | |
| 401 expectedTypeNameUri: 'package:ccc/c.dart'); | |
| 402 } | |
| 403 | |
| 404 // package:ccc | |
| 405 { | |
| 406 LinkedPubPackage linkedPackage = linkedPackages | |
| 407 .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc'); | |
| 408 expect(linkedPackage.linked.linkedLibraryUris, ['package:ccc/c.dart']); | |
| 409 _assertHasLinkedVariable(linkedPackage, 'c1', 'A', | |
| 410 expectedTypeNameUri: 'package:aaa/a.dart'); | |
| 411 _assertHasLinkedVariable(linkedPackage, 'c2', 'D', | |
| 412 expectedTypeNameUri: 'package:ddd/d.dart'); | |
| 413 } | |
| 414 | |
| 415 // package:ddd | |
| 416 { | |
| 417 LinkedPubPackage linkedPackage = linkedPackages | |
| 418 .singleWhere((linkedPackage) => linkedPackage.package.name == 'ddd'); | |
| 419 expect(linkedPackage.linked.linkedLibraryUris, ['package:ddd/d.dart']); | |
| 420 _assertHasLinkedVariable(linkedPackage, 'd', 'String', | |
| 421 expectedTypeNameUri: 'dart:core'); | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 test_getLinkedBundles_missingBundle_listed() async { | |
| 426 newFile( | |
| 427 '$CACHE/aaa/lib/a.dart', | |
| 428 ''' | |
| 429 import 'package:bbb/b.dart'; | |
| 430 B a; | |
| 431 '''); | |
| 432 newFile( | |
| 433 '$CACHE/bbb/lib/b.dart', | |
| 434 ''' | |
| 435 class B {} | |
| 436 '''); | |
| 437 | |
| 438 // Configure packages resolution. | |
| 439 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 440 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 441 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 442 sdkResolver, | |
| 443 resourceResolver, | |
| 444 new PackageMapUriResolver(resourceProvider, { | |
| 445 'aaa': [libFolderA], | |
| 446 'bbb': [libFolderB], | |
| 447 }) | |
| 448 ]); | |
| 449 | |
| 450 // Ensure unlinked bundles for 'aaa'. | |
| 451 await manager.computeUnlinkedForFolder('aaa', libFolderA); | |
| 452 | |
| 453 // Try to link. | |
| 454 // Neither 'aaa' nor 'bbb' are linked. | |
| 455 // 'bbb' does not have the unlinked bundle. | |
| 456 // 'aaa' is not linked because it references 'bbb', which is listed. | |
| 457 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 458 expect(linkedPackages, hasLength(0)); | |
| 459 } | |
| 460 | |
| 461 test_getLinkedBundles_missingBundle_listed_chained() async { | |
| 462 newFile( | |
| 463 '$CACHE/aaa/lib/a.dart', | |
| 464 ''' | |
| 465 import 'package:bbb/b.dart'; | |
| 466 '''); | |
| 467 newFile( | |
| 468 '$CACHE/bbb/lib/b.dart', | |
| 469 ''' | |
| 470 import 'package:ccc/c.dart'; | |
| 471 '''); | |
| 472 newFile( | |
| 473 '$CACHE/ccc/lib/c.dart', | |
| 474 ''' | |
| 475 class C {} | |
| 476 '''); | |
| 477 | |
| 478 // Configure packages resolution. | |
| 479 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 480 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 481 Folder libFolderC = newFolder('$CACHE/ccc/lib'); | |
| 482 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 483 sdkResolver, | |
| 484 resourceResolver, | |
| 485 new PackageMapUriResolver(resourceProvider, { | |
| 486 'aaa': [libFolderA], | |
| 487 'bbb': [libFolderB], | |
| 488 'ccc': [libFolderC], | |
| 489 }) | |
| 490 ]); | |
| 491 | |
| 492 // Ensure unlinked bundles. | |
| 493 await manager.computeUnlinkedForFolder('aaa', libFolderA); | |
| 494 await manager.computeUnlinkedForFolder('bbb', libFolderB); | |
| 495 | |
| 496 // Try to link. | |
| 497 // Neither 'aaa' nor 'bbb' are linked. | |
| 498 // 'ccc' is listed in the package map, but its unlinked bundle is not ready. | |
| 499 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 500 expect(linkedPackages, hasLength(0)); | |
| 501 } | |
| 502 | |
| 503 test_getLinkedBundles_missingBundle_listed_partial() async { | |
| 504 newFile( | |
| 505 '$CACHE/aaa/lib/a.dart', | |
| 506 ''' | |
| 507 int a; | |
| 508 '''); | |
| 509 newFile( | |
| 510 '$CACHE/bbb/lib/b.dart', | |
| 511 ''' | |
| 512 import 'package:ccc/c.dart'; | |
| 513 C b; | |
| 514 '''); | |
| 515 newFile( | |
| 516 '$CACHE/ccc/lib/c.dart', | |
| 517 ''' | |
| 518 class C {} | |
| 519 '''); | |
| 520 | |
| 521 // Configure packages resolution. | |
| 522 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 523 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 524 Folder libFolderC = newFolder('$CACHE/ccc/lib'); | |
| 525 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 526 sdkResolver, | |
| 527 resourceResolver, | |
| 528 new PackageMapUriResolver(resourceProvider, { | |
| 529 'aaa': [libFolderA], | |
| 530 'bbb': [libFolderB], | |
| 531 'ccc': [libFolderC], | |
| 532 }) | |
| 533 ]); | |
| 534 | |
| 535 // Ensure unlinked bundles for 'aaa'. | |
| 536 await manager.computeUnlinkedForFolder('aaa', libFolderA); | |
| 537 await manager.computeUnlinkedForFolder('bbb', libFolderB); | |
| 538 | |
| 539 // Try to link. | |
| 540 // Only 'aaa' is linked. | |
| 541 // The package 'bbb' references the listed 'ccc' without unlinked bundle. | |
| 542 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 543 expect(linkedPackages, hasLength(1)); | |
| 544 | |
| 545 // package:aaa | |
| 546 { | |
| 547 LinkedPubPackage linkedPackage = linkedPackages | |
| 548 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 549 _assertHasLinkedVariable(linkedPackage, 'a', 'int', | |
| 550 expectedTypeNameUri: 'dart:core'); | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 test_getLinkedBundles_missingBundle_notListed() async { | |
| 555 newFile( | |
| 556 '$CACHE/aaa/lib/a.dart', | |
| 557 ''' | |
| 558 int a; | |
| 559 '''); | |
| 560 newFile( | |
| 561 '$CACHE/bbb/lib/b.dart', | |
| 562 ''' | |
| 563 import 'package:ccc/c.dart'; | |
| 564 int b1; | |
| 565 C b2; | |
| 566 '''); | |
| 567 | |
| 568 // Configure packages resolution. | |
| 569 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 570 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 571 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 572 sdkResolver, | |
| 573 resourceResolver, | |
| 574 new PackageMapUriResolver(resourceProvider, { | |
| 575 'aaa': [libFolderA], | |
| 576 'bbb': [libFolderB], | |
| 577 }) | |
| 578 ]); | |
| 579 | |
| 580 // Ensure unlinked bundles. | |
| 581 manager.getUnlinkedBundles(context); | |
| 582 await manager.onUnlinkedComplete; | |
| 583 | |
| 584 // Try to link. | |
| 585 // Both 'aaa' and 'bbb' are linked. | |
| 586 // The package 'ccc' is not listed, so it cannot be resolved anyway, | |
| 587 // with summaries or without them. | |
| 588 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 589 expect(linkedPackages, hasLength(2)); | |
| 590 | |
| 591 // package:aaa | |
| 592 { | |
| 593 LinkedPubPackage linkedPackage = linkedPackages | |
| 594 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 595 _assertHasLinkedVariable(linkedPackage, 'a', 'int', | |
| 596 expectedTypeNameUri: 'dart:core'); | |
| 597 } | |
| 598 | |
| 599 // package:bbb | |
| 600 { | |
| 601 LinkedPubPackage linkedPackage = linkedPackages | |
| 602 .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb'); | |
| 603 _assertHasLinkedVariable(linkedPackage, 'b1', 'int', | |
| 604 expectedTypeNameUri: 'dart:core'); | |
| 605 _assertHasLinkedVariable(linkedPackage, 'b2', 'C', | |
| 606 expectedToBeResolved: false); | |
| 607 } | |
| 608 } | |
| 609 | |
| 610 test_getLinkedBundles_missingLibrary() async { | |
| 611 newFile( | |
| 612 '$CACHE/aaa/lib/a.dart', | |
| 613 ''' | |
| 614 import 'package:bbb/b2.dart'; | |
| 615 int a1; | |
| 616 B2 a2; | |
| 617 '''); | |
| 618 newFile( | |
| 619 '$CACHE/bbb/lib/b.dart', | |
| 620 ''' | |
| 621 class B {} | |
| 622 int b = 42; | |
| 623 '''); | |
| 624 | |
| 625 // Configure packages resolution. | |
| 626 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 627 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 628 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 629 sdkResolver, | |
| 630 resourceResolver, | |
| 631 new PackageMapUriResolver(resourceProvider, { | |
| 632 'aaa': [libFolderA], | |
| 633 'bbb': [libFolderB], | |
| 634 }) | |
| 635 ]); | |
| 636 | |
| 637 // Ensure unlinked bundles. | |
| 638 manager.getUnlinkedBundles(context); | |
| 639 await manager.onUnlinkedComplete; | |
| 640 | |
| 641 // Try to link. | |
| 642 // Both 'aaa' and 'bbb' are linked. | |
| 643 // The name 'B2' in 'a.dart' is not resolved. | |
| 644 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 645 expect(linkedPackages, hasLength(2)); | |
| 646 | |
| 647 // package:aaa | |
| 648 { | |
| 649 LinkedPubPackage linkedPackage = linkedPackages | |
| 650 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 651 _assertHasLinkedVariable(linkedPackage, 'a1', 'int', | |
| 652 expectedTypeNameUri: 'dart:core'); | |
| 653 _assertHasLinkedVariable(linkedPackage, 'a2', 'B2', | |
| 654 expectedToBeResolved: false); | |
| 655 } | |
| 656 | |
| 657 // package:bbb | |
| 658 { | |
| 659 LinkedPubPackage linkedPackage = linkedPackages | |
| 660 .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb'); | |
| 661 _assertHasLinkedVariable(linkedPackage, 'b', 'int', | |
| 662 expectedTypeNameUri: 'dart:core'); | |
| 663 } | |
| 664 } | |
| 665 | |
| 666 test_getLinkedBundles_missingLibrary_hasCycle() async { | |
| 667 newFile( | |
| 668 '$CACHE/aaa/lib/a.dart', | |
| 669 ''' | |
| 670 import 'package:bbb/b.dart'; | |
| 671 B a; | |
| 672 '''); | |
| 673 newFile( | |
| 674 '$CACHE/bbb/lib/b.dart', | |
| 675 ''' | |
| 676 import 'package:aaa/a.dart'; | |
| 677 import 'package:ccc/c2.dart'; | |
| 678 class B {} | |
| 679 int b1; | |
| 680 C2 b2; | |
| 681 '''); | |
| 682 newFile( | |
| 683 '$CACHE/ccc/lib/c.dart', | |
| 684 ''' | |
| 685 class C {} | |
| 686 int c; | |
| 687 '''); | |
| 688 | |
| 689 // Configure packages resolution. | |
| 690 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 691 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 692 Folder libFolderC = newFolder('$CACHE/ccc/lib'); | |
| 693 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 694 sdkResolver, | |
| 695 resourceResolver, | |
| 696 new PackageMapUriResolver(resourceProvider, { | |
| 697 'aaa': [libFolderA], | |
| 698 'bbb': [libFolderB], | |
| 699 'ccc': [libFolderC], | |
| 700 }) | |
| 701 ]); | |
| 702 | |
| 703 // Ensure unlinked bundles. | |
| 704 manager.getUnlinkedBundles(context); | |
| 705 await manager.onUnlinkedComplete; | |
| 706 | |
| 707 // Try to link. | |
| 708 // All bundles 'aaa' and 'bbb' and 'ccc' are linked. | |
| 709 // The name 'C2' in 'b.dart' is not resolved. | |
| 710 // We have the corresponding unlinked bundle, and it is full, so if it does | |
| 711 // not have the library 'package:ccc/c2.dart', this means that this library | |
| 712 // does not exist in 'ccc' at all. | |
| 713 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 714 expect(linkedPackages, hasLength(3)); | |
| 715 | |
| 716 // package:aaa | |
| 717 { | |
| 718 LinkedPubPackage linkedPackage = linkedPackages | |
| 719 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 720 _assertHasLinkedVariable(linkedPackage, 'a', 'B', | |
| 721 expectedTypeNameUri: 'package:bbb/b.dart'); | |
| 722 } | |
| 723 | |
| 724 // package:bbb | |
| 725 { | |
| 726 LinkedPubPackage linkedPackage = linkedPackages | |
| 727 .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb'); | |
| 728 _assertHasLinkedVariable(linkedPackage, 'b1', 'int', | |
| 729 expectedTypeNameUri: 'dart:core'); | |
| 730 _assertHasLinkedVariable(linkedPackage, 'b2', 'C2', | |
| 731 expectedToBeResolved: false); | |
| 732 } | |
| 733 | |
| 734 // package:ccc | |
| 735 { | |
| 736 LinkedPubPackage linkedPackage = linkedPackages | |
| 737 .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc'); | |
| 738 _assertHasLinkedVariable(linkedPackage, 'c', 'int', | |
| 739 expectedTypeNameUri: 'dart:core'); | |
| 740 } | |
| 741 } | |
| 742 | |
| 743 test_getLinkedBundles_noCycle() async { | |
| 744 newFile( | |
| 745 '$CACHE/aaa/lib/a.dart', | |
| 746 ''' | |
| 747 class A {} | |
| 748 int a; | |
| 749 '''); | |
| 750 newFile( | |
| 751 '$CACHE/bbb/lib/b.dart', | |
| 752 ''' | |
| 753 import 'package:aaa/a.dart'; | |
| 754 A b; | |
| 755 '''); | |
| 756 | |
| 757 // Configure packages resolution. | |
| 758 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 759 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 760 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 761 sdkResolver, | |
| 762 resourceResolver, | |
| 763 new PackageMapUriResolver(resourceProvider, { | |
| 764 'aaa': [libFolderA], | |
| 765 'bbb': [libFolderB], | |
| 766 }) | |
| 767 ]); | |
| 768 | |
| 769 // Ensure unlinked bundles. | |
| 770 manager.getUnlinkedBundles(context); | |
| 771 await manager.onUnlinkedComplete; | |
| 772 | |
| 773 // Now we should be able to get linked bundles. | |
| 774 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 775 expect(linkedPackages, hasLength(2)); | |
| 776 | |
| 777 // package:aaa | |
| 778 { | |
| 779 LinkedPubPackage linkedPackage = linkedPackages | |
| 780 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 781 _assertHasLinkedVariable(linkedPackage, 'a', 'int', | |
| 782 expectedTypeNameUri: 'dart:core'); | |
| 783 } | |
| 784 | |
| 785 // package:bbb | |
| 786 { | |
| 787 LinkedPubPackage linkedPackage = linkedPackages | |
| 788 .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb'); | |
| 789 _assertHasLinkedVariable(linkedPackage, 'b', 'A', | |
| 790 expectedTypeNameUri: 'package:aaa/a.dart'); | |
| 791 } | |
| 792 } | |
| 793 | |
| 794 test_getLinkedBundles_noCycle_relativeUri() async { | |
| 795 newFile( | |
| 796 '$CACHE/aaa/lib/a.dart', | |
| 797 ''' | |
| 798 import 'src/a2.dart'; | |
| 799 A a; | |
| 800 '''); | |
| 801 newFile( | |
| 802 '$CACHE/aaa/lib/src/a2.dart', | |
| 803 ''' | |
| 804 class A {} | |
| 805 '''); | |
| 806 | |
| 807 // Configure packages resolution. | |
| 808 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 809 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 810 sdkResolver, | |
| 811 resourceResolver, | |
| 812 new PackageMapUriResolver(resourceProvider, { | |
| 813 'aaa': [libFolderA], | |
| 814 }) | |
| 815 ]); | |
| 816 | |
| 817 // Ensure unlinked bundles. | |
| 818 manager.getUnlinkedBundles(context); | |
| 819 await manager.onUnlinkedComplete; | |
| 820 | |
| 821 // Link. | |
| 822 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 823 expect(linkedPackages, hasLength(1)); | |
| 824 | |
| 825 // package:aaa | |
| 826 { | |
| 827 LinkedPubPackage linkedPackage = linkedPackages | |
| 828 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 829 _assertHasLinkedVariable(linkedPackage, 'a', 'A', | |
| 830 expectedTypeNameUri: 'src/a2.dart'); | |
| 831 } | |
| 832 } | |
| 833 | |
| 834 test_getLinkedBundles_noCycle_withExport() async { | |
| 835 newFile( | |
| 836 '$CACHE/aaa/lib/a.dart', | |
| 837 ''' | |
| 838 import 'package:bbb/b.dart'; | |
| 839 C a; | |
| 840 '''); | |
| 841 newFile( | |
| 842 '$CACHE/bbb/lib/b.dart', | |
| 843 ''' | |
| 844 export 'package:ccc/c.dart'; | |
| 845 '''); | |
| 846 newFile( | |
| 847 '$CACHE/ccc/lib/c.dart', | |
| 848 ''' | |
| 849 class C {} | |
| 850 '''); | |
| 851 | |
| 852 // Configure packages resolution. | |
| 853 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 854 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 855 Folder libFolderC = newFolder('$CACHE/ccc/lib'); | |
| 856 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 857 sdkResolver, | |
| 858 resourceResolver, | |
| 859 new PackageMapUriResolver(resourceProvider, { | |
| 860 'aaa': [libFolderA], | |
| 861 'bbb': [libFolderB], | |
| 862 'ccc': [libFolderC], | |
| 863 }) | |
| 864 ]); | |
| 865 | |
| 866 // Ensure unlinked bundles. | |
| 867 manager.getUnlinkedBundles(context); | |
| 868 await manager.onUnlinkedComplete; | |
| 869 | |
| 870 // Now we should be able to get linked bundles. | |
| 871 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 872 expect(linkedPackages, hasLength(3)); | |
| 873 | |
| 874 // package:aaa | |
| 875 { | |
| 876 LinkedPubPackage linkedPackage = linkedPackages | |
| 877 .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa'); | |
| 878 _assertHasLinkedVariable(linkedPackage, 'a', 'C', | |
| 879 expectedTypeNameUri: 'package:ccc/c.dart'); | |
| 880 } | |
| 881 } | |
| 882 | |
| 883 test_getLinkedBundles_wrongScheme() async { | |
| 884 newFile( | |
| 885 '$CACHE/aaa/lib/a.dart', | |
| 886 ''' | |
| 887 import 'xxx:yyy/zzz.dart'; | |
| 888 int a1; | |
| 889 Z a2; | |
| 890 '''); | |
| 891 | |
| 892 // Configure packages resolution. | |
| 893 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 894 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 895 sdkResolver, | |
| 896 resourceResolver, | |
| 897 new PackageMapUriResolver(resourceProvider, { | |
| 898 'aaa': [libFolderA], | |
| 899 }) | |
| 900 ]); | |
| 901 | |
| 902 // Ensure unlinked bundles. | |
| 903 manager.getUnlinkedBundles(context); | |
| 904 await manager.onUnlinkedComplete; | |
| 905 | |
| 906 // Try to link. | |
| 907 // The package 'aaa' is not linked. | |
| 908 // We don't know how to handle the URI scheme 'xxx'. | |
| 909 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 910 expect(linkedPackages, hasLength(0)); | |
| 911 } | |
| 912 | |
| 913 test_getPackageName() { | |
| 914 String getPackageName(String uriStr) { | |
| 915 return PubSummaryManager.getPackageName(uriStr); | |
| 916 } | |
| 917 | |
| 918 expect(getPackageName('package:foo/bar.dart'), 'foo'); | |
| 919 expect(getPackageName('package:foo/bar/baz.dart'), 'foo'); | |
| 920 expect(getPackageName('wrong:foo/bar.dart'), isNull); | |
| 921 expect(getPackageName('package:foo'), isNull); | |
| 922 } | |
| 923 | |
| 924 test_getUnlinkedBundles() async { | |
| 925 // Create package files. | |
| 926 newFile( | |
| 927 '$CACHE/aaa/lib/a.dart', | |
| 928 ''' | |
| 929 class A {} | |
| 930 '''); | |
| 931 newFile( | |
| 932 '$CACHE/aaa/lib/src/a2.dart', | |
| 933 ''' | |
| 934 class A2 {} | |
| 935 '''); | |
| 936 newFile( | |
| 937 '$CACHE/bbb/lib/b.dart', | |
| 938 ''' | |
| 939 class B {} | |
| 940 '''); | |
| 941 | |
| 942 // Configure packages resolution. | |
| 943 Folder libFolderA = newFolder('$CACHE/aaa/lib'); | |
| 944 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 945 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 946 sdkResolver, | |
| 947 resourceResolver, | |
| 948 new PackageMapUriResolver(resourceProvider, { | |
| 949 'aaa': [libFolderA], | |
| 950 'bbb': [libFolderB], | |
| 951 }) | |
| 952 ]); | |
| 953 | |
| 954 // No unlinked bundles yet. | |
| 955 { | |
| 956 Map<PubPackage, PackageBundle> bundles = | |
| 957 manager.getUnlinkedBundles(context); | |
| 958 expect(bundles, isEmpty); | |
| 959 } | |
| 960 | |
| 961 // The requested unlinked bundles must be available after the wait. | |
| 962 await manager.onUnlinkedComplete; | |
| 963 { | |
| 964 Map<PubPackage, PackageBundle> bundles = | |
| 965 manager.getUnlinkedBundles(context); | |
| 966 expect(bundles, hasLength(2)); | |
| 967 { | |
| 968 PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa'); | |
| 969 expect(bundle.linkedLibraryUris, isEmpty); | |
| 970 expect(bundle.unlinkedUnitUris, | |
| 971 ['package:aaa/a.dart', 'package:aaa/src/a2.dart']); | |
| 972 expect(bundle.unlinkedUnits, hasLength(2)); | |
| 973 expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['A']); | |
| 974 expect(bundle.unlinkedUnits[1].classes.map((c) => c.name), ['A2']); | |
| 975 } | |
| 976 { | |
| 977 PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb'); | |
| 978 expect(bundle.linkedLibraryUris, isEmpty); | |
| 979 expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']); | |
| 980 expect(bundle.unlinkedUnits, hasLength(1)); | |
| 981 expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']); | |
| 982 } | |
| 983 } | |
| 984 | |
| 985 // The files must be created. | |
| 986 _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME); | |
| 987 _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 988 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME); | |
| 989 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 990 } | |
| 991 | |
| 992 test_getUnlinkedBundles_inconsistent_majorVersion() async { | |
| 993 // Create package files. | |
| 994 newFile( | |
| 995 '$CACHE/aaa/lib/a.dart', | |
| 996 ''' | |
| 997 class A {} | |
| 998 '''); | |
| 999 | |
| 1000 // Configure packages resolution. | |
| 1001 Folder libFolder = newFolder('$CACHE/aaa/lib'); | |
| 1002 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 1003 sdkResolver, | |
| 1004 resourceResolver, | |
| 1005 new PackageMapUriResolver(resourceProvider, { | |
| 1006 'aaa': [libFolder], | |
| 1007 }) | |
| 1008 ]); | |
| 1009 | |
| 1010 /** | |
| 1011 * Verify that the [manager] has exactly one cache bundle `aaa`. | |
| 1012 */ | |
| 1013 void _assertSingleBundle() { | |
| 1014 Map<PubPackage, PackageBundle> bundles = | |
| 1015 manager.getUnlinkedBundles(context); | |
| 1016 expect(bundles, hasLength(1)); | |
| 1017 PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa'); | |
| 1018 expect(bundle.unlinkedUnitUris, ['package:aaa/a.dart']); | |
| 1019 } | |
| 1020 | |
| 1021 // Compute the bundle using a non-default major version. | |
| 1022 _createManager(majorVersion: 12345); | |
| 1023 manager.getUnlinkedBundles(context); | |
| 1024 await manager.onUnlinkedComplete; | |
| 1025 _assertSingleBundle(); | |
| 1026 | |
| 1027 // Recompute when using the default major version. | |
| 1028 _createManager(); | |
| 1029 expect(manager.getUnlinkedBundles(context), isEmpty); | |
| 1030 | |
| 1031 // Wait for the bundle to be computed. | |
| 1032 await manager.onUnlinkedComplete; | |
| 1033 _assertSingleBundle(); | |
| 1034 _assertFileExists(libFolder.parent, PubSummaryManager.UNLINKED_NAME); | |
| 1035 _assertFileExists(libFolder.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 1036 | |
| 1037 // Can read from the file again. | |
| 1038 _createManager(); | |
| 1039 _assertSingleBundle(); | |
| 1040 } | |
| 1041 | |
| 1042 test_getUnlinkedBundles_notPubCache_dontCreate() async { | |
| 1043 String aaaPath = '/Users/user/projects/aaa'; | |
| 1044 // Create package files. | |
| 1045 newFile( | |
| 1046 '$aaaPath/lib/a.dart', | |
| 1047 ''' | |
| 1048 class A {} | |
| 1049 '''); | |
| 1050 newFile( | |
| 1051 '$CACHE/bbb/lib/b.dart', | |
| 1052 ''' | |
| 1053 class B {} | |
| 1054 '''); | |
| 1055 | |
| 1056 // Configure packages resolution. | |
| 1057 Folder libFolderA = getFolder('$aaaPath/lib'); | |
| 1058 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 1059 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 1060 sdkResolver, | |
| 1061 resourceResolver, | |
| 1062 new PackageMapUriResolver(resourceProvider, { | |
| 1063 'aaa': [libFolderA], | |
| 1064 'bbb': [libFolderB], | |
| 1065 }) | |
| 1066 ]); | |
| 1067 | |
| 1068 // No unlinked bundles initially. | |
| 1069 { | |
| 1070 Map<PubPackage, PackageBundle> bundles = | |
| 1071 manager.getUnlinkedBundles(context); | |
| 1072 expect(bundles, isEmpty); | |
| 1073 } | |
| 1074 | |
| 1075 // Wait for unlinked bundles to be computed. | |
| 1076 await manager.onUnlinkedComplete; | |
| 1077 Map<PubPackage, PackageBundle> bundles = | |
| 1078 manager.getUnlinkedBundles(context); | |
| 1079 // We have just one bundle - for 'bbb'. | |
| 1080 expect(bundles, hasLength(1)); | |
| 1081 // We computed the unlinked bundle for 'bbb'. | |
| 1082 { | |
| 1083 PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb'); | |
| 1084 expect(bundle.linkedLibraryUris, isEmpty); | |
| 1085 expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']); | |
| 1086 expect(bundle.unlinkedUnits, hasLength(1)); | |
| 1087 expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']); | |
| 1088 } | |
| 1089 | |
| 1090 // The files must be created. | |
| 1091 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME); | |
| 1092 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 1093 } | |
| 1094 | |
| 1095 test_getUnlinkedBundles_notPubCache_useExisting() async { | |
| 1096 String aaaPath = '/Users/user/projects/aaa'; | |
| 1097 // Create package files. | |
| 1098 { | |
| 1099 File file = newFile( | |
| 1100 '$aaaPath/lib/a.dart', | |
| 1101 ''' | |
| 1102 class A {} | |
| 1103 '''); | |
| 1104 PackageBundleAssembler assembler = new PackageBundleAssembler() | |
| 1105 ..addUnlinkedUnit( | |
| 1106 file.createSource(Uri.parse('package:aaa/a.dart')), | |
| 1107 new UnlinkedUnitBuilder()); | |
| 1108 resourceProvider.newFileWithBytes( | |
| 1109 resourceProvider | |
| 1110 .convertPath('$aaaPath/${PubSummaryManager.UNLINKED_SPEC_NAME}'), | |
| 1111 assembler.assemble().toBuffer()); | |
| 1112 } | |
| 1113 newFile( | |
| 1114 '$CACHE/bbb/lib/b.dart', | |
| 1115 ''' | |
| 1116 class B {} | |
| 1117 '''); | |
| 1118 | |
| 1119 // Configure packages resolution. | |
| 1120 Folder libFolderA = getFolder('$aaaPath/lib'); | |
| 1121 Folder libFolderB = newFolder('$CACHE/bbb/lib'); | |
| 1122 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 1123 sdkResolver, | |
| 1124 resourceResolver, | |
| 1125 new PackageMapUriResolver(resourceProvider, { | |
| 1126 'aaa': [libFolderA], | |
| 1127 'bbb': [libFolderB], | |
| 1128 }) | |
| 1129 ]); | |
| 1130 | |
| 1131 // Request already available unlinked bundles. | |
| 1132 { | |
| 1133 Map<PubPackage, PackageBundle> bundles = | |
| 1134 manager.getUnlinkedBundles(context); | |
| 1135 expect(bundles, hasLength(1)); | |
| 1136 // We get the unlinked bundle for 'aaa' because it already exists. | |
| 1137 { | |
| 1138 PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa'); | |
| 1139 expect(bundle, isNotNull); | |
| 1140 } | |
| 1141 } | |
| 1142 | |
| 1143 // Wait for unlinked bundles to be computed. | |
| 1144 await manager.onUnlinkedComplete; | |
| 1145 Map<PubPackage, PackageBundle> bundles = | |
| 1146 manager.getUnlinkedBundles(context); | |
| 1147 expect(bundles, hasLength(2)); | |
| 1148 // We still have the unlinked bundle for 'aaa'. | |
| 1149 { | |
| 1150 PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa'); | |
| 1151 expect(bundle, isNotNull); | |
| 1152 } | |
| 1153 // We computed the unlinked bundle for 'bbb'. | |
| 1154 { | |
| 1155 PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb'); | |
| 1156 expect(bundle.linkedLibraryUris, isEmpty); | |
| 1157 expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']); | |
| 1158 expect(bundle.unlinkedUnits, hasLength(1)); | |
| 1159 expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']); | |
| 1160 } | |
| 1161 | |
| 1162 // The files must be created. | |
| 1163 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME); | |
| 1164 _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME); | |
| 1165 } | |
| 1166 | |
| 1167 test_getUnlinkedBundles_notPubCache_useExisting_inconsistent() async { | |
| 1168 String aaaPath = '/Users/user/projects/aaa'; | |
| 1169 // Create package files. | |
| 1170 newFile( | |
| 1171 '$aaaPath/lib/a.dart', | |
| 1172 ''' | |
| 1173 class A {} | |
| 1174 '''); | |
| 1175 | |
| 1176 // Compute the bundles. | |
| 1177 Folder libFolderA = getFolder('$aaaPath/lib'); | |
| 1178 await new PubSummaryManager(resourceProvider, '_.temp') | |
| 1179 .computeUnlinkedForFolder('aaa', libFolderA); | |
| 1180 | |
| 1181 // Configure packages resolution. | |
| 1182 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 1183 sdkResolver, | |
| 1184 resourceResolver, | |
| 1185 new PackageMapUriResolver(resourceProvider, { | |
| 1186 'aaa': [libFolderA], | |
| 1187 }) | |
| 1188 ]); | |
| 1189 | |
| 1190 // Request already available unlinked bundles. | |
| 1191 expect(manager.getUnlinkedBundles(context), hasLength(1)); | |
| 1192 | |
| 1193 // Update a Dart file. | |
| 1194 // So, the cached bundle cannot be reused. | |
| 1195 resourceProvider.updateFile( | |
| 1196 resourceProvider.convertPath('$aaaPath/lib/a.dart'), | |
| 1197 ''' | |
| 1198 class A2 {} | |
| 1199 '''); | |
| 1200 _createManager(); | |
| 1201 expect(manager.getUnlinkedBundles(context), isEmpty); | |
| 1202 | |
| 1203 // ...and because it is not in the pub cache, it will not be recomputed. | |
| 1204 await manager.onUnlinkedComplete; | |
| 1205 expect(manager.getUnlinkedBundles(context), isEmpty); | |
| 1206 } | |
| 1207 | |
| 1208 test_getUnlinkedBundles_nullPackageMap() async { | |
| 1209 context.sourceFactory = | |
| 1210 new SourceFactory(<UriResolver>[sdkResolver, resourceResolver]); | |
| 1211 Map<PubPackage, PackageBundle> bundles = | |
| 1212 manager.getUnlinkedBundles(context); | |
| 1213 expect(bundles, isEmpty); | |
| 1214 } | |
| 1215 | |
| 1216 test_isPathInPubCache_posix() { | |
| 1217 expect( | |
| 1218 PubSummaryManager.isPathInPubCache(pathos.posix, | |
| 1219 '/home/.pub-cache/hosted/pub.dartlang.org/foo/lib/bar.dart'), | |
| 1220 isTrue); | |
| 1221 expect( | |
| 1222 PubSummaryManager.isPathInPubCache( | |
| 1223 pathos.posix, '/home/.pub-cache/foo/lib/bar.dart'), | |
| 1224 isTrue); | |
| 1225 expect( | |
| 1226 PubSummaryManager.isPathInPubCache( | |
| 1227 pathos.posix, '/home/sources/dart/foo/lib/bar.dart'), | |
| 1228 isFalse); | |
| 1229 } | |
| 1230 | |
| 1231 test_isPathInPubCache_windows() { | |
| 1232 expect( | |
| 1233 PubSummaryManager.isPathInPubCache(pathos.windows, | |
| 1234 r'C:\Users\user\Setters\Pub\Cache\hosted\foo\lib\bar.dart'), | |
| 1235 isTrue); | |
| 1236 expect( | |
| 1237 PubSummaryManager.isPathInPubCache( | |
| 1238 pathos.windows, r'C:\Users\user\Sources\Dart\foo\lib\bar.dart'), | |
| 1239 isFalse); | |
| 1240 } | |
| 1241 | |
| 1242 void _assertFileExists(Folder folder, String fileName) { | |
| 1243 expect(folder.getChildAssumingFile(fileName).exists, isTrue); | |
| 1244 } | |
| 1245 | |
| 1246 void _assertHasLinkedVariable(LinkedPubPackage linkedPackage, | |
| 1247 String variableName, String expectedTypeName, | |
| 1248 {bool expectedToBeResolved: true, | |
| 1249 String expectedTypeNameUri: 'shouldBeSpecifiedIfResolved'}) { | |
| 1250 PackageBundle unlinked = linkedPackage.unlinked; | |
| 1251 PackageBundle linked = linkedPackage.linked; | |
| 1252 expect(unlinked, isNotNull); | |
| 1253 expect(linked, isNotNull); | |
| 1254 for (int i = 0; i < unlinked.unlinkedUnitUris.length; i++) { | |
| 1255 String unlinkedUnitUri = unlinked.unlinkedUnitUris[i]; | |
| 1256 UnlinkedUnit unlinkedUnit = unlinked.unlinkedUnits[i]; | |
| 1257 for (UnlinkedVariable v in unlinkedUnit.variables) { | |
| 1258 if (v.name == variableName) { | |
| 1259 int typeNameReference = v.type.reference; | |
| 1260 expect(unlinkedUnit.references[typeNameReference].name, | |
| 1261 expectedTypeName); | |
| 1262 for (int j = 0; j < linked.linkedLibraryUris.length; j++) { | |
| 1263 String linkedLibraryUri = linked.linkedLibraryUris[j]; | |
| 1264 if (linkedLibraryUri == unlinkedUnitUri) { | |
| 1265 LinkedLibrary linkedLibrary = linked.linkedLibraries[j]; | |
| 1266 LinkedUnit linkedUnit = linkedLibrary.units.single; | |
| 1267 int typeNameDependency = | |
| 1268 linkedUnit.references[typeNameReference].dependency; | |
| 1269 if (expectedToBeResolved) { | |
| 1270 expect(linkedLibrary.dependencies[typeNameDependency].uri, | |
| 1271 expectedTypeNameUri); | |
| 1272 } else { | |
| 1273 expect(typeNameDependency, isZero); | |
| 1274 } | |
| 1275 return; | |
| 1276 } | |
| 1277 } | |
| 1278 fail('Cannot find linked unit for $variableName in $linkedPackage'); | |
| 1279 } | |
| 1280 } | |
| 1281 } | |
| 1282 fail('Cannot find variable $variableName in $linkedPackage'); | |
| 1283 } | |
| 1284 | |
| 1285 void _createManager( | |
| 1286 {bool allowLinking: true, | |
| 1287 int majorVersion: PackageBundleAssembler.currentMajorVersion}) { | |
| 1288 manager = new PubSummaryManager(resourceProvider, '_.temp', | |
| 1289 allowLinking: allowLinking, majorVersion: majorVersion); | |
| 1290 } | |
| 1291 | |
| 1292 LinkedPubPackage _getLinkedPackage( | |
| 1293 List<LinkedPubPackage> packages, String name) { | |
| 1294 return packages | |
| 1295 .singleWhere((linkedPackage) => linkedPackage.package.name == name); | |
| 1296 } | |
| 1297 | |
| 1298 _testImpl_getLinkedBundles_cached_declaredVariables( | |
| 1299 String importOrExport) async { | |
| 1300 String pathA = '$CACHE/aaa/lib'; | |
| 1301 newFile('$pathA/foo.dart', 'class A {}'); | |
| 1302 newFile('$pathA/foo_io.dart', 'class A {}'); | |
| 1303 newFile('$pathA/foo_html.dart', 'class A {}'); | |
| 1304 newFile( | |
| 1305 '$pathA/user.dart', | |
| 1306 ''' | |
| 1307 $importOrExport 'foo.dart' | |
| 1308 if (dart.library.io) 'foo_io.dart' | |
| 1309 if (dart.library.html) 'foo_html.dart'; | |
| 1310 '''); | |
| 1311 // Configure packages resolution. | |
| 1312 Folder libFolderA = newFolder(pathA); | |
| 1313 context.sourceFactory = new SourceFactory(<UriResolver>[ | |
| 1314 sdkResolver, | |
| 1315 resourceResolver, | |
| 1316 new PackageMapUriResolver(resourceProvider, { | |
| 1317 'aaa': [libFolderA], | |
| 1318 }) | |
| 1319 ]); | |
| 1320 | |
| 1321 void _assertDependencyInUser(PackageBundle bundle, String shortName) { | |
| 1322 for (var i = 0; i < bundle.linkedLibraryUris.length; i++) { | |
| 1323 if (bundle.linkedLibraryUris[i].endsWith('user.dart')) { | |
| 1324 LinkedLibrary library = bundle.linkedLibraries[i]; | |
| 1325 expect(library.dependencies.map((d) => d.uri), | |
| 1326 unorderedEquals(['', 'dart:core', shortName])); | |
| 1327 return; | |
| 1328 } | |
| 1329 } | |
| 1330 fail('Not found user.dart in $bundle'); | |
| 1331 } | |
| 1332 | |
| 1333 // Session 1. | |
| 1334 // Create the linked bundle and cache it in a file. | |
| 1335 { | |
| 1336 // Ensure unlinked bundles. | |
| 1337 manager.getUnlinkedBundles(context); | |
| 1338 await manager.onUnlinkedComplete; | |
| 1339 | |
| 1340 // Now we should be able to get the linked bundle. | |
| 1341 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 1342 expect(linkedPackages, hasLength(1)); | |
| 1343 } | |
| 1344 | |
| 1345 // Session 2. | |
| 1346 // Recreate manager and don't allow it to perform new linking. | |
| 1347 // Set a declared variable, which is not used in the package. | |
| 1348 // We still can get the cached linked bundle. | |
| 1349 { | |
| 1350 context.declaredVariables.define('not.used.variable', 'baz'); | |
| 1351 _createManager(allowLinking: false); | |
| 1352 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 1353 expect(linkedPackages, hasLength(1)); | |
| 1354 _assertDependencyInUser(linkedPackages.single.linked, 'foo.dart'); | |
| 1355 } | |
| 1356 | |
| 1357 // Session 3. | |
| 1358 // Recreate manager and don't allow it to perform new linking. | |
| 1359 // Set the value of a referenced declared variable. | |
| 1360 // So, we cannot use the previously cached linked bundle. | |
| 1361 { | |
| 1362 context.declaredVariables.define('dart.library.io', 'does-not-matter'); | |
| 1363 _createManager(allowLinking: false); | |
| 1364 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 1365 expect(linkedPackages, isEmpty); | |
| 1366 } | |
| 1367 | |
| 1368 // Session 4. | |
| 1369 // Enable new linking, and configure to use 'foo_html.dart'. | |
| 1370 { | |
| 1371 context.declaredVariables.define('dart.library.html', 'true'); | |
| 1372 _createManager(); | |
| 1373 List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context); | |
| 1374 expect(linkedPackages, hasLength(1)); | |
| 1375 _assertDependencyInUser(linkedPackages.single.linked, 'foo_html.dart'); | |
| 1376 } | |
| 1377 } | |
| 1378 | |
| 1379 static PackageBundle _getBundleByPackageName( | |
| 1380 Map<PubPackage, PackageBundle> bundles, String name) { | |
| 1381 PubPackage package = | |
| 1382 bundles.keys.singleWhere((package) => package.name == name); | |
| 1383 return bundles[package]; | |
| 1384 } | |
| 1385 } | |
| OLD | NEW |