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 |