guppy_cmdlib/proptest.rs
1// Copyright (c) The cargo-guppy Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Proptest support.
5
6use crate::PackagesAndFeatures;
7use guppy::{
8 graph::PackageGraph,
9 platform::{Platform, TargetFeatures},
10};
11use proptest::{collection::hash_set, prelude::*};
12
13impl PackagesAndFeatures {
14 pub fn strategy(graph: &PackageGraph) -> impl Strategy<Value = Self> + '_ {
15 let workspace = graph.workspace();
16 (
17 // The lower bound of 0 is important because 0 means the whole workspace.
18 hash_set(workspace.proptest1_name_strategy(), 0..8),
19 any::<bool>(),
20 any::<bool>(),
21 // The lower bound of 0 is important here as well, because 0 means none.
22 // (This is at the end to avoid perturbing previously-generated values of all_features
23 // and no_default_features.)
24 hash_set(workspace.proptest1_name_strategy(), 0..4),
25 )
26 .prop_map(
27 move |(packages, all_features, no_default_features, features_only)| {
28 // TODO: select features from these packages (probably requires flat_map :/ )
29 Self {
30 packages: packages
31 .into_iter()
32 .map(|package| package.to_string())
33 .collect(),
34 features_only: features_only
35 .into_iter()
36 .map(|package| package.to_string())
37 .collect(),
38 features: vec![],
39 all_features,
40 no_default_features,
41 }
42 },
43 )
44 }
45}
46
47/// Generates a random, known target triple that can be understood by both cargo and guppy, or
48/// `None`.
49pub fn triple_strategy() -> impl Strategy<Value = Option<String>> {
50 let platform_strategy = Platform::filtered_strategy(
51 |triple| {
52 // Filter out Apple platforms because rustc requires the Apple SDKs to be set up for
53 // them.
54 !triple.contains("-apple-")
55 },
56 Just(TargetFeatures::Unknown),
57 );
58 prop_oneof![
59 // 25% chance to generate None, 75% to generate a particular platform
60 1 => Just(None),
61 3 => platform_strategy.prop_map(|platform| Some(platform.triple_str().to_owned())),
62 ]
63}