OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 pub_update_test; | 5 library pub_update_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
| 10 import '../../../pkg/unittest/lib/unittest.dart'; |
| 11 |
10 import '../../pub/lock_file.dart'; | 12 import '../../pub/lock_file.dart'; |
11 import '../../pub/package.dart'; | 13 import '../../pub/package.dart'; |
12 import '../../pub/pubspec.dart'; | 14 import '../../pub/pubspec.dart'; |
13 import '../../pub/source.dart'; | 15 import '../../pub/source.dart'; |
14 import '../../pub/source_registry.dart'; | 16 import '../../pub/source_registry.dart'; |
15 import '../../pub/system_cache.dart'; | 17 import '../../pub/system_cache.dart'; |
16 import '../../pub/utils.dart'; | 18 import '../../pub/utils.dart'; |
17 import '../../pub/version.dart'; | 19 import '../../pub/version.dart'; |
18 import '../../pub/version_solver.dart'; | 20 import '../../pub/version_solver.dart'; |
19 import '../../../pkg/unittest/lib/unittest.dart'; | 21 import 'test_pub.dart'; |
20 | 22 |
21 Matcher noVersion(List<String> packages) { | 23 Matcher noVersion(List<String> packages) { |
22 return predicate((x) { | 24 return predicate((x) { |
23 if (x is! NoVersionException) return false; | 25 if (x is! NoVersionException) return false; |
24 | 26 |
25 // Make sure the error string mentions the conflicting dependers. | 27 // Make sure the error string mentions the conflicting dependers. |
26 var message = x.toString(); | 28 var message = x.toString(); |
27 return packages.every((package) => message.contains(package)); | 29 return packages.every((package) => message.contains(package)); |
28 }, "is a NoVersionException"); | 30 }, "is a NoVersionException"); |
29 } | 31 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 65 |
64 return true; | 66 return true; |
65 }, "is a SourceMismatchException"); | 67 }, "is a SourceMismatchException"); |
66 } | 68 } |
67 | 69 |
68 MockSource source1; | 70 MockSource source1; |
69 MockSource source2; | 71 MockSource source2; |
70 Source versionlessSource; | 72 Source versionlessSource; |
71 | 73 |
72 main() { | 74 main() { |
| 75 initConfig(); |
| 76 |
73 testResolve('no dependencies', { | 77 testResolve('no dependencies', { |
74 'myapp 0.0.0': {} | 78 'myapp 0.0.0': {} |
75 }, result: { | 79 }, result: { |
76 'myapp from root': '0.0.0' | 80 'myapp from root': '0.0.0' |
77 }); | 81 }); |
78 | 82 |
79 testResolve('simple dependency tree', { | 83 testResolve('simple dependency tree', { |
80 'myapp 0.0.0': { | 84 'myapp 0.0.0': { |
81 'a': '1.0.0', | 85 'a': '1.0.0', |
82 'b': '1.0.0' | 86 'b': '1.0.0' |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 }, | 366 }, |
363 'a 1.0.0': {}, | 367 'a 1.0.0': {}, |
364 'a 2.0.0': { | 368 'a 2.0.0': { |
365 'b': '1.0.0' | 369 'b': '1.0.0' |
366 }, | 370 }, |
367 'b 1.0.0': { | 371 'b 1.0.0': { |
368 'a': '1.0.0' | 372 'a': '1.0.0' |
369 } | 373 } |
370 }, error: couldNotSolve); | 374 }, error: couldNotSolve); |
371 | 375 |
| 376 group('dev dependencies', () { |
| 377 testResolve("includes root package's dev dependencies", { |
| 378 'myapp 1.0.0': { |
| 379 '(dev) foo': '1.0.0', |
| 380 '(dev) bar': '1.0.0' |
| 381 }, |
| 382 'foo 1.0.0': {}, |
| 383 'bar 1.0.0': {} |
| 384 }, result: { |
| 385 'myapp from root': '1.0.0', |
| 386 'foo': '1.0.0', |
| 387 'bar': '1.0.0' |
| 388 }); |
| 389 |
| 390 testResolve("includes dev dependency's transitive dependencies", { |
| 391 'myapp 1.0.0': { |
| 392 '(dev) foo': '1.0.0' |
| 393 }, |
| 394 'foo 1.0.0': { |
| 395 'bar': '1.0.0' |
| 396 }, |
| 397 'bar 1.0.0': {} |
| 398 }, result: { |
| 399 'myapp from root': '1.0.0', |
| 400 'foo': '1.0.0', |
| 401 'bar': '1.0.0' |
| 402 }); |
| 403 |
| 404 testResolve("ignores transitive dependency's dev dependencies", { |
| 405 'myapp 1.0.0': { |
| 406 'foo': '1.0.0' |
| 407 }, |
| 408 'foo 1.0.0': { |
| 409 '(dev) bar': '1.0.0' |
| 410 }, |
| 411 'bar 1.0.0': {} |
| 412 }, result: { |
| 413 'myapp from root': '1.0.0', |
| 414 'foo': '1.0.0' |
| 415 }); |
| 416 }); |
| 417 } |
| 418 |
372 // TODO(rnystrom): More stuff to test: | 419 // TODO(rnystrom): More stuff to test: |
373 // - Depending on a non-existent package. | 420 // - Depending on a non-existent package. |
374 // - Test that only a certain number requests are sent to the mock source so we | 421 // - Test that only a certain number requests are sent to the mock source so we |
375 // can keep track of server traffic. | 422 // can keep track of server traffic. |
376 } | |
377 | 423 |
378 testResolve(description, packages, {lockfile, result, Matcher error}) { | 424 testResolve(description, packages, {lockfile, result, Matcher error}) { |
379 test(description, () { | 425 test(description, () { |
380 var cache = new SystemCache('.'); | 426 var cache = new SystemCache('.'); |
381 source1 = new MockSource('mock1'); | 427 source1 = new MockSource('mock1'); |
382 source2 = new MockSource('mock2'); | 428 source2 = new MockSource('mock2'); |
383 versionlessSource = new MockVersionlessSource(); | 429 versionlessSource = new MockVersionlessSource(); |
384 cache.register(source1); | 430 cache.register(source1); |
385 cache.register(source2); | 431 cache.register(source2); |
386 cache.register(versionlessSource); | 432 cache.register(versionlessSource); |
387 cache.sources.setDefault(source1.name); | 433 cache.sources.setDefault(source1.name); |
388 | 434 |
389 // Build the test package graph. | 435 // Build the test package graph. |
390 var root; | 436 var root; |
391 packages.forEach((nameVersion, dependencies) { | 437 packages.forEach((nameVersion, dependencies) { |
392 var parsed = parseSource(nameVersion); | 438 var parsed = parseSource(nameVersion, (isDev, nameVersion, source) { |
393 nameVersion = parsed.first; | 439 var parts = nameVersion.split(' '); |
394 var source = parsed.last; | 440 var name = parts[0]; |
| 441 var version = parts[1]; |
395 | 442 |
396 var parts = nameVersion.split(' '); | 443 var package = source1.mockPackage(name, version, dependencies); |
397 var name = parts[0]; | 444 if (name == 'myapp') { |
398 var version = parts[1]; | 445 // Don't add the root package to the server, so we can verify that Pub |
399 | 446 // doesn't try to look up information about the local package on the |
400 var package = source1.mockPackage(name, version, dependencies); | 447 // remote server. |
401 if (name == 'myapp') { | 448 root = package; |
402 // Don't add the root package to the server, so we can verify that Pub | 449 } else { |
403 // doesn't try to look up information about the local package on the | 450 source.addPackage(package); |
404 // remote server. | 451 } |
405 root = package; | 452 }); |
406 } else { | |
407 source.addPackage(package); | |
408 } | |
409 }); | 453 }); |
410 | 454 |
411 // Clean up the expectation. | 455 // Clean up the expectation. |
412 if (result != null) { | 456 if (result != null) { |
413 var newResult = {}; | 457 var newResult = {}; |
414 result.forEach((name, version) { | 458 result.forEach((name, version) { |
415 var parsed = parseSource(name); | 459 parseSource(name, (isDev, name, source) { |
416 name = parsed.first; | 460 version = new Version.parse(version); |
417 var source = parsed.last; | 461 newResult[name] = new PackageId(name, source, version, name); |
418 version = new Version.parse(version); | 462 }); |
419 newResult[name] = new PackageId(name, source, version, name); | |
420 }); | 463 }); |
421 result = newResult; | 464 result = newResult; |
422 } | 465 } |
423 | 466 |
424 var realLockFile = new LockFile.empty(); | 467 var realLockFile = new LockFile.empty(); |
425 if (lockfile != null) { | 468 if (lockfile != null) { |
426 lockfile.forEach((name, version) { | 469 lockfile.forEach((name, version) { |
427 version = new Version.parse(version); | 470 version = new Version.parse(version); |
428 realLockFile.packages[name] = | 471 realLockFile.packages[name] = |
429 new PackageId(name, source1, version, name); | 472 new PackageId(name, source1, version, name); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 } | 518 } |
476 | 519 |
477 Future<bool> install(PackageId id, String path) { | 520 Future<bool> install(PackageId id, String path) { |
478 throw 'no'; | 521 throw 'no'; |
479 } | 522 } |
480 | 523 |
481 Package mockPackage(String description, String version, | 524 Package mockPackage(String description, String version, |
482 Map dependencyStrings) { | 525 Map dependencyStrings) { |
483 // Build the pubspec dependencies. | 526 // Build the pubspec dependencies. |
484 var dependencies = <PackageRef>[]; | 527 var dependencies = <PackageRef>[]; |
| 528 var devDependencies = <PackageRef>[]; |
| 529 |
485 dependencyStrings.forEach((name, constraint) { | 530 dependencyStrings.forEach((name, constraint) { |
486 var parsed = parseSource(name); | 531 parseSource(name, (isDev, name, source) { |
487 var description = parsed.first; | 532 var packageName = name.replaceFirst(new RegExp(r"-[^-]+$"), ""); |
488 var packageName = description.replaceFirst(new RegExp(r"-[^-]+$"), ""); | 533 var ref = new PackageRef(packageName, source, |
489 dependencies.add(new PackageRef(packageName, parsed.last, | 534 new VersionConstraint.parse(constraint), name); |
490 new VersionConstraint.parse(constraint), description)); | 535 |
| 536 if (isDev) { |
| 537 devDependencies.add(ref); |
| 538 } else { |
| 539 dependencies.add(ref); |
| 540 } |
| 541 }); |
491 }); | 542 }); |
492 | 543 |
493 var pubspec = new Pubspec( | 544 var pubspec = new Pubspec( |
494 description, new Version.parse(version), dependencies, | 545 description, new Version.parse(version), dependencies, devDependencies, |
495 new PubspecEnvironment()); | 546 new PubspecEnvironment()); |
496 return new Package.inMemory(pubspec); | 547 return new Package.inMemory(pubspec); |
497 } | 548 } |
498 | 549 |
499 void addPackage(Package package) { | 550 void addPackage(Package package) { |
500 _packages.putIfAbsent(package.name, () => new Map<Version, Package>()); | 551 _packages.putIfAbsent(package.name, () => new Map<Version, Package>()); |
501 _packages[package.name][package.version] = package; | 552 _packages[package.name][package.version] = package; |
502 } | 553 } |
503 } | 554 } |
504 | 555 |
(...skipping 14 matching lines...) Expand all Loading... |
519 | 570 |
520 Future<Pubspec> describe(PackageId id) { | 571 Future<Pubspec> describe(PackageId id) { |
521 return new Future<Pubspec>.immediate(_packages[id.description].pubspec); | 572 return new Future<Pubspec>.immediate(_packages[id.description].pubspec); |
522 } | 573 } |
523 | 574 |
524 void addPackage(Package package) { | 575 void addPackage(Package package) { |
525 _packages[package.name] = package; | 576 _packages[package.name] = package; |
526 } | 577 } |
527 } | 578 } |
528 | 579 |
529 Pair<String, Source> parseSource(String name) { | 580 void parseSource(String description, |
530 var match = new RegExp(r"(.*) from (.*)").firstMatch(name); | 581 callback(bool isDev, String name, Source source)) { |
531 if (match == null) return new Pair<String, Source>(name, source1); | 582 var isDev = false; |
532 switch (match[2]) { | 583 |
533 case 'mock1': return new Pair<String, Source>(match[1], source1); | 584 if (description.startsWith("(dev) ")) { |
534 case 'mock2': return new Pair<String, Source>(match[1], source2); | 585 description = description.substring("(dev) ".length); |
535 case 'root': return new Pair<String, Source>(match[1], null); | 586 isDev = true; |
536 case 'versionless': | |
537 return new Pair<String, Source>(match[1], versionlessSource); | |
538 } | 587 } |
| 588 |
| 589 var name = description; |
| 590 var source = source1; |
| 591 |
| 592 var sourceNames = { |
| 593 'mock1': source1, |
| 594 'mock2': source2, |
| 595 'root': null, |
| 596 'versionless': versionlessSource |
| 597 }; |
| 598 |
| 599 var match = new RegExp(r"(.*) from (.*)").firstMatch(description); |
| 600 if (match != null) { |
| 601 name = match[1]; |
| 602 source = sourceNames[match[2]]; |
| 603 } |
| 604 |
| 605 callback(isDev, name, source); |
539 } | 606 } |
OLD | NEW |