hakari/
proptest_helpers.rsuse crate::{
hakari::{DepFormatVersion, WorkspaceHackLineStyle},
HakariBuilder, UnifyTargetHost,
};
use guppy::{
graph::{cargo::CargoResolverVersion, PackageGraph},
platform::{Platform, TargetFeatures},
PackageId,
};
use proptest::{
collection::{hash_set, vec},
prelude::*,
};
impl<'g> HakariBuilder<'g> {
pub fn proptest1_strategy(
graph: &'g PackageGraph,
hakari_id_strategy: impl Strategy<Value = Option<&'g PackageId>> + 'g,
) -> impl Strategy<Value = HakariBuilder<'g>> + 'g {
(
hakari_id_strategy,
vec(Platform::strategy(any::<TargetFeatures>()), 0..4),
any::<CargoResolverVersion>(),
hash_set(graph.proptest1_id_strategy(), 0..8),
hash_set(graph.proptest1_id_strategy(), 0..8),
any::<UnifyTargetHost>(),
any::<bool>(),
any::<DepFormatVersion>(),
any::<WorkspaceHackLineStyle>(),
)
.prop_map(
move |(
hakari_id,
platforms,
version,
traversal_excludes,
final_excludes,
unify_target_host,
output_single_feature,
dep_format_version,
line_style,
)| {
let mut builder = HakariBuilder::new(graph, hakari_id)
.expect("HakariBuilder::new returned an error");
let platforms: Vec<_> = platforms
.iter()
.map(|platform| platform.triple_str().to_owned())
.collect();
builder
.set_platforms(platforms)
.expect("all platforms are known")
.set_resolver(version)
.add_traversal_excludes(traversal_excludes)
.expect("traversal excludes obtained from PackageGraph should work")
.add_final_excludes(final_excludes)
.expect("final excludes obtained from PackageGraph should work")
.set_unify_target_host(unify_target_host)
.set_dep_format_version(dep_format_version)
.set_workspace_hack_line_style(line_style)
.set_output_single_feature(output_single_feature);
builder
},
)
}
}
#[cfg(all(test, feature = "cli-support"))]
mod test {
use super::*;
use fixtures::json::JsonFixture;
use proptest::option;
use std::collections::HashSet;
#[test]
fn builder_summary_roundtrip() {
for (&name, fixture) in JsonFixture::all_fixtures() {
let graph = fixture.graph();
let workspace = graph.workspace();
let strategy = HakariBuilder::proptest1_strategy(
graph,
option::of(workspace.proptest1_id_strategy()),
);
proptest!(|(builder in strategy)| {
let summary = builder.to_summary().unwrap_or_else(|err| {
panic!("for fixture {}, builder -> summary conversion failed: {}", name, err);
});
let builder2 = summary.to_hakari_builder(graph).unwrap_or_else(|err| {
panic!("for fixture {}, summary -> builder conversion failed: {}", name, err);
});
let summary2 = builder2.to_summary().unwrap_or_else(|err| {
panic!("for fixture {}, second builder -> summary conversion failed: {}", name, err);
});
assert_eq!(summary, summary2, "summary roundtripped correctly");
});
}
}
#[test]
fn traversal_excludes() {
for (&name, fixture) in JsonFixture::all_fixtures() {
let graph = fixture.graph();
let workspace = graph.workspace();
let strategy = HakariBuilder::proptest1_strategy(
graph,
option::of(workspace.proptest1_id_strategy()),
);
proptest!(|(builder in strategy, queries in vec(graph.proptest1_id_strategy(), 0..64))| {
if let Some(package) = builder.hakari_package() {
assert!(
builder.is_traversal_excluded(package.id()).expect("valid package ID"),
"for fixture {}, hakari package is excluded from traversals",
name,
);
}
let traversal_excludes: HashSet<_> = builder.traversal_excludes().collect();
for query_id in queries {
assert_eq!(
traversal_excludes.contains(query_id),
builder.is_traversal_excluded(query_id).expect("valid package ID"),
"for fixture {}, traversal_excludes and is_traversal_excluded match",
name,
);
}
});
}
}
}