| 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 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
| 11 | 11 |
| 12 import '../../pub/lock_file.dart'; | 12 import '../../pub/lock_file.dart'; |
| 13 import '../../pub/package.dart'; | 13 import '../../pub/package.dart'; |
| 14 import '../../pub/pubspec.dart'; | 14 import '../../pub/pubspec.dart'; |
| 15 import '../../pub/sdk.dart' as sdk; | 15 import '../../pub/sdk.dart' as sdk; |
| 16 import '../../pub/source.dart'; | 16 import '../../pub/source.dart'; |
| 17 import '../../pub/source_registry.dart'; | 17 import '../../pub/source_registry.dart'; |
| 18 import '../../pub/system_cache.dart'; | 18 import '../../pub/system_cache.dart'; |
| 19 import '../../pub/utils.dart'; | 19 import '../../pub/utils.dart'; |
| 20 import '../../pub/version.dart'; | 20 import '../../pub/version.dart'; |
| 21 import '../../pub/solver/version_solver.dart'; | 21 import '../../pub/solver/version_solver.dart'; |
| 22 import 'test_pub.dart'; | 22 import 'test_pub.dart'; |
| 23 | 23 |
| 24 MockSource source1; | 24 MockSource source1; |
| 25 MockSource source2; | 25 MockSource source2; |
| 26 | 26 |
| 27 bool allowBacktracking; | |
| 28 | |
| 29 main() { | 27 main() { |
| 30 initConfig(); | 28 initConfig(); |
| 31 | 29 |
| 32 // Since this test isn't run from the SDK, it can't find the "version" file | 30 // Since this test isn't run from the SDK, it can't find the "version" file |
| 33 // to load. Instead, just manually inject a version. | 31 // to load. Instead, just manually inject a version. |
| 34 sdk.version = new Version(1, 2, 3); | 32 sdk.version = new Version(1, 2, 3); |
| 35 | 33 |
| 36 for (allowBacktracking in [false, true]) { | 34 group('basic graph', basicGraph); |
| 37 group(allowBacktracking ? 'BackTrackingSolver' : 'GreedySolver', () { | 35 group('with lockfile', withLockFile); |
| 38 group('basic graph', basicGraph); | 36 group('root dependency', rootDependency); |
| 39 group('with lockfile', withLockFile); | 37 group('dev dependency', devDependency); |
| 40 group('root dependency', rootDependency); | 38 group('unsolvable', unsolvable); |
| 41 group('dev dependency', devDependency); | 39 group('backtracking', backtracking); |
| 42 group('unsolvable', unsolvable); | |
| 43 group('backtracking', backtracking); | |
| 44 }); | |
| 45 } | |
| 46 | |
| 47 // These tests are only valid with the backtracking solver. | |
| 48 allowBacktracking = true; | |
| 49 group('SDK constraint', sdkConstraint); | 40 group('SDK constraint', sdkConstraint); |
| 50 } | 41 } |
| 51 | 42 |
| 52 void basicGraph() { | 43 void basicGraph() { |
| 53 testResolve('no dependencies', { | 44 testResolve('no dependencies', { |
| 54 'myapp 0.0.0': {} | 45 'myapp 0.0.0': {} |
| 55 }, result: { | 46 }, result: { |
| 56 'myapp from root': '0.0.0' | 47 'myapp from root': '0.0.0' |
| 57 }); | 48 }); |
| 58 | 49 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 'foo 1.0.3': { 'zoop': '1.0.0' }, | 109 'foo 1.0.3': { 'zoop': '1.0.0' }, |
| 119 'bar 1.0.0': { 'foo': '<=1.0.1' }, | 110 'bar 1.0.0': { 'foo': '<=1.0.1' }, |
| 120 'bang 1.0.0': {}, | 111 'bang 1.0.0': {}, |
| 121 'whoop 1.0.0': {}, | 112 'whoop 1.0.0': {}, |
| 122 'zoop 1.0.0': {} | 113 'zoop 1.0.0': {} |
| 123 }, result: { | 114 }, result: { |
| 124 'myapp from root': '0.0.0', | 115 'myapp from root': '0.0.0', |
| 125 'foo': '1.0.1', | 116 'foo': '1.0.1', |
| 126 'bar': '1.0.0', | 117 'bar': '1.0.0', |
| 127 'bang': '1.0.0' | 118 'bang': '1.0.0' |
| 128 }, maxTries: 2, hasGreedySolution: true); | 119 }, maxTries: 2); |
| 129 | 120 |
| 130 testResolve('circular dependency', { | 121 testResolve('circular dependency', { |
| 131 'myapp 1.0.0': { | 122 'myapp 1.0.0': { |
| 132 'foo': '1.0.0' | 123 'foo': '1.0.0' |
| 133 }, | 124 }, |
| 134 'foo 1.0.0': { | 125 'foo 1.0.0': { |
| 135 'bar': '1.0.0' | 126 'bar': '1.0.0' |
| 136 }, | 127 }, |
| 137 'bar 1.0.0': { | 128 'bar 1.0.0': { |
| 138 'foo': '1.0.0' | 129 'foo': '1.0.0' |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 'bar': '1.0.0', | 211 'bar': '1.0.0', |
| 221 'baz': '1.0.0', | 212 'baz': '1.0.0', |
| 222 'qux': '1.0.0' | 213 'qux': '1.0.0' |
| 223 }, result: { | 214 }, result: { |
| 224 'myapp from root': '0.0.0', | 215 'myapp from root': '0.0.0', |
| 225 'foo': '2.0.0', | 216 'foo': '2.0.0', |
| 226 'bar': '2.0.0', | 217 'bar': '2.0.0', |
| 227 'baz': '2.0.0', | 218 'baz': '2.0.0', |
| 228 'qux': '1.0.0', | 219 'qux': '1.0.0', |
| 229 'newdep': '2.0.0' | 220 'newdep': '2.0.0' |
| 230 }, maxTries: 3, hasGreedySolution: true); | 221 }, maxTries: 3); |
| 231 } | 222 } |
| 232 | 223 |
| 233 rootDependency() { | 224 rootDependency() { |
| 234 testResolve('with root source', { | 225 testResolve('with root source', { |
| 235 'myapp 1.0.0': { | 226 'myapp 1.0.0': { |
| 236 'foo': '1.0.0' | 227 'foo': '1.0.0' |
| 237 }, | 228 }, |
| 238 'foo 1.0.0': { | 229 'foo 1.0.0': { |
| 239 'myapp from root': '>=1.0.0' | 230 'myapp from root': '>=1.0.0' |
| 240 } | 231 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 'b': '1.0.0' | 410 'b': '1.0.0' |
| 420 }, | 411 }, |
| 421 'b 1.0.0': { | 412 'b 1.0.0': { |
| 422 'a': '1.0.0' | 413 'a': '1.0.0' |
| 423 } | 414 } |
| 424 }, result: { | 415 }, result: { |
| 425 'myapp from root': '0.0.0', | 416 'myapp from root': '0.0.0', |
| 426 'a': '1.0.0' | 417 'a': '1.0.0' |
| 427 }, maxTries: 2); | 418 }, maxTries: 2); |
| 428 | 419 |
| 429 /// The latest versions of a and b disagree on c. An older version of either | 420 // The latest versions of a and b disagree on c. An older version of either |
| 430 /// will resolve the problem. This test validates that b, which is farther | 421 // will resolve the problem. This test validates that b, which is farther |
| 431 /// in the dependency graph from myapp is downgraded first. | 422 // in the dependency graph from myapp is downgraded first. |
| 432 testResolve('rolls back leaf versions first', { | 423 testResolve('rolls back leaf versions first', { |
| 433 'myapp 0.0.0': { | 424 'myapp 0.0.0': { |
| 434 'a': 'any' | 425 'a': 'any' |
| 435 }, | 426 }, |
| 436 'a 1.0.0': { | 427 'a 1.0.0': { |
| 437 'b': 'any' | 428 'b': 'any' |
| 438 }, | 429 }, |
| 439 'a 2.0.0': { | 430 'a 2.0.0': { |
| 440 'b': 'any', | 431 'b': 'any', |
| 441 'c': '2.0.0' | 432 'c': '2.0.0' |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 'bar 3.0.0': {'sdk': badVersion }, | 607 'bar 3.0.0': {'sdk': badVersion }, |
| 617 'bar 4.0.0': {'sdk': badVersion } | 608 'bar 4.0.0': {'sdk': badVersion } |
| 618 }, result: { | 609 }, result: { |
| 619 'myapp from root': '0.0.0', | 610 'myapp from root': '0.0.0', |
| 620 'foo': '2.0.0', | 611 'foo': '2.0.0', |
| 621 'bar': '2.0.0' | 612 'bar': '2.0.0' |
| 622 }, maxTries: 3); | 613 }, maxTries: 3); |
| 623 } | 614 } |
| 624 | 615 |
| 625 testResolve(description, packages, | 616 testResolve(description, packages, |
| 626 {lockfile, result, FailMatcherBuilder error, int maxTries, | 617 {lockfile, result, FailMatcherBuilder error, int maxTries}) { |
| 627 bool hasGreedySolution}) { | |
| 628 // Close over the top-level variable since it will be mutated. | |
| 629 var allowBacktracking_ = allowBacktracking; | |
| 630 | |
| 631 if (maxTries == null) maxTries = 1; | 618 if (maxTries == null) maxTries = 1; |
| 632 if (hasGreedySolution == null) hasGreedySolution = maxTries == 1; | |
| 633 | |
| 634 if (!allowBacktracking_) { | |
| 635 // The greedy solver should fail any graph that does expect multiple tries | |
| 636 // and isn't explicitly annotated to have a greedy solution. | |
| 637 if (!hasGreedySolution) { | |
| 638 result = null; | |
| 639 error = couldNotSolve; | |
| 640 } | |
| 641 } | |
| 642 | 619 |
| 643 test(description, () { | 620 test(description, () { |
| 644 var cache = new SystemCache('.'); | 621 var cache = new SystemCache('.'); |
| 645 source1 = new MockSource('mock1'); | 622 source1 = new MockSource('mock1'); |
| 646 source2 = new MockSource('mock2'); | 623 source2 = new MockSource('mock2'); |
| 647 cache.register(source1); | 624 cache.register(source1); |
| 648 cache.register(source2); | 625 cache.register(source2); |
| 649 cache.sources.setDefault(source1.name); | 626 cache.sources.setDefault(source1.name); |
| 650 | 627 |
| 651 // Build the test package graph. | 628 // Build the test package graph. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 if (lockfile != null) { | 661 if (lockfile != null) { |
| 685 lockfile.forEach((name, version) { | 662 lockfile.forEach((name, version) { |
| 686 version = new Version.parse(version); | 663 version = new Version.parse(version); |
| 687 realLockFile.packages[name] = | 664 realLockFile.packages[name] = |
| 688 new PackageId(name, source1, version, name); | 665 new PackageId(name, source1, version, name); |
| 689 }); | 666 }); |
| 690 } | 667 } |
| 691 | 668 |
| 692 // Resolve the versions. | 669 // Resolve the versions. |
| 693 var future = resolveVersions(cache.sources, root, | 670 var future = resolveVersions(cache.sources, root, |
| 694 allowBacktracking: allowBacktracking_, lockFile: realLockFile); | 671 lockFile: realLockFile); |
| 695 | 672 |
| 696 var matcher; | 673 var matcher; |
| 697 if (result != null) { | 674 if (result != null) { |
| 698 matcher = new SolveSuccessMatcher(result, maxTries); | 675 matcher = new SolveSuccessMatcher(result, maxTries); |
| 699 } else if (error != null) { | 676 } else if (error != null) { |
| 700 matcher = error(maxTries); | 677 matcher = error(maxTries); |
| 701 } | 678 } |
| 702 | 679 |
| 703 expect(future, completion(matcher)); | 680 expect(future, completion(matcher)); |
| 704 }); | 681 }); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 }; | 963 }; |
| 987 | 964 |
| 988 var match = new RegExp(r"(.*) from (.*)").firstMatch(description); | 965 var match = new RegExp(r"(.*) from (.*)").firstMatch(description); |
| 989 if (match != null) { | 966 if (match != null) { |
| 990 name = match[1]; | 967 name = match[1]; |
| 991 source = sourceNames[match[2]]; | 968 source = sourceNames[match[2]]; |
| 992 } | 969 } |
| 993 | 970 |
| 994 callback(isDev, name, source); | 971 callback(isDev, name, source); |
| 995 } | 972 } |
| OLD | NEW |