| 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_upgrade_test; | 5 library pub_upgrade_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:unittest/unittest.dart'; | 9 import 'package:unittest/unittest.dart'; |
| 10 | 10 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 'myapp 1.0.0': { | 254 'myapp 1.0.0': { |
| 255 'foo': '1.0.0', | 255 'foo': '1.0.0', |
| 256 'bar': '1.0.0' | 256 'bar': '1.0.0' |
| 257 }, | 257 }, |
| 258 'foo 1.0.0': { | 258 'foo 1.0.0': { |
| 259 'myapp': '>=1.0.0' | 259 'myapp': '>=1.0.0' |
| 260 }, | 260 }, |
| 261 'bar 1.0.0': { | 261 'bar 1.0.0': { |
| 262 'myapp from mock2': '>=1.0.0' | 262 'myapp from mock2': '>=1.0.0' |
| 263 } | 263 } |
| 264 }, error: sourceMismatch('foo', 'bar')); | 264 }, error: sourceMismatch('myapp', 'foo', 'bar')); |
| 265 | 265 |
| 266 testResolve('with wrong version', { | 266 testResolve('with wrong version', { |
| 267 'myapp 1.0.0': { | 267 'myapp 1.0.0': { |
| 268 'foo': '1.0.0' | 268 'foo': '1.0.0' |
| 269 }, | 269 }, |
| 270 'foo 1.0.0': { | 270 'foo 1.0.0': { |
| 271 'myapp': '<1.0.0' | 271 'myapp': '<1.0.0' |
| 272 } | 272 } |
| 273 }, error: couldNotSolve); | 273 }, error: couldNotSolve); |
| 274 } | 274 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 }); | 315 }); |
| 316 } | 316 } |
| 317 | 317 |
| 318 unsolvable() { | 318 unsolvable() { |
| 319 testResolve('no version that matches requirement', { | 319 testResolve('no version that matches requirement', { |
| 320 'myapp 0.0.0': { | 320 'myapp 0.0.0': { |
| 321 'foo': '>=1.0.0 <2.0.0' | 321 'foo': '>=1.0.0 <2.0.0' |
| 322 }, | 322 }, |
| 323 'foo 2.0.0': {}, | 323 'foo 2.0.0': {}, |
| 324 'foo 2.1.3': {} | 324 'foo 2.1.3': {} |
| 325 }, error: noVersion(['myapp'])); | 325 }, error: noVersion(['myapp', 'foo'])); |
| 326 | 326 |
| 327 testResolve('no version that matches combined constraint', { | 327 testResolve('no version that matches combined constraint', { |
| 328 'myapp 0.0.0': { | 328 'myapp 0.0.0': { |
| 329 'foo': '1.0.0', | 329 'foo': '1.0.0', |
| 330 'bar': '1.0.0' | 330 'bar': '1.0.0' |
| 331 }, | 331 }, |
| 332 'foo 1.0.0': { | 332 'foo 1.0.0': { |
| 333 'shared': '>=2.0.0 <3.0.0' | 333 'shared': '>=2.0.0 <3.0.0' |
| 334 }, | 334 }, |
| 335 'bar 1.0.0': { | 335 'bar 1.0.0': { |
| 336 'shared': '>=2.9.0 <4.0.0' | 336 'shared': '>=2.9.0 <4.0.0' |
| 337 }, | 337 }, |
| 338 'shared 2.5.0': {}, | 338 'shared 2.5.0': {}, |
| 339 'shared 3.5.0': {} | 339 'shared 3.5.0': {} |
| 340 }, error: noVersion(['foo', 'bar'])); | 340 }, error: noVersion(['shared', 'foo', 'bar'])); |
| 341 | 341 |
| 342 testResolve('disjoint constraints', { | 342 testResolve('disjoint constraints', { |
| 343 'myapp 0.0.0': { | 343 'myapp 0.0.0': { |
| 344 'foo': '1.0.0', | 344 'foo': '1.0.0', |
| 345 'bar': '1.0.0' | 345 'bar': '1.0.0' |
| 346 }, | 346 }, |
| 347 'foo 1.0.0': { | 347 'foo 1.0.0': { |
| 348 'shared': '<=2.0.0' | 348 'shared': '<=2.0.0' |
| 349 }, | 349 }, |
| 350 'bar 1.0.0': { | 350 'bar 1.0.0': { |
| 351 'shared': '>3.0.0' | 351 'shared': '>3.0.0' |
| 352 }, | 352 }, |
| 353 'shared 2.0.0': {}, | 353 'shared 2.0.0': {}, |
| 354 'shared 4.0.0': {} | 354 'shared 4.0.0': {} |
| 355 }, error: disjointConstraint(['foo', 'bar'])); | 355 }, error: disjointConstraint(['shared', 'foo', 'bar'])); |
| 356 | 356 |
| 357 testResolve('mismatched descriptions', { | 357 testResolve('mismatched descriptions', { |
| 358 'myapp 0.0.0': { | 358 'myapp 0.0.0': { |
| 359 'foo': '1.0.0', | 359 'foo': '1.0.0', |
| 360 'bar': '1.0.0' | 360 'bar': '1.0.0' |
| 361 }, | 361 }, |
| 362 'foo 1.0.0': { | 362 'foo 1.0.0': { |
| 363 'shared-x': '1.0.0' | 363 'shared-x': '1.0.0' |
| 364 }, | 364 }, |
| 365 'bar 1.0.0': { | 365 'bar 1.0.0': { |
| 366 'shared-y': '1.0.0' | 366 'shared-y': '1.0.0' |
| 367 }, | 367 }, |
| 368 'shared-x 1.0.0': {}, | 368 'shared-x 1.0.0': {}, |
| 369 'shared-y 1.0.0': {} | 369 'shared-y 1.0.0': {} |
| 370 }, error: descriptionMismatch('foo', 'bar')); | 370 }, error: descriptionMismatch('shared', 'foo', 'bar')); |
| 371 | 371 |
| 372 testResolve('mismatched sources', { | 372 testResolve('mismatched sources', { |
| 373 'myapp 0.0.0': { | 373 'myapp 0.0.0': { |
| 374 'foo': '1.0.0', | 374 'foo': '1.0.0', |
| 375 'bar': '1.0.0' | 375 'bar': '1.0.0' |
| 376 }, | 376 }, |
| 377 'foo 1.0.0': { | 377 'foo 1.0.0': { |
| 378 'shared': '1.0.0' | 378 'shared': '1.0.0' |
| 379 }, | 379 }, |
| 380 'bar 1.0.0': { | 380 'bar 1.0.0': { |
| 381 'shared from mock2': '1.0.0' | 381 'shared from mock2': '1.0.0' |
| 382 }, | 382 }, |
| 383 'shared 1.0.0': {}, | 383 'shared 1.0.0': {}, |
| 384 'shared 1.0.0 from mock2': {} | 384 'shared 1.0.0 from mock2': {} |
| 385 }, error: sourceMismatch('foo', 'bar')); | 385 }, error: sourceMismatch('shared', 'foo', 'bar')); |
| 386 | 386 |
| 387 testResolve('no valid solution', { | 387 testResolve('no valid solution', { |
| 388 'myapp 0.0.0': { | 388 'myapp 0.0.0': { |
| 389 'a': 'any', | 389 'a': 'any', |
| 390 'b': 'any' | 390 'b': 'any' |
| 391 }, | 391 }, |
| 392 'a 1.0.0': { | 392 'a 1.0.0': { |
| 393 'b': '1.0.0' | 393 'b': '1.0.0' |
| 394 }, | 394 }, |
| 395 'a 2.0.0': { | 395 'a 2.0.0': { |
| 396 'b': '2.0.0' | 396 'b': '2.0.0' |
| 397 }, | 397 }, |
| 398 'b 1.0.0': { | 398 'b 1.0.0': { |
| 399 'a': '2.0.0' | 399 'a': '2.0.0' |
| 400 }, | 400 }, |
| 401 'b 2.0.0': { | 401 'b 2.0.0': { |
| 402 'a': '1.0.0' | 402 'a': '1.0.0' |
| 403 } | 403 } |
| 404 }, error: couldNotSolve, maxTries: 4); | 404 }, error: couldNotSolve, maxTries: 4); |
| 405 | 405 |
| 406 // This is a regression test for #15550. | 406 // This is a regression test for #15550. |
| 407 testResolve('no version that matches while backtracking', { | 407 testResolve('no version that matches while backtracking', { |
| 408 'myapp 0.0.0': { | 408 'myapp 0.0.0': { |
| 409 'a': 'any', | 409 'a': 'any', |
| 410 'b': '>1.0.0' | 410 'b': '>1.0.0' |
| 411 }, | 411 }, |
| 412 'a 1.0.0': {}, | 412 'a 1.0.0': {}, |
| 413 'b 1.0.0': {} | 413 'b 1.0.0': {} |
| 414 }, error: noVersion(['myapp']), maxTries: 1); | 414 }, error: noVersion(['myapp', 'b']), maxTries: 1); |
| 415 } | 415 } |
| 416 | 416 |
| 417 badSource() { | 417 badSource() { |
| 418 testResolve('fail if the root package has a bad source in dep', { | 418 testResolve('fail if the root package has a bad source in dep', { |
| 419 'myapp 0.0.0': { | 419 'myapp 0.0.0': { |
| 420 'foo from bad': 'any' | 420 'foo from bad': 'any' |
| 421 }, | 421 }, |
| 422 }, error: unknownSource('myapp', 'foo', 'bad')); | 422 }, error: unknownSource('myapp', 'foo', 'bad')); |
| 423 | 423 |
| 424 testResolve('fail if the root package has a bad source in dev dep', { | 424 testResolve('fail if the root package has a bad source in dev dep', { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 'a 1.0.0': {}, | 625 'a 1.0.0': {}, |
| 626 'a 1.0.0 from mock2': {}, | 626 'a 1.0.0 from mock2': {}, |
| 627 'b 1.0.0': { | 627 'b 1.0.0': { |
| 628 'a from mock2': 'any' | 628 'a from mock2': 'any' |
| 629 }, | 629 }, |
| 630 'c 1.0.0': {}, | 630 'c 1.0.0': {}, |
| 631 'c 2.0.0': {}, | 631 'c 2.0.0': {}, |
| 632 'c 3.0.0': {}, | 632 'c 3.0.0': {}, |
| 633 'c 4.0.0': {}, | 633 'c 4.0.0': {}, |
| 634 'c 5.0.0': {}, | 634 'c 5.0.0': {}, |
| 635 }, error: sourceMismatch('myapp', 'b'), maxTries: 1); | 635 }, error: sourceMismatch('a', 'myapp', 'b'), maxTries: 1); |
| 636 | 636 |
| 637 testResolve('backjump to conflicting description', { | 637 testResolve('backjump to conflicting description', { |
| 638 'myapp 0.0.0': { | 638 'myapp 0.0.0': { |
| 639 'a-x': 'any', | 639 'a-x': 'any', |
| 640 'b': 'any', | 640 'b': 'any', |
| 641 'c': 'any' | 641 'c': 'any' |
| 642 }, | 642 }, |
| 643 'a-x 1.0.0': {}, | 643 'a-x 1.0.0': {}, |
| 644 'a-y 1.0.0': {}, | 644 'a-y 1.0.0': {}, |
| 645 'b 1.0.0': { | 645 'b 1.0.0': { |
| 646 'a-y': 'any' | 646 'a-y': 'any' |
| 647 }, | 647 }, |
| 648 'c 1.0.0': {}, | 648 'c 1.0.0': {}, |
| 649 'c 2.0.0': {}, | 649 'c 2.0.0': {}, |
| 650 'c 3.0.0': {}, | 650 'c 3.0.0': {}, |
| 651 'c 4.0.0': {}, | 651 'c 4.0.0': {}, |
| 652 'c 5.0.0': {}, | 652 'c 5.0.0': {}, |
| 653 }, error: descriptionMismatch('myapp', 'b'), maxTries: 1); | 653 }, error: descriptionMismatch('a', 'myapp', 'b'), maxTries: 1); |
| 654 | 654 |
| 655 // Dependencies are ordered so that packages with fewer versions are tried | 655 // Dependencies are ordered so that packages with fewer versions are tried |
| 656 // first. Here, there are two valid solutions (either a or b must be | 656 // first. Here, there are two valid solutions (either a or b must be |
| 657 // downgraded once). The chosen one depends on which dep is traversed first. | 657 // downgraded once). The chosen one depends on which dep is traversed first. |
| 658 // Since b has fewer versions, it will be traversed first, which means a will | 658 // Since b has fewer versions, it will be traversed first, which means a will |
| 659 // come later. Since later selections are revised first, a gets downgraded. | 659 // come later. Since later selections are revised first, a gets downgraded. |
| 660 testResolve('traverse into package with fewer versions first', { | 660 testResolve('traverse into package with fewer versions first', { |
| 661 'myapp 0.0.0': { | 661 'myapp 0.0.0': { |
| 662 'a': 'any', | 662 'a': 'any', |
| 663 'b': 'any' | 663 'b': 'any' |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 FailMatcherBuilder noVersion(List<String> packages) { | 1076 FailMatcherBuilder noVersion(List<String> packages) { |
| 1077 return (maxTries) => new SolveFailMatcher(packages, maxTries, | 1077 return (maxTries) => new SolveFailMatcher(packages, maxTries, |
| 1078 NoVersionException); | 1078 NoVersionException); |
| 1079 } | 1079 } |
| 1080 | 1080 |
| 1081 FailMatcherBuilder disjointConstraint(List<String> packages) { | 1081 FailMatcherBuilder disjointConstraint(List<String> packages) { |
| 1082 return (maxTries) => new SolveFailMatcher(packages, maxTries, | 1082 return (maxTries) => new SolveFailMatcher(packages, maxTries, |
| 1083 DisjointConstraintException); | 1083 DisjointConstraintException); |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 FailMatcherBuilder descriptionMismatch(String package1, String package2) { | 1086 FailMatcherBuilder descriptionMismatch( |
| 1087 return (maxTries) => new SolveFailMatcher([package1, package2], maxTries, | 1087 String package, String depender1, String depender2) { |
| 1088 DescriptionMismatchException); | 1088 return (maxTries) => new SolveFailMatcher([package, depender1, depender2], |
| 1089 maxTries, DescriptionMismatchException); |
| 1089 } | 1090 } |
| 1090 | 1091 |
| 1091 // If no solution can be found, the solver just reports the last failure that | 1092 // If no solution can be found, the solver just reports the last failure that |
| 1092 // happened during propagation. Since we don't specify the order that solutions | 1093 // happened during propagation. Since we don't specify the order that solutions |
| 1093 // are tried, this just validates that *some* failure occurred, but not which. | 1094 // are tried, this just validates that *some* failure occurred, but not which. |
| 1094 SolveFailMatcher couldNotSolve(maxTries) => | 1095 SolveFailMatcher couldNotSolve(maxTries) => |
| 1095 new SolveFailMatcher([], maxTries, null); | 1096 new SolveFailMatcher([], maxTries, null); |
| 1096 | 1097 |
| 1097 FailMatcherBuilder sourceMismatch(String package1, String package2) { | 1098 FailMatcherBuilder sourceMismatch( |
| 1098 return (maxTries) => new SolveFailMatcher([package1, package2], maxTries, | 1099 String package, String depender1, String depender2) { |
| 1099 SourceMismatchException); | 1100 return (maxTries) => new SolveFailMatcher([package, depender1, depender2], |
| 1101 maxTries, SourceMismatchException); |
| 1100 } | 1102 } |
| 1101 | 1103 |
| 1102 unknownSource(String depender, String dependency, String source) { | 1104 unknownSource(String depender, String dependency, String source) { |
| 1103 return (maxTries) => new SolveFailMatcher([depender, dependency, source], | 1105 return (maxTries) => new SolveFailMatcher([depender, dependency, source], |
| 1104 maxTries, UnknownSourceException); | 1106 maxTries, UnknownSourceException); |
| 1105 } | 1107 } |
| 1106 | 1108 |
| 1107 class SolveSuccessMatcher implements Matcher { | 1109 class SolveSuccessMatcher implements Matcher { |
| 1108 /// The expected concrete package selections. | 1110 /// The expected concrete package selections. |
| 1109 final Map<String, PackageId> _expected; | 1111 final Map<String, PackageId> _expected; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 } | 1397 } |
| 1396 | 1398 |
| 1397 var source = "mock1"; | 1399 var source = "mock1"; |
| 1398 if (match[7] != null) { | 1400 if (match[7] != null) { |
| 1399 source = match[7]; | 1401 source = match[7]; |
| 1400 if (source == "root") source = null; | 1402 if (source == "root") source = null; |
| 1401 } | 1403 } |
| 1402 | 1404 |
| 1403 return new PackageId(name, source, parsedVersion, description); | 1405 return new PackageId(name, source, parsedVersion, description); |
| 1404 } | 1406 } |
| OLD | NEW |