Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: sdk/lib/_internal/pub/test/version_solver_test.dart

Issue 15347004: Gracefully handle pubspecs with dependencies using unknown sources. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add tests for unknown sources in lockfiles. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/pub/test/update/unknown_source_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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';
(...skipping 22 matching lines...) Expand all
33 33
34 // Since this test isn't run from the SDK, it can't find the "version" file 34 // Since this test isn't run from the SDK, it can't find the "version" file
35 // to load. Instead, just manually inject a version. 35 // to load. Instead, just manually inject a version.
36 sdk.version = new Version(1, 2, 3); 36 sdk.version = new Version(1, 2, 3);
37 37
38 group('basic graph', basicGraph); 38 group('basic graph', basicGraph);
39 group('with lockfile', withLockFile); 39 group('with lockfile', withLockFile);
40 group('root dependency', rootDependency); 40 group('root dependency', rootDependency);
41 group('dev dependency', devDependency); 41 group('dev dependency', devDependency);
42 group('unsolvable', unsolvable); 42 group('unsolvable', unsolvable);
43 group('bad source', badSource);
43 group('backtracking', backtracking); 44 group('backtracking', backtracking);
44 group('SDK constraint', sdkConstraint); 45 group('SDK constraint', sdkConstraint);
45 } 46 }
46 47
47 void basicGraph() { 48 void basicGraph() {
48 testResolve('no dependencies', { 49 testResolve('no dependencies', {
49 'myapp 0.0.0': {} 50 'myapp 0.0.0': {}
50 }, result: { 51 }, result: {
51 'myapp from root': '0.0.0' 52 'myapp from root': '0.0.0'
52 }); 53 });
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 }, 398 },
398 'b 1.0.0': { 399 'b 1.0.0': {
399 'a': '2.0.0' 400 'a': '2.0.0'
400 }, 401 },
401 'b 2.0.0': { 402 'b 2.0.0': {
402 'a': '1.0.0' 403 'a': '1.0.0'
403 } 404 }
404 }, error: couldNotSolve, maxTries: 4); 405 }, error: couldNotSolve, maxTries: 4);
405 } 406 }
406 407
408 badSource() {
409 testResolve('fail if the root package has a bad source in dep', {
410 'myapp 0.0.0': {
411 'foo from bad': 'any'
412 },
413 }, error: unknownSource('myapp', 'foo', 'bad'));
414
415 testResolve('fail if the root package has a bad source in dev dep', {
416 'myapp 0.0.0': {
417 '(dev) foo from bad': 'any'
418 },
419 }, error: unknownSource('myapp', 'foo', 'bad'));
420
421 testResolve('fail if all versions have bad source in dep', {
422 'myapp 0.0.0': {
423 'foo': 'any'
424 },
425 'foo 1.0.0': {
426 'bar from bad': 'any'
427 },
428 'foo 1.0.1': {
429 'baz from bad': 'any'
430 },
431 'foo 1.0.3': {
432 'bang from bad': 'any'
433 },
434 }, error: unknownSource('foo', 'bar', 'bad'), maxTries: 3);
435
436 testResolve('ignore versions with bad source in dep', {
437 'myapp 1.0.0': {
438 'foo': 'any'
439 },
440 'foo 1.0.0': {
441 'bar': 'any'
442 },
443 'foo 1.0.1': {
444 'bar from bad': 'any'
445 },
446 'foo 1.0.3': {
447 'bar from bad': 'any'
448 },
449 'bar 1.0.0': {}
450 }, result: {
451 'myapp from root': '1.0.0',
452 'foo': '1.0.0',
453 'bar': '1.0.0'
454 }, maxTries: 3);
455 }
456
407 backtracking() { 457 backtracking() {
408 testResolve('circular dependency on older version', { 458 testResolve('circular dependency on older version', {
409 'myapp 0.0.0': { 459 'myapp 0.0.0': {
410 'a': '>=1.0.0' 460 'a': '>=1.0.0'
411 }, 461 },
412 'a 1.0.0': {}, 462 'a 1.0.0': {},
413 'a 2.0.0': { 463 'a 2.0.0': {
414 'b': '1.0.0' 464 'b': '1.0.0'
415 }, 465 },
416 'b 1.0.0': { 466 'b 1.0.0': {
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 var name = parts[0]; 818 var name = parts[0];
769 var version = parts[1]; 819 var version = parts[1];
770 820
771 var package = mockPackage(name, version, dependencies); 821 var package = mockPackage(name, version, dependencies);
772 if (name == 'myapp') { 822 if (name == 'myapp') {
773 // Don't add the root package to the server, so we can verify that Pub 823 // Don't add the root package to the server, so we can verify that Pub
774 // doesn't try to look up information about the local package on the 824 // doesn't try to look up information about the local package on the
775 // remote server. 825 // remote server.
776 root = package; 826 root = package;
777 } else { 827 } else {
778 source.addPackage(name, package); 828 cache.sources[source].addPackage(name, package);
779 } 829 }
780 }); 830 });
781 }); 831 });
782 832
783 // Clean up the expectation. 833 // Clean up the expectation.
784 if (result != null) { 834 if (result != null) {
785 var newResult = {}; 835 var newResult = {};
786 result.forEach((name, version) { 836 result.forEach((name, version) {
787 parseSource(name, (isDev, name, source) { 837 parseSource(name, (isDev, name, source) {
788 version = new Version.parse(version); 838 version = new Version.parse(version);
789 newResult[name] = new PackageId(name, source, version, name); 839 newResult[name] = new PackageId(name, source, version, name);
790 }); 840 });
791 }); 841 });
792 result = newResult; 842 result = newResult;
793 } 843 }
794 844
795 var realLockFile = new LockFile.empty(); 845 var realLockFile = new LockFile.empty();
796 if (lockfile != null) { 846 if (lockfile != null) {
797 lockfile.forEach((name, version) { 847 lockfile.forEach((name, version) {
798 version = new Version.parse(version); 848 version = new Version.parse(version);
799 realLockFile.packages[name] = 849 realLockFile.packages[name] =
800 new PackageId(name, source1, version, name); 850 new PackageId(name, source1.name, version, name);
801 }); 851 });
802 } 852 }
803 853
804 // Make a version number like the continuous build's version. 854 // Make a version number like the continuous build's version.
805 var previousVersion = sdk.version; 855 var previousVersion = sdk.version;
806 if (useBleedingEdgeSdkVersion) { 856 if (useBleedingEdgeSdkVersion) {
807 sdk.version = new Version(0, 1, 2, build: '0_r12345_juser'); 857 sdk.version = new Version(0, 1, 2, build: '0_r12345_juser');
808 } 858 }
809 859
810 // Resolve the versions. 860 // Resolve the versions.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 // happened during propagation. Since we don't specify the order that solutions 899 // happened during propagation. Since we don't specify the order that solutions
850 // are tried, this just validates that *some* failure occurred, but not which. 900 // are tried, this just validates that *some* failure occurred, but not which.
851 SolveFailMatcher couldNotSolve(maxTries) => 901 SolveFailMatcher couldNotSolve(maxTries) =>
852 new SolveFailMatcher([], maxTries, null); 902 new SolveFailMatcher([], maxTries, null);
853 903
854 FailMatcherBuilder sourceMismatch(String package1, String package2) { 904 FailMatcherBuilder sourceMismatch(String package1, String package2) {
855 return (maxTries) => new SolveFailMatcher([package1, package2], maxTries, 905 return (maxTries) => new SolveFailMatcher([package1, package2], maxTries,
856 SourceMismatchException); 906 SourceMismatchException);
857 } 907 }
858 908
909 unknownSource(String depender, String dependency, String source) {
910 return (maxTries) => new SolveFailMatcher([depender, dependency, source],
911 maxTries, UnknownSourceException);
912 }
913
859 class SolveSuccessMatcher implements Matcher { 914 class SolveSuccessMatcher implements Matcher {
860 /// The expected concrete package selections. 915 /// The expected concrete package selections.
861 final Map<String, PackageId> _expected; 916 final Map<String, PackageId> _expected;
862 917
863 /// The maximum number of attempts that should have been tried before finding 918 /// The maximum number of attempts that should have been tried before finding
864 /// the solution. 919 /// the solution.
865 final int _maxTries; 920 final int _maxTries;
866 921
867 SolveSuccessMatcher(this._expected, this._maxTries); 922 SolveSuccessMatcher(this._expected, this._maxTries);
868 923
869 Description describe(Description description) { 924 Description describe(Description description) {
870 return description.add( 925 return description.add(
871 'Solver to use at most $_maxTries attempts to find:\n' 926 'Solver to use at most $_maxTries attempts to find:\n'
872 '${_listPackages(_expected.values)}'); 927 '${_listPackages(_expected.values)}');
873 } 928 }
874 929
875 Description describeMismatch(SolveResult result, 930 Description describeMismatch(SolveResult result,
876 Description description, 931 Description description,
877 MatchState state, bool verbose) { 932 MatchState state, bool verbose) {
878 if (!result.succeeded) { 933 if (!result.succeeded) {
879 description.add('Solver failed with:\n${result.error}'); 934 description.add('Solver failed with:\n${result.error}');
880 return; 935 return null;
881 } 936 }
882 937
883 description.add('Resolved:\n${_listPackages(result.packages)}\n'); 938 description.add('Resolved:\n${_listPackages(result.packages)}\n');
884 description.add(state.state); 939 description.add(state.state);
885 return description; 940 return description;
886 } 941 }
887 942
888 bool matches(SolveResult result, MatchState state) { 943 bool matches(SolveResult result, MatchState state) {
889 if (!result.succeeded) return false; 944 if (!result.succeeded) return false;
890 945
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 throw new Exception('Version list for $description was already ' 1081 throw new Exception('Version list for $description was already '
1027 'requested.'); 1082 'requested.');
1028 } 1083 }
1029 1084
1030 _requestedVersions.add(description); 1085 _requestedVersions.add(description);
1031 1086
1032 if (!_packages.containsKey(description)){ 1087 if (!_packages.containsKey(description)){
1033 throw new Exception('MockSource does not have a package matching ' 1088 throw new Exception('MockSource does not have a package matching '
1034 '"$description".'); 1089 '"$description".');
1035 } 1090 }
1091
1036 return _packages[description].keys.toList(); 1092 return _packages[description].keys.toList();
1037 }); 1093 });
1038 } 1094 }
1039 1095
1040 Future<Pubspec> describe(PackageId id) { 1096 Future<Pubspec> describe(PackageId id) {
1041 return new Future.sync(() { 1097 return new Future.sync(() {
1042 // Make sure the solver doesn't request the same thing twice. 1098 // Make sure the solver doesn't request the same thing twice.
1043 if (_requestedPubspecs.containsKey(id.description) && 1099 if (_requestedPubspecs.containsKey(id.description) &&
1044 _requestedPubspecs[id.description].contains(id.version)) { 1100 _requestedPubspecs[id.description].contains(id.version)) {
1045 throw new Exception('Pubspec for $id was already requested.'); 1101 throw new Exception('Pubspec for $id was already requested.');
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 }); 1147 });
1092 1148
1093 var name = description.replaceFirst(new RegExp(r"-[^-]+$"), ""); 1149 var name = description.replaceFirst(new RegExp(r"-[^-]+$"), "");
1094 var pubspec = new Pubspec( 1150 var pubspec = new Pubspec(
1095 name, new Version.parse(version), dependencies, devDependencies, 1151 name, new Version.parse(version), dependencies, devDependencies,
1096 new PubspecEnvironment(sdkConstraint)); 1152 new PubspecEnvironment(sdkConstraint));
1097 return new Package.inMemory(pubspec); 1153 return new Package.inMemory(pubspec);
1098 } 1154 }
1099 1155
1100 void parseSource(String description, 1156 void parseSource(String description,
1101 callback(bool isDev, String name, Source source)) { 1157 callback(bool isDev, String name, String source)) {
1102 var isDev = false; 1158 var isDev = false;
1103 1159
1104 if (description.startsWith("(dev) ")) { 1160 if (description.startsWith("(dev) ")) {
1105 description = description.substring("(dev) ".length); 1161 description = description.substring("(dev) ".length);
1106 isDev = true; 1162 isDev = true;
1107 } 1163 }
1108 1164
1109 var name = description; 1165 var name = description;
1110 var source = source1; 1166 var source = "mock1";
1111
1112 var sourceNames = {
1113 'mock1': source1,
1114 'mock2': source2,
1115 'root': null
1116 };
1117
1118 var match = new RegExp(r"(.*) from (.*)").firstMatch(description); 1167 var match = new RegExp(r"(.*) from (.*)").firstMatch(description);
1119 if (match != null) { 1168 if (match != null) {
1120 name = match[1]; 1169 name = match[1];
1121 source = sourceNames[match[2]]; 1170 source = match[2];
1171 if (source == "root") source = null;
1122 } 1172 }
1123 1173
1124 callback(isDev, name, source); 1174 callback(isDev, name, source);
1125 } 1175 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub/test/update/unknown_source_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698