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}