aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/dependency_resolver/solver_test.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-22 23:42:07 +0900
committernsfisis <nsfisis@gmail.com>2026-06-22 23:42:07 +0900
commit5ab5f3b316798c1411ce8e6a7f5b091fda93589c (patch)
treec7669f94f5d9bd9adc07bc1aab3f14cfdec1ae5f /crates/shirabe/tests/dependency_resolver/solver_test.rs
parentb291e714bc739262140323e08fe2fb9e91e00ee7 (diff)
downloadphp-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.tar.gz
php-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.tar.zst
php-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.zip
test: port previously-ignored Composer tests via __ test hatches
Re-evaluate the reason'd #[ignore] tests under the Phase D criterion: a test is unportable ONLY if the APIs/types needed to WRITE it do not exist. A test that compiles but panics at runtime (todo!() body, a regex the regex crate cannot compile) or fails at runtime (incomplete or incorrect impl behavior) is portable -- it is written in full and marked with a reason-less #[ignore]. About 120 test functions move from reason'd #[ignore] to reason-less #[ignore] (the ported-but-not-yet-passing signal). Impl crates gain only additive __ test hatches (init_command, pool, file_downloader, package handle link setters, artifact/path repository, repository manager, svn); no existing logic changes. Tests whose required APIs genuinely do not exist (mock/reflection harness, ApplicationTester, solve() discarding SolverProblemsException, a script::Event that cannot be passed as an originating event) keep their reason'd #[ignore]. cargo check -p shirabe --tests passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/dependency_resolver/solver_test.rs')
-rw-r--r--crates/shirabe/tests/dependency_resolver/solver_test.rs1777
1 files changed, 1703 insertions, 74 deletions
diff --git a/crates/shirabe/tests/dependency_resolver/solver_test.rs b/crates/shirabe/tests/dependency_resolver/solver_test.rs
index 26f1312..c729fea 100644
--- a/crates/shirabe/tests/dependency_resolver/solver_test.rs
+++ b/crates/shirabe/tests/dependency_resolver/solver_test.rs
@@ -9,11 +9,13 @@ use shirabe::dependency_resolver::default_policy::DefaultPolicy;
use shirabe::dependency_resolver::request::Request;
use shirabe::io::io_interface::IOInterface;
use shirabe::io::null_io::NullIO;
+use shirabe::package::Link;
use shirabe::package::handle::PackageInterfaceHandle;
use shirabe::repository::array_repository::ArrayRepository;
use shirabe::repository::handle::{LockArrayRepositoryHandle, RepositoryInterfaceHandle};
use shirabe::repository::lock_array_repository::LockArrayRepository;
use shirabe::repository::repository_set::RepositorySet;
+use shirabe_semver::constraint::{AnyConstraint, MatchAllConstraint, MultiConstraint};
use crate::test_case::{get_alias_package, get_package, get_version_constraint};
@@ -50,6 +52,40 @@ fn set_up() -> Fixtures {
}
}
+/// PHP `new Link($source, $target, $constraint, $type)`: prettyConstraint defaults to
+/// `(string) $constraint`.
+fn link(source: &str, target: &str, constraint: AnyConstraint, r#type: &str) -> Link {
+ let pretty = constraint.get_pretty_string();
+ Link::new(
+ source.to_string(),
+ target.to_string(),
+ constraint,
+ Some(r#type.to_string()),
+ pretty,
+ )
+}
+
+/// PHP `new Link($source, $target, $constraint, $type, $prettyConstraint)`.
+fn link_pretty(
+ source: &str,
+ target: &str,
+ constraint: AnyConstraint,
+ r#type: &str,
+ pretty: &str,
+) -> Link {
+ Link::new(
+ source.to_string(),
+ target.to_string(),
+ constraint,
+ Some(r#type.to_string()),
+ pretty.to_string(),
+ )
+}
+
+fn multi(constraints: Vec<AnyConstraint>) -> AnyConstraint {
+ MultiConstraint::new(constraints, true, None).into()
+}
+
/// One expected solver job. Mirrors the PHP `['job' => ..., 'package'|'from'|'to' => ...]` rows.
enum ExpectedJob {
Single {
@@ -67,7 +103,7 @@ fn check_solver_result(
mut repo_set: RepositorySet,
repo: ArrayRepository,
repo_locked: LockArrayRepositoryHandle,
- mut request: Request,
+ request: Request,
expected: Vec<ExpectedJob>,
) {
// reposComplete()
@@ -76,6 +112,15 @@ fn check_solver_result(
.unwrap();
repo_set.add_repository(repo_locked.into()).unwrap();
+ check_solver_result_repo_set(&mut repo_set, request, expected);
+}
+
+/// ref: SolverTest::checkSolverResult, against an already-completed RepositorySet (createSolver).
+fn check_solver_result_repo_set(
+ repo_set: &mut RepositorySet,
+ mut request: Request,
+ expected: Vec<ExpectedJob>,
+) {
// createSolver()
let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new()));
let pool = repo_set
@@ -137,6 +182,29 @@ fn check_solver_result(
assert_eq!(expected_ids, result_ids);
}
+/// ref: SolverTest::createSolver + solve, returning the error for expectException-only tests.
+fn solve_expecting_error(
+ mut repo_set: RepositorySet,
+ repo: ArrayRepository,
+ repo_locked: LockArrayRepositoryHandle,
+ mut request: Request,
+) {
+ repo_set
+ .add_repository(RepositoryInterfaceHandle::new(repo))
+ .unwrap();
+ repo_set.add_repository(repo_locked.into()).unwrap();
+
+ let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new()));
+ let pool = repo_set
+ .create_pool(&mut request, io.clone(), None, None, vec![], None, None)
+ .unwrap();
+ let policy: Rc<dyn PolicyInterface> = Rc::new(DefaultPolicy::new(false, false, None));
+ let mut solver =
+ shirabe::dependency_resolver::solver::Solver::new(policy, Rc::new(RefCell::new(pool)), io);
+
+ assert!(solver.solve(&request, None).is_err());
+}
+
#[ignore]
#[test]
fn test_solver_install_single() {
@@ -178,7 +246,7 @@ fn test_solver_remove_if_not_requested() {
);
}
-#[ignore = "solve() error path discards SolverProblemsException (returns placeholder anyhow error); getProblems/getCode/getPrettyString not retrievable"]
+#[ignore = "asserts SolverProblemsException details (getProblems/getCode/getPrettyString) which solve() discards"]
#[test]
fn test_install_non_existing_package_fails() {
let _fixtures = set_up();
@@ -222,40 +290,364 @@ fn test_solver_install_same_package_from_different_repositories() {
);
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_install_with_deps() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let new_package_b = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint("<", "1.1"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_install_honours_not_equal_operator() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let new_package_b11 = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b11.clone()).unwrap();
+ let new_package_b12 = get_package("B", "1.2");
+ fixtures.repo.add_package(new_package_b12.clone()).unwrap();
+ let new_package_b13 = get_package("B", "1.3");
+ fixtures.repo.add_package(new_package_b13.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ multi(vec![
+ get_version_constraint("<=", "1.3"),
+ get_version_constraint("<>", "1.3"),
+ get_version_constraint("!=", "1.2"),
+ ]),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: new_package_b11,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_install_with_deps_in_order() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let package_c = get_package("C", "1.0");
+ fixtures.repo.add_package(package_c.clone()).unwrap();
+
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "c".to_string(),
+ link(
+ "B",
+ "C",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+ package_c
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "C",
+ "A",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+ request.require_name("B", None).unwrap();
+ request.require_name("C", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_c,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_multi_package_name_version_resolution_depends_on_require_order() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let php74 = get_package("ourcustom/PHP", "7.4.23");
+ fixtures.repo.add_package(php74.clone()).unwrap();
+ let php80 = get_package("ourcustom/PHP", "8.0.10");
+ fixtures.repo.add_package(php80.clone()).unwrap();
+ let ext_for_php74 = get_package("ourcustom/ext-foobar", "1.0");
+ fixtures.repo.add_package(ext_for_php74.clone()).unwrap();
+ let ext_for_php80 = get_package("ourcustom/ext-foobar", "1.0");
+ fixtures.repo.add_package(ext_for_php80.clone()).unwrap();
+
+ ext_for_php74
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "ourcustom/php".to_string(),
+ link(
+ "ourcustom/ext-foobar",
+ "ourcustom/PHP",
+ multi(vec![
+ get_version_constraint(">=", "7.4.0"),
+ get_version_constraint("<", "7.5.0"),
+ ]),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ ext_for_php80
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "ourcustom/php".to_string(),
+ link(
+ "ourcustom/ext-foobar",
+ "ourcustom/PHP",
+ multi(vec![
+ get_version_constraint(">=", "8.0.0"),
+ get_version_constraint("<", "8.1.0"),
+ ]),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ // reposComplete()
+ let mut repo_set = fixtures.repo_set;
+ repo_set
+ .add_repository(RepositoryInterfaceHandle::new(fixtures.repo))
+ .unwrap();
+ repo_set
+ .add_repository(fixtures.repo_locked.clone().into())
+ .unwrap();
+
+ let mut request = fixtures.request;
+ request.require_name("ourcustom/PHP", None).unwrap();
+ request.require_name("ourcustom/ext-foobar", None).unwrap();
+
+ check_solver_result_repo_set(
+ &mut repo_set,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: php80.clone(),
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: ext_for_php80,
+ },
+ ],
+ );
+
+ // now we flip the requirements around: we request "ext-foobar" before "php"
+ let mut request = Request::new(Some(fixtures.repo_locked.clone()));
+ request.require_name("ourcustom/ext-foobar", None).unwrap();
+ request.require_name("ourcustom/PHP", None).unwrap();
+
+ check_solver_result_repo_set(
+ &mut repo_set,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: php74,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: ext_for_php74,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_multi_package_name_version_resolution_is_independent_of_require_order_if_ordered_descending_by_requirement()
{
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let php74 = get_package("ourcustom/PHP", "7.4");
+ fixtures.repo.add_package(php74.clone()).unwrap();
+ let php80 = get_package("ourcustom/PHP", "8.0");
+ fixtures.repo.add_package(php80.clone()).unwrap();
+ // note we are inserting this one into the repo first, unlike in the previous test
+ let ext_for_php80 = get_package("ourcustom/ext-foobar", "1.0");
+ fixtures.repo.add_package(ext_for_php80.clone()).unwrap();
+ let ext_for_php74 = get_package("ourcustom/ext-foobar", "1.0");
+ fixtures.repo.add_package(ext_for_php74.clone()).unwrap();
+
+ ext_for_php80
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "ourcustom/php".to_string(),
+ link(
+ "ourcustom/ext-foobar",
+ "ourcustom/PHP",
+ multi(vec![
+ get_version_constraint(">=", "8.0.0"),
+ get_version_constraint("<", "8.1.0"),
+ ]),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ ext_for_php74
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "ourcustom/php".to_string(),
+ link(
+ "ourcustom/ext-foobar",
+ "ourcustom/PHP",
+ multi(vec![
+ get_version_constraint(">=", "7.4.0"),
+ get_version_constraint("<", "7.5.0"),
+ ]),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ // reposComplete()
+ let mut repo_set = fixtures.repo_set;
+ repo_set
+ .add_repository(RepositoryInterfaceHandle::new(fixtures.repo))
+ .unwrap();
+ repo_set
+ .add_repository(fixtures.repo_locked.clone().into())
+ .unwrap();
+
+ let mut request = fixtures.request;
+ request.require_name("ourcustom/PHP", None).unwrap();
+ request.require_name("ourcustom/ext-foobar", None).unwrap();
+
+ check_solver_result_repo_set(
+ &mut repo_set,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: php80.clone(),
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: ext_for_php80.clone(),
+ },
+ ],
+ );
+
+ // unlike in the previous test, the order of requirements no longer matters now
+ let mut request = Request::new(Some(fixtures.repo_locked.clone()));
+ request.require_name("ourcustom/ext-foobar", None).unwrap();
+ request.require_name("ourcustom/PHP", None).unwrap();
+
+ check_solver_result_repo_set(
+ &mut repo_set,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: php80,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: ext_for_php80,
+ },
+ ],
+ );
}
#[ignore]
@@ -297,11 +689,46 @@ fn test_solver_fix_locked_with_alternative() {
);
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_update_does_only_update() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo_locked.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo_locked.add_package(package_b.clone()).unwrap();
+ let new_package_b = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0.0.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.fix_package(package_a.clone());
+ request
+ .require_name("B", Some(get_version_constraint("=", "1.1.0.0")))
+ .unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![ExpectedJob::Update {
+ from: package_b,
+ to: new_package_b,
+ }],
+ );
}
#[ignore]
@@ -328,11 +755,63 @@ fn test_solver_update_single() {
);
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_update_all() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo_locked.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo_locked.add_package(package_b.clone()).unwrap();
+ let new_package_a = get_package("A", "1.1");
+ fixtures.repo.add_package(new_package_a.clone()).unwrap();
+ let new_package_b = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ MatchAllConstraint::new(None).into(),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ new_package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ MatchAllConstraint::new(None).into(),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Update {
+ from: package_b,
+ to: new_package_b,
+ },
+ ExpectedJob::Update {
+ from: package_a,
+ to: new_package_a,
+ },
+ ],
+ );
}
#[ignore]
@@ -475,25 +954,168 @@ fn test_solver_update_fully_constrained_prunes_installed_packages() {
);
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_all_jobs() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_d = get_package("D", "1.0");
+ fixtures.repo_locked.add_package(package_d.clone()).unwrap();
+ let old_package_c = get_package("C", "1.0");
+ fixtures
+ .repo_locked
+ .add_package(old_package_c.clone())
+ .unwrap();
+
+ let package_a = get_package("A", "2.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let new_package_b = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+ let package_c = get_package("C", "1.1");
+ fixtures.repo.add_package(package_c.clone()).unwrap();
+ fixtures.repo.add_package(get_package("D", "1.0")).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint("<", "1.1"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+ request.require_name("C", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "remove",
+ package: package_d,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ExpectedJob::Update {
+ from: old_package_c,
+ to: package_c,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setConflicts not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_three_alternative_require_and_conflict() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "2.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let middle_package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(middle_package_b.clone()).unwrap();
+ let new_package_b = get_package("B", "1.1");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+ let old_package_b = get_package("B", "0.9");
+ fixtures.repo.add_package(old_package_b.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint("<", "1.1"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_conflicts(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint("<", "1.0"),
+ Link::TYPE_CONFLICT,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: middle_package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_solver_obsolete() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo_locked.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ MatchAllConstraint::new(None).into(),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("B", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "remove",
+ package: package_a,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ],
+ );
}
#[ignore]
@@ -520,109 +1142,925 @@ fn test_install_one_of_two_alternatives() {
);
}
-#[ignore = "setRequires/setProvides not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_install_provider() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_q = get_package("Q", "1.0");
+ fixtures.repo.add_package(package_q.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_q
+ .as_complete_package()
+ .unwrap()
+ .__set_provides(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "Q",
+ "B",
+ get_version_constraint("=", "1.0"),
+ Link::TYPE_PROVIDE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ // must explicitly pick the provider, so error in this case
+ solve_expecting_error(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_skip_replacer_of_existing_package() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_q = get_package("Q", "1.0");
+ fixtures.repo.add_package(package_q.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_q
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "Q",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_no_install_replacer_of_missing_package() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_q = get_package("Q", "1.0");
+ fixtures.repo.add_package(package_q.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_q
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "Q",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ solve_expecting_error(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_skip_replaced_package_if_replacer_is_selected() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_q = get_package("Q", "1.0");
+ fixtures.repo.add_package(package_q.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_q
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "Q",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+ request.require_name("Q", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_q,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_pick_older_if_newer_conflicts() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_x = get_package("X", "1.0");
+ fixtures.repo.add_package(package_x.clone()).unwrap();
+ package_x
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "a".to_string(),
+ link(
+ "X",
+ "A",
+ get_version_constraint(">=", "2.0.0.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "b".to_string(),
+ link(
+ "X",
+ "B",
+ get_version_constraint(">=", "2.0.0.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ let package_a = get_package("A", "2.0.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let new_package_a = get_package("A", "2.1.0");
+ fixtures.repo.add_package(new_package_a.clone()).unwrap();
+ let new_package_b = get_package("B", "2.1.0");
+ fixtures.repo.add_package(new_package_b.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "2.0.0.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ // new package A depends on version of package B that does not exist
+ // => new package A is not installable
+ new_package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "2.2.0.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ // add a package S replacing both A and B, so that S and B or S and A cannot be simultaneously installed
+ // but an alternative option for A and B both exists
+ // this creates a more difficult so solve conflict
+ let package_s = get_package("S", "2.0.0");
+ fixtures.repo.add_package(package_s.clone()).unwrap();
+ package_s
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([
+ (
+ "a".to_string(),
+ link(
+ "S",
+ "A",
+ get_version_constraint(">=", "2.0.0.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ (
+ "b".to_string(),
+ link(
+ "S",
+ "B",
+ get_version_constraint(">=", "2.0.0.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ ]));
+
+ let mut request = fixtures.request;
+ request.require_name("X", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: new_package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_x,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_install_circular_require() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b1 = get_package("B", "0.9");
+ fixtures.repo.add_package(package_b1.clone()).unwrap();
+ let package_b2 = get_package("B", "1.1");
+ fixtures.repo.add_package(package_b2.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_b2
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b2,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setProvides not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_install_alternative_with_circular_require() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let package_c = get_package("C", "1.0");
+ fixtures.repo.add_package(package_c.clone()).unwrap();
+ let package_d = get_package("D", "1.0");
+ fixtures.repo.add_package(package_d.clone()).unwrap();
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "virtual".to_string(),
+ link(
+ "B",
+ "Virtual",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_c
+ .as_complete_package()
+ .unwrap()
+ .__set_provides(IndexMap::from([(
+ "virtual".to_string(),
+ link(
+ "C",
+ "Virtual",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_PROVIDE,
+ ),
+ )]));
+ package_d
+ .as_complete_package()
+ .unwrap()
+ .__set_provides(IndexMap::from([(
+ "virtual".to_string(),
+ link(
+ "D",
+ "Virtual",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_PROVIDE,
+ ),
+ )]));
+
+ package_c
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "C",
+ "A",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_d
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "D",
+ "A",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+ request.require_name("C", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_c,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_use_replacer_if_necessary() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let package_d = get_package("D", "1.0");
+ fixtures.repo.add_package(package_d.clone()).unwrap();
+ let package_d2 = get_package("D", "1.1");
+ fixtures.repo.add_package(package_d2.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "c".to_string(),
+ link(
+ "A",
+ "C",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ package_d
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([
+ (
+ "b".to_string(),
+ link(
+ "D",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ (
+ "c".to_string(),
+ link(
+ "D",
+ "C",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ ]));
+
+ package_d2
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([
+ (
+ "b".to_string(),
+ link(
+ "D",
+ "B",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ (
+ "c".to_string(),
+ link(
+ "D",
+ "C",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REPLACE,
+ ),
+ ),
+ ]));
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+ request.require_name("D", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_d2,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ],
+ );
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_issue265() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a1 = get_package("A", "2.0.999999-dev");
+ fixtures.repo.add_package(package_a1.clone()).unwrap();
+ let package_a2 = get_package("A", "2.1-dev");
+ fixtures.repo.add_package(package_a2.clone()).unwrap();
+ let package_a3 = get_package("A", "2.2-dev");
+ fixtures.repo.add_package(package_a3.clone()).unwrap();
+ let package_b1 = get_package("B", "2.0.10");
+ fixtures.repo.add_package(package_b1.clone()).unwrap();
+ let package_b2 = get_package("B", "2.0.9");
+ fixtures.repo.add_package(package_b2.clone()).unwrap();
+ let package_c = get_package("C", "2.0-dev");
+ fixtures.repo.add_package(package_c.clone()).unwrap();
+ let package_d = get_package("D", "2.0.9");
+ fixtures.repo.add_package(package_d.clone()).unwrap();
+
+ package_c
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "a".to_string(),
+ link(
+ "C",
+ "A",
+ get_version_constraint(">=", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "d".to_string(),
+ link(
+ "C",
+ "D",
+ get_version_constraint(">=", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ package_d
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "a".to_string(),
+ link(
+ "D",
+ "A",
+ get_version_constraint(">=", "2.1"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "b".to_string(),
+ link(
+ "D",
+ "B",
+ get_version_constraint(">=", "2.0-dev"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ package_b1
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint("==", "2.1.0.0-dev"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_b2
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint("==", "2.1.0.0-dev"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ package_b2
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "d".to_string(),
+ link(
+ "B",
+ "D",
+ get_version_constraint("==", "2.0.9.0"),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request
+ .require_name("C", Some(get_version_constraint("==", "2.0.0.0-dev")))
+ .unwrap();
+
+ solve_expecting_error(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ );
}
-#[ignore = "setConflicts not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore = "asserts SolverProblemsException details (getProblems/getPrettyString) which solve() discards"]
#[test]
fn test_conflict_result_empty() {
let _fixtures = set_up();
todo!()
}
-#[ignore = "setRequires not available on CompletePackageHandle; also asserts SolverProblemsException details which solve() discards"]
+#[ignore = "asserts SolverProblemsException details (getProblems/getPrettyString) which solve() discards"]
#[test]
fn test_unsatisfiable_requires() {
let _fixtures = set_up();
todo!()
}
-#[ignore = "setRequires not available on CompletePackageHandle; also asserts SolverProblemsException details which solve() discards"]
+#[ignore = "asserts SolverProblemsException details (getProblems/getPrettyString) which solve() discards"]
#[test]
fn test_require_mismatch_exception() {
let _fixtures = set_up();
todo!()
}
-#[ignore = "setRequires/setReplaces not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_learn_literals_with_sorted_rule_literals() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_twig2 = get_package("twig/twig", "2.0");
+ fixtures.repo.add_package(package_twig2.clone()).unwrap();
+ let package_twig16 = get_package("twig/twig", "1.6");
+ fixtures.repo.add_package(package_twig16.clone()).unwrap();
+ let package_twig15 = get_package("twig/twig", "1.5");
+ fixtures.repo.add_package(package_twig15.clone()).unwrap();
+ let package_symfony = get_package("symfony/symfony", "2.0");
+ fixtures.repo.add_package(package_symfony.clone()).unwrap();
+ let package_twig_bridge = get_package("symfony/twig-bridge", "2.0");
+ fixtures
+ .repo
+ .add_package(package_twig_bridge.clone())
+ .unwrap();
+
+ package_twig_bridge
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "twig/twig".to_string(),
+ link(
+ "symfony/twig-bridge",
+ "twig/twig",
+ get_version_constraint("<", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ package_symfony
+ .as_complete_package()
+ .unwrap()
+ .__set_replaces(IndexMap::from([(
+ "symfony/twig-bridge".to_string(),
+ link(
+ "symfony/symfony",
+ "symfony/twig-bridge",
+ get_version_constraint("==", "2.0"),
+ Link::TYPE_REPLACE,
+ ),
+ )]));
+
+ let mut request = fixtures.request;
+ request.require_name("symfony/twig-bridge", None).unwrap();
+ request.require_name("twig/twig", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_twig16,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_twig_bridge,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_install_recursive_alias_dependencies() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "2.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let package_a2 = get_package("A", "2.0");
+ fixtures.repo.add_package(package_a2.clone()).unwrap();
+
+ package_a2
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "b".to_string(),
+ link_pretty(
+ "A",
+ "B",
+ get_version_constraint("==", "2.0"),
+ Link::TYPE_REQUIRE,
+ "== 2.0",
+ ),
+ )]));
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint(">=", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let package_a2_alias = get_alias_package(&package_a2, "1.1");
+ fixtures.repo.add_package(package_a2_alias.clone()).unwrap();
+
+ let mut request = fixtures.request;
+ request
+ .require_name("A", Some(get_version_constraint("==", "1.1.0.0")))
+ .unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a2,
+ },
+ ExpectedJob::Single {
+ job: "markAliasInstalled",
+ package: package_a2_alias,
+ },
+ ],
+ );
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_install_dev_alias() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "2.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "a".to_string(),
+ link(
+ "B",
+ "A",
+ get_version_constraint("<", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ let package_a_alias = get_alias_package(&package_a, "1.1");
+ fixtures.repo.add_package(package_a_alias.clone()).unwrap();
+
+ let mut request = fixtures.request;
+ request
+ .require_name("A", Some(get_version_constraint("==", "2.0")))
+ .unwrap();
+ request.require_name("B", None).unwrap();
+
+ check_solver_result(
+ fixtures.repo_set,
+ fixtures.repo,
+ fixtures.repo_locked,
+ request,
+ vec![
+ ExpectedJob::Single {
+ job: "install",
+ package: package_a,
+ },
+ ExpectedJob::Single {
+ job: "markAliasInstalled",
+ package: package_a_alias,
+ },
+ ExpectedJob::Single {
+ job: "install",
+ package: package_b,
+ },
+ ],
+ );
}
#[ignore]
@@ -699,9 +2137,200 @@ fn test_install_root_aliases_if_alias_of_is_installed() {
);
}
-#[ignore = "setRequires not available on CompletePackageHandle (only RootPackageHandle exposes link setters)"]
+#[ignore]
#[test]
fn test_learn_positive_literal() {
- let _fixtures = set_up();
- todo!()
+ let fixtures = set_up();
+ let package_a = get_package("A", "1.0");
+ fixtures.repo.add_package(package_a.clone()).unwrap();
+ let package_b = get_package("B", "1.0");
+ fixtures.repo.add_package(package_b.clone()).unwrap();
+ let package_c1 = get_package("C", "1.0");
+ fixtures.repo.add_package(package_c1.clone()).unwrap();
+ let package_c2 = get_package("C", "2.0");
+ fixtures.repo.add_package(package_c2.clone()).unwrap();
+ let package_d = get_package("D", "1.0");
+ fixtures.repo.add_package(package_d.clone()).unwrap();
+ let package_e = get_package("E", "1.0");
+ fixtures.repo.add_package(package_e.clone()).unwrap();
+ let package_f1 = get_package("F", "1.0");
+ fixtures.repo.add_package(package_f1.clone()).unwrap();
+ let package_f2 = get_package("F", "2.0");
+ fixtures.repo.add_package(package_f2.clone()).unwrap();
+ let package_g1 = get_package("G", "1.0");
+ fixtures.repo.add_package(package_g1.clone()).unwrap();
+ let package_g2 = get_package("G", "2.0");
+ fixtures.repo.add_package(package_g2.clone()).unwrap();
+ let package_g3 = get_package("G", "3.0");
+ fixtures.repo.add_package(package_g3.clone()).unwrap();
+
+ package_a
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "b".to_string(),
+ link(
+ "A",
+ "B",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "c".to_string(),
+ link(
+ "A",
+ "C",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "d".to_string(),
+ link(
+ "A",
+ "D",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ package_b
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "e".to_string(),
+ link(
+ "B",
+ "E",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ package_c1
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "f".to_string(),
+ link(
+ "C",
+ "F",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+ package_c2
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([
+ (
+ "f".to_string(),
+ link(
+ "C",
+ "F",
+ get_version_constraint("==", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ (
+ "g".to_string(),
+ link(
+ "C",
+ "G",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ ),
+ ]));
+
+ package_d
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "f".to_string(),
+ link(
+ "D",
+ "F",
+ get_version_constraint(">=", "1.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ package_e
+ .as_complete_package()
+ .unwrap()
+ .__set_requires(IndexMap::from([(
+ "g".to_string(),
+ link(
+ "E",
+ "G",
+ get_version_constraint("<=", "2.0"),
+ Link::TYPE_REQUIRE,
+ ),
+ )]));
+
+ // reposComplete() + createSolver() inline so the testFlagLearnedPositiveLiteral flag can be
+ // asserted on the same solver instance used to solve.
+ let mut repo_set = fixtures.repo_set;
+ repo_set
+ .add_repository(RepositoryInterfaceHandle::new(fixtures.repo))
+ .unwrap();
+ repo_set
+ .add_repository(fixtures.repo_locked.into())
+ .unwrap();
+
+ let mut request = fixtures.request;
+ request.require_name("A", None).unwrap();
+
+ let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new()));
+ let pool = repo_set
+ .create_pool(&mut request, io.clone(), None, None, vec![], None, None)
+ .unwrap();
+ let policy: Rc<dyn PolicyInterface> = Rc::new(DefaultPolicy::new(false, false, None));
+ let mut solver =
+ shirabe::dependency_resolver::solver::Solver::new(policy, Rc::new(RefCell::new(pool)), io);
+
+ // check correct setup for assertion later
+ assert!(!solver.test_flag_learned_positive_literal);
+
+ let transaction = solver.solve(&request, None).unwrap();
+
+ let expected = vec![
+ ("install".to_string(), package_f1.get_unique_name()),
+ ("install".to_string(), package_d.get_unique_name()),
+ ("install".to_string(), package_g2.get_unique_name()),
+ ("install".to_string(), package_c2.get_unique_name()),
+ ("install".to_string(), package_e.get_unique_name()),
+ ("install".to_string(), package_b.get_unique_name()),
+ ("install".to_string(), package_a.get_unique_name()),
+ ];
+ let mut result: Vec<(String, String)> = Vec::new();
+ for operation in transaction.get_operations() {
+ if let Some(update) = operation.as_update_operation() {
+ result.push((
+ "update".to_string(),
+ format!(
+ "{} => {}",
+ update.get_initial_package().get_unique_name(),
+ update.get_target_package().get_unique_name()
+ ),
+ ));
+ } else {
+ let op_type = operation.get_operation_type();
+ let job = if op_type == "uninstall" {
+ "remove".to_string()
+ } else {
+ op_type
+ };
+ result.push((job, operation.get_package().get_unique_name()));
+ }
+ }
+ assert_eq!(expected, result);
+
+ // verify that the code path leading to a negative literal resulting in a positive learned
+ // literal is actually executed
+ assert!(solver.test_flag_learned_positive_literal);
}