use pubgrub::range::Range;
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::type_aliases::Map;
use pubgrub::version::{NumberVersion, SemanticVersion};
#[test]
fn no_conflict() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
#[rustfmt::skip]
dependency_provider.add_dependencies(
"root", (1, 0, 0),
vec![("foo", Range::between((1, 0, 0), (2, 0, 0)))],
);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"foo", (1, 0, 0),
vec![("bar", Range::between((1, 0, 0), (2, 0, 0)))],
);
dependency_provider.add_dependencies("bar", (1, 0, 0), vec![]);
dependency_provider.add_dependencies("bar", (2, 0, 0), vec![]);
let computed_solution = resolve(&dependency_provider, "root", (1, 0, 0)).unwrap();
let mut expected_solution = Map::default();
expected_solution.insert("root", (1, 0, 0).into());
expected_solution.insert("foo", (1, 0, 0).into());
expected_solution.insert("bar", (1, 0, 0).into());
assert_eq!(expected_solution, computed_solution);
}
#[test]
fn avoiding_conflict_during_decision_making() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
#[rustfmt::skip]
dependency_provider.add_dependencies(
"root", (1, 0, 0),
vec![
("foo", Range::between((1, 0, 0), (2, 0, 0))),
("bar", Range::between((1, 0, 0), (2, 0, 0))),
],
);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"foo", (1, 1, 0),
vec![("bar", Range::between((2, 0, 0), (3, 0, 0)))],
);
dependency_provider.add_dependencies("foo", (1, 0, 0), vec![]);
dependency_provider.add_dependencies("bar", (1, 0, 0), vec![]);
dependency_provider.add_dependencies("bar", (1, 1, 0), vec![]);
dependency_provider.add_dependencies("bar", (2, 0, 0), vec![]);
let computed_solution = resolve(&dependency_provider, "root", (1, 0, 0)).unwrap();
let mut expected_solution = Map::default();
expected_solution.insert("root", (1, 0, 0).into());
expected_solution.insert("foo", (1, 0, 0).into());
expected_solution.insert("bar", (1, 1, 0).into());
assert_eq!(expected_solution, computed_solution);
}
#[test]
fn conflict_resolution() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
#[rustfmt::skip]
dependency_provider.add_dependencies(
"root", (1, 0, 0),
vec![("foo", Range::higher_than((1, 0, 0)))],
);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"foo", (2, 0, 0),
vec![("bar", Range::between((1, 0, 0), (2, 0, 0)))],
);
dependency_provider.add_dependencies("foo", (1, 0, 0), vec![]);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"bar", (1, 0, 0),
vec![("foo", Range::between((1, 0, 0), (2, 0, 0)))],
);
let computed_solution = resolve(&dependency_provider, "root", (1, 0, 0)).unwrap();
let mut expected_solution = Map::default();
expected_solution.insert("root", (1, 0, 0).into());
expected_solution.insert("foo", (1, 0, 0).into());
assert_eq!(expected_solution, computed_solution);
}
#[test]
fn conflict_with_partial_satisfier() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
#[rustfmt::skip]
dependency_provider.add_dependencies(
"root", (1, 0, 0),
vec![
("foo", Range::between((1, 0, 0), (2, 0, 0))),
("target", Range::between((2, 0, 0), (3, 0, 0))),
],
);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"foo", (1, 1, 0),
vec![
("left", Range::between((1, 0, 0), (2, 0, 0))),
("right", Range::between((1, 0, 0), (2, 0, 0))),
],
);
dependency_provider.add_dependencies("foo", (1, 0, 0), vec![]);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"left", (1, 0, 0),
vec![("shared", Range::higher_than((1, 0, 0)))],
);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"right", (1, 0, 0),
vec![("shared", Range::strictly_lower_than((2, 0, 0)))],
);
dependency_provider.add_dependencies("shared", (2, 0, 0), vec![]);
#[rustfmt::skip]
dependency_provider.add_dependencies(
"shared", (1, 0, 0),
vec![("target", Range::between((1, 0, 0), (2, 0, 0)))],
);
dependency_provider.add_dependencies("target", (2, 0, 0), vec![]);
dependency_provider.add_dependencies("target", (1, 0, 0), vec![]);
let computed_solution = resolve(&dependency_provider, "root", (1, 0, 0)).unwrap();
let mut expected_solution = Map::default();
expected_solution.insert("root", (1, 0, 0).into());
expected_solution.insert("foo", (1, 0, 0).into());
expected_solution.insert("target", (2, 0, 0).into());
assert_eq!(expected_solution, computed_solution);
}
#[test]
fn double_choices() {
let mut dependency_provider = OfflineDependencyProvider::<&str, NumberVersion>::new();
dependency_provider.add_dependencies("a", 0, vec![("b", Range::any()), ("c", Range::any())]);
dependency_provider.add_dependencies("b", 0, vec![("d", Range::exact(0))]);
dependency_provider.add_dependencies("b", 1, vec![("d", Range::exact(1))]);
dependency_provider.add_dependencies("c", 0, vec![]);
dependency_provider.add_dependencies("c", 1, vec![("d", Range::exact(2))]);
dependency_provider.add_dependencies("d", 0, vec![]);
let mut expected_solution = Map::default();
expected_solution.insert("a", 0.into());
expected_solution.insert("b", 0.into());
expected_solution.insert("c", 0.into());
expected_solution.insert("d", 0.into());
let computed_solution = resolve(&dependency_provider, "a", 0).unwrap();
assert_eq!(expected_solution, computed_solution);
}